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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-05-13 18:31:45 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-05-13 18:31:45 +0400
commitb48deabf4e3dd815d70ffd01942aeaa8dff64d53 (patch)
treea0d97b801263c2bf8058ad22084353f45d898ceb /source/blender/bmesh
parent0e2487742ec333bf110738e95ad7d110942fc40a (diff)
new bevel: fix for crash in merge, could result in collapsing faces being invalid. rather then splice each edge, use weld_verts operator which handles removing degenerate geometry.
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c70
1 files changed, 24 insertions, 46 deletions
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index 30a0f0a3dba..37929b4720f 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -39,6 +39,29 @@
#define EDGE_MARK 4
#define FACE_OUT 16
+/* el_a and el_b _must_ be same size */
+static void bm_bridge_splice_loops(BMesh *bm, LinkData *el_a, LinkData *el_b, const float merge_factor)
+{
+ BMOperator op_weld;
+ BMOpSlot *slot_targetmap;
+
+ BMO_op_init(bm, &op_weld, 0, "weld_verts");
+
+ slot_targetmap = BMO_slot_get(op_weld.slots_in, "targetmap");
+
+ do {
+ BMVert *v_a = el_a->data, *v_b = el_b->data;
+ BM_data_interp_from_verts(bm, v_a, v_b, v_b, merge_factor);
+ interp_v3_v3v3(v_b->co, v_a->co, v_b->co, merge_factor);
+ BLI_assert(v_a != v_b);
+ BMO_slot_map_elem_insert(&op_weld, slot_targetmap, v_a, v_b);
+ } while ((el_b = el_b->next),
+ (el_a = el_a->next));
+
+ BMO_op_exec(bm, &op_weld);
+ BMO_op_finish(bm, &op_weld);
+}
+
/* get the 2 loops matching 2 verts.
* first attempt to get the face corners that use the edge defined by v1 & v2,
* if that fails just get any loop thats on the vert (the first one) */
@@ -198,52 +221,7 @@ static void bridge_loop_pair(BMesh *bm,
if (use_merge) {
- LinkData *el_a;
- LinkData *el_b;
- const int vert_len = BM_edgeloop_length_get(el_store_a);
- const int edge_len = is_closed ? vert_len : vert_len - 1;
- BMEdge **earr_a = MEM_mallocN(sizeof(*earr_a) * vert_len, __func__);
- BMEdge **earr_b = MEM_mallocN(sizeof(*earr_b) * vert_len, __func__);
- int i;
-
- el_a = el_a_first;
- el_b = el_b_first;
-
- /* first get the edges in order (before splicing verts) */
- for (i = 0; i < vert_len; i++) {
- LinkData *el_a_next = BM_EDGELOOP_NEXT(el_store_a, el_a);
- LinkData *el_b_next = BM_EDGELOOP_NEXT(el_store_b, el_b);
-
- /* last edge will be NULL for non closed loops */
- earr_a[i] = BM_edge_exists(el_a->data, el_a_next->data);
- earr_b[i] = BM_edge_exists(el_b->data, el_b_next->data);
-
- el_a = el_a_next;
- el_b = el_b_next;
- }
-
- el_a = el_a_first;
- el_b = el_b_first;
- for (i = 0; i < vert_len; i++) {
- BMVert *v_a = el_a->data, *v_b = el_b->data;
- BM_data_interp_from_verts(bm, v_a, v_b, v_b, merge_factor);
- interp_v3_v3v3(v_b->co, v_a->co, v_b->co, merge_factor);
- BM_elem_flag_merge(v_a, v_b);
- BM_vert_splice(bm, v_a, v_b);
-
- el_a = el_a->next;
- el_b = el_b->next;
- }
- for (i = 0; i < edge_len; i++) {
- BMEdge *e1 = earr_a[i];
- BMEdge *e2 = earr_b[i];
- BM_data_interp_from_edges(bm, e1, e2, e2, merge_factor);
- BM_elem_flag_merge(e1, e2);
- BM_edge_splice(bm, e1, e2);
- }
-
- MEM_freeN(earr_a);
- MEM_freeN(earr_b);
+ bm_bridge_splice_loops(bm, el_a_first, el_b_first, merge_factor);
}
else {
LinkData *el_a = el_a_first;