Skip to content

Commit

Permalink
Add overhang threshold for scarf joint seam (#4725)
Browse files Browse the repository at this point in the history
add overhang threshold for scarf joint seam
  • Loading branch information
SoftFever authored Mar 27, 2024
1 parent 116169e commit dcb8d09
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 12 deletions.
18 changes: 13 additions & 5 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4549,10 +4549,11 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// find the point of the loop that is closest to the current extruder position
// or randomize if requested
Point last_pos = this->last_pos();
float seam_overhang = std::numeric_limits<float>::lowest();
if (!m_config.spiral_mode && description == "perimeter") {
assert(m_layer != nullptr);
bool is_outer_wall_first = m_config.wall_sequence == WallSequence::OuterInner;
m_seam_placer.place_seam(m_layer, loop, is_outer_wall_first, this->last_pos());
m_seam_placer.place_seam(m_layer, loop, is_outer_wall_first, this->last_pos(), seam_overhang);
} else
loop.split_at(last_pos, false);

Expand All @@ -4561,14 +4562,21 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
!m_config.spiral_mode &&
(loop.role() == erExternalPerimeter || (loop.role() == erPerimeter && m_config.seam_slope_inner_walls)) &&
layer_id() > 0;

const auto nozzle_diameter = EXTRUDER_CONFIG(nozzle_diameter);
if (enable_seam_slope && m_config.seam_slope_conditional.value) {
enable_seam_slope = loop.is_smooth(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., nozzle_diameter);
}

if (enable_seam_slope && m_config.seam_slope_conditional.value && m_config.scarf_overhang_threshold.value > 0.0f) {
const auto _line_width = loop.role() == erExternalPerimeter ? m_config.outer_wall_line_width.get_abs_value(nozzle_diameter) :
m_config.inner_wall_line_width.get_abs_value(nozzle_diameter);
enable_seam_slope = seam_overhang < m_config.scarf_overhang_threshold.value * 0.01f * _line_width;
}

// 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
const double seam_gap = scale_(m_config.seam_gap.get_abs_value(EXTRUDER_CONFIG(nozzle_diameter)));
const double seam_gap = scale_(m_config.seam_gap.get_abs_value(nozzle_diameter));
const double clip_length = m_enable_loop_clipping && !enable_seam_slope ? seam_gap : 0;

// get paths
Expand Down Expand Up @@ -4596,7 +4604,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
if (m_config.wipe_before_external_loop.value && !paths.empty() && paths.front().size() > 1 && paths.back().size() > 1 && paths.front().role() == erExternalPerimeter && region_perimeters.size() > 1) {
const bool is_full_loop_ccw = loop.polygon().is_counter_clockwise();
bool is_hole_loop = (loop.loop_role() & ExtrusionLoopRole::elrHole) != 0; // loop.make_counter_clockwise();
const double nozzle_diam = EXTRUDER_CONFIG(nozzle_diameter);
const double nozzle_diam = nozzle_diameter;

// note: previous & next are inverted to extrude "in the opposite direction, and we are "rewinding"
Point previous_point = paths.front().polyline.points[1];
Expand Down
10 changes: 7 additions & 3 deletions src/libslic3r/GCode/SeamPlacer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1067,15 +1067,18 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po)
std::unique_ptr<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(
to_unscaled_linesf(po->layers()[layer_idx]->lslices));

for (SeamCandidate &perimeter_point : layers[layer_idx].points) {
auto& layer_seams = layers[layer_idx];
for (SeamCandidate &perimeter_point : layer_seams.points) {
Vec2f point = Vec2f { perimeter_point.position.head<2>() };
if (prev_layer_distancer.get() != nullptr) {
perimeter_point.overhang = prev_layer_distancer->distance_from_lines<true>(point.cast<double>())
const auto _dist = prev_layer_distancer->distance_from_lines<true>(point.cast<double>());
perimeter_point.overhang = _dist
+ 0.6f * perimeter_point.perimeter.flow_width
- tan(SeamPlacer::overhang_angle_threshold)
* po->layers()[layer_idx]->height;
perimeter_point.overhang =
perimeter_point.overhang < 0.0f ? 0.0f : perimeter_point.overhang;
perimeter_point.unsupported_dist = _dist + 0.4f * perimeter_point.perimeter.flow_width;
}

if (should_compute_layer_embedding) { // search for embedded perimeter points (points hidden inside the print ,e.g. multimaterial join, best position for seam)
Expand Down Expand Up @@ -1484,7 +1487,7 @@ void SeamPlacer::init(const Print &print, std::function<void(void)> throw_if_can
}

void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first,
const Point &last_pos) const {
const Point &last_pos, float& overhang) const {
using namespace SeamPlacerImpl;
const PrintObject *po = layer->object();
// Must not be called with supprot layer.
Expand Down Expand Up @@ -1546,6 +1549,7 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
}

Point seam_point = Point::new_scale(seam_position.x(), seam_position.y());
overhang = layer_perimeters.points[seam_index].unsupported_dist;

if (loop.role() == ExtrusionRole::erPerimeter) { //Hopefully inner perimeter
const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
Expand Down
5 changes: 3 additions & 2 deletions src/libslic3r/GCode/SeamPlacer.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef libslic3r_SeamPlacer_hpp_
#define libslic3r_SeamPlacer_hpp_

#include <limits>
#include <optional>
#include <vector>
#include <memory>
Expand Down Expand Up @@ -66,6 +67,7 @@ struct SeamCandidate {
Perimeter &perimeter;
float visibility;
float overhang;
float unsupported_dist;
// distance inside the merged layer regions, for detecting perimeter points which are hidden indside the print (e.g. multimaterial join)
// Negative sign means inside the print, comes from EdgeGrid structure
float embedded_distance;
Expand Down Expand Up @@ -141,8 +143,7 @@ class SeamPlacer {

void init(const Print &print, std::function<void(void)> throw_if_canceled_func);

void place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos) const;

void place_seam(const Layer *layer, ExtrusionLoop &loop, bool external_first, const Point &last_pos, float& overhang) const;
private:
void gather_seam_candidates(const PrintObject *po, const SeamPlacerImpl::GlobalModelInfo &global_model_info);
void calculate_candidates_visibility(const PrintObject *po,
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/Layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_overhang_threshold == other_config.scarf_overhang_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
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ static std::vector<std::string> 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", "scarf_joint_flow_ratio", "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", "scarf_overhang_threshold"
};

static std::vector<std::string> s_Preset_filament_options {
Expand Down
13 changes: 12 additions & 1 deletion src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3588,6 +3588,17 @@ def = this->add("filament_loading_speed", coFloats);
def->max = 180;
def->set_default_value(new ConfigOptionInt(155));

def = this->add("scarf_overhang_threshold", coPercent);
def->label = L("Conditional overhang threshold");
def->category = L("Quality");
def->tooltip = L("This option determines the overhang threshold for the application of scarf joint seams. If the unsupported portion "
"of the perimeter is less than this threshold, scarf joint seams will be applied. The default threshold is set at 40% "
"of the external wall's width. Due to performance considerations, the degree of overhang is estimated.");
def->sidetext = L("%");
def->min = 0;
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionPercent(40));

def = this->add("scarf_joint_speed", coFloatOrPercent);
def->label = L("Scarf joint speed");
def->category = L("Quality");
Expand All @@ -3605,7 +3616,7 @@ def = this->add("filament_loading_speed", coFloats);
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->mode = comDevelop;
def->max = 2;
def->set_default_value(new ConfigOptionFloat(1));

Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, seam_slope_inner_walls))
((ConfigOptionFloatOrPercent, scarf_joint_speed))
((ConfigOptionFloat, scarf_joint_flow_ratio))
((ConfigOptionPercent, scarf_overhang_threshold))


)
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_overhang_threshold"
|| opt_key == "scarf_joint_speed"
|| opt_key == "scarf_joint_flow_ratio"
|| opt_key == "seam_slope_start_height"
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/ConfigManipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
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"));
toggle_line("scarf_overhang_threshold", has_seam_slope && config->opt_bool("seam_slope_conditional"));
}

void ConfigManipulation::update_print_sla_config(DynamicPrintConfig* config, const bool is_global_config/* = false*/)
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_overhang_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");
Expand Down

0 comments on commit dcb8d09

Please sign in to comment.