From 0dae43e4bc68fb3fce2a5c6d41ba7030c7d542a5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 24 Mar 2017 09:32:30 +0100 Subject: [PATCH] Bugfix: when the Voronoi diagram contained very large coordinates we need to check whether they are greater than our allowed range and consider the Voronoi edges infinite in those cases, in order to prevent overflows. https://github.com/alexrj/Slic3r/issues/3776 https://github.com/alexrj/Slic3r/commit/9ad1360e445cd3043c4dc30ccad64b82b914f952 --- xs/src/libslic3r/ClipperUtils.cpp | 9 --------- xs/src/libslic3r/ClipperUtils.hpp | 10 ++++++++++ xs/src/libslic3r/Geometry.cpp | 7 +++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/xs/src/libslic3r/ClipperUtils.cpp b/xs/src/libslic3r/ClipperUtils.cpp index 660b687e0..8aa72cae4 100644 --- a/xs/src/libslic3r/ClipperUtils.cpp +++ b/xs/src/libslic3r/ClipperUtils.cpp @@ -9,15 +9,6 @@ #include -// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library -// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset, -// which is optionally executed by other functions (union, intersection, diff). -// By the way, is the scalling for offset needed at all? -#define CLIPPER_OFFSET_POWER_OF_2 17 -// 2^17=131072 -#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2) -#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1) - namespace Slic3r { #ifdef CLIPPER_UTILS_DEBUG diff --git a/xs/src/libslic3r/ClipperUtils.hpp b/xs/src/libslic3r/ClipperUtils.hpp index d6060386a..b14232d90 100644 --- a/xs/src/libslic3r/ClipperUtils.hpp +++ b/xs/src/libslic3r/ClipperUtils.hpp @@ -12,6 +12,16 @@ using ClipperLib::jtMiter; using ClipperLib::jtRound; using ClipperLib::jtSquare; +// Factor to convert from coord_t (which is int32) to an int64 type used by the Clipper library +// for general offsetting (the offset(), offset2(), offset_ex() functions) and for the safety offset, +// which is optionally executed by other functions (union, intersection, diff). +// By the way, is the scalling for offset needed at all? +#define CLIPPER_OFFSET_POWER_OF_2 17 +// 2^17=131072 +#define CLIPPER_OFFSET_SCALE (1 << CLIPPER_OFFSET_POWER_OF_2) +#define CLIPPER_OFFSET_SCALE_ROUNDING_DELTA ((1 << (CLIPPER_OFFSET_POWER_OF_2 - 1)) - 1) +#define CLIPPER_MAX_COORD_UNSCALED (ClipperLib::hiRange / CLIPPER_OFFSET_SCALE) + namespace Slic3r { //----------------------------------------------------------- diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp index 314990734..96613549a 100644 --- a/xs/src/libslic3r/Geometry.cpp +++ b/xs/src/libslic3r/Geometry.cpp @@ -983,6 +983,13 @@ MedialAxis::process_edge_neighbors(const VD::edge_type* edge, ThickPolyline* pol bool MedialAxis::validate_edge(const VD::edge_type* edge) { + // prevent overflows and detect almost-infinite edges + if (std::abs(edge->vertex0()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) || + std::abs(edge->vertex0()->y()) > double(CLIPPER_MAX_COORD_UNSCALED) || + std::abs(edge->vertex1()->x()) > double(CLIPPER_MAX_COORD_UNSCALED) || + std::abs(edge->vertex1()->y()) > double(CLIPPER_MAX_COORD_UNSCALED)) + return false; + // construct the line representing this edge of the Voronoi diagram const Line line( Point( edge->vertex0()->x(), edge->vertex0()->y() ),