Blender  V2.93
bmesh_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 
73 #include "DNA_key_types.h"
74 #include "DNA_mesh_types.h"
75 #include "DNA_meshdata_types.h"
76 #include "DNA_modifier_types.h"
77 #include "DNA_object_types.h"
78 
79 #include "MEM_guardedalloc.h"
80 
81 #include "BLI_alloca.h"
82 #include "BLI_listbase.h"
83 #include "BLI_math_vector.h"
84 
85 #include "BKE_customdata.h"
86 #include "BKE_mesh.h"
87 #include "BKE_mesh_runtime.h"
88 #include "BKE_multires.h"
89 
90 #include "BKE_key.h"
91 #include "BKE_main.h"
92 
93 #include "DEG_depsgraph_query.h"
94 
95 #include "bmesh.h"
96 #include "intern/bmesh_private.h" /* For element checking. */
97 
98 void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
99 {
100  const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
101  BM_mesh_cd_flag_apply(bm, cd_flag_all);
102  if (mesh) {
103  mesh->cd_flag = cd_flag_all;
104  }
105 }
106 
107 void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
108 {
109  /* CustomData_bmesh_init_pool() must run first */
110  BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
111  BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
112  BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL);
113 
114  if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
117  }
118  }
119  else {
122  }
123  }
124 
125  if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
128  }
129  }
130  else {
133  }
134  }
135 
136  if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
139  }
140  }
141  else {
144  }
145  }
146 }
147 
149 {
150  char cd_flag = 0;
152  cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
153  }
155  cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
156  }
158  cd_flag |= ME_CDFLAG_EDGE_CREASE;
159  }
160  return cd_flag;
161 }
162 
163 /* Static function for alloc (duplicate in modifiers_bmesh.c) */
165  MPoly *mp, MLoop *ml, BMesh *bm, BMVert **vtable, BMEdge **etable)
166 {
168  BMEdge **edges = BLI_array_alloca(edges, mp->totloop);
169  int j;
170 
171  for (j = 0; j < mp->totloop; j++, ml++) {
172  verts[j] = vtable[ml->v];
173  edges[j] = etable[ml->e];
174  }
175 
176  return BM_face_create(bm, verts, edges, mp->totloop, NULL, BM_CREATE_SKIP_CD);
177 }
178 
189 void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
190 {
191  const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
192  bm->pdata.totlayer || bm->ldata.totlayer));
193  MVert *mvert;
194  MEdge *medge;
195  MLoop *mloop;
196  MPoly *mp;
197  KeyBlock *actkey, *block;
198  BMVert *v, **vtable = NULL;
199  BMEdge *e, **etable = NULL;
200  BMFace *f, **ftable = NULL;
201  float(*keyco)[3] = NULL;
202  int totloops, i;
204  CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
205 
206  if (!me || !me->totvert) {
207  if (me && is_new) { /* No verts? still copy custom-data layout. */
208  CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_ASSIGN, 0);
209  CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_ASSIGN, 0);
210  CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_ASSIGN, 0);
211  CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_ASSIGN, 0);
212 
217  }
218  return; /* Sanity check. */
219  }
220 
221  if (is_new) {
222  CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0);
223  CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0);
224  CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0);
225  CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0);
226  }
227  else {
228  CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, bm, BM_VERT);
229  CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_CALLOC, bm, BM_EDGE);
231  CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, bm, BM_FACE);
232  }
233 
234  /* -------------------------------------------------------------------- */
235  /* Shape Key */
236  int tot_shape_keys = 0;
237  if (me->key != NULL && DEG_is_original_id(&me->id)) {
238  /* Evaluated meshes can be topologically inconsistent with their shape keys.
239  * Shape keys are also already integrated into the state of the evaluated
240  * mesh, so considering them here would kind of apply them twice. */
241  tot_shape_keys = BLI_listbase_count(&me->key->block);
242 
243  /* Original meshes must never contain a shape-key custom-data layers.
244  *
245  * This may happen if and object's mesh data is accidentally
246  * set to the output from the modifier stack, causing it to be an "original" ID,
247  * even though the data isn't fully compatible (hence this assert).
248  *
249  * This results in:
250  * - The newly created #BMesh having twice the number of custom-data layers.
251  * - When converting the #BMesh back to a regular mesh,
252  * At least one of the extra shape-key blocks will be created in #Mesh.key
253  * depending on the value of #CustomDataLayer.uid.
254  *
255  * We could support mixing both kinds of data if there is a compelling use-case for it.
256  * At the moment it's simplest to assume all original meshes use the key-block and meshes
257  * that are evaluated (through the modifier stack for example) use custom-data layers.
258  */
260  }
261  if (is_new == false) {
262  tot_shape_keys = min_ii(tot_shape_keys, CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY));
263  }
264  const float(**shape_key_table)[3] = tot_shape_keys ?
265  BLI_array_alloca(shape_key_table, tot_shape_keys) :
266  NULL;
267 
268  if ((params->active_shapekey != 0) && tot_shape_keys > 0) {
269  actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
270  }
271  else {
272  actkey = NULL;
273  }
274 
275  if (is_new) {
276  if (tot_shape_keys || params->add_key_index) {
278  }
279  }
280 
281  if (tot_shape_keys) {
282  if (is_new) {
283  /* Check if we need to generate unique ids for the shape-keys.
284  * This also exists in the file reading code, but is here for a sanity check. */
285  if (!me->key->uidgen) {
286  fprintf(stderr,
287  "%s had to generate shape key uid's in a situation we shouldn't need to! "
288  "(bmesh internal error)\n",
289  __func__);
290 
291  me->key->uidgen = 1;
292  for (block = me->key->block.first; block; block = block->next) {
293  block->uid = me->key->uidgen++;
294  }
295  }
296  }
297 
298  if (actkey && actkey->totelem == me->totvert) {
299  keyco = params->use_shapekey ? actkey->data : NULL;
300  if (is_new) {
301  bm->shapenr = params->active_shapekey;
302  }
303  }
304 
305  for (i = 0, block = me->key->block.first; i < tot_shape_keys; block = block->next, i++) {
306  if (is_new) {
309  bm->vdata.layers[j].uid = block->uid;
310  }
311  shape_key_table[i] = (const float(*)[3])block->data;
312  }
313  }
314 
315  if (is_new) {
320 
322  }
323 
324  const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
325  const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
326  const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
327  const int cd_shape_key_offset = tot_shape_keys ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) :
328  -1;
329  const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ?
331  -1;
332 
333  vtable = MEM_mallocN(sizeof(BMVert **) * me->totvert, __func__);
334 
335  for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
336  v = vtable[i] = BM_vert_create(bm, keyco ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
337  BM_elem_index_set(v, i); /* set_ok */
338 
339  /* Transfer flag. */
341 
342  /* This is necessary for selection counts to work properly. */
343  if (mvert->flag & SELECT) {
344  BM_vert_select_set(bm, v, true);
345  }
346 
347  normal_short_to_float_v3(v->no, mvert->no);
348 
349  /* Copy Custom Data */
350  CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
351 
352  if (cd_vert_bweight_offset != -1) {
353  BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
354  }
355 
356  /* Set shape key original index. */
357  if (cd_shape_keyindex_offset != -1) {
358  BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
359  }
360 
361  /* Set shape-key data. */
362  if (tot_shape_keys) {
363  float(*co_dst)[3] = BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset);
364  for (int j = 0; j < tot_shape_keys; j++, co_dst++) {
365  copy_v3_v3(*co_dst, shape_key_table[j][i]);
366  }
367  }
368  }
369  if (is_new) {
370  bm->elem_index_dirty &= ~BM_VERT; /* Added in order, clear dirty flag. */
371  }
372 
373  etable = MEM_mallocN(sizeof(BMEdge **) * me->totedge, __func__);
374 
375  medge = me->medge;
376  for (i = 0; i < me->totedge; i++, medge++) {
377  e = etable[i] = BM_edge_create(
378  bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
379  BM_elem_index_set(e, i); /* set_ok */
380 
381  /* Transfer flags. */
383 
384  /* This is necessary for selection counts to work properly. */
385  if (medge->flag & SELECT) {
386  BM_edge_select_set(bm, e, true);
387  }
388 
389  /* Copy Custom Data */
390  CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
391 
392  if (cd_edge_bweight_offset != -1) {
393  BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
394  }
395  if (cd_edge_crease_offset != -1) {
396  BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
397  }
398  }
399  if (is_new) {
400  bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
401  }
402 
403  /* Only needed for selection. */
404  if (me->mselect && me->totselect != 0) {
405  ftable = MEM_mallocN(sizeof(BMFace **) * me->totpoly, __func__);
406  }
407 
408  mloop = me->mloop;
409  mp = me->mpoly;
410  for (i = 0, totloops = 0; i < me->totpoly; i++, mp++) {
411  BMLoop *l_iter;
412  BMLoop *l_first;
413 
414  f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart, bm, vtable, etable);
415  if (ftable != NULL) {
416  ftable[i] = f;
417  }
418 
419  if (UNLIKELY(f == NULL)) {
420  printf(
421  "%s: Warning! Bad face in mesh"
422  " \"%s\" at index %d!, skipping\n",
423  __func__,
424  me->id.name + 2,
425  i);
426  continue;
427  }
428 
429  /* Don't use 'i' since we may have skipped the face. */
430  BM_elem_index_set(f, bm->totface - 1); /* set_ok */
431 
432  /* Transfer flag. */
434 
435  /* This is necessary for selection counts to work properly. */
436  if (mp->flag & ME_FACE_SEL) {
437  BM_face_select_set(bm, f, true);
438  }
439 
440  f->mat_nr = mp->mat_nr;
441  if (i == me->act_face) {
442  bm->act_face = f;
443  }
444 
445  int j = mp->loopstart;
446  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
447  do {
448  /* Don't use 'j' since we may have skipped some faces, hence some loops. */
449  BM_elem_index_set(l_iter, totloops++); /* set_ok */
450 
451  /* Save index of corresponding #MLoop. */
452  CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
453  } while ((l_iter = l_iter->next) != l_first);
454 
455  /* Copy Custom Data */
456  CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
457 
458  if (params->calc_face_normal) {
460  }
461  }
462  if (is_new) {
463  bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* Added in order, clear dirty flag. */
464  }
465 
466  /* -------------------------------------------------------------------- */
467  /* MSelect clears the array elements (avoid adding multiple times).
468  *
469  * Take care to keep this last and not use (v/e/ftable) after this.
470  */
471 
472  if (me->mselect && me->totselect != 0) {
473  MSelect *msel;
474  for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
475  BMElem **ele_p;
476  switch (msel->type) {
477  case ME_VSEL:
478  ele_p = (BMElem **)&vtable[msel->index];
479  break;
480  case ME_ESEL:
481  ele_p = (BMElem **)&etable[msel->index];
482  break;
483  case ME_FSEL:
484  ele_p = (BMElem **)&ftable[msel->index];
485  break;
486  default:
487  continue;
488  }
489 
490  if (*ele_p != NULL) {
492  *ele_p = NULL;
493  }
494  }
495  }
496  else {
498  }
499 
500  MEM_freeN(vtable);
501  MEM_freeN(etable);
502  if (ftable) {
503  MEM_freeN(ftable);
504  }
505 }
506 
510 static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
511 {
512  const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
513  BMVert **vertMap = NULL;
514  BMVert *eve;
515  int i = 0;
516  BMIter iter;
517 
518  /* Caller needs to ensure this. */
519  BLI_assert(ototvert > 0);
520 
521  vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
522  if (cd_shape_keyindex_offset != -1) {
523  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
524  const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
525  if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert) &&
526  /* Not fool-proof, but chances are if we have many verts with the same index,
527  * we will want to use the first one,
528  * since the second is more likely to be a duplicate. */
529  (vertMap[keyi] == NULL)) {
530  vertMap[keyi] = eve;
531  }
532  }
533  }
534  else {
535  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
536  if (i < ototvert) {
537  vertMap[i] = eve;
538  }
539  else {
540  break;
541  }
542  }
543  }
544 
545  return vertMap;
546 }
547 
553 {
554  int i;
555  int j = 0;
556 
557  for (i = 0; i < bm->vdata.totlayer; i++) {
558  if (bm->vdata.layers[i].type == CD_SHAPEKEY) {
559  if (currkey->uid == bm->vdata.layers[i].uid) {
560  return j;
561  }
562  j++;
563  }
564  }
565  return -1;
566 }
567 
569 {
570  /* This is a cheap way to set the edge draw, its not precise and will
571  * pick the first 2 faces an edge uses.
572  * The dot comparison is a little arbitrary, but set so that a 5 subd
573  * IcoSphere won't vanish but subd 6 will (as with pre-bmesh Blender). */
574 
575  if (/* (med->flag & ME_EDGEDRAW) && */ /* Assume to be true. */
576  (e->l && (e->l != e->l->radial_next)) &&
577  (dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.9995f)) {
578  med->flag &= ~ME_EDGEDRAW;
579  }
580  else {
581  med->flag |= ME_EDGEDRAW;
582  }
583 }
584 
589 void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
590 {
591  MEdge *med;
592  BMVert *v, *eve;
593  BMEdge *e;
594  BMFace *f;
595  BMIter iter;
596  int i, j;
597 
598  const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
599  const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
600  const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
601  const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
602 
603  MVert *oldverts = NULL;
604  const int ototvert = me->totvert;
605 
606  if (me->key && (cd_shape_keyindex_offset != -1)) {
607  /* Keep the old verts in case we are working on* a key, which is done at the end. */
608 
609  /* Use the array in-place instead of duplicating the array. */
610 #if 0
611  oldverts = MEM_dupallocN(me->mvert);
612 #else
613  oldverts = me->mvert;
614  me->mvert = NULL;
615  CustomData_update_typemap(&me->vdata);
616  CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
617 #endif
618  }
619 
620  /* Free custom data. */
621  CustomData_free(&me->vdata, me->totvert);
622  CustomData_free(&me->edata, me->totedge);
623  CustomData_free(&me->fdata, me->totface);
624  CustomData_free(&me->ldata, me->totloop);
625  CustomData_free(&me->pdata, me->totpoly);
626 
627  /* Add new custom data. */
628  me->totvert = bm->totvert;
629  me->totedge = bm->totedge;
630  me->totloop = bm->totloop;
631  me->totpoly = bm->totface;
632  /* Will be overwritten with a valid value if 'dotess' is set, otherwise we
633  * end up with 'me->totface' and me->mface == NULL which can crash T28625. */
634  me->totface = 0;
635  me->act_face = -1;
636 
637  {
639  CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
640  CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
641  CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
642  CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
643  CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
644  }
645 
646  MVert *mvert = bm->totvert ? MEM_callocN(sizeof(MVert) * bm->totvert, "bm_to_me.vert") : NULL;
647  MEdge *medge = bm->totedge ? MEM_callocN(sizeof(MEdge) * bm->totedge, "bm_to_me.edge") : NULL;
648  MLoop *mloop = bm->totloop ? MEM_callocN(sizeof(MLoop) * bm->totloop, "bm_to_me.loop") : NULL;
649  MPoly *mpoly = bm->totface ? MEM_callocN(sizeof(MPoly) * bm->totface, "bm_to_me.poly") : NULL;
650 
651  CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
652  CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
654  CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
655 
657 
658  /* This is called again, 'dotess' arg is used there. */
660 
661  i = 0;
662  BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
663  copy_v3_v3(mvert->co, v->co);
664  normal_float_to_short_v3(mvert->no, v->no);
665 
666  mvert->flag = BM_vert_flag_to_mflag(v);
667 
668  BM_elem_index_set(v, i); /* set_inline */
669 
670  /* Copy over custom-data. */
671  CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
672 
673  if (cd_vert_bweight_offset != -1) {
674  mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
675  }
676 
677  i++;
678  mvert++;
679 
681  }
683 
684  med = medge;
685  i = 0;
686  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
687  med->v1 = BM_elem_index_get(e->v1);
688  med->v2 = BM_elem_index_get(e->v2);
689 
690  med->flag = BM_edge_flag_to_mflag(e);
691 
692  BM_elem_index_set(e, i); /* set_inline */
693 
694  /* Copy over custom-data. */
695  CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
696 
698 
699  if (cd_edge_crease_offset != -1) {
700  med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
701  }
702  if (cd_edge_bweight_offset != -1) {
703  med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
704  }
705 
706  i++;
707  med++;
709  }
711 
712  i = 0;
713  j = 0;
714  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
715  BMLoop *l_iter, *l_first;
716  mpoly->loopstart = j;
717  mpoly->totloop = f->len;
718  mpoly->mat_nr = f->mat_nr;
719  mpoly->flag = BM_face_flag_to_mflag(f);
720 
721  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
722  do {
723  mloop->e = BM_elem_index_get(l_iter->e);
724  mloop->v = BM_elem_index_get(l_iter->v);
725 
726  /* Copy over custom-data. */
727  CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
728 
729  j++;
730  mloop++;
731  BM_CHECK_ELEMENT(l_iter);
732  BM_CHECK_ELEMENT(l_iter->e);
733  BM_CHECK_ELEMENT(l_iter->v);
734  } while ((l_iter = l_iter->next) != l_first);
735 
736  if (f == bm->act_face) {
737  me->act_face = i;
738  }
739 
740  /* Copy over custom-data. */
741  CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
742 
743  i++;
744  mpoly++;
745  BM_CHECK_ELEMENT(f);
746  }
747 
748  /* Patch hook indices and vertex parents. */
749  if (params->calc_object_remap && (ototvert > 0)) {
750  BLI_assert(bmain != NULL);
751  Object *ob;
752  ModifierData *md;
753  BMVert **vertMap = NULL;
754 
755  for (ob = bmain->objects.first; ob; ob = ob->id.next) {
756  if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
757 
758  if (vertMap == NULL) {
759  vertMap = bm_to_mesh_vertex_map(bm, ototvert);
760  }
761 
762  if (ob->par1 < ototvert) {
763  eve = vertMap[ob->par1];
764  if (eve) {
765  ob->par1 = BM_elem_index_get(eve);
766  }
767  }
768  if (ob->par2 < ototvert) {
769  eve = vertMap[ob->par2];
770  if (eve) {
771  ob->par2 = BM_elem_index_get(eve);
772  }
773  }
774  if (ob->par3 < ototvert) {
775  eve = vertMap[ob->par3];
776  if (eve) {
777  ob->par3 = BM_elem_index_get(eve);
778  }
779  }
780  }
781  if (ob->data == me) {
782  for (md = ob->modifiers.first; md; md = md->next) {
783  if (md->type == eModifierType_Hook) {
784  HookModifierData *hmd = (HookModifierData *)md;
785 
786  if (vertMap == NULL) {
787  vertMap = bm_to_mesh_vertex_map(bm, ototvert);
788  }
789 
790  for (i = j = 0; i < hmd->totindex; i++) {
791  if (hmd->indexar[i] < ototvert) {
792  eve = vertMap[hmd->indexar[i]];
793 
794  if (eve) {
795  hmd->indexar[j++] = BM_elem_index_get(eve);
796  }
797  }
798  else {
799  j++;
800  }
801  }
802 
803  hmd->totindex = j;
804  }
805  }
806  }
807  }
808 
809  if (vertMap) {
810  MEM_freeN(vertMap);
811  }
812  }
813 
815 
816  {
817  BMEditSelection *selected;
819 
820  MEM_SAFE_FREE(me->mselect);
821  if (me->totselect != 0) {
822  me->mselect = MEM_mallocN(sizeof(MSelect) * me->totselect, "Mesh selection history");
823  }
824 
825  for (i = 0, selected = bm->selected.first; selected; i++, selected = selected->next) {
826  if (selected->htype == BM_VERT) {
827  me->mselect[i].type = ME_VSEL;
828  }
829  else if (selected->htype == BM_EDGE) {
830  me->mselect[i].type = ME_ESEL;
831  }
832  else if (selected->htype == BM_FACE) {
833  me->mselect[i].type = ME_FSEL;
834  }
835 
836  me->mselect[i].index = BM_elem_index_get(selected->ele);
837  }
838  }
839 
840  /* See comment below, this logic is in twice. */
841 
842  if (me->key) {
843  KeyBlock *currkey;
844  KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
845 
846  float(*ofs)[3] = NULL;
847 
848  /* Go through and find any shape-key custom-data layers
849  * that might not have corresponding KeyBlocks, and add them if necessary. */
850  for (i = 0; i < bm->vdata.totlayer; i++) {
851  if (bm->vdata.layers[i].type != CD_SHAPEKEY) {
852  continue;
853  }
854 
855  for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
856  if (currkey->uid == bm->vdata.layers[i].uid) {
857  break;
858  }
859  }
860 
861  if (!currkey) {
862  currkey = BKE_keyblock_add(me->key, bm->vdata.layers[i].name);
863  currkey->uid = bm->vdata.layers[i].uid;
864  }
865  }
866 
867  /* Editing the base key should update others. */
868  if (/* Only need offsets for relative shape keys. */
869  (me->key->type == KEY_RELATIVE) &&
870 
871  /* Unlikely, but the active key may not be valid if the
872  * BMesh and the mesh are out of sync. */
873  (actkey != NULL) &&
874 
875  /* Not used here, but 'oldverts' is used later for applying 'ofs'. */
876  (oldverts != NULL) &&
877 
878  /* Needed for referencing oldverts. */
879  (cd_shape_keyindex_offset != -1)) {
880 
881  const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1);
882 
883  /* Active key is a base. */
884  if (act_is_basis) {
885  const float(*fp)[3] = actkey->data;
886 
887  ofs = MEM_callocN(sizeof(float[3]) * bm->totvert, "currkey->data");
888  mvert = me->mvert;
889  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
890  const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
891 
892  /* Could use 'eve->co' or 'mvert->co', they're the same at this point. */
893  if (keyi != ORIGINDEX_NONE && keyi < actkey->totelem) {
894  sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
895  }
896  else {
897  /* If there are new vertices in the mesh, we can't propagate the offset
898  * because it will only work for the existing vertices and not the new
899  * ones, creating a mess when doing e.g. subdivide + translate. */
900  MEM_freeN(ofs);
901  ofs = NULL;
902  break;
903  }
904 
905  mvert++;
906  }
907  }
908  }
909 
910  for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
911  int keyi;
912  const float(*ofs_pt)[3] = ofs;
913  float *newkey, (*oldkey)[3], *fp;
914 
915  const int currkey_uuid = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
916  const int cd_shape_offset = (currkey_uuid == -1) ? -1 :
918  CD_SHAPEKEY,
919  currkey_uuid);
920  const bool apply_offset = (cd_shape_offset != -1) && (ofs != NULL) && (currkey != actkey) &&
921  (bm->shapenr - 1 == currkey->relative);
922 
923  fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data");
924  oldkey = currkey->data;
925 
926  mvert = me->mvert;
927  BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
928 
929  if (currkey == actkey) {
930  copy_v3_v3(fp, eve->co);
931 
932  if (actkey != me->key->refkey) { /* Important see bug T30771. */
933  if (cd_shape_keyindex_offset != -1) {
934  if (oldverts) {
935  keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
936  if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* Valid old vertex. */
937  copy_v3_v3(mvert->co, oldverts[keyi].co);
938  }
939  }
940  }
941  }
942  }
943  else if (cd_shape_offset != -1) {
944  /* In most cases this runs. */
945  copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
946  }
947  else if ((oldkey != NULL) && (cd_shape_keyindex_offset != -1) &&
948  ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
949  (keyi < currkey->totelem)) {
950  /* Old method of reconstructing keys via vertices original key indices,
951  * currently used if the new method above fails
952  * (which is theoretically possible in certain cases of undo). */
953  copy_v3_v3(fp, oldkey[keyi]);
954  }
955  else {
956  /* Fail! fill in with dummy value. */
957  copy_v3_v3(fp, mvert->co);
958  }
959 
960  /* Propagate edited basis offsets to other shapes. */
961  if (apply_offset) {
962  add_v3_v3(fp, *ofs_pt++);
963  /* Apply back new coordinates shape-keys that have offset into BMesh.
964  * Otherwise, in case we call again #BM_mesh_bm_to_me on same BMesh,
965  * we'll apply diff from previous call to #BM_mesh_bm_to_me,
966  * to shape-key values from *original creation of the BMesh*. See T50524. */
967  copy_v3_v3(BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset), fp);
968  }
969 
970  fp += 3;
971  mvert++;
972  }
973 
974  currkey->totelem = bm->totvert;
975  if (currkey->data) {
976  MEM_freeN(currkey->data);
977  }
978  currkey->data = newkey;
979  }
980 
981  if (ofs) {
982  MEM_freeN(ofs);
983  }
984  }
985 
986  /* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */
987  if (params->update_shapekey_indices) {
988  /* We have written a new shape key, if this mesh is _not_ going to be freed,
989  * update the shape key indices to match the newly updated. */
990  if (cd_shape_keyindex_offset != -1) {
991  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
992  BM_ELEM_CD_SET_INT(eve, cd_shape_keyindex_offset, i);
993  }
994  }
995  }
996 
997  if (oldverts != NULL) {
998  MEM_freeN(oldverts);
999  }
1000 
1001  /* Topology could be changed, ensure #CD_MDISPS are ok. */
1003 
1004  /* To be removed as soon as COW is enabled by default.. */
1006 }
1007 
1026 {
1027  /* Must be an empty mesh. */
1028  BLI_assert(me->totvert == 0);
1029  BLI_assert(cd_mask_extra == NULL || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
1030 
1031  me->totvert = bm->totvert;
1032  me->totedge = bm->totedge;
1033  me->totface = 0;
1034  me->totloop = bm->totloop;
1035  me->totpoly = bm->totface;
1036 
1040 
1045 
1046  /* Don't process shape-keys, we only feed them through the modifier stack as needed,
1047  * e.g. for applying modifiers or the like. */
1049  if (cd_mask_extra != NULL) {
1050  CustomData_MeshMasks_update(&mask, cd_mask_extra);
1051  }
1052  mask.vmask &= ~CD_MASK_SHAPEKEY;
1053  CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
1054  CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
1055  CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
1056  CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
1057 
1059 
1060  BMIter iter;
1061  BMVert *eve;
1062  BMEdge *eed;
1063  BMFace *efa;
1064  MVert *mvert = me->mvert;
1065  MEdge *medge = me->medge;
1066  MLoop *mloop = me->mloop;
1067  MPoly *mpoly = me->mpoly;
1068  int *index, add_orig;
1069  unsigned int i, j;
1070 
1071  const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
1072  const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
1073  const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
1074 
1075  me->runtime.deformed_only = true;
1076 
1077  /* Don't add origindex layer if one already exists. */
1078  add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1079 
1080  index = CustomData_get_layer(&me->vdata, CD_ORIGINDEX);
1081 
1082  BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1083  MVert *mv = &mvert[i];
1084 
1085  copy_v3_v3(mv->co, eve->co);
1086 
1087  BM_elem_index_set(eve, i); /* set_inline */
1088 
1089  normal_float_to_short_v3(mv->no, eve->no);
1090 
1091  mv->flag = BM_vert_flag_to_mflag(eve);
1092 
1093  if (cd_vert_bweight_offset != -1) {
1094  mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
1095  }
1096 
1097  if (add_orig) {
1098  *index++ = i;
1099  }
1100 
1101  CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
1102  }
1104 
1105  index = CustomData_get_layer(&me->edata, CD_ORIGINDEX);
1106  BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
1107  MEdge *med = &medge[i];
1108 
1109  BM_elem_index_set(eed, i); /* set_inline */
1110 
1111  med->v1 = BM_elem_index_get(eed->v1);
1112  med->v2 = BM_elem_index_get(eed->v2);
1113 
1114  med->flag = BM_edge_flag_to_mflag(eed);
1115 
1116  /* Handle this differently to editmode switching,
1117  * only enable draw for single user edges rather than calculating angle. */
1118  if ((med->flag & ME_EDGEDRAW) == 0) {
1119  if (eed->l && eed->l == eed->l->radial_next) {
1120  med->flag |= ME_EDGEDRAW;
1121  }
1122  }
1123 
1124  if (cd_edge_crease_offset != -1) {
1125  med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
1126  }
1127  if (cd_edge_bweight_offset != -1) {
1128  med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
1129  }
1130 
1131  CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i);
1132  if (add_orig) {
1133  *index++ = i;
1134  }
1135  }
1137 
1138  index = CustomData_get_layer(&me->pdata, CD_ORIGINDEX);
1139  j = 0;
1140  BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
1141  BMLoop *l_iter;
1142  BMLoop *l_first;
1143  MPoly *mp = &mpoly[i];
1144 
1145  BM_elem_index_set(efa, i); /* set_inline */
1146 
1147  mp->totloop = efa->len;
1148  mp->flag = BM_face_flag_to_mflag(efa);
1149  mp->loopstart = j;
1150  mp->mat_nr = efa->mat_nr;
1151 
1152  l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
1153  do {
1154  mloop->v = BM_elem_index_get(l_iter->v);
1155  mloop->e = BM_elem_index_get(l_iter->e);
1156  CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
1157 
1158  BM_elem_index_set(l_iter, j); /* set_inline */
1159 
1160  j++;
1161  mloop++;
1162  } while ((l_iter = l_iter->next) != l_first);
1163 
1164  CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i);
1165 
1166  if (add_orig) {
1167  *index++ = i;
1168  }
1169  }
1171 
1173 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.c:2239
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_ASSIGN
@ CD_CALLOC
void CustomData_from_bmesh_block(const struct CustomData *source, struct CustomData *dest, void *src_block, int dest_index)
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.c:76
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
void CustomData_bmesh_init_pool(struct CustomData *data, int totelem, const char htype)
Definition: customdata.c:3482
const CustomData_MeshMasks CD_MASK_BMESH
Definition: customdata.c:1964
#define ORIGINDEX_NONE
bool CustomData_bmesh_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, struct BMesh *bm, const char htype)
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
int CustomData_get_n_offset(const struct CustomData *data, int type, int n)
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
Definition: customdata.c:1952
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
int CustomData_get_offset(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.c:1933
void CustomData_update_typemap(struct CustomData *data)
Definition: customdata.c:2071
void CustomData_to_bmesh_block(const struct CustomData *source, struct CustomData *dest, int src_index, void **dest_block, bool use_default_init)
bool BKE_keyblock_is_basis(struct Key *key, const int index)
Definition: key.c:2600
struct KeyBlock * BKE_keyblock_add(struct Key *key, const char *name)
Definition: key.c:1817
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.c:766
void BKE_mesh_runtime_clear_geometry(struct Mesh *mesh)
Definition: mesh_runtime.c:226
void multires_topology_changed(struct Mesh *me)
Definition: multires.c:1479
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int min_ii(int a, int b)
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
#define UNLIKELY(x)
#define ELEM(...)
bool DEG_is_original_id(const struct ID *id)
@ CD_ORIGINDEX
@ CD_SHAPEKEY
@ CD_MVERT
@ CD_BWEIGHT
@ CD_SHAPE_KEYINDEX
#define CD_MASK_SHAPEKEY
@ KEY_RELATIVE
@ ME_CDFLAG_EDGE_CREASE
@ ME_CDFLAG_VERT_BWEIGHT
@ ME_CDFLAG_EDGE_BWEIGHT
@ ME_VSEL
@ ME_FSEL
@ ME_ESEL
@ ME_EDGEDRAW
@ ME_FACE_SEL
@ eModifierType_Hook
Object is a sort of wrapper for general info.
@ PARVERT1
@ PARVERT3
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define BM_ELEM_CD_SET_FLOAT(ele, offset, f)
Definition: bmesh_class.h:534
#define BM_ELEM_CD_GET_INT(ele, offset)
Definition: bmesh_class.h:518
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
#define BM_ELEM_CD_SET_INT(ele, offset, f)
Definition: bmesh_class.h:510
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset)
Definition: bmesh_class.h:545
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:530
char BM_face_flag_from_mflag(const char mflag)
char BM_face_flag_to_mflag(BMFace *f)
short BM_edge_flag_to_mflag(BMEdge *e)
char BM_vert_flag_from_mflag(const char mflag)
char BM_edge_flag_from_mflag(const short mflag)
char BM_vert_flag_to_mflag(BMVert *v)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
Definition: bmesh_core.c:58
BMFace * BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const BMFace *f_example, const eBMCreateFlag create_flag)
Definition: bmesh_core.c:428
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
Definition: bmesh_core.c:147
@ BM_CREATE_SKIP_CD
Definition: bmesh_core.h:33
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:124
#define BM_elem_index_set(ele, index)
Definition: bmesh_inline.h:125
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:930
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:894
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_select_history_clear(BMesh *bm)
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
Select Face.
void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
Select Vert.
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
Select Edge.
#define BM_select_history_store_notest(bm, ele)
static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey)
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
static BMFace * bm_face_create_from_mpoly(MPoly *mp, MLoop *ml, BMesh *bm, BMVert **vtable, BMEdge **etable)
static BMVert ** bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
BMesh -> Mesh.
char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
Mesh -> BMesh.
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
void BM_face_normal_update(BMFace *f)
#define BM_CHECK_ELEMENT(el)
Definition: bmesh_private.h:38
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define SELECT
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong * next
BMHeader head
Definition: bmesh_class.h:123
BMVert * v1
Definition: bmesh_class.h:134
BMVert * v2
Definition: bmesh_class.h:134
struct BMLoop * l
Definition: bmesh_class.h:140
struct BMEditSelection * next
Definition: bmesh_marking.h:24
short mat_nr
Definition: bmesh_class.h:281
int len
Definition: bmesh_class.h:279
BMHeader head
Definition: bmesh_class.h:267
char hflag
Definition: bmesh_class.h:78
void * data
Definition: bmesh_class.h:63
BMHeader head
Definition: bmesh_class.h:157
struct BMVert * v
Definition: bmesh_class.h:165
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMLoop * radial_next
Definition: bmesh_class.h:216
struct BMLoop * next
Definition: bmesh_class.h:245
float co[3]
Definition: bmesh_class.h:99
float no[3]
Definition: bmesh_class.h:100
BMHeader head
Definition: bmesh_class.h:97
int totvert
Definition: bmesh_class.h:297
int shapenr
Definition: bmesh_class.h:353
char elem_index_dirty
Definition: bmesh_class.h:305
CustomData vdata
Definition: bmesh_class.h:337
int totedge
Definition: bmesh_class.h:297
ListBase selected
Definition: bmesh_class.h:356
CustomData edata
Definition: bmesh_class.h:337
int totloop
Definition: bmesh_class.h:297
BMFace * act_face
Definition: bmesh_class.h:366
CustomData pdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
int totface
Definition: bmesh_class.h:297
struct BLI_mempool * pool
CustomDataLayer * layers
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
short relative
Definition: DNA_key_types.h:57
void * data
Definition: DNA_key_types.h:66
int uidgen
int elemsize
Definition: DNA_key_types.h:96
char type
ListBase block
KeyBlock * refkey
Definition: DNA_key_types.h:88
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
ListBase objects
Definition: BKE_main.h:148
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int act_face
char cd_flag
int totvert
struct MLoop * mloop
int totface
Mesh_Runtime runtime
struct CustomData vdata edata fdata
int totpoly
int totloop
struct Key * key
int totselect
struct MPoly * mpoly
struct MSelect * mselect
struct ModifierData * next
short partype
ListBase modifiers
struct Object * parent
void * data
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)