Improved slicing of objects with cracks and gaps.

This commit is contained in:
bubnikv 2018-10-04 15:29:55 +02:00
parent 79bbe7bec9
commit abd22b31c9
2 changed files with 62 additions and 7 deletions

View File

@ -177,7 +177,7 @@ public:
}
}
}
return (value_min != nullptr && dist_min < coordf_t(m_search_radius * m_search_radius)) ?
return (value_min != nullptr && dist_min < coordf_t(m_search_radius) * coordf_t(m_search_radius)) ?
std::make_pair(value_min, dist_min) :
std::make_pair(nullptr, std::numeric_limits<double>::max());
}

View File

@ -1245,6 +1245,21 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
// only the bottom triangle is considered to be cutting the plane.
// remove_tangent_edges(lines);
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
BoundingBox bbox_svg;
{
static int iRun = 0;
for (const Line &line : lines) {
bbox_svg.merge(line.a);
bbox_svg.merge(line.b);
}
SVG svg(debug_out_path("TriangleMeshSlicer_make_loops-raw_lines-%d.svg", iRun ++).c_str(), bbox_svg);
for (const Line &line : lines)
svg.draw(line);
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
struct OpenPolyline {
OpenPolyline() {};
OpenPolyline(const IntersectionReference &start, const IntersectionReference &end, Points &&points) :
@ -1359,6 +1374,17 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
}
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
SVG svg(debug_out_path("TriangleMeshSlicer_make_loops-polylines-%d.svg", iRun ++).c_str(), bbox_svg);
svg.draw(union_ex(*loops));
for (const OpenPolyline &pl : open_polylines)
svg.draw(Polyline(pl.points), "red");
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// Now process the open polylines.
// Do it in two rounds, first try to connect in the same direction only,
// then try to connect the open polylines in reversed order as well.
@ -1476,6 +1502,22 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
}
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
SVG svg(debug_out_path("TriangleMeshSlicer_make_loops-polylines2-%d.svg", iRun++).c_str(), bbox_svg);
svg.draw(union_ex(*loops));
for (const OpenPolyline &pl : open_polylines) {
if (pl.points.empty())
continue;
svg.draw(Polyline(pl.points), "red");
svg.draw(pl.points.front(), "blue");
svg.draw(pl.points.back(), "blue");
}
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// Try to close gaps.
// Do it in two rounds, first try to connect in the same direction only,
// then try to connect the open polylines in reversed order as well.
@ -1506,22 +1548,23 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
continue;
opl.consumed = true;
OpenPolylineEnd end(&opl, false);
size_t n_segments_joined = 1;
for (;;) {
// Find a line starting where last one finishes, only return non-consumed open polylines (OpenPolylineEndAccessor returns null for consumed).
std::pair<const OpenPolylineEnd*, double> next_start_and_dist = closest_end_point_lookup.find(end.point());
const OpenPolylineEnd *next_start = next_start_and_dist.first;
if (next_start == nullptr) {
// Check whether we closed this loop.
double dist = opl.points.front().distance_to(opl.points.back());
if (dist < max_gap_scaled) {
if (dist == 0.) {
// Check whether we closed this loop.
double current_loop_closing_distance2 = opl.points.front().distance_to_sq(opl.points.back());
if (next_start == nullptr || current_loop_closing_distance2 < next_start_and_dist.second) {
if (current_loop_closing_distance2 < coordf_t(max_gap_scaled) * coordf_t(max_gap_scaled)) {
if (current_loop_closing_distance2 == 0.) {
// Remove the duplicate last point.
opl.points.pop_back();
} else {
// The end points are different, keep both of them.
}
if (opl.points.size() >= 3) {
if (try_connect_reversed) {
if (try_connect_reversed && n_segments_joined > 1) {
// The closed polygon is patched from pieces with messed up orientation, therefore
// the orientation of the patched up polygon is not known.
// Orient the patched up polygons CCW. This heuristic may close some holes and cavities.
@ -1548,6 +1591,7 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
auto it = next_start->polyline->points.rbegin();
std::copy(++ it, next_start->polyline->points.rend(), back_inserter(opl.points));
}
++ n_segments_joined;
end = *next_start;
end.start = !end.start;
next_start->polyline->points.clear();
@ -1556,6 +1600,17 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
}
}
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
SVG svg(debug_out_path("TriangleMeshSlicer_make_loops-polylines-final-%d.svg", iRun++).c_str(), bbox_svg);
svg.draw(union_ex(*loops));
for (const OpenPolyline &pl : open_polylines)
svg.draw(Polyline(pl.points), "red");
svg.Close();
}
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
}
// Only used to cut the mesh into two halves.