Browse Source

Before this change packages were only being checked if they were bundled after loading the package_id. However only installed packages were being loaded so this would always be false.

The solution here is to check first if a material file is inside "secure_paths" (these are install directory resource paths). If it is, it must be a bundled material.

CURA-8610
j.delarago 2 years ago
parent
commit
71a817697b
2 changed files with 25 additions and 3 deletions
  1. 20 0
      cura/CuraPackageManager.py
  2. 5 3
      plugins/3MFWriter/ThreeMFWriter.py

+ 20 - 0
cura/CuraPackageManager.py

@@ -1,7 +1,9 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
+import glob
 import os
 
+from pathlib import Path
 from typing import Any, cast, Dict, List, Set, Tuple, TYPE_CHECKING, Optional
 
 from UM.Logger import Logger
@@ -55,6 +57,24 @@ class CuraPackageManager(PackageManager):
 
         super().initialize()
 
+    def isMaterialBundled(self, file_name: str, guid: str):
+        """ Check if there is a bundled material name with file_name and guid """
+        for path in Resources.getSecureSearchPaths():
+            paths = [Path(p) for p in glob.glob(path + '/**/*.xml.fdm_material')]
+            for material in paths:
+                if material.name == file_name:
+                    with open(str(material), encoding="utf-8") as f:
+                        # Make sure the file we found has the same guid as our material
+                        # Parsing this xml would be better but the namespace is needed to search it.
+                        parsed_guid = PluginRegistry.getInstance().getPluginObject(
+                            "XmlMaterialProfile").getMetadataFromSerialized(
+                            f.read(), "GUID")
+                        if guid == parsed_guid:
+                            # The material we found matches both filename and GUID
+                            return True
+
+        return False
+
     def getMaterialFilePackageId(self, file_name: str, guid: str) -> str:
         """Get the id of the installed material package that contains file_name"""
         for material_package in [f for f in os.scandir(self._installation_dirs_dict["materials"]) if f.is_dir()]:

+ 5 - 3
plugins/3MFWriter/ThreeMFWriter.py

@@ -267,10 +267,15 @@ class ThreeMFWriter(MeshWriter):
                 # Don't export materials not in use
                 continue
 
+            if package_manager.isMaterialBundled(extruder.material.getFileName(), extruder.material.getMetaDataEntry("GUID")):
+                # Don't export bundled materials
+                continue
+
             package_id = package_manager.getMaterialFilePackageId(extruder.material.getFileName(), extruder.material.getMetaDataEntry("GUID"))
             package_data = package_manager.getInstalledPackageInfo(package_id)
 
             if not package_data:
+                # We failed to find the package for this material
                 message = Message(catalog.i18nc("@error:material",
                                                 "It was not possible to store material package information in project file: {material}. This project may not open correctly on other systems.".format(material=extruder.getName())),
                                   title=catalog.i18nc("@info:title", "Failed to save material package information"),
@@ -278,9 +283,6 @@ class ThreeMFWriter(MeshWriter):
                 message.show()
                 continue
 
-            if package_data.get("is_bundled"):
-                continue
-
             material_metadata = {"id": package_id,
                                  "display_name": package_data.get("display_name") if package_data.get("display_name") else "",
                                  "package_version": package_data.get("package_version") if package_data.get("package_version") else "",