diff --git a/xs/src/Config.cpp b/xs/src/Config.cpp index 7c3280d5f..e1c520e61 100644 --- a/xs/src/Config.cpp +++ b/xs/src/Config.cpp @@ -22,7 +22,8 @@ ConfigBase::apply(const ConfigBase &other, bool ignore_nonexistent) { } // not the most efficient way, but easier than casting pointers to subclasses - my_opt->deserialize( other.option(*it)->serialize() ); + bool res = my_opt->deserialize( other.option(*it)->serialize() ); + if (!res) CONFESS("Unexpected failure when deserializing serialized value"); } } diff --git a/xs/src/Config.hpp b/xs/src/Config.hpp index 5b4cb8284..e6832cf55 100644 --- a/xs/src/Config.hpp +++ b/xs/src/Config.hpp @@ -265,8 +265,14 @@ class ConfigOptionPoint : public ConfigOption }; bool deserialize(std::string str) { - int res = sscanf(str.c_str(), "%lf%*1[,x]%lf", &this->point.x, &this->point.y); - return res == 2; + if (strncmp(str.c_str(), "0x", 2) == 0) { + this->point.x = 0; + int res = sscanf(str.c_str()+2, "%lf", &this->point.y); + return res == 1; + } else { + int res = sscanf(str.c_str(), "%lf%*1[,x]%lf", &this->point.x, &this->point.y); + return res == 2; + } }; }; @@ -286,15 +292,24 @@ class ConfigOptionPoints : public ConfigOption, public ConfigOptionVectorvalues.clear(); + std::vector values; std::istringstream is(str); std::string point_str; while (std::getline(is, point_str, ',')) { Pointf point; - int res = sscanf(point_str.c_str(), "%lfx%lf", &point.x, &point.y); - if (res != 2) return false; - this->values.push_back(point); + if (strncmp(point_str.c_str(), "0x", 2) == 0) { + // if string starts with "0x", only apply sscanf() to the second coordinate + // otherwise it would parse the string as a hex number + point.x = 0; + int res = sscanf(point_str.c_str()+2, "%lf", &point.y); + if (res != 1) return false; + } else { + int res = sscanf(point_str.c_str(), "%lfx%lf", &point.x, &point.y); + if (res != 2) return false; + } + values.push_back(point); } + this->values = values; return true; }; }; diff --git a/xs/t/15_config.t b/xs/t/15_config.t index c281e2225..b3e16d387 100644 --- a/xs/t/15_config.t +++ b/xs/t/15_config.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 94; +use Test::More tests => 95; foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { $config->set('layer_height', 0.3); @@ -144,4 +144,13 @@ foreach my $config (Slic3r::Config->new, Slic3r::Config::Full->new) { } } +{ + my $config = Slic3r::Config->new; + # the pair [0,0] is part of the test, since it checks whether the 0x0 serialized value is correctly parsed + $config->set('extruder_offset', [ [0,0], [20,0], [0,20] ]); + my $config2 = Slic3r::Config->new; + $config2->apply($config); + is_deeply $config->get('extruder_offset'), $config2->get('extruder_offset'), 'apply dynamic over dynamic'; +} + __END__