diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index b9295a8344d..92f6476fdd9 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1102,8 +1102,11 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, { /* Fills the `r_buffer` buffer with the intersection of the arrays in `buffer_a` and `buffer_b`. * `buffer_a` and `buffer_b` have a sequence of sorted, non-repeating indices representing - * polygons. */ - const auto intersect = [](const Span buffer_a, const Span buffer_b, int *r_buffer) { + * polygons. */ + const auto intersect = [](const Span buffer_a, + const Span buffer_b, + const BitVector<> is_double, + int *r_buffer) { int result_num = 0; int index_a = 0, index_b = 0; while (index_a < buffer_a.size() && index_b < buffer_b.size()) { @@ -1117,7 +1120,12 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, } else { /* Equality. */ - r_buffer[result_num++] = value_a; + + /* Do not add duplicates. + * As they are already in the original array, this can cause buffer overflow. */ + if (!is_double[value_a]) { + r_buffer[result_num++] = value_a; + } index_a++; index_b++; } @@ -1204,6 +1212,7 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, int *isect_result = doubles_buffer.data() + doubles_buffer_num + 1; + /* `polys_a` are the polygons connected to the first corner. So skip the first corner. */ for (int corner_index : IndexRange(corner_first + 1, corner_num - 1)) { elem_index = corners[corner_index]; link_offs = linked_polys_offset[elem_index]; @@ -1217,8 +1226,10 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, polys_b_num--; } while (poly_to_test != poly_index); - doubles_num = intersect( - Span{polys_a, polys_a_num}, Span{polys_b, polys_b_num}, isect_result); + doubles_num = intersect(Span{polys_a, polys_a_num}, + Span{polys_b, polys_b_num}, + is_double, + isect_result); if (doubles_num == 0) { break; @@ -1236,6 +1247,12 @@ static int poly_find_doubles(const OffsetIndices poly_corners_offsets, } doubles_buffer_num += doubles_num; doubles_offsets.append(++doubles_buffer_num); + + if ((doubles_buffer_num + 1) == poly_num) { + /* The last slot is the remaining unduplicated polygon. + * Avoid checking intersection as there are no more slots left. */ + break; + } } }