Blender  V3.3
extract_mesh_vbo_select_idx.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 "draw_subdivision.h"
9 #include "extract_mesh.hh"
10 
11 namespace blender::draw {
12 
13 /* ---------------------------------------------------------------------- */
18  const int len,
19  void *buf,
20  void *tls_data)
21 {
22  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
23  static GPUVertFormat format = {0};
24  if (format.attr_len == 0) {
26  }
29  *(int32_t **)tls_data = (int32_t *)GPU_vertbuf_get_data(vbo);
30 }
31 
33  MeshBatchCache *UNUSED(cache),
34  void *buf,
35  void *tls_data)
36 {
37  extract_select_idx_init_impl(mr, mr->loop_len + mr->loop_loose_len, buf, tls_data);
38 }
39 
40 /* TODO: Use #glVertexID to get loop index and use the data structure on the CPU to retrieve the
41  * select element associated with this loop ID. This would remove the need for this separate
42  * index VBO's. We could upload the p/e/v_origindex as a buffer texture and sample it inside the
43  * shader to output original index. */
44 
46  const BMFace *f,
47  const int f_index,
48  void *data)
49 {
50  BMLoop *l_iter, *l_first;
51  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
52  do {
53  const int l_index = BM_elem_index_get(l_iter);
54  (*(int32_t **)data)[l_index] = f_index;
55  } while ((l_iter = l_iter->next) != l_first);
56 }
57 
59  const BMFace *f,
60  const int UNUSED(f_index),
61  void *data)
62 {
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  (*(int32_t **)data)[l_index] = BM_elem_index_get(l_iter->e);
68  } while ((l_iter = l_iter->next) != l_first);
69 }
70 
72  const BMFace *f,
73  const int UNUSED(f_index),
74  void *data)
75 {
76  BMLoop *l_iter, *l_first;
77  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
78  do {
79  const int l_index = BM_elem_index_get(l_iter);
80  (*(int32_t **)data)[l_index] = BM_elem_index_get(l_iter->v);
81  } while ((l_iter = l_iter->next) != l_first);
82 }
83 
85  const BMEdge *eed,
86  const int ledge_index,
87  void *data)
88 {
89  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed);
90  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed);
91 }
92 
94  const BMEdge *eed,
95  const int ledge_index,
96  void *data)
97 {
98  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed->v1);
99  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed->v2);
100 }
101 
103  const BMVert *eve,
104  const int lvert_index,
105  void *data)
106 {
107  const int offset = mr->loop_len + (mr->edge_loose_len * 2);
108 
109  (*(int32_t **)data)[offset + lvert_index] = BM_elem_index_get(eve);
110 }
111 
113  const MPoly *mp,
114  const int mp_index,
115  void *data)
116 {
117  const int ml_index_end = mp->loopstart + mp->totloop;
118  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
119  (*(int32_t **)data)[ml_index] = (mr->p_origindex) ? mr->p_origindex[mp_index] : mp_index;
120  }
121 }
122 
124  const MPoly *mp,
125  const int UNUSED(mp_index),
126  void *data)
127 {
128  const MLoop *mloop = mr->mloop;
129  const int ml_index_end = mp->loopstart + mp->totloop;
130  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
131  const MLoop *ml = &mloop[ml_index];
132  (*(int32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e;
133  }
134 }
135 
137  const MPoly *mp,
138  const int UNUSED(mp_index),
139  void *data)
140 {
141  const MLoop *mloop = mr->mloop;
142  const int ml_index_end = mp->loopstart + mp->totloop;
143  for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
144  const MLoop *ml = &mloop[ml_index];
145  (*(int32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v;
146  }
147 }
148 
150  const MEdge *UNUSED(med),
151  const int ledge_index,
152  void *data)
153 {
154  const int e_index = mr->ledges[ledge_index];
155  const int e_orig = (mr->e_origindex) ? mr->e_origindex[e_index] : e_index;
156  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = e_orig;
157  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = e_orig;
158 }
159 
161  const MEdge *med,
162  const int ledge_index,
163  void *data)
164 {
165  int v1_orig = (mr->v_origindex) ? mr->v_origindex[med->v1] : med->v1;
166  int v2_orig = (mr->v_origindex) ? mr->v_origindex[med->v2] : med->v2;
167  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 0] = v1_orig;
168  (*(int32_t **)data)[mr->loop_len + ledge_index * 2 + 1] = v2_orig;
169 }
170 
172  const MVert *UNUSED(mv),
173  const int lvert_index,
174  void *data)
175 {
176  const int offset = mr->loop_len + (mr->edge_loose_len * 2);
177 
178  const int v_index = mr->lverts[lvert_index];
179  const int v_orig = (mr->v_origindex) ? mr->v_origindex[v_index] : v_index;
180  (*(int32_t **)data)[offset + lvert_index] = v_orig;
181 }
182 
183 static void extract_vert_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
184  const MeshRenderData *mr,
185  MeshBatchCache *UNUSED(cache),
186  void *buf,
187  void *UNUSED(data))
188 {
189  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
190  const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
191  /* Each element points to an element in the `ibo.points`. */
193  vbo,
195  subdiv_cache->num_subdiv_loops,
196  loose_geom.loop_len);
197  if (!mr->v_origindex) {
198  return;
199  }
200 
201  /* Remap the vertex indices to those pointed by the origin indices layer. At this point, the
202  * VBO data is a copy of #verts_orig_index which contains the coarse vertices indices, so
203  * the memory can both be accessed for lookup and immediately overwritten. */
204  int32_t *vbo_data = static_cast<int32_t *>(GPU_vertbuf_get_data(vbo));
205  for (int i = 0; i < subdiv_cache->num_subdiv_loops; i++) {
206  if (vbo_data[i] == -1) {
207  continue;
208  }
209  vbo_data[i] = mr->v_origindex[vbo_data[i]];
210  }
211 }
212 
213 static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
214  const MeshRenderData *mr,
215  void *buffer,
216  void *UNUSED(data))
217 {
218  const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
219  if (loose_geom.loop_len == 0) {
220  return;
221  }
222 
223  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
224  int32_t *vert_idx_data = (int32_t *)GPU_vertbuf_get_data(vbo);
225  uint offset = subdiv_cache->num_subdiv_loops;
226 
228 
229  for (const DRWSubdivLooseEdge &loose_edge : loose_edges) {
230  const DRWSubdivLooseVertex &v1 = loose_geom.verts[loose_edge.loose_subdiv_v1_index];
231  const DRWSubdivLooseVertex &v2 = loose_geom.verts[loose_edge.loose_subdiv_v2_index];
232 
233  if (v1.coarse_vertex_index != -1u) {
234  vert_idx_data[offset] = mr->v_origindex ? mr->v_origindex[v1.coarse_vertex_index] :
235  v1.coarse_vertex_index;
236  }
237 
238  if (v2.coarse_vertex_index != -1u) {
239  vert_idx_data[offset + 1] = mr->v_origindex ? mr->v_origindex[v2.coarse_vertex_index] :
240  v2.coarse_vertex_index;
241  }
242 
243  offset += 2;
244  }
245 
247  subdiv_cache);
248 
249  for (const DRWSubdivLooseVertex &loose_vert : loose_verts) {
250  vert_idx_data[offset] = mr->v_origindex ? mr->v_origindex[loose_vert.coarse_vertex_index] :
251  loose_vert.coarse_vertex_index;
252  offset += 1;
253  }
254 }
255 
256 static void extract_edge_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
257  const MeshRenderData *UNUSED(mr),
258  MeshBatchCache *UNUSED(cache),
259  void *buf,
260  void *UNUSED(data))
261 {
262  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
263  const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
265  vbo,
266  static_cast<int32_t *>(GPU_vertbuf_get_data(subdiv_cache->edges_orig_index)),
267  subdiv_cache->num_subdiv_loops,
268  loose_geom.edge_len * 2);
269 }
270 
271 static void extract_edge_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
272  const MeshRenderData *mr,
273  void *buffer,
274  void *UNUSED(data))
275 {
276  const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom;
277  if (loose_geom.edge_len == 0) {
278  return;
279  }
280 
281  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
282  int32_t *vert_idx_data = (int32_t *)GPU_vertbuf_get_data(vbo);
283  uint offset = subdiv_cache->num_subdiv_loops;
284 
286  for (const DRWSubdivLooseEdge &loose_edge : loose_edges) {
287  const int coarse_edge_index = mr->e_origindex ? mr->e_origindex[loose_edge.coarse_edge_index] :
288  loose_edge.coarse_edge_index;
289  vert_idx_data[offset] = coarse_edge_index;
290  vert_idx_data[offset + 1] = coarse_edge_index;
291  offset += 2;
292  }
293 }
294 
295 static void extract_poly_idx_init_subdiv(const DRWSubdivCache *subdiv_cache,
296  const MeshRenderData *mr,
297  MeshBatchCache *UNUSED(cache),
298  void *buf,
299  void *UNUSED(data))
300 {
301  GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
303  vbo, subdiv_cache->subdiv_loop_poly_index, subdiv_cache->num_subdiv_loops, 0);
304 
305  if (!mr->p_origindex) {
306  return;
307  }
308 
309  /* Remap the polygon indices to those pointed by the origin indices layer. At this point, the
310  * VBO data is a copy of #subdiv_loop_poly_index which contains the coarse polygon indices, so
311  * the memory can both be accessed for lookup and immediately overwritten. */
312  int32_t *vbo_data = static_cast<int32_t *>(GPU_vertbuf_get_data(vbo));
313  for (int i = 0; i < subdiv_cache->num_subdiv_loops; i++) {
314  vbo_data[i] = mr->p_origindex[vbo_data[i]];
315  }
316 }
317 
319 {
320  MeshExtract extractor = {nullptr};
321  extractor.init = extract_select_idx_init;
325  extractor.data_type = MR_DATA_NONE;
326  extractor.data_size = sizeof(int32_t *);
327  extractor.use_threading = true;
328  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.poly_idx);
329  return extractor;
330 }
331 
333 {
334  MeshExtract extractor = {nullptr};
335  extractor.init = extract_select_idx_init;
342  extractor.data_type = MR_DATA_NONE;
343  extractor.data_size = sizeof(int32_t *);
344  extractor.use_threading = true;
345  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.edge_idx);
346  return extractor;
347 }
348 
350 {
351  MeshExtract extractor = {nullptr};
352  extractor.init = extract_select_idx_init;
361  extractor.data_type = MR_DATA_NONE;
362  extractor.data_size = sizeof(int32_t *);
363  extractor.use_threading = true;
364  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.vert_idx);
365  return extractor;
366 }
367 
368 static void extract_fdot_idx_init(const MeshRenderData *mr,
369  MeshBatchCache *UNUSED(cache),
370  void *buf,
371  void *tls_data)
372 {
373  extract_select_idx_init_impl(mr, mr->poly_len, buf, tls_data);
374 }
375 
377  const BMFace *UNUSED(f),
378  const int f_index,
379  void *data)
380 {
381  (*(int32_t **)data)[f_index] = f_index;
382 }
383 
385  const MPoly *UNUSED(mp),
386  const int mp_index,
387  void *data)
388 {
389  if (mr->p_origindex != nullptr) {
390  (*(int32_t **)data)[mp_index] = mr->p_origindex[mp_index];
391  }
392  else {
393  (*(int32_t **)data)[mp_index] = mp_index;
394  }
395 }
396 
398 {
399  MeshExtract extractor = {nullptr};
400  extractor.init = extract_fdot_idx_init;
403  extractor.data_type = MR_DATA_NONE;
404  extractor.data_size = sizeof(int32_t *);
405  extractor.use_threading = true;
406  extractor.mesh_buffer_offset = offsetof(MeshBufferList, vbo.fdot_idx);
407  return extractor;
408 }
409 
412 } // namespace blender::draw
413 
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
_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
struct GPUVertBuf GPUVertBuf
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)
@ GPU_FETCH_INT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_I32
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
ATTR_WARN_UNUSED_RESULT const BMVert * v2
@ MR_DATA_NONE
blender::Span< DRWSubdivLooseVertex > draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache)
void draw_subdiv_init_origindex_buffer(GPUVertBuf *buffer, int32_t *vert_origindex, uint num_loops, uint loose_len)
blender::Span< DRWSubdivLooseEdge > draw_subdiv_cache_get_loose_edges(const DRWSubdivCache *cache)
int len
Definition: draw_manager.c:108
Extraction of Mesh data into VBO to feed to GPU.
const MeshExtract extract_vert_idx
const MeshExtract extract_fdot_idx
const MeshExtract extract_edge_idx
const MeshExtract extract_poly_idx
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
format
Definition: logImageCore.h:38
static void extract_edge_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr), const BMFace *f, const int UNUSED(f_index), void *data)
static void extract_vert_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr), const BMFace *f, const int UNUSED(f_index), void *data)
static void extract_edge_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *buffer, void *UNUSED(data))
static void extract_fdot_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr), const BMFace *UNUSED(f), const int f_index, void *data)
static void extract_edge_idx_iter_ledge_mesh(const MeshRenderData *mr, const MEdge *UNUSED(med), const int ledge_index, void *data)
static void extract_fdot_idx_iter_poly_mesh(const MeshRenderData *mr, const MPoly *UNUSED(mp), const int mp_index, void *data)
static void extract_vert_idx_iter_lvert_bm(const MeshRenderData *mr, const BMVert *eve, const int lvert_index, void *data)
static void extract_poly_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(data))
static void extract_fdot_idx_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr, const MEdge *med, const int ledge_index, void *data)
static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int UNUSED(mp_index), void *data)
constexpr MeshExtract create_extractor_edge_idx()
static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr, const MVert *UNUSED(mv), const int lvert_index, void *data)
static void extract_vert_idx_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *buffer, void *UNUSED(data))
constexpr MeshExtract create_extractor_fdot_idx()
static void extract_select_idx_init_impl(const MeshRenderData *UNUSED(mr), const int len, void *buf, void *tls_data)
static void extract_edge_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *UNUSED(mr), MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(data))
static void extract_vert_idx_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *UNUSED(data))
constexpr MeshExtract create_extractor_vert_idx()
static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int UNUSED(mp_index), void *data)
static void extract_poly_idx_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int mp_index, void *data)
static void extract_vert_idx_iter_ledge_bm(const MeshRenderData *mr, const BMEdge *eed, const int ledge_index, void *data)
static void extract_poly_idx_iter_poly_bm(const MeshRenderData *UNUSED(mr), const BMFace *f, const int f_index, void *data)
constexpr MeshExtract create_extractor_poly_idx()
static void extract_edge_idx_iter_ledge_bm(const MeshRenderData *mr, const BMEdge *eed, const int ledge_index, void *data)
static void extract_select_idx_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *buf, void *tls_data)
signed int int32_t
Definition: stdint.h:77
BMVert * v1
Definition: bmesh_class.h:122
BMVert * v2
Definition: bmesh_class.h:122
struct BMVert * v
Definition: bmesh_class.h:153
struct BMEdge * e
Definition: bmesh_class.h:164
struct BMLoop * next
Definition: bmesh_class.h:233
struct GPUVertBuf * edges_orig_index
struct GPUVertBuf * verts_orig_index
int * subdiv_loop_poly_index
DRWSubdivLooseGeom loose_geom
DRWSubdivLooseVertex * verts
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
GPUVertBuf * edge_idx
GPUVertBuf * poly_idx
GPUVertBuf * fdot_idx
GPUVertBuf * vert_idx
size_t mesh_buffer_offset
eMRDataType data_type
ExtractLVertBMeshFn * iter_lvert_bm
ExtractLVertMeshFn * iter_lvert_mesh
ExtractLEdgeBMeshFn * iter_ledge_bm
ExtractInitSubdivFn * init_subdiv
size_t data_size
ExtractPolyBMeshFn * iter_poly_bm
ExtractLEdgeMeshFn * iter_ledge_mesh
ExtractPolyMeshFn * iter_poly_mesh
ExtractLooseGeomSubdivFn * iter_loose_geom_subdiv
bool use_threading
ExtractInitFn * init
const MLoop * mloop
Definition: extract_mesh.hh:76
const int * v_origindex
Definition: extract_mesh.hh:66
const int * p_origindex
Definition: extract_mesh.hh:66
const int * e_origindex
Definition: extract_mesh.hh:66