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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-05-11 20:20:29 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-05-11 20:20:29 +0400
commitdc1a36534d2832e9b30f369acd0dabcad93c632f (patch)
tree75270ee9dd4e00eda8b8a56a013869b8ec08b5b2 /source
parent01063faf6fa8513e0afff7392dc9f111de9e5ff1 (diff)
add support for bridging multiple edge loops at once.
Diffstat (limited to 'source')
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c49
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c5
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c59
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c7
5 files changed, 110 insertions, 11 deletions
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index ce2a80c6cfc..1c302668409 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -188,6 +188,55 @@ void BM_mesh_edgeloops_calc_normal(BMesh *bm, ListBase *eloops)
}
}
+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 */
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h
index 06a457c3dd6..e6ea65fa85d 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.h
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.h
@@ -38,6 +38,7 @@ int BM_mesh_edgeloops_find(BMesh *bm, struct ListBase *r_lb,
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 */
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 77e45648813..f145d6939d9 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -515,8 +515,9 @@ static BMOpDefine bmo_bridge_loops_def = {
"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 */
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index a9201fb8de5..5642cc5e8c1 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -289,10 +289,13 @@ static void bridge_loop_pair(BMesh *bm,
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 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
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) {
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 4b325d2212f..84b93384abe 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3672,12 +3672,13 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op)
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 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot)
/* 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);