void PlaceholderParser::apply_config(const DynamicPrintConfig &config) { t_config_option_keys opt_keys = config.keys(); for (t_config_option_keys::const_iterator i = opt_keys.begin(); i != opt_keys.end(); ++i) { const t_config_option_key &opt_key = *i; const ConfigOptionDef* def = config.def->get(opt_key); if (def->multiline) continue; const ConfigOption* opt = config.option(opt_key); if (const ConfigOptionVectorBase* optv = dynamic_cast<const ConfigOptionVectorBase*>(opt)) { // set placeholders for options with multiple values // TODO: treat [bed_shape] as single, not multiple this->set(opt_key, optv->vserialize()); } else if (const ConfigOptionPoint* optp = dynamic_cast<const ConfigOptionPoint*>(opt)) { this->set(opt_key, optp->serialize()); Pointf val = *optp; this->set(opt_key + "_X", val.x); this->set(opt_key + "_Y", val.y); } else { // set single-value placeholders this->set(opt_key, opt->serialize()); } } }
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; } } }
boost::any ConfigOptionsGroup::get_config_value(DynamicPrintConfig& config, std::string opt_key, int opt_index/* = -1*/) { size_t idx = opt_index == -1 ? 0 : opt_index; boost::any ret; wxString text_value = wxString(""); const ConfigOptionDef* opt = config.def()->get(opt_key); switch (opt->type){ case coFloatOrPercent:{ const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key); if (value.percent) { text_value = wxString::Format(_T("%i"), int(value.value)); text_value += "%"; } else text_value = double_to_string(value.value); ret = text_value; break; } case coPercent:{ double val = config.option<ConfigOptionPercent>(opt_key)->value; text_value = wxString::Format(_T("%i"), int(val)); ret = text_value;// += "%"; } break; case coPercents: case coFloats: case coFloat:{ double val = opt->type == coFloats ? config.opt_float(opt_key, idx) : opt->type == coFloat ? config.opt_float(opt_key) : config.option<ConfigOptionPercents>(opt_key)->values.at(idx); ret = double_to_string(val); } break; case coString: ret = static_cast<wxString>(config.opt_string(opt_key)); break; case coStrings: if (config.option<ConfigOptionStrings>(opt_key)->values.empty()) ret = text_value; else ret = static_cast<wxString>(config.opt_string(opt_key, static_cast<unsigned int>(idx))); break; case coBool: ret = config.opt_bool(opt_key); break; case coBools: ret = config.opt_bool(opt_key, idx); break; case coInt: ret = config.opt_int(opt_key); break; case coInts: ret = config.opt_int(opt_key, idx); break; case coEnum:{ if (opt_key.compare("external_fill_pattern") == 0 || opt_key.compare("fill_pattern") == 0 ){ ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value); } else if (opt_key.compare("gcode_flavor") == 0 ){ ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value); } else if (opt_key.compare("support_material_pattern") == 0){ ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value); } else if (opt_key.compare("seam_position") == 0) ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value); } break; case coPoints:{ const auto &value = *config.option<ConfigOptionPoints>(opt_key); ret = value.values.at(idx); } break; case coNone: default: break; } return ret; }
int main(const int argc, const char **argv) { // parse all command line options into a DynamicConfig ConfigDef config_def; config_def.merge(cli_config_def); config_def.merge(print_config_def); DynamicConfig config(&config_def); t_config_option_keys input_files; config.read_cli(argc, argv, &input_files); // apply command line options to a more handy CLIConfig CLIConfig cli_config; cli_config.apply(config, true); 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) { if (!boost::filesystem::exists(*file)) { std::cout << "No such file: " << *file << std::endl; exit(1); } DynamicPrintConfig c; try { c.load(*file); } catch (std::exception &e) { std::cout << "Error while reading config file: " << e.what() << std::endl; exit(1); } 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; for (t_config_option_keys::const_iterator it = input_files.begin(); it != input_files.end(); ++it) { if (!boost::filesystem::exists(*it)) { std::cout << "No such file: " << *it << std::endl; exit(1); } Model model; // TODO: read other file formats with Model::read_from_file() try { Slic3r::IO::STL::read(*it, &model); } catch (std::exception &e) { std::cout << *it << ": " << e.what() << std::endl; exit(1); } if (model.objects.empty()) { printf("Error: file is empty: %s\n", it->c_str()); continue; } model.add_default_instances(); // apply command line transform options for (ModelObjectPtrs::iterator o = model.objects.begin(); o != model.objects.end(); ++o) { if (cli_config.scale_to_fit.is_positive_volume()) (*o)->scale_to_fit(cli_config.scale_to_fit.value); (*o)->scale(cli_config.scale.value); (*o)->rotate(cli_config.rotate.value, Z); } // TODO: handle --merge models.push_back(model); } for (std::vector<Model>::iterator model = models.begin(); model != models.end(); ++model) { if (cli_config.info) { // --info works on unrepaired model model->print_info(); } else if (cli_config.export_obj) { std::string outfile = cli_config.output.value; if (outfile.empty()) outfile = model->objects.front()->input_file + ".obj"; TriangleMesh mesh = model->mesh(); mesh.repair(); Slic3r::IO::OBJ::write(mesh, outfile); printf("File exported to %s\n", outfile.c_str()); } else if (cli_config.export_pov) { std::string outfile = cli_config.output.value; if (outfile.empty()) outfile = model->objects.front()->input_file + ".pov"; TriangleMesh mesh = model->mesh(); mesh.repair(); Slic3r::IO::POV::write(mesh, outfile); printf("File exported to %s\n", outfile.c_str()); } 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); printf("SVG file exported to %s\n", outfile.c_str()); } else { std::cerr << "error: only --export-svg and --export-obj are currently supported" << std::endl; return 1; } } return 0; }