diff options
Diffstat (limited to 'source/blender/blenkernel/intern/modifiers_bmesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/modifiers_bmesh.c | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 381e4350391..a6c2325c740 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -40,7 +40,11 @@ #include "BKE_bmesh.h" #include "BKE_tessmesh.h" -/* main function for copying DerivedMesh data into BMesh */ +/** + * The main function for copying DerivedMesh data into BMesh. + * + * \note The mesh may already have geometry. see 'is_init' + */ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) { MVert *mv, *mvert; @@ -55,7 +59,20 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; - int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + bool is_cddm = (dm->type == DM_TYPE_CDDM); /* duplicate the arrays for non cddm */ + char has_orig_hflag = 0; + + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + + if (is_init == FALSE) { + /* check if we have an origflag */ + has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0; + has_orig_hflag |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0; + has_orig_hflag |= CustomData_has_layer(&bm->pdata, CD_ORIGINDEX) ? BM_FACE : 0; + } /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -63,38 +80,45 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP); CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE); + if (is_init) { + BM_mesh_cd_flag_apply(bm, dm->cd_flag); + } + + cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + totvert = dm->getNumVerts(dm); totedge = dm->getNumEdges(dm); /* totface = dm->getNumPolys(dm); */ /* UNUSED */ - /* add crease layer */ - BM_data_layer_add(bm, &bm->edata, CD_CREASE); - /* add bevel weight layers */ - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); - vtable = MEM_callocN(sizeof(void **) * totvert, __func__); etable = MEM_callocN(sizeof(void **) * totedge, __func__); /*do verts*/ - mv = mvert = dm->dupVertArray(dm); + mv = mvert = is_cddm ? dm->getVertArray(dm) : dm->dupVertArray(dm); for (i = 0; i < totvert; i++, mv++) { v = BM_vert_create(bm, mv->co, NULL, BM_CREATE_SKIP_CD); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); BM_elem_index_set(v, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data, true); + vtable[i] = v; /* add bevel weight */ - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f); - vtable[i] = v; + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mv->bweight / 255.0f); + + if (UNLIKELY(has_orig_hflag & BM_VERT)) { + int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } - MEM_freeN(mvert); + if (!is_cddm) MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ - me = medge = dm->dupEdgeArray(dm); + me = medge = is_cddm ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, BM_CREATE_SKIP_CD); @@ -102,15 +126,18 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) e->head.hflag = BM_edge_flag_from_mflag(me->flag); BM_elem_index_set(e, i); /* set_inline */ - CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data, true); etable[i] = e; - /* add crease */ - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f); - /* add bevel weight */ - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)me->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)me->crease / 255.0f); + + if (UNLIKELY(has_orig_hflag & BM_EDGE)) { + int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } - MEM_freeN(medge); + if (!is_cddm) MEM_freeN(medge); if (is_init) bm->elem_index_dirty &= ~BM_EDGE; /* do faces */ @@ -134,7 +161,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) edges[j] = etable[ml->e]; } - f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, BM_CREATE_SKIP_CD); + f = BM_face_create(bm, verts, edges, mp->totloop, BM_CREATE_SKIP_CD); if (UNLIKELY(f == NULL)) { continue; @@ -147,10 +174,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) { - CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data); + CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data, true); } - CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true); if (face_normals) { copy_v3_v3(f->no, face_normals[i]); @@ -158,6 +185,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) else { BM_face_normal_update(f); } + + if (UNLIKELY(has_orig_hflag & BM_FACE)) { + int *orig_index = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } if (is_init) bm->elem_index_dirty &= ~BM_FACE; |