Blender  V3.3
mesh.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 /* Allow using deprecated functionality for .blend file I/O. */
11 #define DNA_DEPRECATED_ALLOW
12 
13 #include "DNA_defaults.h"
14 #include "DNA_key_types.h"
15 #include "DNA_material_types.h"
16 #include "DNA_mesh_types.h"
17 #include "DNA_meshdata_types.h"
18 #include "DNA_object_types.h"
19 
20 #include "BLI_bitmap.h"
21 #include "BLI_edgehash.h"
22 #include "BLI_endian_switch.h"
23 #include "BLI_ghash.h"
24 #include "BLI_hash.h"
25 #include "BLI_index_range.hh"
26 #include "BLI_linklist.h"
27 #include "BLI_listbase.h"
28 #include "BLI_math.h"
29 #include "BLI_math_vector.hh"
30 #include "BLI_memarena.h"
31 #include "BLI_string.h"
32 #include "BLI_task.hh"
33 #include "BLI_utildefines.h"
34 #include "BLI_vector.hh"
35 
36 #include "BLT_translation.h"
37 
38 #include "BKE_anim_data.h"
39 #include "BKE_bpath.h"
40 #include "BKE_deform.h"
41 #include "BKE_editmesh.h"
42 #include "BKE_global.h"
43 #include "BKE_idtype.h"
44 #include "BKE_key.h"
45 #include "BKE_lib_id.h"
46 #include "BKE_lib_query.h"
47 #include "BKE_main.h"
48 #include "BKE_material.h"
49 #include "BKE_mesh.h"
51 #include "BKE_mesh_runtime.h"
52 #include "BKE_mesh_wrapper.h"
53 #include "BKE_modifier.h"
54 #include "BKE_multires.h"
55 #include "BKE_object.h"
56 
57 #include "PIL_time.h"
58 
59 #include "DEG_depsgraph.h"
60 #include "DEG_depsgraph_query.h"
61 
62 #include "BLO_read_write.h"
63 
64 using blender::float3;
65 using blender::Vector;
66 
67 static void mesh_clear_geometry(Mesh *mesh);
68 static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata);
69 
70 static void mesh_init_data(ID *id)
71 {
72  Mesh *mesh = (Mesh *)id;
73 
75 
77 
83 
85 
86  /* A newly created mesh does not have normals, so tag them dirty. This will be cleared
87  * by #BKE_mesh_vertex_normals_clear_dirty or #BKE_mesh_poly_normals_ensure. */
89 
91 }
92 
93 static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
94 {
95  Mesh *mesh_dst = (Mesh *)id_dst;
96  const Mesh *mesh_src = (const Mesh *)id_src;
97 
98  BKE_mesh_runtime_reset_on_copy(mesh_dst, flag);
99  /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier
100  * or node, but we still need to be able to draw face center vertices. */
101  mesh_dst->runtime.subsurf_face_dot_tags = static_cast<uint32_t *>(
103  if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) {
104  /* This is a direct copy of a main mesh, so for now it has the same topology. */
105  mesh_dst->runtime.deformed_only = true;
106  }
107  /* This option is set for run-time meshes that have been copied from the current objects mode.
108  * Currently this is used for edit-mesh although it could be used for sculpt or other
109  * kinds of data specific to an objects mode.
110  *
111  * The flag signals that the mesh hasn't been modified from the data that generated it,
112  * allowing us to use the object-mode data for drawing.
113  *
114  * While this could be the callers responsibility, keep here since it's
115  * highly unlikely we want to create a duplicate and not use it for drawing. */
116  mesh_dst->runtime.is_original = false;
117 
118  /* Only do tessface if we have no polys. */
119  const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0));
120 
122 
123  if (mesh_src->id.tag & LIB_TAG_NO_MAIN) {
124  /* For copies in depsgraph, keep data like #CD_ORIGINDEX and #CD_ORCO. */
126  }
127 
128  mesh_dst->mat = (Material **)MEM_dupallocN(mesh_src->mat);
129 
131 
132  const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
133  CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert);
134  CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, alloc_type, mesh_dst->totedge);
135  CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, alloc_type, mesh_dst->totloop);
136  CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, alloc_type, mesh_dst->totpoly);
137  if (do_tessface) {
138  CustomData_copy(&mesh_src->fdata, &mesh_dst->fdata, mask.fmask, alloc_type, mesh_dst->totface);
139  }
140  else {
141  mesh_tessface_clear_intern(mesh_dst, false);
142  }
143 
144  BKE_mesh_update_customdata_pointers(mesh_dst, do_tessface);
145 
146  mesh_dst->cd_flag = mesh_src->cd_flag;
147 
148  mesh_dst->edit_mesh = nullptr;
149 
150  mesh_dst->mselect = (MSelect *)MEM_dupallocN(mesh_dst->mselect);
151 
152  /* Set normal layers dirty. They should be dirty by default on new meshes anyway, but being
153  * explicit about it is safer. Alternatively normal layers could be copied if they aren't dirty,
154  * avoiding recomputation in some cases. However, a copied mesh is often changed anyway, so that
155  * idea is not clearly better. With proper reference counting, all custom data layers could be
156  * copied as the cost would be much lower. */
157  BKE_mesh_normals_tag_dirty(mesh_dst);
158 
159  /* TODO: Do we want to add flag to prevent this? */
160  if (mesh_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
161  BKE_id_copy_ex(bmain, &mesh_src->key->id, (ID **)&mesh_dst->key, flag);
162  /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
163  mesh_dst->key->from = &mesh_dst->id;
164  }
165 
167 }
168 
170 {
171  if (mesh->edit_mesh == nullptr) {
172  return;
173  }
174 
175  if (mesh->edit_mesh->is_shallow_copy == false) {
177  }
179  mesh->edit_mesh = nullptr;
180 }
181 
182 static void mesh_free_data(ID *id)
183 {
184  Mesh *mesh = (Mesh *)id;
185 
187 
189 
193 }
194 
196 {
197  Mesh *mesh = (Mesh *)id;
200  for (int i = 0; i < mesh->totcol; i++) {
202  }
203 }
204 
205 static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data)
206 {
207  Mesh *me = (Mesh *)id;
208  if (me->ldata.external) {
210  }
211 }
212 
213 static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address)
214 {
215  Mesh *mesh = (Mesh *)id;
216  const bool is_undo = BLO_write_is_undo(writer);
217 
218  Vector<CustomDataLayer, 16> vert_layers;
219  Vector<CustomDataLayer, 16> edge_layers;
220  Vector<CustomDataLayer, 16> loop_layers;
221  Vector<CustomDataLayer, 16> poly_layers;
222 
223  /* cache only - don't write */
224  mesh->mface = nullptr;
225  mesh->totface = 0;
226  memset(&mesh->fdata, 0, sizeof(mesh->fdata));
227  mesh->runtime = blender::dna::shallow_zero_initialize();
228 
229  /* Do not store actual geometry data in case this is a library override ID. */
230  if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) {
231  mesh->mvert = nullptr;
232  mesh->totvert = 0;
233  memset(&mesh->vdata, 0, sizeof(mesh->vdata));
234 
235  mesh->medge = nullptr;
236  mesh->totedge = 0;
237  memset(&mesh->edata, 0, sizeof(mesh->edata));
238 
239  mesh->mloop = nullptr;
240  mesh->totloop = 0;
241  memset(&mesh->ldata, 0, sizeof(mesh->ldata));
242 
243  mesh->mpoly = nullptr;
244  mesh->totpoly = 0;
245  memset(&mesh->pdata, 0, sizeof(mesh->pdata));
246  }
247  else {
252  }
253 
254  BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
255  BKE_id_blend_write(writer, &mesh->id);
256 
257  /* direct data */
258  if (mesh->adt) {
260  }
261 
263 
265  BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
266 
268  writer, &mesh->vdata, vert_layers, mesh->totvert, CD_MASK_MESH.vmask, &mesh->id);
270  writer, &mesh->edata, edge_layers, mesh->totedge, CD_MASK_MESH.emask, &mesh->id);
271  /* fdata is really a dummy - written so slots align */
274  writer, &mesh->ldata, loop_layers, mesh->totloop, CD_MASK_MESH.lmask, &mesh->id);
276  writer, &mesh->pdata, poly_layers, mesh->totpoly, CD_MASK_MESH.pmask, &mesh->id);
277 }
278 
279 static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
280 {
281  Mesh *mesh = (Mesh *)id;
282  BLO_read_pointer_array(reader, (void **)&mesh->mat);
283 
284  BLO_read_data_address(reader, &mesh->mvert);
285  BLO_read_data_address(reader, &mesh->medge);
286  BLO_read_data_address(reader, &mesh->mface);
287  BLO_read_data_address(reader, &mesh->mloop);
288  BLO_read_data_address(reader, &mesh->mpoly);
289  BLO_read_data_address(reader, &mesh->tface);
290  BLO_read_data_address(reader, &mesh->mtface);
291  BLO_read_data_address(reader, &mesh->mcol);
292  BLO_read_data_address(reader, &mesh->dvert);
296 
297  /* animdata */
298  BLO_read_data_address(reader, &mesh->adt);
300 
301  /* Normally BKE_defvert_blend_read should be called in CustomData_blend_read,
302  * but for backwards compatibility in do_versions to work we do it here. */
305 
311 
313  mesh->edit_mesh = nullptr;
314 
315  mesh->runtime = blender::dna::shallow_zero_initialize();
317 
318  /* happens with old files */
319  if (mesh->mselect == nullptr) {
320  mesh->totselect = 0;
321  }
322 
323  if (BLO_read_requires_endian_switch(reader) && mesh->tface) {
324  TFace *tf = mesh->tface;
325  for (int i = 0; i < mesh->totface; i++, tf++) {
326  BLI_endian_switch_uint32_array(tf->col, 4);
327  }
328  }
329 
330  /* We don't expect to load normals from files, since they are derived data. */
333 }
334 
335 static void mesh_blend_read_lib(BlendLibReader *reader, ID *id)
336 {
337  Mesh *me = (Mesh *)id;
338  /* this check added for python created meshes */
339  if (me->mat) {
340  for (int i = 0; i < me->totcol; i++) {
341  BLO_read_id_address(reader, me->id.lib, &me->mat[i]);
342  }
343  }
344  else {
345  me->totcol = 0;
346  }
347 
348  BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys
349  BLO_read_id_address(reader, me->id.lib, &me->key);
350  BLO_read_id_address(reader, me->id.lib, &me->texcomesh);
351 }
352 
353 static void mesh_read_expand(BlendExpander *expander, ID *id)
354 {
355  Mesh *me = (Mesh *)id;
356  for (int a = 0; a < me->totcol; a++) {
357  BLO_expand(expander, me->mat[a]);
358  }
359 
360  BLO_expand(expander, me->key);
361  BLO_expand(expander, me->texcomesh);
362 }
363 
365  /* id_code */ ID_ME,
366  /* id_filter */ FILTER_ID_ME,
367  /* main_listbase_index */ INDEX_ID_ME,
368  /* struct_size */ sizeof(Mesh),
369  /* name */ "Mesh",
370  /* name_plural */ "meshes",
371  /* translation_context */ BLT_I18NCONTEXT_ID_MESH,
373  /* asset_type_info */ nullptr,
374 
375  /* init_data */ mesh_init_data,
376  /* copy_data */ mesh_copy_data,
377  /* free_data */ mesh_free_data,
378  /* make_local */ nullptr,
379  /* foreach_id */ mesh_foreach_id,
380  /* foreach_cache */ nullptr,
381  /* foreach_path */ mesh_foreach_path,
382  /* owner_get */ nullptr,
383 
384  /* blend_write */ mesh_blend_write,
385  /* blend_read_data */ mesh_blend_read_data,
386  /* blend_read_lib */ mesh_blend_read_lib,
387  /* blend_read_expand */ mesh_read_expand,
388 
389  /* blend_read_undo_preserve */ nullptr,
390 
391  /* lib_override_apply_post */ nullptr,
392 };
393 
394 enum {
407 };
408 
409 static const char *cmpcode_to_str(int code)
410 {
411  switch (code) {
413  return "Vertex Weight Mismatch";
415  return "Vertex Group Mismatch";
417  return "Vertex Doesn't Belong To Same Number Of Groups";
419  return "Color Attribute Mismatch";
421  return "UV Mismatch";
423  return "Loop Mismatch";
425  return "Loop Vert Mismatch In Poly Test";
427  return "Loop Vert Mismatch";
428  case MESHCMP_EDGEUNKNOWN:
429  return "Edge Mismatch";
431  return "Vertex Coordinate Mismatch";
433  return "CustomData Layer Count Mismatch";
435  return "Attribute Value Mismatch";
436  default:
437  return "Mesh Comparison Code Unknown";
438  }
439 }
440 
443  CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh)
444 {
445  const float thresh_sq = thresh * thresh;
446  CustomDataLayer *l1, *l2;
447  int layer_count1 = 0, layer_count2 = 0, j;
448  const uint64_t cd_mask_non_generic = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MPOLY |
451  const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic;
452 
453  for (int i = 0; i < c1->totlayer; i++) {
454  l1 = &c1->layers[i];
455  if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr) {
456  layer_count1++;
457  }
458  }
459 
460  for (int i = 0; i < c2->totlayer; i++) {
461  l2 = &c2->layers[i];
462  if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr) {
463  layer_count2++;
464  }
465  }
466 
467  if (layer_count1 != layer_count2) {
469  }
470 
471  l1 = c1->layers;
472  l2 = c2->layers;
473 
474  for (int i1 = 0; i1 < c1->totlayer; i1++) {
475  l1 = c1->layers + i1;
476  for (int i2 = 0; i2 < c2->totlayer; i2++) {
477  l2 = c2->layers + i2;
478  if (l1->type != l2->type || !STREQ(l1->name, l2->name) || l1->anonymous_id != nullptr ||
479  l2->anonymous_id != nullptr) {
480  continue;
481  }
482  /* At this point `l1` and `l2` have the same name and type, so they should be compared. */
483 
484  switch (l1->type) {
485 
486  case CD_MVERT: {
487  MVert *v1 = (MVert *)l1->data;
488  MVert *v2 = (MVert *)l2->data;
489  int vtot = m1->totvert;
490 
491  for (j = 0; j < vtot; j++, v1++, v2++) {
492  for (int k = 0; k < 3; k++) {
493  if (compare_threshold_relative(v1->co[k], v2->co[k], thresh)) {
494  return MESHCMP_VERTCOMISMATCH;
495  }
496  }
497  }
498  break;
499  }
500 
501  /* We're order-agnostic for edges here. */
502  case CD_MEDGE: {
503  MEdge *e1 = (MEdge *)l1->data;
504  MEdge *e2 = (MEdge *)l2->data;
505  int etot = m1->totedge;
506  EdgeHash *eh = BLI_edgehash_new_ex(__func__, etot);
507 
508  for (j = 0; j < etot; j++, e1++) {
509  BLI_edgehash_insert(eh, e1->v1, e1->v2, e1);
510  }
511 
512  for (j = 0; j < etot; j++, e2++) {
513  if (!BLI_edgehash_lookup(eh, e2->v1, e2->v2)) {
514  return MESHCMP_EDGEUNKNOWN;
515  }
516  }
517  BLI_edgehash_free(eh, nullptr);
518  break;
519  }
520  case CD_MPOLY: {
521  MPoly *p1 = (MPoly *)l1->data;
522  MPoly *p2 = (MPoly *)l2->data;
523  int ptot = m1->totpoly;
524 
525  for (j = 0; j < ptot; j++, p1++, p2++) {
526  MLoop *lp1, *lp2;
527  int k;
528 
529  if (p1->totloop != p2->totloop) {
530  return MESHCMP_POLYMISMATCH;
531  }
532 
533  lp1 = m1->mloop + p1->loopstart;
534  lp2 = m2->mloop + p2->loopstart;
535 
536  for (k = 0; k < p1->totloop; k++, lp1++, lp2++) {
537  if (lp1->v != lp2->v) {
539  }
540  }
541  }
542  break;
543  }
544  case CD_MLOOP: {
545  MLoop *lp1 = (MLoop *)l1->data;
546  MLoop *lp2 = (MLoop *)l2->data;
547  int ltot = m1->totloop;
548 
549  for (j = 0; j < ltot; j++, lp1++, lp2++) {
550  if (lp1->v != lp2->v) {
551  return MESHCMP_LOOPMISMATCH;
552  }
553  }
554  break;
555  }
556  case CD_MLOOPUV: {
557  MLoopUV *lp1 = (MLoopUV *)l1->data;
558  MLoopUV *lp2 = (MLoopUV *)l2->data;
559  int ltot = m1->totloop;
560 
561  for (j = 0; j < ltot; j++, lp1++, lp2++) {
562  if (len_squared_v2v2(lp1->uv, lp2->uv) > thresh_sq) {
563  return MESHCMP_LOOPUVMISMATCH;
564  }
565  }
566  break;
567  }
568  case CD_PROP_BYTE_COLOR: {
569  MLoopCol *lp1 = (MLoopCol *)l1->data;
570  MLoopCol *lp2 = (MLoopCol *)l2->data;
571  int ltot = m1->totloop;
572 
573  for (j = 0; j < ltot; j++, lp1++, lp2++) {
574  if (lp1->r != lp2->r || lp1->g != lp2->g || lp1->b != lp2->b || lp1->a != lp2->a) {
576  }
577  }
578  break;
579  }
580  case CD_MDEFORMVERT: {
581  MDeformVert *dv1 = (MDeformVert *)l1->data;
582  MDeformVert *dv2 = (MDeformVert *)l2->data;
583  int dvtot = m1->totvert;
584 
585  for (j = 0; j < dvtot; j++, dv1++, dv2++) {
586  int k;
587  MDeformWeight *dw1 = dv1->dw, *dw2 = dv2->dw;
588 
589  if (dv1->totweight != dv2->totweight) {
591  }
592 
593  for (k = 0; k < dv1->totweight; k++, dw1++, dw2++) {
594  if (dw1->def_nr != dw2->def_nr) {
596  }
597  if (fabsf(dw1->weight - dw2->weight) > thresh) {
599  }
600  }
601  }
602  break;
603  }
604  case CD_PROP_FLOAT: {
605  const float *l1_data = (float *)l1->data;
606  const float *l2_data = (float *)l2->data;
607 
608  for (int i = 0; i < total_length; i++) {
609  if (compare_threshold_relative(l1_data[i], l2_data[i], thresh)) {
611  }
612  }
613  break;
614  }
615  case CD_PROP_FLOAT2: {
616  const float(*l1_data)[2] = (float(*)[2])l1->data;
617  const float(*l2_data)[2] = (float(*)[2])l2->data;
618 
619  for (int i = 0; i < total_length; i++) {
620  if (compare_threshold_relative(l1_data[i][0], l2_data[i][0], thresh)) {
622  }
623  if (compare_threshold_relative(l1_data[i][1], l2_data[i][1], thresh)) {
625  }
626  }
627  break;
628  }
629  case CD_PROP_FLOAT3: {
630  const float(*l1_data)[3] = (float(*)[3])l1->data;
631  const float(*l2_data)[3] = (float(*)[3])l2->data;
632 
633  for (int i = 0; i < total_length; i++) {
634  if (compare_threshold_relative(l1_data[i][0], l2_data[i][0], thresh)) {
636  }
637  if (compare_threshold_relative(l1_data[i][1], l2_data[i][1], thresh)) {
639  }
640  if (compare_threshold_relative(l1_data[i][2], l2_data[i][2], thresh)) {
642  }
643  }
644  break;
645  }
646  case CD_PROP_INT32: {
647  const int *l1_data = (int *)l1->data;
648  const int *l2_data = (int *)l2->data;
649 
650  for (int i = 0; i < total_length; i++) {
651  if (l1_data[i] != l2_data[i]) {
653  }
654  }
655  break;
656  }
657  case CD_PROP_INT8: {
658  const int8_t *l1_data = (int8_t *)l1->data;
659  const int8_t *l2_data = (int8_t *)l2->data;
660 
661  for (int i = 0; i < total_length; i++) {
662  if (l1_data[i] != l2_data[i]) {
664  }
665  }
666  break;
667  }
668  case CD_PROP_BOOL: {
669  const bool *l1_data = (bool *)l1->data;
670  const bool *l2_data = (bool *)l2->data;
671 
672  for (int i = 0; i < total_length; i++) {
673  if (l1_data[i] != l2_data[i]) {
675  }
676  }
677  break;
678  }
679  case CD_PROP_COLOR: {
680  const MPropCol *l1_data = (MPropCol *)l1->data;
681  const MPropCol *l2_data = (MPropCol *)l2->data;
682 
683  for (int i = 0; i < total_length; i++) {
684  for (j = 0; j < 4; j++) {
685  if (compare_threshold_relative(l1_data[i].color[j], l2_data[i].color[j], thresh)) {
687  }
688  }
689  }
690  break;
691  }
692  default: {
693  break;
694  }
695  }
696  }
697  }
698 
699  return 0;
700 }
701 
702 const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
703 {
704  int c;
705 
706  if (!me1 || !me2) {
707  return "Requires two input meshes";
708  }
709 
710  if (me1->totvert != me2->totvert) {
711  return "Number of verts don't match";
712  }
713 
714  if (me1->totedge != me2->totedge) {
715  return "Number of edges don't match";
716  }
717 
718  if (me1->totpoly != me2->totpoly) {
719  return "Number of faces don't match";
720  }
721 
722  if (me1->totloop != me2->totloop) {
723  return "Number of loops don't match";
724  }
725 
726  if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1->totvert, me1, me2, thresh))) {
727  return cmpcode_to_str(c);
728  }
729 
730  if ((c = customdata_compare(&me1->edata, &me2->edata, me1->totedge, me1, me2, thresh))) {
731  return cmpcode_to_str(c);
732  }
733 
734  if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1->totloop, me1, me2, thresh))) {
735  return cmpcode_to_str(c);
736  }
737 
738  if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1->totpoly, me1, me2, thresh))) {
739  return cmpcode_to_str(c);
740  }
741 
742  return nullptr;
743 }
744 
746 {
747  if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
748  /* Pass, otherwise this function clears 'mface' before
749  * versioning 'mface -> mpoly' code kicks in T30583.
750  *
751  * Callers could also check but safer to do here - campbell */
752  }
753  else {
754  const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
755  const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
756 
757  const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
758  const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
759 
760  if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
762 
763  BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
764 
765  /* TODO: add some `--debug-mesh` option. */
766  if (G.debug & G_DEBUG) {
767  /* NOTE(campbell): this warning may be un-called for if we are initializing the mesh for
768  * the first time from #BMesh, rather than giving a warning about this we could be smarter
769  * and check if there was any data to begin with, for now just print the warning with
770  * some info to help troubleshoot what's going on. */
771  printf(
772  "%s: warning! Tessellation uvs or vcol data got out of sync, "
773  "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
774  "CD_PROP_BYTE_COLOR: "
775  "%d\n",
776  __func__,
777  tottex_tessface,
778  tottex_original,
779  totcol_tessface,
780  totcol_original);
781  }
782  }
783  }
784 }
785 
787 {
788  BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
789  MVertSkin *vs;
790 
791  if (bm) {
793  BMVert *v;
794  BMIter iter;
795 
797 
798  /* Mark an arbitrary vertex as root */
799  BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
801  vs->flag |= MVERT_SKIN_ROOT;
802  break;
803  }
804  }
805  }
806  else {
809  &me->vdata, CD_MVERT_SKIN, CD_DEFAULT, nullptr, me->totvert);
810 
811  /* Mark an arbitrary vertex as root */
812  if (vs) {
813  vs->flag |= MVERT_SKIN_ROOT;
814  }
815  }
816  }
817 }
818 
820 {
821  BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
822  bool changed = false;
823  if (bm) {
826  changed = true;
827  }
828  }
829  else {
830  if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
832  changed = true;
833  }
834  }
835  return changed;
836 }
837 
839 {
840  BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
841  bool changed = false;
842  if (bm) {
845  changed = true;
846  }
847  }
848  else {
851  changed = true;
852  }
853  }
854  return changed;
855 }
856 
865 static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
866 {
867  if (do_ensure_tess_cd) {
869  }
870 
872 }
873 
874 void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
875 {
876  mesh_update_linked_customdata(me, do_ensure_tess_cd);
877 
880 
882 
884  me->mcol = (MCol *)CustomData_get_layer(&me->fdata, CD_MCOL);
886 
889 
892 }
893 
895 {
896  if (me->edit_mesh) {
898  }
899 
901 }
902 
904 {
905  mesh_free_data(&me->id);
906 }
907 
921 {
927 
929 
930  mesh->totvert = 0;
931  mesh->totedge = 0;
932  mesh->totface = 0;
933  mesh->totloop = 0;
934  mesh->totpoly = 0;
935  mesh->act_face = -1;
936  mesh->totselect = 0;
937 
939 }
940 
942 {
943  BKE_animdata_free(&mesh->id, false);
946 }
947 
948 static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
949 {
950  if (free_customdata) {
952  }
953  else {
955  }
956 
957  mesh->mface = nullptr;
958  mesh->mtface = nullptr;
959  mesh->mcol = nullptr;
960  mesh->totface = 0;
961 }
962 
963 Mesh *BKE_mesh_add(Main *bmain, const char *name)
964 {
965  Mesh *me = (Mesh *)BKE_id_new(bmain, ID_ME, name);
966 
967  return me;
968 }
969 
970 /* Custom data layer functions; those assume that totXXX are set correctly. */
971 static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
972 {
975  }
978  }
981  }
984  }
985 
986  if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_MFACE)) {
988  }
989 }
990 
992  int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
993 {
997 
998  /* Don't use #CustomData_reset because we don't want to touch custom-data. */
1004 
1005  mesh->totvert = verts_len;
1006  mesh->totedge = edges_len;
1007  mesh->totface = tessface_len;
1008  mesh->totloop = loops_len;
1009  mesh->totpoly = polys_len;
1010 
1013 
1014  return mesh;
1015 }
1016 
1017 void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
1018 {
1019  /* Copy general settings. */
1020  me_dst->editflag = me_src->editflag;
1021  me_dst->flag = me_src->flag;
1022  me_dst->smoothresh = me_src->smoothresh;
1023  me_dst->remesh_voxel_size = me_src->remesh_voxel_size;
1025  me_dst->remesh_mode = me_src->remesh_mode;
1026  me_dst->symmetry = me_src->symmetry;
1027 
1028  me_dst->face_sets_color_seed = me_src->face_sets_color_seed;
1030 
1031  /* Copy texture space. */
1032  me_dst->texflag = me_src->texflag;
1033  copy_v3_v3(me_dst->loc, me_src->loc);
1034  copy_v3_v3(me_dst->size, me_src->size);
1035 
1037 }
1038 
1039 void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
1040 {
1041  /* User counts aren't handled, don't copy into a mesh from #G_MAIN. */
1043 
1044  BKE_mesh_copy_parameters(me_dst, me_src);
1045 
1047 
1048  /* Copy vertex group names. */
1051 
1052  /* Copy materials. */
1053  if (me_dst->mat != nullptr) {
1054  MEM_freeN(me_dst->mat);
1055  }
1056  me_dst->mat = (Material **)MEM_dupallocN(me_src->mat);
1057  me_dst->totcol = me_src->totcol;
1058 }
1059 
1061  int verts_len,
1062  int edges_len,
1063  int tessface_len,
1064  int loops_len,
1065  int polys_len,
1067 {
1068  /* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
1069  const bool do_tessface = (tessface_len || ((me_src->totface != 0) && (me_src->totpoly == 0)));
1070 
1071  Mesh *me_dst = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
1072 
1073  me_dst->mselect = (MSelect *)MEM_dupallocN(me_src->mselect);
1074 
1075  me_dst->totvert = verts_len;
1076  me_dst->totedge = edges_len;
1077  me_dst->totface = tessface_len;
1078  me_dst->totloop = loops_len;
1079  me_dst->totpoly = polys_len;
1080 
1081  me_dst->cd_flag = me_src->cd_flag;
1082  BKE_mesh_copy_parameters_for_eval(me_dst, me_src);
1083 
1084  CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_CALLOC, verts_len);
1085  CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_CALLOC, edges_len);
1086  CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_CALLOC, loops_len);
1087  CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_CALLOC, polys_len);
1088  if (do_tessface) {
1089  CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, CD_CALLOC, tessface_len);
1090  }
1091  else {
1092  mesh_tessface_clear_intern(me_dst, false);
1093  }
1094 
1095  /* The destination mesh should at least have valid primary CD layers,
1096  * even in cases where the source mesh does not. */
1097  mesh_ensure_cdlayers_primary(me_dst, do_tessface);
1098  BKE_mesh_update_customdata_pointers(me_dst, false);
1099 
1100  /* Expect that normals aren't copied at all, since the destination mesh is new. */
1102 
1103  return me_dst;
1104 }
1105 
1107  int verts_len,
1108  int edges_len,
1109  int tessface_len,
1110  int loops_len,
1111  int polys_len)
1112 {
1114  me_src, verts_len, edges_len, tessface_len, loops_len, polys_len, CD_MASK_EVERYTHING);
1115 }
1116 
1117 void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
1118 {
1119  /* Evaluated mesh may point to edit mesh, but never owns it. */
1120  mesh_eval->edit_mesh = nullptr;
1121  mesh_free_data(&mesh_eval->id);
1122  BKE_libblock_free_data(&mesh_eval->id, false);
1123  MEM_freeN(mesh_eval);
1124 }
1125 
1126 Mesh *BKE_mesh_copy_for_eval(const Mesh *source, bool reference)
1127 {
1128  int flags = LIB_ID_COPY_LOCALIZE;
1129 
1130  if (reference) {
1131  flags |= LIB_ID_COPY_CD_REFERENCE;
1132  }
1133 
1134  Mesh *result = (Mesh *)BKE_id_copy_ex(nullptr, &source->id, nullptr, flags);
1135  return result;
1136 }
1137 
1139  const struct BMeshCreateParams *create_params,
1140  const struct BMeshFromMeshParams *convert_params)
1141 {
1142  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
1143 
1144  BMesh *bm = BM_mesh_create(&allocsize, create_params);
1145  BM_mesh_bm_from_me(bm, me, convert_params);
1146 
1147  return bm;
1148 }
1149 
1151  Object *ob,
1152  const bool add_key_index,
1153  const struct BMeshCreateParams *params)
1154 {
1155  BMeshFromMeshParams bmesh_from_mesh_params{};
1156  bmesh_from_mesh_params.calc_face_normal = false;
1157  bmesh_from_mesh_params.calc_vert_normal = false;
1158  bmesh_from_mesh_params.add_key_index = add_key_index;
1159  bmesh_from_mesh_params.use_shapekey = true;
1160  bmesh_from_mesh_params.active_shapekey = ob->shapenr;
1161  return BKE_mesh_to_bmesh_ex(me, params, &bmesh_from_mesh_params);
1162 }
1163 
1165  const struct BMeshToMeshParams *params,
1166  const Mesh *me_settings)
1167 {
1168  BLI_assert(params->calc_object_remap == false);
1169  Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
1170  BM_mesh_bm_to_me(nullptr, bm, mesh, params);
1172  return mesh;
1173 }
1174 
1176  const CustomData_MeshMasks *cd_mask_extra,
1177  const Mesh *me_settings)
1178 {
1179  Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
1180  BM_mesh_bm_to_me_for_eval(bm, mesh, cd_mask_extra);
1182  return mesh;
1183 }
1184 
1186 {
1188  return;
1189  }
1190  int *indices = (int *)CustomData_add_layer(&data, CD_ORIGINDEX, CD_DEFAULT, nullptr, size);
1191  range_vn_i(indices, size, 0);
1192 }
1193 
1195 {
1198 }
1199 
1201 {
1205 }
1206 
1208 {
1209  /* This is Object-level data access,
1210  * DO NOT touch to Mesh's bb, would be totally thread-unsafe. */
1211  if (ob->runtime.bb == nullptr || ob->runtime.bb->flag & BOUNDBOX_DIRTY) {
1212  Mesh *me = (Mesh *)ob->data;
1213  float min[3], max[3];
1214 
1215  INIT_MINMAX(min, max);
1216  if (!BKE_mesh_wrapper_minmax(me, min, max)) {
1217  min[0] = min[1] = min[2] = -1.0f;
1218  max[0] = max[1] = max[2] = 1.0f;
1219  }
1220 
1221  if (ob->runtime.bb == nullptr) {
1222  ob->runtime.bb = (BoundBox *)MEM_mallocN(sizeof(*ob->runtime.bb), __func__);
1223  }
1225  ob->runtime.bb->flag &= ~BOUNDBOX_DIRTY;
1226  }
1227 
1228  return ob->runtime.bb;
1229 }
1230 
1232 {
1233  if (me->texflag & ME_AUTOSPACE) {
1234  float min[3], max[3];
1235 
1236  INIT_MINMAX(min, max);
1237  if (!BKE_mesh_wrapper_minmax(me, min, max)) {
1238  min[0] = min[1] = min[2] = -1.0f;
1239  max[0] = max[1] = max[2] = 1.0f;
1240  }
1241 
1242  float loc[3], size[3];
1243  mid_v3_v3v3(loc, min, max);
1244 
1245  size[0] = (max[0] - min[0]) / 2.0f;
1246  size[1] = (max[1] - min[1]) / 2.0f;
1247  size[2] = (max[2] - min[2]) / 2.0f;
1248 
1249  for (int a = 0; a < 3; a++) {
1250  if (size[a] == 0.0f) {
1251  size[a] = 1.0f;
1252  }
1253  else if (size[a] > 0.0f && size[a] < 0.00001f) {
1254  size[a] = 0.00001f;
1255  }
1256  else if (size[a] < 0.0f && size[a] > -0.00001f) {
1257  size[a] = -0.00001f;
1258  }
1259  }
1260 
1261  copy_v3_v3(me->loc, loc);
1262  copy_v3_v3(me->size, size);
1263 
1265  }
1266 }
1267 
1269 {
1270  if ((me->texflag & ME_AUTOSPACE) && !(me->texflag & ME_AUTOSPACE_EVALUATED)) {
1272  }
1273 }
1274 
1275 void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_size[3])
1276 {
1278 
1279  if (r_loc) {
1280  copy_v3_v3(r_loc, me->loc);
1281  }
1282  if (r_size) {
1283  copy_v3_v3(r_size, me->size);
1284  }
1285 }
1286 
1287 void BKE_mesh_texspace_get_reference(Mesh *me, char **r_texflag, float **r_loc, float **r_size)
1288 {
1290 
1291  if (r_texflag != nullptr) {
1292  *r_texflag = &me->texflag;
1293  }
1294  if (r_loc != nullptr) {
1295  *r_loc = me->loc;
1296  }
1297  if (r_size != nullptr) {
1298  *r_size = me->size;
1299  }
1300 }
1301 
1303 {
1304  float *texloc, *texsize;
1305  char *texflag;
1306 
1307  if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize)) {
1308  me->texflag = *texflag;
1309  copy_v3_v3(me->loc, texloc);
1310  copy_v3_v3(me->size, texsize);
1311  }
1312 }
1313 
1315 {
1316  Mesh *me = (Mesh *)ob->data;
1317  Mesh *tme = me->texcomesh ? me->texcomesh : me;
1318 
1319  /* Get appropriate vertex coordinates */
1320  float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(me->totvert, sizeof(*vcos), "orco mesh");
1321  MVert *mvert = tme->mvert;
1322  int totvert = min_ii(tme->totvert, me->totvert);
1323 
1324  for (int a = 0; a < totvert; a++, mvert++) {
1325  copy_v3_v3(vcos[a], mvert->co);
1326  }
1327 
1328  return vcos;
1329 }
1330 
1331 void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
1332 {
1333  float loc[3], size[3];
1334 
1335  BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, size);
1336 
1337  if (invert) {
1338  for (int a = 0; a < totvert; a++) {
1339  float *co = orco[a];
1340  madd_v3_v3v3v3(co, loc, co, size);
1341  }
1342  }
1343  else {
1344  for (int a = 0; a < totvert; a++) {
1345  float *co = orco[a];
1346  co[0] = (co[0] - loc[0]) / size[0];
1347  co[1] = (co[1] - loc[1]) / size[1];
1348  co[2] = (co[2] - loc[2]) / size[2];
1349  }
1350  }
1351 }
1352 
1354 {
1356  return;
1357  }
1358 
1359  /* Orcos are stored in normalized 0..1 range by convention. */
1360  float(*orcodata)[3] = BKE_mesh_orco_verts_get(ob);
1361  BKE_mesh_orco_verts_transform(mesh, orcodata, mesh->totvert, false);
1363 }
1364 
1366 {
1367  if (ob == nullptr) {
1368  return nullptr;
1369  }
1370  if (ob->type == OB_MESH) {
1371  return (Mesh *)ob->data;
1372  }
1373 
1374  return nullptr;
1375 }
1376 
1377 void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me)
1378 {
1379  Mesh *old = nullptr;
1380 
1381  if (ob == nullptr) {
1382  return;
1383  }
1384 
1386 
1387  if (ob->type == OB_MESH) {
1388  old = (Mesh *)ob->data;
1389  if (old) {
1390  id_us_min(&old->id);
1391  }
1392  ob->data = me;
1393  id_us_plus((ID *)me);
1394  }
1395 
1396  BKE_object_materials_test(bmain, ob, (ID *)me);
1397 
1399 }
1400 
1401 void BKE_mesh_material_index_remove(Mesh *me, short index)
1402 {
1403  MPoly *mp;
1404  MFace *mf;
1405  int i;
1406 
1407  for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
1408  if (mp->mat_nr && mp->mat_nr >= index) {
1409  mp->mat_nr--;
1410  }
1411  }
1412 
1413  for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
1414  if (mf->mat_nr && mf->mat_nr >= index) {
1415  mf->mat_nr--;
1416  }
1417  }
1418 }
1419 
1420 bool BKE_mesh_material_index_used(Mesh *me, short index)
1421 {
1422  MPoly *mp;
1423  MFace *mf;
1424  int i;
1425 
1426  for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
1427  if (mp->mat_nr == index) {
1428  return true;
1429  }
1430  }
1431 
1432  for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
1433  if (mf->mat_nr == index) {
1434  return true;
1435  }
1436  }
1437 
1438  return false;
1439 }
1440 
1442 {
1443  MPoly *mp;
1444  MFace *mf;
1445  int i;
1446 
1447  for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
1448  mp->mat_nr = 0;
1449  }
1450 
1451  for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
1452  mf->mat_nr = 0;
1453  }
1454 }
1455 
1456 void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len)
1457 {
1458  const short remap_len_short = (short)remap_len;
1459 
1460 #define MAT_NR_REMAP(n) \
1461  if (n < remap_len_short) { \
1462  BLI_assert(n >= 0 && remap[n] < remap_len_short); \
1463  n = remap[n]; \
1464  } \
1465  ((void)0)
1466 
1467  if (me->edit_mesh) {
1468  BMEditMesh *em = me->edit_mesh;
1469  BMIter iter;
1470  BMFace *efa;
1471 
1472  BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1473  MAT_NR_REMAP(efa->mat_nr);
1474  }
1475  }
1476  else {
1477  int i;
1478  for (i = 0; i < me->totpoly; i++) {
1479  MAT_NR_REMAP(me->mpoly[i].mat_nr);
1480  }
1481  }
1482 
1483 #undef MAT_NR_REMAP
1484 }
1485 
1486 void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth)
1487 {
1488  if (use_smooth) {
1489  for (int i = 0; i < me->totpoly; i++) {
1490  me->mpoly[i].flag |= ME_SMOOTH;
1491  }
1492  }
1493  else {
1494  for (int i = 0; i < me->totpoly; i++) {
1495  me->mpoly[i].flag &= ~ME_SMOOTH;
1496  }
1497  }
1498 }
1499 
1501  const bool use_auto_smooth,
1502  const float auto_smooth_angle)
1503 {
1504  if (use_auto_smooth) {
1505  me->flag |= ME_AUTOSMOOTH;
1506  me->smoothresh = auto_smooth_angle;
1507  }
1508  else {
1509  me->flag &= ~ME_AUTOSMOOTH;
1510  }
1511 }
1512 
1513 int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, uint vert)
1514 {
1515  for (int j = 0; j < poly->totloop; j++, loopstart++) {
1516  if (loopstart->v == vert) {
1517  return j;
1518  }
1519  }
1520 
1521  return -1;
1522 }
1523 
1524 int poly_get_adj_loops_from_vert(const MPoly *poly, const MLoop *mloop, uint vert, uint r_adj[2])
1525 {
1526  int corner = poly_find_loop_from_vert(poly, &mloop[poly->loopstart], vert);
1527 
1528  if (corner != -1) {
1529  /* vertex was found */
1530  r_adj[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v;
1531  r_adj[1] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v;
1532  }
1533 
1534  return corner;
1535 }
1536 
1538 {
1539  if (e->v1 == v) {
1540  return e->v2;
1541  }
1542  if (e->v2 == v) {
1543  return e->v1;
1544  }
1545 
1546  return -1;
1547 }
1548 
1549 void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3])
1550 {
1551  for (int i = 2, i_next = 0; i_next < 3; i = i_next++) {
1552  const MLoop *l1 = &mesh->mloop[looptri->tri[i]], *l2 = &mesh->mloop[looptri->tri[i_next]];
1553  const MEdge *e = &mesh->medge[l1->e];
1554 
1555  bool is_real = (l1->v == e->v1 && l2->v == e->v2) || (l1->v == e->v2 && l2->v == e->v1);
1556 
1557  r_edges[i] = is_real ? l1->e : -1;
1558  }
1559 }
1560 
1561 bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
1562 {
1563  using namespace blender;
1564  if (me->totvert == 0) {
1565  return false;
1566  }
1567 
1568  struct Result {
1569  float3 min;
1570  float3 max;
1571  };
1572 
1573  const Result minmax = threading::parallel_reduce(
1574  IndexRange(me->totvert),
1575  1024,
1576  Result{float3(FLT_MAX), float3(-FLT_MAX)},
1577  [&](IndexRange range, const Result &init) {
1578  Result result = init;
1579  for (const int i : range) {
1580  math::min_max(float3(me->mvert[i].co), result.min, result.max);
1581  }
1582  return result;
1583  },
1584  [](const Result &a, const Result &b) {
1585  return Result{math::min(a.min, b.min), math::max(a.max, b.max)};
1586  });
1587 
1588  copy_v3_v3(r_min, math::min(minmax.min, float3(r_min)));
1589  copy_v3_v3(r_max, math::max(minmax.max, float3(r_max)));
1590 
1591  return true;
1592 }
1593 
1594 void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
1595 {
1596  int i;
1599  &me->ldata, CD_NORMAL, me->totloop);
1600 
1601  /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
1603 
1604  for (i = 0; i < me->totvert; i++, mvert++) {
1605  mul_m4_v3(mat, mvert->co);
1606  }
1607 
1608  if (do_keys && me->key) {
1609  LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
1610  float *fp = (float *)kb->data;
1611  for (i = kb->totelem; i--; fp += 3) {
1612  mul_m4_v3(mat, fp);
1613  }
1614  }
1615  }
1616 
1617  /* don't update normals, caller can do this explicitly.
1618  * We do update loop normals though, those may not be auto-generated
1619  * (see e.g. STL import script)! */
1620  if (lnors) {
1621  float m3[3][3];
1622 
1623  copy_m3_m4(m3, mat);
1624  normalize_m3(m3);
1625  for (i = 0; i < me->totloop; i++, lnors++) {
1626  mul_m3_v3(m3, *lnors);
1627  }
1628  }
1630 }
1631 
1632 void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
1633 {
1635  /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
1637 
1638  int i = me->totvert;
1639  for (MVert *mvert = me->mvert; i--; mvert++) {
1640  add_v3_v3(mvert->co, offset);
1641  }
1642 
1643  if (do_keys && me->key) {
1644  LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
1645  float *fp = (float *)kb->data;
1646  for (i = kb->totelem; i--; fp += 3) {
1647  add_v3_v3(fp, offset);
1648  }
1649  }
1650  }
1652 }
1653 
1655 {
1657 }
1658 
1660 {
1661  if (UNLIKELY(mesh->cd_flag)) {
1662  return;
1663  }
1664 
1665  MVert *mv;
1666  MEdge *med;
1667  int i;
1668 
1669  for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
1670  if (mv->bweight != 0) {
1672  break;
1673  }
1674  }
1675 
1676  for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
1677  if (med->bweight != 0) {
1680  break;
1681  }
1682  }
1683  if (med->crease != 0) {
1686  break;
1687  }
1688  }
1689  }
1690 }
1691 
1692 /* -------------------------------------------------------------------- */
1693 /* MSelect functions (currently used in weight paint mode) */
1694 
1696 {
1697  MEM_SAFE_FREE(me->mselect);
1698  me->totselect = 0;
1699 }
1700 
1702 {
1703  MSelect *mselect_src, *mselect_dst;
1704  int i_src, i_dst;
1705 
1706  if (me->totselect == 0) {
1707  return;
1708  }
1709 
1710  mselect_src = me->mselect;
1711  mselect_dst = (MSelect *)MEM_malloc_arrayN(
1712  (me->totselect), sizeof(MSelect), "Mesh selection history");
1713 
1714  for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) {
1715  int index = mselect_src[i_src].index;
1716  switch (mselect_src[i_src].type) {
1717  case ME_VSEL: {
1718  if (me->mvert[index].flag & SELECT) {
1719  mselect_dst[i_dst] = mselect_src[i_src];
1720  i_dst++;
1721  }
1722  break;
1723  }
1724  case ME_ESEL: {
1725  if (me->medge[index].flag & SELECT) {
1726  mselect_dst[i_dst] = mselect_src[i_src];
1727  i_dst++;
1728  }
1729  break;
1730  }
1731  case ME_FSEL: {
1732  if (me->mpoly[index].flag & SELECT) {
1733  mselect_dst[i_dst] = mselect_src[i_src];
1734  i_dst++;
1735  }
1736  break;
1737  }
1738  default: {
1740  break;
1741  }
1742  }
1743  }
1744 
1745  MEM_freeN(mselect_src);
1746 
1747  if (i_dst == 0) {
1748  MEM_freeN(mselect_dst);
1749  mselect_dst = nullptr;
1750  }
1751  else if (i_dst != me->totselect) {
1752  mselect_dst = (MSelect *)MEM_reallocN(mselect_dst, sizeof(MSelect) * i_dst);
1753  }
1754 
1755  me->totselect = i_dst;
1756  me->mselect = mselect_dst;
1757 }
1758 
1759 int BKE_mesh_mselect_find(Mesh *me, int index, int type)
1760 {
1762 
1763  for (int i = 0; i < me->totselect; i++) {
1764  if ((me->mselect[i].index == index) && (me->mselect[i].type == type)) {
1765  return i;
1766  }
1767  }
1768 
1769  return -1;
1770 }
1771 
1773 {
1775 
1776  if (me->totselect) {
1777  if (me->mselect[me->totselect - 1].type == type) {
1778  return me->mselect[me->totselect - 1].index;
1779  }
1780  }
1781  return -1;
1782 }
1783 
1784 void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
1785 {
1786  const int msel_index = BKE_mesh_mselect_find(me, index, type);
1787 
1788  if (msel_index == -1) {
1789  /* add to the end */
1790  me->mselect = (MSelect *)MEM_reallocN(me->mselect, sizeof(MSelect) * (me->totselect + 1));
1791  me->mselect[me->totselect].index = index;
1792  me->mselect[me->totselect].type = type;
1793  me->totselect++;
1794  }
1795  else if (msel_index != me->totselect - 1) {
1796  /* move to the end */
1797  SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]);
1798  }
1799 
1800  BLI_assert((me->mselect[me->totselect - 1].index == index) &&
1801  (me->mselect[me->totselect - 1].type == type));
1802 }
1803 
1804 void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
1805 {
1806  r_count[0] = r_count[1] = r_count[2] = 0;
1807  if (mesh->edit_mesh) {
1808  BMesh *bm = mesh->edit_mesh->bm;
1809  r_count[0] = bm->totvertsel;
1810  r_count[1] = bm->totedgesel;
1811  r_count[2] = bm->totfacesel;
1812  }
1813  /* We could support faces in paint modes. */
1814 }
1815 
1816 void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3])
1817 {
1818  const MVert *mv = mesh->mvert;
1819  for (int i = 0; i < mesh->totvert; i++, mv++) {
1820  copy_v3_v3(vert_coords[i], mv->co);
1821  }
1822 }
1823 
1824 float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
1825 {
1826  float(*vert_coords)[3] = (float(*)[3])MEM_mallocN(sizeof(float[3]) * mesh->totvert, __func__);
1827  BKE_mesh_vert_coords_get(mesh, vert_coords);
1828  if (r_vert_len) {
1829  *r_vert_len = mesh->totvert;
1830  }
1831  return vert_coords;
1832 }
1833 
1834 void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3])
1835 {
1836  /* This will just return the pointer if it wasn't a referenced layer. */
1838  &mesh->vdata, CD_MVERT, mesh->totvert);
1839  mesh->mvert = mv;
1840  for (int i = 0; i < mesh->totvert; i++, mv++) {
1841  copy_v3_v3(mv->co, vert_coords[i]);
1842  }
1844 }
1845 
1847  const float (*vert_coords)[3],
1848  const float mat[4][4])
1849 {
1850  /* This will just return the pointer if it wasn't a referenced layer. */
1852  &mesh->vdata, CD_MVERT, mesh->totvert);
1853  mesh->mvert = mv;
1854  for (int i = 0; i < mesh->totvert; i++, mv++) {
1855  mul_v3_m4v3(mv->co, mat, vert_coords[i]);
1856  }
1858 }
1859 
1861 {
1862  float(*r_loopnors)[3];
1864  r_loopnors = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL);
1865  memset(r_loopnors, 0, sizeof(float[3]) * mesh.totloop);
1866  }
1867  else {
1868  r_loopnors = (float(*)[3])CustomData_add_layer(
1869  &mesh.ldata, CD_NORMAL, CD_CALLOC, nullptr, mesh.totloop);
1871  }
1872  return r_loopnors;
1873 }
1874 
1876  MLoopNorSpaceArray *r_lnors_spacearr,
1877  float (*r_corner_normals)[3])
1878 {
1879  short(*clnors)[2] = nullptr;
1880 
1881  /* Note that we enforce computing clnors when the clnor space array is requested by caller here.
1882  * However, we obviously only use the auto-smooth angle threshold
1883  * only in case auto-smooth is enabled. */
1884  const bool use_split_normals = (r_lnors_spacearr != nullptr) ||
1885  ((mesh->flag & ME_AUTOSMOOTH) != 0);
1886  const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : (float)M_PI;
1887 
1888  /* may be nullptr */
1889  clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
1890 
1893  mesh->totvert,
1894  mesh->medge,
1895  mesh->totedge,
1896  mesh->mloop,
1897  r_corner_normals,
1898  mesh->totloop,
1899  mesh->mpoly,
1901  mesh->totpoly,
1902  use_split_normals,
1903  split_angle,
1904  r_lnors_spacearr,
1905  clnors,
1906  nullptr);
1907 
1909 }
1910 
1912 {
1914 }
1915 
1916 /* Split faces helper functions. */
1917 
1922  float *vnor;
1923 };
1924 
1929  int v1;
1930  int v2;
1931 };
1932 
1933 /* Detect needed new vertices, and update accordingly loops' vertex indices.
1934  * WARNING! Leaves mesh in invalid state. */
1936  MLoopNorSpaceArray *lnors_spacearr,
1937  SplitFaceNewVert **new_verts,
1938  MemArena *memarena)
1939 {
1940  /* This is now mandatory, trying to do the job in simple way without that data is doomed to fail,
1941  * even when only dealing with smooth/flat faces one can find cases that no simple algorithm
1942  * can handle properly. */
1943  BLI_assert(lnors_spacearr != nullptr);
1944 
1945  const int loops_len = mesh->totloop;
1946  int verts_len = mesh->totvert;
1947  MLoop *mloop = mesh->mloop;
1949  float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
1950 
1951  BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__);
1952  BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__);
1953 
1954  MLoop *ml = mloop;
1955  MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
1956 
1957  BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
1958 
1959  for (int loop_idx = 0; loop_idx < loops_len; loop_idx++, ml++, lnor_space++) {
1960  if (!BLI_BITMAP_TEST(done_loops, loop_idx)) {
1961  const int vert_idx = ml->v;
1962  const bool vert_used = BLI_BITMAP_TEST_BOOL(verts_used, vert_idx);
1963  /* If vert is already used by another smooth fan, we need a new vert for this one. */
1964  const int new_vert_idx = vert_used ? verts_len++ : vert_idx;
1965 
1966  BLI_assert(*lnor_space);
1967 
1968  if ((*lnor_space)->flags & MLNOR_SPACE_IS_SINGLE) {
1969  /* Single loop in this fan... */
1970  BLI_assert(POINTER_AS_INT((*lnor_space)->loops) == loop_idx);
1971  BLI_BITMAP_ENABLE(done_loops, loop_idx);
1972  if (vert_used) {
1973  ml->v = new_vert_idx;
1974  }
1975  }
1976  else {
1977  for (LinkNode *lnode = (*lnor_space)->loops; lnode; lnode = lnode->next) {
1978  const int ml_fan_idx = POINTER_AS_INT(lnode->link);
1979  BLI_BITMAP_ENABLE(done_loops, ml_fan_idx);
1980  if (vert_used) {
1981  mloop[ml_fan_idx].v = new_vert_idx;
1982  }
1983  }
1984  }
1985 
1986  if (!vert_used) {
1987  BLI_BITMAP_ENABLE(verts_used, vert_idx);
1988  /* We need to update that vertex's normal here, we won't go over it again. */
1989  /* This is important! *DO NOT* set vnor to final computed lnor,
1990  * vnor should always be defined to 'automatic normal' value computed from its polys,
1991  * not some custom normal.
1992  * Fortunately, that's the loop normal space's 'lnor' reference vector. ;) */
1993  copy_v3_v3(vert_normals[vert_idx], (*lnor_space)->vec_lnor);
1994  }
1995  else {
1996  /* Add new vert to list. */
1997  SplitFaceNewVert *new_vert = (SplitFaceNewVert *)BLI_memarena_alloc(memarena,
1998  sizeof(*new_vert));
1999  new_vert->orig_index = vert_idx;
2000  new_vert->new_index = new_vert_idx;
2001  new_vert->vnor = (*lnor_space)->vec_lnor; /* See note above. */
2002  new_vert->next = *new_verts;
2003  *new_verts = new_vert;
2004  }
2005  }
2006  }
2007 
2008  MEM_freeN(done_loops);
2009  MEM_freeN(verts_used);
2010 
2011  return verts_len - mesh->totvert;
2012 }
2013 
2014 /* Detect needed new edges, and update accordingly loops' edge indices.
2015  * WARNING! Leaves mesh in invalid state. */
2017  SplitFaceNewEdge **new_edges,
2018  MemArena *memarena)
2019 {
2020  const int num_polys = mesh->totpoly;
2021  int num_edges = mesh->totedge;
2022  MEdge *medge = mesh->medge;
2023  MLoop *mloop = mesh->mloop;
2024  const MPoly *mpoly = mesh->mpoly;
2025 
2026  BLI_bitmap *edges_used = BLI_BITMAP_NEW(num_edges, __func__);
2027  EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges);
2028 
2029  const MPoly *mp = mpoly;
2030  for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) {
2031  MLoop *ml_prev = &mloop[mp->loopstart + mp->totloop - 1];
2032  MLoop *ml = &mloop[mp->loopstart];
2033  for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) {
2034  void **eval;
2035  if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) {
2036  const int edge_idx = ml_prev->e;
2037 
2038  /* That edge has not been encountered yet, define it. */
2039  if (BLI_BITMAP_TEST(edges_used, edge_idx)) {
2040  /* Original edge has already been used, we need to define a new one. */
2041  const int new_edge_idx = num_edges++;
2042  *eval = POINTER_FROM_INT(new_edge_idx);
2043  ml_prev->e = new_edge_idx;
2044 
2046  sizeof(*new_edge));
2047  new_edge->orig_index = edge_idx;
2048  new_edge->new_index = new_edge_idx;
2049  new_edge->v1 = ml_prev->v;
2050  new_edge->v2 = ml->v;
2051  new_edge->next = *new_edges;
2052  *new_edges = new_edge;
2053  }
2054  else {
2055  /* We can re-use original edge. */
2056  medge[edge_idx].v1 = ml_prev->v;
2057  medge[edge_idx].v2 = ml->v;
2058  *eval = POINTER_FROM_INT(edge_idx);
2059  BLI_BITMAP_ENABLE(edges_used, edge_idx);
2060  }
2061  }
2062  else {
2063  /* Edge already known, just update loop's edge index. */
2064  ml_prev->e = POINTER_AS_INT(*eval);
2065  }
2066 
2067  ml_prev = ml;
2068  }
2069  }
2070 
2071  MEM_freeN(edges_used);
2072  BLI_edgehash_free(edges_hash, nullptr);
2073 
2074  return num_edges - mesh->totedge;
2075 }
2076 
2077 /* Perform actual split of vertices. */
2079  SplitFaceNewVert *new_verts,
2080  const int num_new_verts)
2081 {
2082  const int verts_len = mesh->totvert - num_new_verts;
2083  MVert *mvert = mesh->mvert;
2084  float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
2085 
2086  /* Normals were already calculated at the beginning of this operation, we rely on that to update
2087  * them partially here. */
2089 
2090  /* Remember new_verts is a single linklist, so its items are in reversed order... */
2091  MVert *new_mv = &mvert[mesh->totvert - 1];
2092  for (int i = mesh->totvert - 1; i >= verts_len; i--, new_mv--, new_verts = new_verts->next) {
2093  BLI_assert(new_verts->new_index == i);
2094  BLI_assert(new_verts->new_index != new_verts->orig_index);
2095  CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
2096  if (new_verts->vnor) {
2097  copy_v3_v3(vert_normals[i], new_verts->vnor);
2098  }
2099  }
2100 }
2101 
2102 /* Perform actual split of edges. */
2104  SplitFaceNewEdge *new_edges,
2105  const int num_new_edges)
2106 {
2107  const int num_edges = mesh->totedge - num_new_edges;
2108  MEdge *medge = mesh->medge;
2109 
2110  /* Remember new_edges is a single linklist, so its items are in reversed order... */
2111  MEdge *new_med = &medge[mesh->totedge - 1];
2112  for (int i = mesh->totedge - 1; i >= num_edges; i--, new_med--, new_edges = new_edges->next) {
2113  BLI_assert(new_edges->new_index == i);
2114  BLI_assert(new_edges->new_index != new_edges->orig_index);
2115  CustomData_copy_data(&mesh->edata, &mesh->edata, new_edges->orig_index, i, 1);
2116  new_med->v1 = new_edges->v1;
2117  new_med->v2 = new_edges->v2;
2118  }
2119 }
2120 
2121 void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
2122 {
2123  const int num_polys = mesh->totpoly;
2124 
2125  if (num_polys == 0) {
2126  return;
2127  }
2129 
2130  MLoopNorSpaceArray lnors_spacearr = {nullptr};
2131  /* Compute loop normals and loop normal spaces (a.k.a. smooth fans of faces around vertices). */
2133  /* Stealing memarena from loop normals space array. */
2134  MemArena *memarena = lnors_spacearr.mem;
2135 
2136  SplitFaceNewVert *new_verts = nullptr;
2137  SplitFaceNewEdge *new_edges = nullptr;
2138 
2139  /* Ensure we own the layers, we need to do this before split_faces_prepare_new_verts as it will
2140  * directly assign new indices to existing edges and loops. */
2144  /* Update pointers in case we duplicated referenced layers. */
2146 
2147  /* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
2148  const int num_new_verts = split_faces_prepare_new_verts(
2149  mesh, &lnors_spacearr, &new_verts, memarena);
2150 
2151  if (num_new_verts > 0) {
2152  /* Reminder: beyond this point, there is no way out, mesh is in invalid state
2153  * (due to early-reassignment of loops' vertex and edge indices to new,
2154  * to-be-created split ones). */
2155 
2156  const int num_new_edges = split_faces_prepare_new_edges(mesh, &new_edges, memarena);
2157  /* We can have to split a vertex without having to add a single new edge... */
2158  const bool do_edges = (num_new_edges > 0);
2159 
2160  /* Reallocate all vert and edge related data. */
2161  mesh->totvert += num_new_verts;
2163  if (do_edges) {
2164  mesh->totedge += num_new_edges;
2166  }
2167  /* Update pointers to a newly allocated memory. */
2169 
2170  /* Update normals manually to avoid recalculation after this operation. */
2172  sizeof(float[3]) * mesh->totvert);
2173 
2174  /* Perform actual split of vertices and edges. */
2175  split_faces_split_new_verts(mesh, new_verts, num_new_verts);
2176  if (do_edges) {
2177  split_faces_split_new_edges(mesh, new_edges, num_new_edges);
2178  }
2179  }
2180 
2181  /* NOTE: after this point mesh is expected to be valid again. */
2182 
2183  /* CD_NORMAL is expected to be temporary only. */
2184  if (free_loop_normals) {
2186  }
2187 
2188  /* Also frees new_verts/edges temp data, since we used its memarena to allocate them. */
2189  BKE_lnor_spacearr_free(&lnors_spacearr);
2190 
2192 #ifdef VALIDATE_MESH
2193  BKE_mesh_validate(mesh, true, true);
2194 #endif
2195 }
2196 
2197 /* **** Depsgraph evaluation **** */
2198 
2200 {
2203  /* We are here because something did change in the mesh. This means we can not trust the existing
2204  * evaluated mesh, and we don't know what parts of the mesh did change. So we simply delete the
2205  * evaluated mesh and let objects to re-create it with updated settings. */
2206  if (mesh->runtime.mesh_eval != nullptr) {
2207  mesh->runtime.mesh_eval->edit_mesh = nullptr;
2208  BKE_id_free(nullptr, mesh->runtime.mesh_eval);
2209  mesh->runtime.mesh_eval = nullptr;
2210  }
2211  if (DEG_is_active(depsgraph)) {
2212  Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id);
2214  mesh_orig->texflag |= ME_AUTOSPACE_EVALUATED;
2215  copy_v3_v3(mesh_orig->loc, mesh->loc);
2216  copy_v3_v3(mesh_orig->size, mesh->size);
2217  }
2218  }
2219 }
typedef float(TangentPoint)[2]
void BKE_animdata_free(struct ID *id, bool do_id_user)
Definition: anim_data.c:197
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1443
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1421
bool BKE_bpath_foreach_path_fixed_process(struct BPathForeachPathData *bpath_data, char *path)
Definition: bpath.c:121
const CustomData_MeshMasks CD_MASK_EVERYTHING
Definition: customdata.cc:2101
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.cc:2373
void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count)
Definition: customdata.cc:5215
int CustomData_number_of_layers(const struct CustomData *data, int type)
eCDAllocType
@ CD_REFERENCE
@ CD_ASSIGN
@ CD_CALLOC
@ CD_DUPLICATE
@ CD_DEFAULT
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void CustomData_free_layers(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2904
bool CustomData_has_layer(const struct CustomData *data, int type)
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
Definition: customdata.cc:77
void CustomData_bmesh_update_active_layers(struct CustomData *fdata, struct CustomData *ldata)
Definition: customdata.cc:3508
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_bmesh_get(const struct CustomData *data, void *block, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
Definition: customdata.cc:2626
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
Definition: customdata.cc:2077
void CustomData_realloc(struct CustomData *data, int totelem)
Definition: customdata.cc:2307
void * CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2976
void CustomData_duplicate_referenced_layers(CustomData *data, int totelem)
Definition: customdata.cc:3020
#define CD_TYPE_AS_MASK(_type)
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.cc:2065
void CustomData_reset(struct CustomData *data)
Definition: customdata.cc:2367
support for deformation groups and hooks.
void BKE_defbase_blend_write(struct BlendWriter *writer, const ListBase *defbase)
Definition: deform.c:1557
void BKE_defgroup_copy_list(struct ListBase *outbase, const struct ListBase *inbase)
void BKE_defvert_blend_read(struct BlendDataReader *reader, int count, struct MDeformVert *mdverts)
Definition: deform.c:1581
void BKE_editmesh_free_data(BMEditMesh *em)
Definition: editmesh.c:181
@ G_DEBUG
Definition: BKE_global.h:174
const char * BKE_idtype_idcode_to_name(short idcode)
Definition: idtype.c:142
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
@ LIB_ID_CREATE_LOCALIZE
Definition: BKE_lib_id.h:184
@ LIB_ID_COPY_CD_REFERENCE
Definition: BKE_lib_id.h:156
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
@ LIB_ID_COPY_SHAPEKEY
Definition: BKE_lib_id.h:170
void BKE_libblock_free_data(struct ID *id, bool do_id_user) ATTR_NONNULL()
Definition: lib_id_delete.c:44
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1050
void * BKE_id_new_nomain(short type, const char *name)
Definition: lib_id.c:1173
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_libblock_init_empty(struct ID *id) ATTR_NONNULL(1)
Definition: lib_id.c:1115
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2008
void * BKE_id_new(struct Main *bmain, short type, const char *name)
Definition: lib_id.c:1159
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
@ IDWALK_CB_NEVER_SELF
Definition: BKE_lib_query.h:35
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
General operations, lookup, etc. for materials.
void BKE_object_materials_test(struct Main *bmain, struct Object *ob, struct ID *id)
Definition: material.c:864
float(* BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3]
const float(* BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3]
@ MLNOR_SPACEARR_LOOP_INDEX
Definition: BKE_mesh.h:571
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_assert_normals_dirty_or_calculated(const struct Mesh *mesh)
bool BKE_mesh_validate(struct Mesh *me, bool do_verbose, bool cddata_check_mask)
bool BKE_mesh_vertex_normals_are_dirty(const struct Mesh *mesh)
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)
@ MLNOR_SPACE_IS_SINGLE
Definition: BKE_mesh.h:553
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
void BKE_mesh_normals_tag_dirty(struct Mesh *mesh)
Definition: mesh_normals.cc:95
void BKE_mesh_tag_coords_changed_uniformly(struct Mesh *mesh)
void BKE_mesh_tag_coords_changed(struct Mesh *mesh)
void BKE_mesh_add_mface_layers(struct CustomData *fdata, struct CustomData *ldata, int total)
void BKE_mesh_runtime_free_data(struct Mesh *mesh)
Free all data (and mutexes) inside the runtime of the given mesh.
Definition: mesh_runtime.cc:72
void BKE_mesh_runtime_clear_cache(struct Mesh *mesh)
This function clears runtime cache of the given mesh.
Definition: mesh_runtime.cc:99
void BKE_mesh_runtime_init_data(struct Mesh *mesh)
Initialize the runtime of the given mesh.
Definition: mesh_runtime.cc:67
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag)
bool BKE_mesh_wrapper_minmax(const struct Mesh *me, float min[3], float max[3])
void BKE_modifiers_test_object(struct Object *ob)
void multires_force_sculpt_rebuild(struct Object *object)
Definition: multires.c:437
General operations, lookup, etc. for blender objects.
void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], const float max[3])
Definition: object.cc:3645
bool BKE_object_obdata_texspace_get(struct Object *ob, char **r_texflag, float **r_loc, float **r_size)
Definition: object.cc:4328
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#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
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition: BLI_bitmap.h:74
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
Definition: edgehash.c:230
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
Definition: edgehash.c:261
bool BLI_edgehash_ensure_p(EdgeHash *eh, unsigned int v0, unsigned int v1, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:307
EdgeHash * BLI_edgehash_new_ex(const char *info, unsigned int nentries_reserve)
Definition: edgehash.c:212
void * BLI_edgehash_lookup(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:295
void BLI_endian_switch_uint32_array(unsigned int *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:41
BLI_INLINE unsigned int BLI_hash_int(unsigned int k)
Definition: BLI_hash.h:89
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
MINLINE int min_ii(int a, int b)
MINLINE bool compare_threshold_relative(float value1, float value2, float thresh)
#define M_PI
Definition: BLI_math_base.h:20
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void range_vn_i(int *array_tar, int size, int start)
Definition: math_vector.c:1021
void copy_vn_i(int *array_tar, int size, int val)
Definition: math_vector.c:1223
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:237
MINLINE void add_v3_v3(float r[3], const float a[3])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:116
unsigned int uint
Definition: BLI_sys_types.h:67
#define INIT_MINMAX(min, max)
#define SWAP(type, a, b)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition: readfile.c:5143
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
Definition: writefile.c:1489
void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
Definition: readfile.c:5245
bool BLO_write_is_undo(BlendWriter *writer)
Definition: writefile.c:1608
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
Definition: writefile.c:1591
#define BLT_I18NCONTEXT_ID_MESH
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
void DEG_debug_print_eval(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
struct ID * DEG_get_original_id(struct ID *id)
@ INDEX_ID_ME
Definition: DNA_ID.h:1026
#define FILTER_ID_ME
Definition: DNA_ID.h:913
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:720
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:744
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ ID_ME
Definition: DNA_ID_enums.h:48
#define CD_MASK_PROP_BYTE_COLOR
@ CD_FLAG_TEMPORARY
#define CD_MASK_MDEFORMVERT
#define CD_MASK_PROP_ALL
#define CD_MASK_MEDGE
#define CD_MASK_MPOLY
@ CD_PROP_BYTE_COLOR
@ CD_FACEMAP
@ CD_MVERT_SKIN
@ CD_PROP_FLOAT
@ CD_CUSTOMLOOPNORMAL
@ CD_MTFACE
@ CD_PROP_FLOAT3
@ CD_MFACE
@ CD_MDEFORMVERT
@ CD_ORIGINDEX
@ CD_PROP_COLOR
@ CD_NUMTYPES
@ CD_PROP_INT8
@ CD_PROP_INT32
@ CD_PROP_FLOAT2
@ CD_PROP_BOOL
@ CD_MEDGE
@ CD_MVERT
@ CD_MLOOPUV
#define CD_MASK_MVERT
#define CD_MASK_MLOOPUV
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ ME_WRAPPER_TYPE_MDATA
struct Mesh Mesh
@ ME_AUTOSMOOTH
@ ME_AUTOSPACE_EVALUATED
@ ME_AUTOSPACE
@ ME_CDFLAG_EDGE_CREASE
@ ME_CDFLAG_VERT_BWEIGHT
@ ME_CDFLAG_EDGE_BWEIGHT
@ ME_VSEL
@ ME_FSEL
@ ME_ESEL
#define ME_POLY_LOOP_PREV(mloop, mp, i)
@ ME_SMOOTH
@ MVERT_SKIN_ROOT
#define ME_POLY_LOOP_NEXT(mloop, mp, i)
struct MSelect MSelect
Object is a sort of wrapper for general info.
@ OB_MESH
@ BOUNDBOX_DIRTY
_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 type
_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 i1
_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
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
Platform independent time functions.
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:875
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:839
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
Definition: bmesh_mesh.cc:125
#define BMALLOC_TEMPLATE_FROM_ME(...)
Definition: bmesh_mesh.h:197
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
#define SELECT
void CustomData_blend_write(BlendWriter *writer, CustomData *data, Span< CustomDataLayer > layers_to_write, int count, eCustomDataMask cddata_mask, ID *id)
Definition: customdata.cc:5108
void CustomData_blend_write_prepare(CustomData &data, Vector< CustomDataLayer, 16 > &layers_to_write)
Definition: customdata.cc:4253
const Depsgraph * depsgraph
#define UINT_MAX
Definition: hash_md5.c:43
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: invert.h:8
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix int ccl_global int * indices
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define G(x, y, z)
void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len)
Definition: mesh.cc:1456
void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth)
Definition: mesh.cc:1486
void BKE_mesh_mselect_validate(Mesh *me)
Definition: mesh.cc:1701
void BKE_mesh_texspace_get_reference(Mesh *me, char **r_texflag, float **r_loc, float **r_size)
Definition: mesh.cc:1287
void BKE_mesh_texspace_calc(Mesh *me)
Definition: mesh.cc:1231
void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.cc:874
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
Definition: mesh.cc:1175
static const char * cmpcode_to_str(int code)
Definition: mesh.cc:409
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
Definition: mesh.cc:1632
bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
Definition: mesh.cc:838
static void mesh_read_expand(BlendExpander *expander, ID *id)
Definition: mesh.cc:353
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
Definition: mesh.cc:1039
void BKE_mesh_vert_coords_apply(Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.cc:1834
void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob)
Definition: mesh.cc:1302
bool BKE_mesh_material_index_used(Mesh *me, short index)
Definition: mesh.cc:1420
void BKE_mesh_tessface_clear(Mesh *mesh)
Definition: mesh.cc:1654
void BKE_mesh_free_editmesh(struct Mesh *mesh)
Definition: mesh.cc:169
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:1106
const char * BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
Definition: mesh.cc:702
Mesh * BKE_mesh_from_bmesh_nomain(BMesh *bm, const struct BMeshToMeshParams *params, const Mesh *me_settings)
Definition: mesh.cc:1164
Mesh * BKE_mesh_add(Main *bmain, const char *name)
Definition: mesh.cc:963
Mesh * BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len, CustomData_MeshMasks mask)
Definition: mesh.cc:1060
int poly_get_adj_loops_from_vert(const MPoly *poly, const MLoop *mloop, uint vert, uint r_adj[2])
Definition: mesh.cc:1524
static void mesh_clear_geometry(Mesh *mesh)
Definition: mesh.cc:920
void BKE_mesh_ensure_skin_customdata(Mesh *me)
Definition: mesh.cc:786
void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
Definition: mesh.cc:1594
static void split_faces_split_new_verts(Mesh *mesh, SplitFaceNewVert *new_verts, const int num_new_verts)
Definition: mesh.cc:2078
static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
Definition: mesh.cc:971
void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3])
Definition: mesh.cc:1549
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me)
Definition: mesh.cc:819
static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: mesh.cc:213
float(* BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
Definition: mesh.cc:1824
void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
Definition: mesh.cc:1353
static int split_faces_prepare_new_edges(const Mesh *mesh, SplitFaceNewEdge **new_edges, MemArena *memarena)
Definition: mesh.cc:2016
static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Definition: mesh.cc:205
#define MAT_NR_REMAP(n)
void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
Definition: mesh.cc:1117
void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
Definition: mesh.cc:1804
void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
Definition: mesh.cc:2121
static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.cc:865
Mesh * BKE_mesh_from_object(Object *ob)
Definition: mesh.cc:1365
int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart, uint vert)
Definition: mesh.cc:1513
static void mesh_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: mesh.cc:335
BoundBox * BKE_mesh_boundbox_get(Object *ob)
Definition: mesh.cc:1207
void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
Definition: mesh.cc:1017
static void split_faces_split_new_edges(Mesh *mesh, SplitFaceNewEdge *new_edges, const int num_new_edges)
Definition: mesh.cc:2103
void BKE_mesh_calc_normals_split(Mesh *mesh)
Definition: mesh.cc:1911
Mesh * BKE_mesh_copy_for_eval(const Mesh *source, bool reference)
Definition: mesh.cc:1126
void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh, const float(*vert_coords)[3], const float mat[4][4])
Definition: mesh.cc:1846
void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
Definition: mesh.cc:1784
static void mesh_free_data(ID *id)
Definition: mesh.cc:182
void BKE_mesh_vert_coords_get(const Mesh *mesh, float(*vert_coords)[3])
Definition: mesh.cc:1816
void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spacearr, float(*r_corner_normals)[3])
Definition: mesh.cc:1875
BMesh * BKE_mesh_to_bmesh(Mesh *me, Object *ob, const bool add_key_index, const struct BMeshCreateParams *params)
Definition: mesh.cc:1150
static void ensure_orig_index_layer(CustomData &data, const int size)
Definition: mesh.cc:1185
static int split_faces_prepare_new_verts(Mesh *mesh, MLoopNorSpaceArray *lnors_spacearr, SplitFaceNewVert **new_verts, MemArena *memarena)
Definition: mesh.cc:1935
static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
Definition: mesh.cc:279
void BKE_mesh_mselect_clear(Mesh *me)
Definition: mesh.cc:1695
int BKE_mesh_edge_other_vert(const MEdge *e, int v)
Definition: mesh.cc:1537
static void mesh_init_data(ID *id)
Definition: mesh.cc:70
static void mesh_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: mesh.cc:195
static float(* ensure_corner_normal_layer(Mesh &mesh))[3]
Definition: mesh.cc:1860
static void mesh_ensure_tessellation_customdata(Mesh *me)
Definition: mesh.cc:745
Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_size[3])
Definition: mesh.cc:1275
bool BKE_mesh_has_custom_loop_normals(Mesh *me)
Definition: mesh.cc:894
void BKE_mesh_texspace_ensure(Mesh *me)
Definition: mesh.cc:1268
int BKE_mesh_mselect_active_get(Mesh *me, int type)
Definition: mesh.cc:1772
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
Definition: mesh.cc:948
void BKE_mesh_free_data_for_undo(Mesh *me)
Definition: mesh.cc:903
static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
Definition: mesh.cc:93
int BKE_mesh_mselect_find(Mesh *me, int index, int type)
Definition: mesh.cc:1759
bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
Definition: mesh.cc:1561
void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
Definition: mesh.cc:2199
void BKE_mesh_clear_geometry(Mesh *mesh)
Definition: mesh.cc:941
float(* BKE_mesh_orco_verts_get(Object *ob))[3]
Definition: mesh.cc:1314
@ MESHCMP_DVERT_TOTGROUPMISMATCH
Definition: mesh.cc:397
@ MESHCMP_CDLAYERS_MISMATCH
Definition: mesh.cc:405
@ MESHCMP_DVERT_WEIGHTMISMATCH
Definition: mesh.cc:395
@ MESHCMP_LOOPCOLMISMATCH
Definition: mesh.cc:398
@ MESHCMP_DVERT_GROUPMISMATCH
Definition: mesh.cc:396
@ MESHCMP_EDGEUNKNOWN
Definition: mesh.cc:403
@ MESHCMP_LOOPMISMATCH
Definition: mesh.cc:400
@ MESHCMP_LOOPUVMISMATCH
Definition: mesh.cc:399
@ MESHCMP_VERTCOMISMATCH
Definition: mesh.cc:404
@ MESHCMP_ATTRIBUTE_VALUE_MISMATCH
Definition: mesh.cc:406
@ MESHCMP_POLYMISMATCH
Definition: mesh.cc:402
@ MESHCMP_POLYVERTMISMATCH
Definition: mesh.cc:401
IDTypeInfo IDType_ID_ME
Definition: mesh.cc:364
void BKE_mesh_auto_smooth_flag_set(Mesh *me, const bool use_auto_smooth, const float auto_smooth_angle)
Definition: mesh.cc:1500
void BKE_mesh_material_index_clear(Mesh *me)
Definition: mesh.cc:1441
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
Definition: mesh.cc:1194
void BKE_mesh_orco_verts_transform(Mesh *me, float(*orco)[3], int totvert, int invert)
Definition: mesh.cc:1331
void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me)
Definition: mesh.cc:1377
static int customdata_compare(CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh)
Definition: mesh.cc:442
void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
Definition: mesh.cc:1659
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *me, const struct BMeshCreateParams *create_params, const struct BMeshFromMeshParams *convert_params)
Definition: mesh.cc:1138
void BKE_mesh_ensure_default_orig_index_customdata_no_check(Mesh *mesh)
Definition: mesh.cc:1200
void BKE_mesh_material_index_remove(Mesh *me, short index)
Definition: mesh.cc:1401
#define fabsf(x)
Definition: metal/compat.h:219
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
static MEdge new_edge(const int v1, const int v2)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
Definition: BLI_task.hh:73
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
#define min(a, b)
Definition: sort.c:35
unsigned int uint32_t
Definition: stdint.h:80
unsigned __int64 uint64_t
Definition: stdint.h:90
signed char int8_t
Definition: stdint.h:75
struct BMesh * bm
Definition: BKE_editmesh.h:40
char is_shallow_copy
Definition: BKE_editmesh.h:62
short mat_nr
Definition: bmesh_class.h:281
void * data
Definition: bmesh_class.h:51
float co[3]
Definition: bmesh_class.h:87
BMHeader head
Definition: bmesh_class.h:85
int totfacesel
Definition: bmesh_class.h:298
CustomData vdata
Definition: bmesh_class.h:337
int totvertsel
Definition: bmesh_class.h:298
int totedgesel
Definition: bmesh_class.h:298
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
const struct AnonymousAttributeID * anonymous_id
CustomDataLayer * layers
CustomDataExternal * external
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
struct Library * lib
Definition: DNA_ID.h:372
char name[66]
Definition: DNA_ID.h:378
ID * from
Definition: DNA_key_types.h:88
ID id
Definition: DNA_key_types.h:63
ListBase block
Definition: DNA_key_types.h:84
struct LinkNode * next
Definition: BLI_linklist.h:23
struct MDeformWeight * dw
unsigned int def_nr
unsigned int v1
unsigned int v2
unsigned char a
unsigned char b
unsigned char r
unsigned char g
struct MemArena * mem
Definition: BKE_mesh.h:565
MLoopNorSpace ** lspacearr
Definition: BKE_mesh.h:560
unsigned int tri[3]
unsigned int e
unsigned int v
short mat_nr
float co[3]
Definition: BKE_main.h:121
float(* vert_normals)[3]
struct Mesh * mesh_eval
uint32_t * subsurf_face_dot_tags
struct MEdge * medge
struct BMEditMesh * edit_mesh
float remesh_voxel_adaptivity
float smoothresh
CustomData vdata
struct Mesh * texcomesh
struct MTFace * mtface
char symmetry
struct MVert * mvert
struct MLoopCol * mloopcol
float size[3]
struct AnimData * adt
uint16_t flag
struct Material ** mat
struct MDeformVert * dvert
float remesh_voxel_size
int totedge
struct MLoopUV * mloopuv
int act_face
ListBase vertex_group_names
char cd_flag
char editflag
int totvert
struct MLoop * mloop
int totface
Mesh_Runtime runtime
CustomData pdata
CustomData fdata
int totpoly
short totcol
int face_sets_color_seed
struct MCol * mcol
char texflag
int vertex_group_active_index
int face_sets_color_default
CustomData edata
int totloop
struct Key * key
int totselect
char remesh_mode
struct MFace * mface
struct MPoly * mpoly
CustomData ldata
float loc[3]
struct MSelect * mselect
struct BoundBox * bb
short shapenr
Object_Runtime runtime
void * data
struct SplitFaceNewEdge * next
Definition: mesh.cc:1926
struct SplitFaceNewVert * next
Definition: mesh.cc:1919
float * vnor
Definition: mesh.cc:1922
long int PIL_check_seconds_timer_i(void)
Definition: time.c:74
float max