Blender  V2.93
mesh_convert.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include "CLG_log.h"
22 
23 #include "MEM_guardedalloc.h"
24 
25 #include "DNA_curve_types.h"
26 #include "DNA_key_types.h"
27 #include "DNA_material_types.h"
28 #include "DNA_mesh_types.h"
29 #include "DNA_meta_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_pointcloud_types.h"
32 #include "DNA_scene_types.h"
33 
34 #include "BLI_edgehash.h"
35 #include "BLI_listbase.h"
36 #include "BLI_math.h"
37 #include "BLI_string.h"
38 #include "BLI_utildefines.h"
39 
40 #include "BKE_DerivedMesh.h"
41 #include "BKE_displist.h"
42 #include "BKE_editmesh.h"
43 #include "BKE_key.h"
44 #include "BKE_lib_id.h"
45 #include "BKE_lib_query.h"
46 #include "BKE_main.h"
47 #include "BKE_material.h"
48 #include "BKE_mball.h"
49 #include "BKE_mesh.h"
50 #include "BKE_mesh_runtime.h"
51 #include "BKE_mesh_wrapper.h"
52 #include "BKE_modifier.h"
53 /* these 2 are only used by conversion functions */
54 #include "BKE_curve.h"
55 /* -- */
56 #include "BKE_object.h"
57 /* -- */
58 #include "BKE_pointcloud.h"
59 
60 #include "DEG_depsgraph.h"
61 #include "DEG_depsgraph_query.h"
62 
63 /* Define for cases when you want extra validation of mesh
64  * after certain modifications.
65  */
66 // #undef VALIDATE_MESH
67 
68 #ifdef VALIDATE_MESH
69 # define ASSERT_IS_VALID_MESH(mesh) \
70  (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
71 #else
72 # define ASSERT_IS_VALID_MESH(mesh)
73 #endif
74 
75 static CLG_LogRef LOG = {"bke.mesh_convert"};
76 
78 {
79  DispList *dl;
80  MVert *mvert;
81  MLoop *mloop, *allloop;
82  MPoly *mpoly;
83  const float *nors, *verts;
84  int a, *index;
85 
86  dl = lb->first;
87  if (dl == NULL) {
88  return;
89  }
90 
91  if (dl->type == DL_INDEX4) {
92  mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, dl->nr);
93  allloop = mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, dl->parts * 4);
94  mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, dl->parts);
95  me->mvert = mvert;
96  me->mloop = mloop;
97  me->mpoly = mpoly;
98  me->totvert = dl->nr;
99  me->totpoly = dl->parts;
100 
101  a = dl->nr;
102  nors = dl->nors;
103  verts = dl->verts;
104  while (a--) {
105  copy_v3_v3(mvert->co, verts);
106  normal_float_to_short_v3(mvert->no, nors);
107  mvert++;
108  nors += 3;
109  verts += 3;
110  }
111 
112  a = dl->parts;
113  index = dl->index;
114  while (a--) {
115  int count = index[2] != index[3] ? 4 : 3;
116 
117  mloop[0].v = index[0];
118  mloop[1].v = index[1];
119  mloop[2].v = index[2];
120  if (count == 4) {
121  mloop[3].v = index[3];
122  }
123 
124  mpoly->totloop = count;
125  mpoly->loopstart = (int)(mloop - allloop);
126  mpoly->flag = ME_SMOOTH;
127 
128  mpoly++;
129  mloop += count;
130  me->totloop += count;
131  index += 4;
132  }
133 
135 
137 
138  BKE_mesh_calc_edges(me, true, false);
139  }
140 }
141 
146  MEdge **r_alledge, int *r_totedge, const MPoly *mpoly, MLoop *mloop, const int totpoly)
147 {
148  int totedge = *r_totedge;
149  int totedge_new;
150  EdgeHash *eh;
151  unsigned int eh_reserve;
152  const MPoly *mp;
153  int i;
154 
155  eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
156  eh = BLI_edgehash_new_ex(__func__, eh_reserve);
157 
158  for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
159  BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart);
160  }
161 
162  totedge_new = BLI_edgehash_len(eh);
163 
164 #ifdef DEBUG
165  /* ensure that there's no overlap! */
166  if (totedge_new) {
167  MEdge *medge = *r_alledge;
168  for (i = 0; i < totedge; i++, medge++) {
169  BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
170  }
171  }
172 #endif
173 
174  if (totedge_new) {
175  EdgeHashIterator *ehi;
176  MEdge *medge;
177  unsigned int e_index = totedge;
178 
179  *r_alledge = medge = (*r_alledge ?
180  MEM_reallocN(*r_alledge, sizeof(MEdge) * (totedge + totedge_new)) :
181  MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__));
182  medge += totedge;
183 
184  totedge += totedge_new;
185 
186  /* --- */
187  for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false;
188  BLI_edgehashIterator_step(ehi), ++medge, e_index++) {
189  BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
191 
192  medge->crease = medge->bweight = 0;
193  medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
194  }
196 
197  *r_totedge = totedge;
198 
199  for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
200  MLoop *l = &mloop[mp->loopstart];
201  MLoop *l_prev = (l + (mp->totloop - 1));
202  int j;
203  for (j = 0; j < mp->totloop; j++, l++) {
204  /* lookup hashed edge index */
205  l_prev->e = POINTER_AS_UINT(BLI_edgehash_lookup(eh, l_prev->v, l->v));
206  l_prev = l;
207  }
208  }
209  }
210 
211  BLI_edgehash_free(eh, NULL);
212 }
213 
214 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
215 /* return non-zero on error */
217  MVert **r_allvert,
218  int *r_totvert,
219  MEdge **r_alledge,
220  int *r_totedge,
221  MLoop **r_allloop,
222  MPoly **r_allpoly,
223  int *r_totloop,
224  int *r_totpoly)
225 {
226  ListBase disp = {NULL, NULL};
227 
228  if (ob->runtime.curve_cache) {
229  disp = ob->runtime.curve_cache->disp;
230  }
231 
233  &disp,
234  r_allvert,
235  r_totvert,
236  r_alledge,
237  r_totedge,
238  r_allloop,
239  r_allpoly,
240  NULL,
241  r_totloop,
242  r_totpoly);
243 }
244 
245 /* BMESH: this doesn't calculate all edges from polygons,
246  * only free standing edges are calculated */
247 
248 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
249 /* use specified dispbase */
251  const ListBase *dispbase,
252  MVert **r_allvert,
253  int *r_totvert,
254  MEdge **r_alledge,
255  int *r_totedge,
256  MLoop **r_allloop,
257  MPoly **r_allpoly,
258  MLoopUV **r_alluv,
259  int *r_totloop,
260  int *r_totpoly)
261 {
262  Curve *cu = ob->data;
263  DispList *dl;
264  MVert *mvert;
265  MPoly *mpoly;
266  MLoop *mloop;
267  MLoopUV *mloopuv = NULL;
268  MEdge *medge;
269  const float *data;
270  int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0;
271  int p1, p2, p3, p4, *index;
272  const bool conv_polys = (
273  /* 2d polys are filled with DL_INDEX3 displists */
274  (CU_DO_2DFILL(cu) == false) ||
275  /* surf polys are never filled */
276  (ob->type == OB_SURF));
277 
278  /* count */
279  dl = dispbase->first;
280  while (dl) {
281  if (dl->type == DL_SEGM) {
282  totvert += dl->parts * dl->nr;
283  totedge += dl->parts * (dl->nr - 1);
284  }
285  else if (dl->type == DL_POLY) {
286  if (conv_polys) {
287  totvert += dl->parts * dl->nr;
288  totedge += dl->parts * dl->nr;
289  }
290  }
291  else if (dl->type == DL_SURF) {
292  if (dl->parts != 0) {
293  int tot;
294  totvert += dl->parts * dl->nr;
295  tot = (((dl->flag & DL_CYCL_U) ? 1 : 0) + (dl->nr - 1)) *
296  (((dl->flag & DL_CYCL_V) ? 1 : 0) + (dl->parts - 1));
297  totpoly += tot;
298  totloop += tot * 4;
299  }
300  }
301  else if (dl->type == DL_INDEX3) {
302  int tot;
303  totvert += dl->nr;
304  tot = dl->parts;
305  totpoly += tot;
306  totloop += tot * 3;
307  }
308  dl = dl->next;
309  }
310 
311  if (totvert == 0) {
312  /* error("can't convert"); */
313  /* Make Sure you check ob->data is a curve */
314  return -1;
315  }
316 
317  *r_allvert = mvert = MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert");
318  *r_alledge = medge = MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge");
319  *r_allloop = mloop = MEM_calloc_arrayN(
320  totpoly, sizeof(MLoop[4]), "nurbs_init mloop"); /* totloop */
321  *r_allpoly = mpoly = MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop");
322 
323  if (r_alluv) {
324  *r_alluv = mloopuv = MEM_calloc_arrayN(totpoly, sizeof(MLoopUV[4]), "nurbs_init mloopuv");
325  }
326 
327  /* verts and faces */
328  vertcount = 0;
329 
330  dl = dispbase->first;
331  while (dl) {
332  const bool is_smooth = (dl->rt & CU_SMOOTH) != 0;
333 
334  if (dl->type == DL_SEGM) {
335  startvert = vertcount;
336  a = dl->parts * dl->nr;
337  data = dl->verts;
338  while (a--) {
339  copy_v3_v3(mvert->co, data);
340  data += 3;
341  vertcount++;
342  mvert++;
343  }
344 
345  for (a = 0; a < dl->parts; a++) {
346  ofs = a * dl->nr;
347  for (b = 1; b < dl->nr; b++) {
348  medge->v1 = startvert + ofs + b - 1;
349  medge->v2 = startvert + ofs + b;
351 
352  medge++;
353  }
354  }
355  }
356  else if (dl->type == DL_POLY) {
357  if (conv_polys) {
358  startvert = vertcount;
359  a = dl->parts * dl->nr;
360  data = dl->verts;
361  while (a--) {
362  copy_v3_v3(mvert->co, data);
363  data += 3;
364  vertcount++;
365  mvert++;
366  }
367 
368  for (a = 0; a < dl->parts; a++) {
369  ofs = a * dl->nr;
370  for (b = 0; b < dl->nr; b++) {
371  medge->v1 = startvert + ofs + b;
372  if (b == dl->nr - 1) {
373  medge->v2 = startvert + ofs;
374  }
375  else {
376  medge->v2 = startvert + ofs + b + 1;
377  }
379  medge++;
380  }
381  }
382  }
383  }
384  else if (dl->type == DL_INDEX3) {
385  startvert = vertcount;
386  a = dl->nr;
387  data = dl->verts;
388  while (a--) {
389  copy_v3_v3(mvert->co, data);
390  data += 3;
391  vertcount++;
392  mvert++;
393  }
394 
395  a = dl->parts;
396  index = dl->index;
397  while (a--) {
398  mloop[0].v = startvert + index[0];
399  mloop[1].v = startvert + index[2];
400  mloop[2].v = startvert + index[1];
401  mpoly->loopstart = (int)(mloop - (*r_allloop));
402  mpoly->totloop = 3;
403  mpoly->mat_nr = dl->col;
404 
405  if (mloopuv) {
406  for (int i = 0; i < 3; i++, mloopuv++) {
407  mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
408  mloopuv->uv[1] = 0.0f;
409  }
410  }
411 
412  if (is_smooth) {
413  mpoly->flag |= ME_SMOOTH;
414  }
415  mpoly++;
416  mloop += 3;
417  index += 3;
418  }
419  }
420  else if (dl->type == DL_SURF) {
421  startvert = vertcount;
422  a = dl->parts * dl->nr;
423  data = dl->verts;
424  while (a--) {
425  copy_v3_v3(mvert->co, data);
426  data += 3;
427  vertcount++;
428  mvert++;
429  }
430 
431  for (a = 0; a < dl->parts; a++) {
432 
433  if ((dl->flag & DL_CYCL_V) == 0 && a == dl->parts - 1) {
434  break;
435  }
436 
437  if (dl->flag & DL_CYCL_U) { /* p2 -> p1 -> */
438  p1 = startvert + dl->nr * a; /* p4 -> p3 -> */
439  p2 = p1 + dl->nr - 1; /* -----> next row */
440  p3 = p1 + dl->nr;
441  p4 = p2 + dl->nr;
442  b = 0;
443  }
444  else {
445  p2 = startvert + dl->nr * a;
446  p1 = p2 + 1;
447  p4 = p2 + dl->nr;
448  p3 = p1 + dl->nr;
449  b = 1;
450  }
451  if ((dl->flag & DL_CYCL_V) && a == dl->parts - 1) {
452  p3 -= dl->parts * dl->nr;
453  p4 -= dl->parts * dl->nr;
454  }
455 
456  for (; b < dl->nr; b++) {
457  mloop[0].v = p1;
458  mloop[1].v = p3;
459  mloop[2].v = p4;
460  mloop[3].v = p2;
461  mpoly->loopstart = (int)(mloop - (*r_allloop));
462  mpoly->totloop = 4;
463  mpoly->mat_nr = dl->col;
464 
465  if (mloopuv) {
466  int orco_sizeu = dl->nr - 1;
467  int orco_sizev = dl->parts - 1;
468 
469  /* exception as handled in convertblender.c too */
470  if (dl->flag & DL_CYCL_U) {
471  orco_sizeu++;
472  if (dl->flag & DL_CYCL_V) {
473  orco_sizev++;
474  }
475  }
476  else if (dl->flag & DL_CYCL_V) {
477  orco_sizev++;
478  }
479 
480  for (int i = 0; i < 4; i++, mloopuv++) {
481  /* find uv based on vertex index into grid array */
482  int v = mloop[i].v - startvert;
483 
484  mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
485  mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
486 
487  /* cyclic correction */
488  if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f) {
489  mloopuv->uv[0] = 1.0f;
490  }
491  if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) {
492  mloopuv->uv[1] = 1.0f;
493  }
494  }
495  }
496 
497  if (is_smooth) {
498  mpoly->flag |= ME_SMOOTH;
499  }
500  mpoly++;
501  mloop += 4;
502 
503  p4 = p3;
504  p3++;
505  p2 = p1;
506  p1++;
507  }
508  }
509  }
510 
511  dl = dl->next;
512  }
513 
514  if (totpoly) {
515  make_edges_mdata_extend(r_alledge, &totedge, *r_allpoly, *r_allloop, totpoly);
516  }
517 
518  *r_totpoly = totpoly;
519  *r_totloop = totloop;
520  *r_totedge = totedge;
521  *r_totvert = totvert;
522 
523  return 0;
524 }
525 
527 {
528  Mesh *mesh;
529  MVert *allvert;
530  MEdge *alledge;
531  MLoop *allloop;
532  MPoly *allpoly;
533  MLoopUV *alluv = NULL;
534  int totvert, totedge, totloop, totpoly;
535 
537  dispbase,
538  &allvert,
539  &totvert,
540  &alledge,
541  &totedge,
542  &allloop,
543  &allpoly,
544  &alluv,
545  &totloop,
546  &totpoly) != 0) {
547  /* Error initializing mdata. This often happens when curve is empty */
548  return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
549  }
550 
551  mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
553 
554  memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
555  memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
556  memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
557  memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
558 
559  if (alluv) {
560  const char *uvname = "UVMap";
561  CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
562  }
563 
564  MEM_freeN(allvert);
565  MEM_freeN(alledge);
566  MEM_freeN(allloop);
567  MEM_freeN(allpoly);
568 
569  return mesh;
570 }
571 
573 {
574  ListBase disp = {NULL, NULL};
575 
576  if (ob->runtime.curve_cache) {
577  disp = ob->runtime.curve_cache->disp;
578  }
579 
580  return BKE_mesh_new_nomain_from_curve_displist(ob, &disp);
581 }
582 
583 /* this may fail replacing ob->data, be sure to check ob->type */
585  Main *bmain, Object *ob, ListBase *dispbase, const char *obdata_name, bool temporary)
586 {
587  Object *ob1;
588  Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
589  Mesh *me;
590  Curve *cu;
591  MVert *allvert = NULL;
592  MEdge *alledge = NULL;
593  MLoop *allloop = NULL;
594  MLoopUV *alluv = NULL;
595  MPoly *allpoly = NULL;
596  int totvert, totedge, totloop, totpoly;
597 
598  cu = ob->data;
599 
600  if (me_eval == NULL) {
602  dispbase,
603  &allvert,
604  &totvert,
605  &alledge,
606  &totedge,
607  &allloop,
608  &allpoly,
609  &alluv,
610  &totloop,
611  &totpoly) != 0) {
612  /* Error initializing */
613  return;
614  }
615 
616  /* make mesh */
617  if (bmain != NULL) {
618  me = BKE_mesh_add(bmain, obdata_name);
619  }
620  else {
621  me = BKE_id_new_nomain(ID_ME, obdata_name);
622  }
623 
624  me->totvert = totvert;
625  me->totedge = totedge;
626  me->totloop = totloop;
627  me->totpoly = totpoly;
628 
629  me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
630  me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
631  me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
632  me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
633 
634  if (alluv) {
635  const char *uvname = "UVMap";
636  me->mloopuv = CustomData_add_layer_named(
637  &me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
638  }
639 
641  }
642  else {
643  if (bmain != NULL) {
644  me = BKE_mesh_add(bmain, obdata_name);
645  }
646  else {
647  me = BKE_id_new_nomain(ID_ME, obdata_name);
648  }
649 
650  ob->runtime.data_eval = NULL;
651  BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
652  }
653 
654  me->totcol = cu->totcol;
655  me->mat = cu->mat;
656 
657  /* Copy evaluated texture space from curve to mesh.
658  *
659  * Note that we disable auto texture space feature since that will cause
660  * texture space to evaluate differently for curve and mesh, since curve
661  * uses CV to calculate bounding box, and mesh uses what is coming from
662  * tessellated curve.
663  */
664  me->texflag = cu->texflag & ~CU_AUTOSPACE;
665  copy_v3_v3(me->loc, cu->loc);
666  copy_v3_v3(me->size, cu->size);
668 
669  cu->mat = NULL;
670  cu->totcol = 0;
671 
672  /* Do not decrement ob->data usercount here,
673  * it's done at end of func with BKE_id_free_us() call. */
674  ob->data = me;
675  ob->type = OB_MESH;
676 
677  /* other users */
678  if (bmain != NULL) {
679  ob1 = bmain->objects.first;
680  while (ob1) {
681  if (ob1->data == cu) {
682  ob1->type = OB_MESH;
683 
684  id_us_min((ID *)ob1->data);
685  ob1->data = ob->data;
686  id_us_plus((ID *)ob1->data);
687  }
688  ob1 = ob1->id.next;
689  }
690  }
691 
692  if (temporary) {
693  /* For temporary objects in BKE_mesh_new_from_object don't remap
694  * the entire scene with associated depsgraph updates, which are
695  * problematic for renderers exporting data. */
696  BKE_id_free(NULL, cu);
697  }
698  else {
699  BKE_id_free_us(bmain, cu);
700  }
701 }
702 
703 void BKE_mesh_from_nurbs(Main *bmain, Object *ob)
704 {
705  Curve *cu = (Curve *)ob->data;
706  ListBase disp = {NULL, NULL};
707 
708  if (ob->runtime.curve_cache) {
709  disp = ob->runtime.curve_cache->disp;
710  }
711 
712  BKE_mesh_from_nurbs_displist(bmain, ob, &disp, cu->id.name, false);
713 }
714 
715 typedef struct EdgeLink {
716  struct EdgeLink *next, *prev;
717  void *edge;
719 
720 typedef struct VertLink {
722  unsigned int index;
724 
725 static void prependPolyLineVert(ListBase *lb, unsigned int index)
726 {
727  VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
728  vl->index = index;
729  BLI_addhead(lb, vl);
730 }
731 
732 static void appendPolyLineVert(ListBase *lb, unsigned int index)
733 {
734  VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
735  vl->index = index;
736  BLI_addtail(lb, vl);
737 }
738 
739 void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
740 {
741  MVert *mvert = me->mvert;
742  MEdge *med, *medge = me->medge;
743  MPoly *mp, *mpoly = me->mpoly;
744  MLoop *mloop = me->mloop;
745 
746  int medge_len = me->totedge;
747  int mpoly_len = me->totpoly;
748  int totedges = 0;
749  int i;
750 
751  /* only to detect edge polylines */
752  int *edge_users;
753 
754  ListBase edges = {NULL, NULL};
755 
756  /* get boundary edges */
757  edge_users = MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
758  for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
759  MLoop *ml = &mloop[mp->loopstart];
760  int j;
761  for (j = 0; j < mp->totloop; j++, ml++) {
762  edge_users[ml->e]++;
763  }
764  }
765 
766  /* create edges from all faces (so as to find edges not in any faces) */
767  med = medge;
768  for (i = 0; i < medge_len; i++, med++) {
769  if (edge_users[i] == edge_users_test) {
770  EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
771  edl->edge = med;
772 
773  BLI_addtail(&edges, edl);
774  totedges++;
775  }
776  }
777  MEM_freeN(edge_users);
778 
779  if (edges.first) {
780  while (edges.first) {
781  /* each iteration find a polyline and add this as a nurbs poly spline */
782 
783  ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */
784  bool closed = false;
785  int totpoly = 0;
786  MEdge *med_current = ((EdgeLink *)edges.last)->edge;
787  unsigned int startVert = med_current->v1;
788  unsigned int endVert = med_current->v2;
789  bool ok = true;
790 
791  appendPolyLineVert(&polyline, startVert);
792  totpoly++;
793  appendPolyLineVert(&polyline, endVert);
794  totpoly++;
795  BLI_freelinkN(&edges, edges.last);
796  totedges--;
797 
798  while (ok) { /* while connected edges are found... */
799  EdgeLink *edl = edges.last;
800  ok = false;
801  while (edl) {
802  EdgeLink *edl_prev = edl->prev;
803 
804  med = edl->edge;
805 
806  if (med->v1 == endVert) {
807  endVert = med->v2;
808  appendPolyLineVert(&polyline, med->v2);
809  totpoly++;
810  BLI_freelinkN(&edges, edl);
811  totedges--;
812  ok = true;
813  }
814  else if (med->v2 == endVert) {
815  endVert = med->v1;
816  appendPolyLineVert(&polyline, endVert);
817  totpoly++;
818  BLI_freelinkN(&edges, edl);
819  totedges--;
820  ok = true;
821  }
822  else if (med->v1 == startVert) {
823  startVert = med->v2;
824  prependPolyLineVert(&polyline, startVert);
825  totpoly++;
826  BLI_freelinkN(&edges, edl);
827  totedges--;
828  ok = true;
829  }
830  else if (med->v2 == startVert) {
831  startVert = med->v1;
832  prependPolyLineVert(&polyline, startVert);
833  totpoly++;
834  BLI_freelinkN(&edges, edl);
835  totedges--;
836  ok = true;
837  }
838 
839  edl = edl_prev;
840  }
841  }
842 
843  /* Now we have a polyline, make into a curve */
844  if (startVert == endVert) {
845  BLI_freelinkN(&polyline, polyline.last);
846  totpoly--;
847  closed = true;
848  }
849 
850  /* --- nurbs --- */
851  {
852  Nurb *nu;
853  BPoint *bp;
854  VertLink *vl;
855 
856  /* create new 'nurb' within the curve */
857  nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb");
858 
859  nu->pntsu = totpoly;
860  nu->pntsv = 1;
861  nu->orderu = 4;
862  nu->flagu = CU_NURB_ENDPOINT | (closed ? CU_NURB_CYCLIC : 0); /* endpoint */
863  nu->resolu = 12;
864 
865  nu->bp = (BPoint *)MEM_calloc_arrayN(totpoly, sizeof(BPoint), "bpoints");
866 
867  /* add points */
868  vl = polyline.first;
869  for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
870  copy_v3_v3(bp->vec, mvert[vl->index].co);
871  bp->f1 = SELECT;
872  bp->radius = bp->weight = 1.0;
873  }
874  BLI_freelistN(&polyline);
875 
876  /* add nurb to curve */
877  BLI_addtail(nurblist, nu);
878  }
879  /* --- done with nurbs --- */
880  }
881  }
882 }
883 
885 {
886  /* make new mesh data from the original copy */
887  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
888  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
889  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
890  ListBase nurblist = {NULL, NULL};
891 
892  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
893  BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);
894 
895  if (nurblist.first) {
896  Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE);
897  cu->flag |= CU_3D;
898 
899  cu->nurb = nurblist;
900 
901  id_us_min(&((Mesh *)ob->data)->id);
902  ob->data = cu;
903  ob->type = OB_CURVE;
904 
906  }
907 }
908 
910 {
911  BLI_assert(me != NULL);
912 
913  pointcloud->totpoint = me->totvert;
914  CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint);
915 
916  /* Copy over all attributes. */
917  const CustomData_MeshMasks mask = {
918  .vmask = CD_MASK_PROP_ALL,
919  };
920  CustomData_merge(&me->vdata, &pointcloud->pdata, mask.vmask, CD_DUPLICATE, me->totvert);
922  CustomData_update_typemap(&pointcloud->pdata);
923 
924  MVert *mvert;
925  mvert = me->mvert;
926  for (int i = 0; i < me->totvert; i++, mvert++) {
927  copy_v3_v3(pointcloud->co[i], mvert->co);
928  }
929 }
930 
932 {
933  BLI_assert(ob->type == OB_MESH);
934 
935  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
936  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
937  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
938 
939  PointCloud *pointcloud = BKE_pointcloud_add(bmain, ob->id.name + 2);
940 
941  BKE_pointcloud_from_mesh(me_eval, pointcloud);
942 
943  BKE_id_materials_copy(bmain, (ID *)ob->data, (ID *)pointcloud);
944 
945  id_us_min(&((Mesh *)ob->data)->id);
946  ob->data = pointcloud;
947  ob->type = OB_POINTCLOUD;
948 
950 }
951 
952 void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
953 {
954  BLI_assert(pointcloud != NULL);
955 
956  me->totvert = pointcloud->totpoint;
957 
958  /* Merge over all attributes. */
959  const CustomData_MeshMasks mask = {
960  .vmask = CD_MASK_PROP_ALL,
961  };
962  CustomData_merge(&pointcloud->pdata, &me->vdata, mask.vmask, CD_DUPLICATE, pointcloud->totpoint);
963 
964  /* Convert the Position attribute to a mesh vertex. */
965  me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
966  CustomData_update_typemap(&me->vdata);
967 
968  const int layer_idx = CustomData_get_named_layer_index(
970  CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx];
971  float(*positions)[3] = pos_layer->data;
972 
973  MVert *mvert;
974  mvert = me->mvert;
975  for (int i = 0; i < me->totvert; i++, mvert++) {
976  copy_v3_v3(mvert->co, positions[i]);
977  }
978 
979  /* Delete Position attribute since it is now in vertex coordinates. */
980  CustomData_free_layer(&me->vdata, CD_PROP_FLOAT3, me->totvert, layer_idx);
981 }
982 
984 {
985  MEdge *med = mesh->medge;
986  for (int i = 0; i < mesh->totedge; i++, med++) {
987  med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
988  }
989 }
990 
992 {
993  BLI_assert(ob->type == OB_POINTCLOUD);
994 
995  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
996  PointCloud *pointcloud_eval = (PointCloud *)ob_eval->runtime.data_eval;
997 
998  Mesh *me = BKE_mesh_add(bmain, ob->id.name + 2);
999 
1000  BKE_mesh_from_pointcloud(pointcloud_eval, me);
1001 
1002  BKE_id_materials_copy(bmain, (ID *)ob->data, (ID *)me);
1003 
1004  id_us_min(&((PointCloud *)ob->data)->id);
1005  ob->data = me;
1006  ob->type = OB_MESH;
1007 
1009 }
1010 
1011 /* Create a temporary object to be used for nurbs-to-mesh conversion.
1012  *
1013  * This is more complex that it should be because BKE_mesh_from_nurbs_displist() will do more than
1014  * simply conversion and will attempt to take over ownership of evaluated result and will also
1015  * modify the input object. */
1017 {
1018  Curve *curve = (Curve *)object->data;
1019 
1020  /* Create object itself. */
1021  Object *temp_object = (Object *)BKE_id_copy_ex(NULL, &object->id, NULL, LIB_ID_COPY_LOCALIZE);
1022 
1023  /* Remove all modifiers, since we don't want them to be applied. */
1025 
1026  /* Copy relevant evaluated fields of curve cache.
1027  *
1028  * Note that there are extra fields in there like bevel and path, but those are not needed during
1029  * conversion, so they are not copied to save unnecessary allocations. */
1030  if (object->runtime.curve_cache != NULL) {
1031  temp_object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache),
1032  "CurveCache for curve types");
1033  BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
1034  }
1035  /* Constructive modifiers will use mesh to store result. */
1036  if (object->runtime.data_eval != NULL) {
1038  NULL, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
1039  }
1040 
1041  /* Need to create copy of curve itself as well, it will be freed by underlying conversion
1042  * functions.
1043  *
1044  * NOTE: Copies the data, but not the shapekeys. */
1045  BKE_id_copy_ex(NULL, object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE);
1046  Curve *temp_curve = (Curve *)temp_object->data;
1047 
1048  /* Make sure texture space is calculated for a copy of curve, it will be used for the final
1049  * result. */
1050  BKE_curve_texspace_calc(temp_curve);
1051 
1052  /* Temporarily set edit so we get updates from edit mode, but also because for text datablocks
1053  * copying it while in edit mode gives invalid data structures. */
1054  temp_curve->editfont = curve->editfont;
1055  temp_curve->editnurb = curve->editnurb;
1056 
1057  return temp_object;
1058 }
1059 
1060 static void curve_to_mesh_eval_ensure(Object *object)
1061 {
1062  if (object->runtime.curve_cache == NULL) {
1063  object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
1064  }
1065  Curve *curve = (Curve *)object->data;
1066  Curve remapped_curve = *curve;
1067  Object remapped_object = *object;
1068  remapped_object.runtime.bb = NULL;
1069  remapped_object.data = &remapped_curve;
1070 
1071  /* Clear all modifiers for the bevel object.
1072  *
1073  * This is because they can not be reliably evaluated for an original object (at least because
1074  * the state of dependencies is not know).
1075  *
1076  * So we create temporary copy of the object which will use same data as the original bevel, but
1077  * will have no modifiers. */
1078  Object bevel_object = {{NULL}};
1079  if (remapped_curve.bevobj != NULL) {
1080  bevel_object = *remapped_curve.bevobj;
1081  bevel_object.runtime.bb = NULL;
1082  BLI_listbase_clear(&bevel_object.modifiers);
1083  remapped_curve.bevobj = &bevel_object;
1084  }
1085 
1086  /* Same thing for taper. */
1087  Object taper_object = {{NULL}};
1088  if (remapped_curve.taperobj != NULL) {
1089  taper_object = *remapped_curve.taperobj;
1090  taper_object.runtime.bb = NULL;
1091  BLI_listbase_clear(&taper_object.modifiers);
1092  remapped_curve.taperobj = &taper_object;
1093  }
1094 
1095  /* NOTE: We don't have dependency graph or scene here, so we pass NULL. This is all fine since
1096  * they are only used for modifier stack, which we have explicitly disabled for all objects.
1097  *
1098  * TODO(sergey): This is a very fragile logic, but proper solution requires re-writing quite a
1099  * bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also
1100  * Mesh From Curve operator.
1101  * Brecht says hold off with that. */
1102  Mesh *mesh_eval = NULL;
1104  NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false);
1105 
1106  /* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
1107  * real issue currently, code here is broken in more than one way, fix(es) will be done
1108  * separately. */
1109  if (mesh_eval != NULL) {
1110  BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true);
1111  }
1112 
1113  MEM_SAFE_FREE(remapped_object.runtime.bb);
1114  MEM_SAFE_FREE(taper_object.runtime.bb);
1115  MEM_SAFE_FREE(bevel_object.runtime.bb);
1116 
1117  BKE_object_free_curve_cache(&bevel_object);
1118  BKE_object_free_curve_cache(&taper_object);
1119 }
1120 
1122 {
1123  Curve *curve = object->data;
1124  Object *temp_object = object_for_curve_to_mesh_create(object);
1125  Curve *temp_curve = (Curve *)temp_object->data;
1126 
1127  /* When input object is an original one, we don't have evaluated curve cache yet, so need to
1128  * create it in the temporary object. */
1129  if (!DEG_is_evaluated_object(object)) {
1130  curve_to_mesh_eval_ensure(temp_object);
1131  }
1132 
1133  /* Reset pointers before conversion. */
1134  temp_curve->editfont = NULL;
1135  temp_curve->editnurb = NULL;
1136 
1137  /* Convert to mesh. */
1139  NULL, temp_object, &temp_object->runtime.curve_cache->disp, curve->id.name + 2, true);
1140 
1141  /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked. If it didn't the curve did
1142  * not have any segments or otherwise would have generated an empty mesh. */
1143  if (temp_object->type != OB_MESH) {
1144  BKE_id_free(NULL, temp_object->data);
1145  BKE_id_free(NULL, temp_object);
1146  return NULL;
1147  }
1148 
1149  Mesh *mesh_result = temp_object->data;
1150 
1151  BKE_id_free(NULL, temp_object);
1152 
1153  /* NOTE: Materials are copied in BKE_mesh_from_nurbs_displist(). */
1154 
1155  return mesh_result;
1156 }
1157 
1159 {
1160  MetaBall *mball = (MetaBall *)object->data;
1161 
1162  /* NOTE: We can only create mesh for a polygonized meta ball. This figures out all original meta
1163  * balls and all evaluated child meta balls (since polygonization is only stored in the mother
1164  * ball).
1165  *
1166  * We create empty mesh so scripters don't run into None objects. */
1167  if (!DEG_is_evaluated_object(object) || object->runtime.curve_cache == NULL ||
1169  return BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
1170  }
1171 
1172  Mesh *mesh_result = BKE_id_new_nomain(ID_ME, ((ID *)object->data)->name + 2);
1173  BKE_mesh_from_metaball(&object->runtime.curve_cache->disp, mesh_result);
1174  BKE_mesh_texspace_copy_from_object(mesh_result, object);
1175 
1176  /* Copy materials. */
1177  mesh_result->totcol = mball->totcol;
1178  mesh_result->mat = MEM_dupallocN(mball->mat);
1179  if (mball->mat != NULL) {
1180  for (int i = mball->totcol; i-- > 0;) {
1181  mesh_result->mat[i] = BKE_object_material_get(object, i + 1);
1182  }
1183  }
1184 
1185  return mesh_result;
1186 }
1187 
1189 {
1190  /* While we could copy this into the new mesh,
1191  * add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
1193 
1194  Mesh *mesh_result = (Mesh *)BKE_id_copy_ex(
1196  /* NOTE: Materials should already be copied. */
1197  /* Copy original mesh name. This is because edit meshes might not have one properly set name. */
1198  BLI_strncpy(mesh_result->id.name, ((ID *)object->data)->name, sizeof(mesh_result->id.name));
1199  return mesh_result;
1200 }
1201 
1203  Object *object,
1204  const bool preserve_origindex)
1205 {
1206  if (DEG_is_original_id(&object->id)) {
1207  return mesh_new_from_mesh(object, (Mesh *)object->data);
1208  }
1209 
1210  if (depsgraph == NULL) {
1211  return NULL;
1212  }
1213 
1214  Object object_for_eval = *object;
1215  if (object_for_eval.runtime.data_orig != NULL) {
1216  object_for_eval.data = object_for_eval.runtime.data_orig;
1217  }
1218 
1221  if (preserve_origindex) {
1222  mask.vmask |= CD_MASK_ORIGINDEX;
1223  mask.emask |= CD_MASK_ORIGINDEX;
1224  mask.lmask |= CD_MASK_ORIGINDEX;
1225  mask.pmask |= CD_MASK_ORIGINDEX;
1226  }
1227  Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
1228  return result;
1229 }
1230 
1232  Object *object,
1233  const bool preserve_all_data_layers,
1234  const bool preserve_origindex)
1235 {
1236  if (preserve_all_data_layers || preserve_origindex) {
1237  return mesh_new_from_mesh_object_with_layers(depsgraph, object, preserve_origindex);
1238  }
1239  Mesh *mesh_input = object->data;
1240  /* If we are in edit mode, use evaluated mesh from edit structure, matching to what
1241  * viewport is using for visualization. */
1242  if (mesh_input->edit_mesh != NULL && mesh_input->edit_mesh->mesh_eval_final) {
1243  mesh_input = mesh_input->edit_mesh->mesh_eval_final;
1244  }
1245  return mesh_new_from_mesh(object, mesh_input);
1246 }
1247 
1249  Object *object,
1250  const bool preserve_all_data_layers,
1251  const bool preserve_origindex)
1252 {
1253  Mesh *new_mesh = NULL;
1254  switch (object->type) {
1255  case OB_FONT:
1256  case OB_CURVE:
1257  case OB_SURF:
1258  new_mesh = mesh_new_from_curve_type_object(object);
1259  break;
1260  case OB_MBALL:
1261  new_mesh = mesh_new_from_mball_object(object);
1262  break;
1263  case OB_MESH:
1264  new_mesh = mesh_new_from_mesh_object(
1265  depsgraph, object, preserve_all_data_layers, preserve_origindex);
1266  break;
1267  default:
1268  /* Object does not have geometry data. */
1269  return NULL;
1270  }
1271  if (new_mesh == NULL) {
1272  /* Happens in special cases like request of mesh for non-mother meta ball. */
1273  return NULL;
1274  }
1275 
1276  /* The result must have 0 users, since it's just a mesh which is free-dangling data-block.
1277  * All the conversion functions are supposed to ensure mesh is not counted. */
1278  BLI_assert(new_mesh->id.us == 0);
1279 
1280  /* It is possible that mesh came from modifier stack evaluation, which preserves edit_mesh
1281  * pointer (which allows draw manager to access edit mesh when drawing). Normally this does
1282  * not cause ownership problems because evaluated object runtime is keeping track of the real
1283  * ownership.
1284  *
1285  * Here we are constructing a mesh which is supposed to be independent, which means no shared
1286  * ownership is allowed, so we make sure edit mesh is reset to NULL (which is similar to as if
1287  * one duplicates the objects and applies all the modifiers). */
1288  new_mesh->edit_mesh = NULL;
1289 
1290  return new_mesh;
1291 }
1292 
1294 {
1295  ID **id_p = cb_data->id_pointer;
1296  if (*id_p == NULL) {
1297  return IDWALK_RET_NOP;
1298  }
1299  *id_p = DEG_get_original_id(*id_p);
1300 
1301  return IDWALK_RET_NOP;
1302 }
1303 
1305 {
1306  ID **id_p = cb_data->id_pointer;
1307  if (*id_p == NULL) {
1308  return IDWALK_RET_NOP;
1309  }
1310 
1311  const int cb_flag = cb_data->cb_flag;
1312  if (cb_flag & IDWALK_CB_USER) {
1313  id_us_plus(*id_p);
1314  }
1315  else if (cb_flag & IDWALK_CB_USER_ONE) {
1316  /* Note: in that context, that one should not be needed (since there should be at least already
1317  * one USER_ONE user of that ID), but better be consistent. */
1318  id_us_ensure_real(*id_p);
1319  }
1320  return IDWALK_RET_NOP;
1321 }
1322 
1325  Object *object,
1326  bool preserve_all_data_layers)
1327 {
1329 
1330  Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers, false);
1331  if (mesh == NULL) {
1332  /* Unable to convert the object to a mesh, return an empty one. */
1333  Mesh *mesh_in_bmain = BKE_mesh_add(bmain, ((ID *)object->data)->name + 2);
1334  id_us_min(&mesh_in_bmain->id);
1335  return mesh_in_bmain;
1336  }
1337 
1338  /* Make sure mesh only points original datablocks, also increase users of materials and other
1339  * possibly referenced data-blocks.
1340  *
1341  * Going to original data-blocks is required to have bmain in a consistent state, where
1342  * everything is only allowed to reference original data-blocks.
1343  *
1344  * Note that user-count updates has to be done *after* mesh has been transferred to Main database
1345  * (since doing refcounting on non-Main IDs is forbidden). */
1348 
1349  /* Append the mesh to 'bmain'.
1350  * We do it a bit longer way since there is no simple and clear way of adding existing data-block
1351  * to the 'bmain'. So we allocate new empty mesh in the 'bmain' (which guarantees all the naming
1352  * and orders and flags) and move the temporary mesh in place there. */
1353  Mesh *mesh_in_bmain = BKE_mesh_add(bmain, mesh->id.name + 2);
1354 
1355  /* NOTE: BKE_mesh_nomain_to_mesh() does not copy materials and instead it preserves them in the
1356  * destination mesh. So we "steal" all related fields before calling it.
1357  *
1358  * TODO(sergey): We really better have a function which gets and ID and accepts it for the bmain.
1359  */
1360  mesh_in_bmain->mat = mesh->mat;
1361  mesh_in_bmain->totcol = mesh->totcol;
1362  mesh_in_bmain->flag = mesh->flag;
1363  mesh_in_bmain->smoothresh = mesh->smoothresh;
1364  mesh->mat = NULL;
1365 
1366  BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, NULL, &CD_MASK_MESH, true);
1367 
1368  /* User-count is required because so far mesh was in a limbo, where library management does
1369  * not perform any user management (i.e. copy of a mesh will not increase users of materials). */
1372 
1373  /* Make sure user count from BKE_mesh_add() is the one we expect here and bring it down to 0. */
1374  BLI_assert(mesh_in_bmain->id.us == 1);
1375  id_us_min(&mesh_in_bmain->id);
1376 
1377  return mesh_in_bmain;
1378 }
1379 
1380 static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
1381 {
1382  KeyBlock *kb;
1383  Key *key = mesh_src->key;
1384  int i;
1385 
1386  if (!mesh_src->key) {
1387  return;
1388  }
1389 
1390  /* ensure we can use mesh vertex count for derived mesh custom data */
1391  if (mesh_src->totvert != mesh_dest->totvert) {
1392  CLOG_ERROR(&LOG,
1393  "vertex size mismatch (mesh/dm) '%s' (%d != %d)",
1394  mesh_src->id.name + 2,
1395  mesh_src->totvert,
1396  mesh_dest->totvert);
1397  return;
1398  }
1399 
1400  for (i = 0, kb = key->block.first; kb; kb = kb->next, i++) {
1401  int ci;
1402  float *array;
1403 
1404  if (mesh_src->totvert != kb->totelem) {
1405  CLOG_ERROR(&LOG,
1406  "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)",
1407  mesh_src->id.name + 2,
1408  mesh_src->totvert,
1409  kb->name,
1410  kb->totelem);
1411  array = MEM_calloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
1412  }
1413  else {
1414  array = MEM_malloc_arrayN((size_t)mesh_src->totvert, sizeof(float[3]), __func__);
1415  memcpy(array, kb->data, sizeof(float[3]) * (size_t)mesh_src->totvert);
1416  }
1417 
1419  &mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name);
1420  ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i);
1421 
1422  mesh_dest->vdata.layers[ci].uid = kb->uid;
1423  }
1424 }
1425 
1427  Scene *scene,
1428  Object *ob_eval,
1429  ModifierData *md_eval,
1430  const bool build_shapekey_layers)
1431 {
1432  Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
1433  const ModifierTypeInfo *mti = BKE_modifier_get_info(md_eval->type);
1434  Mesh *result = NULL;
1435  KeyBlock *kb;
1437 
1438  if (!(md_eval->mode & eModifierMode_Realtime)) {
1439  return result;
1440  }
1441 
1442  if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) {
1443  return result;
1444  }
1445 
1446  if (build_shapekey_layers && me->key &&
1447  (kb = BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) {
1449  }
1450 
1451  if (mti->type == eModifierTypeType_OnlyDeform) {
1452  int numVerts;
1453  float(*deformedVerts)[3] = BKE_mesh_vert_coords_alloc(me, &numVerts);
1454 
1456  mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts);
1457  BKE_mesh_vert_coords_apply(result, deformedVerts);
1458 
1459  if (build_shapekey_layers) {
1461  }
1462 
1463  MEM_freeN(deformedVerts);
1464  }
1465  else {
1466  Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(NULL, &me->id, NULL, LIB_ID_COPY_LOCALIZE);
1467 
1468  if (build_shapekey_layers) {
1469  add_shapekey_layers(mesh_temp, me);
1470  }
1471 
1472  result = mti->modifyMesh(md_eval, &mectx, mesh_temp);
1474 
1475  if (mesh_temp != result) {
1476  BKE_id_free(NULL, mesh_temp);
1477  }
1478  }
1479 
1480  return result;
1481 }
1482 
1483 /* This is a Mesh-based copy of the same function in DerivedMesh.cc */
1484 static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
1485 {
1486  KeyBlock *kb;
1487  int i, j, tot;
1488 
1489  if (!mesh_dst->key) {
1490  return;
1491  }
1492 
1493  tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY);
1494  for (i = 0; i < tot; i++) {
1495  CustomDataLayer *layer =
1496  &mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
1497  float(*cos)[3], (*kbcos)[3];
1498 
1499  for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
1500  if (kb->uid == layer->uid) {
1501  break;
1502  }
1503  }
1504 
1505  if (!kb) {
1506  kb = BKE_keyblock_add(mesh_dst->key, layer->name);
1507  kb->uid = layer->uid;
1508  }
1509 
1510  if (kb->data) {
1511  MEM_freeN(kb->data);
1512  }
1513 
1514  cos = CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i);
1515  kb->totelem = mesh_src->totvert;
1516 
1517  kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
1518  if (kb->uid == actshape_uid) {
1519  MVert *mvert = mesh_src->mvert;
1520 
1521  for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) {
1522  copy_v3_v3(*kbcos, mvert->co);
1523  }
1524  }
1525  else {
1526  for (j = 0; j < kb->totelem; j++, cos++, kbcos++) {
1527  copy_v3_v3(*kbcos, *cos);
1528  }
1529  }
1530  }
1531 
1532  for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
1533  if (kb->totelem != mesh_src->totvert) {
1534  if (kb->data) {
1535  MEM_freeN(kb->data);
1536  }
1537 
1538  kb->totelem = mesh_src->totvert;
1539  kb->data = MEM_calloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
1540  CLOG_ERROR(&LOG, "lost a shapekey layer: '%s'! (bmesh internal error)", kb->name);
1541  }
1542  }
1543 }
1544 
1546  Mesh *mesh_dst,
1547  Object *ob,
1548  const CustomData_MeshMasks *mask,
1549  bool take_ownership)
1550 {
1551  BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
1552 
1553  /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
1554  /* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh);
1555  * check whether it is still true with Mesh */
1556  Mesh tmp = *mesh_dst;
1557  int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
1558  int did_shapekeys = 0;
1559  eCDAllocType alloctype = CD_DUPLICATE;
1560 
1561  if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) {
1562  bool has_any_referenced_layers = CustomData_has_referenced(&mesh_src->vdata) ||
1563  CustomData_has_referenced(&mesh_src->edata) ||
1564  CustomData_has_referenced(&mesh_src->ldata) ||
1565  CustomData_has_referenced(&mesh_src->fdata) ||
1566  CustomData_has_referenced(&mesh_src->pdata);
1567  if (!has_any_referenced_layers) {
1568  alloctype = CD_ASSIGN;
1569  }
1570  }
1571  CustomData_reset(&tmp.vdata);
1572  CustomData_reset(&tmp.edata);
1573  CustomData_reset(&tmp.fdata);
1574  CustomData_reset(&tmp.ldata);
1575  CustomData_reset(&tmp.pdata);
1576 
1577  BKE_mesh_ensure_normals(mesh_src);
1578 
1579  totvert = tmp.totvert = mesh_src->totvert;
1580  totedge = tmp.totedge = mesh_src->totedge;
1581  totloop = tmp.totloop = mesh_src->totloop;
1582  totpoly = tmp.totpoly = mesh_src->totpoly;
1583  tmp.totface = 0;
1584 
1585  CustomData_copy(&mesh_src->vdata, &tmp.vdata, mask->vmask, alloctype, totvert);
1586  CustomData_copy(&mesh_src->edata, &tmp.edata, mask->emask, alloctype, totedge);
1587  CustomData_copy(&mesh_src->ldata, &tmp.ldata, mask->lmask, alloctype, totloop);
1588  CustomData_copy(&mesh_src->pdata, &tmp.pdata, mask->pmask, alloctype, totpoly);
1589  tmp.cd_flag = mesh_src->cd_flag;
1590  tmp.runtime.deformed_only = mesh_src->runtime.deformed_only;
1591 
1592  if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
1593  KeyBlock *kb;
1594  int uid;
1595 
1596  if (ob) {
1597  kb = BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
1598  if (kb) {
1599  uid = kb->uid;
1600  }
1601  else {
1602  CLOG_ERROR(&LOG, "could not find active shapekey %d!", ob->shapenr - 1);
1603 
1604  uid = INT_MAX;
1605  }
1606  }
1607  else {
1608  /* if no object, set to INT_MAX so we don't mess up any shapekey layers */
1609  uid = INT_MAX;
1610  }
1611 
1612  shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid);
1613  did_shapekeys = 1;
1614  }
1615 
1616  /* copy texture space */
1617  if (ob) {
1619  }
1620 
1621  /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
1622  * we set them here in case they are missing */
1623  /* TODO(Sybren): we could probably replace CD_ASSIGN with alloctype and
1624  * always directly pass mesh_src->mxxx, instead of using a ternary operator. */
1625  if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
1626  CustomData_add_layer(&tmp.vdata,
1627  CD_MVERT,
1628  CD_ASSIGN,
1629  (alloctype == CD_ASSIGN) ? mesh_src->mvert :
1630  MEM_dupallocN(mesh_src->mvert),
1631  totvert);
1632  }
1633  if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
1634  CustomData_add_layer(&tmp.edata,
1635  CD_MEDGE,
1636  CD_ASSIGN,
1637  (alloctype == CD_ASSIGN) ? mesh_src->medge :
1638  MEM_dupallocN(mesh_src->medge),
1639  totedge);
1640  }
1641  if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
1642  /* TODO(Sybren): assignment to tmp.mxxx is probably not necessary due to the
1643  * BKE_mesh_update_customdata_pointers() call below. */
1644  tmp.mloop = (alloctype == CD_ASSIGN) ? mesh_src->mloop : MEM_dupallocN(mesh_src->mloop);
1645  tmp.mpoly = (alloctype == CD_ASSIGN) ? mesh_src->mpoly : MEM_dupallocN(mesh_src->mpoly);
1646 
1648  CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
1649  }
1650 
1651  /* object had got displacement layer, should copy this layer to save sculpted data */
1652  /* NOTE: maybe some other layers should be copied? nazgul */
1653  if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) {
1654  if (totloop == mesh_dst->totloop) {
1655  MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
1656  CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
1657  if (alloctype == CD_ASSIGN) {
1658  /* Assign NULL to prevent double-free. */
1659  CustomData_set_layer(&mesh_dst->ldata, CD_MDISPS, NULL);
1660  }
1661  }
1662  }
1663 
1664  /* yes, must be before _and_ after tessellate */
1666 
1667  /* since 2.65 caller must do! */
1668  // BKE_mesh_tessface_calc(&tmp);
1669 
1670  CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
1671  CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
1672  CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
1673  CustomData_free(&mesh_dst->ldata, mesh_dst->totloop);
1674  CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly);
1675 
1676  /* ok, this should now use new CD shapekey data,
1677  * which should be fed through the modifier
1678  * stack */
1679  if (tmp.totvert != mesh_dst->totvert && !did_shapekeys && mesh_dst->key) {
1680  CLOG_ERROR(&LOG, "YEEK! this should be recoded! Shape key loss!: ID '%s'", tmp.id.name);
1681  if (tmp.key && !(tmp.id.tag & LIB_TAG_NO_MAIN)) {
1682  id_us_min(&tmp.key->id);
1683  }
1684  tmp.key = NULL;
1685  }
1686 
1687  /* Clear selection history */
1688  MEM_SAFE_FREE(tmp.mselect);
1689  tmp.totselect = 0;
1691 
1692  /* Clear any run-time data.
1693  * Even though this mesh wont typically have run-time data, the Python API can for e.g.
1694  * create loop-triangle cache here, which is confusing when left in the mesh, see: T81136. */
1696 
1697  /* skip the listbase */
1698  MEMCPY_STRUCT_AFTER(mesh_dst, &tmp, id.prev);
1699 
1700  if (take_ownership) {
1701  if (alloctype == CD_ASSIGN) {
1702  CustomData_free_typemask(&mesh_src->vdata, mesh_src->totvert, ~mask->vmask);
1703  CustomData_free_typemask(&mesh_src->edata, mesh_src->totedge, ~mask->emask);
1704  CustomData_free_typemask(&mesh_src->ldata, mesh_src->totloop, ~mask->lmask);
1705  CustomData_free_typemask(&mesh_src->pdata, mesh_src->totpoly, ~mask->pmask);
1706  }
1707  BKE_id_free(NULL, mesh_src);
1708  }
1709 }
1710 
1711 void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
1712 {
1713  BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
1714 
1715  int a, totvert = mesh_src->totvert;
1716  float *fp;
1717  MVert *mvert;
1718 
1719  if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
1720  return;
1721  }
1722 
1723  if (kb->data) {
1724  MEM_freeN(kb->data);
1725  }
1726  kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data");
1727  kb->totelem = totvert;
1728 
1729  fp = kb->data;
1730  mvert = mesh_src->mvert;
1731 
1732  for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
1733  copy_v3_v3(fp, mvert->co);
1734  }
1735 }
typedef float(TangentPoint)[2]
struct Curve * BKE_curve_add(struct Main *bmain, const char *name, int type)
Definition: curve.c:424
#define CU_DO_2DFILL(cu)
Definition: BKE_curve.h:86
void BKE_curve_texspace_calc(struct Curve *cu)
Definition: curve.c:517
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.c:2239
int CustomData_number_of_layers(const struct CustomData *data, int type)
bool CustomData_free_layer(struct CustomData *data, int type, int totelem, int index)
Definition: customdata.c:2655
eCDAllocType
@ CD_ASSIGN
@ CD_CALLOC
@ CD_DUPLICATE
bool CustomData_has_layer(const struct CustomData *data, int type)
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name)
void * CustomData_set_layer(const struct CustomData *data, int type, void *ptr)
int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
Definition: customdata.c:2308
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.c:2637
bool CustomData_has_referenced(const struct CustomData *data)
Definition: customdata.c:3881
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
bool CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2098
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2193
void CustomData_realloc(struct CustomData *data, int totelem)
Definition: customdata.c:2180
void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask)
Definition: customdata.c:2253
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.c:1933
void CustomData_reset(struct CustomData *data)
Definition: customdata.c:2233
void CustomData_update_typemap(struct CustomData *data)
Definition: customdata.c:2071
display list (or rather multi purpose list) stuff.
void BKE_displist_copy(struct ListBase *lbn, const struct ListBase *lb)
@ DL_CYCL_V
Definition: BKE_displist.h:54
@ DL_CYCL_U
Definition: BKE_displist.h:53
void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct Mesh **r_final, const bool for_orco)
@ DL_SURF
Definition: BKE_displist.h:40
@ DL_INDEX4
Definition: BKE_displist.h:44
@ DL_INDEX3
Definition: BKE_displist.h:42
@ DL_POLY
Definition: BKE_displist.h:36
@ DL_SEGM
Definition: BKE_displist.h:38
void BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me)
Definition: key.c:2224
struct KeyBlock * BKE_keyblock_add(struct Key *key, const char *name)
Definition: key.c:1817
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void * BKE_id_new_nomain(const short type, const char *name)
Definition: lib_id.c:1196
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:145
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void BKE_id_free(struct Main *bmain, void *idv)
void id_us_ensure_real(struct ID *id)
Definition: lib_id.c:238
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void BKE_id_free_us(struct Main *bmain, void *idv) ATTR_NONNULL()
@ IDWALK_NOP
void BKE_library_foreach_ID_link(struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
Definition: lib_query.c:322
@ IDWALK_RET_NOP
Definition: BKE_lib_query.h:97
@ IDWALK_CB_USER_ONE
Definition: BKE_lib_query.h:93
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
void BKE_id_materials_copy(struct Main *bmain, struct ID *id_src, struct ID *id_dst)
Definition: material.c:508
void BKE_mesh_poly_edgehash_insert(struct EdgeHash *ehash, const struct MPoly *mp, const struct MLoop *mloop)
void BKE_mesh_ensure_normals(struct Mesh *me)
struct Mesh * BKE_mesh_add(struct Main *bmain, const char *name)
Definition: mesh.c:849
void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float(*vert_coords)[3])
Definition: mesh.c:1755
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.c:877
void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob)
Definition: mesh.c:1150
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_texspace_calc(struct Mesh *me)
Definition: mesh.c:1079
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.c:766
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, const bool select_new_edges)
float(* BKE_mesh_vert_coords_alloc(const struct Mesh *mesh, int *r_vert_len))[3]
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
void BKE_mesh_runtime_clear_geometry(struct Mesh *mesh)
Definition: mesh_runtime.c:226
struct Mesh * mesh_create_eval_final(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.c:98
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:58
@ MOD_APPLY_TO_BASE_MESH
Definition: BKE_modifier.h:141
General operations, lookup, etc. for blender objects.
void BKE_object_free_modifiers(struct Object *ob, const int flag)
Definition: object.c:1200
void BKE_object_free_derived_caches(struct Object *ob)
Definition: object.c:1719
void BKE_object_free_curve_cache(struct Object *ob)
Definition: object.c:1186
void BKE_object_eval_assign_data(struct Object *object, struct ID *data, bool is_owned)
Definition: object.c:1687
General operations for point-clouds.
void * BKE_pointcloud_add(struct Main *bmain, const char *name)
Definition: pointcloud.cc:216
void BKE_pointcloud_update_customdata_pointers(struct PointCloud *pointcloud)
Definition: pointcloud.cc:303
const char * POINTCLOUD_ATTR_POSITION
Definition: pointcloud.cc:58
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
Definition: edgehash.c:244
BLI_INLINE void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *r_v0, unsigned int *r_v1)
Definition: BLI_edgehash.h:93
BLI_INLINE bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi)
Definition: BLI_edgehash.h:89
EdgeHash * BLI_edgehash_new_ex(const char *info, const unsigned int nentries_reserve)
Definition: edgehash.c:226
EdgeHashIterator * BLI_edgehashIterator_new(EdgeHash *eh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:471
BLI_INLINE void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
Definition: BLI_edgehash.h:85
#define BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly)
Definition: BLI_edgehash.h:115
void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
Definition: edgehash.c:496
void * BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:325
int BLI_edgehash_len(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:434
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:426
BLI_INLINE void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
Definition: BLI_edgehash.h:109
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define POINTER_AS_UINT(i)
#define UNUSED(x)
#define ELEM(...)
#define POINTER_FROM_UINT(i)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
bool DEG_is_original_id(const struct ID *id)
bool DEG_is_evaluated_object(const struct Object *object)
struct ID * DEG_get_original_id(struct ID *id)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ LIB_TAG_NO_MAIN
Definition: DNA_ID.h:572
@ ID_ME
Definition: DNA_ID_enums.h:60
@ CU_SMOOTH
@ CU_NURB_CYCLIC
@ CU_NURB_ENDPOINT
@ CU_AUTOSPACE
@ CU_3D
#define CD_MASK_NORMAL
#define CD_MASK_ORIGINDEX
#define CD_MASK_PROP_ALL
@ CD_PROP_FLOAT3
@ CD_SHAPEKEY
@ CD_MVERT
@ CD_MLOOPUV
@ ME_AUTOSPACE_EVALUATED
@ ME_EDGEDRAW
@ ME_EDGERENDER
@ ME_LOOSEEDGE
@ ME_SMOOTH
@ eModifierMode_Realtime
Object is a sort of wrapper for general info.
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVE
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define SELECT
Scene scene
Curve curve
const Depsgraph * depsgraph
static float verts[][3]
int count
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
Definition: mesh_convert.c:77
static Mesh * mesh_new_from_curve_type_object(Object *object)
void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud)
Definition: mesh_convert.c:909
void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
Definition: mesh_convert.c:952
static Mesh * mesh_new_from_mesh_object(Depsgraph *depsgraph, Object *object, const bool preserve_all_data_layers, const bool preserve_origindex)
static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
static void prependPolyLineVert(ListBase *lb, unsigned int index)
Definition: mesh_convert.c:725
void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
Definition: mesh_convert.c:991
void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
void BKE_mesh_edges_set_draw_render(Mesh *mesh)
Definition: mesh_convert.c:983
void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
Definition: mesh_convert.c:931
void BKE_mesh_from_nurbs(Main *bmain, Object *ob)
Definition: mesh_convert.c:703
static void appendPolyLineVert(ListBase *lb, unsigned int index)
Definition: mesh_convert.c:732
static Object * object_for_curve_to_mesh_create(Object *object)
static int foreach_libblock_make_original_callback(LibraryIDLinkCallbackData *cb_data)
int BKE_mesh_nurbs_displist_to_mdata(Object *ob, const ListBase *dispbase, MVert **r_allvert, int *r_totvert, MEdge **r_alledge, int *r_totedge, MLoop **r_allloop, MPoly **r_allpoly, MLoopUV **r_alluv, int *r_totloop, int *r_totpoly)
Definition: mesh_convert.c:250
void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
Definition: mesh_convert.c:884
Mesh * BKE_mesh_new_nomain_from_curve(Object *ob)
Definition: mesh_convert.c:572
void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
Definition: mesh_convert.c:739
Mesh * BKE_mesh_new_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
Definition: mesh_convert.c:526
static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
struct VertLink VertLink
static void curve_to_mesh_eval_ensure(Object *object)
static Mesh * mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object *object, const bool preserve_origindex)
static Mesh * mesh_new_from_mball_object(Object *object)
static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge, const MPoly *mpoly, MLoop *mloop, const int totpoly)
Definition: mesh_convert.c:145
Mesh * BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, Scene *scene, Object *ob_eval, ModifierData *md_eval, const bool build_shapekey_layers)
struct EdgeLink EdgeLink
static Mesh * mesh_new_from_mesh(Object *object, Mesh *mesh)
Mesh * BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, const bool preserve_all_data_layers, const bool preserve_origindex)
static int foreach_libblock_make_usercounts_callback(LibraryIDLinkCallbackData *cb_data)
static CLG_LogRef LOG
Definition: mesh_convert.c:75
Mesh * BKE_mesh_new_from_object_to_bmain(Main *bmain, Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **r_allvert, int *r_totvert, MEdge **r_alledge, int *r_totedge, MLoop **r_allloop, MPoly **r_allpoly, int *r_totloop, int *r_totpoly)
Definition: mesh_convert.c:216
#define ASSERT_IS_VALID_MESH(mesh)
Definition: mesh_convert.c:72
void BKE_mesh_from_nurbs_displist(Main *bmain, Object *ob, ListBase *dispbase, const char *obdata_name, bool temporary)
Definition: mesh_convert.c:584
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, const CustomData_MeshMasks *mask, bool take_ownership)
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
struct Mesh * mesh_eval_final
Definition: BKE_editmesh.h:63
struct BMVert * v
Definition: bmesh_class.h:165
float weight
uint8_t f1
float vec[4]
float radius
ListBase disp
Definition: BKE_curve.h:49
struct EditFont * editfont
EditNurb * editnurb
ListBase nurb
short type
Definition: BKE_displist.h:71
short col
Definition: BKE_displist.h:73
float * verts
Definition: BKE_displist.h:74
int * index
Definition: BKE_displist.h:75
short rt
Definition: BKE_displist.h:73
struct DispList * next
Definition: BKE_displist.h:70
float * nors
Definition: BKE_displist.h:74
short flag
Definition: BKE_displist.h:71
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
int us
Definition: DNA_ID.h:293
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
char name[64]
Definition: DNA_key_types.h:68
struct KeyBlock * next
Definition: DNA_key_types.h:41
void * data
Definition: DNA_key_types.h:66
ID id
Definition: DNA_key_types.h:79
int elemsize
Definition: DNA_key_types.h:96
ListBase block
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
short mat_nr
float co[3]
short no[3]
Definition: BKE_main.h:116
char name[1024]
Definition: BKE_main.h:118
ListBase objects
Definition: BKE_main.h:148
int64_t cd_dirty_vert
struct MEdge * medge
struct BMEditMesh * edit_mesh
float smoothresh
struct CustomData pdata ldata
struct MVert * mvert
struct Material ** mat
int totedge
char cd_flag
int totvert
short flag
struct MLoop * mloop
int totface
Mesh_Runtime runtime
struct CustomData vdata edata fdata
short texflag
int totpoly
short totcol
int totloop
struct Key * key
int totselect
struct MPoly * mpoly
struct MSelect * mselect
short totcol
struct Material ** mat
bool(* isDisabled)(const struct Scene *scene, struct ModifierData *md, bool userRenderParams)
Definition: BKE_modifier.h:312
ModifierTypeType type
Definition: BKE_modifier.h:173
struct Mesh *(* modifyMesh)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh)
Definition: BKE_modifier.h:244
void(* deformVerts)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float(*vertexCos)[3], int numVerts)
Definition: BKE_modifier.h:197
short flagu
short orderu
BPoint * bp
short resolu
struct CurveCache * curve_cache
struct ID * data_eval
struct ID * data_orig
struct BoundBox * bb
ListBase modifiers
short shapenr
Object_Runtime runtime
void * data
float(* co)[3]
struct CustomData pdata
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)