From 9038dc21e85d1aa956fcb0429659884d028dee66 Mon Sep 17 00:00:00 2001 From: bubnikv <bubnikv@gmail.com> Date: Fri, 10 Jan 2020 15:51:35 +0100 Subject: [PATCH] Fixing regression issue after G-code export refactoring. --- src/libslic3r/ExtrusionEntityCollection.cpp | 39 ++++++++++++++------- src/libslic3r/ExtrusionEntityCollection.hpp | 19 ++++++++-- src/libslic3r/GCode.cpp | 6 ++-- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/ExtrusionEntityCollection.cpp b/src/libslic3r/ExtrusionEntityCollection.cpp index 7e0e1fc9c..147a60d95 100644 --- a/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/src/libslic3r/ExtrusionEntityCollection.cpp @@ -6,6 +6,26 @@ namespace Slic3r { +void filter_by_extrusion_role_in_place(ExtrusionEntitiesPtr &extrusion_entities, ExtrusionRole role) +{ + if (role != erMixed) { + auto first = extrusion_entities.begin(); + auto last = extrusion_entities.end(); + auto result = first; + while (first != last) { + // The caller wants only paths with a specific extrusion role. + auto role2 = (*first)->role(); + if (role != role2) { + // This extrusion entity does not match the role asked. + assert(role2 != erMixed); + *result = *first; + ++ result; + } + ++ first; + } + } +} + ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionPaths &paths) : no_sort(false) { @@ -76,19 +96,12 @@ void ExtrusionEntityCollection::remove(size_t i) ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const ExtrusionEntitiesPtr& extrusion_entities, const Point &start_near, ExtrusionRole role) { - ExtrusionEntityCollection out; - for (const ExtrusionEntity *ee : extrusion_entities) { - if (role != erMixed) { - // The caller wants only paths with a specific extrusion role. - auto role2 = ee->role(); - if (role != role2) { - // This extrusion entity does not match the role asked. - assert(role2 != erMixed); - continue; - } - } - out.entities.emplace_back(ee->clone()); - } + // Return a filtered copy of the collection. + ExtrusionEntityCollection out; + out.entities = filter_by_extrusion_role(extrusion_entities, role); + // Clone the extrusion entities. + for (auto &ptr : out.entities) + ptr = ptr->clone(); chain_and_reorder_extrusion_entities(out.entities, &start_near); return out; } diff --git a/src/libslic3r/ExtrusionEntityCollection.hpp b/src/libslic3r/ExtrusionEntityCollection.hpp index e529bea02..8aacb4d46 100644 --- a/src/libslic3r/ExtrusionEntityCollection.hpp +++ b/src/libslic3r/ExtrusionEntityCollection.hpp @@ -6,6 +6,21 @@ namespace Slic3r { +// Remove those items from extrusion_entities, that do not match role. +// Do nothing if role is mixed. +// Removed elements are NOT being deleted. +void filter_by_extrusion_role_in_place(ExtrusionEntitiesPtr &extrusion_entities, ExtrusionRole role); + +// Return new vector of ExtrusionEntities* with only those items from input extrusion_entities, that match role. +// Return all extrusion entities if role is mixed. +// Returned extrusion entities are shared with the source vector, they are NOT cloned, they are considered to be owned by extrusion_entities. +inline ExtrusionEntitiesPtr filter_by_extrusion_role(const ExtrusionEntitiesPtr &extrusion_entities, ExtrusionRole role) +{ + ExtrusionEntitiesPtr out { extrusion_entities }; + filter_by_extrusion_role_in_place(out, role); + return out; +} + class ExtrusionEntityCollection : public ExtrusionEntity { public: @@ -67,7 +82,7 @@ public: void remove(size_t i); static ExtrusionEntityCollection chained_path_from(const ExtrusionEntitiesPtr &extrusion_entities, const Point &start_near, ExtrusionRole role = erMixed); ExtrusionEntityCollection chained_path_from(const Point &start_near, ExtrusionRole role = erMixed) const - { return (this->no_sort || role == erMixed) ? *this : chained_path_from(this->entities, start_near, role); } + { return this->no_sort ? *this : chained_path_from(this->entities, start_near, role); } void reverse(); const Point& first_point() const { return this->entities.front()->first_point(); } const Point& last_point() const { return this->entities.back()->last_point(); } @@ -107,6 +122,6 @@ public: } }; -} +} // namespace Slic3r #endif diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 7bd352537..942558f27 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2848,9 +2848,9 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy std::string gcode; for (const ObjectByExtruder::Island::Region ®ion : by_region) { m_config.apply(print.regions()[®ion - &by_region.front()]->config()); -// for (ExtrusionEntity *fill : ExtrusionEntityCollection::chained_path_from(region.infills, m_last_pos).entities) { - // Don't sort the infills, they contain gap fill, which shall be extruded after normal fills. - for (const ExtrusionEntity *fill : region.infills) { + ExtrusionEntitiesPtr extrusions { region.infills }; + chain_and_reorder_extrusion_entities(extrusions, &m_last_pos); + for (const ExtrusionEntity *fill : extrusions) { auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill); if (eec) { for (ExtrusionEntity *ee : eec->chained_path_from(m_last_pos).entities)