From 19496ab62a55a02e930eff3d7b735d9540bf01dd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 24 Jul 2013 19:31:58 +0000 Subject: internal bmesh api change: BM_elem_attrs_copy() no longer copies the selection flag. this was slowing down modifiers since the selection flags would be copied and flushed to connected geometry. --- source/blender/bmesh/intern/bmesh_construct.c | 37 +++++++++++++++++++------- source/blender/bmesh/intern/bmesh_construct.h | 1 + source/blender/bmesh/intern/bmesh_operators.h | 2 +- source/blender/bmesh/operators/bmo_subdivide.c | 34 +++++++++++------------ source/blender/editors/mesh/editmesh_knife.c | 30 ++++++++++++--------- 5 files changed, 63 insertions(+), 41 deletions(-) (limited to 'source') diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 1af4836c225..39b127c410e 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -817,11 +817,6 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, BLI_assert(ele_src->htype == ele_dst->htype); - if (ele_src->htype != ele_dst->htype) { - BLI_assert(!"type mismatch"); - return; - } - if ((hflag_mask & BM_ELEM_SELECT) == 0) { /* First we copy select */ if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) { @@ -833,6 +828,9 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, if (hflag_mask == 0) { ele_dst->hflag = ele_src->hflag; } + else if (hflag_mask == 0xff) { + /* pass */ + } else { ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask)); } @@ -860,7 +858,19 @@ void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst) { /* BMESH_TODO, default 'use_flags' to false */ - BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, 0); + BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, BM_ELEM_SELECT); +} + +void BM_elem_select_copy(BMesh *UNUSED(bm_src), BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v) +{ + const BMHeader *ele_src = ele_src_v; + BMHeader *ele_dst = ele_dst_v; + + BLI_assert(ele_src->htype == ele_dst->htype); + + if ((ele_src->hflag & BM_ELEM_SELECT) != (ele_dst->hflag & BM_ELEM_SELECT)) { + BM_elem_select_set(bm_dst, (BMElem *)ele_dst, (ele_src->hflag & BM_ELEM_SELECT) != 0); + } } /* helper function for 'BM_mesh_copy' */ @@ -894,7 +904,8 @@ static BMFace *bm_mesh_copy_new_face(BMesh *bm_new, BMesh *bm_old, /* use totface in case adding some faces fails */ BM_elem_index_set(f_new, (bm_new->totface - 1)); /* set_inline */ - BM_elem_attrs_copy(bm_old, bm_new, f, f_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff); + f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */ j = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); @@ -951,7 +962,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old) BM_ITER_MESH_INDEX (v, &iter, bm_old, BM_VERTS_OF_MESH, i) { /* copy between meshes so cant use 'example' argument */ v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); - BM_elem_attrs_copy(bm_old, bm_new, v, v_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff); + v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */ vtable[i] = v_new; BM_elem_index_set(v, i); /* set_inline */ BM_elem_index_set(v_new, i); /* set_inline */ @@ -968,7 +980,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old) vtable[BM_elem_index_get(e->v2)], e, BM_CREATE_SKIP_CD); - BM_elem_attrs_copy(bm_old, bm_new, e, e_new); + BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff); + e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */ etable[i] = e_new; BM_elem_index_set(e, i); /* set_inline */ BM_elem_index_set(e_new, i); /* set_inline */ @@ -991,6 +1004,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old) bm_old->elem_index_dirty &= ~BM_FACE; bm_new->elem_index_dirty &= ~BM_FACE; + + /* low level! don't do this for normal api use */ + bm_new->totvertsel = bm_old->totvertsel; + bm_new->totedgesel = bm_old->totedgesel; + bm_new->totfacesel = bm_old->totfacesel; + /* safety check */ BLI_assert(i == bm_old->totface); diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h index 3dcb1eb1ccb..9552ef6f5a4 100644 --- a/source/blender/bmesh/intern/bmesh_construct.h +++ b/source/blender/bmesh/intern/bmesh_construct.h @@ -53,6 +53,7 @@ void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type); void BM_elem_attrs_copy_ex(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v, const char hflag_mask); void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v); +void BM_elem_select_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v); void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize); BMesh *BM_mesh_copy(BMesh *bm_old); diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 4c6129cf43f..56d63694d88 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -49,9 +49,9 @@ enum { }; enum { + SUBDIV_SELECT_NONE, SUBDIV_SELECT_ORIG, SUBDIV_SELECT_INNER, - SUBDIV_SELECT_INNER_SEL, SUBDIV_SELECT_LOOPCUT }; diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 6b55d5ea877..d0b23c3cdfb 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -1203,24 +1203,22 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, BMO_op_exec(bm, &op); - if (seltype == SUBDIV_SELECT_INNER) { - BMOIter iter; - BMElem *ele; - - for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT); ele; ele = BMO_iter_step(&iter)) { - BM_elem_select_set(bm, ele, true); - } - } - else if (seltype == SUBDIV_SELECT_LOOPCUT) { - BMOIter iter; - BMElem *ele; - - /* deselect input */ - BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); - - for (ele = BMO_iter_new(&iter, op.slots_out, "geom_inner.out", BM_EDGE); ele; ele = BMO_iter_step(&iter)) { - BM_edge_select_set(bm, (BMEdge *)ele, true); - } + switch (seltype) { + case SUBDIV_SELECT_NONE: + break; + case SUBDIV_SELECT_ORIG: + /* set the newly created data to be selected */ + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); + BM_mesh_select_flush(bm); + break; + case SUBDIV_SELECT_INNER: + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT, BM_ELEM_SELECT, true); + break; + case SUBDIV_SELECT_LOOPCUT: + /* deselect input */ + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + BMO_slot_buffer_hflag_enable(bm, op.slots_out, "geom_inner.out", BM_EDGE, BM_ELEM_SELECT, true); + break; } BMO_op_finish(bm, &op); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 50db460e5bc..9440a67c7f4 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2623,15 +2623,15 @@ static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BM /* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface. * The new face will be on the left side of the chain as viewed from the normal-out side of f. */ -static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **newface) +static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **r_f_new) { BMesh *bm = kcd->em->bm; KnifeEdge *kfe, *kfelast; BMVert *v1, *v2; - BMFace *fnew; + BMFace *f_new; Ref *ref; KnifeVert *kfv, *kfvprev; - BMLoop *lnew, *l_iter; + BMLoop *l_new, *l_iter; int i; int nco = BLI_countlist(chain) - 1; float (*cos)[3] = BLI_array_alloca(cos, nco); @@ -2652,23 +2652,21 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha kfvprev = kfv; } BLI_assert(i == nco); - lnew = NULL; + l_new = NULL; if (nco == 0) { /* Want to prevent creating two-sided polygons */ if (BM_edge_exists(v1, v2)) { - *newface = NULL; + f_new = NULL; } else { - *newface = BM_face_split(bm, f, v1, v2, &lnew, NULL, true); + f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, true); } } else { - fnew = BM_face_split_n(bm, f, v1, v2, cos, nco, &lnew, NULL); - *newface = fnew; - - if (fnew) { + f_new = BM_face_split_n(bm, f, v1, v2, cos, nco, &l_new, NULL); + if (f_new) { /* Now go through lnew chain matching up chain kv's and assign real v's to them */ - for (l_iter = lnew->next, i = 0; i < nco; l_iter = l_iter->next, i++) { + for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) { BLI_assert(equals_v3v3(cos[i], l_iter->v->co)); if (kcd->select_result) { BM_edge_select_set(bm, l_iter->e, true); @@ -2680,10 +2678,15 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha /* the select chain above doesnt account for the first loop */ if (kcd->select_result) { - if (lnew) { - BM_edge_select_set(bm, lnew->e, true); + if (l_new) { + BM_edge_select_set(bm, l_new->e, true); } } + else { + BM_elem_select_copy(bm, bm, f, f_new); + } + + *r_f_new = f_new; } static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges) @@ -2887,6 +2890,7 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd) knife_make_cuts(kcd); #endif + EDBM_selectmode_flush(kcd->em); EDBM_mesh_normals_update(kcd->em); EDBM_update_generic(kcd->em, true, true); } -- cgit v1.2.3