From 4046e39ff3258c1ec62117c04bfdfe63f63e8bf4 Mon Sep 17 00:00:00 2001 From: Rodrigo Faselli <162915171+RF47@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:27:55 -0300 Subject: [PATCH] Adjusted density multiline infill for adaptive cubic, support cubic, lightning patterns (prevent crash) and minor GUI correction. (#10967) * FillAdaptive density adjusted * Fill lightning multiline density adjust * Gui corrections by IanAlexis --- src/libslic3r/Fill/FillAdaptive.cpp | 5 +-- src/libslic3r/Fill/FillLightning.cpp | 2 ++ src/libslic3r/Fill/FillRectilinear.cpp | 5 ++- src/libslic3r/Fill/Lightning/Generator.cpp | 3 +- src/slic3r/GUI/ConfigManipulation.cpp | 37 ++++++++++++---------- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index 3ec9ec3685..ed3bfcf0a0 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -349,8 +349,9 @@ std::pair adaptive_fill_line_spacing(const PrintObject &print_ob } else return 0.; }; - adaptive_line_spacing = to_line_spacing(adaptive_cnt, adaptive_fill_density, adaptive_infill_extrusion_width); - support_line_spacing = to_line_spacing(support_cnt, support_fill_density, support_infill_extrusion_width); + const int n_multiline = print_object.printing_region(0).config().fill_multiline.value; + adaptive_line_spacing = to_line_spacing(adaptive_cnt, adaptive_fill_density, adaptive_infill_extrusion_width) * n_multiline; + support_line_spacing = to_line_spacing(support_cnt, support_fill_density, support_infill_extrusion_width) * n_multiline; } return std::make_pair(adaptive_line_spacing, support_line_spacing); diff --git a/src/libslic3r/Fill/FillLightning.cpp b/src/libslic3r/Fill/FillLightning.cpp index 502de9d51c..7937b9d129 100644 --- a/src/libslic3r/Fill/FillLightning.cpp +++ b/src/libslic3r/Fill/FillLightning.cpp @@ -1,3 +1,4 @@ +#include "../ClipperUtils.hpp" #include "../Print.hpp" #include "../ShortestPath.hpp" #include "FillBase.hpp" @@ -19,6 +20,7 @@ void Filler::_fill_surface_single( // Apply multiline offset if needed multiline_fill(fill_lines, params, spacing); + fill_lines = Slic3r::intersection_pl(std::move(fill_lines), expolygon); chain_or_connect_infill(std::move(fill_lines), expolygon, polylines_out, this->spacing, params); } diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 4138ef0511..cfb9c32300 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2998,7 +2998,6 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar assert(sweep_params.size() >= 1); assert(!params.full_infill()); params.density /= double(sweep_params.size()); - int n_multilines = params.multiline; assert(params.density > 0.0001f && params.density <= 1.f); ExPolygonWithOffset poly_with_offset_base(surface->expolygon, 0, float(scale_(this->overlap - 0.5 * this->spacing))); @@ -3014,9 +3013,9 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar // Rotate polygons so that we can work with vertical lines here float angle = rotate_vector.first + sweep.angle_base; //Fill Multiline - for (int i = 0; i < n_multilines; ++i) { + for (int i = 0; i < params.multiline; ++i) { coord_t group_offset = i * line_spacing; - coord_t internal_offset = (i - (n_multilines - 1) / 2.0f) * line_width; + coord_t internal_offset = (i - (params.multiline - 1) / 2.0f) * line_width; coord_t total_offset = group_offset + internal_offset; coord_t pattern_shift = scale_(sweep.pattern_shift + unscale_(total_offset)); diff --git a/src/libslic3r/Fill/Lightning/Generator.cpp b/src/libslic3r/Fill/Lightning/Generator.cpp index bf1142ee45..6044f0f0a0 100644 --- a/src/libslic3r/Fill/Lightning/Generator.cpp +++ b/src/libslic3r/Fill/Lightning/Generator.cpp @@ -70,6 +70,7 @@ Generator::Generator(const PrintObject &print_object, const std::functionall_regions.front()->config(); const std::vector &nozzle_diameters = print_config.nozzle_diameter.values; double max_nozzle_diameter = *std::max_element(nozzle_diameters.begin(), nozzle_diameters.end()); + const int n_multiline = region_config.fill_multiline.value; // const int infill_extruder = region_config.infill_extruder.value; const double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter)); // Note: There's not going to be a layer below the first one, so the 'initial layer height' doesn't have to be taken into account. @@ -86,7 +87,7 @@ Generator::Generator(const PrintObject &print_object, const std::functionoption("sparse_infill_density")->value > 0; // sparse_infill_filament uses the same logic as in Print::extruders() - for (auto el : { "sparse_infill_pattern", "infill_combination", - "minimum_sparse_infill_area", "sparse_infill_filament", "infill_anchor_max","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"}) + for (auto el : { "sparse_infill_pattern", "infill_combination", "fill_multiline","infill_direction", + "minimum_sparse_infill_area", "sparse_infill_filament", "infill_anchor", "infill_anchor_max","infill_shift_step","sparse_infill_rotate_template","symmetric_infill_y_axis"}) toggle_line(el, have_infill); bool have_combined_infill = config->opt_bool("infill_combination") && have_infill; @@ -597,23 +597,26 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co InfillPattern pattern = config->opt_enum("sparse_infill_pattern"); bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipTpmsFK || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ipLateralLattice || pattern == ipLateralHoneycomb || pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic; - toggle_line("fill_multiline", have_multiline_infill_pattern); - // If the infill pattern does not support multiline infill, set fill_multiline to 1. - if (!have_multiline_infill_pattern) { - DynamicPrintConfig new_conf = *config; - new_conf.set_key_value("fill_multiline", new ConfigOptionInt(1)); - apply(config, &new_conf); + // If there is infill, enable/disable fill_multiline according to whether the pattern supports multiline infill. + if (have_infill) { + toggle_field("fill_multiline", have_multiline_infill_pattern); + // If the infill pattern does not support multiline fill_multiline is changed to 1. + // Necessary when the pattern contains params.multiline (for example, triangles because they belong to the rectilinear class) + if (!have_multiline_infill_pattern) { + DynamicPrintConfig new_conf = *config; + new_conf.set_key_value("fill_multiline", new ConfigOptionInt(1)); + apply(config, &new_conf); + } + // Hide infill anchor max if sparse_infill_pattern is not line or if sparse_infill_pattern is line but infill_anchor_max is 0. + bool infill_anchor = config->opt_enum("sparse_infill_pattern") != ipLine; + toggle_field("infill_anchor_max", infill_anchor); + + // Only allow configuration of open anchors if the anchoring is enabled. + bool has_infill_anchors = infill_anchor && config->option("infill_anchor_max")->value > 0; + toggle_field("infill_anchor", has_infill_anchors); } - // Hide infill anchor max if sparse_infill_pattern is not line or if sparse_infill_pattern is line but infill_anchor_max is 0. - bool infill_anchor = config->opt_enum("sparse_infill_pattern") != ipLine; - toggle_field("infill_anchor_max",infill_anchor); - - // Only allow configuration of open anchors if the anchoring is enabled. - bool has_infill_anchors = have_infill && config->option("infill_anchor_max")->value > 0 && infill_anchor; - toggle_field("infill_anchor", has_infill_anchors); - //cross zag bool is_cross_zag = config->option>("sparse_infill_pattern")->value == InfillPattern::ipCrossZag; bool is_locked_zig = config->option>("sparse_infill_pattern")->value == InfillPattern::ipLockedZag; @@ -640,7 +643,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co toggle_field("top_surface_density", has_top_shell); toggle_field("bottom_surface_density", has_bottom_shell); - for (auto el : { "infill_direction", "sparse_infill_line_width", "fill_multiline","gap_fill_target","filter_out_gap_fill","infill_wall_overlap", + for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap", "sparse_infill_speed", "bridge_speed", "internal_bridge_speed", "bridge_angle", "internal_bridge_angle", "solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "solid_infill_filament", })