From fe1b8134d63eaaba350ac8412ce1fa82bce01831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Fri, 14 Jun 2024 10:59:20 +0200 Subject: [PATCH] Remove ExtrusionOrder dependency on seam placer --- src/libslic3r/GCode.cpp | 29 ++++++-- src/libslic3r/GCode/ExtrusionOrder.cpp | 72 ++++++++----------- src/libslic3r/GCode/ExtrusionOrder.hpp | 95 ++------------------------ 3 files changed, 57 insertions(+), 139 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 10b19a5d1b..50c660b34c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2497,21 +2497,41 @@ LayerResult GCodeGenerator::process_layer( previous_position = get_last_position(brim); } + + const auto place_seam =[&]( + const Layer &layer, ExtrusionEntity *perimeter, const std::optional &previous_position + ) { + auto loop{dynamic_cast(perimeter)}; + + Point seam_point{previous_position ? *previous_position : Point::Zero()}; + if (!this->m_config.spiral_vase && loop != nullptr) { + seam_point = this->m_seam_placer.place_seam(&layer, *loop, seam_point); + loop->seam = seam_point; + } + + auto path{dynamic_cast(perimeter)}; + if (path != nullptr) { + return path->last_point(); + } else { + return seam_point; + } + }; + using GCode::ExtrusionOrder::get_overriden_extrusions; bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden(); std::vector> overriden_extrusions; if (is_anything_overridden) { overriden_extrusions = get_overriden_extrusions( - print, layers, layer_tools, instances_to_print, this->m_seam_placer, - this->m_config.spiral_vase, extruder_id, previous_position + print, layers, layer_tools, instances_to_print, extruder_id, place_seam, + previous_position ); } using GCode::ExtrusionOrder::get_normal_extrusions; using GCode::ExtrusionOrder::NormalExtrusions; const std::vector normal_extrusions{get_normal_extrusions( - print, layers, layer_tools, instances_to_print, this->m_seam_placer, - this->m_config.spiral_vase, extruder_id, previous_position + print, layers, layer_tools, instances_to_print, extruder_id, place_seam, + previous_position )}; if (!skirt.empty()) { @@ -2559,7 +2579,6 @@ LayerResult GCodeGenerator::process_layer( } this->m_label_objects.update(first_instance); - // We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature): if (!overriden_extrusions.empty()) { // Extrude wipes. size_t gcode_size_old = gcode.size(); diff --git a/src/libslic3r/GCode/ExtrusionOrder.cpp b/src/libslic3r/GCode/ExtrusionOrder.cpp index 8e8063b219..2a1734d7f6 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.cpp +++ b/src/libslic3r/GCode/ExtrusionOrder.cpp @@ -1,4 +1,5 @@ #include "ExtrusionOrder.hpp" +#include "libslic3r/ShortestPath.hpp" namespace Slic3r::GCode::ExtrusionOrder { @@ -26,6 +27,8 @@ int get_extruder_id( return extruder_id; } +using ExtractEntityPredicate = std::function; + ExtrusionEntitiesPtr extract_infill_extrusions( const PrintRegion ®ion, const ExtrusionEntityCollection &fills, @@ -121,8 +124,6 @@ std::vector extract_infill_ranges( // identify the content of PrintRegion accross the whole print uniquely. Translate to a Print specific PrintRegion. const PrintRegion ®ion = print.get_print_region(layerm.region().print_region_id()); - const Point* start_near = previous_position ? &(*(previous_position)) : nullptr; - ExtrusionEntitiesPtr extrusions{extract_infill_extrusions( region, layerm.fills(), @@ -131,6 +132,7 @@ std::vector extract_infill_ranges( predicate )}; + const Point* start_near = previous_position ? &(*(previous_position)) : nullptr; const std::vector sorted_extrusions{sort_fill_extrusions(extrusions, start_near)}; if (! sorted_extrusions.empty()) { @@ -144,25 +146,6 @@ std::vector extract_infill_ranges( return result; } -void place_seams( - const Layer &layer, const Seams::Placer &seam_placer, const std::vector &perimeters, std::optional previous_position, const bool spiral_vase -) { - std::vector result; - result.reserve(perimeters.size()); - - for (ExtrusionEntity* perimeter : perimeters) { - auto loop{dynamic_cast(perimeter)}; - - Point seam_point{previous_position ? *previous_position : Point::Zero()}; - if (!spiral_vase && loop != nullptr) { - assert(m_layer != nullptr); - seam_point = seam_placer.place_seam(&layer, *loop, seam_point); - loop->seam = seam_point; - } - previous_position = seam_point; - } -} - std::optional get_last_position(const std::vector &infill_ranges) { if (!infill_ranges.empty() && !infill_ranges.back().items.empty()) { const ExtrusionEntityReference &last_infill{infill_ranges.back().items.back()}; @@ -181,11 +164,15 @@ std::optional get_last_position(const ExtrusionEntityReferences &extrusio return std::nullopt; } -std::optional get_last_position(const std::vector &perimeters){ +std::optional get_last_position(const ExtrusionEntitiesPtr &perimeters){ if (!perimeters.empty()) { - auto last_perimeter{dynamic_cast(perimeters.back())}; - if (last_perimeter != nullptr) { - return last_perimeter->seam; + auto last_perimeter_loop{dynamic_cast(perimeters.back())}; + if (last_perimeter_loop != nullptr) { + return last_perimeter_loop->seam; + } + auto last_perimeter_multi_path{dynamic_cast(perimeters.back())}; + if (last_perimeter_multi_path != nullptr) { + return last_perimeter_multi_path->last_point(); } } return std::nullopt; @@ -220,9 +207,8 @@ std::vector extract_island_extrusions( const LayerSlice &lslice, const Print &print, const Layer &layer, - const Seams::Placer &seam_placer, - const bool spiral_vase, const ExtractEntityPredicate &predicate, + const SeamPlacingFunciton &place_seam, std::optional &previous_position ) { std::vector result; @@ -250,13 +236,17 @@ std::vector extract_island_extrusions( previous_position = last_position; } - place_seams(layer, seam_placer, island_extrusions.perimeters, previous_position, spiral_vase); + for (ExtrusionEntity* perimeter : island_extrusions.perimeters) { + previous_position = place_seam(layer, perimeter, previous_position); + } if (const auto last_position = get_last_position(island_extrusions.perimeters)) { previous_position = last_position; } } else { - place_seams(layer, seam_placer, island_extrusions.perimeters, previous_position, spiral_vase); + for (ExtrusionEntity* perimeter : island_extrusions.perimeters) { + previous_position = place_seam(layer, perimeter, previous_position); + } if (const auto last_position = get_last_position(island_extrusions.perimeters)) { previous_position = last_position; @@ -303,10 +293,9 @@ std::vector extract_ironing_extrusions( std::vector get_slices_extrusions( const Print &print, const Layer &layer, - const Seams::Placer &seam_placer, - std::optional previous_position, - const bool spiral_vase, - const ExtractEntityPredicate &predicate + const ExtractEntityPredicate &predicate, + const SeamPlacingFunciton &place_seam, + std::optional previous_position ) { // Note: ironing. // FIXME move ironing into the loop above over LayerIslands? @@ -320,7 +309,7 @@ std::vector get_slices_extrusions( const LayerSlice &lslice = layer.lslices_ex[idx]; result.emplace_back(SliceExtrusions{ extract_island_extrusions( - lslice, print, layer, seam_placer, spiral_vase, predicate, previous_position + lslice, print, layer, predicate, place_seam, previous_position ), extract_ironing_extrusions(lslice, print, layer, predicate, previous_position) }); @@ -385,9 +374,8 @@ std::vector> get_overriden_extrusions( const GCode::ObjectsLayerToPrint &layers, const LayerTools &layer_tools, const std::vector &instances_to_print, - const Seams::Placer &seam_placer, - const bool spiral_vase, const unsigned int extruder_id, + const SeamPlacingFunciton &place_seam, std::optional &previous_position ) { std::vector> result; @@ -409,7 +397,7 @@ std::vector> get_overriden_extrusions( }; result.emplace_back(get_slices_extrusions( - print, *layer, seam_placer, previous_position, spiral_vase, predicate + print, *layer, predicate, place_seam, previous_position )); previous_position = get_last_position(result.back(), print.config().infill_first); } @@ -422,9 +410,8 @@ std::vector get_normal_extrusions( const GCode::ObjectsLayerToPrint &layers, const LayerTools &layer_tools, const std::vector &instances_to_print, - const Seams::Placer &seam_placer, - const bool spiral_vase, const unsigned int extruder_id, + const SeamPlacingFunciton &place_seam, std::optional &previous_position ) { std::vector result; @@ -458,10 +445,9 @@ std::vector get_normal_extrusions( result.back().slices_extrusions = get_slices_extrusions( print, *layer, - seam_placer, - previous_position, - spiral_vase, - predicate + predicate, + place_seam, + previous_position ); previous_position = get_last_position(result.back().slices_extrusions, print.config().infill_first); } diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index d8c9d32f3a..36610c4b4f 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -71,103 +71,17 @@ struct NormalExtrusions { std::vector slices_extrusions; }; -bool is_overriden(const ExtrusionEntityCollection &eec, const LayerTools &layer_tools, const std::size_t instance_id); +std::optional get_last_position(const ExtrusionEntitiesPtr &perimeters); -int get_extruder_id( - const ExtrusionEntityCollection &eec, - const LayerTools &layer_tools, - const PrintRegion ®ion, - const std::size_t instance_id -); - -using ExtractEntityPredicate = std::function; - -ExtrusionEntitiesPtr extract_infill_extrusions( - const Layer *layer, - const PrintRegion ®ion, - const ExtrusionEntityCollection &fills, - LayerExtrusionRanges::const_iterator begin, - LayerExtrusionRanges::const_iterator end, - const ExtractEntityPredicate &predicate -); - -std::vector extract_perimeter_extrusions( - const Print &print, - const Layer *layer, - const LayerIsland &island, - const ExtractEntityPredicate &predicate -); - -std::vector sort_fill_extrusions(const ExtrusionEntitiesPtr &fills, const Point* start_near); - -std::vector extract_infill_ranges( - const Print &print, - const Layer *layer, - const LayerIsland island, - std::optional previous_position, - const ExtractEntityPredicate &predicate -); - -void place_seams( - const Layer *layer, const Seams::Placer &seam_placer, const std::vector &perimeters, std::optional previous_position, const bool spiral_vase -); - -std::optional get_last_position(const std::vector &infill_ranges); - -std::optional get_last_position(const ExtrusionEntityReferences &extrusions); - -std::optional get_last_position(const std::vector &perimeters); - -std::optional get_last_position(const std::vector &slice_extrusions, const bool infill_first); - -std::vector extract_island_extrusions( - const LayerSlice &lslice, - const Print &print, - const Layer &layer, - const Seams::Placer &seam_placer, - const bool spiral_vase, - const ExtractEntityPredicate &predicate, - std::optional &previous_position -); - -std::vector extract_ironing_extrusions( - const LayerSlice &lslice, - const Print &print, - const Layer &layer, - const ExtractEntityPredicate &predicate, - std::optional &previous_position -); - -std::vector get_slices_extrusions( - const Print &print, - const Layer &layer, - const Seams::Placer &seam_placer, - std::optional previous_position, - const bool spiral_vase, - const ExtractEntityPredicate &predicate -); - -unsigned translate_support_extruder( - const int configured_extruder, - const LayerTools &layer_tools, - const ConfigOptionBools &is_soluable -); - -ExtrusionEntityReferences get_support_extrusions( - const unsigned int extruder_id, - const GCode::ObjectLayerToPrint &layer_to_print, - unsigned int support_extruder, - unsigned int interface_extruder -); +using SeamPlacingFunciton = std::function(const Layer &layer, ExtrusionEntity* perimeter, const std::optional&)>; std::vector> get_overriden_extrusions( const Print &print, const GCode::ObjectsLayerToPrint &layers, const LayerTools &layer_tools, const std::vector &instances_to_print, - const Seams::Placer &seam_placer, - const bool spiral_vase, const unsigned int extruder_id, + const SeamPlacingFunciton &place_seam, std::optional &previous_position ); @@ -176,9 +90,8 @@ std::vector get_normal_extrusions( const GCode::ObjectsLayerToPrint &layers, const LayerTools &layer_tools, const std::vector &instances_to_print, - const Seams::Placer &seam_placer, - const bool spiral_vase, const unsigned int extruder_id, + const SeamPlacingFunciton &place_seam, std::optional &previous_position );