From e7c854c91917c3ed9ecc923a5bc442fcd7f00ce9 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 18 Mar 2017 11:29:48 +0100 Subject: [PATCH] Ported Config::_handle_legacy() to XS --- lib/Slic3r/Config.pm | 66 +--------------------------- xs/src/libslic3r/Config.cpp | 34 ++++++++++++--- xs/src/libslic3r/Config.hpp | 3 +- xs/src/libslic3r/PrintConfig.cpp | 74 ++++++++++++++++++++++++++++++++ xs/src/libslic3r/PrintConfig.hpp | 5 ++- 5 files changed, 110 insertions(+), 72 deletions(-) diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 5168ddf94..2763a8fd0 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -8,12 +8,6 @@ use utf8; use List::Util qw(first max); -# cemetery of old config settings -our @Ignore = qw(duplicate_x duplicate_y multiply_x multiply_y support_material_tool acceleration - adjust_overhang_flow standby_temperature scale rotate duplicate duplicate_grid - rotate scale duplicate_grid start_perimeters_at_concave_points start_perimeters_at_non_overhang - randomize_start seal_position bed_size print_center g0); - # C++ Slic3r::PrintConfigDef exported as a Perl hash of hashes. # The C++ counterpart is a constant singleton. our $Options = print_config_def(); @@ -120,11 +114,7 @@ sub load_ini_hash { my ($ini_hash) = @_; my $config = $class->new; - foreach my $opt_key (keys %$ini_hash) { - ($opt_key, my $value) = _handle_legacy($opt_key, $ini_hash->{$opt_key}); - next if !defined $opt_key; - $config->set_deserialize($opt_key, $value); - } + $config->set_deserialize($_, $ini_hash->{$_}) for keys %$ini_hash; return $config; } @@ -145,60 +135,6 @@ sub get_value { : $self->get($opt_key); } -sub _handle_legacy { - my ($opt_key, $value) = @_; - - # handle legacy options - if ($opt_key =~ /^(extrusion_width|bottom_layer_speed|first_layer_height)_ratio$/) { - $opt_key = $1; - $opt_key =~ s/^bottom_layer_speed$/first_layer_speed/; - $value = $value =~ /^\d+(?:\.\d+)?$/ && $value != 0 ? ($value*100) . "%" : 0; - } - if ($opt_key eq 'threads' && !$Slic3r::have_threads) { - $value = 1; - } - if ($opt_key eq 'gcode_flavor' && $value eq 'makerbot') { - $value = 'makerware'; - } - if ($opt_key eq 'fill_density' && defined($value) && $value !~ /%/ && $value <= 1) { - # fill_density was turned into a percent value - $value *= 100; - $value = "$value"; # force update of the PV value, workaround for bug https://rt.cpan.org/Ticket/Display.html?id=94110 - } - if ($opt_key eq 'randomize_start' && $value) { - $opt_key = 'seam_position'; - $value = 'random'; - } - if ($opt_key eq 'bed_size' && $value) { - $opt_key = 'bed_shape'; - my ($x, $y) = split /,/, $value; - $value = "0x0,${x}x0,${x}x${y},0x${y}"; - } - return () if first { $_ eq $opt_key } @Ignore; - - # For historical reasons, the world's full of configs having these very low values; - # to avoid unexpected behavior we need to ignore them. Banning these two hard-coded - # values is a dirty hack and will need to be removed sometime in the future, but it - # will avoid lots of complaints for now. - if ($opt_key eq 'perimeter_acceleration' && $value == '25') { - $value = 0; - } - if ($opt_key eq 'infill_acceleration' && $value == '50') { - $value = 0; - } - - if (!exists $Options->{$opt_key}) { - my @keys = grep { $Options->{$_}{aliases} && grep $_ eq $opt_key, @{$Options->{$_}{aliases}} } keys %$Options; - if (!@keys) { - warn "Unknown option $opt_key\n"; - return (); - } - $opt_key = $keys[0]; - } - - return ($opt_key, $value); -} - # Create a hash of hashes from the underlying C++ Slic3r::DynamicPrintConfig. # The first hash key is '_' meaning no category. sub as_ini { diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 66b3d0445..9901282ff 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -220,6 +221,12 @@ ConfigDef::add(const t_config_option_key &opt_key, const ConfigOptionDef &def) return &this->options[opt_key]; } +bool +ConfigDef::has(const t_config_option_key &opt_key) const +{ + return this->options.count(opt_key) > 0; +} + const ConfigOptionDef* ConfigDef::get(const t_config_option_key &opt_key) const { @@ -288,12 +295,27 @@ ConfigBase::serialize(const t_config_option_key &opt_key) const { } bool -ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str, bool append) { +ConfigBase::set_deserialize(t_config_option_key opt_key, std::string str, bool append) { const ConfigOptionDef* optdef = this->def->get(opt_key); - if (optdef == NULL) throw UnknownOptionException(); + if (optdef == NULL) { + // If we didn't find an option, look for any other option having this as an alias. + for (const auto &opt : this->def->options) { + for (const t_config_option_key &opt_key2 : opt.second.aliases) { + if (opt_key2 == opt_key) { + opt_key = opt_key2; + optdef = &opt.second; + break; + } + } + if (optdef != NULL) break; + } + if (optdef == NULL) + throw UnknownOptionException(); + } + if (!optdef->shortcut.empty()) { - for (std::vector::const_iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) { - if (!this->set_deserialize(*it, str)) return false; + for (const t_config_option_key &shortcut : optdef->shortcut) { + if (!this->set_deserialize(shortcut, str)) return false; } return true; } @@ -373,7 +395,9 @@ ConfigBase::load(const std::string &file) pt::read_ini(file, tree); BOOST_FOREACH(const pt::ptree::value_type &v, tree) { try { - this->set_deserialize(v.first.c_str(), v.second.get_value().c_str()); + t_config_option_key opt_key = v.first; + std::string value = v.second.get_value(); + this->set_deserialize(opt_key, value); } catch (UnknownOptionException &e) { // ignore } diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index 32a80adee..412c65fd3 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -649,6 +649,7 @@ class ConfigDef 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); + bool has(const t_config_option_key &opt_key) const; const ConfigOptionDef* get(const t_config_option_key &opt_key) const; void merge(const ConfigDef &other); }; @@ -675,7 +676,7 @@ class ConfigBase bool equals(ConfigBase &other); t_config_option_keys diff(ConfigBase &other); std::string serialize(const t_config_option_key &opt_key) const; - bool set_deserialize(const t_config_option_key &opt_key, std::string str, bool append = false); + virtual bool set_deserialize(t_config_option_key opt_key, std::string str, bool append = false); double get_abs_value(const t_config_option_key &opt_key) const; double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const; void setenv_(); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 63d600e4e..5a932bde7 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -1,4 +1,5 @@ #include "PrintConfig.hpp" +#include #include namespace Slic3r { @@ -1577,6 +1578,79 @@ PrintConfigBase::min_object_distance() const : duplicate_distance; } +bool +PrintConfigBase::set_deserialize(t_config_option_key opt_key, std::string str, bool append) +{ + this->_handle_legacy(opt_key, str); + if (opt_key.empty()) return true; // ignore option + return ConfigBase::set_deserialize(opt_key, str, append); +} + +void +PrintConfigBase::_handle_legacy(t_config_option_key &opt_key, std::string &value) const +{ + // handle legacy options + if (opt_key == "extrusion_width_ratio" || opt_key == "bottom_layer_speed_ratio" + || opt_key == "first_layer_height_ratio") { + boost::replace_first(opt_key, "_ratio", ""); + if (opt_key == "bottom_layer_speed") opt_key = "first_layer_speed"; + try { + float v = boost::lexical_cast(value); + if (v != 0) + value = boost::lexical_cast(v*100) + "%"; + } catch (boost::bad_lexical_cast &) { + value = "0"; + } + } else if (opt_key == "gcode_flavor" && value == "makerbot") { + value = "makerware"; + } else if (opt_key == "fill_density" && value.find("%") == std::string::npos) { + try { + // fill_density was turned into a percent value + float v = boost::lexical_cast(value); + value = boost::lexical_cast(v*100) + "%"; + } catch (boost::bad_lexical_cast &) {} + } else if (opt_key == "randomize_start" && value == "1") { + opt_key = "seam_position"; + value = "random"; + } else if (opt_key == "bed_size" && !value.empty()) { + opt_key = "bed_shape"; + ConfigOptionPoint p; + p.deserialize(value); + std::ostringstream oss; + oss << "0x0," << p.value.x << "x0," << p.value.x << "x" << p.value.y << ",0x" << p.value.y; + value = oss.str(); + } else if ((opt_key == "perimeter_acceleration" && value == "25") + || (opt_key == "infill_acceleration" && value == "50")) { + /* For historical reasons, the world's full of configs having these very low values; + to avoid unexpected behavior we need to ignore them. Banning these two hard-coded + values is a dirty hack and will need to be removed sometime in the future, but it + will avoid lots of complaints for now. */ + value = "0"; + } + + // cemetery of old config settings + if (opt_key == "duplicate_x" || opt_key == "duplicate_y" || opt_key == "multiply_x" + || opt_key == "multiply_y" || opt_key == "support_material_tool" + || opt_key == "acceleration" || opt_key == "adjust_overhang_flow" + || opt_key == "standby_temperature" || opt_key == "scale" || opt_key == "rotate" + || opt_key == "duplicate" || opt_key == "duplicate_grid" || opt_key == "rotate" + || opt_key == "scale" || opt_key == "duplicate_grid" + || opt_key == "start_perimeters_at_concave_points" + || opt_key == "start_perimeters_at_non_overhang" || opt_key == "randomize_start" + || opt_key == "seal_position" || opt_key == "bed_size" + || opt_key == "print_center" || opt_key == "g0" || opt_key == "threads") + { + opt_key = ""; + return; + } + + if (!this->def->has(opt_key)) { + printf("Unknown option %s\n", opt_key.c_str()); + opt_key = ""; + return; + } +} + CLIConfigDef::CLIConfigDef() { ConfigOptionDef* def; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 2ea423d8c..5cf7054bf 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -112,8 +112,11 @@ class PrintConfigBase : public virtual ConfigBase PrintConfigBase() { this->def = &print_config_def; }; - + bool set_deserialize(t_config_option_key opt_key, std::string str, bool append = false); double min_object_distance() const; + + protected: + void _handle_legacy(t_config_option_key &opt_key, std::string &value) const; }; // Slic3r dynamic configuration, used to override the configuration