From 589d2be442d93e019c7fc8ccf26fa15d6f61be5d Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Mon, 8 Mar 2021 09:36:13 +0100
Subject: [PATCH] Fix of Repair with Netfabb does not work on builds after
 2.3.0 release (Windows 10) #6193 This is more a workaround than a fix:
 Windows 10 3D model fixing API refuses to load a zip64 encoded 3MF. We need
 to get in touch with Microsoft on that issue, for now the 3MFs generated for
 the Windows 10 3D model fixing API will be limited to 4GB. Saving a bigger
 3MF will fail.

---
 src/libslic3r/Format/3mf.cpp         | 19 +++++++++++++------
 src/libslic3r/Format/3mf.hpp         |  2 +-
 src/slic3r/Utils/FixModelByWin10.cpp |  2 +-
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp
index e10b26f38..8ba248998 100644
--- a/src/libslic3r/Format/3mf.cpp
+++ b/src/libslic3r/Format/3mf.cpp
@@ -2014,9 +2014,10 @@ namespace Slic3r {
         typedef std::map<int, ObjectData> IdToObjectDataMap;
 
         bool m_fullpath_sources{ true };
+        bool m_zip64 { true };
 
     public:
-        bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data = nullptr);
+        bool save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64);
 
     private:
         bool _save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, const ThumbnailData* thumbnail_data);
@@ -2036,10 +2037,11 @@ namespace Slic3r {
         bool _add_custom_gcode_per_print_z_file_to_archive(mz_zip_archive& archive, Model& model, const DynamicPrintConfig* config);
     };
 
-    bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data)
+    bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64)
     {
         clear_errors();
         m_fullpath_sources = fullpath_sources;
+        m_zip64 = zip64;
         return _save_model_to_file(filename, model, config, thumbnail_data);
     }
 
@@ -2233,9 +2235,13 @@ namespace Slic3r {
     {
         mz_zip_writer_staged_context context;
         if (!mz_zip_writer_add_staged_open(&archive, &context, MODEL_FILE.c_str(), 
-            // 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,
+            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 : 
+                // 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,
             nullptr, nullptr, 0, MZ_DEFAULT_COMPRESSION, nullptr, 0, nullptr, 0)) {
             add_error("Unable to add model file to archive");
             return false;
@@ -2926,12 +2932,13 @@ bool load_3mf(const char* path, DynamicPrintConfig* config, Model* model, bool c
     return res;
 }
 
-bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data)
+bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data, bool zip64)
 {
     if (path == nullptr || model == nullptr)
         return false;
 
     _3MF_Exporter exporter;
+    exporter.zip64 = zip64;
     bool res = exporter.save_model_to_file(path, *model, config, fullpath_sources, thumbnail_data);
     if (!res)
         exporter.log_errors();
diff --git a/src/libslic3r/Format/3mf.hpp b/src/libslic3r/Format/3mf.hpp
index ccfd9356d..a09a1b834 100644
--- a/src/libslic3r/Format/3mf.hpp
+++ b/src/libslic3r/Format/3mf.hpp
@@ -33,7 +33,7 @@ namespace Slic3r {
 
     // 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
-    extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data = nullptr);
+    extern bool store_3mf(const char* path, Model* model, const DynamicPrintConfig* config, bool fullpath_sources, const ThumbnailData* thumbnail_data = nullptr, bool zip64 = true);
 
 } // namespace Slic3r
 
diff --git a/src/slic3r/Utils/FixModelByWin10.cpp b/src/slic3r/Utils/FixModelByWin10.cpp
index bcab6daaf..7933a1d69 100644
--- a/src/slic3r/Utils/FixModelByWin10.cpp
+++ b/src/slic3r/Utils/FixModelByWin10.cpp
@@ -363,7 +363,7 @@ void fix_model_by_win10_sdk_gui(ModelObject &model_object, int volume_idx)
 				ModelObject *model_object = model.add_object();
 				model_object->add_volume(*volumes[ivolume]);
 				model_object->add_instance();
-				if (!Slic3r::store_3mf(path_src.string().c_str(), &model, nullptr, false)) {
+				if (!Slic3r::store_3mf(path_src.string().c_str(), &model, nullptr, false, nullptr, false)) {
 					boost::filesystem::remove(path_src);
 					throw Slic3r::RuntimeError(L("Export of a temporary 3mf file failed"));
 				}