mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 00:37:51 -06:00
Added C++ command line processing, thanks @alexrj and @loh
This commit is contained in:
parent
6ca5a18d05
commit
add45a8f6e
11 changed files with 467 additions and 105 deletions
|
@ -241,6 +241,7 @@ add_subdirectory(resources/localization)
|
||||||
|
|
||||||
# libslic3r, Slic3r GUI and the slic3r executable.
|
# libslic3r, Slic3r GUI and the slic3r executable.
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT slic3r)
|
||||||
|
|
||||||
# Perl bindings, currently only used for the unit / integration tests of libslic3r.
|
# Perl bindings, currently only used for the unit / integration tests of libslic3r.
|
||||||
# Also runs the unit / integration tests.
|
# Also runs the unit / integration tests.
|
||||||
|
|
|
@ -566,6 +566,103 @@ ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool cre
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynamicConfig::read_cli(const std::vector<std::string> &tokens, t_config_option_keys* extra)
|
||||||
|
{
|
||||||
|
std::vector<char*> args;
|
||||||
|
// push a bogus executable name (argv[0])
|
||||||
|
args.emplace_back(const_cast<char*>(""));
|
||||||
|
for (size_t i = 0; i < tokens.size(); ++ i)
|
||||||
|
args.emplace_back(const_cast<char *>(tokens[i].c_str()));
|
||||||
|
this->read_cli(args.size(), &args[0], extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DynamicConfig::read_cli(int argc, char** argv, t_config_option_keys* extra)
|
||||||
|
{
|
||||||
|
// cache the CLI option => opt_key mapping
|
||||||
|
std::map<std::string,std::string> opts;
|
||||||
|
for (const auto &oit : this->def()->options) {
|
||||||
|
std::string cli = oit.second.cli;
|
||||||
|
cli = cli.substr(0, cli.find("="));
|
||||||
|
boost::trim_right_if(cli, boost::is_any_of("!"));
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
boost::split(tokens, cli, boost::is_any_of("|"));
|
||||||
|
for (const std::string &t : tokens)
|
||||||
|
opts[t] = oit.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_options = true;
|
||||||
|
for (int i = 1; i < argc; ++ i) {
|
||||||
|
std::string token = argv[i];
|
||||||
|
// Store non-option arguments in the provided vector.
|
||||||
|
if (! parse_options || ! boost::starts_with(token, "-")) {
|
||||||
|
extra->push_back(token);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Stop parsing tokens as options when -- is supplied.
|
||||||
|
if (token == "--") {
|
||||||
|
parse_options = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Remove leading dashes
|
||||||
|
boost::trim_left_if(token, boost::is_any_of("-"));
|
||||||
|
// Remove the "no-" prefix used to negate boolean options.
|
||||||
|
bool no = false;
|
||||||
|
if (boost::starts_with(token, "no-")) {
|
||||||
|
no = true;
|
||||||
|
boost::replace_first(token, "no-", "");
|
||||||
|
}
|
||||||
|
// Read value when supplied in the --key=value form.
|
||||||
|
std::string value;
|
||||||
|
{
|
||||||
|
size_t equals_pos = token.find("=");
|
||||||
|
if (equals_pos != std::string::npos) {
|
||||||
|
value = token.substr(equals_pos+1);
|
||||||
|
token.erase(equals_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Look for the cli -> option mapping.
|
||||||
|
const auto it = opts.find(token);
|
||||||
|
if (it == opts.end()) {
|
||||||
|
printf("Warning: unknown option --%s\n", token.c_str());
|
||||||
|
// instead of continuing, return false to caller
|
||||||
|
// to stop execution and print usage
|
||||||
|
return false;
|
||||||
|
//continue;
|
||||||
|
}
|
||||||
|
const t_config_option_key opt_key = it->second;
|
||||||
|
const ConfigOptionDef &optdef = this->def()->options.at(opt_key);
|
||||||
|
// If the option type expects a value and it was not already provided,
|
||||||
|
// look for it in the next token.
|
||||||
|
if (optdef.type != coBool && optdef.type != coBools && value.empty()) {
|
||||||
|
if (i == (argc-1)) {
|
||||||
|
printf("No value supplied for --%s\n", token.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value = argv[++ i];
|
||||||
|
}
|
||||||
|
// Store the option value.
|
||||||
|
const bool existing = this->has(opt_key);
|
||||||
|
if (ConfigOptionBool* opt = this->opt<ConfigOptionBool>(opt_key, true)) {
|
||||||
|
opt->value = !no;
|
||||||
|
} else if (ConfigOptionBools* opt = this->opt<ConfigOptionBools>(opt_key, true)) {
|
||||||
|
if (!existing) opt->values.clear(); // remove the default values
|
||||||
|
opt->values.push_back(!no);
|
||||||
|
} else if (ConfigOptionStrings* opt = this->opt<ConfigOptionStrings>(opt_key, true)) {
|
||||||
|
if (!existing) opt->values.clear(); // remove the default values
|
||||||
|
opt->deserialize(value, true);
|
||||||
|
} else if (ConfigOptionFloats* opt = this->opt<ConfigOptionFloats>(opt_key, true)) {
|
||||||
|
if (!existing) opt->values.clear(); // remove the default values
|
||||||
|
opt->deserialize(value, true);
|
||||||
|
} else if (ConfigOptionPoints* opt = this->opt<ConfigOptionPoints>(opt_key, true)) {
|
||||||
|
if (!existing) opt->values.clear(); // remove the default values
|
||||||
|
opt->deserialize(value, true);
|
||||||
|
} else {
|
||||||
|
this->set_deserialize(opt_key, value, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
t_config_option_keys DynamicConfig::keys() const
|
t_config_option_keys DynamicConfig::keys() const
|
||||||
{
|
{
|
||||||
t_config_option_keys keys;
|
t_config_option_keys keys;
|
||||||
|
|
|
@ -976,7 +976,7 @@ public:
|
||||||
// Map from a config option name to its definition.
|
// Map from a config option name to its definition.
|
||||||
// The definition does not carry an actual value of the config option, only its constant default value.
|
// The definition does not carry an actual value of the config option, only its constant default value.
|
||||||
// t_config_option_key is std::string
|
// t_config_option_key is std::string
|
||||||
typedef std::map<t_config_option_key,ConfigOptionDef> t_optiondef_map;
|
typedef std::map<t_config_option_key, ConfigOptionDef> t_optiondef_map;
|
||||||
|
|
||||||
// Definition of configuration values for the purpose of GUI presentation, editing, value mapping and config file handling.
|
// Definition of configuration values for the purpose of GUI presentation, editing, value mapping and config file handling.
|
||||||
// The configuration definition is static: It does not carry the actual configuration values,
|
// The configuration definition is static: It does not carry the actual configuration values,
|
||||||
|
@ -984,18 +984,27 @@ typedef std::map<t_config_option_key,ConfigOptionDef> t_optiondef_map;
|
||||||
class ConfigDef
|
class ConfigDef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
t_optiondef_map options;
|
t_optiondef_map options;
|
||||||
~ConfigDef() { for (auto &opt : this->options) delete opt.second.default_value; }
|
|
||||||
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type) {
|
|
||||||
ConfigOptionDef* opt = &this->options[opt_key];
|
|
||||||
opt->type = type;
|
|
||||||
return opt;
|
|
||||||
}
|
|
||||||
bool has(const t_config_option_key &opt_key) const { return this->options.count(opt_key) > 0; }
|
bool has(const t_config_option_key &opt_key) const { return this->options.count(opt_key) > 0; }
|
||||||
const ConfigOptionDef* get(const t_config_option_key &opt_key) const {
|
const ConfigOptionDef* get(const t_config_option_key &opt_key) const {
|
||||||
t_optiondef_map::iterator it = const_cast<ConfigDef*>(this)->options.find(opt_key);
|
t_optiondef_map::iterator it = const_cast<ConfigDef*>(this)->options.find(opt_key);
|
||||||
return (it == this->options.end()) ? nullptr : &it->second;
|
return (it == this->options.end()) ? nullptr : &it->second;
|
||||||
}
|
}
|
||||||
|
std::vector<std::string> keys() const {
|
||||||
|
std::vector<std::string> out;
|
||||||
|
out.reserve(options.size());
|
||||||
|
for(auto const& kvp : options)
|
||||||
|
out.push_back(kvp.first);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConfigOptionDef* add(const t_config_option_key &opt_key, ConfigOptionType type) {
|
||||||
|
ConfigOptionDef* opt = &this->options[opt_key];
|
||||||
|
opt->type = type;
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// An abstract configuration store.
|
// An abstract configuration store.
|
||||||
|
@ -1219,6 +1228,10 @@ public:
|
||||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||||
|
|
||||||
|
// Command line processing
|
||||||
|
void read_cli(const std::vector<std::string> &tokens, t_config_option_keys* extra);
|
||||||
|
bool read_cli(int argc, char** argv, t_config_option_keys* extra);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<t_config_option_key,ConfigOption*> t_options_map;
|
typedef std::map<t_config_option_key,ConfigOption*> t_options_map;
|
||||||
t_options_map options;
|
t_options_map options;
|
||||||
|
|
|
@ -113,6 +113,12 @@ Model Model::read_from_archive(const std::string &input_file, PresetBundle* bund
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::repair()
|
||||||
|
{
|
||||||
|
for (ModelObject *o : this->objects)
|
||||||
|
o->repair();
|
||||||
|
}
|
||||||
|
|
||||||
ModelObject* Model::add_object()
|
ModelObject* Model::add_object()
|
||||||
{
|
{
|
||||||
this->objects.emplace_back(new ModelObject(this));
|
this->objects.emplace_back(new ModelObject(this));
|
||||||
|
@ -886,6 +892,12 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelObject::repair()
|
||||||
|
{
|
||||||
|
for (ModelVolume *v : this->volumes)
|
||||||
|
v->mesh.repair();
|
||||||
|
}
|
||||||
|
|
||||||
// Called by Print::validate() from the UI thread.
|
// Called by Print::validate() from the UI thread.
|
||||||
void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
|
void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,6 +120,7 @@ public:
|
||||||
void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
|
void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
|
||||||
void translate(coordf_t x, coordf_t y, coordf_t z);
|
void translate(coordf_t x, coordf_t y, coordf_t z);
|
||||||
void scale(const Vec3d &versor);
|
void scale(const Vec3d &versor);
|
||||||
|
void scale(const double s) { this->scale(Vec3d(s, s, s)); }
|
||||||
void rotate(float angle, const Axis &axis);
|
void rotate(float angle, const Axis &axis);
|
||||||
void rotate(float angle, const Vec3d& axis);
|
void rotate(float angle, const Vec3d& axis);
|
||||||
void mirror(const Axis &axis);
|
void mirror(const Axis &axis);
|
||||||
|
@ -128,6 +129,7 @@ public:
|
||||||
bool needed_repair() const;
|
bool needed_repair() const;
|
||||||
void cut(coordf_t z, Model* model) const;
|
void cut(coordf_t z, Model* model) const;
|
||||||
void split(ModelObjectPtrs* new_objects);
|
void split(ModelObjectPtrs* new_objects);
|
||||||
|
void repair();
|
||||||
|
|
||||||
// Called by Print::validate() from the UI thread.
|
// Called by Print::validate() from the UI thread.
|
||||||
void check_instances_print_volume_state(const BoundingBoxf3& print_volume);
|
void check_instances_print_volume_state(const BoundingBoxf3& print_volume);
|
||||||
|
@ -190,11 +192,11 @@ public:
|
||||||
// Split this volume, append the result to the object owning this volume.
|
// Split this volume, append the result to the object owning this volume.
|
||||||
// Return the number of volumes created from this one.
|
// Return the number of volumes created from this one.
|
||||||
// This is useful to assign different materials to different volumes of an object.
|
// This is useful to assign different materials to different volumes of an object.
|
||||||
size_t split(unsigned int max_extruders);
|
size_t split(unsigned int max_extruders);
|
||||||
|
|
||||||
ModelMaterial* assign_unique_material();
|
ModelMaterial* assign_unique_material();
|
||||||
|
|
||||||
void calculate_convex_hull();
|
void calculate_convex_hull();
|
||||||
const TriangleMesh& get_convex_hull() const;
|
const TriangleMesh& get_convex_hull() const;
|
||||||
|
|
||||||
// Helpers for loading / storing into AMF / 3MF files.
|
// Helpers for loading / storing into AMF / 3MF files.
|
||||||
|
@ -325,6 +327,10 @@ public:
|
||||||
static Model read_from_file(const std::string &input_file, bool add_default_instances = true);
|
static Model read_from_file(const std::string &input_file, bool add_default_instances = true);
|
||||||
static Model read_from_archive(const std::string &input_file, PresetBundle* bundle, bool add_default_instances = true);
|
static Model read_from_archive(const std::string &input_file, PresetBundle* bundle, bool add_default_instances = true);
|
||||||
|
|
||||||
|
/// Repair the ModelObjects of the current Model.
|
||||||
|
/// This function calls repair function on each TriangleMesh of each model object volume
|
||||||
|
void repair();
|
||||||
|
|
||||||
ModelObject* add_object();
|
ModelObject* add_object();
|
||||||
ModelObject* add_object(const char *name, const char *path, const TriangleMesh &mesh);
|
ModelObject* add_object(const char *name, const char *path, const TriangleMesh &mesh);
|
||||||
ModelObject* add_object(const char *name, const char *path, TriangleMesh &&mesh);
|
ModelObject* add_object(const char *name, const char *path, TriangleMesh &&mesh);
|
||||||
|
|
|
@ -2345,7 +2345,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintConfigDef print_config_def;
|
const PrintConfigDef print_config_def;
|
||||||
|
|
||||||
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults()
|
DynamicPrintConfig* DynamicPrintConfig::new_from_defaults()
|
||||||
{
|
{
|
||||||
|
@ -2601,4 +2601,135 @@ StaticPrintConfig::StaticCache<class Slic3r::SLAMaterialConfig> SLAMaterialConf
|
||||||
StaticPrintConfig::StaticCache<class Slic3r::SLAPrinterConfig> SLAPrinterConfig::s_cache_SLAPrinterConfig;
|
StaticPrintConfig::StaticCache<class Slic3r::SLAPrinterConfig> SLAPrinterConfig::s_cache_SLAPrinterConfig;
|
||||||
StaticPrintConfig::StaticCache<class Slic3r::SLAFullPrintConfig> SLAFullPrintConfig::s_cache_SLAFullPrintConfig;
|
StaticPrintConfig::StaticCache<class Slic3r::SLAFullPrintConfig> SLAFullPrintConfig::s_cache_SLAFullPrintConfig;
|
||||||
|
|
||||||
|
|
||||||
|
CLIConfigDef::CLIConfigDef()
|
||||||
|
{
|
||||||
|
ConfigOptionDef *def;
|
||||||
|
|
||||||
|
def = this->add("cut", coFloat);
|
||||||
|
def->label = L("Cut");
|
||||||
|
def->tooltip = L("Cut model at the given Z.");
|
||||||
|
def->cli = "cut";
|
||||||
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
|
def = this->add("export_3mf", coBool);
|
||||||
|
def->label = L("Export 3MF");
|
||||||
|
def->tooltip = L("Slice the model and export slices as 3MF.");
|
||||||
|
def->cli = "export-3mf";
|
||||||
|
def->default_value = new ConfigOptionBool(false);
|
||||||
|
|
||||||
|
def = this->add("slice", coBool);
|
||||||
|
def->label = L("Slice");
|
||||||
|
def->tooltip = L("Slice the model and export gcode.");
|
||||||
|
def->cli = "slice";
|
||||||
|
def->default_value = new ConfigOptionBool(false);
|
||||||
|
|
||||||
|
def = this->add("help", coBool);
|
||||||
|
def->label = L("Help");
|
||||||
|
def->tooltip = L("Show this help.");
|
||||||
|
def->cli = "help";
|
||||||
|
def->default_value = new ConfigOptionBool(false);
|
||||||
|
|
||||||
|
def = this->add("gui", coBool);
|
||||||
|
def->label = L("Use GUI");
|
||||||
|
def->tooltip = L("Start the Slic3r GUI.");
|
||||||
|
def->cli = "gui";
|
||||||
|
def->default_value = new ConfigOptionBool(false);
|
||||||
|
|
||||||
|
def = this->add("info", coBool);
|
||||||
|
def->label = L("Output Model Info");
|
||||||
|
def->tooltip = L("Write information about the model to the console.");
|
||||||
|
def->cli = "info";
|
||||||
|
def->default_value = new ConfigOptionBool(false);
|
||||||
|
|
||||||
|
def = this->add("load", coStrings);
|
||||||
|
def->label = L("Load config file");
|
||||||
|
def->tooltip = L("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 = L("Output File");
|
||||||
|
def->tooltip = L("The file where the output will be written (if not specified, it will be based on the input file).");
|
||||||
|
def->cli = "output";
|
||||||
|
def->default_value = new ConfigOptionString("");
|
||||||
|
|
||||||
|
def = this->add("rotate", coFloat);
|
||||||
|
def->label = L("Rotate");
|
||||||
|
def->tooltip = L("Rotation angle around the Z axis in degrees (0-360, default: 0).");
|
||||||
|
def->cli = "rotate";
|
||||||
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
|
def = this->add("rotate_x", coFloat);
|
||||||
|
def->label = L("Rotate around X");
|
||||||
|
def->tooltip = L("Rotation angle around the X axis in degrees (0-360, default: 0).");
|
||||||
|
def->cli = "rotate-x";
|
||||||
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
|
def = this->add("rotate_y", coFloat);
|
||||||
|
def->label = L("Rotate around Y");
|
||||||
|
def->tooltip = L("Rotation angle around the Y axis in degrees (0-360, default: 0).");
|
||||||
|
def->cli = "rotate-y";
|
||||||
|
def->default_value = new ConfigOptionFloat(0);
|
||||||
|
|
||||||
|
def = this->add("save", coString);
|
||||||
|
def->label = L("Save config file");
|
||||||
|
def->tooltip = L("Save configuration to the specified file.");
|
||||||
|
def->cli = "save";
|
||||||
|
def->default_value = new ConfigOptionString();
|
||||||
|
|
||||||
|
def = this->add("scale", coFloat);
|
||||||
|
def->label = L("Scale");
|
||||||
|
def->tooltip = L("Scaling factor (default: 1).");
|
||||||
|
def->cli = "scale";
|
||||||
|
def->default_value = new ConfigOptionFloat(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
def = this->add("scale_to_fit", coPoint3);
|
||||||
|
def->label = L("Scale to Fit");
|
||||||
|
def->tooltip = L("Scale to fit the given volume.");
|
||||||
|
def->cli = "scale-to-fit";
|
||||||
|
def->default_value = new ConfigOptionPoint3(Pointf3(0,0,0));
|
||||||
|
*/
|
||||||
|
|
||||||
|
def = this->add("center", coPoint);
|
||||||
|
def->label = L("Center");
|
||||||
|
def->tooltip = L("Center the print around the given center (default: 100, 100).");
|
||||||
|
def->cli = "center";
|
||||||
|
def->default_value = new ConfigOptionPoint(Vec2d(100,100));
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLIConfigDef cli_config_def;
|
||||||
|
DynamicPrintAndCLIConfig::PrintAndCLIConfigDef DynamicPrintAndCLIConfig::s_def;
|
||||||
|
|
||||||
|
std::ostream& print_cli_options(std::ostream& out)
|
||||||
|
{
|
||||||
|
for (const auto& opt : cli_config_def.options) {
|
||||||
|
if (opt.second.cli.size() != 0) {
|
||||||
|
out << "\t" << std::left << std::setw(40) << std::string("--") + opt.second.cli;
|
||||||
|
out << "\t" << opt.second.tooltip << "\n";
|
||||||
|
if (opt.second.default_value != nullptr)
|
||||||
|
out << "\t" << std::setw(40) << " " << "\t" << " (default: " << opt.second.default_value->serialize() << ")";
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& print_print_options(std::ostream& out)
|
||||||
|
{
|
||||||
|
for (const auto& opt : print_config_def.options) {
|
||||||
|
if (opt.second.cli.size() != 0) {
|
||||||
|
out << "\t" << std::left << std::setw(40) << std::string("--") + opt.second.cli;
|
||||||
|
out << "\t" << opt.second.tooltip << "\n";
|
||||||
|
if (opt.second.default_value != nullptr)
|
||||||
|
out << "\t" << std::setw(40) << " " << "\t" << " (default: " << opt.second.default_value->serialize() << ")";
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ private:
|
||||||
|
|
||||||
// The one and only global definition of SLic3r configuration options.
|
// The one and only global definition of SLic3r configuration options.
|
||||||
// This definition is constant.
|
// This definition is constant.
|
||||||
extern PrintConfigDef print_config_def;
|
extern const PrintConfigDef print_config_def;
|
||||||
|
|
||||||
// Slic3r dynamic configuration, used to override the configuration
|
// Slic3r dynamic configuration, used to override the configuration
|
||||||
// per object, per modification volume or per printing material.
|
// per object, per modification volume or per printing material.
|
||||||
|
@ -968,6 +968,88 @@ protected:
|
||||||
#undef STATIC_PRINT_CONFIG_CACHE_DERIVED
|
#undef STATIC_PRINT_CONFIG_CACHE_DERIVED
|
||||||
#undef OPT_PTR
|
#undef OPT_PTR
|
||||||
|
|
||||||
}
|
class CLIConfigDef : public ConfigDef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CLIConfigDef();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const CLIConfigDef cli_config_def;
|
||||||
|
|
||||||
|
#define OPT_PTR(KEY) if (opt_key == #KEY) return &this->KEY
|
||||||
|
|
||||||
|
class CLIConfig : public virtual ConfigBase, public StaticConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfigOptionFloat cut;
|
||||||
|
ConfigOptionBool export_3mf;
|
||||||
|
ConfigOptionBool gui;
|
||||||
|
ConfigOptionBool info;
|
||||||
|
ConfigOptionBool help;
|
||||||
|
ConfigOptionStrings load;
|
||||||
|
ConfigOptionString output;
|
||||||
|
ConfigOptionFloat rotate;
|
||||||
|
ConfigOptionFloat rotate_x;
|
||||||
|
ConfigOptionFloat rotate_y;
|
||||||
|
ConfigOptionString save;
|
||||||
|
ConfigOptionFloat scale;
|
||||||
|
// ConfigOptionPoint3 scale_to_fit;
|
||||||
|
ConfigOptionPoint center;
|
||||||
|
ConfigOptionBool slice;
|
||||||
|
|
||||||
|
CLIConfig() : ConfigBase(), StaticConfig()
|
||||||
|
{
|
||||||
|
this->set_defaults();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
|
||||||
|
const ConfigDef* def() const override { return &cli_config_def; }
|
||||||
|
|
||||||
|
ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) override
|
||||||
|
{
|
||||||
|
OPT_PTR(cut);
|
||||||
|
OPT_PTR(export_3mf);
|
||||||
|
OPT_PTR(gui);
|
||||||
|
OPT_PTR(help);
|
||||||
|
OPT_PTR(info);
|
||||||
|
OPT_PTR(load);
|
||||||
|
OPT_PTR(output);
|
||||||
|
OPT_PTR(rotate);
|
||||||
|
OPT_PTR(rotate_x);
|
||||||
|
OPT_PTR(rotate_y);
|
||||||
|
OPT_PTR(save);
|
||||||
|
OPT_PTR(scale);
|
||||||
|
// OPT_PTR(scale_to_fit);
|
||||||
|
OPT_PTR(slice);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef OPT_PTR
|
||||||
|
|
||||||
|
class DynamicPrintAndCLIConfig : public DynamicPrintConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DynamicPrintAndCLIConfig() { this->apply(FullPrintConfig::defaults()); this->apply(CLIConfig()); }
|
||||||
|
DynamicPrintAndCLIConfig(const DynamicPrintAndCLIConfig &other) : DynamicPrintConfig(other) {}
|
||||||
|
|
||||||
|
// Overrides ConfigBase::def(). Static configuration definition. Any value stored into this ConfigBase shall have its definition here.
|
||||||
|
const ConfigDef* def() const override { return &s_def; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
class PrintAndCLIConfigDef : public PrintConfigDef
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrintAndCLIConfigDef() { this->options.insert(cli_config_def.options.begin(), cli_config_def.options.end()); }
|
||||||
|
};
|
||||||
|
static PrintAndCLIConfigDef s_def;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Iterate through all of the print options and write them to a stream.
|
||||||
|
std::ostream& print_print_options(std::ostream& out);
|
||||||
|
/// Iterate through all of the CLI options and write them to a stream.
|
||||||
|
std::ostream& print_cli_options(std::ostream& out);
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1591,7 +1591,7 @@ std::vector<ExPolygons> PrintObject::slice_support_enforcers() const
|
||||||
std::vector<float> zs;
|
std::vector<float> zs;
|
||||||
zs.reserve(this->layers().size());
|
zs.reserve(this->layers().size());
|
||||||
for (const Layer *l : this->layers())
|
for (const Layer *l : this->layers())
|
||||||
zs.emplace_back(l->slice_z);
|
zs.emplace_back((float)l->slice_z);
|
||||||
return this->_slice_volumes(zs, volumes);
|
return this->_slice_volumes(zs, volumes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1604,7 +1604,7 @@ std::vector<ExPolygons> PrintObject::slice_support_blockers() const
|
||||||
std::vector<float> zs;
|
std::vector<float> zs;
|
||||||
zs.reserve(this->layers().size());
|
zs.reserve(this->layers().size());
|
||||||
for (const Layer *l : this->layers())
|
for (const Layer *l : this->layers())
|
||||||
zs.emplace_back(l->slice_z);
|
zs.emplace_back((float)l->slice_z);
|
||||||
return this->_slice_volumes(zs, volumes);
|
return this->_slice_volumes(zs, volumes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
186
src/slic3r.cpp
186
src/slic3r.cpp
|
@ -1,7 +1,12 @@
|
||||||
|
//#include "ConfigBase.hpp"
|
||||||
#include "Config.hpp"
|
#include "Config.hpp"
|
||||||
#include "Geometry.hpp"
|
#include "Geometry.hpp"
|
||||||
|
//#include "IO.hpp"
|
||||||
#include "Model.hpp"
|
#include "Model.hpp"
|
||||||
|
//#include "SLAPrint.hpp"
|
||||||
|
#include "Print.hpp"
|
||||||
#include "TriangleMesh.hpp"
|
#include "TriangleMesh.hpp"
|
||||||
|
#include "Format/3mf.hpp"
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -12,6 +17,9 @@
|
||||||
#include <boost/nowide/args.hpp>
|
#include <boost/nowide/args.hpp>
|
||||||
#include <boost/nowide/iostream.hpp>
|
#include <boost/nowide/iostream.hpp>
|
||||||
|
|
||||||
|
#ifdef USE_WX
|
||||||
|
// #include "GUI/GUI.hpp"
|
||||||
|
#endif
|
||||||
#include "slic3r/GUI/GUI.hpp"
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
|
@ -87,37 +95,55 @@ void MyFrame::OnHello(wxCommandEvent& event)
|
||||||
wxLogMessage("Hello world from wxWidgets!");
|
wxLogMessage("Hello world from wxWidgets!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// utility function for displaying CLI usage
|
||||||
|
void printUsage();
|
||||||
|
|
||||||
#if 1
|
using namespace Slic3r;
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Convert arguments to UTF-8 (needed on Windows).
|
// Convert arguments to UTF-8 (needed on Windows). argv then points to memory owned by a.
|
||||||
// argv then points to memory owned by a.
|
|
||||||
boost::nowide::args a(argc, argv);
|
boost::nowide::args a(argc, argv);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// parse all command line options into a DynamicConfig
|
// parse all command line options into a DynamicConfig
|
||||||
ConfigDef config_def;
|
DynamicPrintAndCLIConfig config;
|
||||||
config_def.merge(cli_config_def);
|
|
||||||
config_def.merge(print_config_def);
|
|
||||||
DynamicConfig config(&config_def);
|
|
||||||
t_config_option_keys input_files;
|
t_config_option_keys input_files;
|
||||||
config.read_cli(argc, argv, &input_files);
|
// if any option is unsupported, print usage and abort immediately
|
||||||
|
if (! config.read_cli(argc, argv, &input_files)) {
|
||||||
|
printUsage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// apply command line options to a more handy CLIConfig
|
// apply command line options to a more handy CLIConfig
|
||||||
CLIConfig cli_config;
|
CLIConfig cli_config;
|
||||||
cli_config.apply(config, true);
|
cli_config.apply(config, true);
|
||||||
|
|
||||||
DynamicPrintConfig print_config;
|
DynamicPrintConfig print_config;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
MyApp *gui = new MyApp();
|
||||||
|
|
||||||
|
MyApp::SetInstance(gui);
|
||||||
|
wxEntry(argc, argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WX
|
||||||
|
if (cli_config.gui) {
|
||||||
|
GUI::App *gui = new GUI::App();
|
||||||
|
GUI::App::SetInstance(gui);
|
||||||
|
wxEntry(argc, argv);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (cli_config.gui) {
|
||||||
|
std::cout << "GUI support has not been built." << "\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// load config files supplied via --load
|
// load config files supplied via --load
|
||||||
for (const std::string &file : cli_config.load.values) {
|
for (const std::string &file : cli_config.load.values) {
|
||||||
if (!boost::filesystem::exists(file)) {
|
if (!boost::filesystem::exists(file)) {
|
||||||
boost::nowide::cout << "No such file: " << file << std::endl;
|
boost::nowide::cout << "No such file: " << file << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicPrintConfig c;
|
DynamicPrintConfig c;
|
||||||
try {
|
try {
|
||||||
c.load(file);
|
c.load(file);
|
||||||
|
@ -135,12 +161,13 @@ main(int argc, char **argv)
|
||||||
print_config.normalize();
|
print_config.normalize();
|
||||||
|
|
||||||
// write config if requested
|
// write config if requested
|
||||||
if (!cli_config.save.value.empty()) print_config.save(cli_config.save.value);
|
if (! cli_config.save.value.empty())
|
||||||
|
print_config.save(cli_config.save.value);
|
||||||
|
|
||||||
// read input file(s) if any
|
// read input file(s) if any
|
||||||
std::vector<Model> models;
|
std::vector<Model> models;
|
||||||
for (const t_config_option_key &file : input_files) {
|
for (const t_config_option_key &file : input_files) {
|
||||||
if (!boost::filesystem::exists(file)) {
|
if (! boost::filesystem::exists(file)) {
|
||||||
boost::nowide::cerr << "No such file: " << file << std::endl;
|
boost::nowide::cerr << "No such file: " << file << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -162,9 +189,10 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
// apply command line transform options
|
// apply command line transform options
|
||||||
for (ModelObject* o : model.objects) {
|
for (ModelObject* o : model.objects) {
|
||||||
|
/*
|
||||||
if (cli_config.scale_to_fit.is_positive_volume())
|
if (cli_config.scale_to_fit.is_positive_volume())
|
||||||
o->scale_to_fit(cli_config.scale_to_fit.value);
|
o->scale_to_fit(cli_config.scale_to_fit.value);
|
||||||
|
*/
|
||||||
// TODO: honor option order?
|
// TODO: honor option order?
|
||||||
o->scale(cli_config.scale.value);
|
o->scale(cli_config.scale.value);
|
||||||
o->rotate(Geometry::deg2rad(cli_config.rotate_x.value), X);
|
o->rotate(Geometry::deg2rad(cli_config.rotate_x.value), X);
|
||||||
|
@ -175,87 +203,79 @@ main(int argc, char **argv)
|
||||||
// TODO: handle --merge
|
// TODO: handle --merge
|
||||||
models.push_back(model);
|
models.push_back(model);
|
||||||
}
|
}
|
||||||
|
if (cli_config.help) {
|
||||||
|
printUsage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (Model &model : models) {
|
for (Model &model : models) {
|
||||||
if (cli_config.info) {
|
if (cli_config.info) {
|
||||||
// --info works on unrepaired model
|
// --info works on unrepaired model
|
||||||
model.print_info();
|
model.print_info();
|
||||||
} else if (cli_config.export_obj) {
|
} else if (cli_config.export_3mf) {
|
||||||
std::string outfile = cli_config.output.value;
|
std::string outfile = cli_config.output.value;
|
||||||
if (outfile.empty()) outfile = model.objects.front()->input_file + ".obj";
|
if (outfile.empty()) outfile = model.objects.front()->input_file;
|
||||||
|
// Check if the file is already a 3mf.
|
||||||
TriangleMesh mesh = model.mesh();
|
if(outfile.substr(outfile.find_last_of('.'), outfile.length()) == ".3mf")
|
||||||
mesh.repair();
|
outfile = outfile.substr(0, outfile.find_last_of('.')) + "_2" + ".3mf";
|
||||||
IO::OBJ::write(mesh, outfile);
|
else
|
||||||
boost::nowide::cout << "File exported to " << outfile << std::endl;
|
// Remove the previous extension and add .3mf extention.
|
||||||
} else if (cli_config.export_pov) {
|
outfile = outfile.substr(0, outfile.find_last_of('.')) + ".3mf";
|
||||||
std::string outfile = cli_config.output.value;
|
store_3mf(outfile.c_str(), &model, nullptr, false);
|
||||||
if (outfile.empty()) outfile = model.objects.front()->input_file + ".pov";
|
boost::nowide::cout << "File file exported to " << outfile << std::endl;
|
||||||
|
} else if (cli_config.cut > 0) {
|
||||||
TriangleMesh mesh = model.mesh();
|
|
||||||
mesh.repair();
|
|
||||||
IO::POV::write(mesh, outfile);
|
|
||||||
boost::nowide::cout << "File exported to " << outfile << std::endl;
|
|
||||||
} else if (cli_config.export_svg) {
|
|
||||||
std::string outfile = cli_config.output.value;
|
|
||||||
if (outfile.empty()) outfile = model.objects.front()->input_file + ".svg";
|
|
||||||
|
|
||||||
SLAPrint print(&model);
|
|
||||||
print.config.apply(print_config, true);
|
|
||||||
print.slice();
|
|
||||||
print.write_svg(outfile);
|
|
||||||
boost::nowide::cout << "SVG file exported to " << outfile << std::endl;
|
|
||||||
} else if (cli_config.cut_x > 0 || cli_config.cut_y > 0 || cli_config.cut > 0) {
|
|
||||||
model.repair();
|
model.repair();
|
||||||
model.translate(0, 0, -model.bounding_box().min.z);
|
model.translate(0, 0, - model.bounding_box().min(2));
|
||||||
|
if (! model.objects.empty()) {
|
||||||
if (!model.objects.empty()) {
|
|
||||||
// FIXME: cut all objects
|
|
||||||
Model out;
|
Model out;
|
||||||
if (cli_config.cut_x > 0) {
|
model.objects.front()->cut(cli_config.cut, &out);
|
||||||
model.objects.front()->cut(X, cli_config.cut_x, &out);
|
|
||||||
} else if (cli_config.cut_y > 0) {
|
|
||||||
model.objects.front()->cut(Y, cli_config.cut_y, &out);
|
|
||||||
} else {
|
|
||||||
model.objects.front()->cut(Z, cli_config.cut, &out);
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelObject &upper = *out.objects[0];
|
ModelObject &upper = *out.objects[0];
|
||||||
ModelObject &lower = *out.objects[1];
|
ModelObject &lower = *out.objects[1];
|
||||||
|
// Use the input name and trim off the extension.
|
||||||
if (upper.facets_count() > 0) {
|
std::string outfile = cli_config.output.value;
|
||||||
TriangleMesh m = upper.mesh();
|
if (outfile.empty())
|
||||||
IO::STL::write(m, upper.input_file + "_upper.stl");
|
outfile = model.objects.front()->input_file;
|
||||||
}
|
outfile = outfile.substr(0, outfile.find_last_of('.'));
|
||||||
if (lower.facets_count() > 0) {
|
std::cerr << outfile << "\n";
|
||||||
TriangleMesh m = lower.mesh();
|
if (upper.facets_count() > 0)
|
||||||
IO::STL::write(m, lower.input_file + "_lower.stl");
|
upper.mesh().write_binary((outfile + "_upper.stl").c_str());
|
||||||
}
|
if (lower.facets_count() > 0)
|
||||||
|
lower.mesh().write_binary((outfile + "_lower.stl").c_str());
|
||||||
}
|
}
|
||||||
} else if (cli_config.cut_grid.value.x > 0 && cli_config.cut_grid.value.y > 0) {
|
} else if (cli_config.slice) {
|
||||||
TriangleMesh mesh = model.mesh();
|
std::string outfile = cli_config.output.value;
|
||||||
mesh.repair();
|
Print print;
|
||||||
|
model.arrange_objects(print.config().min_object_distance());
|
||||||
TriangleMeshPtrs meshes = mesh.cut_by_grid(cli_config.cut_grid.value);
|
model.center_instances_around_point(cli_config.center);
|
||||||
size_t i = 0;
|
if (outfile.empty()) outfile = model.objects.front()->input_file + ".gcode";
|
||||||
for (TriangleMesh* m : meshes) {
|
print.apply_config(print_config);
|
||||||
std::ostringstream ss;
|
for (auto* mo : model.objects) {
|
||||||
ss << model.objects.front()->input_file << "_" << i++ << ".stl";
|
print.auto_assign_extruders(mo);
|
||||||
IO::STL::write(*m, ss.str());
|
print.add_model_object(mo);
|
||||||
delete m;
|
|
||||||
}
|
}
|
||||||
|
print.validate();
|
||||||
|
print.export_gcode(outfile, nullptr);
|
||||||
} else {
|
} else {
|
||||||
boost::nowide::cerr << "error: command not supported" << std::endl;
|
boost::nowide::cerr << "error: command not supported" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
MyApp *gui = new MyApp();
|
|
||||||
|
|
||||||
MyApp::SetInstance(gui);
|
|
||||||
wxEntry(argc, argv);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
void printUsage()
|
||||||
|
{
|
||||||
|
std::cout << "Slic3r " << SLIC3R_VERSION << " is a STL-to-GCODE translator for RepRap 3D printers" << "\n"
|
||||||
|
<< "written by Alessandro Ranellucci <aar@cpan.org> - http://slic3r.org/ - https://github.com/slic3r/Slic3r" << "\n"
|
||||||
|
// << "Git Version " << BUILD_COMMIT << "\n\n"
|
||||||
|
<< "Usage: ./slic3r [ OPTIONS ] [ file.stl ] [ file2.stl ] ..." << "\n";
|
||||||
|
// CLI Options
|
||||||
|
std::cout << "** CLI OPTIONS **\n";
|
||||||
|
print_cli_options(boost::nowide::cout);
|
||||||
|
std::cout << "****\n";
|
||||||
|
// Print options
|
||||||
|
std::cout << "** PRINT OPTIONS **\n";
|
||||||
|
print_print_options(boost::nowide::cout);
|
||||||
|
std::cout << "****\n";
|
||||||
|
}
|
||||||
|
|
|
@ -380,7 +380,7 @@ void PageVendors::on_variant_checked()
|
||||||
|
|
||||||
PageFirmware::PageFirmware(ConfigWizard *parent) :
|
PageFirmware::PageFirmware(ConfigWizard *parent) :
|
||||||
ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware"))),
|
ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware"))),
|
||||||
gcode_opt(print_config_def.options["gcode_flavor"]),
|
gcode_opt(*print_config_def.get("gcode_flavor")),
|
||||||
gcode_picker(nullptr)
|
gcode_picker(nullptr)
|
||||||
{
|
{
|
||||||
append_text(_(L("Choose the type of firmware used by your printer.")));
|
append_text(_(L("Choose the type of firmware used by your printer.")));
|
||||||
|
@ -440,13 +440,13 @@ PageDiameters::PageDiameters(ConfigWizard *parent) :
|
||||||
{
|
{
|
||||||
spin_nozzle->SetDigits(2);
|
spin_nozzle->SetDigits(2);
|
||||||
spin_nozzle->SetIncrement(0.1);
|
spin_nozzle->SetIncrement(0.1);
|
||||||
const auto &def_nozzle = print_config_def.options["nozzle_diameter"];
|
const auto &def_nozzle = *print_config_def.get("nozzle_diameter");
|
||||||
auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value);
|
auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value);
|
||||||
spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
|
spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
|
||||||
|
|
||||||
spin_filam->SetDigits(2);
|
spin_filam->SetDigits(2);
|
||||||
spin_filam->SetIncrement(0.25);
|
spin_filam->SetIncrement(0.25);
|
||||||
const auto &def_filam = print_config_def.options["filament_diameter"];
|
const auto &def_filam = *print_config_def.get("filament_diameter");
|
||||||
auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value);
|
auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value);
|
||||||
spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
|
spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
|
||||||
|
|
||||||
|
@ -490,13 +490,13 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) :
|
||||||
spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
|
spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
|
||||||
{
|
{
|
||||||
spin_extr->SetIncrement(5.0);
|
spin_extr->SetIncrement(5.0);
|
||||||
const auto &def_extr = print_config_def.options["temperature"];
|
const auto &def_extr = *print_config_def.get("temperature");
|
||||||
spin_extr->SetRange(def_extr.min, def_extr.max);
|
spin_extr->SetRange(def_extr.min, def_extr.max);
|
||||||
auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value);
|
auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value);
|
||||||
spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200);
|
spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200);
|
||||||
|
|
||||||
spin_bed->SetIncrement(5.0);
|
spin_bed->SetIncrement(5.0);
|
||||||
const auto &def_bed = print_config_def.options["bed_temperature"];
|
const auto &def_bed = *print_config_def.get("bed_temperature");
|
||||||
spin_bed->SetRange(def_bed.min, def_bed.max);
|
spin_bed->SetRange(def_bed.min, def_bed.max);
|
||||||
auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value);
|
auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value);
|
||||||
spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
|
spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
|
||||||
|
|
|
@ -137,7 +137,7 @@ PROTOTYPES: DISABLE
|
||||||
SV*
|
SV*
|
||||||
print_config_def()
|
print_config_def()
|
||||||
CODE:
|
CODE:
|
||||||
t_optiondef_map &def = Slic3r::print_config_def.options;
|
t_optiondef_map &def = *const_cast<t_optiondef_map*>(&Slic3r::print_config_def.options);
|
||||||
|
|
||||||
HV* options_hv = newHV();
|
HV* options_hv = newHV();
|
||||||
for (t_optiondef_map::iterator oit = def.begin(); oit != def.end(); ++oit) {
|
for (t_optiondef_map::iterator oit = def.begin(); oit != def.end(); ++oit) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue