From 2b0a0023e04530ef6b91074f90f6c6a221509348 Mon Sep 17 00:00:00 2001 From: Ian Bassi Date: Fri, 24 Apr 2026 03:21:44 -0300 Subject: [PATCH] 3MF Export/Import Orca export tags (#12509) * Using bbs versioning for bbs atributes * Orca tags * Bump SLIC3R version to match current BBS * New import logic * to_string_sf * 2.3.2 No tagged * Update comment --- src/libslic3r/Format/bbs_3mf.cpp | 46 ++++++-- src/libslic3r/Format/bbs_3mf.hpp | 2 +- src/libslic3r/Model.cpp | 12 +- src/libslic3r/Model.hpp | 1 + src/slic3r/GUI/Plater.cpp | 197 ++++++++++++++++++------------- version.inc | 2 +- 6 files changed, 163 insertions(+), 97 deletions(-) diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 42f55aae8a..e91d92309c 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -172,7 +172,10 @@ const std::string BBL_LICENSE_TAG = "License"; const std::string BBL_REGION_TAG = "Region"; const std::string BBL_MODIFICATION_TAG = "ModificationDate"; const std::string BBL_CREATION_DATE_TAG = "CreationDate"; +// Orca: BBL current version const std::string BBL_APPLICATION_TAG = "Application"; +// OrcaSlicer version tag +const std::string ORCASLICER_TAG = "OrcaSlicer"; const std::string BBL_MAKERLAB_TAG = "MakerLab"; const std::string BBL_MAKERLAB_VERSION_TAG = "MakerLabVersion"; @@ -1031,6 +1034,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) std::string m_origin_file; // Semantic version of Orca Slicer, that generated this 3MF. boost::optional m_bambuslicer_generator_version; + // Semantic version from the OrcaSlicer metadata tag (if present). + boost::optional m_orca_slicer_version; unsigned int m_fdm_supports_painting_version = 0; unsigned int m_seam_painting_version = 0; unsigned int m_mm_painting_version = 0; @@ -1102,7 +1107,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //BBS: add plate data related logic // add backup & restore logic bool load_model_from_file(const std::string& filename, Model& model, PlateDataPtrs& plate_data_list, std::vector& project_presets, DynamicPrintConfig& config, - ConfigSubstitutionContext& config_substitutions, LoadStrategy strategy, bool* is_bbl_3mf, Semver& file_version, Import3mfProgressFn proFn = nullptr, BBLProject *project = nullptr, int plate_id = 0); + ConfigSubstitutionContext& config_substitutions, LoadStrategy strategy, bool* is_bbl_3mf, bool* is_orca_3mf, Semver& file_version, Import3mfProgressFn proFn = nullptr, BBLProject *project = nullptr, int plate_id = 0); bool get_thumbnail(const std::string &filename, std::string &data); bool load_gcode_3mf_from_stream(std::istream & data, Model& model, PlateDataPtrs& plate_data_list, DynamicPrintConfig& config, Semver& file_version); unsigned int version() const { return m_version; } @@ -1310,7 +1315,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) //BBS: add plate data related logic // add backup & restore logic bool _BBS_3MF_Importer::load_model_from_file(const std::string& filename, Model& model, PlateDataPtrs& plate_data_list, std::vector& project_presets, DynamicPrintConfig& config, - ConfigSubstitutionContext& config_substitutions, LoadStrategy strategy, bool* is_bbl_3mf, Semver& file_version, Import3mfProgressFn proFn, BBLProject *project, int plate_id) + ConfigSubstitutionContext& config_substitutions, LoadStrategy strategy, bool* is_bbl_3mf, bool* is_orca_3mf, Semver& file_version, Import3mfProgressFn proFn, BBLProject *project, int plate_id) { m_version = 0; m_fdm_supports_painting_version = 0; @@ -1366,8 +1371,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (is_bbl_3mf) { *is_bbl_3mf = m_is_bbl_3mf; } - if (m_bambuslicer_generator_version) - file_version = *m_bambuslicer_generator_version; + // If the OrcaSlicer tag is present, use it as file_version (ignoring the Bambu Application version). + // Otherwise fall back to the version parsed from the Application tag. + if (m_orca_slicer_version) { + file_version = *m_orca_slicer_version; + if (is_orca_3mf) + *is_orca_3mf = true; + } else { + if (m_bambuslicer_generator_version) + file_version = *m_bambuslicer_generator_version; + if (is_orca_3mf) + *is_orca_3mf = false; + } // save for restore if (result && m_load_aux && !m_load_restore) { save_string_file(model.get_backup_path() + "/origin.txt", filename); @@ -3818,6 +3833,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) m_is_bbl_3mf = true; m_bambuslicer_generator_version = Semver::parse(m_curr_characters.substr(11)); } + } else if (m_curr_metadata_name == ORCASLICER_TAG) { + // OrcaSlicer version tag (written from OrcaSlicer 2.3.2 onwards) + m_orca_slicer_version = Semver::parse(m_curr_characters); + if (m_orca_slicer_version) { + m_is_bbl_3mf = true; + } //TODO: currently use version 0, no need to load&&save this string /*} else if (m_curr_metadata_name == BBS_FDM_SUPPORTS_PAINTING_VERSION) { m_fdm_supports_painting_version = (unsigned int) atoi(m_curr_characters.c_str()); @@ -6658,8 +6679,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) // Orca: PRIVACY: do not store creation & modification date in 3mf metadata_item_map[BBL_CREATION_DATE_TAG] = ""; metadata_item_map[BBL_MODIFICATION_TAG] = ""; - //SoftFever: write BambuStudio tag to keep it compatible - metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % "BambuStudio" % SoftFever_VERSION).str(); + // Orca: Write the BambuStudio compatibility version string using SLIC3R_VERSION + metadata_item_map[BBL_APPLICATION_TAG] = (boost::format("%1%-%2%") % "BambuStudio" % SLIC3R_VERSION).str(); } metadata_item_map[BBS_3MF_VERSION] = std::to_string(VERSION_BBS_3MF); @@ -6684,6 +6705,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) BOOST_LOG_TRIVIAL(info) << "bbs_3mf: save key= " << item.first << ", value = " << item.second; stream << " <" << METADATA_TAG << " name=\"" << item.first << "\">" << xml_escape(item.second) << "\n"; + if (item.first == BBL_APPLICATION_TAG) { + stream << " <" << METADATA_TAG << " name=\"" << ORCASLICER_TAG << "\">" + << xml_escape(SoftFever_VERSION) << "\n"; + } } stream << " <" << RESOURCES_TAG << ">\n"; @@ -7543,7 +7568,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) { const std::string& temp_path = model.get_backup_path(); std::string temp_file = temp_path + std::string("/") + "_temp_1.config"; - config.save_to_json(temp_file, std::string("project_settings"), std::string("project"), std::string(SoftFever_VERSION)); + config.save_to_json(temp_file, std::string("project_settings"), std::string("project"), std::string(SLIC3R_VERSION)); return _add_file_to_archive(archive, BBS_PROJECT_CONFIG_FILE, temp_file); } @@ -7938,7 +7963,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) // save slice header for debug stream << " <" << SLICE_HEADER_TAG << ">\n"; stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Type" << "\" " << VALUE_ATTR << "=\"" << "slicer" << "\"/>\n"; - stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Version" << "\" " << VALUE_ATTR << "=\"" << convert_to_full_version(SoftFever_VERSION) << "\"/>\n"; + stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "X-BBL-Client-Version" << "\" " << VALUE_ATTR << "=\"" << convert_to_full_version(SLIC3R_VERSION) << "\"/>\n"; + stream << " <" << SLICE_HEADER_ITEM_TAG << " " << KEY_ATTR << "=\"" << "OrcaSlicer-Version" << "\" " << VALUE_ATTR << "=\"" << SoftFever_VERSION << "\"/>\n"; stream << " \n"; for (unsigned int i = 0; i < (unsigned int)plate_data_list.size(); ++i) @@ -8634,7 +8660,7 @@ private: //BBS: add plate data list related logic bool load_bbs_3mf(const char* path, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, Model* model, PlateDataPtrs* plate_data_list, std::vector* project_presets, - bool* is_bbl_3mf, Semver* file_version, Import3mfProgressFn proFn, LoadStrategy strategy, BBLProject *project, int plate_id) + bool* is_bbl_3mf, bool* is_orca_3mf, Semver* file_version, Import3mfProgressFn proFn, LoadStrategy strategy, BBLProject *project, int plate_id) { if (path == nullptr || config == nullptr || model == nullptr) return false; @@ -8642,7 +8668,7 @@ bool load_bbs_3mf(const char* path, DynamicPrintConfig* config, ConfigSubstituti // All import should use "C" locales for number formatting. CNumericLocalesSetter locales_setter; _BBS_3MF_Importer importer; - bool res = importer.load_model_from_file(path, *model, *plate_data_list, *project_presets, *config, *config_substitutions, strategy, is_bbl_3mf, *file_version, proFn, project, plate_id); + bool res = importer.load_model_from_file(path, *model, *plate_data_list, *project_presets, *config, *config_substitutions, strategy, is_bbl_3mf, is_orca_3mf, *file_version, proFn, project, plate_id); importer.log_errors(); //BBS: remove legacy project logic currently //handle_legacy_project_loaded(importer.version(), *config); diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index 5fd57c4d61..080655a427 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -248,7 +248,7 @@ struct StoreParams // add restore logic // Load the content of a 3mf file into the given model and preset bundle. extern bool load_bbs_3mf(const char* path, DynamicPrintConfig* config, ConfigSubstitutionContext* config_substitutions, Model* model, PlateDataPtrs* plate_data_list, std::vector* project_presets, - bool* is_bbl_3mf, Semver* file_version, Import3mfProgressFn proFn = nullptr, LoadStrategy strategy = LoadStrategy::Default, BBLProject *project = nullptr, int plate_id = 0); + bool* is_bbl_3mf, bool* is_orca_3mf, Semver* file_version, Import3mfProgressFn proFn = nullptr, LoadStrategy strategy = LoadStrategy::Default, BBLProject *project = nullptr, int plate_id = 0); extern std::string bbs_3mf_get_thumbnail(const char * path); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 05a56c3a47..e3b2ada837 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -323,7 +323,7 @@ Model Model::read_from_file(const std::string& // BBS: backup & restore //FIXME options & LoadStrategy::CheckVersion ? //BBS: is_xxx is used for is_bbs_3mf when load 3mf - result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, is_xxx, file_version, proFn, options, project, plate_id); + result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, is_xxx, nullptr, file_version, proFn, options, project, plate_id); #ifdef __APPLE__ else if (boost::algorithm::iends_with(input_file, ".usd") || boost::algorithm::iends_with(input_file, ".usda") || boost::algorithm::iends_with(input_file, ".usdc") || boost::algorithm::iends_with(input_file, ".usdz") || @@ -382,7 +382,8 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig Model model; bool result = false; - bool is_bbl_3mf; + bool is_bbl_3mf = false; + bool is_orca_3mf = false; if (boost::algorithm::iends_with(input_file, ".3mf")) { PrusaFileParser prusa_file_parser; if (prusa_file_parser.check_3mf_from_prusa(input_file)) { @@ -392,7 +393,7 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig } else { // BBS: add part plate related logic // BBS: backup & restore - result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, &is_bbl_3mf, file_version, proFn, options, project); + result = load_bbs_3mf(input_file.c_str(), config, config_substitutions, &model, plate_data, project_presets, &is_bbl_3mf, &is_orca_3mf, file_version, proFn, options, project); } } else if (boost::algorithm::iends_with(input_file, ".zip.amf")) @@ -401,7 +402,10 @@ Model Model::read_from_archive(const std::string& input_file, DynamicPrintConfig throw Slic3r::RuntimeError(_L("Unknown file format. Input file must have .3mf or .zip.amf extension.")); if (out_file_type != En3mfType::From_Prusa) { - out_file_type = is_bbl_3mf ? En3mfType::From_BBS : En3mfType::From_Other; + if (is_orca_3mf) + out_file_type = En3mfType::From_Orca; + else + out_file_type = is_bbl_3mf ? En3mfType::From_BBS : En3mfType::From_Other; } if (!result) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 7d483e61c5..5974ca4cd6 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -719,6 +719,7 @@ enum class ConversionType : int { }; enum class En3mfType : int { + From_Orca, From_BBS, From_Prusa, From_Other diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 72e17448d8..22d590a969 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -5954,9 +5954,9 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (cancel) is_user_cancel = cancel; }); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ - << boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_3mf %3%, file_version %4% \n") % plate_data.size() % - project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS) % file_version.to_string(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ + << boost::format(", plate_data.size %1%, project_preset.size %2%, is_bbs_or_orca_3mf %3%, file_version %4% \n") % plate_data.size() % + project_presets.size() % (en_3mf_file_type == En3mfType::From_BBS || en_3mf_file_type == En3mfType::From_Orca) % file_version.to_string(); // 1. add extruder for prusa model if the number of existing extruders is not enough // 2. add extruder for BBS or Other model if only import geometry @@ -5998,88 +5998,123 @@ std::vector Plater::priv::load_files(const std::vector& input_ if(load_type != LoadType::LoadGeometry) show_info(q, _L("The 3MF is not supported by OrcaSlicer, loading geometry data only."), _L("Load 3MF")); } - // else if (load_config && (file_version.maj() != app_version.maj())) { - // // version mismatch, only load geometries - // load_config = false; - // if (!load_model) { - // // only load config case, return directly - // show_info(q, _L("The Config cannot be loaded."), _L("Load 3MF")); - // q->skip_thumbnail_invalid = false; - // return empty_result; - // } - // load_old_project = true; - // // select view to 3D - // q->select_view_3D("3D"); - // // select plate 0 as default - // q->select_plate(0); - // if (load_type != LoadType::LoadGeometry) { - // if (en_3mf_file_type == En3mfType::From_BBS) - // show_info(q, _L("The 3MF was generated by an old OrcaSlicer, loading geometry data only."), _L("Load 3MF")); - // else - // show_info(q, _L("The 3MF is not supported by OrcaSlicer, loading geometry data only."), _L("Load 3MF")); - // } - // for (ModelObject *model_object : model.objects) { - // model_object->config.reset(); - // // Is there any modifier or advanced config data? - // for (ModelVolume *model_volume : model_object->volumes) model_volume->config.reset(); - // } - // } - // Orca: check if the project is created with OrcaSlicer 2.3.1-alpha and use the sparse infill rotation template for non-safe infill patterns - else if (load_config && (file_version < app_version) && file_version == Semver("2.3.1-alpha")) { - if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) { - const auto _sparse_infill_pattern = - config_loaded.option>("sparse_infill_pattern")->value; - bool is_safe_to_rotate = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine || - _sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag || - _sparse_infill_pattern == ipLockedZag; - if (!is_safe_to_rotate) { - wxString msg_text = _( - L("This project was created with an OrcaSlicer 2.3.1-alpha and uses " - "infill rotation template settings that may not work properly with your current infill pattern. " - "This could result in weak support or print quality issues.")); - msg_text += "\n\n" + - _(L("Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?")); - MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO); - dialog.SetButtonLabel(wxID_YES, _L("Yes")); - dialog.SetButtonLabel(wxID_NO, _L("No")); - if (dialog.ShowModal() == wxID_YES) { - config_loaded.opt_string("sparse_infill_rotate_template") = ""; + else if (en_3mf_file_type == En3mfType::From_Orca) { + // OrcaSlicer file (has OrcaSlicer tag) - compare file_version with SoftFever_VERSION + // Migration fix for OrcaSlicer 2.3.1-alpha sparse infill rotation template + if (load_config && (file_version < app_version) && file_version == Semver("2.3.1-alpha")) { + if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) { + const auto _sparse_infill_pattern = + config_loaded.option>("sparse_infill_pattern")->value; + bool is_safe_to_rotate = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine || + _sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag || + _sparse_infill_pattern == ipLockedZag; + if (!is_safe_to_rotate) { + wxString msg_text = _( + L("This project was created with an OrcaSlicer 2.3.1-alpha and uses " + "infill rotation template settings that may not work properly with your current infill pattern. " + "This could result in weak support or print quality issues.")); + msg_text += "\n\n" + + _(L("Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?")); + MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO); + dialog.SetButtonLabel(wxID_YES, _L("Yes")); + dialog.SetButtonLabel(wxID_NO, _L("No")); + if (dialog.ShowModal() == wxID_YES) { + config_loaded.opt_string("sparse_infill_rotate_template") = ""; + } + } + } + } else if (load_config && (file_version > app_version)) { + if (config_substitutions.unrecogized_keys.size() > 0) { + wxString text = wxString::Format(_L("The 3MF file version %s is newer than %s's version %s, found the following unrecognized keys:"), + file_version.to_string_sf(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string_sf()); + text += "\n"; + wxString context = text; + wxString append = _L("You'd better upgrade your software.\n"); + context += "\n\n"; + context += append; + show_info(q, context, _L("Newer 3MF version")); + } + else { + //if the minor version is not matched + if (file_version.min() != app_version.min()) { + wxString text = wxString::Format(_L("The 3MF file version %s is newer than %s's version %s, we suggest to upgrade your software."), + file_version.to_string_sf(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string_sf()); + text += "\n"; + show_info(q, text, _L("Newer 3MF version")); } } } - - } else if (load_config && (file_version > app_version)) { - if (config_substitutions.unrecogized_keys.size() > 0) { - wxString text = wxString::Format(_L("The 3MF file version %s is newer than %s's version %s, found the following unrecognized keys:"), - file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string()); - text += "\n"; - bool first = true; - // std::string context = into_u8(text); - wxString context = text; - // if (wxGetApp().app_config->get("user_mode") == "develop") { - // for (auto &key : config_substitutions.unrecogized_keys) { - // context += " -"; - // context += key; - // context += ";\n"; - // first = false; - // } - // } - wxString append = _L("You'd better upgrade your software.\n"); - context += "\n\n"; - // context += into_u8(append); - context += append; - show_info(q, context, _L("Newer 3MF version")); + else if (load_config && config_loaded.empty()) { + load_config = false; + show_info(q, _L("The 3MF file was generated by an old OrcaSlicer version, loading geometry data only."), _L("Load 3MF")); } - else { - //if the minor version is not matched - if (file_version.min() != app_version.min()) { - wxString text = wxString::Format(_L("The 3MF file version %s is newer than %s's version %s, we suggest to upgrade your software."), - file_version.to_string(), std::string(SLIC3R_APP_FULL_NAME), app_version.to_string()); - text += "\n"; - show_info(q, text, _L("Newer 3MF version")); + } + else if (en_3mf_file_type == En3mfType::From_BBS) { + // No OrcaSlicer tag - check Bambu/Application version + Semver orca_tag_start_version(2, 3, 2); + if (file_version <= orca_tag_start_version) { + // Compatible old version (before OrcaSlicer tagging was introduced after 2.3.2). + // Any version prior or equal to 2.3.2 is older than the current one, no version warnings needed. + // Still apply migration fixes for known old versions. + if (load_config && (file_version == Semver("2.3.1-alpha"))) { + if (!config_loaded.opt_string("sparse_infill_rotate_template").empty()) { + const auto _sparse_infill_pattern = + config_loaded.option>("sparse_infill_pattern")->value; + bool is_safe_to_rotate = _sparse_infill_pattern == ipRectilinear || _sparse_infill_pattern == ipLine || + _sparse_infill_pattern == ipZigZag || _sparse_infill_pattern == ipCrossZag || + _sparse_infill_pattern == ipLockedZag; + if (!is_safe_to_rotate) { + wxString msg_text = _( + L("This project was created with an OrcaSlicer 2.3.1-alpha and uses " + "infill rotation template settings that may not work properly with your current infill pattern. " + "This could result in weak support or print quality issues.")); + msg_text += "\n\n" + + _(L("Would you like OrcaSlicer to automatically fix this by clearing the rotation template settings?")); + MessageDialog dialog(wxGetApp().plater(), msg_text, "", wxICON_WARNING | wxYES | wxNO); + dialog.SetButtonLabel(wxID_YES, _L("Yes")); + dialog.SetButtonLabel(wxID_NO, _L("No")); + if (dialog.ShowModal() == wxID_YES) { + config_loaded.opt_string("sparse_infill_rotate_template") = ""; + } + } + } + } + else if (load_config && config_loaded.empty()) { + load_config = false; + show_info(q, _L("The 3MF file was generated by an older version, loading geometry data only."), _L("Load 3MF")); + } + } else { + // BambuStudio project (version > 2.3.2 without OrcaSlicer tag) + // Report that a BambuStudio project is being imported and compare with SLIC3R_VERSION + Semver slic3r_version = *(Semver::parse(SLIC3R_VERSION)); + if (load_config && config_loaded.empty()) { + load_config = false; + show_info(q, _L("The 3MF file was generated by BambuStudio, loading geometry data only."), _L("Load 3MF")); + } + else if (load_config && (file_version > slic3r_version)) { + // BambuStudio file version is newer than our compatible SLIC3R_VERSION + if (config_substitutions.unrecogized_keys.size() > 0) { + wxString text = wxString::Format(_L("The 3MF was created by BambuStudio (version %s), which is newer than the compatible version %s. Found unrecognized settings:"), + file_version.to_string(), slic3r_version.to_string()); + text += "\n"; + wxString context = text; + wxString append = _L("You'd better upgrade your software.\n"); + context += "\n\n"; + context += append; + show_info(q, context, _L("BambuStudio Project")); + } else { + wxString text = wxString::Format(_L("The 3MF was created by BambuStudio (version %s), which is newer than the compatible version %s. Some settings may not be fully compatible."), + file_version.to_string(), slic3r_version.to_string()); + text += "\n"; + show_info(q, text, _L("BambuStudio Project")); + } + } else if (load_config) { + // BambuStudio version is older or same as our SLIC3R_VERSION + wxString text = _L("The 3MF was created by BambuStudio. Some settings may differ from OrcaSlicer."); + show_info(q, text, _L("BambuStudio Project")); } } - } + } else if (load_config && config_loaded.empty()) { load_config = false; show_info(q, _L("The 3MF file was generated by an old OrcaSlicer version, loading geometry data only."), _L("Load 3MF")); @@ -6120,7 +6155,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ } Semver old_version(1, 5, 9); - if ((en_3mf_file_type == En3mfType::From_BBS) && (file_version < old_version) && load_model && load_config && !config_loaded.empty()) { + if ((en_3mf_file_type == En3mfType::From_BBS || en_3mf_file_type == En3mfType::From_Orca) && (file_version < old_version) && load_model && load_config && !config_loaded.empty()) { translate_old = true; partplate_list.get_plate_size(current_width, current_depth, current_height); } @@ -6207,7 +6242,7 @@ std::vector Plater::priv::load_files(const std::vector& input_ { // BBS: modify the prime tower params for old version file Semver old_version3(2, 0, 0); - if (en_3mf_file_type == En3mfType::From_BBS && file_version < old_version3) { + if ((en_3mf_file_type == En3mfType::From_BBS || en_3mf_file_type == En3mfType::From_Orca) && file_version < old_version3) { double old_filament_prime_volume = 0.; int filament_count = 0; { diff --git a/version.inc b/version.inc index 24b1354ce0..ce4b024c74 100644 --- a/version.inc +++ b/version.inc @@ -14,7 +14,7 @@ set(ORCA_VERSION_MAJOR ${CMAKE_MATCH_1}) set(ORCA_VERSION_MINOR ${CMAKE_MATCH_2}) set(ORCA_VERSION_PATCH ${CMAKE_MATCH_3}) -set(SLIC3R_VERSION "01.10.01.50") +set(SLIC3R_VERSION "02.05.01.52") if (NOT DEFINED ORCA_UPDATER_SIG_KEY) set(ORCA_UPDATER_SIG_KEY "" CACHE STRING "Base64url encoded updater signature key")