Blender  V3.3
draw_cache_extract_mesh_render_data.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 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_array.hh"
13 #include "BLI_bitmap.h"
14 #include "BLI_math.h"
15 #include "BLI_task.h"
16 
17 #include "BKE_editmesh.h"
18 #include "BKE_editmesh_cache.h"
19 #include "BKE_mesh.h"
20 
21 #include "GPU_batch.h"
22 
23 #include "ED_mesh.h"
24 
26 
27 /* ---------------------------------------------------------------------- */
31 static void mesh_render_data_lverts_bm(const MeshRenderData *mr,
32  MeshBufferCache *cache,
33  BMesh *bm);
34 static void mesh_render_data_ledges_bm(const MeshRenderData *mr,
35  MeshBufferCache *cache,
36  BMesh *bm);
39 
41 {
42  mr->ledges = cache->loose_geom.edges;
43  mr->lverts = cache->loose_geom.verts;
44  mr->vert_loose_len = cache->loose_geom.vert_len;
45  mr->edge_loose_len = cache->loose_geom.edge_len;
46 
47  mr->loop_loose_len = mr->vert_loose_len + (mr->edge_loose_len * 2);
48 }
49 
51 {
52  /* Early exit: Are loose geometry already available.
53  * Only checking for loose verts as loose edges and verts are calculated at the same time. */
54  if (cache->loose_geom.verts) {
55  return;
56  }
58 }
59 
61 {
62  cache->loose_geom.vert_len = 0;
63  cache->loose_geom.edge_len = 0;
64 
65  if (mr->extract_type != MR_EXTRACT_BMESH) {
66  /* Mesh */
68  }
69  else {
70  /* #BMesh */
71  BMesh *bm = mr->bm;
72  mesh_render_data_lverts_bm(mr, cache, bm);
73  mesh_render_data_ledges_bm(mr, cache, bm);
74  }
75 }
76 
78 {
79  BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, __func__);
80 
81  cache->loose_geom.edges = static_cast<int *>(
82  MEM_mallocN(mr->edge_len * sizeof(*cache->loose_geom.edges), __func__));
83  const MEdge *med = mr->medge;
84  for (int med_index = 0; med_index < mr->edge_len; med_index++, med++) {
85  if (med->flag & ME_LOOSEEDGE) {
86  cache->loose_geom.edges[cache->loose_geom.edge_len++] = med_index;
87  }
88  /* Tag verts as not loose. */
89  BLI_BITMAP_ENABLE(lvert_map, med->v1);
90  BLI_BITMAP_ENABLE(lvert_map, med->v2);
91  }
92  if (cache->loose_geom.edge_len < mr->edge_len) {
93  cache->loose_geom.edges = static_cast<int *>(MEM_reallocN(
94  cache->loose_geom.edges, cache->loose_geom.edge_len * sizeof(*cache->loose_geom.edges)));
95  }
96 
97  cache->loose_geom.verts = static_cast<int *>(
98  MEM_mallocN(mr->vert_len * sizeof(*cache->loose_geom.verts), __func__));
99  for (int v = 0; v < mr->vert_len; v++) {
100  if (!BLI_BITMAP_TEST(lvert_map, v)) {
101  cache->loose_geom.verts[cache->loose_geom.vert_len++] = v;
102  }
103  }
104  if (cache->loose_geom.vert_len < mr->vert_len) {
105  cache->loose_geom.verts = static_cast<int *>(MEM_reallocN(
106  cache->loose_geom.verts, cache->loose_geom.vert_len * sizeof(*cache->loose_geom.verts)));
107  }
108 
109  MEM_freeN(lvert_map);
110 }
111 
113 {
114  int elem_id;
115  BMIter iter;
116  BMVert *eve;
117  cache->loose_geom.verts = static_cast<int *>(
118  MEM_mallocN(mr->vert_len * sizeof(*cache->loose_geom.verts), __func__));
119  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, elem_id) {
120  if (eve->e == nullptr) {
121  cache->loose_geom.verts[cache->loose_geom.vert_len++] = elem_id;
122  }
123  }
124  if (cache->loose_geom.vert_len < mr->vert_len) {
125  cache->loose_geom.verts = static_cast<int *>(MEM_reallocN(
126  cache->loose_geom.verts, cache->loose_geom.vert_len * sizeof(*cache->loose_geom.verts)));
127  }
128 }
129 
131 {
132  int elem_id;
133  BMIter iter;
134  BMEdge *ede;
135  cache->loose_geom.edges = static_cast<int *>(
136  MEM_mallocN(mr->edge_len * sizeof(*cache->loose_geom.edges), __func__));
137  BM_ITER_MESH_INDEX (ede, &iter, bm, BM_EDGES_OF_MESH, elem_id) {
138  if (ede->l == nullptr) {
139  cache->loose_geom.edges[cache->loose_geom.edge_len++] = elem_id;
140  }
141  }
142  if (cache->loose_geom.edge_len < mr->edge_len) {
143  cache->loose_geom.edges = static_cast<int *>(MEM_reallocN(
144  cache->loose_geom.edges, cache->loose_geom.edge_len * sizeof(*cache->loose_geom.edges)));
145  }
146 }
147 
149  MeshBufferCache *cache,
150  const eMRIterType iter_type,
151  const eMRDataType data_flag)
152 {
153  if ((iter_type & (MR_ITER_LEDGE | MR_ITER_LVERT)) || (data_flag & MR_DATA_LOOSE_GEOM)) {
156  }
157 }
158 
161 /* ---------------------------------------------------------------------- */
171 
173  MeshBufferCache *cache,
174  const eMRDataType data_flag)
175 {
176  if (data_flag & MR_DATA_POLYS_SORTED) {
179  }
180 }
181 
183 {
187 }
188 
190 {
191  if (cache->poly_sorted.tri_first_index) {
192  return;
193  }
195 }
196 
198 {
199  int *tri_first_index = static_cast<int *>(
200  MEM_mallocN(sizeof(*tri_first_index) * mr->poly_len, __func__));
201  int *mat_tri_len = mesh_render_data_mat_tri_len_build(mr);
202 
203  /* Apply offset. */
204  int visible_tri_len = 0;
205  blender::Array<int, 32> mat_tri_offs(mr->mat_len);
206  {
207  for (int i = 0; i < mr->mat_len; i++) {
208  mat_tri_offs[i] = visible_tri_len;
209  visible_tri_len += mat_tri_len[i];
210  }
211  }
212 
213  /* Sort per material. */
214  int mat_last = mr->mat_len - 1;
215  if (mr->extract_type == MR_EXTRACT_BMESH) {
216  BMIter iter;
217  BMFace *f;
218  int i;
219  BM_ITER_MESH_INDEX (f, &iter, mr->bm, BM_FACES_OF_MESH, i) {
221  const int mat = min_ii(f->mat_nr, mat_last);
222  tri_first_index[i] = mat_tri_offs[mat];
223  mat_tri_offs[mat] += f->len - 2;
224  }
225  else {
226  tri_first_index[i] = -1;
227  }
228  }
229  }
230  else {
231  const MPoly *mp = &mr->mpoly[0];
232  for (int i = 0; i < mr->poly_len; i++, mp++) {
233  if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
234  const int mat = min_ii(mp->mat_nr, mat_last);
235  tri_first_index[i] = mat_tri_offs[mat];
236  mat_tri_offs[mat] += mp->totloop - 2;
237  }
238  else {
239  tri_first_index[i] = -1;
240  }
241  }
242  }
243 
244  cache->poly_sorted.tri_first_index = tri_first_index;
245  cache->poly_sorted.mat_tri_len = mat_tri_len;
246  cache->poly_sorted.visible_tri_len = visible_tri_len;
247 }
248 
249 static void mesh_render_data_mat_tri_len_bm_range_fn(void *__restrict userdata,
250  const int iter,
251  const TaskParallelTLS *__restrict tls)
252 {
253  MeshRenderData *mr = static_cast<MeshRenderData *>(userdata);
254  int *mat_tri_len = static_cast<int *>(tls->userdata_chunk);
255 
256  BMesh *bm = mr->bm;
257  BMFace *efa = BM_face_at_index(bm, iter);
258  if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
259  int mat = min_ii(efa->mat_nr, mr->mat_len - 1);
260  mat_tri_len[mat] += efa->len - 2;
261  }
262 }
263 
264 static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata,
265  const int iter,
266  const TaskParallelTLS *__restrict tls)
267 {
268  MeshRenderData *mr = static_cast<MeshRenderData *>(userdata);
269  int *mat_tri_len = static_cast<int *>(tls->userdata_chunk);
270 
271  const MPoly *mp = &mr->mpoly[iter];
272  if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
273  int mat = min_ii(mp->mat_nr, mr->mat_len - 1);
274  mat_tri_len[mat] += mp->totloop - 2;
275  }
276 }
277 
278 static void mesh_render_data_mat_tri_len_reduce_fn(const void *__restrict userdata,
279  void *__restrict chunk_join,
280  void *__restrict chunk)
281 {
282  const MeshRenderData *mr = static_cast<const MeshRenderData *>(userdata);
283  int *dst_mat_len = static_cast<int *>(chunk_join);
284  int *src_mat_len = static_cast<int *>(chunk);
285  for (int i = 0; i < mr->mat_len; i++) {
286  dst_mat_len[i] += src_mat_len[i];
287  }
288 }
289 
291  int face_len,
292  TaskParallelRangeFunc range_func)
293 {
294  /* Extending the #MatOffsetUserData with an int per material slot. */
295  size_t mat_tri_len_size = sizeof(int) * mr->mat_len;
296  int *mat_tri_len = static_cast<int *>(MEM_callocN(mat_tri_len_size, __func__));
297 
298  TaskParallelSettings settings;
300  settings.userdata_chunk = mat_tri_len;
301  settings.userdata_chunk_size = mat_tri_len_size;
304  BLI_task_parallel_range(0, face_len, mr, range_func, &settings);
305 
306  return mat_tri_len;
307 }
308 
309 /* Count how many triangles for each material. */
311 {
312  if (mr->extract_type == MR_EXTRACT_BMESH) {
313  BMesh *bm = mr->bm;
316  }
319 }
320 
323 /* ---------------------------------------------------------------------- */
328  const eMRIterType iter_type,
329  const eMRDataType data_flag)
330 {
331  Mesh *me = mr->me;
332  if (mr->extract_type != MR_EXTRACT_BMESH) {
333  /* Mesh */
334  if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
335  /* NOTE(campbell): It's possible to skip allocating tessellation,
336  * the tessellation can be calculated as part of the iterator, see: P2188.
337  * The overall advantage is small (around 1%), so keep this as-is. */
338  mr->mlooptri = static_cast<MLoopTri *>(
339  MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI"));
340  if (mr->poly_normals != nullptr) {
342  me->mpoly,
343  me->mvert,
344  me->totloop,
345  me->totpoly,
346  mr->mlooptri,
347  mr->poly_normals);
348  }
349  else {
351  me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mr->mlooptri);
352  }
353  }
354  }
355  else {
356  /* #BMesh */
357  if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
358  /* Edit mode ensures this is valid, no need to calculate. */
359  BLI_assert((mr->bm->totloop == 0) || (mr->edit_bmesh->looptris != nullptr));
360  }
361  }
362 }
363 
365 {
366  Mesh *me = mr->me;
367  const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
368  const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
369 
370  if (mr->extract_type != MR_EXTRACT_BMESH) {
371  /* Mesh */
375  }
376  if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
377  mr->loop_normals = static_cast<float(*)[3]>(
378  MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
379  short(*clnors)[2] = static_cast<short(*)[2]>(
382  mr->vert_normals,
383  mr->vert_len,
384  mr->me->medge,
385  mr->edge_len,
386  mr->me->mloop,
387  mr->loop_normals,
388  mr->loop_len,
389  mr->me->mpoly,
390  mr->poly_normals,
391  mr->poly_len,
392  is_auto_smooth,
393  split_angle,
394  nullptr,
395  clnors,
396  nullptr);
397  }
398  }
399  else {
400  /* #BMesh */
401  if (data_flag & MR_DATA_POLY_NOR) {
402  /* Use #BMFace.no instead. */
403  }
404  if (((data_flag & MR_DATA_LOOP_NOR) && is_auto_smooth) || (data_flag & MR_DATA_TAN_LOOP_NOR)) {
405 
406  const float(*vert_coords)[3] = nullptr;
407  const float(*vert_normals)[3] = nullptr;
408  const float(*poly_normals)[3] = nullptr;
409 
410  if (mr->edit_data && mr->edit_data->vertexCos) {
411  vert_coords = mr->bm_vert_coords;
412  vert_normals = mr->bm_vert_normals;
413  poly_normals = mr->bm_poly_normals;
414  }
415 
416  mr->loop_normals = static_cast<float(*)[3]>(
417  MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__));
418  const int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
420  vert_coords,
421  vert_normals,
422  poly_normals,
423  is_auto_smooth,
424  split_angle,
425  mr->loop_normals,
426  nullptr,
427  nullptr,
428  clnors_offset,
429  false);
430  }
431  }
432 }
433 
435  const Object &object,
436  const Mesh &mesh)
437 {
438  const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh);
439  const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(mesh_final);
440  const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(mesh_final);
441 
442  /* Necessary because which attributes are active/default is stored in #CustomData. */
443  Mesh me_query = blender::dna::shallow_zero_initialize();
445  ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id);
446 
447  mr.active_color_name = nullptr;
448  mr.default_color_name = nullptr;
449 
451  mr.active_color_name = active->name;
452  }
453  if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) {
454  mr.default_color_name = render->name;
455  }
456 }
457 
459  Mesh *me,
460  const bool is_editmode,
461  const bool is_paint_mode,
462  const bool is_mode_active,
463  const float obmat[4][4],
464  const bool do_final,
465  const bool do_uvedit,
466  const ToolSettings *ts)
467 {
468  MeshRenderData *mr = static_cast<MeshRenderData *>(MEM_callocN(sizeof(*mr), __func__));
469  mr->toolsettings = ts;
470  mr->mat_len = mesh_render_mat_len_get(object, me);
471 
472  copy_m4_m4(mr->obmat, obmat);
473 
474  if (is_editmode) {
475  Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
476  Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(object);
477 
478  BLI_assert(editmesh_eval_cage && editmesh_eval_final);
479  mr->bm = me->edit_mesh->bm;
480  mr->edit_bmesh = me->edit_mesh;
481  mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage;
482  mr->edit_data = is_mode_active ? mr->me->runtime.edit_data : nullptr;
483 
484  if (mr->edit_data) {
485  EditMeshData *emd = mr->edit_data;
486  if (emd->vertexCos) {
489  }
490 
493  mr->bm_poly_normals = mr->edit_data->polyNos;
494  mr->bm_poly_centers = mr->edit_data->polyCos;
495  }
496 
497  /* A subdivision wrapper may be created in edit mode when X-ray is turned on to ensure that the
498  * topology seen by the user matches the one used for the selection routines. This wrapper
499  * seemingly takes precedence over the MDATA one, however the mesh we use for rendering is not
500  * the subdivided one, but the one where the MDATA wrapper would have been added. So consider
501  * the subdivision wrapper as well for the `has_mdata` case. */
502  bool has_mdata = is_mode_active && ELEM(mr->me->runtime.wrapper_type,
505  bool use_mapped = is_mode_active &&
506  (has_mdata && !do_uvedit && mr->me && !mr->me->runtime.is_original);
507 
508  int bm_ensure_types = BM_VERT | BM_EDGE | BM_LOOP | BM_FACE;
509 
510  BM_mesh_elem_index_ensure(mr->bm, bm_ensure_types);
511  BM_mesh_elem_table_ensure(mr->bm, bm_ensure_types & ~BM_LOOP);
512 
513  mr->efa_act_uv = EDBM_uv_active_face_get(mr->edit_bmesh, false, false);
514  mr->efa_act = BM_mesh_active_face_get(mr->bm, false, true);
517 
521 #ifdef WITH_FREESTYLE
524 #endif
525 
526  if (use_mapped) {
527  mr->v_origindex = static_cast<const int *>(
529  mr->e_origindex = static_cast<const int *>(
531  mr->p_origindex = static_cast<const int *>(
533 
534  use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex);
535  }
536 
537  mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_BMESH;
538 
539  /* Seems like the mesh_eval_final do not have the right origin indices.
540  * Force not mapped in this case. */
541  if (has_mdata && do_final && editmesh_eval_final != editmesh_eval_cage) {
542  // mr->edit_bmesh = NULL;
544  }
545  }
546  else {
547  mr->me = me;
548  mr->edit_bmesh = nullptr;
549 
550  bool use_mapped = is_paint_mode && mr->me && !mr->me->runtime.is_original;
551  if (use_mapped) {
552  mr->v_origindex = static_cast<const int *>(
554  mr->e_origindex = static_cast<const int *>(
556  mr->p_origindex = static_cast<const int *>(
558 
559  use_mapped = (mr->v_origindex || mr->e_origindex || mr->p_origindex);
560  }
561 
562  mr->extract_type = use_mapped ? MR_EXTRACT_MAPPED : MR_EXTRACT_MESH;
563  }
564 
565  if (mr->extract_type != MR_EXTRACT_BMESH) {
566  /* Mesh */
567  mr->vert_len = mr->me->totvert;
568  mr->edge_len = mr->me->totedge;
569  mr->loop_len = mr->me->totloop;
570  mr->poly_len = mr->me->totpoly;
571  mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
572 
573  mr->mvert = static_cast<MVert *>(CustomData_get_layer(&mr->me->vdata, CD_MVERT));
574  mr->medge = static_cast<MEdge *>(CustomData_get_layer(&mr->me->edata, CD_MEDGE));
575  mr->mloop = static_cast<MLoop *>(CustomData_get_layer(&mr->me->ldata, CD_MLOOP));
576  mr->mpoly = static_cast<MPoly *>(CustomData_get_layer(&mr->me->pdata, CD_MPOLY));
577 
578  mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
579  mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
580  mr->p_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
581  }
582  else {
583  /* #BMesh */
584  BMesh *bm = mr->bm;
585 
586  mr->vert_len = bm->totvert;
587  mr->edge_len = bm->totedge;
588  mr->loop_len = bm->totloop;
589  mr->poly_len = bm->totface;
590  mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
591  }
592 
593  retrieve_active_attribute_names(*mr, *object, *me);
594 
595  return mr;
596 }
597 
599 {
600  MEM_SAFE_FREE(mr->mlooptri);
602 
603  /* Loose geometry are owned by #MeshBufferCache. */
604  mr->ledges = nullptr;
605  mr->lverts = nullptr;
606 
607  MEM_freeN(mr);
608 }
609 
typedef float(TangentPoint)[2]
struct CustomDataLayer * BKE_id_attributes_active_color_get(const struct ID *id)
struct CustomDataLayer * BKE_id_attributes_render_color_get(const struct ID *id)
void BKE_id_attribute_copy_domains_temp(short id_type, const struct CustomData *vdata, const struct CustomData *edata, const struct CustomData *ldata, const struct CustomData *pdata, const struct CustomData *cdata, struct ID *r_id)
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_offset(const struct CustomData *data, int type)
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd)
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd)
const float(* BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3]
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop, const struct MPoly *mpoly, const struct MVert *mvert, int totloop, int totpoly, struct MLoopTri *mlooptri, const float(*poly_normals)[3])
void BKE_mesh_recalc_looptri(const struct MLoop *mloop, const struct MPoly *mpoly, const struct MVert *mvert, int totloop, int totpoly, struct MLoopTri *mlooptri)
void BKE_mesh_normals_loop_split(const struct MVert *mverts, const float(*vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, struct MLoop *mloops, float(*r_loopnors)[3], int numLoops, struct MPoly *mpolys, const float(*polynors)[3], int numPolys, bool use_split_normals, float split_angle, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], int *r_loop_to_poly)
struct Mesh * BKE_object_get_editmesh_eval_final(const struct Object *object)
struct Mesh * BKE_object_get_editmesh_eval_cage(const struct Object *object)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
MINLINE int min_ii(int a, int b)
#define M_PI
Definition: BLI_math_base.h:20
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
void(* TaskParallelRangeFunc)(void *__restrict userdata, int iter, const TaskParallelTLS *__restrict tls)
Definition: BLI_task.h:145
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
#define ELEM(...)
@ ID_ME
Definition: DNA_ID_enums.h:48
@ CD_CUSTOMLOOPNORMAL
@ CD_ORIGINDEX
@ CD_FREESTYLE_EDGE
@ CD_FREESTYLE_FACE
@ CD_MEDGE
@ CD_MVERT
@ CD_BWEIGHT
@ ME_WRAPPER_TYPE_MDATA
@ ME_WRAPPER_TYPE_SUBD
@ ME_AUTOSMOOTH
@ ME_HIDE
@ ME_LOOSEEDGE
struct BMFace * EDBM_uv_active_face_get(struct BMEditMesh *em, bool sloppy, bool selected)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMEdge * BM_mesh_active_edge_get(BMesh *bm)
BMVert * BM_mesh_active_vert_get(BMesh *bm)
BMFace * BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:558
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.cc:446
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
Definition: bmesh_mesh.h:115
void BM_loops_calc_normal_vcos(BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*fnos)[3], const bool use_split_normals, const float split_angle, float(*r_lnos)[3], MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild)
BMesh Compute Loop Normals from/to external data.
ATTR_WARN_UNUSED_RESULT const BMVert * v
BLI_INLINE int mesh_render_mat_len_get(const Object *object, const Mesh *me)
@ MR_DATA_LOOP_NOR
@ MR_DATA_POLYS_SORTED
@ MR_DATA_TAN_LOOP_NOR
@ MR_DATA_POLY_NOR
@ MR_DATA_LOOPTRI
@ MR_DATA_LOOSE_GEOM
static void mesh_render_data_loose_geom_build(const MeshRenderData *mr, MeshBufferCache *cache)
static void retrieve_active_attribute_names(MeshRenderData &mr, const Object &object, const Mesh &mesh)
void mesh_render_data_update_looptris(MeshRenderData *mr, const eMRIterType iter_type, const eMRDataType data_flag)
static void mesh_render_data_lverts_bm(const MeshRenderData *mr, MeshBufferCache *cache, BMesh *bm)
static void mesh_render_data_ledges_bm(const MeshRenderData *mr, MeshBufferCache *cache, BMesh *bm)
static void mesh_render_data_mat_tri_len_mesh_range_fn(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict tls)
static int * mesh_render_data_mat_tri_len_build(MeshRenderData *mr)
static void mesh_render_data_polys_sorted_build(MeshRenderData *mr, MeshBufferCache *cache)
void mesh_render_data_free(MeshRenderData *mr)
static void mesh_render_data_mat_tri_len_bm_range_fn(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict tls)
MeshRenderData * mesh_render_data_create(Object *object, Mesh *me, const bool is_editmode, const bool is_paint_mode, const bool is_mode_active, const float obmat[4][4], const bool do_final, const bool do_uvedit, const ToolSettings *ts)
static void mesh_render_data_loose_geom_ensure(const MeshRenderData *mr, MeshBufferCache *cache)
static int * mesh_render_data_mat_tri_len_build_threaded(MeshRenderData *mr, int face_len, TaskParallelRangeFunc range_func)
static void mesh_render_data_mat_tri_len_reduce_fn(const void *__restrict userdata, void *__restrict chunk_join, void *__restrict chunk)
void mesh_render_data_update_loose_geom(MeshRenderData *mr, MeshBufferCache *cache, const eMRIterType iter_type, const eMRDataType data_flag)
static void mesh_render_data_loose_geom_mesh(const MeshRenderData *mr, MeshBufferCache *cache)
static void mesh_render_data_loose_geom_load(MeshRenderData *mr, MeshBufferCache *cache)
static void mesh_render_data_polys_sorted_ensure(MeshRenderData *mr, MeshBufferCache *cache)
static void mesh_render_data_polys_sorted_load(MeshRenderData *mr, const MeshBufferCache *cache)
void mesh_render_data_update_polys_sorted(MeshRenderData *mr, MeshBufferCache *cache, const eMRDataType data_flag)
void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_flag)
Extraction of Mesh data into VBO to feed to GPU.
BLI_INLINE const CustomData * mesh_cd_vdata_get_from_mesh(const Mesh *me)
@ MR_EXTRACT_BMESH
Definition: extract_mesh.hh:31
@ MR_EXTRACT_MESH
Definition: extract_mesh.hh:33
@ MR_EXTRACT_MAPPED
Definition: extract_mesh.hh:32
#define MIN_RANGE_LEN
Definition: extract_mesh.hh:24
BLI_INLINE const Mesh * editmesh_final_or_this(const Object *object, const Mesh *me)
Definition: extract_mesh.hh:99
BLI_INLINE const CustomData * mesh_cd_ldata_get_from_mesh(const Mesh *me)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
bool active
all scheduled work for the GPU.
struct BMLoop * l
Definition: bmesh_class.h:128
struct BMLoop *(* looptris)[3]
Definition: BKE_editmesh.h:48
struct BMesh * bm
Definition: BKE_editmesh.h:40
short mat_nr
Definition: bmesh_class.h:281
int len
Definition: bmesh_class.h:267
struct BMEdge * e
Definition: bmesh_class.h:97
int totvert
Definition: bmesh_class.h:297
CustomData vdata
Definition: bmesh_class.h:337
int totedge
Definition: bmesh_class.h:297
CustomData edata
Definition: bmesh_class.h:337
int totloop
Definition: bmesh_class.h:297
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
int totface
Definition: bmesh_class.h:297
float const (* polyNos)[3]
const float(* polyCos)[3]
float const (* vertexNos)[3]
const float(* vertexCos)[3]
unsigned int v1
unsigned int v2
short mat_nr
MeshExtractLooseGeom loose_geom
struct MeshBufferCache::@274 poly_sorted
eMRExtractType extract_type
Definition: extract_mesh.hh:37
BMVert * eve_act
Definition: extract_mesh.hh:78
const float(* bm_vert_normals)[3]
Definition: extract_mesh.hh:62
const float(* poly_normals)[3]
Definition: extract_mesh.hh:85
const MLoop * mloop
Definition: extract_mesh.hh:76
const float(* bm_poly_centers)[3]
Definition: extract_mesh.hh:64
BMEdge * eed_act
Definition: extract_mesh.hh:79
const int * v_origindex
Definition: extract_mesh.hh:66
const float(* vert_normals)[3]
Definition: extract_mesh.hh:84
const float(* bm_poly_normals)[3]
Definition: extract_mesh.hh:63
EditMeshData * edit_data
Definition: extract_mesh.hh:57
const char * default_color_name
Definition: extract_mesh.hh:90
BMFace * efa_act_uv
Definition: extract_mesh.hh:81
const MVert * mvert
Definition: extract_mesh.hh:74
float(* loop_normals)[3]
Definition: extract_mesh.hh:86
const float(* bm_vert_coords)[3]
Definition: extract_mesh.hh:61
const ToolSettings * toolsettings
Definition: extract_mesh.hh:53
const char * active_color_name
Definition: extract_mesh.hh:89
const MPoly * mpoly
Definition: extract_mesh.hh:77
MLoopTri * mlooptri
Definition: extract_mesh.hh:83
struct MeshRenderData::@319 poly_sorted
BMEditMesh * edit_bmesh
Definition: extract_mesh.hh:55
const int * p_origindex
Definition: extract_mesh.hh:66
BMFace * efa_act
Definition: extract_mesh.hh:80
const MEdge * medge
Definition: extract_mesh.hh:75
int * tri_first_index
Definition: extract_mesh.hh:93
const int * e_origindex
Definition: extract_mesh.hh:66
float obmat[4][4]
Definition: extract_mesh.hh:51
struct EditMeshData * edit_data
struct MEdge * medge
struct BMEditMesh * edit_mesh
float smoothresh
CustomData vdata
struct MVert * mvert
uint16_t flag
int totedge
int totvert
struct MLoop * mloop
Mesh_Runtime runtime
CustomData pdata
int totpoly
CustomData edata
int totloop
struct MPoly * mpoly
CustomData ldata
TaskParallelReduceFunc func_reduce
Definition: BLI_task.h:181
size_t userdata_chunk_size
Definition: BLI_task.h:169