diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 060617875d..a6bc2e4a8c 100644 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -158,6 +158,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): self._container_registry.addContainer(definition_container) Logger.log("d", "Workspace loading is checking materials...") + material_containers = [] # Get all the material files and check if they exist. If not, add them. xml_material_profile = self._getXmlProfileClass() if self._material_container_suffix is None: @@ -172,8 +173,16 @@ class ThreeMFWorkspaceReader(WorkspaceReader): material_container.deserialize(archive.open(material_container_file).read().decode("utf-8")) self._container_registry.addContainer(material_container) else: - pass - + if not materials[0].isReadOnly(): # Only create new materials if they are not read only. + if self._resolve_strategies["material"] == "override": + materials[0].deserialize(archive.open(material_container_file).read().decode("utf-8")) + elif self._resolve_strategies["material"] == "new": + # Note that we *must* deserialize it with a new ID, as multiple containers will be + # auto created & added. + material_container = xml_material_profile(self.getNewId(container_id)) + material_container.deserialize(archive.open(material_container_file).read().decode("utf-8")) + self._container_registry.addContainer(material_container) + material_containers.append(material_container) Logger.log("d", "Workspace loading is checking instance containers...") # Get quality_changes and user profiles saved in the workspace @@ -311,6 +320,21 @@ class ThreeMFWorkspaceReader(WorkspaceReader): quality_changes_index = stack.getContainerIndex(old_container) stack.replaceContainer(quality_changes_index, container) + if self._resolve_strategies["material"] == "new": + for material in material_containers: + old_material = global_stack.findContainer({"type": "material"}) + if old_material.getId() in self._id_mapping: + material_index = global_stack.getContainerIndex(old_material) + global_stack.replaceContainer(material_index, material) + continue + + for stack in extruder_stacks: + old_material = stack.findContainer({"type": "material"}) + if old_material.getId() in self._id_mapping: + material_index = stack.getContainerIndex(old_material) + stack.replaceContainer(material_index, material) + continue + for stack in extruder_stacks: ExtruderManager.getInstance().registerExtruder(stack, global_stack.getId()) else: diff --git a/plugins/3MFReader/WorkspaceDialog.qml b/plugins/3MFReader/WorkspaceDialog.qml index 4120c5b61e..cdefd9a4b0 100644 --- a/plugins/3MFReader/WorkspaceDialog.qml +++ b/plugins/3MFReader/WorkspaceDialog.qml @@ -128,7 +128,7 @@ UM.Dialog width: parent.width height: visible ? 25 : 0 text: catalog.i18nc("@info:tooltip", "How should the conflict in the material(s) be resolved?") - visible: false //manager.materialConflict + visible: manager.materialConflict Row { width: parent.width diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 07acc5c37c..94f7368ab0 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -340,10 +340,22 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): mapping[key] = element first.append(element) + def clearData(self): + self._metadata = {} + self._name = "" + self._definition = None + self._instances = {} + self._read_only = False + self._dirty = False + self._path = "" + ## Overridden from InstanceContainer def deserialize(self, serialized): data = ET.fromstring(serialized) + # Reset previous metadata + self.clearData() # Ensure any previous data is gone. + self.addMetaDataEntry("type", "material") self.addMetaDataEntry("base_file", self.id) @@ -445,7 +457,16 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): definition = definitions[0] if machine_compatibility: - new_material = XmlMaterialProfile(self.id + "_" + machine_id) + new_material_id = self.id + "_" + machine_id + + # It could be that we are overwriting, so check if the ID already exists. + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=new_material_id) + if materials: + new_material = materials[0] + new_material.clearData() + else: + new_material = XmlMaterialProfile(new_material_id) + new_material.setName(self.getName()) new_material.setMetaData(copy.deepcopy(self.getMetaData())) new_material.setDefinition(definition) @@ -459,9 +480,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): new_material.setProperty(key, "value", value, definition) new_material._dirty = False - - UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) - + if not materials: + UM.Settings.ContainerRegistry.getInstance().addContainer(new_material) hotends = machine.iterfind("./um:hotend", self.__namespaces) for hotend in hotends: @@ -491,7 +511,15 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): else: Logger.log("d", "Unsupported material setting %s", key) - new_hotend_material = XmlMaterialProfile(self.id + "_" + machine_id + "_" + hotend_id.replace(" ", "_")) + # It could be that we are overwriting, so check if the ID already exists. + new_hotend_id = self.id + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id=new_hotend_id) + if materials: + new_hotend_material = materials[0] + new_hotend_material.clearData() + else: + new_hotend_material = XmlMaterialProfile(new_hotend_id) + new_hotend_material.setName(self.getName()) new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) new_hotend_material.setDefinition(definition) @@ -509,7 +537,8 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): new_hotend_material.setProperty(key, "value", value, definition) new_hotend_material._dirty = False - UM.Settings.ContainerRegistry.getInstance().addContainer(new_hotend_material) + if not materials: # It was not added yet, do so now. + UM.Settings.ContainerRegistry.getInstance().addContainer(new_hotend_material) def _addSettingElement(self, builder, instance): try: