From fbf890200cfa93278259ddc87c7ae3636e85cc57 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 16 May 2013 15:28:57 +0000 Subject: [PATCH] fix for crash in grid-fill where it was possible for rail edges to overlap. --- source/blender/bmesh/intern/bmesh_edgeloop.c | 21 +++++++++++++++++++ source/blender/bmesh/intern/bmesh_edgeloop.h | 2 ++ .../blender/bmesh/operators/bmo_grid_fill.c | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index 1ab7652502c..7c5b20381ab 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -601,3 +601,24 @@ void BM_edgeloop_expand(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, int el_sto BLI_assert(el_store->len == el_store_len); } + +bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b) +{ + LinkData *node; + + /* init */ + for (node = el_store_a->verts.first; node; node = node->next) { + BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); + } + for (node = el_store_b->verts.first; node; node = node->next) { + BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG); + } + + /* check 'a' */ + for (node = el_store_a->verts.first; node; node = node->next) { + if (BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) { + return true; + } + } + return false; +} diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h index 50f85a3155b..aa57fcfc47d 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.h +++ b/source/blender/bmesh/intern/bmesh_edgeloop.h @@ -57,6 +57,8 @@ void BM_edgeloop_calc_normal(BMesh *bm, struct BMEdgeLoopStore *e void BM_edgeloop_flip(BMesh *bm, struct BMEdgeLoopStore *el_store); void BM_edgeloop_expand(BMesh *bm, struct BMEdgeLoopStore *el_store, int el_store_len); +bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b); + #define BM_EDGELOOP_NEXT(el_store, elink) \ (elink)->next ? elink->next : (BM_edgeloop_is_closed(el_store) ? BM_edgeloop_verts_get(el_store)->first : NULL) diff --git a/source/blender/bmesh/operators/bmo_grid_fill.c b/source/blender/bmesh/operators/bmo_grid_fill.c index 05116c93a13..21325cf05b2 100644 --- a/source/blender/bmesh/operators/bmo_grid_fill.c +++ b/source/blender/bmesh/operators/bmo_grid_fill.c @@ -423,6 +423,12 @@ void bmo_grid_fill_exec(BMesh *bm, BMOperator *op) goto cleanup; } + if (BM_edgeloop_overlap_check(estore_rail_a, estore_rail_b)) { + BMO_error_raise(bm, op, BMERR_INVALID_SELECTION, + "Connecting edge loops overlap"); + goto cleanup; + } + /* finally we have all edge loops needed */ bm_grid_fill(bm, estore_a, estore_b, estore_rail_a, estore_rail_b, mat_nr, use_smooth);