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
This commit is contained in:
Ian Bassi
2026-04-24 03:21:44 -03:00
committed by GitHub
parent f8b0bcc725
commit 2b0a0023e0
6 changed files with 163 additions and 97 deletions

View File

@@ -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<Semver> m_bambuslicer_generator_version;
// Semantic version from the OrcaSlicer metadata tag (if present).
boost::optional<Semver> 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<Preset*>& 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<Preset*>& 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) << "</" << METADATA_TAG << ">\n";
if (item.first == BBL_APPLICATION_TAG) {
stream << " <" << METADATA_TAG << " name=\"" << ORCASLICER_TAG << "\">"
<< xml_escape(SoftFever_VERSION) << "</" << METADATA_TAG << ">\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 << " </" << SLICE_HEADER_TAG << ">\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<Preset*>* 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);

View File

@@ -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<Preset*>* 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);

View File

@@ -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)

View File

@@ -719,6 +719,7 @@ enum class ConversionType : int {
};
enum class En3mfType : int {
From_Orca,
From_BBS,
From_Prusa,
From_Other

View File

@@ -5954,9 +5954,9 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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<ConfigOptionEnum<InfillPattern>>("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<ConfigOptionEnum<InfillPattern>>("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<ConfigOptionEnum<InfillPattern>>("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<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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<size_t> Plater::priv::load_files(const std::vector<fs::path>& 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;
{

View File

@@ -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")