diff --git a/lib/Slic3r/GCode/PlaceholderParser.pm b/lib/Slic3r/GCode/PlaceholderParser.pm index 4dbb44819..0c2dafb82 100644 --- a/lib/Slic3r/GCode/PlaceholderParser.pm +++ b/lib/Slic3r/GCode/PlaceholderParser.pm @@ -30,32 +30,6 @@ sub update_timestamp { $self->_single_set('version', $Slic3r::VERSION); } -sub apply_config { - my ($self, $config) = @_; - - # options with single value - my @opt_keys = grep $Slic3r::Config::Options->{$_}{cli} !~ /\@$/, - grep !$Slic3r::Config::Options->{$_}{multiline}, - @{$config->get_keys}; - $self->_single_set($_, $config->serialize($_)) for @opt_keys; - - # options with multiple values - foreach my $opt_key (@opt_keys) { - my $value = $config->$opt_key; - next unless ref($value) eq 'ARRAY'; - # TODO: this is a workaroud for XS string param handling - # https://rt.cpan.org/Public/Bug/Display.html?id=94110 - no warnings 'void'; - "$_" for @$value; - $self->_multiple_set("${opt_key}_" . $_, $value->[$_]."") for 0..$#$value; - $self->_multiple_set($opt_key, $value->[0].""); - if ($Slic3r::Config::Options->{$opt_key}{type} eq 'point') { - $self->_multiple_set("${opt_key}_X", $value->[0].""); - $self->_multiple_set("${opt_key}_Y", $value->[1].""); - } - } -} - # TODO: or this could be an alias sub set { my ($self, $key, $val) = @_; diff --git a/xs/src/PlaceholderParser.cpp b/xs/src/PlaceholderParser.cpp index 78e48ef40..c384afa32 100644 --- a/xs/src/PlaceholderParser.cpp +++ b/xs/src/PlaceholderParser.cpp @@ -1,7 +1,4 @@ #include "PlaceholderParser.hpp" -#ifdef SLIC3RXS -#include "perlglue.hpp" -#endif namespace Slic3r { @@ -18,6 +15,104 @@ PlaceholderParser::~PlaceholderParser() { } +void PlaceholderParser::apply_config(DynamicPrintConfig &config) +{ + // options that are set and aren't text-boxes + t_config_option_keys opt_keys; + for (t_optiondef_map::iterator i = config.def->begin(); + i != config.def->end(); ++i) + { + const t_config_option_key &key = i->first; + const ConfigOptionDef &def = i->second; + + if (config.has(key) && !def.multiline) { + opt_keys.push_back(key); + } + } + + for (t_config_option_keys::iterator i = opt_keys.begin(); + i != opt_keys.end(); ++i) + { + const t_config_option_key &key = *i; + + // set placeholders for options with multiple values + const ConfigOptionDef &def = (*config.def)[key]; + switch (def.type) { + case coFloats: + this->set_multiple_from_vector(key, + *(ConfigOptionFloats*)config.option(key)); + break; + + case coInts: + this->set_multiple_from_vector(key, + *(ConfigOptionInts*)config.option(key)); + break; + + case coStrings: + this->set_multiple_from_vector(key, + *(ConfigOptionStrings*)config.option(key)); + break; + + case coPoints: + this->set_multiple_from_vector(key, + *(ConfigOptionPoints*)config.option(key)); + break; + + case coBools: + this->set_multiple_from_vector(key, + *(ConfigOptionBools*)config.option(key)); + break; + + case coPoint: + { + const ConfigOptionPoint &opt = + *(ConfigOptionPoint*)config.option(key); + + this->_single[key] = opt.serialize(); + + Pointf val = opt; + this->_multiple[key + "_X"] = val.x; + this->_multiple[key + "_Y"] = val.y; + } + + break; + + default: + // set single-value placeholders + this->_single[key] = config.serialize(key); + break; + } + } +} + +std::ostream& operator<<(std::ostream &stm, const Pointf &pointf) +{ + return stm << pointf.x << "," << pointf.y; +} + +template +void PlaceholderParser::set_multiple_from_vector(const std::string &key, + ConfigOptionVector &opt) +{ + const std::vector &vals = opt.values; + + for (size_t i = 0; i < vals.size(); ++i) { + std::stringstream multikey_stm; + multikey_stm << key << "_" << i; + + std::stringstream val_stm; + val_stm << vals[i]; + + this->_multiple[multikey_stm.str()] = val_stm.str(); + } + + if (vals.size() > 0) { + std::stringstream val_stm; + val_stm << vals[0]; + this->_multiple[key] = val_stm.str(); + } +} + #ifdef SLIC3RXS REGISTER_CLASS(PlaceholderParser, "GCode::PlaceholderParser"); #endif diff --git a/xs/src/PlaceholderParser.hpp b/xs/src/PlaceholderParser.hpp index 13c229da8..e69d6ed93 100644 --- a/xs/src/PlaceholderParser.hpp +++ b/xs/src/PlaceholderParser.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "PrintConfig.hpp" namespace Slic3r { @@ -17,6 +18,13 @@ class PlaceholderParser PlaceholderParser(); ~PlaceholderParser(); + + void apply_config(DynamicPrintConfig &config); + + private: + template + void set_multiple_from_vector( + const std::string &key, ConfigOptionVector &opt); }; } diff --git a/xs/xsp/PlaceholderParser.xsp b/xs/xsp/PlaceholderParser.xsp index 18ea6b58d..1f027a0d7 100644 --- a/xs/xsp/PlaceholderParser.xsp +++ b/xs/xsp/PlaceholderParser.xsp @@ -10,10 +10,11 @@ %name{_new} PlaceholderParser(); ~PlaceholderParser(); + void apply_config(DynamicPrintConfig *config) + %code%{ THIS->apply_config(*config); %}; + void _single_set(std::string k, std::string v) %code%{ THIS->_single[k] = v; %}; - void _multiple_set(std::string k, std::string v) - %code%{ THIS->_multiple[k] = v; %}; std::string _single_get(std::string k) %code%{ RETVAL = THIS->_single[k]; %};