Fixed asserts in connecting islands and in perimeter overhangs
due to self intersections in clipped clipping rectangle.
This commit is contained in:
parent
767a556443
commit
7f6f63db0f
@ -317,15 +317,18 @@ void Layer::build_up_down_graph(Layer& below, Layer& above)
|
|||||||
coord_t* end = srcs + 4;
|
coord_t* end = srcs + 4;
|
||||||
std::sort(begin, end);
|
std::sort(begin, end);
|
||||||
end = std::unique(begin, end);
|
end = std::unique(begin, end);
|
||||||
assert(begin + 2 == end);
|
if (begin + 1 == end) {
|
||||||
if (begin + 1 == end)
|
// Self intersection may happen on source contour. Just copy the Z value.
|
||||||
pt.z() = *begin;
|
pt.z() = *begin;
|
||||||
else if (begin + 2 <= end) {
|
} else {
|
||||||
|
assert(begin + 2 == end);
|
||||||
|
if (begin + 2 <= end) {
|
||||||
// store a -1 based negative index into the "intersections" vector here.
|
// store a -1 based negative index into the "intersections" vector here.
|
||||||
m_intersections.emplace_back(srcs[0], srcs[1]);
|
m_intersections.emplace_back(srcs[0], srcs[1]);
|
||||||
pt.z() = -coord_t(m_intersections.size());
|
pt.z() = -coord_t(m_intersections.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const std::vector<std::pair<coord_t, coord_t>>& intersections() const { return m_intersections; }
|
const std::vector<std::pair<coord_t, coord_t>>& intersections() const { return m_intersections; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -397,22 +397,37 @@ static ClipperLib_Z::Paths clip_extrusion(const ClipperLib_Z::Path &subject, con
|
|||||||
ClipperLib_Z::Clipper clipper;
|
ClipperLib_Z::Clipper clipper;
|
||||||
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
|
clipper.ZFillFunction([](const ClipperLib_Z::IntPoint &e1bot, const ClipperLib_Z::IntPoint &e1top, const ClipperLib_Z::IntPoint &e2bot,
|
||||||
const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
|
const ClipperLib_Z::IntPoint &e2top, ClipperLib_Z::IntPoint &pt) {
|
||||||
|
// The clipping contour may be simplified by clipping it with a bounding box of "subject" path.
|
||||||
|
// The clipping function used may produce self intersections outside of the "subject" bounding box. Such self intersections are
|
||||||
|
// harmless to the result of the clipping operation,
|
||||||
|
// Both ends of each edge belong to the same source: Either they are from subject or from clipping path.
|
||||||
|
assert(e1bot.z() >= 0 && e1top.z() >= 0);
|
||||||
|
assert(e2bot.z() >= 0 && e2top.z() >= 0);
|
||||||
|
assert((e1bot.z() == 0) == (e1top.z() == 0));
|
||||||
|
assert((e2bot.z() == 0) == (e2top.z() == 0));
|
||||||
|
|
||||||
|
// Start & end points of the clipped polyline (extrusion path with a non-zero width).
|
||||||
ClipperLib_Z::IntPoint start = e1bot;
|
ClipperLib_Z::IntPoint start = e1bot;
|
||||||
ClipperLib_Z::IntPoint end = e1top;
|
ClipperLib_Z::IntPoint end = e1top;
|
||||||
|
|
||||||
if (start.z() <= 0 && end.z() <= 0) {
|
if (start.z() <= 0 && end.z() <= 0) {
|
||||||
start = e2bot;
|
start = e2bot;
|
||||||
end = e2top;
|
end = e2top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (start.z() <= 0 && end.z() <= 0) {
|
||||||
|
// Self intersection on the source contour.
|
||||||
|
assert(start.z() == 0 && end.z() == 0);
|
||||||
|
pt.z() = 0;
|
||||||
|
} else {
|
||||||
|
// Interpolate extrusion line width.
|
||||||
assert(start.z() > 0 && end.z() > 0);
|
assert(start.z() > 0 && end.z() > 0);
|
||||||
|
|
||||||
// Interpolate extrusion line width.
|
|
||||||
double length_sqr = (end - start).cast<double>().squaredNorm();
|
double length_sqr = (end - start).cast<double>().squaredNorm();
|
||||||
double dist_sqr = (pt - start).cast<double>().squaredNorm();
|
double dist_sqr = (pt - start).cast<double>().squaredNorm();
|
||||||
double t = std::sqrt(dist_sqr / length_sqr);
|
double t = std::sqrt(dist_sqr / length_sqr);
|
||||||
|
|
||||||
pt.z() = start.z() + coord_t((end.z() - start.z()) * t);
|
pt.z() = start.z() + coord_t((end.z() - start.z()) * t);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
clipper.AddPath(subject, ClipperLib_Z::ptSubject, false);
|
clipper.AddPath(subject, ClipperLib_Z::ptSubject, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user