mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-15 01:46:01 +08:00
Port --load and --save to XS
This commit is contained in:
parent
c2b06b22aa
commit
30139fd647
@ -87,8 +87,10 @@ sub load {
|
||||
my $class = shift;
|
||||
my ($file) = @_;
|
||||
|
||||
my $ini = __PACKAGE__->read_ini($file);
|
||||
return $class->load_ini_hash($ini->{_});
|
||||
# legacy syntax of load()
|
||||
my $config = $class->new;
|
||||
$config->_load($file);
|
||||
return $config;
|
||||
}
|
||||
|
||||
sub load_ini_hash {
|
||||
@ -186,13 +188,6 @@ sub as_ini {
|
||||
return $ini;
|
||||
}
|
||||
|
||||
sub save {
|
||||
my $self = shift;
|
||||
my ($file) = @_;
|
||||
|
||||
__PACKAGE__->write_ini($file, $self->as_ini);
|
||||
}
|
||||
|
||||
# this method is idempotent by design and only applies to ::DynamicConfig or ::Full
|
||||
# objects because it performs cross checks
|
||||
sub validate {
|
||||
|
@ -24,17 +24,28 @@ main(const int argc, const char **argv)
|
||||
t_config_option_keys input_files;
|
||||
config.read_cli(argc, argv, &input_files);
|
||||
|
||||
// apply command line options to a more specific DynamicPrintConfig which provides normalize()
|
||||
DynamicPrintConfig print_config;
|
||||
print_config.apply(config, true);
|
||||
print_config.normalize();
|
||||
|
||||
// apply command line options to a more handy CLIConfig
|
||||
CLIConfig cli_config;
|
||||
cli_config.apply(config, true);
|
||||
|
||||
/* TODO: loop through the config files supplied on the command line (now stored in
|
||||
cli_config), load each one, normalize it and apply it to print_config */
|
||||
DynamicPrintConfig print_config;
|
||||
|
||||
// load config files supplied via --load
|
||||
for (std::vector<std::string>::const_iterator file = cli_config.load.values.begin();
|
||||
file != cli_config.load.values.end(); ++file) {
|
||||
DynamicPrintConfig c;
|
||||
c.load(*file);
|
||||
c.normalize();
|
||||
print_config.apply(c);
|
||||
}
|
||||
|
||||
// apply command line options to a more specific DynamicPrintConfig which provides normalize()
|
||||
// (command line options override --load files)
|
||||
print_config.apply(config, true);
|
||||
print_config.normalize();
|
||||
|
||||
// write config if requested
|
||||
if (!cli_config.save.value.empty()) print_config.save(cli_config.save.value);
|
||||
|
||||
// read input file(s) if any
|
||||
std::vector<Model> models;
|
||||
|
@ -1,8 +1,14 @@
|
||||
#include "Config.hpp"
|
||||
#include <stdlib.h> // for setenv()
|
||||
#include <assert.h>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <boost/algorithm/string/erase.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/property_tree/ini_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
#if defined(_WIN32) && !defined(setenv) && defined(_putenv_s)
|
||||
#define setenv(k, v, o) _putenv_s(k, v)
|
||||
@ -116,7 +122,7 @@ ConfigBase::serialize(const t_config_option_key &opt_key) const {
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str) {
|
||||
ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str, bool append) {
|
||||
const ConfigOptionDef* optdef = this->def->get(opt_key);
|
||||
if (optdef == NULL) throw "Calling set_deserialize() on unknown option";
|
||||
if (!optdef->shortcut.empty()) {
|
||||
@ -128,7 +134,7 @@ ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str)
|
||||
|
||||
ConfigOption* opt = this->option(opt_key, true);
|
||||
assert(opt != NULL);
|
||||
return opt->deserialize(str);
|
||||
return opt->deserialize(str, append);
|
||||
}
|
||||
|
||||
double
|
||||
@ -189,6 +195,38 @@ ConfigBase::option(const t_config_option_key &opt_key, bool create) {
|
||||
return this->optptr(opt_key, create);
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::load(const std::string &file)
|
||||
{
|
||||
namespace pt = boost::property_tree;
|
||||
pt::ptree tree;
|
||||
pt::read_ini(file, tree);
|
||||
BOOST_FOREACH(const pt::ptree::value_type &v, tree) {
|
||||
this->set_deserialize(v.first.c_str(), v.second.get_value<std::string>().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigBase::save(const std::string &file) const
|
||||
{
|
||||
using namespace std;
|
||||
ofstream c;
|
||||
c.open(file.c_str(), ios::out | ios::trunc);
|
||||
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
char buf[sizeof "0000-00-00 00:00:00"];
|
||||
strftime(buf, sizeof buf, "%F %T", gmtime(&now));
|
||||
c << "# generated by Slic3r " << SLIC3R_VERSION << " on " << buf << endl;
|
||||
}
|
||||
|
||||
t_config_option_keys my_keys = this->keys();
|
||||
for (t_config_option_keys::const_iterator opt_key = my_keys.begin(); opt_key != my_keys.end(); ++opt_key)
|
||||
c << *opt_key << " = " << this->serialize(*opt_key) << endl;
|
||||
c.close();
|
||||
}
|
||||
|
||||
DynamicConfig& DynamicConfig::operator= (DynamicConfig other)
|
||||
{
|
||||
this->swap(other);
|
||||
@ -325,11 +363,11 @@ DynamicConfig::read_cli(const int argc, const char** argv, t_config_option_keys*
|
||||
opt->values.push_back(!boost::starts_with(token, "no-"));
|
||||
} else {
|
||||
// we expect one more token carrying the value
|
||||
if (i == argc) {
|
||||
if (i == (argc-1)) {
|
||||
printf("No value supplied for --%s\n", token.c_str());
|
||||
exit(1);
|
||||
}
|
||||
this->option(opt_key, true)->deserialize(argv[++i]);
|
||||
this->set_deserialize(opt_key, argv[++i], true);
|
||||
}
|
||||
} else {
|
||||
extra->push_back(token);
|
||||
|
@ -22,7 +22,7 @@ class ConfigOption {
|
||||
virtual ~ConfigOption() {};
|
||||
virtual ConfigOption* clone() const = 0;
|
||||
virtual std::string serialize() const = 0;
|
||||
virtual bool deserialize(std::string str) = 0;
|
||||
virtual bool deserialize(std::string str, bool append = false) = 0;
|
||||
virtual void set(const ConfigOption &option) = 0;
|
||||
virtual int getInt() const { return 0; };
|
||||
virtual double getFloat() const { return 0; };
|
||||
@ -90,7 +90,7 @@ class ConfigOptionFloat : public ConfigOptionSingle<double>
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
return !iss.fail();
|
||||
@ -123,8 +123,8 @@ class ConfigOptionFloats : public ConfigOptionVector<double>
|
||||
return vv;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
this->values.clear();
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (!append) this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ',')) {
|
||||
@ -153,7 +153,7 @@ class ConfigOptionInt : public ConfigOptionSingle<int>
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
return !iss.fail();
|
||||
@ -186,8 +186,8 @@ class ConfigOptionInts : public ConfigOptionVector<int>
|
||||
return vv;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
this->values.clear();
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (!append) this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ',')) {
|
||||
@ -222,7 +222,7 @@ class ConfigOptionString : public ConfigOptionSingle<std::string>
|
||||
return str;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
// s/\\n/\n/g
|
||||
size_t pos = 0;
|
||||
while ((pos = str.find("\\n", pos)) != std::string::npos) {
|
||||
@ -256,8 +256,8 @@ class ConfigOptionStrings : public ConfigOptionVector<std::string>
|
||||
return this->values;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
this->values.clear();
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (!append) this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ';')) {
|
||||
@ -286,7 +286,7 @@ class ConfigOptionPercent : public ConfigOptionFloat
|
||||
return s;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
// don't try to parse the trailing % since it's optional
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
@ -327,7 +327,7 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
|
||||
return s;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
this->percent = str.find_first_of("%") != std::string::npos;
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value;
|
||||
@ -350,7 +350,7 @@ class ConfigOptionPoint : public ConfigOptionSingle<Pointf>
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
std::istringstream iss(str);
|
||||
iss >> this->value.x;
|
||||
iss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
|
||||
@ -388,8 +388,8 @@ class ConfigOptionPoints : public ConfigOptionVector<Pointf>
|
||||
return vv;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
this->values.clear();
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (!append) this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string point_str;
|
||||
while (std::getline(is, point_str, ',')) {
|
||||
@ -421,7 +421,7 @@ class ConfigOptionBool : public ConfigOptionSingle<bool>
|
||||
return std::string(this->value ? "1" : "0");
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
this->value = (str.compare("1") == 0);
|
||||
return true;
|
||||
};
|
||||
@ -453,8 +453,8 @@ class ConfigOptionBools : public ConfigOptionVector<bool>
|
||||
return vv;
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
this->values.clear();
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (!append) this->values.clear();
|
||||
std::istringstream is(str);
|
||||
std::string item_str;
|
||||
while (std::getline(is, item_str, ',')) {
|
||||
@ -483,7 +483,7 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>
|
||||
return "";
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
t_config_enum_values enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
|
||||
if (enum_keys_map.count(str) == 0) return false;
|
||||
this->value = static_cast<T>(enum_keys_map[str]);
|
||||
@ -507,7 +507,7 @@ class ConfigOptionEnumGeneric : public ConfigOptionInt
|
||||
return "";
|
||||
};
|
||||
|
||||
bool deserialize(std::string str) {
|
||||
bool deserialize(std::string str, bool append = false) {
|
||||
if (this->keys_map->count(str) == 0) return false;
|
||||
this->value = (*const_cast<t_config_enum_values*>(this->keys_map))[str];
|
||||
return true;
|
||||
@ -596,10 +596,12 @@ 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 set_deserialize(const t_config_option_key &opt_key, std::string str, bool append = false);
|
||||
double get_abs_value(const t_config_option_key &opt_key);
|
||||
double get_abs_value(const t_config_option_key &opt_key, double ratio_over);
|
||||
void setenv_();
|
||||
void load(const std::string &file);
|
||||
void save(const std::string &file) const;
|
||||
};
|
||||
|
||||
class DynamicConfig : public virtual ConfigBase
|
||||
|
@ -1383,6 +1383,12 @@ CLIConfigDef::CLIConfigDef()
|
||||
def->cli = "info";
|
||||
def->default_value = new ConfigOptionBool(false);
|
||||
|
||||
def = this->add("load", coStrings);
|
||||
def->label = "Load config file";
|
||||
def->tooltip = "Load configuration from the specified file. It can be used more than once to load options from multiple files.";
|
||||
def->cli = "load";
|
||||
def->default_value = new ConfigOptionStrings();
|
||||
|
||||
def = this->add("output", coString);
|
||||
def->label = "Output File";
|
||||
def->tooltip = "The file where the output will be written (if not specified, it will be based on the input file).";
|
||||
@ -1395,6 +1401,12 @@ CLIConfigDef::CLIConfigDef()
|
||||
def->cli = "rotate";
|
||||
def->default_value = new ConfigOptionFloat(0);
|
||||
|
||||
def = this->add("save", coString);
|
||||
def->label = "Save config file";
|
||||
def->tooltip = "Save configuration to the specified file.";
|
||||
def->cli = "save";
|
||||
def->default_value = new ConfigOptionString();
|
||||
|
||||
def = this->add("scale", coFloat);
|
||||
def->label = "Scale";
|
||||
def->tooltip = "Scaling factor (default: 1).";
|
||||
|
@ -506,8 +506,10 @@ class CLIConfig
|
||||
ConfigOptionBool export_pov;
|
||||
ConfigOptionBool export_svg;
|
||||
ConfigOptionBool info;
|
||||
ConfigOptionStrings load;
|
||||
ConfigOptionString output;
|
||||
ConfigOptionFloat rotate;
|
||||
ConfigOptionString save;
|
||||
ConfigOptionFloat scale;
|
||||
|
||||
CLIConfig() : ConfigBase(), StaticConfig() {
|
||||
@ -520,8 +522,10 @@ class CLIConfig
|
||||
OPT_PTR(export_pov);
|
||||
OPT_PTR(export_svg);
|
||||
OPT_PTR(info);
|
||||
OPT_PTR(load);
|
||||
OPT_PTR(output);
|
||||
OPT_PTR(rotate);
|
||||
OPT_PTR(save);
|
||||
OPT_PTR(scale);
|
||||
|
||||
return NULL;
|
||||
|
@ -38,6 +38,8 @@
|
||||
void normalize();
|
||||
%name{setenv} void setenv_();
|
||||
double min_object_distance();
|
||||
%name{_load} void load(std::string file);
|
||||
void save(std::string file);
|
||||
};
|
||||
|
||||
%name{Slic3r::Config::Static} class StaticPrintConfig {
|
||||
@ -84,6 +86,8 @@
|
||||
%};
|
||||
%name{setenv} void setenv_();
|
||||
double min_object_distance();
|
||||
%name{_load} void load(std::string file);
|
||||
void save(std::string file);
|
||||
};
|
||||
|
||||
%package{Slic3r::Config};
|
||||
|
Loading…
x
Reference in New Issue
Block a user