From d6c2aef6c54013f976abb9a71f6748108d63d794 Mon Sep 17 00:00:00 2001 From: "qing.zhang" Date: Tue, 5 Nov 2024 18:30:24 +0800 Subject: [PATCH] FIX: infill generate fail Jira: none Two intersection points have the same pos, which causes the sort function to fail. Each intersection pair type should be LOW and HIGH, sort fail causes the HIGH point to be put first, so the check step will report fail. make sort function works on that situation Signed-off-by: qing.zhang Change-Id: I407146e55265c5b55f4e44ac174ce82b2cb0af05 --- src/libslic3r/Fill/FillRectilinear.cpp | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 2dbf1d17a..64c0ce44d 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -124,6 +124,8 @@ struct SegmentIntersection // y position of the intersection, rational number. int64_t pos_p { 0 }; uint32_t pos_q { 1 }; + // the index fo the prev point in the contour + size_t prev_idx{0}; coord_t pos() const { // Division rounds both positive and negative down to zero. @@ -798,6 +800,7 @@ static std::vector slice_region_by_vertical_lines(con SegmentIntersection is; is.iContour = iContour; is.iSegment = iSegment; + is.prev_idx = iPrev; assert(l <= this_x); assert(r >= this_x); // Calculate the intersection position in y axis. x is known. @@ -839,6 +842,12 @@ static std::vector slice_region_by_vertical_lines(con // +-1 to take rounding into account. assert(is.pos() + 1 >= std::min(p1.y(), p2.y())); assert(is.pos() <= std::max(p1.y(), p2.y()) + 1); + //BBS: check segment intersection type + const coord_t dir = p2.x() - p1.x(); + const bool low = dir > 0; + is.type = poly_with_offset.is_contour_outer(iContour) ? + (low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) : + (low ? SegmentIntersection::INNER_LOW : SegmentIntersection::INNER_HIGH); segs[i].intersections.push_back(is); } } @@ -848,7 +857,13 @@ static std::vector slice_region_by_vertical_lines(con for (size_t i_seg = 0; i_seg < segs.size(); ++ i_seg) { SegmentedIntersectionLine &sil = segs[i_seg]; // Sort the intersection points using exact rational arithmetic. - std::sort(sil.intersections.begin(), sil.intersections.end()); + //BBS: if the LOW and HIGH has seam y pos, LOW should be first + std::sort(sil.intersections.begin(), sil.intersections.end(), [](const SegmentIntersection &l, const SegmentIntersection &r) { + if (l.pos() == r.pos() && l.iContour == r.iContour) + return l.type < r.type; + + return l.pos() < r.pos(); + }); // Assign the intersection types, remove duplicate or overlapping intersection points. // When a loop vertex touches a vertical line, intersection point is generated for both segments. // If such two segments are oriented equally, then one of them is removed. @@ -858,16 +873,11 @@ static std::vector slice_region_by_vertical_lines(con size_t j = 0; for (size_t i = 0; i < sil.intersections.size(); ++ i) { // What is the orientation of the segment at the intersection point? - SegmentIntersection &is = sil.intersections[i]; + SegmentIntersection &is = sil.intersections[i]; const size_t iContour = is.iContour; - const Points &contour = poly_with_offset.contour(iContour).points; const size_t iSegment = is.iSegment; - const size_t iPrev = prev_idx_modulo(iSegment, contour); - const coord_t dir = contour[iSegment].x() - contour[iPrev].x(); - const bool low = dir > 0; - is.type = poly_with_offset.is_contour_outer(iContour) ? - (low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) : - (low ? SegmentIntersection::INNER_LOW : SegmentIntersection::INNER_HIGH); + const size_t iPrev = is.prev_idx; + const bool low = is.type == SegmentIntersection::OUTER_LOW || is.type == SegmentIntersection::INNER_LOW; bool take_next = true; if (j > 0) { SegmentIntersection &is2 = sil.intersections[j - 1]; @@ -876,7 +886,7 @@ static std::vector slice_region_by_vertical_lines(con if (is.pos_p == is2.pos_p) { // Two successive segments meet exactly at the vertical line. // Verify that the segments of sil.intersections[i] and sil.intersections[j-1] are adjoint. - assert(iSegment == prev_idx_modulo(is2.iSegment, contour) || is2.iSegment == iPrev); + assert(iSegment == is2.prev_idx || is2.iSegment == iPrev); assert(is.type == is2.type); // Two successive segments of the same direction (both to the right or both to the left) // meet exactly at the vertical line.