diff --git a/resources/profiles/BBL/process/fdm_process_common.json b/resources/profiles/BBL/process/fdm_process_common.json index 92669d52f2..8ac22e5098 100644 --- a/resources/profiles/BBL/process/fdm_process_common.json +++ b/resources/profiles/BBL/process/fdm_process_common.json @@ -8,6 +8,7 @@ "bottom_color_penetration_layers": "3", "bottom_shell_thickness": "0", "bottom_surface_pattern": "monotonic", + "bridge_bottom_surface_pattern": "default", "bottom_surface_density": "100", "bridge_flow": "0.95", "bridge_no_support": "0", diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 1f04f8d953..4ec290a73f 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -20,6 +20,22 @@ namespace Slic3r { +static InfillPattern infill_for_bridge_bottom(BridgeBottomSurfacePattern pattern, InfillPattern top_surface_pattern) +{ + switch (pattern) { + case bbspDefault: return top_surface_pattern == ipMonotonic ? ipMonotonic : ipRectilinear; + case bbspConcentric: return ipConcentric; + case bbspRectilinear: return ipRectilinear; + case bbspMonotonic: return ipMonotonic; + case bbspMonotonicLine: return ipMonotonicLine; + case bbspAlignedRectilinear: return ipAlignedRectilinear; + case bbspHilbertCurve: return ipHilbertCurve; + case bbspArchimedeanChords: return ipArchimedeanChords; + case bbspOctagramSpiral: return ipOctagramSpiral; + } + return ipRectilinear; +} + struct SurfaceFillParams { // Zero based extruder ID. @@ -228,7 +244,6 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p if (surface.is_solid()) { params.density = 100.f; - //FIXME for non-thick bridges, shall we allow a bottom surface pattern? if (surface.is_floating_vertical_shell()) params.pattern = InfillPattern::ipFloatingConcentric; else if (surface.is_solid_infill()) @@ -236,6 +251,9 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p else if (surface.is_external() && !is_bridge) { params.pattern = surface.is_top() ? region_config.top_surface_pattern.value : region_config.bottom_surface_pattern.value; params.density = surface.is_top() ? region_config.top_surface_density.value : region_config.bottom_surface_density.value; + } else if (is_bridge && surface.is_bottom()) { + params.pattern = infill_for_bridge_bottom(region_config.bridge_bottom_surface_pattern.value, + region_config.top_surface_pattern.value); } else params.pattern = region_config.top_surface_pattern == ipMonotonic ? ipMonotonic : ipRectilinear; if (params.pattern == ipMonotonicLine) params.monotonic_travel_into_wall = region_config.monotonic_travel_into_wall.value; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 632b750031..1db7cd02fc 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1018,7 +1018,7 @@ static std::vector s_Preset_print_options { "smooth_speed_discontinuity_area","smooth_coefficient", "seam_position", "seam_placement_away_from_overhangs", "wall_sequence", "is_infill_first", "sparse_infill_density", "fill_multiline", "sparse_infill_pattern", "sparse_infill_anchor", "sparse_infill_anchor_max", "top_surface_pattern", "monotonic_travel_into_wall", "locked_skin_infill_pattern", "locked_skeleton_infill_pattern", - "bottom_surface_pattern", "internal_solid_infill_pattern", "infill_direction", "bridge_angle", "infill_shift_step", "skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density", + "bottom_surface_pattern", "bridge_bottom_surface_pattern", "internal_solid_infill_pattern", "infill_direction", "bridge_angle", "infill_shift_step", "skeleton_infill_density", "infill_lock_depth", "skin_infill_depth", "skin_infill_density", "infill_rotate_step","top_surface_density", "bottom_surface_density", "symmetric_infill_y_axis","sparse_infill_lattice_angle_1","sparse_infill_lattice_angle_2", "minimum_sparse_infill_area", "reduce_infill_retraction_mode", "ironing_pattern", "ironing_type", diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 7d8ab09dd3..240880be52 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -244,6 +244,19 @@ static t_config_enum_values s_keys_map_InfillPattern { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern) +static t_config_enum_values s_keys_map_BridgeBottomSurfacePattern { + { "default", bbspDefault }, + { "concentric", bbspConcentric }, + { "zig-zag", bbspRectilinear }, + { "monotonic", bbspMonotonic }, + { "monotonicline", bbspMonotonicLine }, + { "alignedrectilinear", bbspAlignedRectilinear }, + { "hilbertcurve", bbspHilbertCurve }, + { "archimedeanchords", bbspArchimedeanChords }, + { "octagramspiral", bbspOctagramSpiral }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(BridgeBottomSurfacePattern) + static t_config_enum_values s_keys_map_IroningType { { "no ironing", int(IroningType::NoIroning) }, { "top", int(IroningType::TopSurfaces) }, @@ -2125,6 +2138,19 @@ void PrintConfigDef::init_fff_params() def->enum_labels = def_top_fill_pattern->enum_labels; def->set_default_value(new ConfigOptionEnum(ipRectilinear)); + def = this->add("bridge_bottom_surface_pattern", coEnum); + def->label = L("Bridge bottom surface pattern"); + def->category = L("Strength"); + def->tooltip = L("Line pattern for the underside of bridges (overhangs printed over support or air). " + "Default uses monotonic if the top surface is monotonic, otherwise rectilinear."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("default"); + def->enum_values.insert(def->enum_values.end(), def_top_fill_pattern->enum_values.begin(), def_top_fill_pattern->enum_values.end()); + def->enum_labels.push_back(L("Default")); + def->enum_labels.insert(def->enum_labels.end(), def_top_fill_pattern->enum_labels.begin(), def_top_fill_pattern->enum_labels.end()); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(bbspDefault)); + def = this->add("bottom_surface_density", coPercent); def->label = L("Bottom surface density"); def->category = L("Strength"); @@ -9519,6 +9545,10 @@ std::map validate(const FullPrintConfig &cfg, bool und error_message.emplace("bottom_surface_pattern", L("invalid value ") + cfg.bottom_surface_pattern.serialize()); } + if (!print_config_def.get("bridge_bottom_surface_pattern")->has_enum_value(cfg.bridge_bottom_surface_pattern.serialize())) { + error_message.emplace("bridge_bottom_surface_pattern", L("invalid value ") + cfg.bridge_bottom_surface_pattern.serialize()); + } + // --soild-fill-pattern if (!print_config_def.get("internal_solid_infill_pattern")->has_enum_value(cfg.internal_solid_infill_pattern.serialize())) { error_message.emplace("internal_solid_infill_pattern", L("invalid value ") + cfg.internal_solid_infill_pattern.serialize()); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 0f1319c8ec..db8667781a 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -91,6 +91,19 @@ enum InfillPattern : int { ipCount, }; +// Pattern choices for bridge_bottom_surface_pattern. Default is setting behaviour, not a fill algorithm. +enum BridgeBottomSurfacePattern { + bbspDefault, + bbspConcentric, + bbspRectilinear, + bbspMonotonic, + bbspMonotonicLine, + bbspAlignedRectilinear, + bbspHilbertCurve, + bbspArchimedeanChords, + bbspOctagramSpiral, +}; + enum EnsureVerticalThicknessLevel{ evtDisabled, evtPartial, @@ -1072,6 +1085,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionEnum, ensure_vertical_shell_thickness)) ((ConfigOptionEnum, top_surface_pattern)) ((ConfigOptionEnum, bottom_surface_pattern)) + ((ConfigOptionEnum, bridge_bottom_surface_pattern)) ((ConfigOptionPercent, monotonic_travel_into_wall)) ((ConfigOptionPercent, top_surface_density)) ((ConfigOptionPercent, bottom_surface_density)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index cc9a3f828f..099273fab0 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1256,6 +1256,7 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "top_surface_density" || opt_key == "monotonic_travel_into_wall" || opt_key == "bottom_surface_pattern" + || opt_key == "bridge_bottom_surface_pattern" || opt_key == "bottom_surface_density" || opt_key == "internal_solid_infill_pattern" || opt_key == "external_fill_link_max_length" diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index b9609b3840..cb258df682 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -911,7 +911,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in bool has_bottom_solid_infill = config->opt_int("bottom_shell_layers") > 0; bool has_solid_infill = has_top_solid_infill || has_bottom_solid_infill; // solid_infill_filament uses the same logic as in Print::extruders() - for (auto el : {"top_surface_pattern", "bottom_surface_pattern", "top_surface_density", "bottom_surface_density", "internal_solid_infill_pattern", "solid_infill_filament"}) + for (auto el : {"top_surface_pattern", "bottom_surface_pattern", "bridge_bottom_surface_pattern", "top_surface_density", "bottom_surface_density", "internal_solid_infill_pattern", "solid_infill_filament"}) toggle_field(el, has_solid_infill); for (auto el : { "infill_direction", "sparse_infill_line_width", "bridge_angle", diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index 2b7effa3b1..80ea3e3690 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -105,7 +105,7 @@ std::map> SettingsFactory::PART_CAT {"bottom_shell_layers", "",1}, {"bottom_shell_thickness", "",1}, {"sparse_infill_density", "",1}, {"sparse_infill_pattern", "",1},{"sparse_infill_anchor", "",1},{"sparse_infill_anchor_max", "",1}, {"sparse_infill_lattice_angle_1", "",1},{"sparse_infill_lattice_angle_2", "",1}, {"top_surface_pattern", "",1},{"top_surface_density", "",1},{"monotonic_travel_into_wall", "",1}, - {"bottom_surface_pattern", "",1}, {"bottom_surface_density", "",1}, {"internal_solid_infill_pattern", "",1}, + {"bottom_surface_pattern", "",1}, {"bottom_surface_density", "",1}, {"bridge_bottom_surface_pattern", "",1}, {"internal_solid_infill_pattern", "",1}, {"infill_combination", "",1}, {"infill_wall_overlap", "",1}, {"infill_direction", "",1}, {"bridge_angle", "",1},{"minimum_sparse_infill_area", "",1} }}, { L("Speed"), {{"outer_wall_speed", "",1},{"inner_wall_speed", "",2},{"sparse_infill_speed", "",3},{"top_surface_speed", "",4}, {"internal_solid_infill_speed", "",5}, diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 5b7ec39a65..93d4d79aaf 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3301,6 +3301,7 @@ void TabPrint::build() optgroup->append_single_option_line("bottom_shell_thickness"); optgroup->append_single_option_line("bottom_color_penetration_layers"); optgroup->append_single_option_line("infill_instead_top_bottom_surfaces"); + optgroup->append_single_option_line("bridge_bottom_surface_pattern"); optgroup->append_single_option_line("internal_solid_infill_pattern"); optgroup = page->new_optgroup(L("Sparse infill"), L"param_infill");