mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-03 20:10:40 +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;
|
||||
}
|
||||
|
||||
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
|
||||
ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ class ExPolygon
|
||||
bool contains(const Point &point) const;
|
||||
bool contains_b(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;
|
||||
Polygons simplify_p(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 "../ExPolygon.hpp"
|
||||
#include "../PolylineCollection.hpp"
|
||||
@ -7,17 +13,16 @@
|
||||
|
||||
#include "FillRectilinear.hpp"
|
||||
|
||||
//#define DEBUG_RECTILINEAR
|
||||
#ifdef DEBUG_RECTILINEAR
|
||||
#include "../SVG.hpp"
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
void
|
||||
FillRectilinear::_fill_single_direction(ExPolygon expolygon,
|
||||
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
|
||||
expolygon.rotate(-direction.first);
|
||||
|
||||
|
@ -148,6 +148,32 @@ Polygon::contains(const Point &point) const
|
||||
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()
|
||||
Polygons
|
||||
Polygon::simplify(double tolerance) const
|
||||
|
@ -39,6 +39,8 @@ class Polygon : public MultiPoint {
|
||||
// Does an unoriented polygon contain a point?
|
||||
// Tested by counting intersections along a horizontal line.
|
||||
bool contains(const Point &point) const;
|
||||
void douglas_peucker(double tolerance);
|
||||
void remove_vertical_collinear_points(coord_t tolerance);
|
||||
Polygons simplify(double tolerance) const;
|
||||
void simplify(double tolerance, Polygons &polygons) const;
|
||||
void triangulate_convex(Polygons* polygons) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user