diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-07-11 08:24:36 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-07-11 08:24:36 +0400 |
commit | 7fec23ae0a88ff4e6383d33574936bb37ca44763 (patch) | |
tree | 0dbe4f5408faee02e1c18059e1a8bc3593b3a334 /source | |
parent | b36999b2f7f6bd3766c87249832dc52dd5fc5ae3 (diff) |
fix for problem with edge slide where it would stop shapekey modifier from being applied (because of added vertices),
now, instead of making hidden copies of faces, the faces are copied into a temp bmesh.
also remove a hash that was being created and not used (old code).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 28 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 14 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 6 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 137 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 5 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 2 |
8 files changed, 78 insertions, 119 deletions
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 15030f90c65..a6897d533e7 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -890,6 +890,24 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old, return f_new; } +void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTemplate *allocsize) +{ + if (allocsize == NULL) { + allocsize = &bm_mesh_allocsize_default; + } + + CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH, CD_CALLOC, 0); + + CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT); + CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE); + CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP); + CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE); +} + + BMesh *BM_mesh_copy(BMesh *bm_old) { BMesh *bm_new; @@ -908,15 +926,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old) /* allocate a bmesh */ bm_new = BM_mesh_create(&allocsize); - CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0); - CustomData_copy(&bm_old->pdata, &bm_new->pdata, CD_MASK_BMESH, CD_CALLOC, 0); - - CustomData_bmesh_init_pool(&bm_new->vdata, allocsize.totvert, BM_VERT); - CustomData_bmesh_init_pool(&bm_new->edata, allocsize.totedge, BM_EDGE); - CustomData_bmesh_init_pool(&bm_new->ldata, allocsize.totloop, BM_LOOP); - CustomData_bmesh_init_pool(&bm_new->pdata, allocsize.totface, BM_FACE); + BM_mesh_copy_init_customdata(bm_new, bm_old, &allocsize); vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable"); etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable"); diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 949366309b9..24b94a61cee 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -27,6 +27,8 @@ * \ingroup bmesh */ +struct BMAllocTemplate; + BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const bool no_double); @@ -50,6 +52,7 @@ void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type); void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target); +void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize); BMesh *BM_mesh_copy(BMesh *bm_old); char BM_face_flag_from_mflag(const char mflag); diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index b7eeceae494..ecb776e7589 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -210,7 +210,7 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge return l; } -BMFace *BM_face_copy(BMesh *bm, BMFace *f, +BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges) { BMVert **verts = BLI_array_alloca(verts, f->len); @@ -221,11 +221,13 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, BMFace *f_copy; int i; + BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges)); + l_iter = l_first = BM_FACE_FIRST_LOOP(f); i = 0; do { if (copy_verts) { - verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0); + verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, 0); } else { verts[i] = l_iter->v; @@ -248,7 +250,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, v1 = verts[(i + 1) % f->len]; } - edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, 0); + edges[i] = BM_edge_create(bm_dst, v1, v2, l_iter->e, 0); } else { edges[i] = l_iter->e; @@ -256,14 +258,14 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, i++; } while ((l_iter = l_iter->next) != l_first); - f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD); + f_copy = BM_face_create(bm_dst, verts, edges, f->len, BM_CREATE_SKIP_CD); - BM_elem_attrs_copy(bm, bm, f, f_copy); + BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy); l_iter = l_first = BM_FACE_FIRST_LOOP(f); l_copy = BM_FACE_FIRST_LOOP(f_copy); do { - BM_elem_attrs_copy(bm, bm, l_iter, l_copy); + BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy); l_copy = l_copy->next; } while ((l_iter = l_iter->next) != l_first); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index a1f378aaa5d..6e691a9a0b5 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -27,7 +27,7 @@ * \ingroup bmesh */ -BMFace *BM_face_copy(BMesh *bm, BMFace *f, +BMFace *BM_face_copy(BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges); typedef enum eBMCreateFlag { diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index c75843f029a..cb8e9bd7004 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -345,7 +345,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l /* do we have a multires layer? */ if (has_mdisp) { - f_tmp = BM_face_copy(bm, f, false, false); + f_tmp = BM_face_copy(bm, bm, f, false, false); } #ifdef USE_BMESH_HOLES @@ -414,7 +414,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[ BLI_assert(v1 != v2); - f_tmp = BM_face_copy(bm, f, true, true); + f_tmp = BM_face_copy(bm, bm, f, true, true); if (!r_l) r_l = &l_dummy; @@ -662,7 +662,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce /* flag existing faces so we can differentiate oldfaces from new faces */ for (i = 0; i < BLI_array_count(oldfaces); i++) { BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP); - oldfaces[i] = BM_face_copy(bm, oldfaces[i], true, true); + oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true); BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP); } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 4ff1c22a4ed..8818ad1d421 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -59,7 +59,6 @@ #include "BLI_string.h" #include "BLI_ghash.h" #include "BLI_linklist.h" -#include "BLI_smallhash.h" #include "BKE_nla.h" #include "BKE_bmesh.h" @@ -4995,8 +4994,7 @@ static bool createEdgeSlideVerts(TransInfo *t) TransDataEdgeSlideVert *sv_array; int sv_tot; BMBVHTree *btree; - /* BMVert -> sv_array index */ - SmallHash table; + int *sv_table; /* BMVert -> sv_array index */ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); View3D *v3d = NULL; RegionView3D *rv3d = NULL; @@ -5036,14 +5034,7 @@ static bool createEdgeSlideVerts(TransInfo *t) else { ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat); } - - BLI_smallhash_init(&sld->vhash); - BLI_smallhash_init(&table); - if (sld->use_origfaces) { - BLI_smallhash_init(&sld->origfaces); - } - /*ensure valid selection*/ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { @@ -5077,20 +5068,26 @@ static bool createEdgeSlideVerts(TransInfo *t) } } + sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__); + j = 0; - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { BM_elem_flag_enable(v, BM_ELEM_TAG); - BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j)); + sv_table[i] = j; j += 1; } else { BM_elem_flag_disable(v, BM_ELEM_TAG); + sv_table[i] = -1; } + BM_elem_index_set(v, i); /* set_inline */ } + bm->elem_index_dirty &= ~BM_VERT; if (!j) { MEM_freeN(sld); + MEM_freeN(sv_table); return false; } @@ -5187,9 +5184,9 @@ static bool createEdgeSlideVerts(TransInfo *t) BMEdge *e_prev; /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */ - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); BLI_assert(v != NULL); - sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + sv = &sv_array[sv_table[BM_elem_index_get(v)]]; sv->v = v; copy_v3_v3(sv->v_co_orig, v->co); sv->loop_nr = loop_nr; @@ -5213,9 +5210,9 @@ static bool createEdgeSlideVerts(TransInfo *t) e = get_other_edge(v, e); if (!e) { - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); BLI_assert(v != NULL); - sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + sv = &sv_array[sv_table[BM_elem_index_get(v)]]; sv->v = v; copy_v3_v3(sv->v_co_orig, v->co); sv->loop_nr = loop_nr; @@ -5282,7 +5279,6 @@ static bool createEdgeSlideVerts(TransInfo *t) loop_nr++; } - /* use for visibility checks */ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); @@ -5330,8 +5326,8 @@ static bool createEdgeSlideVerts(TransInfo *t) continue; } - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); - j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + j = sv_table[BM_elem_index_get(v)]; if (sv_array[j].v_b) { ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat); @@ -5378,36 +5374,29 @@ static bool createEdgeSlideVerts(TransInfo *t) bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); + if (sld->use_origfaces) { + sld->origfaces = BLI_ghash_ptr_new(__func__); + sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default); + /* we need to have matching customdata */ + BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL); + } + /*create copies of faces for customdata projection*/ sv_array = sld->sv; for (i = 0; i < sld->totsv; i++, sv_array++) { - BMIter fiter, liter; + BMIter fiter; BMFace *f; - BMLoop *l; if (sld->use_origfaces) { BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) { - - if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) { - BMFace *copyf = BM_face_copy(bm, f, true, true); - - BM_face_select_set(bm, copyf, false); - BM_elem_flag_enable(copyf, BM_ELEM_HIDDEN); - BM_ITER_ELEM (l, &liter, copyf, BM_LOOPS_OF_FACE) { - BM_vert_select_set(bm, l->v, false); - BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN); - BM_edge_select_set(bm, l->e, false); - BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN); - } - - BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf); + if (!BLI_ghash_haskey(sld->origfaces, f)) { + BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true); + BLI_ghash_insert(sld->origfaces, f, f_copy); } } } - BLI_smallhash_insert(&sld->vhash, (uintptr_t)sv_array->v, sv_array); - /* switch a/b if loop direction is different from global direction */ l_nr = sv_array->loop_nr; if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) { @@ -5419,9 +5408,8 @@ static bool createEdgeSlideVerts(TransInfo *t) if (rv3d) calcNonProportionalEdgeSlide(t, sld, mval); - sld->origfaces_init = true; sld->em = em; - + /*zero out start*/ zero_v2(mval_start); @@ -5439,18 +5427,13 @@ static bool createEdgeSlideVerts(TransInfo *t) t->customData = sld; - BLI_smallhash_release(&table); + MEM_freeN(sv_table); if (btree) { BKE_bmbvh_free(btree); } MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); - if (sld->use_origfaces) { - /* arrays are dirty from copying faces: EDBM_index_arrays_free */ - EDBM_update_generic(em, false, true); - } - return true; } @@ -5472,15 +5455,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { BMFace *f_copy; /* the copy of 'f' */ BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ - bool is_sel, is_hide; - - /* the face attributes of the copied face will get - * copied over, so its necessary to save the selection - * and hidden state*/ - is_sel = BM_elem_flag_test(l->f, BM_ELEM_SELECT) != 0; - is_hide = BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) != 0; - f_copy = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l->f); + f_copy = BLI_ghash_lookup(sld->origfaces, l->f); /* project onto copied projection face */ f_copy_flip = f_copy; @@ -5494,12 +5470,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) if (sld->perc < 0.0f) { if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_b)) { - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); } } else if (sld->perc > 0.0f) { if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_a)) { - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); } } @@ -5585,7 +5561,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) l_adj = l; } - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_adj->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f); } } } @@ -5602,37 +5578,24 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) } /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(em->bm, em->bm, f_copy, l->f); - - /* restore selection and hidden flags */ - BM_face_select_set(em->bm, l->f, is_sel); - if (!is_hide) { - /* this check is a workaround for bug, see note - [#30735], - * without this edge can be hidden and selected */ - BM_elem_hide_set(em->bm, l->f, is_hide); - } + BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f); } } } void freeEdgeSlideTempFaces(EdgeSlideData *sld) { - if (sld->origfaces_init && sld->use_origfaces) { - SmallHashIter hiter; - BMFace *copyf; - - copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL); - for (; copyf; copyf = BLI_smallhash_iternext(&hiter, NULL)) { - BM_face_verts_kill(sld->em->bm, copyf); + if (sld->use_origfaces) { + if (sld->bm_origfaces) { + BM_mesh_free(sld->bm_origfaces); + sld->bm_origfaces = NULL; } - BLI_smallhash_release(&sld->origfaces); - - /* arrays are dirty from removing faces: EDBM_index_arrays_free */ - EDBM_update_generic(sld->em, FALSE, TRUE); + if (sld->origfaces) { + BLI_ghash_free(sld->origfaces, NULL, NULL); + sld->origfaces = NULL; + } } - - sld->origfaces_init = false; } @@ -5640,30 +5603,12 @@ void freeEdgeSlideVerts(TransInfo *t) { EdgeSlideData *sld = t->customData; -#if 0 /*BMESH_TODO*/ - if (me->drawflag & ME_DRAWEXTRA_EDGELEN) { - TransDataEdgeSlideVert *sv; - LinkNode *look = sld->vertlist; - GHash *vertgh = sld->vhash; - while (look) { - sv = BLI_ghash_lookup(vertgh, (EditVert *)look->link); - if (sv != NULL) { - sv->v_a->f &= !SELECT; - sv->v_b->f &= !SELECT; - } - look = look->next; - } - } -#endif - if (!sld) return; freeEdgeSlideTempFaces(sld); bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); - - BLI_smallhash_release(&sld->vhash); MEM_freeN(sld->sv); MEM_freeN(sld); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index ea20721b5ae..911d4b0a623 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -201,15 +201,14 @@ typedef struct EdgeSlideData { TransDataEdgeSlideVert *sv; int totsv; - struct SmallHash vhash; - struct SmallHash origfaces; + struct GHash *origfaces; int mval_start[2], mval_end[2]; struct BMEditMesh *em; /* flag that is set when origfaces is initialized */ bool use_origfaces; - bool origfaces_init; + struct BMesh *bm_origfaces; float perc; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 0db8b07d5f5..0e2fbe8a526 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1616,7 +1616,7 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw) return NULL; } - f_cpy = BM_face_copy(bm, self->f, do_verts, do_edges); + f_cpy = BM_face_copy(bm, bm, self->f, do_verts, do_edges); if (f_cpy) { return BPy_BMFace_CreatePyObject(bm, f_cpy); |