Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/modifiers_bmesh.c')
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c78
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;