diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index e8ed43356..281591596 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -812,6 +812,14 @@ public: bool operator==(const ConfigOptionEnum &rhs) const { return this->value == rhs.value; } int getInt() const override { return (int)this->value; } + bool operator==(const ConfigOption &rhs) const override + { + if (rhs.type() != this->type()) + throw std::runtime_error("ConfigOptionEnum: Comparing incompatible types"); + // rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum + return this->value == (T)rhs.getInt(); + } + void set(const ConfigOption *rhs) override { if (rhs->type() != this->type()) throw std::runtime_error("ConfigOptionEnum: Assigning an incompatible type"); @@ -887,6 +895,14 @@ public: ConfigOptionEnumGeneric& operator=(const ConfigOption *opt) { this->set(opt); return *this; } bool operator==(const ConfigOptionEnumGeneric &rhs) const { return this->value == rhs.value; } + bool operator==(const ConfigOption &rhs) const override + { + if (rhs.type() != this->type()) + throw std::runtime_error("ConfigOptionEnumGeneric: Comparing incompatible types"); + // rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum + return this->value == rhs.getInt(); + } + void set(const ConfigOption *rhs) override { if (rhs->type() != this->type()) throw std::runtime_error("ConfigOptionEnumGeneric: Assigning an incompatible type"); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 4ed37a153..05b1b4bb5 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2612,6 +2612,13 @@ CLIConfigDef::CLIConfigDef() def->cli = "cut"; def->default_value = new ConfigOptionFloat(0); + def = this->add("dont_arrange", coBool); + def->label = L("Dont arrange"); + def->tooltip = L("Don't arrange the objects on the build plate. The model coordinates " + "define the absolute positions on the build plate. " + "The option --center will be ignored."); + def->default_value = new ConfigOptionBool(false); + def = this->add("datadir", coString); def->label = L("User data directory"); def->tooltip = L("Load and store settings at the given directory. " @@ -2707,10 +2714,10 @@ CLIConfigDef::CLIConfigDef() def->default_value = new ConfigOptionPoint3(Pointf3(0,0,0)); */ - def = this->add("center", coPoint); - def->label = L("Center"); + def = this->add("print_center", coPoint); + def->label = L("Print center"); def->tooltip = L("Center the print around the given center (default: 100, 100)."); - def->cli = "center"; + def->cli = "print-center"; def->default_value = new ConfigOptionPoint(Vec2d(100,100)); } diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index dec528d58..c03ed2572 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -983,6 +983,7 @@ class CLIConfig : public virtual ConfigBase, public StaticConfig public: ConfigOptionFloat cut; ConfigOptionString datadir; + ConfigOptionBool dont_arrange; ConfigOptionBool export_3mf; ConfigOptionBool gui; ConfigOptionBool info; @@ -990,13 +991,13 @@ public: ConfigOptionStrings load; ConfigOptionBool no_gui; ConfigOptionString output; + ConfigOptionPoint print_center; ConfigOptionFloat rotate; ConfigOptionFloat rotate_x; ConfigOptionFloat rotate_y; ConfigOptionString save; ConfigOptionFloat scale; // ConfigOptionPoint3 scale_to_fit; - ConfigOptionPoint center; ConfigOptionBool slice; CLIConfig() : ConfigBase(), StaticConfig() @@ -1011,6 +1012,7 @@ public: { OPT_PTR(cut); OPT_PTR(datadir); + OPT_PTR(dont_arrange); OPT_PTR(export_3mf); OPT_PTR(gui); OPT_PTR(help); @@ -1018,6 +1020,7 @@ public: OPT_PTR(load); OPT_PTR(no_gui); OPT_PTR(output); + OPT_PTR(print_center); OPT_PTR(rotate); OPT_PTR(rotate_x); OPT_PTR(rotate_y); diff --git a/src/slic3r.cpp b/src/slic3r.cpp index 29e1e28e9..a31c23f91 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -139,6 +139,11 @@ int main(int argc, char **argv) if (! cli_config.save.value.empty()) print_config.save(cli_config.save.value); + if (cli_config.help) { + printUsage(); + return 0; + } + // read input file(s) if any std::vector models; for (const t_config_option_key &file : input_files) { @@ -146,7 +151,6 @@ int main(int argc, char **argv) boost::nowide::cerr << "No such file: " << file << std::endl; exit(1); } - Model model; try { model = Model::read_from_file(file); @@ -154,14 +158,11 @@ int main(int argc, char **argv) boost::nowide::cerr << file << ": " << e.what() << std::endl; exit(1); } - if (model.objects.empty()) { boost::nowide::cerr << "Error: file is empty: " << file << std::endl; continue; } - - model.add_default_instances(); - + model.add_default_instances(); // apply command line transform options for (ModelObject* o : model.objects) { /* @@ -174,15 +175,10 @@ int main(int argc, char **argv) o->rotate(Geometry::deg2rad(cli_config.rotate_y.value), Y); o->rotate(Geometry::deg2rad(cli_config.rotate.value), Z); } - // TODO: handle --merge models.push_back(model); } - if (cli_config.help) { - printUsage(); - return 0; - } - + for (Model &model : models) { if (cli_config.info) { // --info works on unrepaired model @@ -220,16 +216,22 @@ int main(int argc, char **argv) } else if (cli_config.slice) { std::string outfile = cli_config.output.value; Print print; - model.arrange_objects(print.config().min_object_distance()); - model.center_instances_around_point(cli_config.center); - if (outfile.empty()) outfile = model.objects.front()->input_file + ".gcode"; - print.apply_config(print_config); + if (! cli_config.dont_arrange) { + model.arrange_objects(print.config().min_object_distance()); + model.center_instances_around_point(cli_config.print_center); + } + if (outfile.empty()) + outfile = model.objects.front()->input_file + ".gcode"; for (auto* mo : model.objects) { print.auto_assign_extruders(mo); print.add_model_object(mo); } - print.validate(); - print.export_gcode(outfile, nullptr); + print.apply_config(print_config); + std::string err = print.validate(); + if (err.empty()) + print.export_gcode(outfile, nullptr); + else + std::cerr << err << "\n"; } else { boost::nowide::cerr << "error: command not supported" << std::endl; return 1;