diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp index 7eefdcdb3..d478ce659 100644 --- a/xs/src/libslic3r/ExtrusionEntity.hpp +++ b/xs/src/libslic3r/ExtrusionEntity.hpp @@ -303,6 +303,18 @@ inline void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines polylines.clear(); } +inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &loops, ExtrusionRole role, double mm3_per_mm, float width, float height) { + dst.reserve(dst.size() + loops.size()); + for (Polygon &poly : loops) { + if (poly.is_valid()) { + ExtrusionPath path(role, mm3_per_mm, width, height); + path.polyline.points = poly.points; + path.polyline.points.push_back(path.polyline.points.front()); + dst.emplace_back(new ExtrusionLoop(std::move(path))); + } + } +} + inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons &&loops, ExtrusionRole role, double mm3_per_mm, float width, float height) { dst.reserve(dst.size() + loops.size()); diff --git a/xs/src/libslic3r/Fill/FillBase.cpp b/xs/src/libslic3r/Fill/FillBase.cpp index e1eae0244..7fa0cb215 100644 --- a/xs/src/libslic3r/Fill/FillBase.cpp +++ b/xs/src/libslic3r/Fill/FillBase.cpp @@ -22,6 +22,7 @@ Fill* Fill::new_from_type(const InfillPattern type) { switch (type) { case ipConcentric: return new FillConcentric(); + case ipConcentricGapFill: return new FillConcentricWGapFill(); case ipHoneycomb: return new FillHoneycomb(); case ip3DHoneycomb: return new Fill3DHoneycomb(); case ipGyroid: return new FillGyroid(); diff --git a/xs/src/libslic3r/Fill/FillConcentric.cpp b/xs/src/libslic3r/Fill/FillConcentric.cpp index b21ad2799..c6e362ff6 100644 --- a/xs/src/libslic3r/Fill/FillConcentric.cpp +++ b/xs/src/libslic3r/Fill/FillConcentric.cpp @@ -1,10 +1,13 @@ #include "../ClipperUtils.hpp" #include "../ExPolygon.hpp" #include "../Surface.hpp" +#include "../ExtrusionEntityCollection.hpp" +#include "../MedialAxis.hpp" #include "FillConcentric.hpp" namespace Slic3r { + void FillConcentric::_fill_surface_single( const FillParams ¶ms, @@ -61,4 +64,98 @@ void FillConcentric::_fill_surface_single( // We want the loops to be split inside the G-code generator to get optimum path planning. } +void FillConcentricWGapFill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out) { + + // Perform offset. + Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(0 - 0.5 * this->spacing))); + // Create the infills for each of the regions. + Polylines polylines_out; + for (size_t i = 0; i < expp.size(); ++i) { + //_fill_surface_single( + //params, + //surface->thickness_layers, + //_infill_direction(surface), + //expp[i], + //polylines_out); + ExPolygon expolygon = expp[i]; + + coordf_t init_spacing = this->spacing; + + // no rotation is supported for this infill pattern + BoundingBox bounding_box = expolygon.contour.bounding_box(); + + coord_t min_spacing = scale_(this->spacing); + coord_t distance = coord_t(min_spacing / params.density); + + if (params.density > 0.9999f && !params.dont_adjust) { + distance = this->_adjust_solid_spacing(bounding_box.size().x, distance); + this->spacing = unscale(distance); + } + + ExPolygons gaps; + Polygons loops = (Polygons)expolygon; + Polygons last = loops; + while (!last.empty()) { + Polygons next_onion = offset2(last, -(distance + min_spacing / 2), +min_spacing / 2); + loops.insert(loops.end(), next_onion.begin(), next_onion.end()); + append(gaps, diff_ex( + offset(last, -0.5f * distance), + offset(next_onion, 0.5f * distance + 10))); // safety offset + last = next_onion; + } + + // generate paths from the outermost to the innermost, to avoid + // adhesion problems of the first central tiny loops + //note: useless if we don't apply no_sort flag + //loops = union_pt_chained(loops, false); + + + //get the role + ExtrusionRole good_role = role; + if (good_role == erNone || good_role == erCustom) { + good_role = (flow.bridge ? erBridgeInfill : + (surface->is_solid() ? + ((surface->is_top()) ? erTopSolidInfill : erSolidInfill) : + erInternalInfill)); + } + + ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection(); + coll_nosort->no_sort = true; //can be sorted inside the pass + extrusion_entities_append_loops( + coll_nosort->entities, loops, + good_role, + flow.mm3_per_mm() * params.flow_mult, + flow.width * params.flow_mult, + flow.height); + + //add gapfills + if (!gaps.empty() && params.density >= 1) { + // collapse + double min = 0.2 * distance * (1 - INSET_OVERLAP_TOLERANCE); + double max = 2. * distance; + ExPolygons gaps_ex = diff_ex( + offset2_ex(gaps, -min / 2, +min / 2), + offset2_ex(gaps, -max / 2, +max / 2), + true); + ThickPolylines polylines; + for (const ExPolygon &ex : gaps_ex) { + //remove too small gaps that are too hard to fill. + //ie one that are smaller than an extrusion with width of min and a length of max. + if (ex.area() > min*max) { + ex.medial_axis(ex, max, min, &polylines, flow.height); + } + } + if (!polylines.empty()) { + ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, flow); + coll_nosort->append(gap_fill.entities); + } + } + + if (!coll_nosort->entities.empty()) + out.push_back(coll_nosort); + else delete coll_nosort; + } +} + } // namespace Slic3r diff --git a/xs/src/libslic3r/Fill/FillConcentric.hpp b/xs/src/libslic3r/Fill/FillConcentric.hpp index 1286858ea..918a370a7 100644 --- a/xs/src/libslic3r/Fill/FillConcentric.hpp +++ b/xs/src/libslic3r/Fill/FillConcentric.hpp @@ -12,16 +12,29 @@ public: protected: virtual Fill* clone() const { return new FillConcentric(*this); }; - virtual void _fill_surface_single( - const FillParams ¶ms, - unsigned int thickness_layers, - const std::pair &direction, - ExPolygon &expolygon, - Polylines &polylines_out); + virtual void _fill_surface_single( + const FillParams ¶ms, + unsigned int thickness_layers, + const std::pair &direction, + ExPolygon &expolygon, + Polylines &polylines_out); virtual bool no_sort() const { return true; } }; + +class FillConcentricWGapFill : public Fill { +public: + virtual ~FillConcentricWGapFill() {} + +protected: + virtual Fill* clone() const { return new FillConcentricWGapFill(*this); }; + virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, + const Flow &flow, const ExtrusionRole &role, ExtrusionEntitiesPtr &out); + + virtual bool no_sort() const { return true; } +}; + } // namespace Slic3r #endif // slic3r_FillConcentric_hpp_ diff --git a/xs/src/libslic3r/Fill/FillSmooth.cpp b/xs/src/libslic3r/Fill/FillSmooth.cpp index 7168c5882..3b936a653 100644 --- a/xs/src/libslic3r/Fill/FillSmooth.cpp +++ b/xs/src/libslic3r/Fill/FillSmooth.cpp @@ -269,8 +269,9 @@ namespace Slic3r { } } - if (!eecroot->entities.empty()) + if (!eecroot->entities.empty()) out.push_back(eecroot); + else delete eecroot; } diff --git a/xs/src/libslic3r/MedialAxis.cpp b/xs/src/libslic3r/MedialAxis.cpp index 7be8c0958..64bd1bdf4 100644 --- a/xs/src/libslic3r/MedialAxis.cpp +++ b/xs/src/libslic3r/MedialAxis.cpp @@ -301,13 +301,14 @@ remove_point_too_near(ThickPolyline* to_reduce) to_reduce->points.erase(to_reduce->points.begin() + id); to_reduce->width.erase(to_reduce->width.begin() + id); newdist = to_reduce->points[id].distance_to(to_reduce->points[id - 1]); + //if you removed a point, it check if the next one isn't too near from the previous one. + // if not, it bypass it. + if (newdist > smallest) { + ++id; + } } //go to next one - //if you removed a point, it check if the next one isn't too near from the previous one. - // if not, it byepass it. - if (newdist > smallest) { - ++id; - } + else ++id; } } @@ -620,20 +621,33 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con line.a = *(polyline.points.begin() + first_idx); } // prevent the line from touching on the other side, otherwise intersection() might return that solution - if (polyline.points.size() == 2) line.a = line.midpoint(); + if (polyline.points.size() == 2 && this->expolygon.contains(line.midpoint())) line.a = line.midpoint(); line.extend_end(max_width); Point new_back; if (this->expolygon.contour.has_boundary_point(polyline.points.back())) { new_back = polyline.points.back(); } else { - //TODO: verify also for holes. - (void)this->expolygon.contour.first_intersection(line, &new_back); + bool finded = this->expolygon.contour.first_intersection(line, &new_back); + //verify also for holes. + Point new_back_temp; + for (Polygon hole : this->expolygon.holes) { + if (hole.first_intersection(line, &new_back_temp)) { + if (!finded || line.a.distance_to(new_back_temp) < line.a.distance_to(new_back)) { + finded = true; + new_back = new_back_temp; + } + } + } // safety check if no intersection - if (new_back.x == 0 && new_back.y == 0) { + if (!finded) { if (!this->expolygon.contains(line.b)) { //it's outside!!! - std::cout << "Error, a line is formed that start in a polygon, end outside of it can don't cross it!\n"; + if (!this->expolygon.contains(line.a)) { + std::cout << "Error, a line is formed that start outside a polygon, end outside of it and don't cross it!\n"; + } else { + std::cout << "Error, a line is formed that start in a polygon, end outside of it and don't cross it!\n"; + } } new_back = line.b; } @@ -641,10 +655,19 @@ MedialAxis::extends_line(ThickPolyline& polyline, const ExPolygons& anchors, con polyline.width.push_back(polyline.width.back()); } Point new_bound; - //TODO: verify also for holes. - (void)bounds.contour.first_intersection(line, &new_bound); + bool finded = bounds.contour.first_intersection(line, &new_bound); + //verify also for holes. + Point new_bound_temp; + for (Polygon hole : bounds.holes) { + if (hole.first_intersection(line, &new_bound_temp)) { + if (!finded || line.a.distance_to(new_bound_temp) < line.a.distance_to(new_bound)) { + finded = true; + new_bound = new_bound_temp; + } + } + } // safety check if no intersection - if (new_bound.x == 0 && new_bound.y == 0) { + if (!finded) { if (line.b.coincides_with_epsilon(polyline.points.back())) { return; } @@ -1479,4 +1502,105 @@ MedialAxis::build(ThickPolylines* polylines_out) } +ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) { + // this value determines granularity of adaptive width, as G-code does not allow + // variable extrusion within a single move; this value shall only affect the amount + // of segments, and any pruning shall be performed before we apply this tolerance + const double tolerance = scale_(0.05); + + int id_line = 0; + ExtrusionEntityCollection coll; + for (const ThickPolyline &p : polylines) { + id_line++; + ExtrusionPaths paths; + ExtrusionPath path(role); + ThickLines lines = p.thicklines(); + + for (int i = 0; i < (int)lines.size(); ++i) { + const ThickLine& line = lines[i]; + + const coordf_t line_len = line.length(); + if (line_len < SCALED_EPSILON) continue; + + double thickness_delta = fabs(line.a_width - line.b_width); + if (thickness_delta > tolerance) { + const unsigned short segments = ceil(thickness_delta / tolerance); + const coordf_t seg_len = line_len / segments; + Points pp; + std::vector width; + { + pp.push_back(line.a); + width.push_back(line.a_width); + for (size_t j = 1; j < segments; ++j) { + pp.push_back(line.point_at(j*seg_len)); + + coordf_t w = line.a_width + (j*seg_len) * (line.b_width - line.a_width) / line_len; + width.push_back(w); + width.push_back(w); + } + pp.push_back(line.b); + width.push_back(line.b_width); + + assert(pp.size() == segments + 1); + assert(width.size() == segments * 2); + } + + // delete this line and insert new ones + lines.erase(lines.begin() + i); + for (size_t j = 0; j < segments; ++j) { + ThickLine new_line(pp[j], pp[j + 1]); + new_line.a_width = width[2 * j]; + new_line.b_width = width[2 * j + 1]; + lines.insert(lines.begin() + i + j, new_line); + } + + --i; + continue; + } + + const double w = fmax(line.a_width, line.b_width); + if (path.polyline.points.empty()) { + path.polyline.append(line.a); + path.polyline.append(line.b); + // Convert from spacing to extrusion width based on the extrusion model + // of a square extrusion ended with semi circles. + flow.width = unscale(w) + flow.height * (1. - 0.25 * PI); +#ifdef SLIC3R_DEBUG + printf(" filling %f gap\n", flow.width); +#endif + path.mm3_per_mm = flow.mm3_per_mm(); + path.width = flow.width; + path.height = flow.height; + } else { + thickness_delta = fabs(scale_(flow.width) - w); + if (thickness_delta <= tolerance / 2) { + // the width difference between this line and the current flow width is + // within the accepted tolerance + path.polyline.append(line.b); + } else { + // we need to initialize a new line + paths.emplace_back(std::move(path)); + path = ExtrusionPath(role); + --i; + } + } + } + if (path.polyline.is_valid()) + paths.emplace_back(std::move(path)); + // Append paths to collection. + if (!paths.empty()) { + if (paths.front().first_point().coincides_with(paths.back().last_point())) { + coll.append(ExtrusionLoop(paths)); + } else { + //not a loop : avoid to "sort" it. + ExtrusionEntityCollection unsortable_coll(paths); + unsortable_coll.no_sort = true; + coll.append(unsortable_coll); + } + } + } + + return coll; +} + } // namespace Slic3r diff --git a/xs/src/libslic3r/MedialAxis.hpp b/xs/src/libslic3r/MedialAxis.hpp index 560e2bf03..e4fd8e85d 100644 --- a/xs/src/libslic3r/MedialAxis.hpp +++ b/xs/src/libslic3r/MedialAxis.hpp @@ -5,6 +5,8 @@ #include "ExPolygon.hpp" #include "Polyline.hpp" #include "Geometry.hpp" +#include "ExtrusionEntityCollection.hpp" +#include "Flow.hpp" #include #include "boost/polygon/voronoi.hpp" @@ -58,6 +60,9 @@ namespace Slic3r { void remove_too_short_polylines(ThickPolylines& pp, const coord_t min_size); void ensure_not_overextrude(ThickPolylines& pp); }; + + ExtrusionEntityCollection thin_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow); + } diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp index eeb60773c..7c60b7cff 100644 --- a/xs/src/libslic3r/PerimeterGenerator.cpp +++ b/xs/src/libslic3r/PerimeterGenerator.cpp @@ -282,6 +282,7 @@ void PerimeterGenerator::process() no_thin_zone = diff_ex(last, offset_ex(half_thins, (float)(min_width / 2) - SCALED_EPSILON), true); } // compute a bit of overlap to anchor thin walls inside the print. + ExPolygons thin_zones_extruded; for (ExPolygon &half_thin : half_thins) { //growing back the polygon ExPolygons thin = offset_ex(half_thin, (float)(min_width / 2)); @@ -298,11 +299,13 @@ void PerimeterGenerator::process() // the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop thin[0].medial_axis(bound, ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls, this->layer_height); + thin_zones_extruded.emplace_back(thin[0]); } break; } } } + next_onion = diff_ex(offset_ex(last, -(float)(ext_perimeter_width / 2)), thin_zones_extruded, true); } } else { //FIXME Is this offset correct if the line width of the inner perimeters differs @@ -445,7 +448,7 @@ void PerimeterGenerator::process() // append thin walls if (!thin_walls.empty()) { - ExtrusionEntityCollection tw = this->_variable_width + ExtrusionEntityCollection tw = thin_variable_width (thin_walls, erExternalPerimeter, this->ext_perimeter_flow); entities.append(tw.entities); @@ -485,7 +488,7 @@ void PerimeterGenerator::process() } } if (!polylines.empty()) { - ExtrusionEntityCollection gap_fill = this->_variable_width(polylines, + ExtrusionEntityCollection gap_fill = thin_variable_width(polylines, erGapFill, this->solid_infill_flow); this->gap_fill->append(gap_fill.entities); /* Make sure we don't infill narrow parts that are already gap-filled @@ -605,7 +608,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops( // append thin walls to the nearest-neighbor search (only for first iteration) if (!thin_walls.empty()) { - ExtrusionEntityCollection tw = this->_variable_width + ExtrusionEntityCollection tw = thin_variable_width (thin_walls, erExternalPerimeter, this->ext_perimeter_flow); coll.append(tw.entities); @@ -1219,109 +1222,6 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop, return my_loop; } - -ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const -{ - // this value determines granularity of adaptive width, as G-code does not allow - // variable extrusion within a single move; this value shall only affect the amount - // of segments, and any pruning shall be performed before we apply this tolerance - const double tolerance = scale_(0.05); - - int id_line = 0; - ExtrusionEntityCollection coll; - for (const ThickPolyline &p : polylines) { - id_line++; - ExtrusionPaths paths; - ExtrusionPath path(role); - ThickLines lines = p.thicklines(); - - for (int i = 0; i < (int)lines.size(); ++i) { - const ThickLine& line = lines[i]; - - const coordf_t line_len = line.length(); - if (line_len < SCALED_EPSILON) continue; - - double thickness_delta = fabs(line.a_width - line.b_width); - if (thickness_delta > tolerance) { - const unsigned short segments = ceil(thickness_delta / tolerance); - const coordf_t seg_len = line_len / segments; - Points pp; - std::vector width; - { - pp.push_back(line.a); - width.push_back(line.a_width); - for (size_t j = 1; j < segments; ++j) { - pp.push_back(line.point_at(j*seg_len)); - - coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len; - width.push_back(w); - width.push_back(w); - } - pp.push_back(line.b); - width.push_back(line.b_width); - - assert(pp.size() == segments + 1); - assert(width.size() == segments*2); - } - - // delete this line and insert new ones - lines.erase(lines.begin() + i); - for (size_t j = 0; j < segments; ++j) { - ThickLine new_line(pp[j], pp[j+1]); - new_line.a_width = width[2*j]; - new_line.b_width = width[2*j+1]; - lines.insert(lines.begin() + i + j, new_line); - } - - --i; - continue; - } - - const double w = fmax(line.a_width, line.b_width); - if (path.polyline.points.empty()) { - path.polyline.append(line.a); - path.polyline.append(line.b); - // Convert from spacing to extrusion width based on the extrusion model - // of a square extrusion ended with semi circles. - flow.width = unscale(w) + flow.height * (1. - 0.25 * PI); - #ifdef SLIC3R_DEBUG - printf(" filling %f gap\n", flow.width); - #endif - path.mm3_per_mm = flow.mm3_per_mm(); - path.width = flow.width; - path.height = flow.height; - } else { - thickness_delta = fabs(scale_(flow.width) - w); - if (thickness_delta <= tolerance/2) { - // the width difference between this line and the current flow width is - // within the accepted tolerance - path.polyline.append(line.b); - } else { - // we need to initialize a new line - paths.emplace_back(std::move(path)); - path = ExtrusionPath(role); - --i; - } - } - } - if (path.polyline.is_valid()) - paths.emplace_back(std::move(path)); - // Append paths to collection. - if (!paths.empty()) { - if (paths.front().first_point().coincides_with(paths.back().last_point())) { - coll.append(ExtrusionLoop(paths)); - } else { - //not a loop : avoid to "sort" it. - ExtrusionEntityCollection unsortable_coll(paths); - unsortable_coll.no_sort = true; - coll.append(unsortable_coll); - } - } - } - - return coll; -} - bool PerimeterGeneratorLoop::is_internal_contour() const { // An internal contour is a contour containing no other contours diff --git a/xs/src/libslic3r/PerimeterGenerator.hpp b/xs/src/libslic3r/PerimeterGenerator.hpp index 0aae5bdb1..ecb6aa2ba 100644 --- a/xs/src/libslic3r/PerimeterGenerator.hpp +++ b/xs/src/libslic3r/PerimeterGenerator.hpp @@ -99,13 +99,10 @@ private: double _mm3_per_mm_overhang; Polygons _lower_slices_p; - ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops, - ThickPolylines &thin_walls) const; + ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const; ExtrusionLoop _traverse_and_join_loops(const PerimeterGeneratorLoop &loop, const PerimeterGeneratorLoops &childs, const Point entryPoint) const; ExtrusionLoop _extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entryPoint, const Line &direction = Line(Point(0,0),Point(0,0))) const; PerimeterIntersectionPoint _get_nearest_point(const PerimeterGeneratorLoops &children, ExtrusionLoop &myPolylines, const coord_t dist_cut, const coord_t max_dist) const; - ExtrusionEntityCollection _variable_width - (const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const; }; } diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 66bf3db2a..dfdb4e983 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -316,6 +316,7 @@ PrintConfigDef::PrintConfigDef() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("rectilinear"); def->enum_values.push_back("concentric"); + def->enum_values.push_back("concentricgapfill"); def->enum_values.push_back("hilbertcurve"); def->enum_values.push_back("archimedeanchords"); def->enum_values.push_back("octagramspiral"); @@ -324,10 +325,11 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("smoothhilbert"); def->enum_labels.push_back(L("Rectilinear")); def->enum_labels.push_back(L("Concentric")); + def->enum_labels.push_back(L("Concentric (filled)")); def->enum_labels.push_back(L("Hilbert Curve")); def->enum_labels.push_back(L("Archimedean Chords")); def->enum_labels.push_back(L("Octagram Spiral")); - def->enum_labels.push_back("Ironing"); + def->enum_labels.push_back(L("Ironing")); // solid_fill_pattern is an obsolete equivalent to top_fill_pattern/bottom_fill_pattern. def->aliases = { "solid_fill_pattern" }; def->default_value = new ConfigOptionEnum(ipRectilinear); @@ -340,14 +342,16 @@ PrintConfigDef::PrintConfigDef() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("rectilinear"); def->enum_values.push_back("concentric"); + def->enum_values.push_back("concentricgapfill"); def->enum_values.push_back("hilbertcurve"); def->enum_values.push_back("archimedeanchords"); def->enum_values.push_back("octagramspiral"); - def->enum_labels.push_back("Rectilinear"); - def->enum_labels.push_back("Concentric"); - def->enum_labels.push_back("Hilbert Curve"); - def->enum_labels.push_back("Archimedean Chords"); - def->enum_labels.push_back("Octagram Spiral"); + def->enum_labels.push_back(L("Rectilinear")); + def->enum_labels.push_back(L("Concentric")); + def->enum_labels.push_back(L("Concentric (filled)")); + def->enum_labels.push_back(L("Hilbert Curve")); + def->enum_labels.push_back(L("Archimedean Chords")); + def->enum_labels.push_back(L("Octagram Spiral")); def->default_value = new ConfigOptionEnum(ipRectilinear); def = this->add("enforce_full_fill_volume", coBool); @@ -819,6 +823,7 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("cubic"); def->enum_values.push_back("line"); def->enum_values.push_back("concentric"); + def->enum_values.push_back("concentricgapfill"); def->enum_values.push_back("honeycomb"); def->enum_values.push_back("3dhoneycomb"); def->enum_values.push_back("gyroid"); @@ -832,6 +837,7 @@ PrintConfigDef::PrintConfigDef() def->enum_labels.push_back(L("Cubic")); def->enum_labels.push_back(L("Line")); def->enum_labels.push_back(L("Concentric")); + def->enum_labels.push_back(L("Concentric (filled)")); def->enum_labels.push_back(L("Honeycomb")); def->enum_labels.push_back(L("3D Honeycomb")); def->enum_labels.push_back(L("Gyroid")); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 4dc2d95c8..9884b1c50 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -34,7 +34,7 @@ enum PrintHostType { enum InfillPattern { ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb, ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipSmooth, ipSmoothHilbert, ipSmoothTriple, - ipRectiWithPerimeter, + ipRectiWithPerimeter, ipConcentricGapFill }; enum SupportMaterialPattern { @@ -89,6 +89,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum::get_enu keys_map["cubic"] = ipCubic; keys_map["line"] = ipLine; keys_map["concentric"] = ipConcentric; + keys_map["concentricgapfill"] = ipConcentricGapFill; keys_map["honeycomb"] = ipHoneycomb; keys_map["3dhoneycomb"] = ip3DHoneycomb; keys_map["gyroid"] = ipGyroid; diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp index 404f3e2c9..bbca3eb27 100644 --- a/xs/src/libslic3r/SupportMaterial.cpp +++ b/xs/src/libslic3r/SupportMaterial.cpp @@ -3098,7 +3098,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( size_t idx_layer_top_contact = size_t(-1); size_t idx_layer_intermediate = size_t(-1); size_t idx_layer_inteface = size_t(-1); - std::unique_ptr filler_interface = std::unique_ptr(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear)); + std::unique_ptr filler_interface = std::unique_ptr(Fill::new_from_type(m_slicing_params.soluble_interface ? ipConcentricGapFill : ipRectilinear)); std::unique_ptr filler_support = std::unique_ptr(Fill::new_from_type(infill_pattern)); std::unique_ptr filler_solid = std::unique_ptr(Fill::new_from_type(ipRectiWithPerimeter)); filler_interface->set_bounding_box(bbox_object);