Blender  V3.3
extract_mesh_ibo_points.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 "BLI_vector.hh"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "draw_subdivision.h"
13 #include "extract_mesh.hh"
14 
15 namespace blender::draw {
16 
17 /* ---------------------------------------------------------------------- */
21 static void extract_points_init(const MeshRenderData *mr,
22  MeshBatchCache *UNUSED(cache),
23  void *UNUSED(buf),
24  void *tls_data)
25 {
26  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
28 }
29 
30 BLI_INLINE void vert_set_bm(GPUIndexBufBuilder *elb, const BMVert *eve, int l_index)
31 {
32  const int v_index = BM_elem_index_get(eve);
33  if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
34  GPU_indexbuf_set_point_vert(elb, v_index, l_index);
35  }
36  else {
37  GPU_indexbuf_set_point_restart(elb, v_index);
38  }
39 }
40 
42  const MeshRenderData *mr,
43  const int v_index,
44  const int l_index)
45 {
46  const MVert *mv = &mr->mvert[v_index];
47  if (!((mr->use_hide && (mv->flag & ME_HIDE)) ||
48  ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) &&
49  (mr->v_origindex[v_index] == ORIGINDEX_NONE)))) {
50  GPU_indexbuf_set_point_vert(elb, v_index, l_index);
51  }
52  else {
53  GPU_indexbuf_set_point_restart(elb, v_index);
54  }
55 }
56 
58  const BMFace *f,
59  const int UNUSED(f_index),
60  void *_userdata)
61 {
62  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
63  BMLoop *l_iter, *l_first;
64  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
65  do {
66  const int l_index = BM_elem_index_get(l_iter);
67 
68  vert_set_bm(elb, l_iter->v, l_index);
69  } while ((l_iter = l_iter->next) != l_first);
70 }
71 
73  const MPoly *mp,
74  const int UNUSED(mp_index),
75  void *_userdata)
76 {
77  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
78  const MLoop *mloop = mr->mloop;
79  const int ml_index_end = mp->loopstart + mp->totloop;
80  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
81  const MLoop *ml = &mloop[ml_index];
82  vert_set_mesh(elb, mr, ml->v, ml_index);
83  }
84 }
85 
87  const BMEdge *eed,
88  const int ledge_index,
89  void *_userdata)
90 {
91  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
92  vert_set_bm(elb, eed->v1, mr->loop_len + (ledge_index * 2));
93  vert_set_bm(elb, eed->v2, mr->loop_len + (ledge_index * 2) + 1);
94 }
95 
97  const MEdge *med,
98  const int ledge_index,
99  void *_userdata)
100 {
101  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
102  vert_set_mesh(elb, mr, med->v1, mr->loop_len + (ledge_index * 2));
103  vert_set_mesh(elb, mr, med->v2, mr->loop_len + (ledge_index * 2) + 1);
104 }
105 
107  const BMVert *eve,
108  const int lvert_index,
109  void *_userdata)
110 {
111  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
112  const int offset = mr->loop_len + (mr->edge_loose_len * 2);
113  vert_set_bm(elb, eve, offset + lvert_index);
114 }
115 
117  const MVert *UNUSED(mv),
118  const int lvert_index,
119  void *_userdata)
120 {
121  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
122  const int offset = mr->loop_len + (mr->edge_loose_len * 2);
123  vert_set_mesh(elb, mr, mr->lverts[lvert_index], offset + lvert_index);
124 }
125 
126 static void extract_points_task_reduce(void *_userdata_to, void *_userdata_from)
127 {
128  GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
129  GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
130  GPU_indexbuf_join(elb_to, elb_from);
131 }
132 
134  MeshBatchCache *UNUSED(cache),
135  void *buf,
136  void *_userdata)
137 {
138  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
139  GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
140  GPU_indexbuf_build_in_place(elb, ibo);
141 }
142 
143 static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache,
144  const MeshRenderData *mr,
145  MeshBatchCache *UNUSED(cache),
146  void *UNUSED(buffer),
147  void *data)
148 {
149  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
150  GPU_indexbuf_init(elb,
152  mr->vert_len,
153  subdiv_cache->num_subdiv_loops + subdiv_cache->loose_geom.loop_len);
154 }
155 
157  const MeshRenderData *mr,
158  const DRWSubdivCache *subdiv_cache,
159  uint subdiv_quad_index,
160  bool for_bmesh)
161 {
162  int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
163  uint start_loop_idx = subdiv_quad_index * 4;
164  uint end_loop_idx = (subdiv_quad_index + 1) * 4;
165  for (uint i = start_loop_idx; i < end_loop_idx; i++) {
166  int coarse_vertex_index = subdiv_loop_vert_index[i];
167 
168  if (coarse_vertex_index == -1) {
169  continue;
170  }
171 
172  if (mr->v_origindex && mr->v_origindex[coarse_vertex_index] == -1) {
173  continue;
174  }
175 
176  if (for_bmesh) {
177  const BMVert *mv = BM_vert_at_index(mr->bm, coarse_vertex_index);
179  GPU_indexbuf_set_point_restart(elb, coarse_vertex_index);
180  continue;
181  }
182  }
183  else {
184  const MVert *mv = &mr->mvert[coarse_vertex_index];
185  if (mr->use_hide && (mv->flag & ME_HIDE)) {
186  GPU_indexbuf_set_point_restart(elb, coarse_vertex_index);
187  continue;
188  }
189  }
190 
191  GPU_indexbuf_set_point_vert(elb, coarse_vertex_index, i);
192  }
193 }
194 
195 static void extract_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
196  const MeshRenderData *mr,
197  void *_data,
198  uint subdiv_quad_index,
199  const BMFace *UNUSED(coarse_quad))
200 {
201  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
202  extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index, true);
203 }
204 
205 static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
206  const MeshRenderData *mr,
207  void *_data,
208  uint subdiv_quad_index,
209  const MPoly *UNUSED(coarse_quad))
210 {
211  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
212  extract_points_iter_subdiv_common(elb, mr, subdiv_cache, subdiv_quad_index, false);
213 }
214 
215 static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
216  const MeshRenderData *mr,
217  void *UNUSED(buffer),
218  void *data)
219 {
220  const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
221  const int loop_loose_len = loose_geom.loop_len;
222  if (loop_loose_len == 0) {
223  return;
224  }
225 
226  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(data);
227 
228  uint offset = subdiv_cache->num_subdiv_loops;
229 
230  if (mr->extract_type != MR_EXTRACT_BMESH) {
232  subdiv_cache);
233 
234  for (const DRWSubdivLooseEdge &loose_edge : loose_edges) {
235  const DRWSubdivLooseVertex &v1 = loose_geom.verts[loose_edge.loose_subdiv_v1_index];
236  const DRWSubdivLooseVertex &v2 = loose_geom.verts[loose_edge.loose_subdiv_v2_index];
237  if (v1.coarse_vertex_index != -1u) {
238  vert_set_mesh(elb, mr, v1.coarse_vertex_index, offset);
239  }
240  if (v2.coarse_vertex_index != -1u) {
241  vert_set_mesh(elb, mr, v2.coarse_vertex_index, offset + 1);
242  }
243 
244  offset += 2;
245  }
247  subdiv_cache);
248 
249  for (const DRWSubdivLooseVertex &loose_vert : loose_verts) {
250  vert_set_mesh(elb, mr, loose_vert.coarse_vertex_index, offset);
251  offset += 1;
252  }
253  }
254  else {
256  subdiv_cache);
257 
258  for (const DRWSubdivLooseEdge &loose_edge : loose_edges) {
259  const DRWSubdivLooseVertex &v1 = loose_geom.verts[loose_edge.loose_subdiv_v1_index];
260  const DRWSubdivLooseVertex &v2 = loose_geom.verts[loose_edge.loose_subdiv_v2_index];
261  if (v1.coarse_vertex_index != -1u) {
262  BMVert *eve = mr->v_origindex ? bm_original_vert_get(mr, v1.coarse_vertex_index) :
263  BM_vert_at_index(mr->bm, v1.coarse_vertex_index);
264  vert_set_bm(elb, eve, offset);
265  }
266  if (v2.coarse_vertex_index != -1u) {
267  BMVert *eve = mr->v_origindex ? bm_original_vert_get(mr, v2.coarse_vertex_index) :
268  BM_vert_at_index(mr->bm, v2.coarse_vertex_index);
269  vert_set_bm(elb, eve, offset + 1);
270  }
271 
272  offset += 2;
273  }
275  subdiv_cache);
276 
277  for (const DRWSubdivLooseVertex &loose_vert : loose_verts) {
278  BMVert *eve = mr->v_origindex ? bm_original_vert_get(mr, loose_vert.coarse_vertex_index) :
279  BM_vert_at_index(mr->bm, loose_vert.coarse_vertex_index);
280  vert_set_bm(elb, eve, offset);
281  offset += 1;
282  }
283  }
284 }
285 
286 static void extract_points_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
287  const MeshRenderData *UNUSED(mr),
288  MeshBatchCache *UNUSED(cache),
289  void *buf,
290  void *_userdata)
291 {
292  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
293  GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
294  GPU_indexbuf_build_in_place(elb, ibo);
295 }
296 
298 {
299  MeshExtract extractor = {nullptr};
300  extractor.init = extract_points_init;
308  extractor.finish = extract_points_finish;
314  extractor.use_threading = true;
315  extractor.data_type = MR_DATA_NONE;
316  extractor.data_size = sizeof(GPUIndexBufBuilder);
317  extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.points);
318  return extractor;
319 }
320 
323 } // namespace blender::draw
324 
#define ORIGINDEX_NONE
#define BLI_INLINE
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
@ ME_HIDE
struct GPUIndexBufBuilder GPUIndexBufBuilder
struct GPUIndexBuf GPUIndexBuf
void GPU_indexbuf_set_point_vert(GPUIndexBufBuilder *builder, uint elem, uint v1)
void GPU_indexbuf_set_point_restart(GPUIndexBufBuilder *builder, uint elem)
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_join(GPUIndexBufBuilder *builder, const GPUIndexBufBuilder *builder_from)
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:19
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
Read Guarded memory(de)allocation.
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
Definition: bmesh_mesh.h:103
ATTR_WARN_UNUSED_RESULT const BMVert * v2
@ MR_DATA_NONE
blender::Span< DRWSubdivLooseVertex > draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache)
blender::Span< DRWSubdivLooseEdge > draw_subdiv_cache_get_loose_edges(const DRWSubdivCache *cache)
Extraction of Mesh data into VBO to feed to GPU.
BLI_INLINE BMVert * bm_original_vert_get(const MeshRenderData *mr, int idx)
@ MR_EXTRACT_BMESH
Definition: extract_mesh.hh:31
@ MR_EXTRACT_MAPPED
Definition: extract_mesh.hh:32
const MeshExtract extract_points
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
constexpr MeshExtract create_extractor_points()
static void extract_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *_data, uint subdiv_quad_index, const MPoly *UNUSED(coarse_quad))
static void extract_points_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache), const MeshRenderData *UNUSED(mr), MeshBatchCache *UNUSED(cache), void *buf, void *_userdata)
static void extract_points_iter_ledge_bm(const MeshRenderData *mr, const BMEdge *eed, const int ledge_index, void *_userdata)
BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb, const MeshRenderData *mr, const int v_index, const int l_index)
static void extract_points_iter_subdiv_common(GPUIndexBufBuilder *elb, const MeshRenderData *mr, const DRWSubdivCache *subdiv_cache, uint subdiv_quad_index, bool for_bmesh)
static void extract_points_task_reduce(void *_userdata_to, void *_userdata_from)
static void extract_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *_data, uint subdiv_quad_index, const BMFace *UNUSED(coarse_quad))
static void extract_points_iter_ledge_mesh(const MeshRenderData *mr, const MEdge *med, const int ledge_index, void *_userdata)
static void extract_points_iter_lvert_mesh(const MeshRenderData *mr, const MVert *UNUSED(mv), const int lvert_index, void *_userdata)
static void extract_points_iter_lvert_bm(const MeshRenderData *mr, const BMVert *eve, const int lvert_index, void *_userdata)
static void extract_points_iter_poly_bm(const MeshRenderData *UNUSED(mr), const BMFace *f, const int UNUSED(f_index), void *_userdata)
static void extract_points_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int UNUSED(mp_index), void *_userdata)
static void extract_points_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *UNUSED(buf), void *tls_data)
static void extract_points_finish(const MeshRenderData *UNUSED(mr), MeshBatchCache *UNUSED(cache), void *buf, void *_userdata)
static void extract_points_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *UNUSED(buffer), void *data)
BLI_INLINE void vert_set_bm(GPUIndexBufBuilder *elb, const BMVert *eve, int l_index)
static void extract_points_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *UNUSED(buffer), void *data)
BMVert * v1
Definition: bmesh_class.h:122
BMVert * v2
Definition: bmesh_class.h:122
struct BMVert * v
Definition: bmesh_class.h:153
struct BMLoop * next
Definition: bmesh_class.h:233
struct GPUVertBuf * verts_orig_index
DRWSubdivLooseGeom loose_geom
DRWSubdivLooseVertex * verts
unsigned int v1
unsigned int v2
unsigned int v
GPUIndexBuf * points
ExtractIterSubdivBMeshFn * iter_subdiv_bm
size_t mesh_buffer_offset
eMRDataType data_type
ExtractFinishFn * finish
ExtractLVertBMeshFn * iter_lvert_bm
ExtractLVertMeshFn * iter_lvert_mesh
ExtractLEdgeBMeshFn * iter_ledge_bm
ExtractIterSubdivMeshFn * iter_subdiv_mesh
ExtractInitSubdivFn * init_subdiv
size_t data_size
ExtractPolyBMeshFn * iter_poly_bm
ExtractLEdgeMeshFn * iter_ledge_mesh
ExtractFinishSubdivFn * finish_subdiv
ExtractPolyMeshFn * iter_poly_mesh
ExtractLooseGeomSubdivFn * iter_loose_geom_subdiv
ExtractTaskReduceFn * task_reduce
bool use_threading
ExtractInitFn * init
eMRExtractType extract_type
Definition: extract_mesh.hh:37
const MLoop * mloop
Definition: extract_mesh.hh:76
const int * v_origindex
Definition: extract_mesh.hh:66
const MVert * mvert
Definition: extract_mesh.hh:74