diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index bbaabf0f53..796550999c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2283,6 +2283,66 @@ std::string GCodeGenerator::generate_ramping_layer_change_gcode( return travel_gcode; } +std::vector GCodeGenerator::get_sorted_extrusions( + const Print &print, + const ObjectsLayerToPrint &layers, + const LayerTools &layer_tools, + const std::vector &instances_to_print, + const bool first_layer +) { + // Map from extruder ID to index of skirt loops to be extruded with that extruder. + // Extrude skirt at the print_z of the raft layers and normal object layers + // not at the print_z of the interlaced support material layers. + std::map> skirt_loops_per_extruder{ + first_layer ? + Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) : + Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done)}; + + 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::ExtruderExtrusions; + using GCode::ExtrusionOrder::get_extrusions; + + const std::optional previous_position{ + this->last_position ? std::optional{this->point_to_gcode(*this->last_position)} : + std::nullopt}; + std::vector extrusions{ + get_extrusions( + print, + this->m_wipe_tower.get(), + layers, + first_layer, + layer_tools, + instances_to_print, + skirt_loops_per_extruder, + this->m_writer.extruder()->id(), + place_seam, + !this->m_brim_done, + previous_position + ) + }; + this->m_brim_done = true; + + return extrusions; +} + // In sequential mode, process_layer is called once per each object and its copy, // therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object. // In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated. @@ -2357,6 +2417,9 @@ LayerResult GCodeGenerator::process_layer( m_enable_loop_clipping = !enable; } + using GCode::ExtrusionOrder::ExtruderExtrusions; + std::vector extrusions{ + this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, first_layer)}; std::string gcode; assert(is_decimal_separator_point()); // for the sprintfs @@ -2424,15 +2487,6 @@ LayerResult GCodeGenerator::process_layer( m_second_layer_things_done = true; } - // Map from extruder ID to index of skirt loops to be extruded with that extruder. - std::map> skirt_loops_per_extruder; - - // Extrude skirt at the print_z of the raft layers and normal object layers - // not at the print_z of the interlaced support material layers. - skirt_loops_per_extruder = first_layer ? - Skirt::make_skirt_loops_per_extruder_1st_layer(print, layer_tools, m_skirt_done) : - Skirt::make_skirt_loops_per_extruder_other_layers(print, layer_tools, m_skirt_done); - if (this->config().avoid_crossing_curled_overhangs) { m_avoid_crossing_curled_overhangs.clear(); for (const ObjectLayerToPrint &layer_to_print : layers) { @@ -2462,52 +2516,6 @@ LayerResult GCodeGenerator::process_layer( } } - using GCode::ExtrusionOrder::NormalExtrusions; - - - - 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; - } - }; - - std::optional previous_position; - if (this->last_position) { - previous_position = this->point_to_gcode(*this->last_position); - } - 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 - ) - }; - 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.hpp b/src/libslic3r/GCode.hpp index 3dafeb09b6..bd93d6e48a 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -231,6 +231,14 @@ private: const GCode::Impl::Travels::ElevatedTravelParams &elevation_params ) const; + std::vector get_sorted_extrusions( + const Print &print, + const ObjectsLayerToPrint &layers, + const LayerTools &layer_tools, + const std::vector &instances_to_print, + const bool first_layer + ); + LayerResult process_layer( const Print &print, // Set of object & print layers of the same PrintObject and with the same print_z. @@ -243,6 +251,7 @@ private: // If set to size_t(-1), then print all copies of all objects. // Otherwise print a single copy of a single object. const size_t single_object_idx = size_t(-1)); + // Process all layers of all objects (non-sequential mode) with a parallel pipeline: // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // and export G-code into file. diff --git a/src/libslic3r/GCode/ExtrusionOrder.cpp b/src/libslic3r/GCode/ExtrusionOrder.cpp index 7404d7daf8..a440cd0f7e 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.cpp +++ b/src/libslic3r/GCode/ExtrusionOrder.cpp @@ -446,4 +446,66 @@ std::vector get_normal_extrusions( return result; } +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; +} + } diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index 8629afca55..ce074a95f9 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -104,7 +104,7 @@ struct ExtruderExtrusions { std::vector normal_extrusions; }; -inline std::vector get_extrusions( +std::vector get_extrusions( const Print &print, const GCode::WipeTowerIntegration *wipe_tower, const GCode::ObjectsLayerToPrint &layers, @@ -116,55 +116,7 @@ inline std::vector get_extrusions( 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; -} +); }