diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh_conv.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_conv.c | 221 |
1 files changed, 164 insertions, 57 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 388d148377a..c68bb2cd20c 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -98,8 +98,108 @@ #include "bmesh.h" #include "intern/bmesh_private.h" /* for element checking */ -/* Mesh -> BMesh */ -void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) +void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) +{ + const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; + BM_mesh_cd_flag_apply(bm, cd_flag_all); + if (mesh) { + mesh->cd_flag = cd_flag_all; + } +} + +void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag) +{ + /* CustomData_bmesh_init_pool() must run first */ + BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); + BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL); + BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL); + + if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) { + if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT); + } + } + + if (cd_flag & ME_CDFLAG_EDGE_CREASE) { + if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_add(bm, &bm->edata, CD_CREASE); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + BM_data_layer_free(bm, &bm->edata, CD_CREASE); + } + } +#ifdef WITH_FREESTYLE + if (cd_flag & ME_CDFLAG_FREESTYLE_EDGE) { + if (!CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_add(bm, &bm->edata, CD_FREESTYLE_EDGE); + } + } + else { + if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_free(bm, &bm->edata, CD_FREESTYLE_EDGE); + } + } + + if (cd_flag & ME_CDFLAG_FREESTYLE_FACE) { + if (!CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(bm, &bm->pdata, CD_FREESTYLE_FACE); + } + } + else { + if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_free(bm, &bm->pdata, CD_FREESTYLE_FACE); + } + } +#endif +} + +char BM_mesh_cd_flag_from_bmesh(BMesh *bm) +{ + char cd_flag = 0; + if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_VERT_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; + } + if (CustomData_has_layer(&bm->edata, CD_CREASE)) { + cd_flag |= ME_CDFLAG_EDGE_CREASE; + } +#ifdef WITH_FREESTYLE + if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) { + cd_flag |= ME_CDFLAG_FREESTYLE_EDGE; + } + if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) { + cd_flag |= ME_CDFLAG_FREESTYLE_FACE; + } +#endif + return cd_flag; +} + +/** + * \brief Mesh -> BMesh + * + * \warning This function doesn't calculate face normals. + */ +void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr) { MVert *mvert; BLI_array_declare(verts); @@ -110,12 +210,15 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) BMVert *v, **vt = NULL, **verts = NULL; BMEdge *e, **fedges = NULL, **et = NULL; BMFace *f; - BMLoop *l; BLI_array_declare(fedges); float (*keyco)[3] = NULL; int *keyi; int totuv, i, j; + int cd_vert_bweight_offset; + int cd_edge_bweight_offset; + int cd_edge_crease_offset; + /* free custom data */ /* this isnt needed in most cases but do just incase */ CustomData_free(&bm->vdata, bm->totvert); @@ -152,15 +255,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name); } - if (!CustomData_has_layer(&bm->edata, CD_CREASE)) - CustomData_add_layer(&bm->edata, CD_CREASE, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) - CustomData_add_layer(&bm->edata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) - CustomData_add_layer(&bm->vdata, CD_BWEIGHT, CD_ASSIGN, NULL, 0); - if ((act_key_nr != 0) && (me->key != NULL)) { actkey = BLI_findlink(&me->key->block, act_key_nr - 1); } @@ -205,6 +299,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP); CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE); + BM_mesh_cd_flag_apply(bm, me->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); + for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ @@ -215,15 +315,15 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) /* this is necessary for selection counts to work properly */ if (mvert->flag & SELECT) { - BM_vert_select_set(bm, v, TRUE); + BM_vert_select_set(bm, v, true); } normal_short_to_float_v3(v->no, mvert->no); /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data); + CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true); - BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f); + if (cd_vert_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f); /* set shapekey data */ if (me->key) { @@ -263,21 +363,23 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) /* this is necessary for selection counts to work properly */ if (medge->flag & SELECT) { - BM_edge_select_set(bm, e, TRUE); + BM_edge_select_set(bm, e, true); } /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data); + CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true); + + if (cd_edge_bweight_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f); + if (cd_edge_crease_offset != -1) BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f); - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)medge->crease / 255.0f); - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)medge->bweight / 255.0f); } bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */ mpoly = me->mpoly; for (i = 0; i < me->totpoly; i++, mpoly++) { - BMIter iter; + BMLoop *l_iter; + BMLoop *l_first; BLI_array_empty(fedges); BLI_array_empty(verts); @@ -329,42 +431,41 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) /* this is necessary for selection counts to work properly */ if (mpoly->flag & ME_FACE_SEL) { - BM_face_select_set(bm, f, TRUE); + BM_face_select_set(bm, f, true); } f->mat_nr = mpoly->mat_nr; if (i == me->act_face) bm->act_face = f; - j = 0; - BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) { + j = mpoly->loopstart; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { /* Save index of correspsonding MLoop */ - CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data); - } + CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true); + } while ((l_iter = l_iter->next) != l_first); /* Copy Custom Data */ - CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data); + CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true); } bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */ if (me->mselect && me->totselect != 0) { - BMVert **vert_array = MEM_callocN(sizeof(BMVert *) * bm->totvert, - "Selection Conversion Vertex Pointer Array"); - BMEdge **edge_array = MEM_callocN(sizeof(BMEdge *) * bm->totedge, - "Selection Conversion Edge Pointer Array"); - BMFace **face_array = MEM_callocN(sizeof(BMFace *) * bm->totface, - "Selection Conversion Face Pointer Array"); - - BMIter iter; - BMVert *vert; - BMEdge *edge; - BMFace *face; + BMVert **vert_array = MEM_mallocN(sizeof(BMVert *) * bm->totvert, "VSelConv"); + BMEdge **edge_array = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, "ESelConv"); + BMFace **face_array = MEM_mallocN(sizeof(BMFace *) * bm->totface, "FSelConv"); MSelect *msel; - BM_ITER_MESH_INDEX (vert, &iter, bm, BM_VERTS_OF_MESH, i) { vert_array[i] = vert; } - BM_ITER_MESH_INDEX (edge, &iter, bm, BM_EDGES_OF_MESH, i) { edge_array[i] = edge; } - BM_ITER_MESH_INDEX (face, &iter, bm, BM_FACES_OF_MESH, i) { face_array[i] = face; } +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)vert_array, bm->totvert); } +#pragma omp section + { BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)edge_array, bm->totedge); } +#pragma omp section + { BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)face_array, bm->totface); } + } for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) { switch (msel->type) { @@ -400,7 +501,9 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr) } -/* BMesh -> Mesh */ +/** + * \brief BMesh -> Mesh + */ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert) { BMVert **vertMap = NULL; @@ -483,7 +586,7 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e) } } -void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) +void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) { MLoop *mloop; MPoly *mpoly; @@ -496,6 +599,10 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) BMIter iter, liter; int i, j, ototvert; + const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + ototvert = me->totvert; /* new vertex block */ @@ -550,15 +657,13 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly); + me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); + /* this is called again, 'dotess' arg is used there */ - mesh_update_customdata_pointers(me, 0); + BKE_mesh_update_customdata_pointers(me, 0); i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - float *bweight = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BWEIGHT); - - mvert->bweight = bweight ? (char)((*bweight) * 255) : 0; - copy_v3_v3(mvert->co, v->co); normal_float_to_short_v3(mvert->no, v->no); @@ -569,6 +674,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) /* copy over customdat */ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i); + if (cd_vert_bweight_offset != -1) mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset); + i++; mvert++; @@ -579,13 +686,8 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) med = medge; i = 0; BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - float *crease = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE); - float *bweight = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT); - med->v1 = BM_elem_index_get(e->v1); med->v2 = BM_elem_index_get(e->v2); - med->crease = crease ? (char)((*crease) * 255) : 0; - med->bweight = bweight ? (char)((*bweight) * 255) : 0; med->flag = BM_edge_flag_to_mflag(e); @@ -596,6 +698,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) bmesh_quick_edgedraw_flag(med, e); + if (cd_edge_crease_offset != -1) med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset); + if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset); + i++; med++; BM_CHECK_ELEMENT(e); @@ -677,7 +782,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) hmd->indexar[j++] = BM_elem_index_get(eve); } } - else j++; + else { + j++; + } } hmd->totindex = j; @@ -689,11 +796,11 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) if (vertMap) MEM_freeN(vertMap); } - if (dotess) { + if (do_tessface) { BKE_mesh_tessface_calc(me); } - mesh_update_customdata_pointers(me, dotess); + BKE_mesh_update_customdata_pointers(me, do_tessface); { BMEditSelection *selected; @@ -757,12 +864,12 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) * bmesh and the mesh are out of sync */ (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */ { - int act_is_basis = FALSE; + bool act_is_basis = false; /* find if this key is a basis for any others */ for (currkey = me->key->block.first; currkey; currkey = currkey->next) { if (bm->shapenr - 1 == currkey->relative) { - act_is_basis = TRUE; + act_is_basis = true; break; } } |