From 0cc0e82a936c53a522cebed37f12c60b157ec83d Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 3 Mar 2024 23:09:57 +0800 Subject: [PATCH 1/9] Allow apply scarf joint seams to perimeters without sharp corners only --- src/libslic3r/ExtrusionEntity.cpp | 59 +++++++++++++++++++++++++++ src/libslic3r/ExtrusionEntity.hpp | 3 +- src/libslic3r/GCode.cpp | 5 ++- src/libslic3r/Layer.cpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 6 +++ src/libslic3r/PrintConfig.hpp | 1 + src/libslic3r/PrintObject.cpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 10 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 6b75c0ee98..1f9b913821 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "Utils.hpp" #define L(s) (s) @@ -340,6 +341,64 @@ double ExtrusionLoop::min_mm3_per_mm() const return min_mm3_per_mm; } +// Orca: This function is used to check if the loop is smooth(continuous) or not. +// TODO: the main logic is largly copied from the calculate_polygon_angles_at_vertices function in SeamPlacer file. Need to refactor the code in the future. +bool ExtrusionLoop::is_smooth(double angle_threshold, double min_arm_length) const +{ + // go through all the points in the loop and check if the angle between two segments(AB and BC) is less than the threshold + size_t idx_prev = 0; + size_t idx_curr = 0; + size_t idx_next = 0; + + float distance_to_prev = 0; + float distance_to_next = 0; + + Points points; + collect_points(points); + + std::vector lengths{}; + for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) { + lengths.push_back((unscale(points[point_idx]) - unscale(points[point_idx + 1])).norm()); + } + lengths.push_back(std::max((unscale(points[0]) - unscale(points[points.size() - 1])).norm(), 0.1)); + + // push idx_prev far enough back as initialization + while (distance_to_prev < min_arm_length) { + idx_prev = Slic3r::prev_idx_modulo(idx_prev, points.size()); + distance_to_prev += lengths[idx_prev]; + } + + for (size_t _i = 0; _i < points.size(); ++_i) { + // pull idx_prev to current as much as possible, while respecting the min_arm_length + while (distance_to_prev - lengths[idx_prev] > min_arm_length) { + distance_to_prev -= lengths[idx_prev]; + idx_prev = Slic3r::next_idx_modulo(idx_prev, points.size()); + } + + // push idx_next forward as far as needed + while (distance_to_next < min_arm_length) { + distance_to_next += lengths[idx_next]; + idx_next = Slic3r::next_idx_modulo(idx_next, points.size()); + } + + // Calculate angle between idx_prev, idx_curr, idx_next. + const Point& p0 = points[idx_prev]; + const Point& p1 = points[idx_curr]; + const Point& p2 = points[idx_next]; + if (abs(angle(p1 - p0, p2 - p1)) > angle_threshold) { + return false; + } + + // increase idx_curr by one + float curr_distance = lengths[idx_curr]; + idx_curr++; + distance_to_prev += curr_distance; + distance_to_next -= curr_distance; + } + + return true; +} + ExtrusionLoopSloped::ExtrusionLoopSloped(ExtrusionPaths& original_paths, double seam_gap, double slope_min_length, diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index cb350386e9..2ff7d5fb0b 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -479,7 +479,8 @@ class ExtrusionLoop : public ExtrusionEntity append(dst, p.polyline.points); } double total_volume() const override { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; } - + // check if the loop is smooth, angle_threshold is in radians, default is 10 degrees + bool is_smooth(double angle_threshold = 0.174, double min_arm_length = 0.025) const; //static inline std::string role_to_string(ExtrusionLoopRole role); #ifndef NDEBUG diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8253551b7f..0b55ac069d 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4557,11 +4557,14 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou loop.split_at(last_pos, false); const auto seam_scarf_type = m_config.seam_slope_type.value; - const bool enable_seam_slope = ((seam_scarf_type == SeamScarfType::External && !is_hole) || seam_scarf_type == SeamScarfType::All) && + bool enable_seam_slope = ((seam_scarf_type == SeamScarfType::External && !is_hole) || seam_scarf_type == SeamScarfType::All) && !m_config.spiral_mode && (loop.role() == erExternalPerimeter || (loop.role() == erPerimeter && m_config.seam_slope_inner_walls)) && layer_id() > 0; + if (enable_seam_slope && m_config.seam_slope_conditional.value) + enable_seam_slope = enable_seam_slope && loop.is_smooth(0.174, EXTRUDER_CONFIG(nozzle_diameter)); + // 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 diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index edea7411ef..f531093f11 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -186,6 +186,7 @@ void Layer::make_perimeters() && config.fuzzy_skin_point_distance == other_config.fuzzy_skin_point_distance && config.fuzzy_skin_first_layer == other_config.fuzzy_skin_first_layer && config.seam_slope_type == other_config.seam_slope_type + && config.seam_slope_conditional == other_config.seam_slope_conditional && config.seam_slope_start_height == other_config.seam_slope_start_height && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop && config.seam_slope_min_length == other_config.seam_slope_min_length diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index f9ed88d4f1..1440059709 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -820,7 +820,7 @@ static std::vector s_Preset_print_options { "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic", "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", - "seam_slope_type", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", + "seam_slope_type", "seam_slope_conditional", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 984192bd9f..5bc43a0cb9 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3547,6 +3547,12 @@ def = this->add("filament_loading_speed", coFloats); def->enum_labels.push_back(L("Contour and hole")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(SeamScarfType::None)); + + def = this->add("seam_slope_conditional", coBool); + def->label = L("Conditional scarf joint"); + def->tooltip = L("Apply scarf joints only to smooth perimeters where traditional seams do not conceal the seams at sharp corners effectively."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(true)); def = this->add("seam_slope_start_height", coFloatOrPercent); def->label = L("Scarf start height"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 07be77ab3d..cf0ce7be66 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -953,6 +953,7 @@ PRINT_CONFIG_CLASS_DEFINE( // Orca: seam slopes ((ConfigOptionEnum, seam_slope_type)) + ((ConfigOptionBool, seam_slope_conditional)) ((ConfigOptionFloatOrPercent, seam_slope_start_height)) ((ConfigOptionBool, seam_slope_entire_loop)) ((ConfigOptionFloat, seam_slope_min_length)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 2233057ece..37773752b8 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1143,6 +1143,7 @@ bool PrintObject::invalidate_state_by_config_options( } else if ( opt_key == "seam_position" || opt_key == "seam_slope_type" + || opt_key == "seam_slope_conditional" || opt_key == "seam_slope_start_height" || opt_key == "seam_slope_entire_loop" || opt_key == "seam_slope_min_length" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 1c0667b298..974fd53cc5 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -756,6 +756,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_field("seam_slope_type", !has_spiral_vase); bool has_seam_slope = !has_spiral_vase && config->opt_enum("seam_slope_type") != SeamScarfType::None; + toggle_line("seam_slope_conditional", has_seam_slope); toggle_line("seam_slope_start_height", has_seam_slope); toggle_line("seam_slope_entire_loop", has_seam_slope); toggle_line("seam_slope_min_length", has_seam_slope); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 212fdf6f2f..e56461d056 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1977,6 +1977,7 @@ void TabPrint::build() optgroup->append_single_option_line("staggered_inner_seams", "seam"); optgroup->append_single_option_line("seam_gap","seam"); optgroup->append_single_option_line("seam_slope_type"); + optgroup->append_single_option_line("seam_slope_conditional"); optgroup->append_single_option_line("seam_slope_start_height"); optgroup->append_single_option_line("seam_slope_entire_loop"); optgroup->append_single_option_line("seam_slope_min_length"); From 6f1e3f12be616373b471f99322a98bec4a0e3aca Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 4 Mar 2024 18:25:28 +0800 Subject: [PATCH 2/9] 1. Fix an error when detect whether a loop is smooth 2. Expose scarf_angle_threshold to UI --- src/libslic3r/ExtrusionEntity.cpp | 4 ++-- src/libslic3r/GCode.cpp | 8 +++++--- src/libslic3r/Layer.cpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 15 +++++++++++++-- src/libslic3r/PrintConfig.hpp | 1 + src/libslic3r/PrintObject.cpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 9 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 1f9b913821..47903aa1a1 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -353,8 +353,8 @@ bool ExtrusionLoop::is_smooth(double angle_threshold, double min_arm_length) con float distance_to_prev = 0; float distance_to_next = 0; - Points points; - collect_points(points); + const auto _polyline = as_polyline(); + const Points& points = _polyline.points; std::vector lengths{}; for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) { diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0b55ac069d..5c3bb18f60 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -23,6 +23,7 @@ #include "GCode/ExtrusionProcessor.hpp" #include #include +#include #include #include #include @@ -4562,9 +4563,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou (loop.role() == erExternalPerimeter || (loop.role() == erPerimeter && m_config.seam_slope_inner_walls)) && layer_id() > 0; - if (enable_seam_slope && m_config.seam_slope_conditional.value) - enable_seam_slope = enable_seam_slope && loop.is_smooth(0.174, EXTRUDER_CONFIG(nozzle_diameter)); - + if (enable_seam_slope && m_config.seam_slope_conditional.value) { + enable_seam_slope = enable_seam_slope && + loop.is_smooth((180 - m_config.scarf_angle_threshold.value) * M_PI / 180., EXTRUDER_CONFIG(nozzle_diameter)); + } // 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 diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index f531093f11..692d73e6f8 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -187,6 +187,7 @@ void Layer::make_perimeters() && config.fuzzy_skin_first_layer == other_config.fuzzy_skin_first_layer && config.seam_slope_type == other_config.seam_slope_type && config.seam_slope_conditional == other_config.seam_slope_conditional + && config.scarf_angle_threshold == other_config.scarf_angle_threshold && config.seam_slope_start_height == other_config.seam_slope_start_height && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop && config.seam_slope_min_length == other_config.seam_slope_min_length diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 1440059709..15dfcafe34 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -820,7 +820,7 @@ static std::vector s_Preset_print_options { "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic", "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", - "seam_slope_type", "seam_slope_conditional", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", + "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 5bc43a0cb9..12f5bc0869 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3552,8 +3552,19 @@ def = this->add("filament_loading_speed", coFloats); def->label = L("Conditional scarf joint"); def->tooltip = L("Apply scarf joints only to smooth perimeters where traditional seams do not conceal the seams at sharp corners effectively."); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionBool(true)); - + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("scarf_angle_threshold", coInt); + def->label = L("Conditional angle threshold"); + def->tooltip = L( + "This option sets the threshold angle for applying a conditional scarf joint seam.\nIf the maximum angle within the perimeter loop " + "exceeds this value (indicating the absence of sharp corners), a scarf joint seam will be used. The default value is 155°."); + def->mode = comAdvanced; + def->sidetext = L("°"); + def->min = 0; + def->max = 180; + def->set_default_value(new ConfigOptionInt(155)); + def = this->add("seam_slope_start_height", coFloatOrPercent); def->label = L("Scarf start height"); def->tooltip = L("Start height of the scarf.\n" diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index cf0ce7be66..cb8645b9bd 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -954,6 +954,7 @@ PRINT_CONFIG_CLASS_DEFINE( // Orca: seam slopes ((ConfigOptionEnum, seam_slope_type)) ((ConfigOptionBool, seam_slope_conditional)) + ((ConfigOptionInt, scarf_angle_threshold)) ((ConfigOptionFloatOrPercent, seam_slope_start_height)) ((ConfigOptionBool, seam_slope_entire_loop)) ((ConfigOptionFloat, seam_slope_min_length)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 37773752b8..e722e12ea8 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1144,6 +1144,7 @@ bool PrintObject::invalidate_state_by_config_options( opt_key == "seam_position" || opt_key == "seam_slope_type" || opt_key == "seam_slope_conditional" + || opt_key == "scarf_angle_threshold" || opt_key == "seam_slope_start_height" || opt_key == "seam_slope_entire_loop" || opt_key == "seam_slope_min_length" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 974fd53cc5..a6d613b3bd 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -763,6 +763,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_line("seam_slope_steps", has_seam_slope); toggle_line("seam_slope_inner_walls", has_seam_slope); toggle_field("seam_slope_min_length", !config->opt_bool("seam_slope_entire_loop")); + toggle_line("scarf_angle_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional")); } void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index e56461d056..d4884b4a35 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1978,6 +1978,7 @@ void TabPrint::build() optgroup->append_single_option_line("seam_gap","seam"); optgroup->append_single_option_line("seam_slope_type"); optgroup->append_single_option_line("seam_slope_conditional"); + optgroup->append_single_option_line("scarf_angle_threshold"); optgroup->append_single_option_line("seam_slope_start_height"); optgroup->append_single_option_line("seam_slope_entire_loop"); optgroup->append_single_option_line("seam_slope_min_length"); From 595c39d7fbb7d0fc10f60553147f778b86e32aa2 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 4 Mar 2024 18:37:19 +0800 Subject: [PATCH 3/9] fix linux build error --- src/libslic3r/GCode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 5c3bb18f60..3981a610f3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -23,7 +23,6 @@ #include "GCode/ExtrusionProcessor.hpp" #include #include -#include #include #include #include From 1aa8e6224f0420847b3a394ffc6e15919386f1ea Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 4 Mar 2024 20:35:28 +0800 Subject: [PATCH 4/9] minor code changes --- src/libslic3r/GCode.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3981a610f3..aef0fc8546 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4563,8 +4563,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou layer_id() > 0; if (enable_seam_slope && m_config.seam_slope_conditional.value) { - enable_seam_slope = enable_seam_slope && - loop.is_smooth((180 - m_config.scarf_angle_threshold.value) * M_PI / 180., EXTRUDER_CONFIG(nozzle_diameter)); + enable_seam_slope = loop.is_smooth((180 - m_config.scarf_angle_threshold.value) * M_PI / 180., EXTRUDER_CONFIG(nozzle_diameter)); } // 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 From 798419f3d6f648b64283ae5438f219c373d312db Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 4 Mar 2024 23:17:02 +0800 Subject: [PATCH 5/9] Support slowdown speed for scarf joint only --- src/libslic3r/GCode.cpp | 7 +++++++ src/libslic3r/Layer.cpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 14 ++++++++++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/PrintObject.cpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 8 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index aef0fc8546..1a2874544b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5085,6 +5085,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double new_speed = m_config.get_abs_value(overhang_speed_key_map[overhang_degree].c_str()); speed = new_speed == 0.0 ? speed : new_speed; } + + if (sloped) { + speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("inner_wall_speed"))); + } } else if (path.role() == erExternalPerimeter) { speed = m_config.get_abs_value("outer_wall_speed"); if (m_config.overhang_speed_classic.value && m_config.enable_overhang_speed.value && @@ -5092,6 +5096,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double new_speed = m_config.get_abs_value(overhang_speed_key_map[overhang_degree].c_str()); speed = new_speed == 0.0 ? speed : new_speed; } + if (sloped) { + speed = std::min(speed, m_config.scarf_joint_speed.get_abs_value(m_config.get_abs_value("outer_wall_speed"))); + } } else if(path.role() == erInternalBridgeInfill) { speed = m_config.get_abs_value("internal_bridge_speed"); diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 692d73e6f8..d753a06610 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -188,6 +188,7 @@ void Layer::make_perimeters() && config.seam_slope_type == other_config.seam_slope_type && config.seam_slope_conditional == other_config.seam_slope_conditional && config.scarf_angle_threshold == other_config.scarf_angle_threshold + && config.scarf_joint_speed == other_config.scarf_joint_speed && config.seam_slope_start_height == other_config.seam_slope_start_height && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop && config.seam_slope_min_length == other_config.seam_slope_min_length diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 15dfcafe34..83d37b8bd2 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -820,7 +820,7 @@ static std::vector s_Preset_print_options { "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic", "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", - "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", + "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 12f5bc0869..eaad44d965 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3565,6 +3565,20 @@ def = this->add("filament_loading_speed", coFloats); def->max = 180; def->set_default_value(new ConfigOptionInt(155)); + def = this->add("scarf_joint_speed", coFloatOrPercent); + def->label = L("Scarf joint speed"); + def->category = L("Quality"); + def->tooltip = L( + "This option sets the printing speed for scarf joints. It is recommended to print scarf joints at a slow speed (less than 100 " + "mm/s). Additionally, enabling 'Extrusion rate smoothing' is advised if this speed significantly differs from the outer wall " + "speed. Should the speed set here exceed the outer wall speed, the outer wall speed will be utilized instead. When expressed as a " + "percentage (e.g., 80%), the value is calculated based on the outer wall speed. The default value is 100%."); + def->sidetext = L("mm/s or %"); + def->ratio_over = "outer_wall_speed"; + def->min = 1; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); + def = this->add("seam_slope_start_height", coFloatOrPercent); def->label = L("Scarf start height"); def->tooltip = L("Start height of the scarf.\n" diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index cb8645b9bd..8b7d520715 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -960,6 +960,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, seam_slope_min_length)) ((ConfigOptionInt, seam_slope_steps)) ((ConfigOptionBool, seam_slope_inner_walls)) + ((ConfigOptionFloatOrPercent, scarf_joint_speed)) + ) PRINT_CONFIG_CLASS_DEFINE( diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index e722e12ea8..3423cb6698 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1145,6 +1145,7 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "seam_slope_type" || opt_key == "seam_slope_conditional" || opt_key == "scarf_angle_threshold" + || opt_key == "scarf_joint_speed" || opt_key == "seam_slope_start_height" || opt_key == "seam_slope_entire_loop" || opt_key == "seam_slope_min_length" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index a6d613b3bd..f9ce6e608f 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -762,6 +762,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_line("seam_slope_min_length", has_seam_slope); toggle_line("seam_slope_steps", has_seam_slope); toggle_line("seam_slope_inner_walls", has_seam_slope); + toggle_line("scarf_joint_speed", has_seam_slope); toggle_field("seam_slope_min_length", !config->opt_bool("seam_slope_entire_loop")); toggle_line("scarf_angle_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional")); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 222adc3877..9495015923 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1979,6 +1979,7 @@ void TabPrint::build() optgroup->append_single_option_line("seam_slope_type", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_conditional", "seam#scarf-joint-seam"); optgroup->append_single_option_line("scarf_angle_threshold", "seam#scarf-joint-seam"); + optgroup->append_single_option_line("scarf_joint_speed", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_start_height", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_entire_loop", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_min_length", "seam#scarf-joint-seam"); From c9603424f262a8fa7590e92d7ea8e729fc96e9f5 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Mon, 4 Mar 2024 23:20:55 +0800 Subject: [PATCH 6/9] update tips --- src/libslic3r/PrintConfig.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index eaad44d965..2053697e49 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3570,11 +3570,11 @@ def = this->add("filament_loading_speed", coFloats); def->category = L("Quality"); def->tooltip = L( "This option sets the printing speed for scarf joints. It is recommended to print scarf joints at a slow speed (less than 100 " - "mm/s). Additionally, enabling 'Extrusion rate smoothing' is advised if this speed significantly differs from the outer wall " - "speed. Should the speed set here exceed the outer wall speed, the outer wall speed will be utilized instead. When expressed as a " - "percentage (e.g., 80%), the value is calculated based on the outer wall speed. The default value is 100%."); + "mm/s). It's also advisable to enable 'Extrusion rate smoothing' if the set speed varies significantly from the speed of the " + "outer or inner walls. If the speed specified here is higher than the speed of the outer or inner walls, the printer will default " + "to the slower of the two speeds. When specified as a percentage (e.g., 80%), the speed is calculated based on the respective " + "outer or inner wall speed. The default value is set to 100%."); def->sidetext = L("mm/s or %"); - def->ratio_over = "outer_wall_speed"; def->min = 1; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); From 6b0fc5149d4baa3f5088564e2d74fca5be652a98 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Tue, 5 Mar 2024 22:24:06 +0800 Subject: [PATCH 7/9] improve the logic a bit --- src/libslic3r/ExtrusionEntity.cpp | 7 ++++--- src/libslic3r/GCode.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/ExtrusionEntity.cpp b/src/libslic3r/ExtrusionEntity.cpp index 47903aa1a1..dee7477939 100644 --- a/src/libslic3r/ExtrusionEntity.cpp +++ b/src/libslic3r/ExtrusionEntity.cpp @@ -353,8 +353,8 @@ bool ExtrusionLoop::is_smooth(double angle_threshold, double min_arm_length) con float distance_to_prev = 0; float distance_to_next = 0; - const auto _polyline = as_polyline(); - const Points& points = _polyline.points; + const auto _polygon = polygon(); + const Points& points = _polygon.points; std::vector lengths{}; for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) { @@ -385,7 +385,8 @@ bool ExtrusionLoop::is_smooth(double angle_threshold, double min_arm_length) con const Point& p0 = points[idx_prev]; const Point& p1 = points[idx_curr]; const Point& p2 = points[idx_next]; - if (abs(angle(p1 - p0, p2 - p1)) > angle_threshold) { + const auto a = angle(p0 - p1, p2 - p1); + if (a > 0 ? a < angle_threshold : a > -angle_threshold) { return false; } diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1a2874544b..aa381298d0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4563,7 +4563,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou layer_id() > 0; if (enable_seam_slope && m_config.seam_slope_conditional.value) { - enable_seam_slope = loop.is_smooth((180 - m_config.scarf_angle_threshold.value) * M_PI / 180., EXTRUDER_CONFIG(nozzle_diameter)); + enable_seam_slope = loop.is_smooth(m_config.scarf_angle_threshold.value * M_PI / 180., EXTRUDER_CONFIG(nozzle_diameter)); } // 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 From 402a3046c80bd3aaec8aaab9d24087d4363cf10b Mon Sep 17 00:00:00 2001 From: SoftFever Date: Thu, 7 Mar 2024 20:57:42 +0800 Subject: [PATCH 8/9] Fixed a bug that scarf speed may not respected for overhangs --- src/libslic3r/GCode.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index aa381298d0..09377c2e3c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5182,6 +5182,9 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, (is_bridge(path.role()) || is_perimeter(path.role()))) { bool is_external = is_external_perimeter(path.role()); double ref_speed = is_external ? m_config.get_abs_value("outer_wall_speed") : m_config.get_abs_value("inner_wall_speed"); + if (sloped) { + ref_speed = std::min(ref_speed, m_config.scarf_joint_speed.get_abs_value(ref_speed)); + } ConfigOptionPercents overhang_overlap_levels({75, 50, 25, 13, 12.99, 0}); if (m_config.slowdown_for_curled_perimeters){ @@ -5245,6 +5248,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } double F = speed * 60; // convert mm/sec to mm/min + if(abs(F - 5753.504) < 0.002) + { + std::cout << "F: " << F << std::endl; + } //Orca: process custom gcode for extrusion role change if (path.role() != m_last_extrusion_role && !m_config.change_extrusion_role_gcode.value.empty()) { From 5cc279d5bcb5656f18edf9fcd4f0d0c5369dc44f Mon Sep 17 00:00:00 2001 From: SoftFever Date: Thu, 7 Mar 2024 22:14:45 +0800 Subject: [PATCH 9/9] Add a new scarf flow ratio option --- src/libslic3r/GCode.cpp | 2 ++ src/libslic3r/Layer.cpp | 1 + src/libslic3r/Preset.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 7 +++++++ src/libslic3r/PrintConfig.hpp | 2 ++ src/libslic3r/PrintObject.cpp | 1 + src/slic3r/GUI/ConfigManipulation.cpp | 1 + src/slic3r/GUI/Tab.cpp | 1 + 8 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 09377c2e3c..3b68d6ecf3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5071,6 +5071,8 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, _mm3_per_mm *= m_config.bottom_solid_infill_flow_ratio; else if (path.role() == erInternalBridgeInfill) _mm3_per_mm *= m_config.internal_bridge_flow; + else if(sloped) + _mm3_per_mm *= m_config.scarf_joint_flow_ratio; double e_per_mm = m_writer.extruder()->e_per_mm3() * _mm3_per_mm; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index d753a06610..6487ddb40a 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -189,6 +189,7 @@ void Layer::make_perimeters() && config.seam_slope_conditional == other_config.seam_slope_conditional && config.scarf_angle_threshold == other_config.scarf_angle_threshold && config.scarf_joint_speed == other_config.scarf_joint_speed + && config.scarf_joint_flow_ratio == other_config.scarf_joint_flow_ratio && config.seam_slope_start_height == other_config.seam_slope_start_height && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop && config.seam_slope_min_length == other_config.seam_slope_min_length diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 83d37b8bd2..b99af03736 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -820,7 +820,7 @@ static std::vector s_Preset_print_options { "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", "tree_support_branch_angle_organic", "hole_to_polyhole", "hole_to_polyhole_threshold", "hole_to_polyhole_twisted", "mmu_segmented_region_max_width", "mmu_segmented_region_interlocking_depth", "small_area_infill_flow_compensation", "small_area_infill_flow_compensation_model", - "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", + "seam_slope_type", "seam_slope_conditional", "scarf_angle_threshold", "scarf_joint_speed", "scarf_joint_flow_ratio", "seam_slope_start_height", "seam_slope_entire_loop", "seam_slope_min_length", "seam_slope_steps", "seam_slope_inner_walls", }; static std::vector s_Preset_filament_options { diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 2053697e49..63a7a96546 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -3579,6 +3579,13 @@ def = this->add("filament_loading_speed", coFloats); def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloatOrPercent(100, true)); + def = this->add("scarf_joint_flow_ratio", coFloat); + def->label = L("Scarf joint flow ratio"); + def->tooltip = L("This factor affects the amount of material for scarf joints."); + def->mode = comAdvanced; + def->max = 2; + def->set_default_value(new ConfigOptionFloat(1)); + def = this->add("seam_slope_start_height", coFloatOrPercent); def->label = L("Scarf start height"); def->tooltip = L("Start height of the scarf.\n" diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8b7d520715..3129fd3589 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -961,6 +961,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionInt, seam_slope_steps)) ((ConfigOptionBool, seam_slope_inner_walls)) ((ConfigOptionFloatOrPercent, scarf_joint_speed)) + ((ConfigOptionFloat, scarf_joint_flow_ratio)) + ) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 3423cb6698..3d9672025a 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1146,6 +1146,7 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "seam_slope_conditional" || opt_key == "scarf_angle_threshold" || opt_key == "scarf_joint_speed" + || opt_key == "scarf_joint_flow_ratio" || opt_key == "seam_slope_start_height" || opt_key == "seam_slope_entire_loop" || opt_key == "seam_slope_min_length" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index f9ce6e608f..79ee44e846 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -763,6 +763,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_line("seam_slope_steps", has_seam_slope); toggle_line("seam_slope_inner_walls", has_seam_slope); toggle_line("scarf_joint_speed", has_seam_slope); + toggle_line("scarf_joint_flow_ratio", has_seam_slope); toggle_field("seam_slope_min_length", !config->opt_bool("seam_slope_entire_loop")); toggle_line("scarf_angle_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional")); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9495015923..b3c8297adc 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1984,6 +1984,7 @@ void TabPrint::build() optgroup->append_single_option_line("seam_slope_entire_loop", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_min_length", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_steps", "seam#scarf-joint-seam"); + optgroup->append_single_option_line("scarf_joint_flow_ratio", "seam#scarf-joint-seam"); optgroup->append_single_option_line("seam_slope_inner_walls", "seam#scarf-joint-seam"); optgroup->append_single_option_line("role_based_wipe_speed","seam"); optgroup->append_single_option_line("wipe_speed", "seam");