Fix of Can't convert polyline with more than two points to a line (#6933)
Sometimes Clipper produces a polyline with more than 2 points when clipping a line with a polygon or a set of polygons. We hope the intermediate points are collinear with the line, so we may just ignore them.
This commit is contained in:
parent
cab71073a1
commit
0a51afa3e6
5 changed files with 9 additions and 11 deletions
|
@ -647,7 +647,9 @@ Lines _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Pol
|
|||
// convert Polylines to Lines
|
||||
Lines retval;
|
||||
for (Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
|
||||
retval.emplace_back(polyline->line());
|
||||
if (polyline->size() >= 2)
|
||||
//FIXME It may happen, that Clipper produced a polyline with more than 2 collinear points by clipping a single line with polygons. It is a very rare issue, but it happens, see GH #6933.
|
||||
retval.push_back({ polyline->front(), polyline->back() });
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -928,7 +928,9 @@ static Polylines connect_lines_using_hooks(Polylines &&lines, const ExPolygon &b
|
|||
Linef l { { bg::get<0, 0>(seg), bg::get<0, 1>(seg) }, { bg::get<1, 0>(seg), bg::get<1, 1>(seg) } };
|
||||
assert(line_alg::distance_to_squared(l, Vec2d(pt.cast<double>())) > 1000 * 1000);
|
||||
#endif // NDEBUG
|
||||
} else if (pl.line().distance_to_squared(pt) <= 1000 * 1000)
|
||||
} else if (pl.size() >= 2 &&
|
||||
//FIXME Hoping that pl is really a line, trimmed by a polygon using ClipperUtils. Sometimes Clipper leaves some additional collinear points on the polyline, let's hope it is all right.
|
||||
Line{ pl.front(), pl.back() }.distance_to_squared(pt) <= 1000 * 1000)
|
||||
out = closest.front().second;
|
||||
}
|
||||
return out;
|
||||
|
|
|
@ -33,7 +33,9 @@ public:
|
|||
void rotate(double angle, const Point ¢er);
|
||||
void reverse() { std::reverse(this->points.begin(), this->points.end()); }
|
||||
|
||||
const Point& first_point() const { return this->points.front(); }
|
||||
const Point& front() const { return this->points.front(); }
|
||||
const Point& back() const { return this->points.back(); }
|
||||
const Point& first_point() const { return this->front(); }
|
||||
virtual const Point& last_point() const = 0;
|
||||
virtual Lines lines() const = 0;
|
||||
size_t size() const { return points.size(); }
|
||||
|
|
|
@ -10,13 +10,6 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
Line Polyline::line() const
|
||||
{
|
||||
if (this->points.size() > 2)
|
||||
throw Slic3r::InvalidArgument("Can't convert polyline with more than two points to a line");
|
||||
return Line(this->points.front(), this->points.back());
|
||||
}
|
||||
|
||||
const Point& Polyline::leftmost_point() const
|
||||
{
|
||||
const Point *p = &this->points.front();
|
||||
|
|
|
@ -62,7 +62,6 @@ public:
|
|||
|
||||
const Point& last_point() const override { return this->points.back(); }
|
||||
const Point& leftmost_point() const;
|
||||
Line line() const;
|
||||
Lines lines() const override;
|
||||
|
||||
void clip_end(double distance);
|
||||
|
|
Loading…
Reference in a new issue