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:
Diffstat (limited to 'source/blender/bmesh/tools/bmesh_intersect.c')
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 4ca8364c312..c73b80d57f7 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -509,7 +509,7 @@ static bool bm_loop_filter_fn(const BMLoop *l, void *user_data)
* Return true if we have any intersections.
*/
static void bm_isect_tri_tri(
- struct ISectState *s, int a_index, int b_index, BMLoop **a, BMLoop **b)
+ struct ISectState *s, int a_index, int b_index, BMLoop **a, BMLoop **b, bool no_shared)
{
BMFace *f_a = (*a)->f;
BMFace *f_b = (*b)->f;
@@ -527,9 +527,16 @@ static void bm_isect_tri_tri(
STACK_DECLARE(iv_ls_a);
STACK_DECLARE(iv_ls_b);
- if (UNLIKELY(ELEM(fv_a[0], UNPACK3(fv_b)) || ELEM(fv_a[1], UNPACK3(fv_b)) ||
- ELEM(fv_a[2], UNPACK3(fv_b)))) {
- return;
+ if (no_shared) {
+ if (UNLIKELY(ELEM(fv_a[0], UNPACK3(fv_b)) || ELEM(fv_a[1], UNPACK3(fv_b)) ||
+ ELEM(fv_a[2], UNPACK3(fv_b)))) {
+ return;
+ }
+ }
+ else {
+ if (UNLIKELY(BM_face_share_edge_check(f_a, f_b))) {
+ return;
+ }
}
STACK_INIT(iv_ls_a, ARRAY_SIZE(iv_ls_a));
@@ -564,11 +571,11 @@ static void bm_isect_tri_tri(
for (i_b = 0; i_b < 3; i_b++) {
if (len_squared_v3v3(fv_a[i_a]->co, fv_b[i_b]->co) <= s->epsilon.eps2x_sq) {
#ifdef USE_DUMP
- if (BM_ELEM_API_FLAG_TEST(fv_a[i_a], VERT_VISIT) == 0) {
- printf(" ('VERT-VERT-A') %d, %d),\n", i_a, BM_elem_index_get(fv_a[i_a]));
+ if (BM_ELEM_API_FLAG_TEST(fv_a[i_a], VERT_VISIT_A) == 0) {
+ printf(" ('VERT-VERT-A') %u, %d),\n", i_a, BM_elem_index_get(fv_a[i_a]));
}
- if (BM_ELEM_API_FLAG_TEST(fv_b[i_b], VERT_VISIT) == 0) {
- printf(" ('VERT-VERT-B') %d, %d),\n", i_b, BM_elem_index_get(fv_b[i_b]));
+ if (BM_ELEM_API_FLAG_TEST(fv_b[i_b], VERT_VISIT_B) == 0) {
+ printf(" ('VERT-VERT-B') %u, %d),\n", i_b, BM_elem_index_get(fv_b[i_b]));
}
#endif
STACK_PUSH_TEST_A(fv_a[i_a]);
@@ -905,7 +912,7 @@ static int isect_bvhtree_point_v3(BVHTree *tree, const float **looptris, const f
BLI_bvhtree_ray_cast(tree, co, dir, 0.0f, &hit, raycast_callback, &raycast_data);
# ifdef USE_DUMP
- printf("%s: Total intersections: %d\n", __func__, z_buffer.count);
+ printf("%s: Total intersections: %zu\n", __func__, z_buffer.count);
# endif
int num_isect;
@@ -1082,6 +1089,12 @@ bool BM_mesh_intersect(BMesh *bm,
tree_b = tree_a;
}
+ /* For self intersection this can be useful, sometimes users generate geometry
+ * where surfaces that seem disconnected happen to share an edge.
+ * So when performing intersection calculation allow shared vertices,
+ * just not shared edges. See T75946. */
+ const bool isect_tri_tri_no_shared = (boolean_mode != BMESH_ISECT_BOOLEAN_NONE);
+
int flag = BVH_OVERLAP_USE_THREADING | BVH_OVERLAP_RETURN_PAIRS;
# ifdef DEBUG
/* The overlap result must match that obtained in Release to succeed
@@ -1103,7 +1116,8 @@ bool BM_mesh_intersect(BMesh *bm,
overlap[i].indexA,
overlap[i].indexB,
looptris[overlap[i].indexA],
- looptris[overlap[i].indexB]);
+ looptris[overlap[i].indexB],
+ isect_tri_tri_no_shared);
# ifdef USE_DUMP
printf(")),\n");
# endif
@@ -1140,7 +1154,7 @@ bool BM_mesh_intersect(BMesh *bm,
# ifdef USE_DUMP
printf(" ((%d, %d), (", i_a, i_b);
# endif
- bm_isect_tri_tri(&s, i_a, i_b, looptris[i_a], looptris[i_b]);
+ bm_isect_tri_tri(&s, i_a, i_b, looptris[i_a], looptris[i_b], isect_tri_tri_no_shared);
# ifdef USE_DUMP
printf(")),\n");
# endif
@@ -1179,7 +1193,7 @@ bool BM_mesh_intersect(BMesh *bm,
}
# ifdef USE_DUMP
- printf("# SPLITTING EDGE: %d, %d\n", BM_elem_index_get(e), v_ls_base->list_len);
+ printf("# SPLITTING EDGE: %d, %u\n", BM_elem_index_get(e), v_ls_base->list_len);
# endif
/* intersect */
is_wire = BLI_gset_haskey(s.wire_edges, e);
@@ -1258,6 +1272,13 @@ bool BM_mesh_intersect(BMesh *bm,
continue;
}
+ /* It's possible the vertex to dissolve is an edge on an existing face
+ * that doesn't divide the face, therefor the edges are not wire
+ * and shouldn't be handled here, see: T63787. */
+ if (!BLI_gset_haskey(s.wire_edges, e_pair[0]) || !BLI_gset_haskey(s.wire_edges, e_pair[1])) {
+ continue;
+ }
+
v_a = BM_edge_other_vert(e_pair[0], v);
v_b = BM_edge_other_vert(e_pair[1], v);