From 4ac098df4dca54895da7608f5b0a394cd9c279ac Mon Sep 17 00:00:00 2001 From: igiannakas <59056762+igiannakas@users.noreply.github.com> Date: Sat, 5 Aug 2023 09:46:07 +0100 Subject: [PATCH] ENH: reorder wall seq for inner outer inner mode Enhancement on wall ordering for inner outer inner mode Github pull request: #2182 Change-Id: I0902ea0c728f7e37a1a43f9796997f33d37a9940 --- src/libslic3r/PerimeterGenerator.cpp | 51 +++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index a3069bd00..982b3158a 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -1462,7 +1462,8 @@ void PerimeterGenerator::process_arachne() bool is_outer_wall_first = this->print_config->wall_infill_order == WallInfillOrder::OuterInnerInfill || - this->print_config->wall_infill_order == WallInfillOrder::InfillOuterInner; + this->print_config->wall_infill_order == WallInfillOrder::InfillOuterInner || + this->print_config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill; if (is_outer_wall_first) { start_perimeter = 0; end_perimeter = int(perimeters.size()); @@ -1589,16 +1590,48 @@ void PerimeterGenerator::process_arachne() } } // BBS. adjust wall generate seq - if (this->print_config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill) - if (ordered_extrusions.size() > 1) { - int last_outer = 0; - int outer = 0; - for (; outer < ordered_extrusions.size(); ++outer) - if (ordered_extrusions[outer].extrusion->inset_idx == 0 && outer - last_outer > 1) { - std::swap(ordered_extrusions[outer], ordered_extrusions[outer - 1]); - last_outer = outer; + if (this->print_config->wall_infill_order == WallInfillOrder::InnerOuterInnerInfill){ + if (ordered_extrusions.size() > 2) { // 3 walls minimum needed to do inner outer inner ordering + int position = 0; // index to run the re-ordering for multiple external perimeters in a single island. + int arr_i = 0; // index to run through the walls + int outer, first_internal, second_internal; // allocate index values + // run the re-ordering for all wall loops in the same island + while (position < ordered_extrusions.size()) { + outer = first_internal = second_internal = -1; // initialise all index values to -1 + // run through the walls to get the index values that need re-ordering until the first one for each + // is found. Start at "position" index to enable the for loop to iterate for multiple external + // perimeters in a single island + for (arr_i = position; arr_i < ordered_extrusions.size(); ++arr_i) { + switch (ordered_extrusions[arr_i].extrusion->inset_idx) { + case 0: // external perimeter + if (outer == -1) + outer = arr_i; + break; + case 1: // first internal wall + if (first_internal == -1 && arr_i > outer) + first_internal = arr_i; + break; + case 2: // second internal wall + if (ordered_extrusions[arr_i].extrusion->inset_idx == 2 && second_internal == -1 && + arr_i > first_internal) + second_internal = arr_i; + break; + } + if (second_internal != -1) + break; // found all three perimeters to re-order } + if (outer > -1 && first_internal > -1 && second_internal > -1) { // found perimeters to re-order? + const auto temp = ordered_extrusions[second_internal]; + ordered_extrusions[second_internal] = ordered_extrusions[first_internal]; + ordered_extrusions[first_internal] = ordered_extrusions[outer]; + ordered_extrusions[outer] = temp; + } else + break; // did not find any more candidates to re-order, so stop the while loop early + // go to the next perimeter to continue scanning for external walls in the same island + position = arr_i + 1; + } } + } if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(*this, ordered_extrusions); !extrusion_coll.empty()) this->loops->append(extrusion_coll);