From e1cfd111004babbf160ac8e54edeb61f9d48bc68 Mon Sep 17 00:00:00 2001 From: Jianjia Date: Thu, 13 Apr 2023 10:27:40 +0800 Subject: [PATCH] ENH: increase grid infill's strength Previously grid infill may be cut, so the strength on one direction is too weak. Now we switch the order at neighboring layers, so the strength of both directions are good enough. Change-Id: I0ba768eeee34ce430e43ea57d8f06c209d469d39 --- src/libslic3r/ExtrusionEntity.hpp | 82 ++++++++++++++++++--- src/libslic3r/ExtrusionEntityCollection.hpp | 24 +++++- src/libslic3r/Fill/Fill.cpp | 3 +- src/libslic3r/Fill/FillBase.cpp | 5 ++ src/libslic3r/Fill/FillBase.hpp | 1 + src/libslic3r/Fill/FillRectilinear.cpp | 4 + src/libslic3r/GCode.cpp | 4 +- 7 files changed, 105 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 40ee73672..34ee42304 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -92,6 +92,8 @@ public: virtual bool is_collection() const { return false; } virtual bool is_loop() const { return false; } virtual bool can_reverse() const { return true; } + virtual bool can_sort() const { return true; }//BBS: only used in ExtrusionEntityCollection + virtual void set_reverse() {} virtual ExtrusionEntity* clone() const = 0; // Create a new object, initialize it with this object using the move semantics. virtual ExtrusionEntity* clone_move() = 0; @@ -142,12 +144,53 @@ public: ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role), m_no_extrusion(false) {} ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height, bool no_extrusion = false) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role), m_no_extrusion(no_extrusion) {} ExtrusionPath(int overhang_degree, int curve_degree, ExtrusionRole role, double mm3_per_mm, float width, float height) : overhang_degree(overhang_degree), curve_degree(curve_degree), mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {} - ExtrusionPath(const ExtrusionPath& rhs) : polyline(rhs.polyline), overhang_degree(rhs.overhang_degree), curve_degree(rhs.curve_degree), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role), m_no_extrusion(rhs.m_no_extrusion) {} - ExtrusionPath(ExtrusionPath&& rhs) : polyline(std::move(rhs.polyline)), overhang_degree(rhs.overhang_degree), curve_degree(rhs.curve_degree), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role), m_no_extrusion(rhs.m_no_extrusion) {} - ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) : polyline(polyline), overhang_degree(rhs.overhang_degree), curve_degree(rhs.curve_degree), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role), m_no_extrusion(rhs.m_no_extrusion) {} - ExtrusionPath(Polyline &&polyline, const ExtrusionPath &rhs) : polyline(std::move(polyline)), overhang_degree(rhs.overhang_degree), curve_degree(rhs.curve_degree), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role), m_no_extrusion(rhs.m_no_extrusion) {} + ExtrusionPath(const ExtrusionPath &rhs) + : polyline(rhs.polyline) + , overhang_degree(rhs.overhang_degree) + , curve_degree(rhs.curve_degree) + , mm3_per_mm(rhs.mm3_per_mm) + , width(rhs.width) + , height(rhs.height) + , m_can_reverse(rhs.m_can_reverse) + , m_role(rhs.m_role) + , m_no_extrusion(rhs.m_no_extrusion) + {} + ExtrusionPath(ExtrusionPath &&rhs) + : polyline(std::move(rhs.polyline)) + , overhang_degree(rhs.overhang_degree) + , curve_degree(rhs.curve_degree) + , mm3_per_mm(rhs.mm3_per_mm) + , width(rhs.width) + , height(rhs.height) + , m_can_reverse(rhs.m_can_reverse) + , m_role(rhs.m_role) + , m_no_extrusion(rhs.m_no_extrusion) + {} + ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) + : polyline(polyline) + , overhang_degree(rhs.overhang_degree) + , curve_degree(rhs.curve_degree) + , mm3_per_mm(rhs.mm3_per_mm) + , width(rhs.width) + , height(rhs.height) + , m_can_reverse(rhs.m_can_reverse) + , m_role(rhs.m_role) + , m_no_extrusion(rhs.m_no_extrusion) + {} + ExtrusionPath(Polyline &&polyline, const ExtrusionPath &rhs) + : polyline(std::move(polyline)) + , overhang_degree(rhs.overhang_degree) + , curve_degree(rhs.curve_degree) + , mm3_per_mm(rhs.mm3_per_mm) + , width(rhs.width) + , height(rhs.height) + , m_can_reverse(rhs.m_can_reverse) + , m_role(rhs.m_role) + , m_no_extrusion(rhs.m_no_extrusion) + {} ExtrusionPath& operator=(const ExtrusionPath& rhs) { + m_can_reverse = rhs.m_can_reverse; m_role = rhs.m_role; m_no_extrusion = rhs.m_no_extrusion; this->mm3_per_mm = rhs.mm3_per_mm; @@ -159,6 +202,7 @@ public: return *this; } ExtrusionPath& operator=(ExtrusionPath&& rhs) { + m_can_reverse = rhs.m_can_reverse; m_role = rhs.m_role; m_no_extrusion = rhs.m_no_extrusion; this->mm3_per_mm = rhs.mm3_per_mm; @@ -229,10 +273,12 @@ public: bool is_force_no_extrusion() const { return m_no_extrusion; } void set_force_no_extrusion(bool no_extrusion) { m_no_extrusion = no_extrusion; } void set_extrusion_role(ExtrusionRole extrusion_role) { m_role = extrusion_role; } + void set_reverse() override { m_can_reverse = false; } + bool can_reverse() const override { return m_can_reverse; } private: void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const; - + bool m_can_reverse = true; ExtrusionRole m_role; //BBS bool m_no_extrusion = false; @@ -247,16 +293,27 @@ public: ExtrusionPaths paths; ExtrusionMultiPath() {} - ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(rhs.paths) {} - ExtrusionMultiPath(ExtrusionMultiPath &&rhs) : paths(std::move(rhs.paths)) {} + ExtrusionMultiPath(const ExtrusionMultiPath &rhs) : paths(rhs.paths), m_can_reverse(rhs.m_can_reverse) {} + ExtrusionMultiPath(ExtrusionMultiPath &&rhs) : paths(std::move(rhs.paths)), m_can_reverse(rhs.m_can_reverse) {} ExtrusionMultiPath(const ExtrusionPaths &paths) : paths(paths) {} - ExtrusionMultiPath(const ExtrusionPath &path) { this->paths.push_back(path); } + ExtrusionMultiPath(const ExtrusionPath &path) {this->paths.push_back(path); m_can_reverse = path.can_reverse(); } - ExtrusionMultiPath& operator=(const ExtrusionMultiPath &rhs) { this->paths = rhs.paths; return *this; } - ExtrusionMultiPath& operator=(ExtrusionMultiPath &&rhs) { this->paths = std::move(rhs.paths); return *this; } + ExtrusionMultiPath &operator=(const ExtrusionMultiPath &rhs) + { + this->paths = rhs.paths; + m_can_reverse = rhs.m_can_reverse; + return *this; + } + ExtrusionMultiPath &operator=(ExtrusionMultiPath &&rhs) + { + this->paths = std::move(rhs.paths); + m_can_reverse = rhs.m_can_reverse; + return *this; + } bool is_loop() const override { return false; } - bool can_reverse() const override { return true; } + bool can_reverse() const override { return m_can_reverse; } + void set_reverse() override { m_can_reverse = false; } ExtrusionEntity* clone() const override { return new ExtrusionMultiPath(*this); } // Create a new object, initialize it with this object using the move semantics. ExtrusionEntity* clone_move() override { return new ExtrusionMultiPath(std::move(*this)); } @@ -289,6 +346,9 @@ public: append(dst, p.polyline.points); } double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; } + +private: + bool m_can_reverse = true; }; // Single continuous extrusion loop, possibly with varying extrusion thickness, extrusion height or bridging / non bridging. diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp index 6e62a45fd..413834db2 100644 --- a/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/src/libslic3r/ExtrusionEntityCollection.hpp @@ -32,12 +32,17 @@ public: ExtrusionEntitiesPtr entities; // we own these entities bool no_sort; ExtrusionEntityCollection(): no_sort(false) {} - ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort) { this->append(other.entities); } - ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort) {} + ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort), is_reverse(other.is_reverse) { this->append(other.entities); } + ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort), is_reverse(other.is_reverse) {} explicit ExtrusionEntityCollection(const ExtrusionPaths &paths); ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other); ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other) - { this->entities = std::move(other.entities); this->no_sort = other.no_sort; return *this; } + { + this->entities = std::move(other.entities); + this->no_sort = other.no_sort; + is_reverse = other.is_reverse; + return *this; + } ~ExtrusionEntityCollection() { clear(); } explicit operator ExtrusionPaths() const; @@ -50,7 +55,15 @@ public: } return out; } - bool can_reverse() const override { return !this->no_sort; } + bool can_sort() const override { return !this->no_sort; } + bool can_reverse() const override + { + if (this->no_sort) + return false; + else + return is_reverse; + } + void set_reverse() override { is_reverse = false; } bool empty() const { return this->entities.empty(); } void clear(); void swap (ExtrusionEntityCollection &c); @@ -126,6 +139,9 @@ public: throw Slic3r::RuntimeError("Calling length() on a ExtrusionEntityCollection"); return 0.; } + +private: + bool is_reverse{true}; }; } // namespace Slic3r diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index f1af208ea..6650c4cb2 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -476,7 +476,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.using_internal_flow = using_internal_flow; params.no_extrusion_overlap = surface_fill.params.overlap; params.with_loop = surface_fill.params.with_loop; - + if (surface_fill.params.pattern == ipGrid) + params.can_reverse = false; LayerRegion* layerm = this->m_regions[surface_fill.region_id]; for (ExPolygon& expoly : surface_fill.expolygons) { f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index acbf8f028..baa426c49 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -187,6 +187,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para out.push_back(eec = new ExtrusionEntityCollection()); // Only concentric fills are not sorted. eec->no_sort = this->no_sort(); + size_t idx = eec->entities.size(); if (params.use_arachne) { Flow new_flow = params.flow.with_spacing(float(this->spacing)); variable_width(thick_polylines, params.extrusion_role, new_flow, eec->entities); @@ -198,6 +199,10 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para params.extrusion_role, flow_mm3_per_mm, float(flow_width), params.flow.height()); } + if (!params.can_reverse) { + for (size_t i = idx; i < eec->entities.size(); i++) + eec->entities[i]->set_reverse(); + } } } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index 5d0cbc2ad..4ddfbaf5e 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -77,6 +77,7 @@ struct FillParams //BBS: only used for new top surface pattern float no_extrusion_overlap{ 0.0 }; bool dont_sort{ false }; // do not sort the lines, just simply connect them + bool can_reverse{true}; }; static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index e0ac77e47..1b5132481 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2994,6 +2994,10 @@ Polylines FillGrid::fill_surface(const Surface *surface, const FillParams ¶m { { 0.f, 0.f }, { float(M_PI / 2.), 0.f } }, polylines_out)) BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface() failed to fill a region."; + + if (this->layer_id % 2 == 1) + for (int i = 0; i < polylines_out.size(); i++) + std::reverse(polylines_out[i].begin(), polylines_out[i].end()); return polylines_out; } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7b6deb7ab..26303e4a3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4436,9 +4436,9 @@ void GCode::ObjectByExtruder::Island::Region::append(const Type type, const Extr // First we append the entities, there are eec->entities.size() of them: size_t old_size = perimeters_or_infills->size(); - size_t new_size = old_size + (eec->can_reverse() ? eec->entities.size() : 1); + size_t new_size = old_size + (eec->can_sort() ? eec->entities.size() : 1); perimeters_or_infills->reserve(new_size); - if (eec->can_reverse()) { + if (eec->can_sort()) { for (auto* ee : eec->entities) perimeters_or_infills->emplace_back(ee); } else