From 00295919bf5323262fbc9118c9b9724a0e5129e8 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 23 Mar 2021 09:59:08 +0100 Subject: [PATCH] Fixes of MutablePolygon --- src/libslic3r/MutablePolygon.cpp | 47 ++++++++++++++++++++++++++------ src/libslic3r/MutablePolygon.hpp | 8 +++--- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/MutablePolygon.cpp b/src/libslic3r/MutablePolygon.cpp index 104b4c6ee..54ce10b49 100644 --- a/src/libslic3r/MutablePolygon.cpp +++ b/src/libslic3r/MutablePolygon.cpp @@ -122,7 +122,7 @@ static bool clip_narrow_corner( } else { assert(backward == Free); p02 = it0.prev()->cast(); - if (cross2(p0 - p2, p02 - p2) > 0) + if (cross2(p02 - p2, p0 - p2) > 0) backward = Blocked; else { // New clipping edge lenght. @@ -141,14 +141,37 @@ static bool clip_narrow_corner( } } + assert(dist2_current <= shortcut_length2); + assert(polygon.size() >= 2); + assert(polygon.size() == 2 || forward == Blocked || forward == Far); + assert(polygon.size() == 2 || backward == Blocked || backward == Far); + if (polygon.size() <= 3) { // A hole degenerated to an empty polygon, or a tiny triangle remained. - assert(polygon.size() < 3 || (forward == Blocked && backward == Blocked) || (forward == Far && backward == Far)); - if (polygon.size() < 3 || forward == Far) { - assert(polygon.size() < 3 || dist2_current <= shortcut_length2); + bool blocked = forward == Blocked || backward == Blocked; + assert(polygon.size() < 3 || + // Remaining triangle is CCW oriented. Both sides must be "blocked", but the other side may have not been + // updated after the the p02 / p22 became united into a single point. + blocked || + // Remaining triangle is concave, however both of its arms are long. + (forward == Far && backward == Far)); +#ifndef _NDEBUG + if (polygon.size() == 3) { + // Verify that the remaining triangle is CCW or CW. + p02 = it0.prev()->cast(); + p22 = it2.next()->cast(); + assert(p02 == p22); + auto orient1 = cross2(p02 - p2, p0 - p2); + auto orient2 = cross2(p2 - p0, p22 - p0); + assert(orient1 > 0 == blocked); + assert(orient2 > 0 == blocked); + } +#endif // _NDEBUG + if (polygon.size() < 3 || (forward == Far && backward == Far)) { polygon.clear(); } else { // The remaining triangle is CCW oriented, keep it. + assert(forward == Blocked || backward == Blocked); } return true; } @@ -168,7 +191,7 @@ static bool clip_narrow_corner( } else if (forward == Blocked || backward == Blocked) { // One side is far, the other blocked. assert(forward == Far || backward == Far); - if (backward == Far) { + if (forward == Far) { // Sort, so we will clip the 1st edge. std::swap(p0, p2); std::swap(p02, p22); @@ -177,6 +200,10 @@ static bool clip_narrow_corner( // Circle intersects a line at two points, however because |p2 - p0| < shortcut_length, // only the second intersection is valid. Because |p2 - p02| > shortcut_length, such // intersection should always be found on (p0, p02). +#ifndef NDEBUG + auto dfar2 = (p02 - p2).squaredNorm(); + assert(dfar2 >= shortcut_length2); +#endif // NDEBUG const Vec2d v = (p02 - p0).cast(); const Vec2d d = (p0 - p2).cast(); const double a = v.squaredNorm(); @@ -273,15 +300,17 @@ void smooth_outward(MutablePolygon &polygon, coord_t clip_dist_scaled) Point pt_new = p1 + (t * v2d).cast(); #ifndef NDEBUG double d2new = (pt_new - (swap ? p2 : p0)).cast().squaredNorm(); - assert(std::abs(d2new - clip_dist_scaled2) < sqr(10. * SCALED_EPSILON)); + assert(std::abs(d2new - clip_dist_scaled2) < 1e-5 * clip_dist_scaled2); #endif // NDEBUG it2.insert(pt_new); } else { // Cut the corner with a line perpendicular to the bisector. double t = sqrt(0.25 * clip_dist_scaled2 / d2); - assert(t > 0. && t < 1.); - Point p0 = p1 + (v1d * t).cast(); - Point p2 = p1 + (v2d * (t * lv2 / lv1)).cast(); + double t2 = t * lv1 / lv2; + assert(t > 0. && t < 1.); + assert(t2 > 0. && t2 < 1.); + Point p0 = p1 + (v1d * t ).cast(); + Point p2 = p1 + (v2d * t2).cast(); if (swap) std::swap(p0, p2); it2.insert(p2).insert(p0); diff --git a/src/libslic3r/MutablePolygon.hpp b/src/libslic3r/MutablePolygon.hpp index a601f19e3..ef2b61221 100644 --- a/src/libslic3r/MutablePolygon.hpp +++ b/src/libslic3r/MutablePolygon.hpp @@ -85,7 +85,7 @@ public: } void advance_front() { - assert(!this->empty()); + assert(! this->empty()); if (m_begin == m_end) this->make_empty(); else @@ -93,7 +93,7 @@ public: } void retract_back() { - assert(!this->empty()); + assert(! this->empty()); if (m_begin == m_end) this->make_empty(); else @@ -101,13 +101,13 @@ public: } MutablePolygon::iterator remove_front(MutablePolygon::iterator it) { - if (m_begin == it) + if (! this->empty() && m_begin == it) this->advance_front(); return it.remove(); } MutablePolygon::iterator remove_back(MutablePolygon::iterator it) { - if (m_end == it) + if (! this->empty() && m_end == it) this->retract_back(); return it.remove(); }