[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45334] trunk/blender/source/blender/ editors/mesh/editmesh_tools.c: fix [#30758] bmesh: unable to rip a single vertex
Campbell Barton
ideasman42 at gmail.com
Mon Apr 2 10:35:20 CEST 2012
Revision: 45334
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45334
Author: campbellbarton
Date: 2012-04-02 08:35:12 +0000 (Mon, 02 Apr 2012)
Log Message:
-----------
fix [#30758] bmesh: unable to rip a single vertex
this also adds the ability to rip disconnected face fans apart which is handy.
Modified Paths:
--------------
trunk/blender/source/blender/editors/mesh/editmesh_tools.c
Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c 2012-04-02 07:54:12 UTC (rev 45333)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c 2012-04-02 08:35:12 UTC (rev 45334)
@@ -2132,6 +2132,8 @@
return dist_to_line_segment_v2(mvalf, vec1, vec2);
}
+
+
/* based on mouse cursor position, it defines how is being ripped */
static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
@@ -2174,6 +2176,7 @@
* then rip two adjacent edges in the vert fan. */
if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
BMEditSelection ese;
+ int totboundary_edge = 0;
singlesel = TRUE;
/* find selected vert - same some time and check history first */
@@ -2196,17 +2199,93 @@
if (v->e) {
/* find closest edge to mouse cursor */
BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN) && BM_edge_face_count(e) == 2) {
- d = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval);
- if (d < dist) {
- dist = d;
- e2 = e;
+ int is_boundary = BM_edge_is_boundary(e);
+ /* consider wire as boundary for this purpose,
+ * otherwise we can't a face away from a wire edge */
+ totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e));
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ if (is_boundary == FALSE && BM_edge_face_count(e) == 2) {
+ d = mesh_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval);
+ if (d < dist) {
+ dist = d;
+ e2 = e;
+ }
}
}
}
}
+ /* should we go ahead with edge rip or do we need to do special case, split off vertex?:
+ * split off vertex if...
+ * - we cant find an edge - this means we are ripping a faces vert that is connected to other
+ * geometry only at the vertex.
+ * - the boundary edge total is greater then 2,
+ * in this case edge split _can_ work but we get far nicer results if we use this special case. */
+ if (totboundary_edge > 2) {
+ BMVert **vout;
+ int vout_len;
+
+ BM_elem_select_set(bm, v, FALSE);
+ bmesh_vert_separate(bm, v, &vout, &vout_len);
+
+ if (vout_len < 2) {
+ /* should never happen */
+ BKE_report(op->reports, RPT_ERROR, "Error ripping vertex from faces");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ int vi_best = 0;
+
+ dist = FLT_MAX;
+
+ for (i = 0; i < vout_len; i++) {
+ BM_ITER(l, &iter, bm, BM_LOOPS_OF_VERT, vout[i]) {
+ if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
+ float l_mid_co[3];
+ BM_loop_face_tangent(l, l_mid_co);
+
+ /* scale to average of surrounding edge size, only needs to be approx */
+ mul_v3_fl(l_mid_co, (BM_edge_length_calc(l->e) + BM_edge_length_calc(l->prev->e)) / 2.0f);
+ add_v3_v3(l_mid_co, v->co);
+
+ d = mesh_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval);
+
+ if (d < dist) {
+ dist = d;
+ vi_best = i;
+ }
+ }
+ }
+ }
+
+ /* select the vert from the best region */
+ v = vout[vi_best];
+ BM_elem_select_set(bm, v, TRUE);
+
+ /* splice all others back together */
+ if (vout_len > 2) {
+
+ /* vout[0] == best
+ * vout[1] == glue
+ * vout[2+] == splice with glue
+ */
+ if (vi_best != 0) {
+ SWAP(BMVert *, vout[0], vout[vi_best]);
+ vi_best = 0;
+ }
+
+ for (i = 2; i < vout_len; i++) {
+ BM_vert_splice(bm, vout[i], vout[1]);
+ }
+ }
+
+ MEM_freeN(vout);
+
+ return OPERATOR_FINISHED;
+ }
+ }
+
if (!e2) {
BKE_report(op->reports, RPT_ERROR, "Selected vertex has no edge/face pairs attached");
return OPERATOR_CANCELLED;
More information about the Bf-blender-cvs
mailing list