diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index c4a0f300a..6ae84028e 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -2,7 +2,6 @@ #include "../Model.hpp" #include "../Utils.hpp" #include "../GCode.hpp" -#include "../slic3r/GUI/PresetBundle.hpp" #include "3mf.hpp" @@ -344,16 +343,16 @@ namespace Slic3r { _3MF_Importer(); ~_3MF_Importer(); - bool load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle); + bool load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config); private: void _destroy_xml_parser(); void _stop_xml_parser(); - bool _load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle); + bool _load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config); bool _extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); void _extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat); - void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename); + void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename); bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model); // handlers to parse the .model file @@ -447,7 +446,7 @@ namespace Slic3r { _destroy_xml_parser(); } - bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle) + bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config) { m_version = 0; m_model = &model; @@ -465,7 +464,7 @@ namespace Slic3r { m_curr_characters.clear(); clear_errors(); - return _load_model_from_file(filename, model, bundle); + return _load_model_from_file(filename, model, config); } void _3MF_Importer::_destroy_xml_parser() @@ -483,7 +482,7 @@ namespace Slic3r { XML_StopParser(m_xml_parser, false); } - bool _3MF_Importer::_load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle) + bool _3MF_Importer::_load_model_from_file(const std::string& filename, Model& model, DynamicPrintConfig& config) { mz_zip_archive archive; mz_zip_zero_struct(&archive); @@ -536,7 +535,7 @@ namespace Slic3r { else if (boost::algorithm::iequals(name, PRINT_CONFIG_FILE)) { // extract slic3r print config file - _extract_print_config_from_archive(archive, stat, bundle, filename); + _extract_print_config_from_archive(archive, stat, config, filename); } else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE)) { @@ -656,7 +655,7 @@ namespace Slic3r { return true; } - void _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename) + void _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig& config, const std::string& archive_filename) { if (stat.m_uncomp_size > 0) { @@ -667,8 +666,7 @@ namespace Slic3r { add_error("Error while reading config data to buffer"); return; } -//FIXME Get rid of the dependencies on slic3r GUI library! -// bundle.load_config_string(buffer.data(), archive_filename.c_str()); + config.load_from_gcode_string(buffer.data()); } } @@ -2004,13 +2002,13 @@ namespace Slic3r { return true; } - bool load_3mf(const char* path, PresetBundle* bundle, Model* model) + bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model) { - if ((path == nullptr) || (bundle == nullptr) || (model == nullptr)) + if ((path == nullptr) || (config == nullptr) || (model == nullptr)) return false; _3MF_Importer importer; - bool res = importer.load_model_from_file(path, *model, *bundle); + bool res = importer.load_model_from_file(path, *model, *config); importer.log_errors(); return res; } diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp index 85bc812e3..cfab1c600 100644 --- a/src/libslic3r/Format/3mf.hpp +++ b/src/libslic3r/Format/3mf.hpp @@ -5,10 +5,9 @@ namespace Slic3r { class Model; class Print; - class PresetBundle; // Load the content of a 3mf file into the given model and preset bundle. - extern bool load_3mf(const char* path, PresetBundle* bundle, Model* model); + extern bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model); // Save the given model and the config data contained in the given Print into a 3mf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index 3e0eb54de..f24146a59 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -8,8 +8,8 @@ #include "../libslic3r.h" #include "../Model.hpp" #include "../GCode.hpp" +#include "../PrintConfig.hpp" #include "../Utils.hpp" -#include "../slic3r/GUI/PresetBundle.hpp" #include "AMF.hpp" #include <boost/filesystem/operations.hpp> @@ -49,7 +49,7 @@ namespace Slic3r struct AMFParserContext { - AMFParserContext(XML_Parser parser, const std::string& archive_filename, PresetBundle* preset_bundle, Model *model) : + AMFParserContext(XML_Parser parser, DynamicPrintConfig *config, Model *model) : m_version(0), m_parser(parser), m_model(*model), @@ -57,8 +57,7 @@ struct AMFParserContext m_volume(nullptr), m_material(nullptr), m_instance(nullptr), - m_preset_bundle(preset_bundle), - m_archive_filename(archive_filename) + m_config(config) { m_path.reserve(12); } @@ -208,10 +207,8 @@ struct AMFParserContext Instance *m_instance; // Generic string buffer for vertices, face indices, metadata etc. std::string m_value[3]; - // Pointer to preset bundle to update if config data are stored inside the amf file - PresetBundle* m_preset_bundle; - // Fullpath name of the amf file - std::string m_archive_filename; + // Pointer to config to update if config data are stored inside the amf file + DynamicPrintConfig *m_config; private: AMFParserContext& operator=(AMFParserContext&); @@ -511,10 +508,8 @@ void AMFParserContext::endElement(const char * /* name */) break; case NODE_TYPE_METADATA: - if ((m_preset_bundle != nullptr) && strncmp(m_value[0].c_str(), SLIC3R_CONFIG_TYPE, strlen(SLIC3R_CONFIG_TYPE)) == 0) { -//FIXME Get rid of the dependencies on slic3r GUI library! -// m_preset_bundle->load_config_string(m_value[1].c_str(), m_archive_filename.c_str()); - } + if ((m_config != nullptr) && strncmp(m_value[0].c_str(), SLIC3R_CONFIG_TYPE, strlen(SLIC3R_CONFIG_TYPE)) == 0) + m_config->load_from_gcode_string(m_value[1].c_str()); else if (strncmp(m_value[0].c_str(), "slic3r.", 7) == 0) { const char *opt_key = m_value[0].c_str() + 7; if (print_config_def.options.find(opt_key) != print_config_def.options.end()) { @@ -603,7 +598,7 @@ void AMFParserContext::endDocument() } // Load an AMF file into a provided model. -bool load_amf_file(const char *path, PresetBundle* bundle, Model *model) +bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model) { if ((path == nullptr) || (model == nullptr)) return false; @@ -620,7 +615,7 @@ bool load_amf_file(const char *path, PresetBundle* bundle, Model *model) return false; } - AMFParserContext ctx(parser, path, bundle, model); + AMFParserContext ctx(parser, config, model); XML_SetUserData(parser, (void*)&ctx); XML_SetElementHandler(parser, AMFParserContext::startElement, AMFParserContext::endElement); XML_SetCharacterDataHandler(parser, AMFParserContext::characters); @@ -655,7 +650,7 @@ bool load_amf_file(const char *path, PresetBundle* bundle, Model *model) return result; } -bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, const char* path, PresetBundle* bundle, Model* model, unsigned int& version) +bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig* config, Model* model, unsigned int& version) { if (stat.m_uncomp_size == 0) { @@ -671,7 +666,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi return false; } - AMFParserContext ctx(parser, path, bundle, model); + AMFParserContext ctx(parser, config, model); XML_SetUserData(parser, (void*)&ctx); XML_SetElementHandler(parser, AMFParserContext::startElement, AMFParserContext::endElement); XML_SetCharacterDataHandler(parser, AMFParserContext::characters); @@ -707,7 +702,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi } // Load an AMF archive into a provided model. -bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model) +bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model) { if ((path == nullptr) || (model == nullptr)) return false; @@ -734,7 +729,7 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model) { if (boost::iends_with(stat.m_filename, ".amf")) { - if (!extract_model_from_archive(archive, stat, path, bundle, model, version)) + if (!extract_model_from_archive(archive, stat, config, model, version)) { mz_zip_reader_end(&archive); printf("Archive does not contain a valid model"); @@ -762,12 +757,12 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model) } // Load an AMF file into a provided model. -// If bundle is not a null pointer, updates it if the amf file/archive contains config data -bool load_amf(const char *path, PresetBundle* bundle, Model *model) +// If config is not a null pointer, updates it if the amf file/archive contains config data +bool load_amf(const char *path, DynamicPrintConfig *config, Model *model) { if (boost::iends_with(path, ".amf.xml")) // backward compatibility with older slic3r output - return load_amf_file(path, bundle, model); + return load_amf_file(path, config, model); else if (boost::iends_with(path, ".amf")) { boost::nowide::ifstream file(path, boost::nowide::ifstream::binary); @@ -778,7 +773,7 @@ bool load_amf(const char *path, PresetBundle* bundle, Model *model) file.read(const_cast<char*>(zip_mask.data()), 2); file.close(); - return (zip_mask == "PK") ? load_amf_archive(path, bundle, model) : load_amf_file(path, bundle, model); + return (zip_mask == "PK") ? load_amf_archive(path, config, model) : load_amf_file(path, config, model); } else return false; diff --git a/src/libslic3r/Format/AMF.hpp b/src/libslic3r/Format/AMF.hpp index 4779e9a51..ae8863e02 100644 --- a/src/libslic3r/Format/AMF.hpp +++ b/src/libslic3r/Format/AMF.hpp @@ -5,10 +5,9 @@ namespace Slic3r { class Model; class Print; -class PresetBundle; -// Load the content of an amf file into the given model and preset bundle. -extern bool load_amf(const char *path, PresetBundle* bundle, Model *model); +// Load the content of an amf file into the given model and configuration. +extern bool load_amf(const char *path, DynamicPrintConfig *config, Model *model); // Save the given model and the config data contained in the given Print into an amf file. // The model could be modified during the export process if meshes are not repaired or have no shared vertices @@ -16,4 +15,4 @@ extern bool store_amf(const char *path, Model *model, Print* print, bool export_ }; // namespace Slic3r -#endif /* slic3r_Format_AMF_hpp_ */ \ No newline at end of file +#endif /* slic3r_Format_AMF_hpp_ */ diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 2d23c69b7..ae74ab18e 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -44,10 +44,14 @@ void Model::swap(Model &other) std::swap(this->objects, other.objects); } -Model Model::read_from_file(const std::string &input_file, bool add_default_instances) +Model Model::read_from_file(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances) { Model model; - + + DynamicPrintConfig temp_config; + if (config == nullptr) + config = &temp_config; + bool result = false; if (boost::algorithm::iends_with(input_file, ".stl")) result = load_stl(input_file.c_str(), &model); @@ -55,7 +59,9 @@ Model Model::read_from_file(const std::string &input_file, bool add_default_inst result = load_obj(input_file.c_str(), &model); else if (!boost::algorithm::iends_with(input_file, ".zip.amf") && (boost::algorithm::iends_with(input_file, ".amf") || boost::algorithm::iends_with(input_file, ".amf.xml"))) - result = load_amf(input_file.c_str(), nullptr, &model); + result = load_amf(input_file.c_str(), config, &model); + else if (boost::algorithm::iends_with(input_file, ".3mf")) + result = load_3mf(input_file.c_str(), config, &model); #ifdef SLIC3R_PRUS else if (boost::algorithm::iends_with(input_file, ".prusa")) result = load_prus(input_file.c_str(), &model); @@ -78,15 +84,15 @@ Model Model::read_from_file(const std::string &input_file, bool add_default_inst return model; } -Model Model::read_from_archive(const std::string &input_file, PresetBundle* bundle, bool add_default_instances) +Model Model::read_from_archive(const std::string &input_file, DynamicPrintConfig *config, bool add_default_instances) { Model model; bool result = false; if (boost::algorithm::iends_with(input_file, ".3mf")) - result = load_3mf(input_file.c_str(), bundle, &model); + result = load_3mf(input_file.c_str(), config, &model); else if (boost::algorithm::iends_with(input_file, ".zip.amf")) - result = load_amf(input_file.c_str(), bundle, &model); + result = load_amf(input_file.c_str(), config, &model); else throw std::runtime_error("Unknown file format. Input file must have .3mf or .zip.amf extension."); diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 062efdb85..020bf69ac 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -343,8 +343,8 @@ public: void swap(Model &other); ~Model() { this->clear_objects(); this->clear_materials(); } - 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_file(const std::string &input_file, DynamicPrintConfig *config = nullptr, bool add_default_instances = true); + static Model read_from_archive(const std::string &input_file, DynamicPrintConfig *config, 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 diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index c90ad7650..f7d9e68c1 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -76,20 +76,37 @@ extern unsigned get_current_pid(); // Compute the next highest power of 2 of 32-bit v // http://graphics.stanford.edu/~seander/bithacks.html -template<typename T> -inline T next_highest_power_of_2(T v) +inline uint16_t next_highest_power_of_2(uint16_t v) { - if (v != 0) - -- v; + if (v != 0) + -- v; v |= v >> 1; v |= v >> 2; v |= v >> 4; - if (sizeof(T) >= sizeof(uint16_t)) - v |= v >> 8; - if (sizeof(T) >= sizeof(uint32_t)) - v |= v >> 16; - if (sizeof(T) >= sizeof(uint64_t)) - v |= v >> 32; + v |= v >> 8; + return ++ v; +} +inline uint32_t next_highest_power_of_2(uint32_t v) +{ + if (v != 0) + -- v; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return ++ v; +} +inline uint64_t next_highest_power_of_2(uint64_t v) +{ + if (v != 0) + -- v; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v |= v >> 32; return ++ v; } diff --git a/src/slic3r.cpp b/src/slic3r.cpp index a31c23f91..4cd833e2f 100644 --- a/src/slic3r.cpp +++ b/src/slic3r.cpp @@ -133,11 +133,12 @@ int main(int argc, char **argv) // 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()) + if (! cli_config.save.value.empty()) { + print_config.normalize(); print_config.save(cli_config.save.value); + } if (cli_config.help) { printUsage(); @@ -153,7 +154,7 @@ int main(int argc, char **argv) } Model model; try { - model = Model::read_from_file(file); + model = Model::read_from_file(file, &print_config, true); } catch (std::exception &e) { boost::nowide::cerr << file << ": " << e.what() << std::endl; exit(1); @@ -226,6 +227,7 @@ int main(int argc, char **argv) print.auto_assign_extruders(mo); print.add_model_object(mo); } + print_config.normalize(); print.apply_config(print_config); std::string err = print.validate(); if (err.empty()) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 658e1731a..771b39766 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1762,7 +1762,7 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c if (items_count > 1) m_original_height += (items_count - 1) * Px_Square_Contour; - int pow_of_two_size = next_highest_power_of_2(std::max(m_original_width, m_original_height)); + int pow_of_two_size = (int)next_highest_power_of_2(std::max<uint32_t>(m_original_width, m_original_height)); m_width = pow_of_two_size; m_height = pow_of_two_size; diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp index 892ecd861..8764b9e43 100644 --- a/xs/xsp/Model.xsp +++ b/xs/xsp/Model.xsp @@ -21,21 +21,12 @@ %name{read_from_file} Model(std::string input_file, bool add_default_instances = true) %code%{ try { - RETVAL = new Model(Model::read_from_file(input_file, add_default_instances)); + RETVAL = new Model(Model::read_from_file(input_file, nullptr, add_default_instances)); } catch (std::exception& e) { croak("Error while opening %s: %s\n", input_file.c_str(), e.what()); } %}; - %name{read_from_archive} Model(std::string input_file, PresetBundle* bundle, bool add_default_instances = true) - %code%{ - try { - RETVAL = new Model(Model::read_from_archive(input_file, bundle, add_default_instances)); - } catch (std::exception& e) { - croak("Error while opening %s: %s\n", input_file.c_str(), e.what()); - } - %}; - Clone<Model> clone() %code%{ RETVAL = THIS; %}; @@ -122,67 +113,7 @@ load_stl(CLASS, path, object_name) OUTPUT: RETVAL -Model* -load_obj(CLASS, path, object_name) - char* CLASS; - char* path; - char* object_name; - CODE: - RETVAL = new Model(); - if (! load_obj(path, RETVAL, object_name)) { - delete RETVAL; - RETVAL = NULL; - } - OUTPUT: - RETVAL - -Model* -load_amf(CLASS, bundle, path) - char* CLASS; - PresetBundle* bundle; - char* path; - CODE: - RETVAL = new Model(); - if (! load_amf(path, bundle, RETVAL)) { - delete RETVAL; - RETVAL = NULL; - } - OUTPUT: - RETVAL - -Model* -load_3mf(CLASS, bundle, path) - char* CLASS; - PresetBundle* bundle; - char* path; - CODE: - RETVAL = new Model(); - if (! load_3mf(path, bundle, RETVAL)) { - delete RETVAL; - RETVAL = NULL; - } - OUTPUT: - RETVAL - -Model* -load_prus(CLASS, path) - char* CLASS; - char* path; - CODE: -#ifdef SLIC3R_PRUS - RETVAL = new Model(); - if (! load_prus(path, RETVAL)) { - delete RETVAL; - RETVAL = NULL; - } -#else - RETVAL = nullptr; -#endif - OUTPUT: - RETVAL - %} - }; %name{Slic3r::Model::Material} class ModelMaterial {