[Bf-blender-cvs] [df0a1fa] master: Fix T44766: Connect fails /w selected ngon edges

Campbell Barton noreply at git.blender.org
Tue May 19 15:53:24 CEST 2015


Commit: df0a1fa3c5de560ddddc87b6694b6ee224422af8
Author: Campbell Barton
Date:   Tue May 19 23:46:31 2015 +1000
Branches: master
https://developer.blender.org/rBdf0a1fa3c5de560ddddc87b6694b6ee224422af8

Fix T44766: Connect fails /w selected ngon edges

===================================================================

M	source/blender/editors/mesh/editmesh_tools.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 54acf4a..f023aec 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1109,28 +1109,111 @@ static bool bm_vert_connect_select_history(BMesh *bm)
 	return false;
 }
 
+/**
+ * Convert an edge selection to a temp vertex selection
+ * (which must be cleared after use as a path to connect).
+ */
+static bool bm_vert_connect_select_history_edge_to_vert_path(BMesh *bm, ListBase *r_selected)
+{
+	ListBase selected_orig = {NULL, NULL};
+	BMEditSelection *ese;
+	int edges_len = 0;
+	bool side = false;
+
+	/* first check all edges are OK */
+	for (ese = bm->selected.first; ese; ese = ese->next) {
+		if (ese->htype == BM_EDGE) {
+			edges_len += 1;
+		}
+		else {
+			return false;
+		}
+	}
+	/* if this is a mixed selection, bail out! */
+	if (bm->totedgesel != edges_len) {
+		return false;
+	}
+
+	SWAP(ListBase, bm->selected, selected_orig);
+
+	/* convert edge selection into 2 ordered loops (where the first edge ends up in the middle) */
+	for (ese = selected_orig.first; ese; ese = ese->next) {
+		BMEdge *e_curr = (BMEdge *)ese->ele;
+		BMEdge *e_prev = ese->prev ? (BMEdge *)ese->prev->ele : NULL;
+		BMLoop *l_curr;
+		BMLoop *l_prev;
+		BMVert *v;
+
+		if (e_prev) {
+			BMFace *f = BM_edge_pair_share_face_by_len(e_curr, e_prev, &l_curr, &l_prev, true);
+			if (f) {
+				if ((e_curr->v1 != l_curr->v) == (e_prev->v1 != l_prev->v)) {
+					side = !side;
+				}
+			}
+			else if (is_quad_flip_v3(e_curr->v1->co, e_curr->v2->co, e_prev->v2->co, e_prev->v1->co)) {
+				side = !side;
+			}
+		}
+
+		v = (&e_curr->v1)[side];
+		if (!bm->selected.last || (BMVert *)((BMEditSelection *)bm->selected.last)->ele != v) {
+			BM_select_history_store_notest(bm, v);
+		}
+
+		v = (&e_curr->v1)[!side];
+		if (!bm->selected.first || (BMVert *)((BMEditSelection *)bm->selected.first)->ele != v) {
+			BM_select_history_store_head_notest(bm, v);
+		}
+
+		e_prev = e_curr;
+	}
+
+	*r_selected = bm->selected;
+	bm->selected = selected_orig;
+
+	return true;
+}
 
 static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	BMesh *bm = em->bm;
 	bool is_pair = (em->bm->totvertsel == 2);
+	ListBase selected_orig = {NULL, NULL};
+	int retval;
 
 	/* when there is only 2 vertices, we can ignore selection order */
 	if (is_pair) {
 		return edbm_vert_connect_exec(C, op);
 	}
 
-	if (bm_vert_connect_select_history(em->bm)) {
+	if (bm->selected.first) {
+		BMEditSelection *ese = bm->selected.first;
+		if (ese->htype == BM_EDGE) {
+			if (bm_vert_connect_select_history_edge_to_vert_path(bm, &selected_orig)) {
+				SWAP(ListBase, bm->selected, selected_orig);
+			}
+		}
+	}
+
+	if (bm_vert_connect_select_history(bm)) {
 		EDBM_selectmode_flush(em);
 		EDBM_update_generic(em, true, true);
-
-		return OPERATOR_FINISHED;
+		retval = OPERATOR_FINISHED;
 	}
 	else {
 		BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
-		return OPERATOR_CANCELLED;
+		retval = OPERATOR_CANCELLED;
 	}
+
+	if (!BLI_listbase_is_empty(&selected_orig)) {
+		BM_select_history_clear(bm);
+		bm->selected = selected_orig;
+	}
+
+	return retval;
 }
 
 void MESH_OT_vert_connect_path(wmOperatorType *ot)




More information about the Bf-blender-cvs mailing list