Make FillRectilinear more tolerant with degenerate polygons. #2941

This commit is contained in:
Alessandro Ranellucci 2017-04-04 15:35:31 +02:00
parent 557f1e234d
commit 99c86bcf91

View File

@ -340,7 +340,12 @@ FillRectilinear::_fill_single_direction(ExPolygon expolygon,
// Get the first lower point. // Get the first lower point.
vertical_t::iterator it = v.begin(); // minimum x,y vertical_t::iterator it = v.begin(); // minimum x,y
IntersectionPoint p = it->second; IntersectionPoint p = it->second;
assert(p.type == IntersectionPoint::ipTypeLower); if (p.type != IntersectionPoint::ipTypeLower) {
// Degenerate polygon, this shouldn't happen.
// We used to have an assert here, but let's be tolerant.
grid.erase(p.x);
continue;
}
// Start our polyline. // Start our polyline.
Polyline polyline; Polyline polyline;
@ -351,17 +356,32 @@ FillRectilinear::_fill_single_direction(ExPolygon expolygon,
// Complete the vertical line by finding the corresponding upper or lower point. // Complete the vertical line by finding the corresponding upper or lower point.
if (p.type == IntersectionPoint::ipTypeUpper) { if (p.type == IntersectionPoint::ipTypeUpper) {
// find first point along c.x with y < c.y // find first point along c.x with y < c.y
assert(it != grid[p.x].begin()); if (it == grid[p.x].begin()) {
// Degenerate polygon, this shouldn't happen.
// We used to have an assert here, but let's be tolerant.
grid.erase(p.x);
break;
}
--it; --it;
} else { } else {
// find first point along c.x with y > c.y // find first point along c.x with y > c.y
++it; ++it;
assert(it != grid[p.x].end()); if (it == grid[p.x].end()) {
// Degenerate polygon, this shouldn't happen.
// We used to have an assert here, but let's be tolerant.
grid.erase(p.x);
break;
}
} }
// Append the point to our polyline. // Append the point to our polyline.
IntersectionPoint b = it->second; IntersectionPoint b = it->second;
assert(b.type != p.type); if (b.type == p.type) {
// Degenerate polygon, this shouldn't happen.
// We used to have an assert here, but let's be tolerant.
grid.erase(p.x);
break;
}
polyline.append(b); polyline.append(b);
polyline.points.back().y += this->endpoints_overlap * (b.type == IntersectionPoint::ipTypeUpper ? 1 : -1); polyline.points.back().y += this->endpoints_overlap * (b.type == IntersectionPoint::ipTypeUpper ? 1 : -1);
@ -409,8 +429,12 @@ FillRectilinear::_fill_single_direction(ExPolygon expolygon,
// If the connection brought us to another x coordinate, we expect the point // If the connection brought us to another x coordinate, we expect the point
// type to be the same. // type to be the same.
assert((p.type == b.type && p.x > b.x) if (!(p.type == b.type && p.x > b.x) && !(p.type != b.type && p.x == b.x)) {
|| (p.type != b.type && p.x == b.x)); // Degenerate polygon, this shouldn't happen.
// We used to have an assert here, but let's be tolerant.
grid.erase(p.x);
break;
}
} }
// Yay, we have a polyline! // Yay, we have a polyline!