[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45796] trunk/blender/source/blender: bmesh: improve rip tool
Campbell Barton
ideasman42 at gmail.com
Thu Apr 19 23:47:33 CEST 2012
Revision: 45796
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45796
Author: campbellbarton
Date: 2012-04-19 21:47:32 +0000 (Thu, 19 Apr 2012)
Log Message:
-----------
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)
Modified Paths:
--------------
trunk/blender/source/blender/bmesh/intern/bmesh_core.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
trunk/blender/source/blender/editors/mesh/editmesh_rip.c
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2012-04-19 21:14:11 UTC (rev 45795)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2012-04-19 21:47:32 UTC (rev 45796)
@@ -814,8 +814,7 @@
do {
i += BM_ELEM_API_FLAG_TEST(e, flag) ? 1 : 0;
- e = bmesh_disk_edge_next(e, v);
- } while (e != v->e);
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
return i;
}
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-04-19 21:14:11 UTC (rev 45795)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-04-19 21:47:32 UTC (rev 45796)
@@ -309,6 +309,59 @@
}
/**
+ * The function takes a vertex at the center of a fan and returns the opposite edge in the fan.
+ * All edges in the fan must be manifold, otherwise return NULL.
+ *
+ * \note This could (probably) be done more effieiently.
+ */
+BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
+{
+ BMLoop *l_a;
+ int tot = 0;
+ int i;
+
+ BLI_assert(BM_vert_in_edge(e_first, v));
+
+ l_a = e_first->l;
+ do {
+ l_a = BM_loop_other_vert_loop(l_a, v);
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ if (BM_edge_is_manifold(l_a->e)) {
+ l_a = l_a->radial_next;
+ }
+ else {
+ return NULL;
+ }
+
+ tot++;
+ } while (l_a != e_first->l);
+
+ /* we know the total, now loop half way */
+ tot /= 2;
+ i = 0;
+
+ l_a = e_first->l;
+ do {
+ if (i == tot) {
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ return l_a->e;
+ }
+
+ l_a = BM_loop_other_vert_loop(l_a, v);
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ if (BM_edge_is_manifold(l_a->e)) {
+ l_a = l_a->radial_next;
+ }
+ /* this wont have changed from the previous loop */
+
+
+ i++;
+ } while (l_a != e_first->l);
+
+ return NULL;
+}
+
+/**
* Returms edge length
*/
float BM_edge_length_calc(BMEdge *e)
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-04-19 21:14:11 UTC (rev 45795)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-04-19 21:47:32 UTC (rev 45796)
@@ -49,6 +49,7 @@
int BM_vert_edge_count(BMVert *v);
int BM_edge_face_count(BMEdge *e);
int BM_vert_face_count(BMVert *v);
+BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e);
int BM_vert_is_wire(BMVert *v);
int BM_edge_is_wire(BMEdge *e);
Modified: trunk/blender/source/blender/editors/mesh/editmesh_rip.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_rip.c 2012-04-19 21:14:11 UTC (rev 45795)
+++ trunk/blender/source/blender/editors/mesh/editmesh_rip.c 2012-04-19 21:47:32 UTC (rev 45796)
@@ -66,7 +66,7 @@
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 @@
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 @@
/* 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 @@
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,27 +540,60 @@
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;
- if (l) {
- BM_elem_flag_enable(l->e, BM_ELEM_TAG);
+ /* 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;
+
+ 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);
+ }
+ }
}
}
}
More information about the Bf-blender-cvs
mailing list