Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Hejl <hejl.lukas@gmail.com>2022-08-29 16:58:57 +0300
committersupermerill <merill@free.fr>2022-09-13 21:39:03 +0300
commitd81e39185acb8f66ae4ab546a1d46625cb96eb09 (patch)
tree193248bcb0c2706679e61282203c0564afe28a48
parent0f0b4d1c200cff25c751c91ba33e897c71c65eaa (diff)
Fix of #8724, #8747, and #8753: Crash when Voronoi vertexes of a finite edge have some coordinate NaN or infinite.
-rw-r--r--src/libslic3r/Arachne/SkeletalTrapezoidation.cpp18
-rw-r--r--src/libslic3r/Arachne/utils/VoronoiUtils.cpp1
-rw-r--r--src/libslic3r/Arachne/utils/VoronoiUtils.hpp5
-rw-r--r--src/libslic3r/Geometry/VoronoiUtilsCgal.cpp7
4 files changed, 28 insertions, 3 deletions
diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
index 7bd37df11..e9afa0305 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
@@ -451,8 +451,23 @@ SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const Bead
constructFromPolygons(polys);
}
+static bool has_finite_edge_with_non_finite_vertex(const Geometry::VoronoiDiagram &voronoi_diagram)
+{
+ for (const VoronoiUtils::vd_t::edge_type &edge : voronoi_diagram.edges()) {
+ if (edge.is_finite()) {
+ assert(edge.vertex0() != nullptr && edge.vertex1() != nullptr);
+ if (edge.vertex0() == nullptr || edge.vertex1() == nullptr || !VoronoiUtils::is_finite(*edge.vertex0()) ||
+ !VoronoiUtils::is_finite(*edge.vertex1()))
+ return true;
+ }
+ }
+ return false;
+}
static bool detect_missing_voronoi_vertex(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector<SkeletalTrapezoidation::Segment> &segments) {
+ if (has_finite_edge_with_non_finite_vertex(voronoi_diagram))
+ return true;
+
for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) {
if (!cell.incident_edge())
continue; // There is no spoon
@@ -471,7 +486,8 @@ static bool detect_missing_voronoi_vertex(const Geometry::VoronoiDiagram &vorono
VoronoiUtils::vd_t::edge_type *ending_vd_edge = nullptr;
VoronoiUtils::vd_t::edge_type *edge = cell.incident_edge();
do {
- if (edge->is_infinite()) continue;
+ if (edge->is_infinite() || edge->vertex0() == nullptr || edge->vertex1() == nullptr || !VoronoiUtils::is_finite(*edge->vertex0()) || !VoronoiUtils::is_finite(*edge->vertex1()))
+ continue;
Vec2i64 v0 = VoronoiUtils::p(edge->vertex0());
Vec2i64 v1 = VoronoiUtils::p(edge->vertex1());
diff --git a/src/libslic3r/Arachne/utils/VoronoiUtils.cpp b/src/libslic3r/Arachne/utils/VoronoiUtils.cpp
index 3da556b47..82bd79523 100644
--- a/src/libslic3r/Arachne/utils/VoronoiUtils.cpp
+++ b/src/libslic3r/Arachne/utils/VoronoiUtils.cpp
@@ -15,6 +15,7 @@ Vec2i64 VoronoiUtils::p(const vd_t::vertex_type *node)
{
const double x = node->x();
const double y = node->y();
+ assert(std::isfinite(x) && std::isfinite(y));
assert(x <= double(std::numeric_limits<int64_t>::max()) && x >= std::numeric_limits<int64_t>::lowest());
assert(y <= double(std::numeric_limits<int64_t>::max()) && y >= std::numeric_limits<int64_t>::lowest());
return {int64_t(x + 0.5 - (x < 0)), int64_t(y + 0.5 - (y < 0))}; // Round to the nearest integer coordinates.
diff --git a/src/libslic3r/Arachne/utils/VoronoiUtils.hpp b/src/libslic3r/Arachne/utils/VoronoiUtils.hpp
index e736f98bc..aa4693643 100644
--- a/src/libslic3r/Arachne/utils/VoronoiUtils.hpp
+++ b/src/libslic3r/Arachne/utils/VoronoiUtils.hpp
@@ -35,6 +35,11 @@ public:
* The \p approximate_step_size is measured parallel to the \p source_segment, not along the parabola.
*/
static std::vector<Point> discretizeParabola(const Point &source_point, const Segment &source_segment, Point start, Point end, coord_t approximate_step_size, float transitioning_angle);
+
+ static inline bool is_finite(const VoronoiUtils::vd_t::vertex_type &vertex)
+ {
+ return std::isfinite(vertex.x()) && std::isfinite(vertex.y());
+ }
};
} // namespace Slic3r::Arachne
diff --git a/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp b/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp
index caaf1ee9c..062a3b397 100644
--- a/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp
+++ b/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp
@@ -3,6 +3,7 @@
#include <CGAL/Surface_sweep_2_algorithms.h>
#include "libslic3r/Geometry/Voronoi.hpp"
+#include "libslic3r/Arachne/utils/VoronoiUtils.hpp"
#include "VoronoiUtilsCgal.hpp"
@@ -28,7 +29,8 @@ bool VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(const VD &voronoi_
if (edge.color() != 0)
continue;
- if (edge.is_finite() && edge.is_linear()) {
+ if (edge.is_finite() && edge.is_linear() && edge.vertex0() != nullptr && edge.vertex1() != nullptr &&
+ Arachne::VoronoiUtils::is_finite(*edge.vertex0()) && Arachne::VoronoiUtils::is_finite(*edge.vertex1())) {
segments.emplace_back(to_cgal_point(*edge.vertex0()), to_cgal_point(*edge.vertex1()));
edge.color(1);
assert(edge.twin() != nullptr);
@@ -73,7 +75,8 @@ bool VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(const VoronoiDiagram &vor
do {
// FIXME Lukas H.: Also process parabolic segments.
- if (edge->is_finite() && edge->is_linear())
+ if (edge->is_finite() && edge->is_linear() && edge->vertex0() != nullptr && edge->vertex1() != nullptr &&
+ Arachne::VoronoiUtils::is_finite(*edge->vertex0()) && Arachne::VoronoiUtils::is_finite(*edge->vertex1()))
edges.emplace_back(edge);
edge = edge->rot_next();