mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-03 15:50:38 +08:00
Remove collinear points from polygons right after slicing the stl into polygons.
Triangulation of planar surfaces results in additional edges (i.e. splitting a rectangle into two triangles). Those edges end up as collinear points in the contour polygons and cause additional, redundant computation. Most collinear points would be removed by Douglas-Peucker during gcode export. Fixes #4726.
This commit is contained in:
parent
66b00c90c3
commit
faeb213ce1
@ -129,6 +129,14 @@ ExPolygon::has_boundary_point(const Point &point) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExPolygon::remove_colinear_points()
|
||||||
|
{
|
||||||
|
this->contour.remove_collinear_points();
|
||||||
|
for (Polygon &p : this->holes)
|
||||||
|
p.remove_collinear_points();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ExPolygon::remove_vertical_collinear_points(coord_t tolerance)
|
ExPolygon::remove_vertical_collinear_points(coord_t tolerance)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +37,8 @@ class ExPolygon
|
|||||||
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;
|
||||||
BoundingBox bounding_box() const { return this->contour.bounding_box(); };
|
BoundingBox bounding_box() const { return this->contour.bounding_box(); };
|
||||||
|
/// removes collinear points within SCALED_EPSILON tolerance
|
||||||
|
void remove_colinear_points();
|
||||||
void remove_vertical_collinear_points(coord_t tolerance);
|
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;
|
||||||
|
@ -156,6 +156,42 @@ Polygon::douglas_peucker(double tolerance)
|
|||||||
this->points.pop_back();
|
this->points.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Polygon::remove_collinear_points()
|
||||||
|
{
|
||||||
|
if(this->points.size() > 2) {
|
||||||
|
// copy points and append both 1 and last point in place to cover the boundaries
|
||||||
|
Points pp;
|
||||||
|
pp.reserve(this->points.size()+2);
|
||||||
|
pp.push_back(this->points.back());
|
||||||
|
pp.insert(pp.begin()+1, this->points.begin(), this->points.end());
|
||||||
|
pp.push_back(this->points.front());
|
||||||
|
// delete old points vector. Will be re-filled in the loop
|
||||||
|
this->points.clear();
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
size_t k = 0;
|
||||||
|
while (i < pp.size()-2) {
|
||||||
|
k = i+1;
|
||||||
|
const Point &p1 = pp[i];
|
||||||
|
while (k < pp.size()-1) {
|
||||||
|
const Point &p2 = pp[k];
|
||||||
|
const Point &p3 = pp[k+1];
|
||||||
|
Line l(p1, p3);
|
||||||
|
if(l.distance_to(p2) < SCALED_EPSILON) {
|
||||||
|
k++;
|
||||||
|
} else {
|
||||||
|
if(i > 0) this->points.push_back(p1); // implicitly removes the first point we appended above
|
||||||
|
i = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(k > pp.size()-2) break; // all remaining points are collinear and can be skipped
|
||||||
|
}
|
||||||
|
this->points.push_back(pp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Polygon::remove_vertical_collinear_points(coord_t tolerance)
|
Polygon::remove_vertical_collinear_points(coord_t tolerance)
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,8 @@ class Polygon : public MultiPoint {
|
|||||||
// 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 douglas_peucker(double tolerance);
|
||||||
|
/// removes collinear points within SCALED_EPSILON tolerance
|
||||||
|
void remove_collinear_points();
|
||||||
void remove_vertical_collinear_points(coord_t 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;
|
||||||
|
@ -842,6 +842,19 @@ void PrintObject::_slice()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove collinear points from slice polygons (artifacts from stl-triangulation)
|
||||||
|
std::queue<SurfaceCollection*> queue;
|
||||||
|
for (Layer* layer : this->layers) {
|
||||||
|
for (LayerRegion* layerm : layer->regions) {
|
||||||
|
queue.push(&layerm->slices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parallelize<SurfaceCollection*>(
|
||||||
|
queue,
|
||||||
|
boost::bind(&Slic3r::SurfaceCollection::remove_collinear_points, _1),
|
||||||
|
this->_print->config.threads.value
|
||||||
|
);
|
||||||
|
|
||||||
// remove last layer(s) if empty
|
// remove last layer(s) if empty
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (! this->layers.empty()) {
|
while (! this->layers.empty()) {
|
||||||
|
@ -39,6 +39,14 @@ SurfaceCollection::simplify(double tolerance)
|
|||||||
this->surfaces = ss;
|
this->surfaces = ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SurfaceCollection::remove_collinear_points()
|
||||||
|
{
|
||||||
|
for(Surface &surface : this->surfaces) {
|
||||||
|
surface.expolygon.remove_colinear_points();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* group surfaces by common properties */
|
/* group surfaces by common properties */
|
||||||
void
|
void
|
||||||
SurfaceCollection::group(std::vector<SurfacesConstPtr> *retval) const
|
SurfaceCollection::group(std::vector<SurfacesConstPtr> *retval) const
|
||||||
|
@ -18,6 +18,8 @@ class SurfaceCollection
|
|||||||
operator Polygons() const;
|
operator Polygons() const;
|
||||||
operator ExPolygons() const;
|
operator ExPolygons() const;
|
||||||
void simplify(double tolerance);
|
void simplify(double tolerance);
|
||||||
|
/// Unifies straight multi-segment lines to a single line (artifacts from stl-triangulation)
|
||||||
|
void remove_collinear_points();
|
||||||
void group(std::vector<SurfacesConstPtr> *retval) const;
|
void group(std::vector<SurfacesConstPtr> *retval) const;
|
||||||
template <class T> bool any_internal_contains(const T &item) const;
|
template <class T> bool any_internal_contains(const T &item) const;
|
||||||
template <class T> bool any_bottom_contains(const T &item) const;
|
template <class T> bool any_bottom_contains(const T &item) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user