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>2016-06-21 00:54:46 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-06-21 01:10:56 +0300
commita170607578b8911df30039dacf7399506476be87 (patch)
tree7a26dc33b455587d2d01c71fe005a112baa4e093 /source/blender/bmesh/intern/bmesh_polygon_edgenet.c
parented225d4517c151e8ad0aa30a61daf46f9982f298 (diff)
Fix T48683: Knife cut creates hole
BM_face_split_edgenet wasn't correctly detecting boundary vertices to walk over, since vertices may be attached to boundary edges not part of the newly created face.
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_polygon_edgenet.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c62
1 files changed, 57 insertions, 5 deletions
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 009df44b1da..c142dcae514 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -97,6 +97,10 @@ static BMLoop *bm_edge_flagged_radial_first(BMEdge *e)
return NULL;
}
+/**
+ * \note Be sure to update #bm_face_split_edgenet_find_loop_pair_exists
+ * when making changed to edge picking logic.
+ */
static bool bm_face_split_edgenet_find_loop_pair(
BMVert *v_init, const float face_normal[3],
BMEdge *e_pair[2])
@@ -189,6 +193,58 @@ static bool bm_face_split_edgenet_find_loop_pair(
return true;
}
+/**
+ * A reduced version of #bm_face_split_edgenet_find_loop_pair
+ * that only checks if it would return true.
+ *
+ * \note There is no use in caching resulting edges here,
+ * since between this check and running #bm_face_split_edgenet_find_loop,
+ * the selected edges may have had faces attached.
+ */
+static bool bm_face_split_edgenet_find_loop_pair_exists(
+ BMVert *v_init)
+{
+ int edges_boundary_len = 0;
+ int edges_wire_len = 0;
+
+ {
+ BMEdge *e, *e_first;
+ e = e_first = v_init->e;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
+ const unsigned int count = bm_edge_flagged_radial_count(e);
+ if (count == 1) {
+ edges_boundary_len++;
+ }
+ else if (count == 0) {
+ edges_wire_len++;
+ }
+ }
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_init)) != e_first);
+ }
+
+ /* first edge should always be boundary */
+ if (edges_boundary_len == 0) {
+ return false;
+ }
+
+ /* attempt one boundary and one wire, or 2 boundary */
+ if (edges_wire_len == 0) {
+ if (edges_boundary_len >= 2) {
+ /* pass */
+ }
+ else {
+ /* one boundary and no wire */
+ return false;
+ }
+ }
+ else {
+ /* pass */
+ }
+
+ return true;
+}
+
static bool bm_face_split_edgenet_find_loop_walk(
BMVert *v_init, const float face_normal[3],
/* cache to avoid realloc every time */
@@ -450,7 +506,6 @@ bool BM_face_split_edgenet(
}
if (f_new) {
- bool l_prev_is_boundary;
BLI_array_append(face_arr, f_new);
copy_v3_v3(f_new->no, f->no);
@@ -466,13 +521,10 @@ bool BM_face_split_edgenet(
/* add new verts to keep finding loops for
* (verts between boundary and manifold edges) */
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- l_prev_is_boundary = (bm_edge_flagged_radial_count(l_iter->prev->e) == 1);
do {
- bool l_iter_is_boundary = (bm_edge_flagged_radial_count(l_iter->e) == 1);
- if (l_prev_is_boundary != l_iter_is_boundary) {
+ if (bm_face_split_edgenet_find_loop_pair_exists(l_iter->v)) {
STACK_PUSH(vert_queue, l_iter->v);
}
- l_prev_is_boundary = l_iter_is_boundary;
} while ((l_iter = l_iter->next) != l_first);
}
}