[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56690] trunk/blender/source/blender: add support for bridging multiple edge loops at once.

Campbell Barton ideasman42 at gmail.com
Sat May 11 18:20:29 CEST 2013


Revision: 56690
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56690
Author:   campbellbarton
Date:     2013-05-11 16:20:29 +0000 (Sat, 11 May 2013)
Log Message:
-----------
add support for bridging multiple edge loops at once.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.c
    trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.h
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/operators/bmo_bridge.c
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.c	2013-05-11 16:15:09 UTC (rev 56689)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.c	2013-05-11 16:20:29 UTC (rev 56690)
@@ -188,6 +188,55 @@
 	}
 }
 
+void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops)
+{
+	ListBase eloops_ordered = {NULL};
+	BMEdgeLoopStore *el_store;
+	float cent[3];
+	int tot = 0;
+	zero_v3(cent);
+	/* assumes we calculated centers already */
+	for (el_store = eloops->first; el_store; el_store = el_store->next, tot++) {
+		add_v3_v3(cent, el_store->co);
+	}
+	mul_v3_fl(cent, 1.0f / (float)tot);
+
+	/* find far outest loop */
+	{
+		BMEdgeLoopStore *el_store_best = NULL;
+		float len_best = -1.0f;
+		for (el_store = eloops->first; el_store; el_store = el_store->next) {
+			const float len = len_squared_v3v3(cent, el_store->co);
+			if (len > len_best) {
+				len_best = len;
+				el_store_best = el_store;
+			}
+		}
+
+		BLI_remlink(eloops, el_store_best);
+		BLI_addtail(&eloops_ordered, el_store_best);
+	}
+
+	/* not so efficient re-ordering */
+	while (eloops->first) {
+		BMEdgeLoopStore *el_store_best = NULL;
+		const float *co = ((BMEdgeLoopStore *)eloops_ordered.last)->co;
+		float len_best = FLT_MAX;
+		for (el_store = eloops->first; el_store; el_store = el_store->next) {
+			const float len = len_squared_v3v3(co, el_store->co);
+			if (len < len_best) {
+				len_best = len;
+				el_store_best = el_store;
+			}
+		}
+
+		BLI_remlink(eloops, el_store_best);
+		BLI_addtail(&eloops_ordered, el_store_best);
+	}
+
+	*eloops = eloops_ordered;
+}
+
 /* -------------------------------------------------------------------- */
 /* BM_edgeloop_*** functions */
 

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.h	2013-05-11 16:15:09 UTC (rev 56689)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_edgeloop.h	2013-05-11 16:20:29 UTC (rev 56690)
@@ -38,6 +38,7 @@
 void                BM_mesh_edgeloops_free(struct ListBase *eloops);
 void                BM_mesh_edgeloops_calc_center(BMesh *bm, struct ListBase *eloops);
 void                BM_mesh_edgeloops_calc_normal(BMesh *bm, struct ListBase *eloops);
+void                BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops);
 
 
 /* single edgeloop */

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-05-11 16:15:09 UTC (rev 56689)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-05-11 16:20:29 UTC (rev 56690)
@@ -515,8 +515,9 @@
 	"bridge_loops",
 	/* slots_in */
 	{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
-	 {"use_merge",        BMO_OP_SLOT_BOOL},
-	 {"merge_factor",         BMO_OP_SLOT_FLT},
+	 {"use_cyclic",         BMO_OP_SLOT_BOOL},
+	 {"use_merge",          BMO_OP_SLOT_BOOL},
+	 {"merge_factor",       BMO_OP_SLOT_FLT},
 	 {{'\0'}},
 	},
 	/* slots_out */

Modified: trunk/blender/source/blender/bmesh/operators/bmo_bridge.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_bridge.c	2013-05-11 16:15:09 UTC (rev 56689)
+++ trunk/blender/source/blender/bmesh/operators/bmo_bridge.c	2013-05-11 16:20:29 UTC (rev 56690)
@@ -289,10 +289,13 @@
 void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
 {
 	ListBase eloops = {NULL};
+	LinkData *el_store;
+	int eloop_len;
 
 	/* merge-bridge support */
 	const bool  use_merge    = BMO_slot_bool_get(op->slots_in,  "use_merge");
 	const float merge_factor = BMO_slot_float_get(op->slots_in, "merge_factor");
+	const bool  use_cyclic   = BMO_slot_bool_get(op->slots_in,  "use_cyclic") && (use_merge == false);
 	int count;
 	bool change = false;
 
@@ -303,20 +306,64 @@
 	BM_mesh_edgeloops_calc_normal(bm, &eloops);
 	BM_mesh_edgeloops_calc_center(bm, &eloops);
 
-	if ((count == 2) && (BM_edgeloop_length_get(eloops.first) == BM_edgeloop_length_get(eloops.last))) {
-		bridge_loop_pair(bm, eloops.first, eloops.last, use_merge, merge_factor);
+	if (count < 2) {
+		BMO_error_raise(bm, op, BMERR_INVALID_SELECTION,
+		                "Select at least two edge loops");
+		goto cleanup;
+
+	}
+	else {
+		bool match = true;
+		eloop_len = BM_edgeloop_length_get(eloops.first);
+		for (el_store = eloops.first; el_store; el_store = el_store->next) {
+			if (eloop_len != BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store)) {
+				match = false;
+				break;
+			}
+		}
+		if (!match) {
+			BMO_error_raise(bm, op, BMERR_INVALID_SELECTION,
+			                "Selected loops must have equal edge counts");
+			goto cleanup;
+		}
+	}
+
+	if (count > 2) {
+		BM_mesh_edgeloops_calc_order(bm, &eloops);
+	}
+
+	for (el_store = eloops.first; el_store; el_store = el_store->next) {
+		LinkData *el_store_next = el_store->next;
+
+		if (el_store_next == NULL) {
+			if (use_cyclic && (count > 2)) {
+				el_store_next = eloops.first;
+			}
+			else {
+				break;
+			}
+		}
+
+		bridge_loop_pair(bm,
+		                 (struct BMEdgeLoopStore *)el_store,
+		                 (struct BMEdgeLoopStore *)el_store_next,
+		                 use_merge, merge_factor);
 		change = true;
+	}
 
+	if ((count == 2) && (BM_edgeloop_length_get(eloops.first) == BM_edgeloop_length_get(eloops.last))) {
+
+
+
 	}
 	else if (count == 2) {
-		BMO_error_raise(bm, op, BMERR_INVALID_SELECTION,
-		                "Selected loops must have equal edge counts");
+
 	}
 	else {
-		BMO_error_raise(bm, op, BMERR_INVALID_SELECTION,
-		                "Select only two edge loops");
+
 	}
 
+cleanup:
 	BM_mesh_edgeloops_free(&eloops);
 
 	if (change) {

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2013-05-11 16:15:09 UTC (rev 56689)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2013-05-11 16:20:29 UTC (rev 56690)
@@ -3672,12 +3672,13 @@
 	BMOperator bmop;
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	const bool use_cyclic = RNA_boolean_get(op->ptr, "use_cyclic");
 	const bool use_merge = RNA_boolean_get(op->ptr, "use_merge");
 	const float merge_factor = RNA_float_get(op->ptr, "merge_factor");
 	
 	EDBM_op_init(em, &bmop, op,
-	             "bridge_loops edges=%he use_merge=%b merge_factor=%f",
-	             BM_ELEM_SELECT, use_merge, merge_factor);
+	             "bridge_loops edges=%he use_cyclic=%b use_merge=%b merge_factor=%f",
+	             BM_ELEM_SELECT, use_cyclic, use_merge, merge_factor);
 
 	BMO_op_exec(em->bm, &bmop);
 
@@ -3711,7 +3712,7 @@
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 	
-	RNA_def_boolean(ot->srna, "inside", 0, "Inside", "");
+	RNA_def_boolean(ot->srna, "use_cyclic", 0, "Cyclic", "Close the bridge loop when using 3 or more");
 
 	RNA_def_boolean(ot->srna, "use_merge", false, "Merge", "Merge rather than creating faces");
 	RNA_def_float(ot->srna, "merge_factor", 0.5f, 0.0f, 1.0f, "Merge Factor", "", 0.0f, 1.0f);




More information about the Bf-blender-cvs mailing list