diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e150201ce5..4ec2bb4882 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2408,9 +2408,6 @@ LayerResult GCodeGenerator::process_layer( unsigned int first_extruder_id = layer_tools.extruders.front(); const std::vector instances_to_print{sort_print_object_instances(layers, ordering, single_object_instance_idx)}; - const PrintInstance* first_instance{instances_to_print.empty() ? nullptr : &instances_to_print.front().print_object.instances()[instances_to_print.front().instance_id]}; - m_label_objects.update(first_instance); - // Initialize config with the 1st object to be printed at this layer. m_config.apply(layer.object()->config(), true); @@ -2442,8 +2439,11 @@ LayerResult GCodeGenerator::process_layer( return result; } const Point first_point{*GCode::ExtrusionOrder::get_first_point(extrusions)}; + const PrintInstance* first_instance{get_first_instance(extrusions, instances_to_print)}; + m_label_objects.update(first_instance); std::string gcode; + assert(is_decimal_separator_point()); // for the sprintfs // add tag for processor @@ -2461,7 +2461,6 @@ LayerResult GCodeGenerator::process_layer( m_last_layer_z = static_cast(print_z); m_max_layer_z = std::max(m_max_layer_z, m_last_layer_z); m_last_height = height; - m_already_extruded = false; // Set new layer - this will change Z and force a retraction if retract_layer_change is enabled. if (!first_layer && ! print.config().before_layer_gcode.value.empty()) { @@ -2599,7 +2598,8 @@ LayerResult GCodeGenerator::process_layer( // Allow a straight travel move to the first object point. m_avoid_crossing_perimeters.disable_once(); } - this->m_label_objects.update(first_instance); + + m_label_objects.update(first_instance); if (!extruder_extrusions.overriden_extrusions.empty()) { // Extrude wipes. @@ -2633,7 +2633,6 @@ LayerResult GCodeGenerator::process_layer( if (support_extrusions.empty() && is_empty(slices_extrusions)) { continue; } - this->initialize_instance(instance, layers[instance.object_layer_to_print_id]); if (!support_extrusions.empty()) { @@ -3064,8 +3063,6 @@ std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const this->writer().update_position(gcode_point); } - m_already_extruded = true; - return gcode; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 862241bc2e..b35bd567e0 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -312,7 +312,6 @@ private: const ObjectLayerToPrint &layer_to_print ); - // This function will be called for each printing extruder, possibly twice: First for wiping extrusions, second for normal extrusions. std::string extrude_slices( const InstanceToPrint &print_instance, const ObjectLayerToPrint &layer_to_print, @@ -431,7 +430,6 @@ private: std::optional m_previous_layer_last_position; std::optional m_previous_layer_last_position_before_wipe; // This needs to be populated during the layer processing! - bool m_already_extruded{false}; std::unique_ptr m_cooling_buffer; std::unique_ptr m_spiral_vase; std::unique_ptr m_find_replace; diff --git a/src/libslic3r/GCode/ExtrusionOrder.cpp b/src/libslic3r/GCode/ExtrusionOrder.cpp index 9310847c7b..e7eba21d5b 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.cpp +++ b/src/libslic3r/GCode/ExtrusionOrder.cpp @@ -118,7 +118,9 @@ std::vector extract_perimeter_extrusions( } SmoothPath path{smooth_path(&layer, ExtrusionEntityReference{*ee, reverse_loop}, extruder_id, last_position)}; previous_position = get_gcode_point(last_position, offset); - result.push_back(Perimeter{std::move(path), reverse_loop, ee}); + if (!path.empty()) { + result.push_back(Perimeter{std::move(path), reverse_loop, ee}); + } } } } @@ -179,10 +181,15 @@ std::vector extract_infill_ranges( std::vector paths; for (const ExtrusionEntityReference &extrusion_reference : sorted_extrusions) { std::optional last_position{get_instance_point(previous_position, offset)}; - paths.push_back(smooth_path(&layer, extrusion_reference, extruder_id, last_position)); + SmoothPath path{smooth_path(&layer, extrusion_reference, extruder_id, last_position)}; + if (!path.empty()) { + paths.push_back(std::move(path)); + } previous_position = get_gcode_point(last_position, offset); } - result.push_back({std::move(paths), ®ion}); + if (!paths.empty()) { + result.push_back({std::move(paths), ®ion}); + } it = it_end; } return result; @@ -277,12 +284,17 @@ std::vector get_slices_extrusions( for (size_t idx : layer.lslice_indices_sorted_by_print_order) { const LayerSlice &lslice = layer.lslices_ex[idx]; - result.emplace_back(SliceExtrusions{ - extract_island_extrusions( - lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position - ), - extract_ironing_extrusions(lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position) - }); + std::vector island_extrusions{extract_island_extrusions( + lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position + )}; + std::vector ironing_extrusions{extract_ironing_extrusions( + lslice, print, layer, predicate, smooth_path, offset, extruder_id, previous_position + )}; + if (!island_extrusions.empty() || !ironing_extrusions.empty()) { + result.emplace_back( + SliceExtrusions{std::move(island_extrusions), std::move(ironing_extrusions)} + ); + } } return result; } @@ -342,12 +354,18 @@ std::vector get_support_extrusions( if (collection != nullptr) { for (const ExtrusionEntity * sub_entity : *collection) { std::optional last_position{get_instance_point(previous_position, {0, 0})}; - paths.push_back({smooth_path(nullptr, {*sub_entity, entity_reference.flipped()}, extruder_id, last_position), is_interface}); + SmoothPath path{smooth_path(nullptr, {*sub_entity, entity_reference.flipped()}, extruder_id, last_position)}; + if (!path.empty()) { + paths.push_back({std::move(path), is_interface}); + } previous_position = get_gcode_point(last_position, {0, 0}); } } else { std::optional last_position{get_instance_point(previous_position, {0, 0})}; - paths.push_back({smooth_path(nullptr, entity_reference, extruder_id, last_position), is_interface}); + SmoothPath path{smooth_path(nullptr, entity_reference, extruder_id, last_position)}; + if (!path.empty()) { + paths.push_back({std::move(path), is_interface}); + } previous_position = get_gcode_point(last_position, {0, 0}); } } @@ -387,9 +405,12 @@ std::vector get_overriden_extrusions( const PrintObject &print_object = instance.print_object; const Point &offset = print_object.instances()[instance.instance_id].shift; - result.push_back({offset, get_slices_extrusions( + std::vector slices_extrusions{get_slices_extrusions( print, *layer, predicate, smooth_path, offset, extruder_id, previous_position - )}); + )}; + if (!slices_extrusions.empty()) { + result.push_back({offset, std::move(slices_extrusions)}); + } } } return result; @@ -561,4 +582,146 @@ std::vector get_extrusions( return extrusions; } +std::optional get_first_point(const SmoothPath &path) { + for (const SmoothPathElement & element : path) { + if (!element.path.empty()) { + return InstancePoint{element.path.front().point}; + } + } + return std::nullopt; +} + +std::optional get_first_point(const std::vector &smooth_paths) { + for (const SmoothPath &path : smooth_paths) { + if (auto result = get_first_point(path)) { + return result; + } + } + return std::nullopt; +} + +std::optional get_first_point(const std::vector &infill_ranges) { + for (const InfillRange &infill_range : infill_ranges) { + if (auto result = get_first_point(infill_range.items)) { + return result; + } + } + return std::nullopt; +} + +std::optional get_first_point(const std::vector &perimeters) { + for (const Perimeter &perimeter : perimeters) { + if (auto result = get_first_point(perimeter.smooth_path)) { + return result; + } + } + return std::nullopt; +} + +std::optional get_first_point(const std::vector &extrusions) { + for (const IslandExtrusions &island : extrusions) { + if (island.infill_first) { + if (auto result = get_first_point(island.infill_ranges)) { + return result; + } + if (auto result = get_first_point(island.perimeters)) { + return result; + } + } else { + if (auto result = get_first_point(island.perimeters)) { + return result; + } + if (auto result = get_first_point(island.infill_ranges)) { + return result; + } + } + } + return std::nullopt; +} + +std::optional get_first_point(const std::vector &extrusions) { + for (const SliceExtrusions &slice : extrusions) { + if (auto result = get_first_point(slice.common_extrusions)) { + return result; + } + } + return std::nullopt; +} + +std::optional get_first_point(const ExtruderExtrusions &extrusions) { + for (const auto&[_, path] : extrusions.skirt) { + if (auto result = get_first_point(path)) { + return result->local_point; + }; + } + for (const BrimPath &brim_path : extrusions.brim) { + if (auto result = get_first_point(brim_path.path)) { + return result->local_point; + }; + } + for (const OverridenExtrusions &overriden_extrusions : extrusions.overriden_extrusions) { + if (auto result = get_first_point(overriden_extrusions.slices_extrusions)) { + return result->local_point - overriden_extrusions.instance_offset; + } + } + + for (const NormalExtrusions &normal_extrusions : extrusions.normal_extrusions) { + for (const SupportPath &support_path : normal_extrusions.support_extrusions) { + if (auto result = get_first_point(support_path.path)) { + return result->local_point + normal_extrusions.instance_offset; + } + } + if (auto result = get_first_point(normal_extrusions.slices_extrusions)) { + return result->local_point + normal_extrusions.instance_offset; + } + } + + return std::nullopt; +} + +std::optional get_first_point(const std::vector &extrusions) { + if (extrusions.empty()) { + return std::nullopt; + } + + if (extrusions.front().wipe_tower_start) { + return extrusions.front().wipe_tower_start; + } + + for (const ExtruderExtrusions &extruder_extrusions : extrusions) { + if (auto result = get_first_point(extruder_extrusions)) { + return result; + } + } + + return std::nullopt; +} + +const PrintInstance * get_first_instance( + const std::vector &extrusions, + const std::vector &instances_to_print +) { + for (const ExtruderExtrusions &extruder_extrusions : extrusions) { + if (!extruder_extrusions.overriden_extrusions.empty()) { + for (std::size_t i{0}; i < instances_to_print.size(); ++i) { + const OverridenExtrusions &overriden_extrusions{extruder_extrusions.overriden_extrusions[i]}; + if (!is_empty(overriden_extrusions.slices_extrusions)) { + const InstanceToPrint &instance{instances_to_print[i]}; + return &instance.print_object.instances()[instance.instance_id]; + } + } + } + for (std::size_t i{0}; i < instances_to_print.size(); ++i) { + const InstanceToPrint &instance{instances_to_print[i]}; + const std::vector &support_extrusions{extruder_extrusions.normal_extrusions[i].support_extrusions}; + const std::vector &slices_extrusions{extruder_extrusions.normal_extrusions[i].slices_extrusions}; + + if (!support_extrusions.empty() || !is_empty(slices_extrusions)) { + return &instance.print_object.instances()[instance.instance_id]; + } + } + } + return nullptr; +} + } diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index f2df2560a9..3c2fb530e9 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -131,120 +131,12 @@ std::vector get_extrusions( std::optional previous_position ); -inline std::optional get_first_point(const SmoothPath &path) { - for (const SmoothPathElement & element : path) { - if (!element.path.empty()) { - return InstancePoint{element.path.front().point}; - } - } - return std::nullopt; -} +std::optional get_first_point(const std::vector &extrusions); -inline std::optional get_first_point(const std::vector &smooth_paths) { - for (const SmoothPath &path : smooth_paths) { - if (auto result = get_first_point(path)) { - return result; - } - } - return std::nullopt; -} - -inline std::optional get_first_point(const std::vector &infill_ranges) { - for (const InfillRange &infill_range : infill_ranges) { - if (auto result = get_first_point(infill_range.items)) { - return result; - } - } - return std::nullopt; -} - -inline std::optional get_first_point(const std::vector &perimeters) { - for (const Perimeter &perimeter : perimeters) { - if (auto result = get_first_point(perimeter.smooth_path)) { - return result; - } - } - return std::nullopt; -} - -inline std::optional get_first_point(const std::vector &extrusions) { - for (const IslandExtrusions &island : extrusions) { - if (island.infill_first) { - if (auto result = get_first_point(island.infill_ranges)) { - return result; - } - if (auto result = get_first_point(island.perimeters)) { - return result; - } - } else { - if (auto result = get_first_point(island.perimeters)) { - return result; - } - if (auto result = get_first_point(island.infill_ranges)) { - return result; - } - } - } - return std::nullopt; -} - -inline std::optional get_first_point(const std::vector &extrusions) { - for (const SliceExtrusions &slice : extrusions) { - if (auto result = get_first_point(slice.common_extrusions)) { - return result; - } - } - return std::nullopt; -} - -inline std::optional get_first_point(const ExtruderExtrusions &extrusions) { - for (const auto&[_, path] : extrusions.skirt) { - if (auto result = get_first_point(path)) { - return result->local_point; - }; - } - for (const BrimPath &brim_path : extrusions.brim) { - if (auto result = get_first_point(brim_path.path)) { - return result->local_point; - }; - } - for (const OverridenExtrusions &overriden_extrusions : extrusions.overriden_extrusions) { - if (auto result = get_first_point(overriden_extrusions.slices_extrusions)) { - return result->local_point - overriden_extrusions.instance_offset; - } - } - - for (const NormalExtrusions &normal_extrusions : extrusions.normal_extrusions) { - for (const SupportPath &support_path : normal_extrusions.support_extrusions) { - if (auto result = get_first_point(support_path.path)) { - return result->local_point + normal_extrusions.instance_offset; - } - } - if (auto result = get_first_point(normal_extrusions.slices_extrusions)) { - return result->local_point + normal_extrusions.instance_offset; - } - } - - return std::nullopt; -} - -inline std::optional get_first_point(const std::vector &extrusions) { - if (extrusions.empty()) { - return std::nullopt; - } - - if (extrusions.front().wipe_tower_start) { - return extrusions.front().wipe_tower_start; - } - - for (const ExtruderExtrusions &extruder_extrusions : extrusions) { - if (auto result = get_first_point(extruder_extrusions)) { - return result; - } - } - - return std::nullopt; -} +const PrintInstance * get_first_instance( + const std::vector &extrusions, + const std::vector &instances_to_print +); } #endif // slic3r_GCode_ExtrusionOrder_hpp_