diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index aed71aa723..7023398867 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -361,8 +361,8 @@ static bool verify_traversal_order( c[1] - c[0], c[2] - c[0], c[3] - c[1], c[3] - c[2], c[3] - c[0], c[5] - c[4], c[6] - c[4], c[7] - c[5], c[7] - c[6], c[7] - c[4] }; - assert(std::abs(dirs[4].z()) < 0.001); - assert(std::abs(dirs[9].z()) < 0.001); + assert(std::abs(dirs[4].z()) < 0.005); + assert(std::abs(dirs[9].z()) < 0.005); assert(dirs[0].isApprox(dirs[3])); assert(dirs[1].isApprox(dirs[2])); assert(dirs[5].isApprox(dirs[8])); @@ -413,7 +413,7 @@ static void generate_infill_lines_recursive( Line new_line(Point::new_scale(from), Point::new_scale(to)); if (last_line.a.x() == std::numeric_limits::max()) { last_line.a = new_line.a; - } else if ((new_line.a - last_line.b).cwiseAbs().maxCoeff() > 300) { // SCALED_EPSILON is 100 and it is not enough) { + } else if ((new_line.a - last_line.b).cwiseAbs().maxCoeff() > 300) { // SCALED_EPSILON is 100 and it is not enough context.output_lines.emplace_back(last_line); last_line.a = new_line.a; } @@ -434,64 +434,6 @@ static void generate_infill_lines_recursive( } } -#if 0 -// Collect the line segments. -static Polylines chain_lines(const std::vector &lines, const double point_distance_epsilon) -{ - // Create line end point lookup. - struct LineEnd { - LineEnd(Line *line, bool start) : line(line), start(start) {} - Line *line; - // Is it the start or end point? - bool start; - const Point& point() const { return start ? line->a : line->b; } - const Point& other_point() const { return start ? line->b : line->a; } - LineEnd other_end() const { return LineEnd(line, ! start); } - bool operator==(const LineEnd &rhs) const { return this->line == rhs.line && this->start == rhs.start; } - }; - struct LineEndAccessor { - const Point* operator()(const LineEnd &pt) const { return &pt.point(); } - }; - typedef ClosestPointInRadiusLookup ClosestPointLookupType; - ClosestPointLookupType closest_end_point_lookup(point_distance_epsilon); - for (const Line &line : lines) { - closest_end_point_lookup.insert(LineEnd(&line, true)); - closest_end_point_lookup.insert(LineEnd(&line, false)); - } - - // Chain the lines. - std::vector line_consumed(lines.size(), false); - static const double point_distance_epsilon2 = point_distance_epsilon * point_distance_epsilon; - Polylines out; - for (const Line &seed : lines) - if (! line_consumed[&seed - lines.data()]) { - line_consumed[&seed - lines.data()] = true; - closest_end_point_lookup.erase(LineEnd(&seed, false)); - closest_end_point_lookup.erase(LineEnd(&seed, true)); - Polyline pl { seed.a, seed.b }; - for (size_t round = 0; round < 2; ++ round) { - for (;;) { - auto [line_end, dist2] = closest_end_point_lookup.find(pl.last_point()); - if (line_end == nullptr || dist2 >= point_distance_epsilon2) - // Cannot extent in this direction. - break; - // Average the last point. - pl.points.back() = 0.5 * (pl.points.back() + line_end->point()); - // and extend with the new line segment. - pl.points.emplace_back(line_end->other_point()); - closest_end_point_lookup.erase(line_end); - closest_end_point_lookup.erase(line_end->other_end()); - line_consumed[line_end->line - lines.data()] = true; - } - // reverse and try the oter direction. - pl.reverse(); - } - out.emplace_back(std::move(pl)); - } - return out; -} -#endif - #ifndef NDEBUG // #define ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT #endif @@ -574,10 +516,14 @@ void Filler::_fill_surface_single( if (line.a.x() != std::numeric_limits::max()) lines.emplace_back(line); } +#if 0 + // Chain touching line segments, convert lines to polylines. + //all_polylines = chain_lines(lines, 300.); // SCALED_EPSILON is 100 and it is not enough +#else // Convert lines to polylines. - //FIXME chain the lines all_polylines.reserve(lines.size()); std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; }); +#endif } // Crop all polylines @@ -590,7 +536,7 @@ void Filler::_fill_surface_single( } #endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */ - if (params.dont_connect) + if (params.dont_connect || all_polylines.size() <= 1) append(polylines_out, std::move(all_polylines)); else connect_infill(chain_polylines(std::move(all_polylines)), expolygon, polylines_out, this->spacing, params); diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 314bbf7163..3d5903df13 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -1973,4 +1973,59 @@ std::vector chain_print_object_instances(const Print &prin return out; } +Polylines chain_lines(const std::vector &lines, const double point_distance_epsilon) +{ + // Create line end point lookup. + struct LineEnd { + LineEnd(const Line *line, bool start) : line(line), start(start) {} + const Line *line; + // Is it the start or end point? + bool start; + const Point& point() const { return start ? line->a : line->b; } + const Point& other_point() const { return start ? line->b : line->a; } + LineEnd other_end() const { return LineEnd(line, ! start); } + bool operator==(const LineEnd &rhs) const { return this->line == rhs.line && this->start == rhs.start; } + }; + struct LineEndAccessor { + const Point* operator()(const LineEnd &pt) const { return &pt.point(); } + }; + typedef ClosestPointInRadiusLookup ClosestPointLookupType; + ClosestPointLookupType closest_end_point_lookup(point_distance_epsilon); + for (const Line &line : lines) { + closest_end_point_lookup.insert(LineEnd(&line, true)); + closest_end_point_lookup.insert(LineEnd(&line, false)); + } + + // Chain the lines. + std::vector line_consumed(lines.size(), false); + static const double point_distance_epsilon2 = point_distance_epsilon * point_distance_epsilon; + Polylines out; + for (const Line &seed : lines) + if (! line_consumed[&seed - lines.data()]) { + line_consumed[&seed - lines.data()] = true; + closest_end_point_lookup.erase(LineEnd(&seed, false)); + closest_end_point_lookup.erase(LineEnd(&seed, true)); + Polyline pl { seed.a, seed.b }; + for (size_t round = 0; round < 2; ++ round) { + for (;;) { + auto [line_end, dist2] = closest_end_point_lookup.find(pl.last_point()); + if (line_end == nullptr || dist2 >= point_distance_epsilon2) + // Cannot extent in this direction. + break; + // Average the last point. + pl.points.back() = (0.5 * (pl.points.back().cast() + line_end->point().cast())).cast(); + // and extend with the new line segment. + pl.points.emplace_back(line_end->other_point()); + closest_end_point_lookup.erase(*line_end); + closest_end_point_lookup.erase(line_end->other_end()); + line_consumed[line_end->line - lines.data()] = true; + } + // reverse and try the oter direction. + pl.reverse(); + } + out.emplace_back(std::move(pl)); + } + return out; +} + } // namespace Slic3r diff --git a/src/libslic3r/ShortestPath.hpp b/src/libslic3r/ShortestPath.hpp index 65d8b7f239..14912ee857 100644 --- a/src/libslic3r/ShortestPath.hpp +++ b/src/libslic3r/ShortestPath.hpp @@ -33,6 +33,8 @@ class Print; struct PrintInstance; std::vector chain_print_object_instances(const Print &print); +// Chain lines into polylines. +Polylines chain_lines(const std::vector &lines, const double point_distance_epsilon); } // namespace Slic3r