mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 22:46:01 +08:00
Fix of #8724, #8747, and #8753: Crash when Voronoi vertexes of a finite edge have some coordinate NaN or infinite.
This commit is contained in:
parent
c74f16d7c7
commit
de48bcd1b2
@ -451,8 +451,23 @@ SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const Bead
|
|||||||
constructFromPolygons(polys);
|
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) {
|
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()) {
|
for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) {
|
||||||
if (!cell.incident_edge())
|
if (!cell.incident_edge())
|
||||||
continue; // There is no spoon
|
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 *ending_vd_edge = nullptr;
|
||||||
VoronoiUtils::vd_t::edge_type *edge = cell.incident_edge();
|
VoronoiUtils::vd_t::edge_type *edge = cell.incident_edge();
|
||||||
do {
|
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 v0 = VoronoiUtils::p(edge->vertex0());
|
||||||
Vec2i64 v1 = VoronoiUtils::p(edge->vertex1());
|
Vec2i64 v1 = VoronoiUtils::p(edge->vertex1());
|
||||||
|
@ -15,6 +15,7 @@ Vec2i64 VoronoiUtils::p(const vd_t::vertex_type *node)
|
|||||||
{
|
{
|
||||||
const double x = node->x();
|
const double x = node->x();
|
||||||
const double y = node->y();
|
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(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());
|
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.
|
return {int64_t(x + 0.5 - (x < 0)), int64_t(y + 0.5 - (y < 0))}; // Round to the nearest integer coordinates.
|
||||||
|
@ -35,6 +35,11 @@ public:
|
|||||||
* The \p approximate_step_size is measured parallel to the \p source_segment, not along the parabola.
|
* 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 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
|
} // namespace Slic3r::Arachne
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <CGAL/Surface_sweep_2_algorithms.h>
|
#include <CGAL/Surface_sweep_2_algorithms.h>
|
||||||
|
|
||||||
#include "libslic3r/Geometry/Voronoi.hpp"
|
#include "libslic3r/Geometry/Voronoi.hpp"
|
||||||
|
#include "libslic3r/Arachne/utils/VoronoiUtils.hpp"
|
||||||
|
|
||||||
#include "VoronoiUtilsCgal.hpp"
|
#include "VoronoiUtilsCgal.hpp"
|
||||||
|
|
||||||
@ -28,7 +29,8 @@ bool VoronoiUtilsCgal::is_voronoi_diagram_planar_intersection(const VD &voronoi_
|
|||||||
if (edge.color() != 0)
|
if (edge.color() != 0)
|
||||||
continue;
|
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()));
|
segments.emplace_back(to_cgal_point(*edge.vertex0()), to_cgal_point(*edge.vertex1()));
|
||||||
edge.color(1);
|
edge.color(1);
|
||||||
assert(edge.twin() != nullptr);
|
assert(edge.twin() != nullptr);
|
||||||
@ -73,7 +75,8 @@ bool VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(const VoronoiDiagram &vor
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// FIXME Lukas H.: Also process parabolic segments.
|
// 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);
|
edges.emplace_back(edge);
|
||||||
|
|
||||||
edge = edge->rot_next();
|
edge = edge->rot_next();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user