diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp index 8aac6e49c8..144a275059 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp @@ -162,15 +162,13 @@ void Fill3DHoneycomb::_fill_surface_single( pl.translate(bb.min); // clip pattern to boundaries, chain the clipped polylines - Polylines polylines_chained = chain_polylines(intersection_pl(polylines, to_polygons(expolygon))); + polylines = intersection_pl(polylines, to_polygons(expolygon)); // connect lines if needed - if (! polylines_chained.empty()) { - if (params.dont_connect) - append(polylines_out, std::move(polylines_chained)); - else - this->connect_infill(std::move(polylines_chained), expolygon, polylines_out, this->spacing, params); - } + if (params.dont_connect || polylines.size() <= 1) + append(polylines_out, chain_polylines(std::move(polylines))); + else + this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params); } } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index 188deca7c1..a1d592bc3a 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -1333,9 +1333,9 @@ void Filler::_fill_surface_single( #endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */ if (params.dont_connect || all_polylines_with_hooks.size() <= 1) - append(polylines_out, std::move(all_polylines_with_hooks)); + append(polylines_out, chain_polylines(std::move(all_polylines_with_hooks))); else - connect_infill(chain_polylines(std::move(all_polylines_with_hooks)), expolygon, polylines_out, this->spacing, params); + connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->spacing, params); #ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT { diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index 964b87cefc..b0cd507bc0 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -190,11 +190,10 @@ void FillGyroid::_fill_surface_single( polylines.end()); if (! polylines.empty()) { - polylines = chain_polylines(polylines); // connect lines size_t polylines_out_first_idx = polylines_out.size(); if (params.dont_connect) - append(polylines_out, std::move(polylines)); + append(polylines_out, chain_polylines(polylines)); else this->connect_infill(std::move(polylines), expolygon, polylines_out, this->spacing, params); diff --git a/src/libslic3r/Fill/FillHoneycomb.cpp b/src/libslic3r/Fill/FillHoneycomb.cpp index 948af182bb..aa0157fb9a 100644 --- a/src/libslic3r/Fill/FillHoneycomb.cpp +++ b/src/libslic3r/Fill/FillHoneycomb.cpp @@ -18,21 +18,21 @@ void FillHoneycomb::_fill_surface_single( Cache::iterator it_m = this->cache.find(cache_id); if (it_m == this->cache.end()) { it_m = this->cache.insert(it_m, std::pair(cache_id, CacheData())); - CacheData &m = it_m->second; - coord_t min_spacing = scale_(this->spacing); - m.distance = min_spacing / params.density; - m.hex_side = m.distance / (sqrt(3)/2); - m.hex_width = m.distance * 2; // $m->{hex_width} == $m->{hex_side} * sqrt(3); - coord_t hex_height = m.hex_side * 2; - m.pattern_height = hex_height + m.hex_side; - m.y_short = m.distance * sqrt(3)/3; - m.x_offset = min_spacing / 2; - m.y_offset = m.x_offset * sqrt(3)/3; - m.hex_center = Point(m.hex_width/2, m.hex_side); + CacheData &m = it_m->second; + coord_t min_spacing = coord_t(scale_(this->spacing)); + m.distance = coord_t(min_spacing / params.density); + m.hex_side = coord_t(m.distance / (sqrt(3)/2)); + m.hex_width = m.distance * 2; // $m->{hex_width} == $m->{hex_side} * sqrt(3); + coord_t hex_height = m.hex_side * 2; + m.pattern_height = hex_height + m.hex_side; + m.y_short = coord_t(m.distance * sqrt(3)/3); + m.x_offset = min_spacing / 2; + m.y_offset = coord_t(m.x_offset * sqrt(3)/3); + m.hex_center = Point(m.hex_width/2, m.hex_side); } CacheData &m = it_m->second; - Polygons polygons; + Polylines all_polylines; { // adjust actual bounding box to the nearest multiple of our hex pattern // and align it so that it matches across layers @@ -52,7 +52,7 @@ void FillHoneycomb::_fill_surface_single( coord_t x = bounding_box.min(0); while (x <= bounding_box.max(0)) { - Polygon p; + Polyline p; coord_t ax[2] = { x + m.x_offset, x + m.distance - m.x_offset }; for (size_t i = 0; i < 2; ++ i) { std::reverse(p.points.begin(), p.points.end()); // turn first half upside down @@ -69,55 +69,15 @@ void FillHoneycomb::_fill_surface_single( x += m.distance; } p.rotate(-direction.first, m.hex_center); - polygons.push_back(p); + all_polylines.push_back(p); } } - if (params.complete || true) { - // we were requested to complete each loop; - // in this case we don't try to make more continuous paths - Polygons polygons_trimmed = intersection((Polygons)expolygon, polygons); - for (Polygons::iterator it = polygons_trimmed.begin(); it != polygons_trimmed.end(); ++ it) - polylines_out.push_back(it->split_at_first_point()); - } else { - // consider polygons as polylines without re-appending the initial point: - // this cuts the last segment on purpose, so that the jump to the next - // path is more straight - Polylines paths; - { - Polylines p; - for (Polygon &poly : polygons) - p.emplace_back(poly.points); - paths = intersection_pl(p, to_polygons(expolygon)); - } - - // connect paths - if (! paths.empty()) { // prevent calling leftmost_point() on empty collections - Polylines chained = chain_polylines(std::move(paths)); - assert(paths.empty()); - paths.clear(); - for (Polyline &path : chained) { - if (! paths.empty()) { - // distance between first point of this path and last point of last path - double distance = (path.first_point() - paths.back().last_point()).cast().norm(); - if (distance <= m.hex_width) { - paths.back().points.insert(paths.back().points.end(), path.points.begin(), path.points.end()); - continue; - } - } - // Don't connect the paths. - paths.push_back(std::move(path)); - } - } - - // clip paths again to prevent connection segments from crossing the expolygon boundaries - paths = intersection_pl(paths, to_polygons(offset_ex(expolygon, SCALED_EPSILON))); - // Move the polylines to the output, avoid a deep copy. - size_t j = polylines_out.size(); - polylines_out.resize(j + paths.size(), Polyline()); - for (size_t i = 0; i < paths.size(); ++ i) - std::swap(polylines_out[j ++], paths[i]); - } + all_polylines = intersection_pl(std::move(all_polylines), to_polygons(expolygon)); + if (params.dont_connect || all_polylines.size() <= 1) + append(polylines_out, chain_polylines(std::move(all_polylines))); + else + connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params); } } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index 7a322ce991..002fcadc0d 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -1,4 +1,5 @@ #include "../ClipperUtils.hpp" +#include "../ShortestPath.hpp" #include "../Surface.hpp" #include "FillPlanePath.hpp" @@ -23,14 +24,14 @@ void FillPlanePath::_fill_surface_single( Point shift = this->_centered() ? bounding_box.center() : bounding_box.min; - expolygon.translate(-shift(0), -shift(1)); - bounding_box.translate(-shift(0), -shift(1)); + expolygon.translate(-shift.x(), -shift.y()); + bounding_box.translate(-shift.x(), -shift.y()); Pointfs pts = _generate( - coord_t(ceil(coordf_t(bounding_box.min(0)) / distance_between_lines)), - coord_t(ceil(coordf_t(bounding_box.min(1)) / distance_between_lines)), - coord_t(ceil(coordf_t(bounding_box.max(0)) / distance_between_lines)), - coord_t(ceil(coordf_t(bounding_box.max(1)) / distance_between_lines))); + coord_t(ceil(coordf_t(bounding_box.min.x()) / distance_between_lines)), + coord_t(ceil(coordf_t(bounding_box.min.y()) / distance_between_lines)), + coord_t(ceil(coordf_t(bounding_box.max.x()) / distance_between_lines)), + coord_t(ceil(coordf_t(bounding_box.max.y()) / distance_between_lines))); Polylines polylines; if (pts.size() >= 2) { @@ -38,39 +39,24 @@ void FillPlanePath::_fill_surface_single( polylines.push_back(Polyline()); Polyline &polyline = polylines.back(); polyline.points.reserve(pts.size()); - for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it) + for (const Vec2d &pt : pts) polyline.points.push_back(Point( - coord_t(floor((*it)(0) * distance_between_lines + 0.5)), - coord_t(floor((*it)(1) * distance_between_lines + 0.5)))); + coord_t(floor(pt.x() * distance_between_lines + 0.5)), + coord_t(floor(pt.y() * distance_between_lines + 0.5)))); // intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines); - polylines = intersection_pl(polylines, to_polygons(expolygon)); - -/* - if (1) { - require "Slic3r/SVG.pm"; - print "Writing fill.svg\n"; - Slic3r::SVG::output("fill.svg", - no_arrows => 1, - polygons => \@$expolygon, - green_polygons => [ $bounding_box->polygon ], - polylines => [ $polyline ], - red_polylines => \@paths, - ); - } -*/ - + polylines = intersection_pl(std::move(polylines), to_polygons(expolygon)); + Polylines chained; + if (params.dont_connect || params.density > 0.5 || polylines.size() <= 1) + chained = chain_polylines(std::move(polylines)); + else + connect_infill(std::move(polylines), expolygon, chained, this->spacing, params); // paths must be repositioned and rotated back - for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) { - it->translate(shift(0), shift(1)); - it->rotate(direction.first); + for (Polyline &pl : chained) { + pl.translate(shift.x(), shift.y()); + pl.rotate(direction.first); } + append(polylines_out, std::move(chained)); } - - // Move the polylines to the output, avoid a deep copy. - size_t j = polylines_out.size(); - polylines_out.resize(j + polylines.size(), Polyline()); - for (size_t i = 0; i < polylines.size(); ++ i) - std::swap(polylines_out[j ++], polylines[i]); } // Follow an Archimedean spiral, in polar coordinates: r=a+b\theta @@ -85,13 +71,13 @@ Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t m coordf_t r = 1; Pointfs out; //FIXME Vojtech: If used as a solid infill, there is a gap left at the center. - out.push_back(Vec2d(0, 0)); - out.push_back(Vec2d(1, 0)); + out.emplace_back(0, 0); + out.emplace_back(1, 0); while (r < rmax) { // Discretization angle to achieve a discretization error lower than RESOLUTION. theta += 2. * acos(1. - RESOLUTION / r); r = a + b * theta; - out.push_back(Vec2d(r * cos(theta), r * sin(theta))); + out.emplace_back(r * cos(theta), r * sin(theta)); } return out; } @@ -128,15 +114,12 @@ static inline Point hilbert_n_to_xy(const size_t n) ++ ndigits; } } - int state = (ndigits & 1) ? 4 : 0; -// int dirstate = (ndigits & 1) ? 0 : 4; + int state = (ndigits & 1) ? 4 : 0; coord_t x = 0; coord_t y = 0; for (int i = (int)ndigits - 1; i >= 0; -- i) { int digit = (n >> (i * 2)) & 3; state += digit; -// if (digit != 3) -// dirstate = state; // lowest non-3 digit x |= digit_to_x[state] << i; y |= digit_to_y[state] << i; state = next_state[state]; @@ -162,7 +145,7 @@ Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x, line.reserve(sz2); for (size_t i = 0; i < sz2; ++ i) { Point p = hilbert_n_to_xy(i); - line.push_back(Vec2d(p(0) + min_x, p(1) + min_y)); + line.emplace_back(p.x() + min_x, p.y() + min_y); } return line; } @@ -175,27 +158,27 @@ Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_ coordf_t r = 0; coordf_t r_inc = sqrt(2.); Pointfs out; - out.push_back(Vec2d(0, 0)); + out.emplace_back(0., 0.); while (r < rmax) { r += r_inc; coordf_t rx = r / sqrt(2.); coordf_t r2 = r + rx; - out.push_back(Vec2d( r, 0.)); - out.push_back(Vec2d( r2, rx)); - out.push_back(Vec2d( rx, rx)); - out.push_back(Vec2d( rx, r2)); - out.push_back(Vec2d(0., r)); - out.push_back(Vec2d(-rx, r2)); - out.push_back(Vec2d(-rx, rx)); - out.push_back(Vec2d(-r2, rx)); - out.push_back(Vec2d(-r, 0.)); - out.push_back(Vec2d(-r2, -rx)); - out.push_back(Vec2d(-rx, -rx)); - out.push_back(Vec2d(-rx, -r2)); - out.push_back(Vec2d(0., -r)); - out.push_back(Vec2d( rx, -r2)); - out.push_back(Vec2d( rx, -rx)); - out.push_back(Vec2d( r2+r_inc, -rx)); + out.emplace_back( r, 0.); + out.emplace_back( r2, rx); + out.emplace_back( rx, rx); + out.emplace_back( rx, r2); + out.emplace_back( 0., r); + out.emplace_back(-rx, r2); + out.emplace_back(-rx, rx); + out.emplace_back(-r2, rx); + out.emplace_back(- r, 0.); + out.emplace_back(-r2, -rx); + out.emplace_back(-rx, -rx); + out.emplace_back(-rx, -r2); + out.emplace_back( 0., -r); + out.emplace_back( rx, -r2); + out.emplace_back( rx, -rx); + out.emplace_back( r2+r_inc, -rx); } return out; } diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 1669f60d21..a27b857349 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -2324,7 +2324,6 @@ static inline void fill_expolygons_generate_paths( { FillParams fill_params; fill_params.density = density; - fill_params.complete = true; fill_params.dont_adjust = true; for (const ExPolygon &expoly : expolygons) { Surface surface(stInternal, expoly); @@ -2351,7 +2350,6 @@ static inline void fill_expolygons_generate_paths( { FillParams fill_params; fill_params.density = density; - fill_params.complete = true; fill_params.dont_adjust = true; for (ExPolygon &expoly : expolygons) { Surface surface(stInternal, std::move(expoly)); diff --git a/xs/xsp/Filler.xsp b/xs/xsp/Filler.xsp index caeb2af9aa..2ea2b34d5a 100644 --- a/xs/xsp/Filler.xsp +++ b/xs/xsp/Filler.xsp @@ -36,8 +36,6 @@ %code{% THIS->params.density = density; %}; void set_dont_adjust(bool dont_adjust) %code{% THIS->params.dont_adjust = dont_adjust; %}; - void set_complete(bool complete) - %code{% THIS->params.complete = complete; %}; PolylineCollection* _fill_surface(Surface *surface) %code{%