From 94732b6bad154d753ecd5cbfa7fbf585052c7511 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Fri, 27 Jun 2025 12:21:12 +0800 Subject: [PATCH] ENH: 3mf: fix save fullpath issue jira: STUDIO-12970 Change-Id: I71bbd9fd3e1bae669fcc29822f75a3ab9025af56 (cherry picked from commit da0f893433049899227a71e5ddc79833431ce39a) --- src/libslic3r/AppConfig.cpp | 3 ++ src/libslic3r/Format/bbs_3mf.cpp | 52 ++++++++++++++++++-------------- src/slic3r/GUI/Plater.cpp | 7 ++++- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index e01bef5d09..ef80fc1a73 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -193,6 +193,9 @@ void AppConfig::set_defaults() if (get("camera_orbit_mult").empty()) set("camera_orbit_mult", "1.0"); + if (get("export_sources_full_pathnames").empty()) + set_bool("export_sources_full_pathnames", false); + if (get("zoom_to_mouse").empty()) set_bool("zoom_to_mouse", false); diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 721e330f9b..1478c388a6 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -3891,7 +3891,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) } // Definition of read/write method for EmbossShape - static void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume &volume, mz_zip_archive &archive); + static void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume &volume, mz_zip_archive &archive,bool export_full_path); static std::optional read_emboss_shape(const char **attributes, unsigned int num_attributes); bool _BBS_3MF_Importer::_handle_start_shape_configuration(const char **attributes, unsigned int num_attributes) @@ -7518,6 +7518,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return true; } + boost::filesystem::path get_dealed_platform_path(std::string path_str) { +#if defined(__linux__) || defined(__LINUX__) || defined(__APPLE__) + std::string translated_input = path_str; + std::replace(translated_input.begin(), translated_input.end(), '\\', '/'); + + boost::filesystem::path file_path(translated_input); +#else + boost::filesystem::path file_path(path_str); +#endif + return file_path; + } + bool _BBS_3MF_Exporter::_add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model, PlateDataPtrs& plate_data_list, const ObjectToObjectDataMap &objects_data, const DynamicPrintConfig& config, int export_plate_idx, bool save_gcode, bool use_loaded_id) { std::stringstream stream; @@ -7592,15 +7604,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) // stores volume's source data { - #if defined(__linux__) || defined(__LINUX__) || defined(__APPLE__) - std::string translated_input = volume->source.input_file; - std::replace(translated_input.begin(), translated_input.end(), '\\', '/'); - - boost::filesystem::path file_path(translated_input); - #else - boost::filesystem::path file_path(volume->source.input_file); - #endif - + auto file_path =get_dealed_platform_path(volume->source.input_file); std::string input_file = xml_escape(m_fullpath_sources ? volume->source.input_file : file_path.filename().string()); //std::string prefix = std::string(" <") + METADATA_TAG + " " + KEY_ATTR + "=\""; std::string prefix = std::string(" <") + METADATA_TAG + " " + KEY_ATTR + "=\""; @@ -7624,9 +7628,9 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << METADATA_TAG << " "<< KEY_ATTR << "=\"" << key << "\" " << VALUE_ATTR << "=\"" << volume->config.opt_serialize(key) << "\"/>\n"; } - if (const std::optional &es = volume->emboss_shape; - es.has_value()) - to_xml(stream, *es, *volume, archive); + if (const std::optional &es = volume->emboss_shape; es.has_value()) { + to_xml(stream, *es, *volume, archive, m_fullpath_sources); + } if (const std::optional &tc = volume->text_configuration; tc.has_value()) @@ -8964,18 +8968,21 @@ Transform3d create_fix(const std::optional &prev, const ModelVolume return *prev * fix_trmat; } -bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const ModelVolume &volume, mz_zip_archive &archive){ +bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const ModelVolume &volume, mz_zip_archive &archive, bool export_full_path) +{ if (svg.path_in_3mf.empty()) return true; // EmbossedText OR unwanted store .svg file into .3mf (protection of copyRight) - if (!svg.path.empty()) - stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path) << "\" "; + if (!svg.path.empty()) { + auto file_path =get_dealed_platform_path(svg.path); + std::string input_file = xml_escape(export_full_path ? svg.path : file_path.filename().string()); + stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(input_file) << "\" "; + } stream << SVG_FILE_PATH_IN_3MF_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(svg.path_in_3mf) << "\" "; std::shared_ptr file_data = svg.file_data; - assert(file_data != nullptr); - if (file_data == nullptr && !svg.path.empty()) - file_data = read_from_disk(svg.path); + assert(file_data != nullptr); + if (file_data == nullptr && !svg.path.empty()) file_data = read_from_disk(svg.path); if (file_data == nullptr) { BOOST_LOG_TRIVIAL(warning) << "Can't write svg file no filedata"; return false; @@ -8988,13 +8995,14 @@ bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const Mo } // namespace -void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume &volume, mz_zip_archive &archive) +void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume &volume, mz_zip_archive &archive, bool export_full_path) { stream << " <" << SHAPE_TAG << " "; if (es.svg_file.has_value()) - if(!to_xml(stream, *es.svg_file, volume, archive)) + if (!to_xml(stream, *es.svg_file, volume, archive, export_full_path)) { BOOST_LOG_TRIVIAL(warning) << "Can't write svg file defiden embossed shape into 3mf"; - + } + stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" "; if (!es.final_shape.is_healed) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6248bbe648..ba5644f659 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -11067,7 +11067,12 @@ int Plater::save_project(bool saveAs) return wxID_CANCEL; //BBS export 3mf without gcode - if (export_3mf(into_path(filename), SaveStrategy::SplitModel | SaveStrategy::ShareMesh | SaveStrategy::FullPathSources) < 0) { + auto save_strategy = SaveStrategy::SplitModel | SaveStrategy::ShareMesh; + bool full_pathnames = wxGetApp().app_config->get_bool("export_sources_full_pathnames"); + if (full_pathnames) { + save_strategy = save_strategy | SaveStrategy::FullPathSources; + } + if (export_3mf(into_path(filename), save_strategy) < 0) { MessageDialog(this, _L("Failed to save the project.\nPlease check whether the folder exists online or if other programs open the project file."), _L("Save project"), wxOK | wxICON_WARNING).ShowModal(); return wxID_CANCEL;