diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f322ad0526..39793f5111 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2603,9 +2603,8 @@ LayerResult GCodeGenerator::process_layer( this->set_origin(0., 0.); m_avoid_crossing_perimeters.use_external_mp(); - for (const ExtrusionEntity *ee : extruder_extrusions.brim) { - gcode += this->extrude_entity({ *ee, false }, smooth_path_caches.global(), "brim"sv, m_config.support_material_speed.value); - } + + gcode += this->extrude_brim(extruder_extrusions.brim, "brim", m_config.support_material_speed.value); m_avoid_crossing_perimeters.use_external_mp(false); // Allow a straight travel move to the first object point. m_avoid_crossing_perimeters.disable_once(); @@ -2957,60 +2956,6 @@ std::string GCodeGenerator::extrude_perimeter( return gcode; } -std::string GCodeGenerator::extrude_loop(const ExtrusionLoop &loop_src, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed) -{ - // Extrude all loops CCW unless CW movements are prefered. - const bool is_hole = loop_src.is_clockwise(); - const bool reverse_loop = m_config.prefer_clockwise_movements ? !is_hole : is_hole; - - Point seam_point = this->last_position.has_value() ? *this->last_position : Point::Zero(); - if (!m_config.spiral_vase && comment_is_perimeter(description)) { - assert(m_layer != nullptr); - seam_point = loop_src.seam; - } - // Because the G-code export has 1um resolution, don't generate segments shorter than 1.5 microns, - // thus empty path segments will not be produced by G-code export. - GCode::SmoothPath smooth_path = smooth_path_cache.resolve_or_fit_split_with_seam(loop_src, reverse_loop, m_scaled_resolution, seam_point, scaled(0.0015)); - - // Clip the path to avoid the extruder to get exactly on the first point of the loop; - // if polyline was shorter than the clipping distance we'd get a null polyline, so - // we discard it in that case. - if (m_enable_loop_clipping) - clip_end(smooth_path, scaled(EXTRUDER_CONFIG(nozzle_diameter)) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER, scaled(GCode::ExtrusionOrder::min_gcode_segment_length)); - - if (smooth_path.empty()) - return {}; - - assert(validate_smooth_path(smooth_path, ! m_enable_loop_clipping)); - - // Apply the small perimeter speed. - if (loop_src.paths.front().role().is_perimeter() && loop_src.length() <= SMALL_PERIMETER_LENGTH && speed == -1) - speed = m_config.small_perimeter_speed.get_abs_value(m_config.perimeter_speed); - - // Extrude along the smooth path. - std::string gcode; - for (const GCode::SmoothPathElement &el : smooth_path) - gcode += this->_extrude(el.path_attributes, el.path, description, speed); - - // reset acceleration - gcode += m_writer.set_print_acceleration(fast_round_up(m_config.default_acceleration.value)); - - if (m_wipe.enabled()) { - // Wipe will hide the seam. - m_wipe.set_path(std::move(smooth_path)); - } else if (loop_src.paths.back().role().is_external_perimeter() && m_layer != nullptr && m_config.perimeters.value > 1) { - // Only wipe inside if the wipe along the perimeter is disabled. - // Make a little move inwards before leaving loop. - if (std::optional pt = wipe_hide_seam(smooth_path, reverse_loop, scale_(EXTRUDER_CONFIG(nozzle_diameter))); pt) { - // Generate the seam hiding travel move. - gcode += m_writer.travel_to_xy(this->point_to_gcode(*pt), "move inwards before travel"); - this->last_position = *pt; - } - } - - return gcode; -} - std::string GCodeGenerator::extrude_skirt( GCode::SmoothPath smooth_path, const ExtrusionFlow &extrusion_flow_override, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed) @@ -3035,6 +2980,34 @@ std::string GCodeGenerator::extrude_skirt( return gcode; } +std::string GCodeGenerator::extrude_brim( + const std::vector &brim, + const std::string &extrusion_name, + const double speed +) { + std::string gcode{}; + + for (const auto &[path, is_loop] : brim) { + // extrude along the path + for (const GCode::SmoothPathElement &el : path) + gcode += this->_extrude(el.path_attributes, el.path, extrusion_name, speed); + + + // reset acceleration + gcode += m_writer.set_print_acceleration((unsigned int)floor(m_config.default_acceleration.value + 0.5)); + + if (is_loop) { + m_wipe.set_path(GCode::SmoothPath{path}); + } else { + GCode::SmoothPath reversed_smooth_path{path}; + GCode::reverse(reversed_smooth_path); + m_wipe.set_path(std::move(reversed_smooth_path)); + } + } + + return gcode; +}; + std::string GCodeGenerator::extrude_infill_range( const std::vector &infill_range, const PrintRegion ®ion, @@ -3122,19 +3095,6 @@ std::string GCodeGenerator::extrude_multi_path(const ExtrusionMultiPath &multipa return gcode; } -std::string GCodeGenerator::extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed) -{ - if (const ExtrusionPath *path = dynamic_cast(&entity.extrusion_entity())) - return this->extrude_path(*path, entity.flipped(), smooth_path_cache, description, speed); - else if (const ExtrusionMultiPath *multipath = dynamic_cast(&entity.extrusion_entity())) - return this->extrude_multi_path(*multipath, entity.flipped(), smooth_path_cache, description, speed); - else if (const ExtrusionLoop *loop = dynamic_cast(&entity.extrusion_entity())) - return this->extrude_loop(*loop, smooth_path_cache, description, speed); - else - throw Slic3r::InvalidArgument("Invalid argument supplied to extrude()"); - return {}; -} - std::string GCodeGenerator::extrude_path(const ExtrusionPath &path, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, std::string_view description, double speed) { Geometry::ArcWelder::Path smooth_path = smooth_path_cache.resolve_or_fit(path, reverse, m_scaled_resolution); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 04809992dd..c3c455fa77 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -281,10 +281,7 @@ private: coordf_t print_z, bool vase_mode ); - std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.); - std::string extrude_perimeter(const GCode::ExtrusionOrder::Perimeter &perimeter, const std::string_view description); - std::string extrude_loop(const ExtrusionLoop &loop, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.); std::string extrude_skirt(GCode::SmoothPath smooth_path, const ExtrusionFlow &extrusion_flow_override, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed); @@ -307,6 +304,12 @@ private: const GCode::SmoothPathCache &smooth_path_cache ); + std::string extrude_brim( + const std::vector &brim, + const std::string &extrusion_name, + const double speed + ); + std::string extrude_infill_range( const std::vector &infill_range, const PrintRegion ®ion, diff --git a/src/libslic3r/GCode/ExtrusionOrder.cpp b/src/libslic3r/GCode/ExtrusionOrder.cpp index f58da71ebd..80c10a37bb 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.cpp +++ b/src/libslic3r/GCode/ExtrusionOrder.cpp @@ -497,8 +497,14 @@ std::vector get_extrusions( // 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}); + for (const ExtrusionEntity *entity : print.brim().entities) { + const ExtrusionEntityReference entity_reference{*entity, false}; + std::optional last_position{get_instance_point(previous_position, {0, 0})}; + SmoothPath path{smooth_path(nullptr, entity_reference, extruder_id, last_position)}; + previous_position = get_gcode_point(last_position, {0, 0}); + const bool is_loop{dynamic_cast(entity) != nullptr}; + extruder_extrusions.brim.push_back({std::move(path), is_loop}); + } get_brim = false; } diff --git a/src/libslic3r/GCode/ExtrusionOrder.hpp b/src/libslic3r/GCode/ExtrusionOrder.hpp index ecbbf13f7d..5fbc507f94 100644 --- a/src/libslic3r/GCode/ExtrusionOrder.hpp +++ b/src/libslic3r/GCode/ExtrusionOrder.hpp @@ -89,10 +89,15 @@ using PathSmoothingFunction = std::function &previous_position )>; +struct BrimPath { + SmoothPath path; + bool is_loop; +}; + struct ExtruderExtrusions { unsigned extruder_id; std::vector> skirt; - ExtrusionEntitiesPtr brim; + std::vector brim; std::vector> overriden_extrusions; std::vector normal_extrusions; };