Fixed crash in reworked infill anchoring due to numeric issues.

Added some more asserts to EdgeGrid.
This commit is contained in:
Vojtech Bubnik 2020-11-20 18:46:39 +01:00
parent b7abe7dfa9
commit 54a5c1da1e
2 changed files with 27 additions and 12 deletions

View file

@ -84,10 +84,14 @@ public:
template<typename VISITOR> void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, VISITOR &visitor) const template<typename VISITOR> void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, VISITOR &visitor) const
{ {
// End points of the line segment. // End points of the line segment.
p1(0) -= m_bbox.min(0); assert(m_bbox.contains(p1));
p1(1) -= m_bbox.min(1); assert(m_bbox.contains(p2));
p2(0) -= m_bbox.min(0); p1 -= m_bbox.min;
p2(1) -= m_bbox.min(1); p2 -= m_bbox.min;
assert(p1.x() >= 0 && p1.x() < m_cols * m_resolution);
assert(p1.y() >= 0 && p1.y() < m_rows * m_resolution);
assert(p2.x() >= 0 && p2.x() < m_cols * m_resolution);
assert(p2.y() >= 0 && p2.y() < m_rows * m_resolution);
// Get the cells of the end points. // Get the cells of the end points.
coord_t ix = p1(0) / m_resolution; coord_t ix = p1(0) / m_resolution;
coord_t iy = p1(1) / m_resolution; coord_t iy = p1(1) / m_resolution;
@ -115,18 +119,22 @@ public:
ey -= ex; ey -= ex;
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ix += 1; ix += 1;
assert(ix <= ixb);
} }
else if (ex == ey) { else if (ex == ey) {
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
ix += 1; ix += 1;
iy += 1; iy += 1;
assert(ix <= ixb);
assert(iy <= iyb);
} }
else { else {
assert(ex > ey); assert(ex > ey);
ex -= ey; ex -= ey;
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
iy += 1; iy += 1;
assert(iy <= iyb);
} }
if (! visitor(iy, ix)) if (! visitor(iy, ix))
return; return;
@ -141,11 +149,13 @@ public:
ey -= ex; ey -= ex;
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ix += 1; ix += 1;
assert(ix <= ixb);
} }
else { else {
ex -= ey; ex -= ey;
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
iy -= 1; iy -= 1;
assert(iy >= iyb);
} }
if (! visitor(iy, ix)) if (! visitor(iy, ix))
return; return;
@ -163,12 +173,14 @@ public:
ey -= ex; ey -= ex;
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ix -= 1; ix -= 1;
assert(ix >= ixb);
} }
else { else {
assert(ex >= ey); assert(ex >= ey);
ex -= ey; ex -= ey;
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
iy += 1; iy += 1;
assert(iy <= iyb);
} }
if (! visitor(iy, ix)) if (! visitor(iy, ix))
return; return;
@ -183,6 +195,7 @@ public:
ey -= ex; ey -= ex;
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ix -= 1; ix -= 1;
assert(ix >= ixb);
} }
else if (ex == ey) { else if (ex == ey) {
// The lower edge of a grid cell belongs to the cell. // The lower edge of a grid cell belongs to the cell.
@ -191,10 +204,12 @@ public:
if (dx > 0) { if (dx > 0) {
ex = int64_t(dy) * m_resolution; ex = int64_t(dy) * m_resolution;
ix -= 1; ix -= 1;
assert(ix >= ixb);
} }
if (dy > 0) { if (dy > 0) {
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
iy -= 1; iy -= 1;
assert(iy >= iyb);
} }
} }
else { else {
@ -202,6 +217,7 @@ public:
ex -= ey; ex -= ey;
ey = int64_t(dx) * m_resolution; ey = int64_t(dx) * m_resolution;
iy -= 1; iy -= 1;
assert(iy >= iyb);
} }
if (! visitor(iy, ix)) if (! visitor(iy, ix))
return; return;

View file

@ -841,7 +841,7 @@ void mark_boundary_segments_touching_infill(
EdgeGrid::Grid grid; EdgeGrid::Grid grid;
// Make sure that the the grid is big enough for queries against the thick segment. // Make sure that the the grid is big enough for queries against the thick segment.
grid.set_bbox(boundary_bbox.inflated(distance_colliding + SCALED_EPSILON)); grid.set_bbox(boundary_bbox.inflated(distance_colliding * 1.43));
// Inflate the bounding box by a thick line width. // Inflate the bounding box by a thick line width.
grid.create(boundary, std::max(clip_distance, distance_colliding) + scale_(10.)); grid.create(boundary, std::max(clip_distance, distance_colliding) + scale_(10.));
@ -961,9 +961,6 @@ void mark_boundary_segments_touching_infill(
#endif // INFILL_DEBUG_OUTPUT #endif // INFILL_DEBUG_OUTPUT
} visitor(grid, boundary, boundary_parameters, boundary_intersections, distance_colliding); } visitor(grid, boundary, boundary_parameters, boundary_intersections, distance_colliding);
BoundingBoxf bboxf(boundary_bbox.min.cast<double>(), boundary_bbox.max.cast<double>());
bboxf.offset(- SCALED_EPSILON);
for (const Polyline &polyline : infill) { for (const Polyline &polyline : infill) {
#ifdef INFILL_DEBUG_OUTPUT #ifdef INFILL_DEBUG_OUTPUT
++ iStep; ++ iStep;
@ -1019,12 +1016,14 @@ void mark_boundary_segments_touching_infill(
Vec2d vperp = perp(v); Vec2d vperp = perp(v);
Vec2d a = pt1 - v - vperp; Vec2d a = pt1 - v - vperp;
Vec2d b = pt2 + v - vperp; Vec2d b = pt2 + v - vperp;
if (Geometry::liang_barsky_line_clipping(a, b, bboxf)) assert(grid.bbox().contains(a.cast<coord_t>()));
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor); assert(grid.bbox().contains(b.cast<coord_t>()));
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
a = pt1 - v + vperp; a = pt1 - v + vperp;
b = pt2 + v + vperp; b = pt2 + v + vperp;
if (Geometry::liang_barsky_line_clipping(a, b, bboxf)) assert(grid.bbox().contains(a.cast<coord_t>()));
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor); assert(grid.bbox().contains(b.cast<coord_t>()));
grid.visit_cells_intersecting_line(a.cast<coord_t>(), b.cast<coord_t>(), visitor);
#endif #endif
#ifdef INFILL_DEBUG_OUTPUT #ifdef INFILL_DEBUG_OUTPUT
// export_infill_to_svg(boundary, boundary_parameters, boundary_intersections, infill, distance_colliding * 2, debug_out_path("%s-%03d-%03d-%03d.svg", "FillBase-mark_boundary_segments_touching_infill-step", iRun, iStep, int(point_idx)), { polyline }); // export_infill_to_svg(boundary, boundary_parameters, boundary_intersections, infill, distance_colliding * 2, debug_out_path("%s-%03d-%03d-%03d.svg", "FillBase-mark_boundary_segments_touching_infill-step", iRun, iStep, int(point_idx)), { polyline });