mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-04 02:00:39 +08:00
Bugfix: prevent crashes from rounding issues caused by almost-collinear points in the new FillRectilinear. #3684
This commit is contained in:
parent
086fd2e8a8
commit
702cf43a0a
@ -129,6 +129,14 @@ ExPolygon::has_boundary_point(const Point &point) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExPolygon::remove_vertical_collinear_points(coord_t tolerance)
|
||||||
|
{
|
||||||
|
this->contour.remove_vertical_collinear_points(tolerance);
|
||||||
|
for (Polygon &p : this->holes)
|
||||||
|
p.remove_vertical_collinear_points(tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
|
ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,7 @@ class ExPolygon
|
|||||||
bool contains(const Point &point) const;
|
bool contains(const Point &point) const;
|
||||||
bool contains_b(const Point &point) const;
|
bool contains_b(const Point &point) const;
|
||||||
bool has_boundary_point(const Point &point) const;
|
bool has_boundary_point(const Point &point) const;
|
||||||
|
void remove_vertical_collinear_points(coord_t tolerance);
|
||||||
void simplify_p(double tolerance, Polygons* polygons) const;
|
void simplify_p(double tolerance, Polygons* polygons) const;
|
||||||
Polygons simplify_p(double tolerance) const;
|
Polygons simplify_p(double tolerance) const;
|
||||||
ExPolygons simplify(double tolerance) const;
|
ExPolygons simplify(double tolerance) const;
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
//#define DEBUG_RECTILINEAR
|
||||||
|
#ifdef DEBUG_RECTILINEAR
|
||||||
|
#undef NDEBUG
|
||||||
|
#include "../SVG.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../ClipperUtils.hpp"
|
#include "../ClipperUtils.hpp"
|
||||||
#include "../ExPolygon.hpp"
|
#include "../ExPolygon.hpp"
|
||||||
#include "../PolylineCollection.hpp"
|
#include "../PolylineCollection.hpp"
|
||||||
@ -7,17 +13,16 @@
|
|||||||
|
|
||||||
#include "FillRectilinear.hpp"
|
#include "FillRectilinear.hpp"
|
||||||
|
|
||||||
//#define DEBUG_RECTILINEAR
|
|
||||||
#ifdef DEBUG_RECTILINEAR
|
|
||||||
#include "../SVG.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
void
|
void
|
||||||
FillRectilinear::_fill_single_direction(ExPolygon expolygon,
|
FillRectilinear::_fill_single_direction(ExPolygon expolygon,
|
||||||
const direction_t &direction, coord_t x_shift, Polylines* out)
|
const direction_t &direction, coord_t x_shift, Polylines* out)
|
||||||
{
|
{
|
||||||
|
// Remove almost collinear points (vertical ones might break this algorithm
|
||||||
|
// because of rounding).
|
||||||
|
expolygon.remove_vertical_collinear_points(1);
|
||||||
|
|
||||||
// rotate polygons so that we can work with vertical lines here
|
// rotate polygons so that we can work with vertical lines here
|
||||||
expolygon.rotate(-direction.first);
|
expolygon.rotate(-direction.first);
|
||||||
|
|
||||||
|
@ -148,6 +148,32 @@ Polygon::contains(const Point &point) const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Polygon::douglas_peucker(double tolerance)
|
||||||
|
{
|
||||||
|
this->points.push_back(this->points.front());
|
||||||
|
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
||||||
|
this->points.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Polygon::remove_vertical_collinear_points(coord_t tolerance)
|
||||||
|
{
|
||||||
|
Points &pp = this->points;
|
||||||
|
pp.push_back(pp.front());
|
||||||
|
for (size_t i = 0; i < pp.size()-1; ++i) {
|
||||||
|
while (i < pp.size()-1) {
|
||||||
|
Point &next = pp[i+1];
|
||||||
|
if (std::abs(next.x - pp[i].x) <= tolerance) {
|
||||||
|
pp.erase(pp.begin() + i+1);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pp.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
// this only works on CCW polygons as CW will be ripped out by Clipper's simplify_polygons()
|
// this only works on CCW polygons as CW will be ripped out by Clipper's simplify_polygons()
|
||||||
Polygons
|
Polygons
|
||||||
Polygon::simplify(double tolerance) const
|
Polygon::simplify(double tolerance) const
|
||||||
|
@ -39,6 +39,8 @@ class Polygon : public MultiPoint {
|
|||||||
// Does an unoriented polygon contain a point?
|
// Does an unoriented polygon contain a point?
|
||||||
// Tested by counting intersections along a horizontal line.
|
// Tested by counting intersections along a horizontal line.
|
||||||
bool contains(const Point &point) const;
|
bool contains(const Point &point) const;
|
||||||
|
void douglas_peucker(double tolerance);
|
||||||
|
void remove_vertical_collinear_points(coord_t tolerance);
|
||||||
Polygons simplify(double tolerance) const;
|
Polygons simplify(double tolerance) const;
|
||||||
void simplify(double tolerance, Polygons &polygons) const;
|
void simplify(double tolerance, Polygons &polygons) const;
|
||||||
void triangulate_convex(Polygons* polygons) const;
|
void triangulate_convex(Polygons* polygons) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user