Skip to content

Commit

Permalink
Limit Arachne maximum width
Browse files Browse the repository at this point in the history
  • Loading branch information
vovodroid committed Jan 23, 2024
1 parent 8b76a0a commit fc894b7
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 17 deletions.
8 changes: 4 additions & 4 deletions src/libslic3r/Arachne/utils/ExtrusionLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,17 @@ double ExtrusionLine::area() const
} // namespace Slic3r::Arachne

namespace Slic3r {
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow)
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, float max_width)
{
for (const ClipperLib_Z::Path &extrusion_path : extrusion_paths) {
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion_path);
Slic3r::append(dst, PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
Slic3r::append(dst, PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON), max_width).paths);
}
}

void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow)
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, float max_width)
{
ThickPolyline thick_polyline = Arachne::to_thick_polyline(extrusion);
Slic3r::append(dst, PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON)).paths);
Slic3r::append(dst, PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, role, flow, scaled<float>(0.05), float(SCALED_EPSILON), max_width).paths);
}
} // namespace Slic3r
4 changes: 2 additions & 2 deletions src/libslic3r/Arachne/utils/ExtrusionLine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ using VariableWidthLines = std::vector<ExtrusionLine>; //<! The ExtrusionLines g

namespace Slic3r {

void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow);
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow);
void extrusion_paths_append(ExtrusionPaths &dst, const ClipperLib_Z::Paths &extrusion_paths, const ExtrusionRole role, const Flow &flow, float max_width = FLT_MAX);
void extrusion_paths_append(ExtrusionPaths &dst, const Arachne::ExtrusionLine &extrusion, const ExtrusionRole role, const Flow &flow, float max_width = FLT_MAX);

} // namespace Slic3r

Expand Down
8 changes: 7 additions & 1 deletion src/libslic3r/Fill/Fill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,13 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
for (const ThickPolyline &thick_polyline : thick_polylines) {
Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing));

ExtrusionMultiPath multi_path = PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, surface_fill.params.extrusion_role, new_flow, scaled<float>(0.05), float(SCALED_EPSILON));
assert(!this->object()->print()->config().nozzle_diameter.empty());
float min_nozzle_diameter = float(*std::min_element(this->object()->print()->config().nozzle_diameter.values.begin(), this->object()->print()->config().nozzle_diameter.values.end()));
float max_bead_width = this->object()->config().max_bead_width.value;
if (const auto &max_bead_width_opt = this->object()->config().max_bead_width; max_bead_width_opt.percent)
max_bead_width = (max_bead_width_opt.value * 0.01 * min_nozzle_diameter);

ExtrusionMultiPath multi_path = PerimeterGenerator::thick_polyline_to_multi_path(thick_polyline, surface_fill.params.extrusion_role, new_flow, scaled<float>(0.05), float(SCALED_EPSILON), max_bead_width);
// Append paths to collection.
if (!multi_path.empty()) {
if (multi_path.paths.front().first_point() == multi_path.paths.back().last_point())
Expand Down
22 changes: 15 additions & 7 deletions src/libslic3r/PerimeterGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@

namespace Slic3r {

ExtrusionMultiPath PerimeterGenerator::thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
ExtrusionMultiPath PerimeterGenerator::thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance, float max_width)
{
ExtrusionMultiPath multi_path;
ExtrusionPath path(role);
Expand Down Expand Up @@ -124,7 +124,7 @@ ExtrusionMultiPath PerimeterGenerator::thick_polyline_to_multi_path(const ThickP
continue;
}

const double w = fmax(line.a_width, line.b_width);
const double w = fmin(fmax(line.a_width, line.b_width),scale_(max_width - flow.height() * float(1. - 0.25 * PI)));
const Flow new_flow = (role.is_bridge() && flow.bridge()) ? flow : flow.with_width(unscale<float>(w) + flow.height() * float(1. - 0.25 * PI));
if (path.empty()) {
// Convert from spacing to extrusion width based on the extrusion model
Expand Down Expand Up @@ -512,7 +512,7 @@ struct PerimeterGeneratorArachneExtrusion
bool fuzzify = false;
};

static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::Parameters &params, const Polygons &lower_slices_polygons_cache, std::vector<PerimeterGeneratorArachneExtrusion> &pg_extrusions)
static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::Parameters &params, const Polygons &lower_slices_polygons_cache, std::vector<PerimeterGeneratorArachneExtrusion> &pg_extrusions, float max_bead_widh = FLT_MAX)
{
ExtrusionEntityCollection extrusion_coll;
for (PerimeterGeneratorArachneExtrusion &pg_extrusion : pg_extrusions) {
Expand Down Expand Up @@ -561,13 +561,13 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P

// get non-overhang paths by intersecting this loop with the grown lower slices
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctIntersection), role_normal,
is_external ? params.ext_perimeter_flow : params.perimeter_flow);
is_external ? params.ext_perimeter_flow : params.perimeter_flow, max_bead_widh);

// get overhang paths by checking what parts of this loop fall
// outside the grown lower slices (thus where the distance between
// the loop centerline and original lower slices is >= half nozzle diameter
extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), role_overhang,
params.overhang_flow);
params.overhang_flow, max_bead_widh);

// Reapply the nearest point search for starting point.
// We allow polyline reversal because Clipper may have randomly reversed polylines during clipping.
Expand Down Expand Up @@ -607,7 +607,7 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator::P
chain_and_reorder_extrusion_paths(paths, &start_point);
}
} else {
extrusion_paths_append(paths, *extrusion, role_normal, is_external ? params.ext_perimeter_flow : params.perimeter_flow);
extrusion_paths_append(paths, *extrusion, role_normal, is_external ? params.ext_perimeter_flow : params.perimeter_flow, max_bead_widh);
}

// Append paths to collection.
Expand Down Expand Up @@ -1329,8 +1329,16 @@ void PerimeterGenerator::process_arachne(
}
}
}

assert(!params.print_config.nozzle_diameter.empty());
float min_nozzle_diameter = float(*std::min_element(params.print_config.nozzle_diameter.values.begin(), params.print_config.nozzle_diameter.values.end()));

float max_bead_width = params.object_config.max_bead_width.value;

if (const auto &max_bead_width_opt = params.object_config.max_bead_width; max_bead_width_opt.percent)
max_bead_width = (max_bead_width_opt.value * 0.01 * min_nozzle_diameter);

if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(params, lower_slices_polygons_cache, ordered_extrusions); !extrusion_coll.empty()) {
if (ExtrusionEntityCollection extrusion_coll = traverse_extrusions(params, lower_slices_polygons_cache, ordered_extrusions, max_bead_width); !extrusion_coll.empty()) {
if (params.config.internal_first_on_overhangs)
for (ExtrusionEntity* ent : extrusion_coll)
if (ent->is_loop())
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/PerimeterGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void process_arachne(
// Infills without the gap fills
ExPolygons &out_fill_expolygons);

ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance);
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, float tolerance, float merge_tolerance, float max_width = FLT_MAX);

void split_top_surfaces(const Parameters &params, const ExPolygons *lower_slices,const ExPolygons *upper_slices, const ExPolygons &orig_polygons, ExPolygons &top_fills,
ExPolygons &non_top_polygons, ExPolygons &fill_clip);
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static std::vector<std::string> s_Preset_print_options {
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
"mmu_segmented_region_interlocking_depth", "wipe_tower_extruder", "wipe_tower_no_sparse_layers", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
"wall_distribution_count", "min_feature_size", "min_bead_width",
"wall_distribution_count", "min_feature_size", "min_bead_width", "max_bead_width",
// SuperSlicer
"only_one_perimeter_top", "min_width_top_surface",
"overhangs_reverse", "external_perimeters_reverse", "internal_perimeters_reverse", "infill_reverse"
Expand Down
10 changes: 10 additions & 0 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3658,6 +3658,16 @@ void PrintConfigDef::init_fff_params()
def->min = 0;
def->set_default_value(new ConfigOptionFloatOrPercent(85, true));

def = this->add("max_bead_width", coFloatOrPercent);
def->label = L("Maximum perimeter width");
def->category = L("Advanced");
def->tooltip = L("Maximum width of the perimeter. "
"If expressed as a percentage (for example 85%), it will be computed based on the nozzle diameter.");
def->sidetext = L("mm or %");
def->mode = comExpert;
def->min = 0;
def->set_default_value(new ConfigOptionFloatOrPercent(250, true));

def = this->add("make_overhang_printable", coBool);
def->label = L("Make overhang printable");
def->category = L("Advanced");
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/PrintConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInt, wall_distribution_count))
((ConfigOptionFloatOrPercent, min_feature_size))
((ConfigOptionFloatOrPercent, min_bead_width))
((ConfigOptionFloatOrPercent, max_bead_width))
((ConfigOptionBool, support_material))
// Automatic supports (generated based fdm support point generator).
((ConfigOptionBool, support_material_auto))
Expand Down
3 changes: 2 additions & 1 deletion src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,8 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "wall_transition_angle"
|| opt_key == "wall_distribution_count"
|| opt_key == "min_feature_size"
|| opt_key == "min_bead_width") {
|| opt_key == "min_bead_width"
|| opt_key == "max_bead_width") {
steps.emplace_back(posSlice);
} else if (
opt_key == "seam_position"
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 @@ -369,6 +369,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
toggle_field("wall_distribution_count", have_arachne);
toggle_field("min_feature_size", have_arachne);
toggle_field("min_bead_width", have_arachne);
toggle_field("max_bead_width", have_arachne);
toggle_field("thin_walls", !have_arachne);

toggle_field("only_one_perimeter_first", have_perimeters);
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 @@ -1727,6 +1727,7 @@ void TabPrint::build()
optgroup->append_single_option_line("wall_transition_length");
optgroup->append_single_option_line("wall_distribution_count");
optgroup->append_single_option_line("min_bead_width");
optgroup->append_single_option_line("max_bead_width");
optgroup->append_single_option_line("min_feature_size");

page = add_options_page(L("Output options"), "output+page_white");
Expand Down

0 comments on commit fc894b7

Please sign in to comment.