From 9845767295f257e4b3c501ad96a64953f7ba2274 Mon Sep 17 00:00:00 2001 From: "qing.zhang" Date: Mon, 3 Jun 2024 10:31:06 +0800 Subject: [PATCH] FIX: wrong wall order Github: 4139 Signed-off-by: qing.zhang Change-Id: Ibc2c433b3de5a0c5e7cd2edcd4f9e91956645e88 (cherry picked from commit d4282d26cbbfbbfacf7352c5e45c078eb3ef14f8) --- src/libslic3r/ExtrusionEntity.hpp | 13 ++++++++---- src/libslic3r/GCode.cpp | 2 +- src/libslic3r/PerimeterGenerator.cpp | 30 +++++++++++++++++++++------- 3 files changed, 33 insertions(+), 12 deletions(-) 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())