diff options
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 16 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_edgesplit.c | 398 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_tools.c | 81 |
5 files changed, 73 insertions, 428 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 3ca7750f571..133e446f891 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -41,8 +41,6 @@ * TESTING ONLY! */ // #define USE_DEBUG_INDEX_MEMCHECK -static int bm_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); - #ifdef USE_DEBUG_INDEX_MEMCHECK #define DEBUG_MEMCHECK_INDEX_INVALIDATE(ele) \ { \ @@ -1748,7 +1746,7 @@ static int bm_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) * * \return Success */ -int bm_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) +int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) { BMEdge **stack = NULL; BLI_array_declare(stack); @@ -1856,11 +1854,11 @@ int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, for (i = 0; i < e_in_len; i++) { BMEdge *e = e_in[i]; if (e->l && BM_vert_in_edge(e, v)) { - bm_edge_separate(bm, e, e->l); + bmesh_edge_separate(bm, e, e->l); } } - return bm_vert_separate(bm, v, r_vout, r_vout_len); + return bmesh_vert_separate(bm, v, r_vout, r_vout_len); } /** @@ -1911,7 +1909,7 @@ int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget) * \note Does nothing if \a l_sep is already the only loop in the * edge radial. */ -static int bm_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) +int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) { BMEdge *ne; int radlen; @@ -1959,8 +1957,8 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl) /* peel the face from the edge radials on both sides of the * loop vert, disconnecting the face from its fan */ - bm_edge_separate(bm, sl->e, sl); - bm_edge_separate(bm, sl->prev->e, sl->prev); + bmesh_edge_separate(bm, sl->e, sl); + bmesh_edge_separate(bm, sl->prev->e, sl->prev); if (bmesh_disk_count(sv) == 2) { /* If there are still only two edges out of sv, then @@ -1978,7 +1976,7 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl) /* Split all fans connected to the vert, duplicating it for * each fans. */ - bm_vert_separate(bm, sv, &vtar, &len); + bmesh_vert_separate(bm, sv, &vtar, &len); /* There should have been at least two fans cut apart here, * otherwise the early exit would have kicked in. */ diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 11f3e052bff..e10222dc29a 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -41,6 +41,9 @@ void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_vert_kill(BMesh *bm, BMVert *v); int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); +int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); + +int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len); int bmesh_loop_reverse(BMesh *bm, BMFace *f); diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 97990c614d5..f2dcaded8ca 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -890,8 +890,7 @@ static BMOpDefine bmo_vertexshortestpath_def = { static BMOpDefine bmo_edgesplit_def = { "edgesplit", {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {BMO_OP_SLOT_ELEMENT_BUF, "edgeout1"}, /* old output disconnected edges */ - {BMO_OP_SLOT_ELEMENT_BUF, "edgeout2"}, /* new output disconnected edges */ + {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */ {0} /* null-terminating sentine */}, bmo_edgesplit_exec, BMO_OP_FLAG_UNTAN_MULTIRES diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c index f1d3fbeb6af..44d0ad4ff94 100644 --- a/source/blender/bmesh/operators/bmo_edgesplit.c +++ b/source/blender/bmesh/operators/bmo_edgesplit.c @@ -15,208 +15,21 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor(s): Joseph Eagar + * Contributor(s): Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ -#include <string.h> /* for memcpy */ - #include "MEM_guardedalloc.h" -#include "BLI_array.h" - #include "bmesh.h" #include "intern/bmesh_operators_private.h" /* own include */ -typedef struct EdgeTag { - BMVert *newv1, *newv2; - BMEdge *newe1, *newe2; -} EdgeTag; - -/* (EDGE_DEL == FACE_DEL) - this must be the case */ -enum { - EDGE_DEL = 1, - EDGE_SEAM = 2, - EDGE_MARK = 4, - EDGE_RET1 = 8, - EDGE_RET2 = 16 -}; - enum { - FACE_DEL = EDGE_DEL, - FACE_NEW = 2 + EDGE_SEAM = 1 }; -static BMFace *remake_face(BMesh *bm, EdgeTag *etags, BMFace *f, BMVert **f_verts, BMEdge **edges_tmp) -{ - BMIter liter1, liter2; - EdgeTag *et; - BMFace *f2; - BMLoop *l, *l2; - BMEdge *e; - BMVert *lastv1, *lastv2 /* , *v1, *v2 */ /* UNUSED */; - int i; - - /* we do final edge last */ - lastv1 = f_verts[f->len - 1]; - lastv2 = f_verts[0]; - /* v1 = f_verts[0]; */ /* UNUSED */ - /* v2 = f_verts[1]; */ /* UNUSED */ - for (i = 0; i < f->len - 1; i++) { - e = BM_edge_create(bm, f_verts[i], f_verts[i + 1], NULL, TRUE); - if (!e) { - return NULL; - } - edges_tmp[i] = e; - } - - edges_tmp[i] = BM_edge_create(bm, lastv1, lastv2, NULL, TRUE); - - f2 = BM_face_create(bm, f_verts, edges_tmp, f->len, FALSE); - if (!f2) { - return NULL; - } - - BM_elem_attrs_copy(bm, bm, f, f2); - - l = BM_iter_new(&liter1, bm, BM_LOOPS_OF_FACE, f); - l2 = BM_iter_new(&liter2, bm, BM_LOOPS_OF_FACE, f2); - for ( ; l && l2; l = BM_iter_step(&liter1), l2 = BM_iter_step(&liter2)) { - BM_elem_attrs_copy(bm, bm, l, l2); - if (l->e != l2->e) { - /* set up data for figuring out the two sides of - * the split */ - - /* set edges index as dirty after running all */ - BM_elem_index_set(l2->e, BM_elem_index_get(l->e)); /* set_dirty! */ - et = &etags[BM_elem_index_get(l->e)]; - - if (!et->newe1) { - et->newe1 = l2->e; - } - else if (!et->newe2) { - et->newe2 = l2->e; - } - else { - /* Only two new edges should be created from each original edge - * for edge split operation */ - - //BLI_assert(et->newe1 == l2->e || et->newe2 == l2->e); - et->newe2 = l2->e; - } - - if (BMO_elem_flag_test(bm, l->e, EDGE_SEAM)) { - BMO_elem_flag_enable(bm, l2->e, EDGE_SEAM); - } - - BM_elem_attrs_copy(bm, bm, l->e, l2->e); - } - - BMO_elem_flag_enable(bm, l->e, EDGE_MARK); - BMO_elem_flag_enable(bm, l2->e, EDGE_MARK); - } - - return f2; -} - -static void tag_out_edges(BMesh *bm, EdgeTag *etags, BMOperator *UNUSED(op)) -{ - EdgeTag *et; - BMIter iter; - BMLoop *l, *l_start, *l_prev; - BMEdge *e; - BMVert *v; - int i, ok; - - ok = 0; - while (ok++ < 100000) { - BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (!BMO_elem_flag_test(bm, e, EDGE_SEAM)) - continue; - - if (e->l) { - break; - } - } - - if (!e) { - break; - } - - /* ok we found an edge, part of a region of splits we need - * to identify. now walk along it */ - for (i = 0; i < 2; i++) { - l = e->l; - - v = i ? l->next->v : l->v; - - while (1) { - et = &etags[BM_elem_index_get(l->e)]; - if (et->newe1 == l->e) { - if (et->newe1) { - BMO_elem_flag_enable(bm, et->newe1, EDGE_RET1); - BMO_elem_flag_disable(bm, et->newe1, EDGE_SEAM); - } - if (et->newe2) { - BMO_elem_flag_enable(bm, et->newe2, EDGE_RET2); - BMO_elem_flag_disable(bm, et->newe2, EDGE_SEAM); - } - } - else { - if (et->newe1) { - BMO_elem_flag_enable(bm, et->newe1, EDGE_RET2); - BMO_elem_flag_disable(bm, et->newe1, EDGE_SEAM); - } - if (et->newe2) { - BMO_elem_flag_enable(bm, et->newe2, EDGE_RET1); - BMO_elem_flag_disable(bm, et->newe2, EDGE_SEAM); - } - } - - /* If the original edge was non-manifold edges, then it is - * possible l->e is not et->newe1 or et->newe2. So always clear - * the flag on l->e as well, to prevent infinite looping. */ - BMO_elem_flag_disable(bm, l->e, EDGE_SEAM); - l_start = l; - - do { - /* l_prev checks stops us from looping over the same edge forever [#30459] */ - l_prev = l; - l = BM_face_other_edge_loop(l->f, l->e, v); - if (l == l_start || BM_edge_face_count(l->e) != 2) { - break; - } - l = l->radial_next; - } while (l != l_start && l != l_prev && !BMO_elem_flag_test(bm, l->e, EDGE_SEAM)); - - if (l == l_start || !BMO_elem_flag_test(bm, l->e, EDGE_SEAM)) { - break; - } - - v = (l->v == v) ? l->next->v : l->v; - } - } - } -} - -/* helper functions for edge tag's */ -BM_INLINE BMVert *bm_edge_tag_vert_get(EdgeTag *et, BMVert *v, BMLoop *l) -{ - return (l->e->v1 == v) ? et->newv1 : et->newv2; -} - -BM_INLINE void bm_edge_tag_vert_set(EdgeTag *et, BMVert *v, BMLoop *l, BMVert *vset) -{ - if (l->e->v1 == v) { - et->newv1 = vset; - } - else { - et->newv2 = vset; - } -} - /** * Remove the EDGE_SEAM flag for edges we cant split * @@ -238,6 +51,11 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) /* tag all boundry verts so as not to untag an edge which is inbetween only 2 faces [] */ BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + + /* unrelated to flag assignment in this function - since this is the + * only place we loop over all edges, disable tag */ + BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); + if (BM_edge_is_boundary(e)) { vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; @@ -270,202 +88,36 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) void bmo_edgesplit_exec(BMesh *bm, BMOperator *op) { - EdgeTag *etags, *et; /* edge aligned array of tags */ - BMIter iter, liter; - BMFace *f, *f2; - BMLoop *l, *l2, *l3; - BMLoop *l_next, *l_prev; + BMOIter siter; BMEdge *e; - BMVert *v, *v2; - - /* face/vert aligned vert array */ - BMVert **f_verts = NULL; - BLI_array_declare(f_verts); - - BMEdge **edges_tmp = NULL; - BLI_array_declare(edges_tmp); - int i, j; BMO_slot_buffer_flag_enable(bm, op, "edges", EDGE_SEAM, BM_EDGE); bm_edgesplit_validate_seams(bm, op); - etags = MEM_callocN(sizeof(EdgeTag) * bm->totedge, "EdgeTag"); - - BM_mesh_elem_index_ensure(bm, BM_EDGE); - - BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { - - if (BMO_elem_flag_test(bm, f, FACE_NEW)) { - continue; - } - - BLI_array_empty(f_verts); - BLI_array_growitems(f_verts, f->len); - memset(f_verts, 0, sizeof(BMVert *) * f->len); - - /* this is passed onto remake_face() so it doesnt need to allocate - * a new array on each call. */ - BLI_array_empty(edges_tmp); - BLI_array_growitems(edges_tmp, f->len); - - i = 0; - BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { - if (!BMO_elem_flag_test(bm, l->e, EDGE_SEAM)) { - if (!f_verts[i]) { - - et = &etags[BM_elem_index_get(l->e)]; - if (bm_edge_tag_vert_get(et, l->v, l)) { - f_verts[i] = bm_edge_tag_vert_get(et, l->v, l); - } - else { - f_verts[i] = l->v; - } - } - i++; - continue; - } - - l_next = l->next; - l_prev = l->prev; - - for (j = 0; j < 2; j++) { - /* correct as long as i & j dont change during the loop */ - const int fv_index = j ? (i + 1) % f->len : i; /* face vert index */ - l2 = j ? l_next : l_prev; - v = j ? l2->v : l->v; - - if (BMO_elem_flag_test(bm, l2->e, EDGE_SEAM)) { - if (f_verts[fv_index] == NULL) { - /* make unique vert here for this face only */ - v2 = BM_vert_create(bm, v->co, v); - f_verts[fv_index] = v2; - } - else { - v2 = f_verts[fv_index]; - } - } - else { - /* generate unique vert for non-seam edge(s) - * around the manifold vert fan if necessary */ - - /* first check that we have two seam edges - * somewhere within this fa */ - l3 = l2; - do { - if (BM_edge_face_count(l3->e) != 2) { - /* if we hit a boundary edge, tag - * l3 as null so we know to disconnect - * it */ - if (BM_edge_face_count(l3->e) == 1) { - l3 = NULL; - } - break; - } - - l3 = l3->radial_next; - l3 = BM_face_other_edge_loop(l3->f, l3->e, v); - } while (l3 != l2 && !BMO_elem_flag_test(bm, l3->e, EDGE_SEAM)); - - if (l3 == NULL || (BMO_elem_flag_test(bm, l3->e, EDGE_SEAM) && l3->e != l->e)) { - et = &etags[BM_elem_index_get(l2->e)]; - if (bm_edge_tag_vert_get(et, v, l2) == NULL) { - v2 = BM_vert_create(bm, v->co, v); - - l3 = l2; - do { - bm_edge_tag_vert_set(et, v, l3, v2); - if (BM_edge_face_count(l3->e) != 2) { - break; - } - - l3 = l3->radial_next; - l3 = BM_face_other_edge_loop(l3->f, l3->e, v); - - et = &etags[BM_elem_index_get(l3->e)]; - } while (l3 != l2 && !BMO_elem_flag_test(bm, l3->e, EDGE_SEAM)); - } - else { - v2 = bm_edge_tag_vert_get(et, v, l2); - } - - f_verts[fv_index] = v2; - } - else { - f_verts[fv_index] = v; - } - } - } - - i++; - } - - /* debugging code, quick way to find the face/vert combination - * which is failing assuming quads start planer - campbell */ -#if 0 - if (f->len == 4) { - float no1[3]; - float no2[3]; - float angle_error; - printf(" ** found QUAD\n"); - normal_tri_v3(no1, f_verts[0]->co, f_verts[1]->co, f_verts[2]->co); - normal_tri_v3(no2, f_verts[0]->co, f_verts[2]->co, f_verts[3]->co); - if ((angle_error = angle_v3v3(no1, no2)) > 0.05) { - printf(" ERROR %.4f\n", angle_error); - print_v3("0", f_verts[0]->co); - print_v3("1", f_verts[1]->co); - print_v3("2", f_verts[2]->co); - print_v3("3", f_verts[3]->co); - - } - } - else { - printf(" ** fount %d len face\n", f->len); - } -#endif + BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) { + if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { + /* this flag gets copied so we can be sure duplicate edges get it too (important) */ + BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); - f2 = remake_face(bm, etags, f, f_verts, edges_tmp); - if (f2) { - BMO_elem_flag_enable(bm, f, FACE_DEL); - BMO_elem_flag_enable(bm, f2, FACE_NEW); + bmesh_edge_separate(bm, e, e->l); + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); } - /* else { ... should we raise an error here, or an assert? - campbell */ } - - /* remake_face() sets invalid indices, - * likely these will be corrected on operator exit anyway */ - bm->elem_index_dirty &= ~BM_EDGE; - - /* cant call the operator because 'tag_out_edges' - * relies on original index values, from before editing geometry */ -#if 0 - BMO_op_callf(bm, "del geom=%ff context=%i", FACE_DEL, DEL_ONLYFACES); -#else - BMO_remove_tagged_context(bm, FACE_DEL, DEL_ONLYFACES); -#endif - - /* test EDGE_MARK'd edges if we need to delete them, EDGE_MARK - * is set in remake_face */ - BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { - if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { - if (!e->l) { - BMO_elem_flag_enable(bm, e, EDGE_DEL); + BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) { + if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v1, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v1, NULL, NULL); + } + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v2, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v2, NULL, NULL); } } } -#if 0 - BMO_op_callf(bm, "del geom=%fe context=%i", EDGE_DEL, DEL_EDGES); -#else - BMO_remove_tagged_context(bm, EDGE_DEL, DEL_EDGES); -#endif - - tag_out_edges(bm, etags, op); - BMO_slot_buffer_from_flag(bm, op, "edgeout1", EDGE_RET1, BM_EDGE); - BMO_slot_buffer_from_flag(bm, op, "edgeout2", EDGE_RET2, BM_EDGE); - - BLI_array_free(f_verts); - BLI_array_free(edges_tmp); - if (etags) MEM_freeN(etags); + BMO_slot_buffer_from_hflag(bm, op, "edgeout", BM_ELEM_INTERNAL_TAG, BM_EDGE); } diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 924e1fbf339..022e94e8209 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -2325,17 +2325,11 @@ static float mesh_rip_edgedist(ARegion *ar, float mat[][4], float *co1, float *c return dist_to_line_segment_v2(mvalf, vec1, vec2); } -/* #define USE_BVH_VISIBILITY */ - /* based on mouse cursor position, it defines how is being ripped */ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) { Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); -#ifdef USE_BVH_VISIBILITY - BMBVHTree *bvhtree; - View3D *v3d = CTX_wm_view3d(C); -#endif RegionView3D *rv3d = CTX_wm_region_view3d(C); BMEditMesh *em = BMEdit_FromObject(obedit); BMesh *bm = em->bm; @@ -2345,9 +2339,10 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) BMLoop *l; BMEdge *e, *e2; BMVert *v, *ripvert = NULL; - int side = 0, i, singlesel = FALSE; + int i, singlesel = FALSE; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; - float dist = FLT_MAX, d; + float dist = FLT_MAX; + float d, d_a, d_b; /* note on selection: * When calling edge split we operate on tagged edges rather then selected @@ -2465,44 +2460,47 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) bvhtree = BMBVH_NewBVH(em, 0, NULL, NULL); #endif - for (i = 0; i < 2; i++) { - BMO_ITER(e, &siter, bm, &bmop, i ? "edgeout2":"edgeout1", BM_EDGE) { - float cent[3] = {0, 0, 0}, mid[3]; - float vec[3]; - float fmval_tweak[3]; - BMVert *v1_other; - BMVert *v2_other; + BMO_ITER(e, &siter, bm, &bmop, "edgeout", BM_EDGE) { + float cent[3] = {0, 0, 0}, mid[3]; + float vec[3]; + float fmval_tweak[3]; + BMVert *v1_other; + BMVert *v2_other; #ifdef USE_BVH_VISIBILITY - if (!BMBVH_EdgeVisible(bvhtree, e, ar, v3d, obedit) || !e->l) - continue; + if (!BMBVH_EdgeVisible(bvhtree, e, ar, v3d, obedit) || !e->l) + continue; #endif - /* method for calculating distance: - * - * for each edge: calculate face center, then made a vector - * from edge midpoint to face center. offset edge midpoint - * by a small amount along this vector. */ - - /* rather then the face center, get the middle of - * both edge verts connected to this one */ - v1_other = BM_face_other_vert_loop(e->l->f, e->v2, e->v1)->v; - v2_other = BM_face_other_vert_loop(e->l->f, e->v1, e->v2)->v; - mid_v3_v3v3(cent, v1_other->co, v2_other->co); - mid_v3_v3v3(mid, e->v1->co, e->v2->co); - sub_v3_v3v3(vec, cent, mid); - normalize_v3(vec); - mul_v3_fl(vec, 0.01f); + /* method for calculating distance: + * + * for each edge: calculate face center, then made a vector + * from edge midpoint to face center. offset edge midpoint + * by a small amount along this vector. */ - /* ratrher then adding to both verts, subtract from the mouse */ - sub_v2_v2v2(fmval_tweak, fmval, vec); + /* rather then the face center, get the middle of + * both edge verts connected to this one */ + v1_other = BM_face_other_vert_loop(e->l->f, e->v2, e->v1)->v; + v2_other = BM_face_other_vert_loop(e->l->f, e->v1, e->v2)->v; + mid_v3_v3v3(cent, v1_other->co, v2_other->co); + mid_v3_v3v3(mid, e->v1->co, e->v2->co); - d = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval_tweak); + ED_view3d_project_float_v2(ar, cent, cent, projectMat); + ED_view3d_project_float_v2(ar, mid, mid, projectMat); - if (d < dist) { - side = i; - dist = d; - } + sub_v2_v2v2(vec, cent, mid); + normalize_v2(vec); + mul_v2_fl(vec, 0.1f); + + + /* ratrher then adding to both verts, subtract from the mouse */ + sub_v2_v2v2(fmval_tweak, fmval, vec); + + d_a = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval_tweak); + d_b = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval); + + if (d_a > d_b) { + BM_elem_select_set(bm, e, FALSE); } } @@ -2553,11 +2551,6 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) BM_elem_select_set(bm, v_best, TRUE); } #endif - - } - else { - /* de-select one of the sides */ - BMO_slot_buffer_hflag_disable(bm, &bmop, side ? "edgeout1" : "edgeout2", BM_ELEM_SELECT, BM_EDGE, TRUE); } EDBM_selectmode_flush(em); |