diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index a399a8333..5168ddf94 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -265,8 +265,10 @@ sub validate { if !first { $_ eq $self->fill_pattern } @{$Options->{fill_pattern}{values}}; # --external-fill-pattern - die "Invalid value for --external-fill-pattern\n" - if !first { $_ eq $self->external_fill_pattern } @{$Options->{external_fill_pattern}{values}}; + die "Invalid value for --top-infill-pattern\n" + if !first { $_ eq $self->top_infill_pattern } @{$Options->{top_infill_pattern}{values}}; + die "Invalid value for --bottom-infill-pattern\n" + if !first { $_ eq $self->bottom_infill_pattern } @{$Options->{bottom_infill_pattern}{values}}; # --fill-density die "The selected fill pattern is not supposed to work at 100% density\n" diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index e24b7429e..c6190ea4d 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -466,7 +466,7 @@ sub build { top_solid_layers bottom_solid_layers extra_perimeters avoid_crossing_perimeters thin_walls overhangs seam_position external_perimeters_first - fill_density fill_pattern external_fill_pattern fill_gaps + fill_density fill_pattern top_infill_pattern bottom_infill_pattern fill_gaps infill_every_layers infill_only_where_needed solid_infill_every_layers fill_angle solid_infill_below_area only_retract_when_crossing_perimeters infill_first @@ -542,7 +542,14 @@ sub build { my $optgroup = $page->new_optgroup('Infill'); $optgroup->append_single_option_line('fill_density'); $optgroup->append_single_option_line('fill_pattern'); - $optgroup->append_single_option_line('external_fill_pattern'); + { + my $line = Slic3r::GUI::OptionsGroup::Line->new( + label => 'External infill pattern', + ); + $line->append_option($optgroup->get_option('top_infill_pattern')); + $line->append_option($optgroup->get_option('bottom_infill_pattern')); + $optgroup->append_line($line); + } } { my $optgroup = $page->new_optgroup('Reducing printing time'); @@ -794,7 +801,7 @@ sub _update { } if ($config->fill_density == 100 - && !first { $_ eq $config->fill_pattern } @{$Slic3r::Config::Options->{external_fill_pattern}{values}}) { + && !first { $_ eq $config->fill_pattern } @{$Slic3r::Config::Options->{top_infill_pattern}{values}}) { my $dialog = Wx::MessageDialog->new($self, "The " . $config->fill_pattern . " infill pattern is not supposed to work at 100% density.\n" . "\nShall I switch to rectilinear fill pattern?", @@ -824,8 +831,8 @@ sub _update { my $have_solid_infill = ($config->top_solid_layers > 0) || ($config->bottom_solid_layers > 0); # solid_infill_extruder uses the same logic as in Print::extruders() $self->get_field($_)->toggle($have_solid_infill) - for qw(external_fill_pattern infill_first solid_infill_extruder solid_infill_extrusion_width - solid_infill_speed); + for qw(top_infill_pattern bottom_infill_pattern infill_first solid_infill_extruder + solid_infill_extrusion_width solid_infill_speed); $self->get_field($_)->toggle($have_infill || $have_solid_infill) for qw(fill_angle infill_extrusion_width infill_speed bridge_speed); diff --git a/slic3r.pl b/slic3r.pl index c9c282e8f..ee9e45214 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -431,7 +431,10 @@ $j --fill-angle Infill angle in degrees (range: 0-90, default: $config->{fill_angle}) --fill-pattern Pattern to use to fill non-solid layers (default: $config->{fill_pattern}) --fill-gaps Fill gaps with single passes (default: yes) - --external-fill-pattern Pattern to use to fill solid layers (default: $config->{external_fill_pattern}) + --external-infill-pattern Pattern to use to fill solid layers. + (Shortcut for --top-infill-pattern and --bottom-infill-pattern) + --top-infill-pattern Pattern to use to fill top solid layers (default: $config->{top_infill_pattern}) + --bottom-infill-pattern Pattern to use to fill bottom solid layers (default: $config->{bottom_infill_pattern}) --start-gcode Load initial G-code from the supplied file. This will overwrite the default command (home all axes [G28]). --end-gcode Load final G-code from the supplied file. This will overwrite diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index ed8ffc468..1f366f3cb 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -192,7 +192,9 @@ ConfigOptionDef::ConfigOptionDef(const ConfigOptionDef &other) full_label(other.full_label), category(other.category), tooltip(other.tooltip), sidetext(other.sidetext), cli(other.cli), ratio_over(other.ratio_over), multiline(other.multiline), full_width(other.full_width), readonly(other.readonly), - height(other.height), width(other.width), min(other.min), max(other.max) + height(other.height), width(other.width), min(other.min), max(other.max), + aliases(other.aliases), shortcut(other.shortcut), enum_values(other.enum_values), + enum_labels(other.enum_labels), enum_keys_map(other.enum_keys_map) { if (other.default_value != NULL) this->default_value = other.default_value->clone(); @@ -212,6 +214,13 @@ ConfigDef::add(const t_config_option_key &opt_key, ConfigOptionType type) return opt; } +ConfigOptionDef* +ConfigDef::add(const t_config_option_key &opt_key, const ConfigOptionDef &def) +{ + this->options.emplace(opt_key, def); + return &this->options[opt_key]; +} + const ConfigOptionDef* ConfigDef::get(const t_config_option_key &opt_key) const { diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index 128ef04bc..8e375701e 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -641,6 +641,7 @@ class ConfigDef public: t_optiondef_map options; ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type); + ConfigOptionDef* add(const t_config_option_key &opt_key, const ConfigOptionDef &def); const ConfigOptionDef* get(const t_config_option_key &opt_key) const; void merge(const ConfigDef &other); }; diff --git a/xs/src/libslic3r/Fill/FillPlanePath.hpp b/xs/src/libslic3r/Fill/FillPlanePath.hpp index 7e308aac5..0956db4e1 100644 --- a/xs/src/libslic3r/Fill/FillPlanePath.hpp +++ b/xs/src/libslic3r/Fill/FillPlanePath.hpp @@ -35,6 +35,7 @@ class FillArchimedeanChords : public FillPlanePath public: virtual Fill* clone() const { return new FillArchimedeanChords(*this); }; virtual ~FillArchimedeanChords() {} + virtual bool can_solid() const { return true; }; protected: virtual bool _centered() const { return true; } @@ -46,6 +47,7 @@ class FillHilbertCurve : public FillPlanePath public: virtual Fill* clone() const { return new FillHilbertCurve(*this); }; virtual ~FillHilbertCurve() {} + virtual bool can_solid() const { return true; }; protected: virtual bool _centered() const { return false; } @@ -57,6 +59,7 @@ class FillOctagramSpiral : public FillPlanePath public: virtual Fill* clone() const { return new FillOctagramSpiral(*this); }; virtual ~FillOctagramSpiral() {} + virtual bool can_solid() const { return true; }; protected: virtual bool _centered() const { return true; } diff --git a/xs/src/libslic3r/LayerRegionFill.cpp b/xs/src/libslic3r/LayerRegionFill.cpp index 0b4276439..954f1d135 100644 --- a/xs/src/libslic3r/LayerRegionFill.cpp +++ b/xs/src/libslic3r/LayerRegionFill.cpp @@ -67,7 +67,9 @@ LayerRegion::make_fill() group_attrib[i].is_solid = true; group_attrib[i].fw = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width; - group_attrib[i].pattern = surface.is_external() ? this->region()->config.external_fill_pattern.value : ipRectilinear; + group_attrib[i].pattern = surface.surface_type == stTop ? this->region()->config.top_infill_pattern.value + : surface.is_bottom() ? this->region()->config.bottom_infill_pattern.value + : ipRectilinear; } // Loop through solid groups, find compatible groups and append them to this one. for (size_t i = 0; i < groups.size(); ++i) { @@ -171,8 +173,8 @@ LayerRegion::make_fill() if (surface.is_solid()) { density = 100.; - fill_pattern = (surface.is_external() && !is_bridge) - ? this->region()->config.external_fill_pattern.value + fill_pattern = (surface.surface_type == stTop) ? this->region()->config.top_infill_pattern.value + : (surface.is_bottom() && !is_bridge) ? this->region()->config.bottom_infill_pattern.value : ipRectilinear; } else if (density <= 0) continue; diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index a91816d5f..99713270c 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -5,6 +5,20 @@ namespace Slic3r { PrintConfigDef::PrintConfigDef() { + ConfigOptionDef external_fill_pattern; + external_fill_pattern.type = coEnum; + external_fill_pattern.enum_keys_map = ConfigOptionEnum::get_enum_values(); + external_fill_pattern.enum_values.push_back("rectilinear"); + external_fill_pattern.enum_values.push_back("concentric"); + external_fill_pattern.enum_values.push_back("hilbertcurve"); + external_fill_pattern.enum_values.push_back("archimedeanchords"); + external_fill_pattern.enum_values.push_back("octagramspiral"); + external_fill_pattern.enum_labels.push_back("Rectilinear"); + external_fill_pattern.enum_labels.push_back("Concentric"); + external_fill_pattern.enum_labels.push_back("Hilbert Curve"); + external_fill_pattern.enum_labels.push_back("Archimedean Chords"); + external_fill_pattern.enum_labels.push_back("Octagram Spiral"); + ConfigOptionDef* def; def = this->add("avoid_crossing_perimeters", coBool); @@ -47,6 +61,14 @@ PrintConfigDef::PrintConfigDef() def->height = 50; def->default_value = new ConfigOptionString(""); + def = this->add("bottom_infill_pattern", external_fill_pattern); + def->label = "Bottom"; + def->full_label = "Bottom infill pattern"; + def->category = "Infill"; + def->tooltip = "Infill pattern for bottom layers. This only affects the external visible layer, and not its adjacent solid shells."; + def->cli = "bottom-infill-pattern=s"; + def->default_value = new ConfigOptionEnum(ipRectilinear); + def = this->add("bottom_solid_layers", coInt); def->label = "Bottom"; def->category = "Layers and Perimeters"; @@ -177,27 +199,15 @@ PrintConfigDef::PrintConfigDef() def->default_value = opt; } - def = this->add("external_fill_pattern", coEnum); + def = this->add("external_fill_pattern", external_fill_pattern); def->label = "Top/bottom fill pattern"; def->category = "Infill"; def->tooltip = "Fill pattern for top/bottom infill. This only affects the external visible layer, and not its adjacent solid shells."; - def->cli = "external-fill-pattern|solid-fill-pattern=s"; - def->enum_keys_map = ConfigOptionEnum::get_enum_values(); - def->enum_values.push_back("rectilinear"); - def->enum_values.push_back("alignedrectilinear"); - def->enum_values.push_back("concentric"); - def->enum_values.push_back("hilbertcurve"); - def->enum_values.push_back("archimedeanchords"); - def->enum_values.push_back("octagramspiral"); - def->enum_labels.push_back("Rectilinear"); - def->enum_labels.push_back("Aligned Rectilinear"); - def->enum_labels.push_back("Concentric"); - def->enum_labels.push_back("Hilbert Curve"); - def->enum_labels.push_back("Archimedean Chords"); - def->enum_labels.push_back("Octagram Spiral"); + def->cli = "external-fill-pattern|external-infill-pattern|solid-fill-pattern=s"; def->aliases.push_back("solid_fill_pattern"); - def->default_value = new ConfigOptionEnum(ipRectilinear); - + def->shortcut.push_back("top_infill_pattern"); + def->shortcut.push_back("bottom_infill_pattern"); + def = this->add("external_perimeter_extrusion_width", coFloatOrPercent); def->label = "↳ external"; def->gui_type = "f_enum_open"; @@ -1402,6 +1412,14 @@ PrintConfigDef::PrintConfigDef() def->enum_labels.push_back("default"); def->default_value = new ConfigOptionFloatOrPercent(0, false); + def = this->add("top_infill_pattern", external_fill_pattern); + def->label = "Top"; + def->full_label = "Top infill pattern"; + def->category = "Infill"; + def->tooltip = "Infill pattern for top layers. This only affects the external visible layer, and not its adjacent solid shells."; + def->cli = "top-infill-pattern=s"; + def->default_value = new ConfigOptionEnum(ipRectilinear); + def = this->add("top_solid_infill_speed", coFloatOrPercent); def->label = "↳ top solid"; def->gui_type = "f_enum_open"; @@ -1504,6 +1522,17 @@ DynamicPrintConfig::normalize() { } } + /* + if (this->has("external_fill_pattern")) { + InfillPattern p = this->opt >("external_fill_pattern"); + this->erase("external_fill_pattern"); + if (!this->has("bottom_infill_pattern")) + this->opt >("bottom_infill_pattern", true)->value = p; + if (!this->has("top_infill_pattern")) + this->opt >("top_infill_pattern", true)->value = p; + } + */ + if (!this->has("solid_infill_extruder") && this->has("infill_extruder")) this->option("solid_infill_extruder", true)->setInt(this->option("infill_extruder")->getInt()); diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 5082d31b3..06944cbc3 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -202,10 +202,10 @@ class PrintObjectConfig : public virtual StaticPrintConfig class PrintRegionConfig : public virtual StaticPrintConfig { public: + ConfigOptionEnum bottom_infill_pattern; ConfigOptionInt bottom_solid_layers; ConfigOptionFloat bridge_flow_ratio; ConfigOptionFloat bridge_speed; - ConfigOptionEnum external_fill_pattern; ConfigOptionFloatOrPercent external_perimeter_extrusion_width; ConfigOptionFloatOrPercent external_perimeter_speed; ConfigOptionBool external_perimeters_first; @@ -233,6 +233,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig ConfigOptionFloatOrPercent solid_infill_speed; ConfigOptionBool thin_walls; ConfigOptionFloatOrPercent top_infill_extrusion_width; + ConfigOptionEnum top_infill_pattern; ConfigOptionInt top_solid_layers; ConfigOptionFloatOrPercent top_solid_infill_speed; @@ -242,10 +243,10 @@ class PrintRegionConfig : public virtual StaticPrintConfig } virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { + OPT_PTR(bottom_infill_pattern); OPT_PTR(bottom_solid_layers); OPT_PTR(bridge_flow_ratio); OPT_PTR(bridge_speed); - OPT_PTR(external_fill_pattern); OPT_PTR(external_perimeter_extrusion_width); OPT_PTR(external_perimeter_speed); OPT_PTR(external_perimeters_first); @@ -273,6 +274,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig OPT_PTR(solid_infill_speed); OPT_PTR(thin_walls); OPT_PTR(top_infill_extrusion_width); + OPT_PTR(top_infill_pattern); OPT_PTR(top_solid_infill_speed); OPT_PTR(top_solid_layers); diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp index cfa0ef3c7..1aebd2c37 100644 --- a/xs/src/libslic3r/PrintObject.cpp +++ b/xs/src/libslic3r/PrintObject.cpp @@ -257,7 +257,8 @@ PrintObject::invalidate_state_by_config_options(const std::vector