99
99
#include "intern/bmesh_private.h" /* for element checking */
102
* Currently this is only used for Python scripts
103
* which may fail to keep matching UV/TexFace layers.
105
* \note This should only perform any changes in exceptional cases,
106
* if we need this to be faster we could inline #BM_data_layer_add and only
107
* call #update_data_blocks once at the end.
109
void BM_mesh_cd_validate(BMesh *bm)
111
int totlayer_mtex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
112
int totlayer_uv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
114
if (LIKELY(totlayer_mtex == totlayer_uv)) {
117
else if (totlayer_mtex < totlayer_uv) {
118
const int uv_index_first = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
120
const char *from_name = bm->ldata.layers[uv_index_first + totlayer_mtex].name;
121
BM_data_layer_add_named(bm, &bm->pdata, CD_MTEXPOLY, from_name);
122
CustomData_set_layer_unique_name(&bm->pdata, totlayer_mtex);
123
} while (totlayer_uv != ++totlayer_mtex);
125
else if (totlayer_uv < totlayer_mtex) {
126
const int mtex_index_first = CustomData_get_layer_index(&bm->pdata, CD_MTEXPOLY);
128
const char *from_name = bm->pdata.layers[mtex_index_first + totlayer_uv].name;
129
BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, from_name);
130
CustomData_set_layer_unique_name(&bm->ldata, totlayer_uv);
131
} while (totlayer_mtex != ++totlayer_uv);
134
BLI_assert(totlayer_mtex == totlayer_uv);
101
137
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
103
139
const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
112
148
/* CustomData_bmesh_init_pool() must run first */
113
149
BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
114
150
BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
151
BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL);
116
153
if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
117
154
if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
202
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
203
static BMFace *bm_face_create_from_mpoly(MPoly *mp, MLoop *ml,
204
BMesh *bm, BMVert **vtable, BMEdge **etable)
206
BMVert **verts = BLI_array_alloca(verts, mp->totloop);
207
BMEdge **edges = BLI_array_alloca(edges, mp->totloop);
210
for (j = 0; j < mp->totloop; j++, ml++) {
211
verts[j] = vtable[ml->v];
212
edges[j] = etable[ml->e];
215
return BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD);
166
220
* \brief Mesh -> BMesh
168
222
* \warning This function doesn't calculate face normals.
170
void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr)
224
void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
225
const bool calc_face_normal, const bool set_key, int act_key_nr)
173
BLI_array_declare(verts);
177
231
KeyBlock *actkey, *block;
178
BMVert *v, **vt = NULL, **verts = NULL;
179
BMEdge *e, **fedges = NULL, **et = NULL;
232
BMVert *v, **vtable = NULL;
233
BMEdge *e, **etable = NULL;
181
BLI_array_declare(fedges);
182
235
float (*keyco)[3] = NULL;
209
262
return; /* sanity check */
212
vt = MEM_mallocN(sizeof(void **) * me->totvert, "mesh to bmesh vtable");
265
vtable = MEM_mallocN(sizeof(void **) * me->totvert, "mesh to bmesh vtable");
214
267
CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
215
268
CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
274
327
cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
276
329
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
277
v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
330
v = vtable[i] = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
278
331
BM_elem_index_set(v, i); /* set_ok */
281
333
/* transfer flag */
282
334
v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);
314
366
bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
316
368
if (!me->totedge) {
321
et = MEM_mallocN(sizeof(void **) * me->totedge, "mesh to bmesh etable");
373
etable = MEM_mallocN(sizeof(void **) * me->totedge, "mesh to bmesh etable");
323
375
medge = me->medge;
324
376
for (i = 0; i < me->totedge; i++, medge++) {
325
e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, BM_CREATE_SKIP_CD);
377
e = etable[i] = BM_edge_create(bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
326
378
BM_elem_index_set(e, i); /* set_ok */
329
380
/* transfer flags */
330
381
e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);
345
396
bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
348
for (i = 0; i < me->totpoly; i++, mpoly++) {
400
for (i = 0; i < me->totpoly; i++, mp++) {
352
BLI_array_empty(fedges);
353
BLI_array_empty(verts);
355
BLI_array_grow_items(fedges, mpoly->totloop);
356
BLI_array_grow_items(verts, mpoly->totloop);
358
for (j = 0; j < mpoly->totloop; j++) {
359
ml = &me->mloop[mpoly->loopstart + j];
367
/* not sure what this block is supposed to do,
368
* but its unused. so commenting - campbell */
372
v1 = vt[me->mloop[mpoly->loopstart].v];
373
v2 = vt[me->mloop[mpoly->loopstart + 1].v];
375
if (v1 == fedges[0]->v1) {
385
f = BM_face_create(bm, verts, fedges, mpoly->totloop, BM_CREATE_SKIP_CD);
404
f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart,
387
407
if (UNLIKELY(f == NULL)) {
388
408
printf("%s: Warning! Bad face in mesh"
395
415
BM_elem_index_set(f, bm->totface - 1); /* set_ok */
397
417
/* transfer flag */
398
f->head.hflag = BM_face_flag_from_mflag(mpoly->flag & ~ME_FACE_SEL);
418
f->head.hflag = BM_face_flag_from_mflag(mp->flag & ~ME_FACE_SEL);
400
420
/* this is necessary for selection counts to work properly */
401
if (mpoly->flag & ME_FACE_SEL) {
421
if (mp->flag & ME_FACE_SEL) {
402
422
BM_face_select_set(bm, f, true);
405
f->mat_nr = mpoly->mat_nr;
425
f->mat_nr = mp->mat_nr;
406
426
if (i == me->act_face) bm->act_face = f;
408
j = mpoly->loopstart;
409
429
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
411
431
/* Save index of correspsonding MLoop */
415
435
/* Copy Custom Data */
416
436
CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
438
if (calc_face_normal) {
439
BM_face_normal_update(f);
419
443
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
628
649
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
630
651
/* this is called again, 'dotess' arg is used there */
631
mesh_update_customdata_pointers(me, 0);
652
BKE_mesh_update_customdata_pointers(me, 0);
634
655
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
766
789
BKE_mesh_tessface_calc(me);
769
mesh_update_customdata_pointers(me, do_tessface);
792
BKE_mesh_update_customdata_pointers(me, do_tessface);
772
795
BMEditSelection *selected;