Blender  V3.3
extract_mesh_vbo_edituv_stretch_area.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "BKE_mesh.h"
11 
12 #include "extract_mesh.hh"
13 
14 #include "draw_subdivision.h"
15 
16 namespace blender::draw {
17 
18 /* ---------------------------------------------------------------------- */
23  MeshBatchCache *UNUSED(cache),
24  void *buf,
25  void *UNUSED(tls_data))
26 {
27  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
28  static GPUVertFormat format = {0};
29  if (format.attr_len == 0) {
31  }
32 
35 }
36 
37 BLI_INLINE float area_ratio_get(float area, float uvarea)
38 {
39  if (area >= FLT_EPSILON && uvarea >= FLT_EPSILON) {
40  return uvarea / area;
41  }
42  return 0.0f;
43 }
44 
45 BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
46 {
47  ratio *= tot_ratio;
48  return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
49 }
50 
51 static void compute_area_ratio(const MeshRenderData *mr,
52  float *r_area_ratio,
53  float &r_tot_area,
54  float &r_tot_uv_area)
55 {
56  float tot_area = 0.0f, tot_uv_area = 0.0f;
57 
58  if (mr->extract_type == MR_EXTRACT_BMESH) {
59  CustomData *cd_ldata = &mr->bm->ldata;
60  int uv_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV);
61 
62  BMFace *efa;
63  BMIter f_iter;
64  int f;
65  BM_ITER_MESH_INDEX (efa, &f_iter, mr->bm, BM_FACES_OF_MESH, f) {
66  float area = BM_face_calc_area(efa);
67  float uvarea = BM_face_calc_area_uv(efa, uv_ofs);
68  tot_area += area;
69  tot_uv_area += uvarea;
70  r_area_ratio[f] = area_ratio_get(area, uvarea);
71  }
72  }
73  else {
75  const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
76  const MPoly *mp = mr->mpoly;
77  for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
78  float area = BKE_mesh_calc_poly_area(mp, &mr->mloop[mp->loopstart], mr->mvert);
79  float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data);
80  tot_area += area;
81  tot_uv_area += uvarea;
82  r_area_ratio[mp_index] = area_ratio_get(area, uvarea);
83  }
84  }
85 
86  r_tot_area = tot_area;
87  r_tot_uv_area = tot_uv_area;
88 }
89 
91  MeshBatchCache *cache,
92  void *buf,
93  void *UNUSED(data))
94 {
95  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
96  float *area_ratio = static_cast<float *>(MEM_mallocN(sizeof(float) * mr->poly_len, __func__));
97  compute_area_ratio(mr, area_ratio, cache->tot_area, cache->tot_uv_area);
98 
99  /* Copy face data for each loop. */
100  float *loop_stretch = (float *)GPU_vertbuf_get_data(vbo);
101 
102  if (mr->extract_type == MR_EXTRACT_BMESH) {
103  BMFace *efa;
104  BMIter f_iter;
105  int f, l_index = 0;
106  BM_ITER_MESH_INDEX (efa, &f_iter, mr->bm, BM_FACES_OF_MESH, f) {
107  for (int i = 0; i < efa->len; i++, l_index++) {
108  loop_stretch[l_index] = area_ratio[f];
109  }
110  }
111  }
112  else {
114  const MPoly *mp = mr->mpoly;
115  for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
116  for (int i = 0; i < mp->totloop; i++, l_index++) {
117  loop_stretch[l_index] = area_ratio[mp_index];
118  }
119  }
120  }
121 
122  MEM_freeN(area_ratio);
123 }
124 
126  const MeshRenderData *mr,
127  MeshBatchCache *cache,
128  void *buffer,
129  void *UNUSED(data))
130 {
131 
132  /* Initialize final buffer. */
133  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
134  static GPUVertFormat format = {0};
135  if (format.attr_len == 0) {
137  }
138 
140 
141  /* Initialize coarse data buffer. */
142 
143  GPUVertBuf *coarse_data = GPU_vertbuf_calloc();
144 
145  /* We use the same format as we just copy data around. */
146  GPU_vertbuf_init_with_format(coarse_data, &format);
147  GPU_vertbuf_data_alloc(coarse_data, mr->loop_len);
148 
150  static_cast<float *>(GPU_vertbuf_get_data(coarse_data)),
151  cache->tot_area,
152  cache->tot_uv_area);
153 
154  draw_subdiv_build_edituv_stretch_area_buffer(subdiv_cache, coarse_data, vbo);
155 
156  GPU_vertbuf_discard(coarse_data);
157 }
158 
160 {
161  MeshExtract extractor = {nullptr};
165  extractor.data_type = MR_DATA_NONE;
166  extractor.data_size = 0;
167  extractor.use_threading = false;
168  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.edituv_stretch_area);
169  return extractor;
170 }
171 
174 } // namespace blender::draw
175 
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_offset(const struct CustomData *data, int type)
float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array)
float BKE_mesh_calc_poly_area(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_INLINE
#define UNUSED(x)
#define ELEM(...)
@ CD_MLOOPUV
void GPU_vertbuf_discard(GPUVertBuf *)
struct GPUVertBuf GPUVertBuf
GPUVertBuf * GPU_vertbuf_calloc(void)
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
#define GPU_vertbuf_init_with_format(verts, format)
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
void GPU_vertbuf_init_build_on_device(GPUVertBuf *verts, GPUVertFormat *format, uint v_len)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Read Guarded memory(de)allocation.
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_FACES_OF_MESH
float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset)
float BM_face_calc_area(const BMFace *f)
@ MR_DATA_NONE
void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache *cache, GPUVertBuf *coarse_data, GPUVertBuf *subdiv_data)
Extraction of Mesh data into VBO to feed to GPU.
@ MR_EXTRACT_BMESH
Definition: extract_mesh.hh:31
@ MR_EXTRACT_MESH
Definition: extract_mesh.hh:33
@ MR_EXTRACT_MAPPED
Definition: extract_mesh.hh:32
const MeshExtract extract_edituv_stretch_area
ccl_global float * buffer
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static void area(int d1, int d2, int e1, int e2, float weights[2])
BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
static void extract_edituv_stretch_area_finish(const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *UNUSED(data))
static void extract_edituv_stretch_area_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *cache, void *buffer, void *UNUSED(data))
BLI_INLINE float area_ratio_get(float area, float uvarea)
static void compute_area_ratio(const MeshRenderData *mr, float *r_area_ratio, float &r_tot_area, float &r_tot_uv_area)
static void extract_edituv_stretch_area_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(tls_data))
constexpr MeshExtract create_extractor_edituv_stretch_area()
int len
Definition: bmesh_class.h:267
CustomData ldata
Definition: bmesh_class.h:337
GPUVertBuf * edituv_stretch_area
size_t mesh_buffer_offset
eMRDataType data_type
ExtractFinishFn * finish
ExtractInitSubdivFn * init_subdiv
size_t data_size
bool use_threading
ExtractInitFn * init
eMRExtractType extract_type
Definition: extract_mesh.hh:37
const MLoop * mloop
Definition: extract_mesh.hh:76
const MVert * mvert
Definition: extract_mesh.hh:74
const MPoly * mpoly
Definition: extract_mesh.hh:77
CustomData ldata