diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 4fd3096549..b96988fb91 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -661,7 +661,7 @@ ModelVolumeType type_from_string(const std::string &s) : m_version(0) , m_check_version(false) , m_xml_parser(nullptr) - , m_model(nullptr) + , m_model(nullptr) , m_unit_factor(1.0f) , m_curr_metadata_name("") , m_curr_characters("") @@ -934,6 +934,18 @@ ModelVolumeType type_from_string(const std::string &s) ++object_idx; } + //BBS: copy object isteadof instance + int object_size = model.objects.size(); + for (int obj_index = 0; obj_index < object_size; obj_index ++) { + ModelObject* object = model.objects[obj_index]; + while (object->instances.size() > 1) { + ModelObject* new_model_object = model.add_object(*object); + new_model_object->clear_instances(); + new_model_object->add_instance(*object->instances.back()); + object->delete_last_instance(); + } + } + // // fixes the min z of the model if negative // model.adjust_min_z(); @@ -1005,8 +1017,8 @@ ModelVolumeType type_from_string(const std::string &s) } void _3MF_Importer::_extract_print_config_from_archive( - mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, - DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, + mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, + DynamicPrintConfig& config, ConfigSubstitutionContext& config_substitutions, const std::string& archive_filename) { if (stat.m_uncomp_size > 0) { @@ -1227,7 +1239,7 @@ ModelVolumeType type_from_string(const std::string &s) } } } - + void _3MF_Importer::_extract_sla_drain_holes_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat) { if (stat.m_uncomp_size > 0) { @@ -1237,13 +1249,13 @@ ModelVolumeType type_from_string(const std::string &s) add_error("Error while reading sla support points data to buffer"); return; } - + if (buffer.back() == '\n') buffer.pop_back(); - + std::vector objects; boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off); - + // Info on format versioning - see 3mf.hpp int version = 0; std::string key("drain_holes_format_version="); @@ -1252,38 +1264,38 @@ ModelVolumeType type_from_string(const std::string &s) version = std::stoi(objects[0]); objects.erase(objects.begin()); // pop the header } - + for (const std::string& object : objects) { std::vector object_data; boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off); - + if (object_data.size() != 2) { add_error("Error while reading object data"); continue; } - + std::vector object_data_id; boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off); if (object_data_id.size() != 2) { add_error("Error while reading object id"); continue; } - + int object_id = std::atoi(object_data_id[1].c_str()); if (object_id == 0) { add_error("Found invalid object id"); continue; } - + IdToSlaDrainHolesMap::iterator object_item = m_sla_drain_holes.find(object_id); if (object_item != m_sla_drain_holes.end()) { add_error("Found duplicated SLA drain holes"); continue; } - + std::vector object_data_points; boost::split(object_data_points, object_data[1], boost::is_any_of(" "), boost::token_compress_off); - + sla::DrainHoles sla_drain_holes; if (version == 1) { @@ -1306,7 +1318,7 @@ ModelVolumeType type_from_string(const std::string &s) hole.pos += hole.normal.normalized(); hole.height -= 1.f; } - + if (!sla_drain_holes.empty()) m_sla_drain_holes.insert({ object_id, sla_drain_holes }); } @@ -1394,11 +1406,11 @@ ModelVolumeType type_from_string(const std::string &s) pt::ptree attr_tree = tree.find("")->second; if (attr_tree.find("type") == attr_tree.not_found()) { // It means that data was saved in old version (2.2.0 and older) of PrusaSlicer - // read old data ... + // read old data ... std::string gcode = tree.get (".gcode"); // ... and interpret them to the new data - type = gcode == "M600" ? CustomGCode::ColorChange : - gcode == "M601" ? CustomGCode::PausePrint : + type = gcode == "M600" ? CustomGCode::ColorChange : + gcode == "M601" ? CustomGCode::PausePrint : gcode == "tool_change" ? CustomGCode::ToolChange : CustomGCode::Custom; extra = type == CustomGCode::PausePrint ? color : type == CustomGCode::Custom ? gcode : ""; @@ -2113,7 +2125,7 @@ ModelVolumeType type_from_string(const std::string &s) tri_id -= min_id; } - if (m_prusaslicer_generator_version && + if (m_prusaslicer_generator_version && *m_prusaslicer_generator_version >= *Semver::parse("2.4.0-alpha1") && *m_prusaslicer_generator_version < *Semver::parse("2.4.0-alpha3")) // PrusaSlicer 2.4.0-alpha2 contained a bug, where all vertices of a single object were saved for each volume the object contained. @@ -2227,7 +2239,7 @@ ModelVolumeType type_from_string(const std::string &s) if (importer != nullptr) importer->_handle_start_config_xml_element(name, attributes); } - + void XMLCALL _3MF_Importer::_handle_end_config_xml_element(void* userData, const char* name) { _3MF_Importer* importer = (_3MF_Importer*)userData; @@ -2340,7 +2352,7 @@ ModelVolumeType type_from_string(const std::string &s) } } - // Adds relationships file ("_rels/.rels"). + // Adds relationships file ("_rels/.rels"). // The content of this file is the same for each PrusaSlicer 3mf. // The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA. if (!_add_relationships_file_to_archive(archive)) { @@ -2384,13 +2396,13 @@ ModelVolumeType type_from_string(const std::string &s) boost::filesystem::remove(filename); return false; } - + if (!_add_sla_drain_holes_file_to_archive(archive, model)) { close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } - + // Adds custom gcode per height file ("Metadata/Prusa_Slicer_custom_gcode_per_print_z.xml"). // All custom gcode per height of whole Model are stored here @@ -2502,11 +2514,11 @@ ModelVolumeType type_from_string(const std::string &s) bool _3MF_Exporter::_add_model_file_to_archive(const std::string& filename, mz_zip_archive& archive, const Model& model, IdToObjectDataMap& objects_data) { mz_zip_writer_staged_context context; - if (!mz_zip_writer_add_staged_open(&archive, &context, MODEL_FILE.c_str(), - m_zip64 ? + if (!mz_zip_writer_add_staged_open(&archive, &context, MODEL_FILE.c_str(), + m_zip64 ? // Maximum expected and allowed 3MF file size is 16GiB. // This switches the ZIP file to a 64bit mode, which adds a tiny bit of overhead to file records. - (uint64_t(1) << 30) * 16 : + (uint64_t(1) << 30) * 16 : // Maximum expected 3MF file size is 4GB-1. This is a workaround for interoperability with Windows 10 3D model fixing API, see // GH issue #6193. (uint64_t(1) << 32) - 1, @@ -2589,7 +2601,7 @@ ModelVolumeType type_from_string(const std::string &s) } stream << "\n"; - + std::string buf = stream.str(); if ((! buf.empty() && ! mz_zip_writer_add_staged_data(&context, buf.data(), buf.size())) || @@ -2877,7 +2889,7 @@ ModelVolumeType type_from_string(const std::string &s) sprintf(buffer, (i == 0) ? "%f" : ";%f", layer_height_profile[i]); out += buffer; } - + out += "\n"; } } @@ -2936,8 +2948,8 @@ ModelVolumeType type_from_string(const std::string &s) boost::replace_all(out, ">\n ", ">\n "); boost::replace_all(out, ">", ">\n "); - // OR just - boost::replace_all(out, "><", ">\n<"); + // OR just + boost::replace_all(out, "><", ">\n<"); } if (!out.empty()) { @@ -2984,13 +2996,13 @@ ModelVolumeType type_from_string(const std::string &s) } return true; } - + bool _3MF_Exporter::_add_sla_drain_holes_file_to_archive(mz_zip_archive& archive, Model& model) { assert(is_decimal_separator_point()); const char *const fmt = "object_id=%d|"; std::string out; - + unsigned int count = 0; for (const ModelObject* object : model.objects) { ++count; @@ -3007,7 +3019,7 @@ ModelVolumeType type_from_string(const std::string &s) if (!drain_holes.empty()) { out += string_printf(fmt, count); - + // Store the layer height profile as a single space separated list. for (size_t i = 0; i < drain_holes.size(); ++i) out += string_printf((i == 0 ? "%f %f %f %f %f %f %f %f" : " %f %f %f %f %f %f %f %f"), @@ -3019,15 +3031,15 @@ ModelVolumeType type_from_string(const std::string &s) drain_holes[i].normal(2), drain_holes[i].radius, drain_holes[i].height); - + out += "\n"; } } - + if (!out.empty()) { // Adds version header at the beginning: out = std::string("drain_holes_format_version=") + std::to_string(drain_holes_format_version) + std::string("\n") + out; - + if (!mz_zip_writer_add_mem(&archive, SLA_DRAIN_HOLES_FILE.c_str(), static_cast(out.data()), out.length(), mz_uint(MZ_DEFAULT_COMPRESSION))) { add_error("Unable to add sla support points file to archive"); return false; @@ -3099,7 +3111,7 @@ ModelVolumeType type_from_string(const std::string &s) if (volume->is_modifier()) stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << MODIFIER_KEY << "\" " << VALUE_ATTR << "=\"1\"/>\n"; // stores volume's type (overrides the modifier field above) - stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " << + stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << VOLUME_TYPE_KEY << "\" " << VALUE_ATTR << "=\"" << ModelVolume::type_to_string(volume->type()) << "\"/>\n"; // stores volume's local matrix @@ -3137,7 +3149,7 @@ ModelVolumeType type_from_string(const std::string &s) for (const std::string& key : volume->config.keys()) { stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; } - + // stores mesh's statistics const RepairedMeshErrors& stats = volume->mesh().stats().repaired_errors; stream << " <" << MESH_TAG << " "; @@ -3190,12 +3202,12 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv std::string gcode = //code.type == CustomGCode::ColorChange ? config->opt_string("color_change_gcode") : code.type == CustomGCode::PausePrint ? config->opt_string("machine_pause_gcode") : code.type == CustomGCode::Template ? config->opt_string("template_custom_gcode") : - code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; + code.type == CustomGCode::ToolChange ? "tool_change" : code.extra; code_tree.put(".gcode" , gcode ); } pt::ptree& mode_tree = main_tree.add("mode", ""); - // store mode of a custom_gcode_per_print_z + // store mode of a custom_gcode_per_print_z mode_tree.put(".value", model.custom_gcode_per_print_z.mode == CustomGCode::Mode::SingleExtruder ? CustomGCode::SingleExtruderMode : model.custom_gcode_per_print_z.mode == CustomGCode::Mode::MultiAsSingle ? CustomGCode::MultiAsSingleMode : CustomGCode::MultiExtruderMode); @@ -3208,7 +3220,7 @@ bool _3MF_Exporter::_add_custom_gcode_per_print_z_file_to_archive( mz_zip_archiv // Post processing("beautification") of the output string boost::replace_all(out, "><", ">\n<"); } - } + } if (!out.empty()) { if (!mz_zip_writer_add_mem(&archive, CUSTOM_GCODE_PER_PRINT_Z_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a7434c8c07..723de0a603 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2948,7 +2948,12 @@ std::vector Plater::priv::load_files(const std::vector& input_ wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); } - LoadType load_type = static_cast(std::stoi(wxGetApp().app_config->get("import_project_action"))); + std::string import_project_action = wxGetApp().app_config->get("import_project_action"); + LoadType load_type; + if (import_project_action.empty()) + load_type = LoadType::Unknown; + else + load_type = static_cast(std::stoi(import_project_action)); // BBS: version check Semver app_version = *(Semver::parse(SLIC3R_VERSION));