diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2015-05-06 16:31:57 +0300 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2015-05-06 16:31:57 +0300 |
commit | f26b373cb922e79bce34eed7bdb7a8ee29a3dab4 (patch) | |
tree | e1b2aad3353a3a7bced978eb74f78eb13a8cee3a /source/blender/editors/mesh | |
parent | ebcb8223bd886fd327cddae1394436e10f1f7a73 (diff) | |
parent | 5ffd10a6da956210062f5cd18c61de348f379849 (diff) |
Merge branch 'master' into gooseberry
Conflicts:
source/blender/editors/object/object_shapekey.c
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r-- | source/blender/editors/mesh/editmesh_rip.c | 164 |
1 files changed, 82 insertions, 82 deletions
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index abd88ae65aa..2a0bdfc45f0 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -63,9 +63,10 @@ * point and would result in the same distance. */ #define INSET_DEFAULT 0.00001f -static float edbm_rip_edgedist_squared(ARegion *ar, float mat[4][4], - const float co1[3], const float co2[3], const float mvalf[2], - const float inset) +static float edbm_rip_edgedist_squared( + ARegion *ar, float mat[4][4], + const float co1[3], const float co2[3], const float mvalf[2], + const float inset) { float vec1[2], vec2[2], dist_sq; @@ -89,8 +90,9 @@ static float edbm_rip_edgedist_squared(ARegion *ar, float mat[4][4], } #if 0 -static float edbm_rip_linedist(ARegion *ar, float mat[4][4], - const float co1[3], const float co2[3], const float mvalf[2]) +static float edbm_rip_linedist( + ARegion *ar, float mat[4][4], + const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[2], vec2[2]; @@ -114,9 +116,10 @@ static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3]) } -static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l, - ARegion *ar, - float projectMat[4][4], const float fmval[2]) +static float edbm_rip_edge_side_measure( + BMEdge *e, BMLoop *e_l, + ARegion *ar, + float projectMat[4][4], const float fmval[2]) { float cent[3] = {0, 0, 0}, mid[3]; @@ -532,14 +535,14 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve BMesh *bm = em->bm; BMIter iter, liter; BMLoop *l; - BMEdge *e, *e2; + BMEdge *e_best; BMVert *v; const int totvert_orig = bm->totvert; int i; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; float dist_sq = FLT_MAX; float d; - bool is_wire; + bool is_wire, is_manifold_region; BMEditSelection ese; int totboundary_edge = 0; @@ -565,86 +568,81 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve } is_wire = BM_vert_is_wire(v); + is_manifold_region = BM_vert_is_manifold_region(v); - e2 = NULL; + e_best = NULL; - if (v->e) { + { + BMEdge *e; /* find closest edge to mouse cursor */ BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { /* consider wire as boundary for this purpose, * otherwise we can't a face away from a wire edge */ totboundary_edge += (BM_edge_is_boundary(e) || BM_edge_is_wire(e)); if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { - if (BM_edge_is_manifold(e)) { + if ((is_manifold_region == false) || BM_edge_is_manifold(e)) { d = edbm_rip_edgedist_squared(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); - if ((e2 == NULL) || (d < dist_sq)) { + if ((e_best == NULL) || (d < dist_sq)) { dist_sq = d; - e2 = e; - } - } - } - } - - /* if we are ripping a single vertex from 3 faces, - * then measure the distance to the face corner as well as the edge */ - if (BM_vert_face_count_is_equal(v, 3) && - BM_vert_edge_count_is_equal(v, 3)) - { - BMEdge *e_all[3]; - BMLoop *l_all[3]; - int i1, i2; - - BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3); - BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3); - - /* not do a loop similar to the one above, but test against loops */ - for (i1 = 0; i1 < 3; i1++) { - /* consider wire as boundary for this purpose, - * otherwise we can't a face away from a wire edge */ - float l_mid_co[3]; - l = l_all[i1]; - edbm_calc_loop_co(l, l_mid_co); - d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); - if ((e2 == NULL) || (d < dist_sq)) { - dist_sq = d; - - /* find the edge that is not in this loop */ - e2 = NULL; - for (i2 = 0; i2 < 3; i2++) { - if (!BM_edge_in_loop(e_all[i2], l)) { - e2 = e_all[i2]; - break; - } + e_best = e; } - BLI_assert(e2 != NULL); } } } } - if (e2) { + if (e_best && (is_manifold_region == false)) { /* Try to split off a non-manifold fan (when we have multiple disconnected fans) */ - - /* note: we're lazy here and first split then check there are any faces remaining, - * this isn't good practice, however its less hassle then checking for multiple-disconnected regions */ - BMLoop *l_sep = e2->l->v == v ? e2->l : e2->l->next; + BMLoop *l_sep = e_best->l->v == v ? e_best->l : e_best->l->next; BMVert *v_new; + BLI_assert(l_sep->v == v); v_new = bmesh_urmv_loop_region(bm, l_sep); - if (BM_vert_find_first_loop(v)) { - BM_vert_select_set(bm, v, false); - BM_select_history_remove(bm, v); + BLI_assert(BM_vert_find_first_loop(v)); - BM_vert_select_set(bm, v_new, true); - if (ese.ele) { - BM_select_history_store(bm, v_new); - } + BM_vert_select_set(bm, v, false); + BM_select_history_remove(bm, v); - return OPERATOR_FINISHED; + BM_vert_select_set(bm, v_new, true); + if (ese.ele) { + BM_select_history_store(bm, v_new); } - else { - /* rewind */ - BM_vert_splice(bm, v, v_new); + return OPERATOR_FINISHED; + } + + /* if we are ripping a single vertex from 3 faces, + * then measure the distance to the face corner as well as the edge */ + if (BM_vert_face_count_is_equal(v, 3) && + BM_vert_edge_count_is_equal(v, 3)) + { + BMEdge *e_all[3]; + BMLoop *l_all[3]; + int i1, i2; + + BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3); + + /* not do a loop similar to the one above, but test against loops */ + for (i1 = 0; i1 < 3; i1++) { + /* consider wire as boundary for this purpose, + * otherwise we can't a face away from a wire edge */ + float l_mid_co[3]; + l = l_all[i1]; + edbm_calc_loop_co(l, l_mid_co); + d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); + if ((e_best == NULL) || (d < dist_sq)) { + dist_sq = d; + + /* find the edge that is not in this loop */ + e_best = NULL; + for (i2 = 0; i2 < 3; i2++) { + if (!BM_edge_in_loop(e_all[i2], l)) { + e_best = e_all[i2]; + break; + } + } + BLI_assert(e_best != NULL); + } } } @@ -703,6 +701,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve } } else { + BMEdge *e; /* a wire vert, find the best edge */ BM_ITER_ELEM (e, &iter, vout[i], BM_EDGES_OF_VERT) { if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { @@ -751,7 +750,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve } } - if (!e2) { + if (!e_best) { BKE_report(op->reports, RPT_ERROR, "Selected vertex has no edge/face pairs attached"); return OPERATOR_CANCELLED; } @@ -766,16 +765,16 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve int larr_len = 0; /* rip two adjacent edges */ - if (BM_edge_is_boundary(e2) || BM_vert_face_count_is_equal(v, 2)) { + if (BM_edge_is_boundary(e_best) || BM_vert_face_count_is_equal(v, 2)) { /* Don't run the edge split operator in this case */ - l = BM_edge_vert_share_loop(e2->l, v); + l = BM_edge_vert_share_loop(e_best->l, v); larr[larr_len] = l; larr_len++; /* only tag for face-fill (we don't call the operator) */ - if (BM_edge_is_boundary(e2)) { - BM_elem_flag_enable(e2, BM_ELEM_TAG); + if (BM_edge_is_boundary(e_best)) { + BM_elem_flag_enable(e_best, BM_ELEM_TAG); } else { BM_elem_flag_enable(l->e, BM_ELEM_TAG); @@ -783,10 +782,10 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve } } else { - if (BM_edge_is_manifold(e2)) { + if (BM_edge_is_manifold(e_best)) { BMLoop *l_iter, *l_first; - l_iter = l_first = e2->l; + l_iter = l_first = e_best->l; do { larr[larr_len] = BM_edge_vert_share_loop(l_iter, v); BM_elem_flag_enable(larr[larr_len]->e, BM_ELEM_TAG); @@ -880,7 +879,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve BMesh *bm = em->bm; BMIter iter, eiter; BMLoop *l; - BMEdge *e, *e2; + BMEdge *e_best; BMVert *v; const int totedge_orig = bm->totedge; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; @@ -894,11 +893,12 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve /* expand edge selection */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BMEdge *e; bool all_manifold; int totedge_manifold; /* manifold, visible edges */ int i; - e2 = NULL; + e_best = NULL; i = 0; totedge_manifold = 0; all_manifold = true; @@ -910,7 +910,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve /* important to check selection rather then tag here * else we get feedback loop */ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - e2 = e; + e_best = e; i++; } totedge_manifold++; @@ -923,18 +923,18 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve } /* single edge, extend */ - if (i == 1 && e2->l) { + if (i == 1 && e_best->l) { /* note: if the case of 3 edges has one change in loop stepping, * if this becomes more involved we may be better off splitting * the 3 edge case into its own else-if branch */ if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == false)) { - BMLoop *l_a = e2->l; + BMLoop *l_a = e_best->l; BMLoop *l_b = l_a->radial_next; /* find the best face to follow, this way the edge won't point away from * the mouse when there are more than 4 (takes the shortest face fan around) */ - l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) < - edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b; + l = (edbm_rip_edge_side_measure(e_best, l_a, ar, projectMat, fmval) < + edbm_rip_edge_side_measure(e_best, l_b, ar, projectMat, fmval)) ? l_a : l_b; l = BM_loop_other_edge_loop(l, v); /* important edge is manifold else we can be attempting to split off a fan that don't budge, @@ -952,7 +952,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve } } else { - e = BM_vert_other_disk_edge(v, e2); + e = BM_vert_other_disk_edge(v, e_best); if (e) { BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG)); |