Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-04-20 01:47:32 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-04-20 01:47:32 +0400
commit741a177a74057b9baaae17640205017ca393ed89 (patch)
tree33cf96b86350248bcbd54df29d57f64510f12c52 /source/blender/editors/mesh/editmesh_rip.c
parentebbfcd71e5ea35a64759ecbf9bc0f34d582a6bde (diff)
bmesh: improve rip tool
- When the rip extends into a fan, pick the opposite edge in the fan (rather then 2 along) - When stepping over the fan to find the rip edge, walk in the direction closest to the mouse (generally works nicer)
Diffstat (limited to 'source/blender/editors/mesh/editmesh_rip.c')
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 34666c2cb7a..3d310e5ea90 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -66,7 +66,7 @@ static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], float *co1, floa
return dist_to_line_segment_v2(mvalf, vec1, vec2);
}
-static float edbm_rip_edge_side_measure(BMEdge *e,
+static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l,
ARegion *ar,
float projectMat[4][4], const float fmval[2])
{
@@ -80,6 +80,8 @@ static float edbm_rip_edge_side_measure(BMEdge *e,
BMVert *v1_other;
BMVert *v2_other;
+ BLI_assert(BM_vert_in_edge(e, e_l->v));
+
/* method for calculating distance:
*
* for each edge: calculate face center, then made a vector
@@ -88,8 +90,8 @@ static float edbm_rip_edge_side_measure(BMEdge *e,
/* 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;
+ 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);
@@ -323,12 +325,12 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs,
e = lp->l_a->e;
v_prev = edbm_ripsel_edloop_pair_start_vert(e);
for (; e; e = edbm_ripsel_edge_uid_step(e, &v_prev)) {
- score_a += edbm_rip_edge_side_measure(e, ar, projectMat, fmval);
+ score_a += edbm_rip_edge_side_measure(e, e->l, ar, projectMat, fmval);
}
e = lp->l_b->e;
v_prev = edbm_ripsel_edloop_pair_start_vert(e);
for (; e; e = edbm_ripsel_edge_uid_step(e, &v_prev)) {
- score_b += edbm_rip_edge_side_measure(e, ar, projectMat, fmval);
+ score_b += edbm_rip_edge_side_measure(e, e->l, ar, projectMat, fmval);
}
e = (score_a > score_b) ? lp->l_a->e : lp->l_b->e;
@@ -538,26 +540,59 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
dist = FLT_MAX;
}
else {
+ int totedge;
+ int all_minifold;
/* expand edge selection */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
e2 = NULL;
i = 0;
+ totedge = 0;
+ all_minifold = TRUE;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- /* important to check selection rather then tag here
- * else we get feedback loop */
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- e2 = e;
- i++;
+
+ if (!BM_edge_is_wire(e) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+ {
+ /* important to check selection rather then tag here
+ * else we get feedback loop */
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ e2 = e;
+ i++;
+ }
+ totedge++;
+ }
+
+ /** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */
+ if ((all_minifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) {
+ all_minifold = FALSE;
}
}
+ /* single edge, extend */
if (i == 1 && e2->l) {
- l = BM_face_other_edge_loop(e2->l->f, e2, v);
- l = l->radial_next;
- l = BM_face_other_edge_loop(l->f, l->e, v);
+ if ((totedge == 4) || (all_minifold == FALSE)) {
+ BMLoop *l_a = e2->l;
+ BMLoop *l_b = l_a->radial_next;
+
+ /* find the best face to follow, this wat the edge won't point away from
+ * the mouse when there are more then 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;
- if (l) {
- BM_elem_flag_enable(l->e, BM_ELEM_TAG);
+ l = BM_face_other_edge_loop(l->f, e2, v);
+ l = l->radial_next;
+ l = BM_face_other_edge_loop(l->f, l->e, v);
+
+ if (l) {
+ BM_elem_flag_enable(l->e, BM_ELEM_TAG);
+ }
+ }
+ else {
+ e = BM_vert_other_disk_edge(v, e2);
+
+ if (e) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
}
}
}