diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index b50abeda29..19515d53e8 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2308,7 +2308,7 @@ std::vector GCodeGenerator::get_sorte GCode::SmoothPath result; if (auto loop = dynamic_cast(extrusion_entity)) { - Point seam_point = previous_position ? previous_position->value : Point::Zero(); + Point seam_point = previous_position ? previous_position->local_point : Point::Zero(); if (loop->role().is_perimeter() && layer != nullptr) { seam_point = this->m_seam_placer.place_seam(layer, *loop, seam_point); } @@ -2457,6 +2457,8 @@ LayerResult GCodeGenerator::process_layer( const std::vector extrusions{ this->get_sorted_extrusions(print, layers, layer_tools, instances_to_print, smooth_path_caches, first_layer)}; + const std::optional first_point{GCode::ExtrusionOrder::get_first_point(extrusions)}; + std::string gcode; assert(is_decimal_separator_point()); // for the sprintfs @@ -2552,6 +2554,7 @@ LayerResult GCodeGenerator::process_layer( } } + // Extrude the skirt, brim, support, perimeters, infill ordered by the extruders. for (const ExtruderExtrusions &extruder_extrusions : extrusions) { diff --git a/src/libslic3r/GCode/ExtrusionOrder.cpp b/src/libslic3r/GCode/ExtrusionOrder.cpp index b6524181e7..9310847c7b 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.cpp +++ b/src/libslic3r/GCode/ExtrusionOrder.cpp @@ -29,7 +29,7 @@ int get_extruder_id( } Point get_gcode_point(const InstancePoint &point, const Point &offset) { - return point.value + offset; + return point.local_point + offset; } InstancePoint get_instance_point(const Point &point, const Point &offset) { @@ -173,7 +173,7 @@ std::vector extract_infill_ranges( )}; const std::optional previous_instance_point{get_instance_point(previous_position, offset)}; - const Point* start_near{previous_instance_point ? &(previous_instance_point->value) : nullptr}; + const Point* start_near{previous_instance_point ? &(previous_instance_point->local_point) : nullptr}; const ExtrusionEntityReferences sorted_extrusions{sort_fill_extrusions(extrusions, start_near)}; std::vector paths; @@ -501,15 +501,17 @@ std::vector get_extrusions( std::vector extrusions; for (const unsigned int extruder_id : layer_tools.extruders) { + ExtruderExtrusions extruder_extrusions{extruder_id}; + 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 = Point::new_scale(wipe_tower->transform_wt_pt(tool_change.end_pos)); current_extruder_id = tool_change.new_tool; + extruder_extrusions.wipe_tower_start = Point::new_scale(wipe_tower->transform_wt_pt(tool_change.start_pos)); } } - 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; diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index 6bdf6f1c4a..e3bc49f065 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -92,7 +92,7 @@ struct OverridenExtrusions { }; struct InstancePoint { - Point value; + Point local_point; }; using PathSmoothingFunction = std::function brim; std::vector overriden_extrusions; std::vector normal_extrusions; + std::optional wipe_tower_start; }; static constexpr const double min_gcode_segment_length = 0.002; @@ -129,6 +130,121 @@ std::vector get_extrusions( bool get_brim, 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; +} + +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 BrimPath &brim_path : extrusions.brim) { + if (auto result = get_first_point(brim_path.path)) { + return result->local_point; + }; + } + for (const auto&[_, path] : extrusions.skirt) { + if (auto result = get_first_point(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; +} } #endif // slic3r_GCode_ExtrusionOrder_hpp_