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 987e81ede..c6e362ff6 100644 --- a/xs/src/libslic3r/Fill/FillConcentric.cpp +++ b/xs/src/libslic3r/Fill/FillConcentric.cpp @@ -7,8 +7,64 @@ #include "FillConcentric.hpp" namespace Slic3r { + -void FillConcentric::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, +void FillConcentric::_fill_surface_single( + const FillParams ¶ms, + unsigned int thickness_layers, + const std::pair &direction, + ExPolygon &expolygon, + Polylines &polylines_out) +{ + // 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); + } + + Polygons loops = (Polygons)expolygon; + Polygons last = loops; + while (! last.empty()) { + last = offset2(last, -(distance + min_spacing/2), +min_spacing/2); + loops.insert(loops.end(), last.begin(), last.end()); + } + + // generate paths from the outermost to the innermost, to avoid + // adhesion problems of the first central tiny loops + loops = union_pt_chained(loops, false); + + // split paths using a nearest neighbor search + size_t iPathFirst = polylines_out.size(); + Point last_pos(0, 0); + for (const Polygon &loop : loops) { + polylines_out.push_back(loop.split_at_index(last_pos.nearest_point_index(loop))); + last_pos = polylines_out.back().last_point(); + } + + // clip the paths to prevent the extruder from getting exactly on the first point of the loop + // Keep valid paths only. + size_t j = iPathFirst; + for (size_t i = iPathFirst; i < polylines_out.size(); ++ i) { + polylines_out[i].clip_end(this->loop_clipping); + if (polylines_out[i].is_valid()) { + if (j < i) + polylines_out[j] = std::move(polylines_out[i]); + ++ j; + } + } + if (j < polylines_out.size()) + polylines_out.erase(polylines_out.begin() + j, polylines_out.end()); + //TODO: return ExtrusionLoop objects to get better chained paths, + // otherwise the outermost loop starts at the closest point to (0, 0). + // 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. diff --git a/xs/src/libslic3r/Fill/FillConcentric.hpp b/xs/src/libslic3r/Fill/FillConcentric.hpp index d4523e176..918a370a7 100644 --- a/xs/src/libslic3r/Fill/FillConcentric.hpp +++ b/xs/src/libslic3r/Fill/FillConcentric.hpp @@ -12,10 +12,27 @@ 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 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; } + virtual bool no_sort() const { return true; } }; } // namespace Slic3r diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 08748e88f..f17b4c67f 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,12 +325,13 @@ 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("Ironing (triple)"); - def->enum_labels.push_back("Ironing (hilbert)"); + def->enum_labels.push_back(L("Ironing")); + def->enum_labels.push_back(L("Ironing (triple)")); + def->enum_labels.push_back(L("Ironing (hilbert)")); // 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); @@ -342,14 +344,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); @@ -790,6 +794,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"); @@ -803,6 +808,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 f2be5e1c7..5e066ee61 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);