Просмотр исходного кода

Fix setting new material for stacks

CURA-4204

When a new material is created during project file loading, the material
for each stack is set according to the parent material ID, but actually
the child material should be used. This fix uses a hack to find the
corresponding child material for a stack so when a user chooses to
create a new material during project file loading, the material can be
correctly set.
Lipu Fei 7 лет назад
Родитель
Сommit
d662770b22
1 измененных файлов с 41 добавлено и 21 удалено
  1. 41 21
      plugins/3MFReader/ThreeMFWorkspaceReader.py

+ 41 - 21
plugins/3MFReader/ThreeMFWorkspaceReader.py

@@ -814,29 +814,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
                                 each_extruder_stack.definitionChanges = each_changes_container
 
         if self._resolve_strategies["material"] == "new":
+            # the actual material instance container can have an ID such as
+            #  <material>_<machine>_<variant>
+            # which cannot be determined immediately, so here we use a HACK to find the right new material
+            # instance ID:
+            #  - get the old material IDs for all material
+            #  - find the old material with the longest common prefix in ID, that's the old material
+            #  - update the name by replacing the old prefix with the new
+            #  - find the new material container and set it to the stack
+            old_to_new_material_dict = {}
             for each_material in material_containers:
-                old_material = global_stack.material
-
-                # check if the old material container has been renamed to this material container ID
-                # if the container hasn't been renamed, we do nothing.
-                new_id = self._id_mapping.get(old_material.getId())
-                if new_id is None or new_id != each_material.getId():
-                    continue
-
-                if old_material.getId() in self._id_mapping:
-                    global_stack.material = each_material
-
-                for each_extruder_stack in extruder_stacks:
-                    old_material = each_extruder_stack.material
-
-                    # check if the old material container has been renamed to this material container ID
-                    # if the container hasn't been renamed, we do nothing.
-                    new_id = self._id_mapping.get(old_material.getId())
-                    if new_id is None or new_id != each_material.getId():
-                        continue
+                # find the material's old name
+                for old_id, new_id in self._id_mapping.items():
+                    if each_material.getId() == new_id:
+                        old_to_new_material_dict[old_id] = each_material
+                        break
 
-                    if old_material.getId() in self._id_mapping:
-                        each_extruder_stack.material = each_material
+            # replace old material in global and extruder stacks with new
+            self._replaceStackMaterialWithNew(global_stack, old_to_new_material_dict)
+            for each_extruder_stack in extruder_stacks:
+                self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict)
 
         if extruder_stacks:
             for stack in extruder_stacks:
@@ -861,6 +858,29 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
             nodes = []
         return nodes
 
+    def _replaceStackMaterialWithNew(self, stack, old_new_material_dict):
+        old_material_id_in_stack = stack.material.getId()
+        best_matching_old_material_id = None
+        best_matching_old_meterial_prefix_length = -1
+        for old_parent_material_id in old_new_material_dict:
+            if len(old_parent_material_id) < best_matching_old_meterial_prefix_length:
+                continue
+            if len(old_parent_material_id) <= len(old_material_id_in_stack):
+                if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]:
+                    best_matching_old_meterial_prefix_length = len(old_parent_material_id)
+                    best_matching_old_material_id = old_parent_material_id
+
+        if best_matching_old_material_id is None:
+            return
+
+        new_material_id = old_new_material_dict[best_matching_old_material_id].getId() + old_material_id_in_stack[len(best_matching_old_material_id):]
+        new_material_containers = self._container_registry.findInstanceContainers(id = new_material_id, type = "material")
+        if not new_material_containers:
+            Logger.log("e", "Cannot find new material container [%s]", new_material_id)
+            return
+
+        stack.material = new_material_containers[0]
+
     def _stripFileToId(self, file):
         mime_type = MimeTypeDatabase.getMimeTypeForFile(file)
         file = mime_type.stripExtension(file)