diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8ab4ffcd98..bbaabf0f53 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2463,84 +2463,50 @@ LayerResult GCodeGenerator::process_layer( } using GCode::ExtrusionOrder::NormalExtrusions; - struct ExtruderExtrusions { - unsigned extruder_id; - std::vector> skirt; - ExtrusionEntitiesPtr brim; - std::vector> overriden_extrusions; - std::vector normal_extrusions; + + + + 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; + } }; - unsigned current_extruder_id{this->m_writer.extruder()->id()}; - unsigned toolchange_number{0}; std::optional previous_position; if (this->last_position) { previous_position = this->point_to_gcode(*this->last_position); } - - std::vector extrusions; - for (const unsigned int extruder_id : layer_tools.extruders) - { - if (layer_tools.has_wipe_tower && m_wipe_tower) { - if (is_toolchange_required(first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) { - const WipeTower::ToolChangeResult tool_change{m_wipe_tower->get_toolchange(toolchange_number++)}; - previous_position = m_wipe_tower->transform_wt_pt(tool_change.end_pos).cast(); - current_extruder_id = tool_change.new_tool; - } - } - - ExtruderExtrusions extruder_extrusions{extruder_id}; - - if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) { - const std::pair loops = loops_it->second; - for (std::size_t i = loops.first; i < loops.second; ++i) { - extruder_extrusions.skirt.emplace_back(i, print.skirt().entities[i]); - } - } - - // Extrude brim with the extruder of the 1st region. - using GCode::ExtrusionOrder::get_last_position; - if (!m_brim_done) { - extruder_extrusions.brim = print.brim().entities; - previous_position = get_last_position(extruder_extrusions.brim, {0.0, 0.0}); - m_brim_done = true; - } - - 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(); - if (is_anything_overridden) { - extruder_extrusions.overriden_extrusions = get_overriden_extrusions( - print, layers, layer_tools, instances_to_print, extruder_id, place_seam, - previous_position - ); - } - - using GCode::ExtrusionOrder::get_normal_extrusions; - extruder_extrusions.normal_extrusions = get_normal_extrusions( - print, layers, layer_tools, instances_to_print, extruder_id, place_seam, + using GCode::ExtrusionOrder::ExtruderExtrusions; + using GCode::ExtrusionOrder::get_extrusions; + const std::vector extrusions{ + get_extrusions( + print, + m_wipe_tower.get(), + layers, + first_layer, + layer_tools, + instances_to_print, + skirt_loops_per_extruder, + this->m_writer.extruder()->id(), + place_seam, + !m_brim_done, previous_position - ); - extrusions.push_back(std::move(extruder_extrusions)); - } + ) + }; + m_brim_done = true; // Extrude the skirt, brim, support, perimeters, infill ordered by the extruders. for (const ExtruderExtrusions &extruder_extrusions : extrusions) diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index 75ea09d6c2..8629afca55 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -3,6 +3,7 @@ #include +#include "libslic3r/GCode/WipeTowerIntegration.hpp" #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/GCode/SeamPlacer.hpp" #include "libslic3r/Print.hpp" @@ -95,6 +96,76 @@ std::vector get_normal_extrusions( std::optional &previous_position ); +struct ExtruderExtrusions { + unsigned extruder_id; + std::vector> skirt; + ExtrusionEntitiesPtr brim; + std::vector> overriden_extrusions; + std::vector normal_extrusions; +}; + +inline std::vector get_extrusions( + const Print &print, + const GCode::WipeTowerIntegration *wipe_tower, + const GCode::ObjectsLayerToPrint &layers, + const bool is_first_layer, + const LayerTools &layer_tools, + const std::vector &instances_to_print, + const std::map> &skirt_loops_per_extruder, + unsigned current_extruder_id, + const SeamPlacingFunciton &place_seam, + bool get_brim, + std::optional previous_position +) { + unsigned toolchange_number{0}; + + std::vector extrusions; + for (const unsigned int extruder_id : layer_tools.extruders) + { + if (layer_tools.has_wipe_tower && wipe_tower != nullptr) { + if (is_toolchange_required(is_first_layer, layer_tools.extruders.back(), extruder_id, current_extruder_id)) { + const WipeTower::ToolChangeResult tool_change{wipe_tower->get_toolchange(toolchange_number++)}; + previous_position = wipe_tower->transform_wt_pt(tool_change.end_pos).cast(); + current_extruder_id = tool_change.new_tool; + } + } + + ExtruderExtrusions extruder_extrusions{extruder_id}; + + if (auto loops_it = skirt_loops_per_extruder.find(extruder_id); loops_it != skirt_loops_per_extruder.end()) { + const std::pair loops = loops_it->second; + for (std::size_t i = loops.first; i < loops.second; ++i) { + extruder_extrusions.skirt.emplace_back(i, print.skirt().entities[i]); + } + } + + // Extrude brim with the extruder of the 1st region. + using GCode::ExtrusionOrder::get_last_position; + if (get_brim) { + extruder_extrusions.brim = print.brim().entities; + previous_position = get_last_position(extruder_extrusions.brim, {0.0, 0.0}); + get_brim = false; + } + + using GCode::ExtrusionOrder::get_overriden_extrusions; + bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden(); + if (is_anything_overridden) { + extruder_extrusions.overriden_extrusions = get_overriden_extrusions( + print, layers, layer_tools, instances_to_print, extruder_id, place_seam, + previous_position + ); + } + + using GCode::ExtrusionOrder::get_normal_extrusions; + extruder_extrusions.normal_extrusions = get_normal_extrusions( + print, layers, layer_tools, instances_to_print, extruder_id, place_seam, + previous_position + ); + extrusions.push_back(std::move(extruder_extrusions)); + } + return extrusions; +} + } #endif // slic3r_GCode_ExtrusionOrder_hpp_ diff --git a/src/libslic3r/GCode/WipeTowerIntegration.hpp b/src/libslic3r/GCode/WipeTowerIntegration.hpp index 666a7f3175..05c60a2291 100644 --- a/src/libslic3r/GCode/WipeTowerIntegration.hpp +++ b/src/libslic3r/GCode/WipeTowerIntegration.hpp @@ -39,7 +39,7 @@ public: std::string tool_change(GCodeGenerator &gcodegen, int extruder_id, bool finish_layer); std::string finalize(GCodeGenerator &gcodegen); std::vector used_filament_length() const; - WipeTower::ToolChangeResult get_toolchange(std::size_t index) { + WipeTower::ToolChangeResult get_toolchange(std::size_t index) const { return m_tool_changes.at(m_layer_idx).at(index); }