summaryrefslogtreecommitdiff
path: root/modules/csg
diff options
context:
space:
mode:
authorJustin Wash <justin.wash@pm.me>2023-04-27 17:16:42 -0500
committerRĂ©mi Verschelde <rverschelde@gmail.com>2023-05-12 12:06:59 +0200
commit268b60ddd6843dc5468a7951b3910084cd435ae3 (patch)
tree2121c2d4ab309055860002e34ff377b679c0415e /modules/csg
parent0c312c7a08cfc807de809ba281553927209b9a79 (diff)
Fix infinite loop in Build2DFaces::_find_edge_intersections
(cherry picked from commit 1ac2c537da86bd9a9234954dd4ba67e32c1b0d3a)
Diffstat (limited to 'modules/csg')
-rw-r--r--modules/csg/csg.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index a8ae4cfa5e..0bd8e5d9ad 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -1068,6 +1068,8 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
}
void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_segment_points[2], Vector<int> &r_segment_indices) {
+ LocalVector<Vector<Vector2>> processed_edges;
+
// For each face.
for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
Face2D face = faces[face_idx];
@@ -1079,17 +1081,32 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
// Check each edge.
for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
- Vector2 edge_points[2] = {
+ Vector<Vector2> edge_points_and_uvs = {
face_vertices[face_edge_idx].point,
- face_vertices[(face_edge_idx + 1) % 3].point
- };
- Vector2 edge_uvs[2] = {
+ face_vertices[(face_edge_idx + 1) % 3].point,
face_vertices[face_edge_idx].uv,
face_vertices[(face_edge_idx + 1) % 3].uv
};
- Vector2 intersection_point;
+
+ Vector2 edge_points[2] = {
+ edge_points_and_uvs[0],
+ edge_points_and_uvs[1],
+ };
+ Vector2 edge_uvs[2] = {
+ edge_points_and_uvs[2],
+ edge_points_and_uvs[3],
+ };
+
+ // Check if edge has already been processed.
+ if (processed_edges.find(edge_points_and_uvs) != -1) {
+ continue;
+ }
+
+ processed_edges.push_back(edge_points_and_uvs);
// First check if the ends of the segment are on the edge.
+ Vector2 intersection_point;
+
bool on_edge = false;
for (int edge_point_idx = 0; edge_point_idx < 2; ++edge_point_idx) {
intersection_point = Geometry2D::get_closest_point_to_segment(p_segment_points[edge_point_idx], edge_points);