diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index 00ed27886..e32c6d3c0 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -43,12 +43,17 @@ enum ExtrusionRole : uint8_t { // Special flags describing loop enum ExtrusionLoopRole { - elrDefault, - elrContourInternalPerimeter, - elrSkirt, - elrPerimeterHole, + elrDefault = 1 << 0, + elrContourInternalPerimeter = 1 << 1, + elrSkirt = 1 << 2, + elrPerimeterHole = 1 << 3, + elrSecondPerimeter = 1 << 4 }; +inline ExtrusionLoopRole operator |(ExtrusionLoopRole a, ExtrusionLoopRole b) { + return static_cast(static_cast(a) | static_cast(b)); +} + inline bool is_perimeter(ExtrusionRole role) { diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 741bd6820..ea4abd9aa 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4009,7 +4009,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou // extrude all loops ccw bool was_clockwise = loop.make_counter_clockwise(); - bool is_hole = loop.loop_role() == elrPerimeterHole; + bool is_hole = loop.loop_role() & elrPerimeterHole; // find the point of the loop that is closest to the current extruder position // or randomize if requested Point last_pos = this->last_pos(); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index f992cb640..060f89dae 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -468,7 +468,14 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime } else { loop_role = loop.is_contour? elrDefault: elrPerimeterHole; } - + + if( loop.depth == 1 ) { + if (loop_role == elrDefault) + loop_role = elrSecondPerimeter; + else + loop_role = loop_role | elrSecondPerimeter; + } + // detect overhanging/bridging perimeters ExtrusionPaths paths; @@ -1436,13 +1443,22 @@ void PerimeterGenerator::process_classic() //BBS. adjust wall generate seq else if (this->object_config->wall_sequence == WallSequence::InnerOuterInner) if (entities.entities.size() > 1){ - int last_outer=0; - int outer = 0; - for (; outer < entities.entities.size(); ++outer) - if (entities.entities[outer]->role() == erExternalPerimeter && outer - last_outer > 1) { - std::swap(entities.entities[outer], entities.entities[outer - 1]); - last_outer = outer; + int second_wall = -1; + ExtrusionEntitiesPtr entities_reorder; + ExtrusionEntitiesPtr entities_second_wall; + for (int entity_idx = 0; entity_idx < entities.entities.size(); ++entity_idx) { + ExtrusionLoop *eloop = static_cast(entities.entities[entity_idx]); + if (eloop->loop_role() & elrSecondPerimeter) { + entities_second_wall.push_back(entities.entities[entity_idx]); + } else { + entities_reorder.push_back(entities.entities[entity_idx]); + if (entities.entities[entity_idx]->role() == erExternalPerimeter && !entities_second_wall.empty()) { + entities_reorder.insert(entities_reorder.end(), entities_second_wall.begin(), entities_second_wall.end()); + entities_second_wall.clear(); + } } + } + entities.entities = std::move( entities_reorder); } // append perimeters for this slice as a collection if (! entities.empty())