From 3148027fbe7b0e70a0ab1dbc4733d85470aad674 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 23 Nov 2017 12:43:14 +0100 Subject: [PATCH 1/2] Fix version upgrade for quality_changes CURA-4613 Explained in the code comments. --- .../VersionUpgrade30to31/VersionUpgrade30to31.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py index 7b788f96ba..c496a66b29 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py @@ -116,7 +116,10 @@ class VersionUpgrade30to31(VersionUpgrade): all_quality_changes = self._getSingleExtrusionMachineQualityChanges(parser) # Note that DO NOT!!! use the quality_changes returned from _getSingleExtrusionMachineQualityChanges(). # Those are loaded from the hard drive which are original files that haven't been upgraded yet. - if len(all_quality_changes) == 1 and not parser.has_option("metadata", "extruder"): + # NOTE 2: The number can be 0 or 1 depends on whether you are loading it from the qualities folder or + # from a project file. When you load from a project file, the custom profile may not be in cura + # yet, so you will get 0. + if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"): self._createExtruderQualityChangesForSingleExtrusionMachine(filename, parser) # Update version numbers @@ -199,7 +202,7 @@ class VersionUpgrade30to31(VersionUpgrade): def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes): suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower()) - machine_name = filename.strip("." + os.sep).replace(suffix, "") + machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "") new_filename = machine_name + "_" + "fdmextruder" + suffix extruder_quality_changes_parser = configparser.ConfigParser() From 17f09ec21e57cbb45e207b3682c3d8489dab19f1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 23 Nov 2017 12:46:32 +0100 Subject: [PATCH 2/2] Fix variant/material/quality handling in stacks CURA-4613 --- cura/Settings/CuraContainerRegistry.py | 75 ++++++++++++++++++++++++-- cura/Settings/CuraContainerStack.py | 17 ++++-- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 1674405824..543678ee22 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -4,6 +4,7 @@ import os import os.path import re +import configparser from typing import Optional @@ -19,6 +20,7 @@ from UM.Message import Message from UM.Platform import Platform from UM.PluginRegistry import PluginRegistry # For getting the possible profile writers to write with. from UM.Util import parseBool +from UM.Resources import Resources from . import ExtruderStack from . import GlobalStack @@ -444,21 +446,84 @@ class CuraContainerRegistry(ContainerRegistry): self.addContainer(user_container) variant_id = "default" - if machine.variant.getId() != "empty_variant": + if machine.variant.getId() not in ("empty", "empty_variant"): variant_id = machine.variant.getId() + else: + variant_id = "empty_variant" extruder_stack.setVariantById(variant_id) - extruder_stack.setMaterialById("default") - extruder_stack.setQualityById("default") - if machine.qualityChanges.getId() != "empty_quality_changes": + + material_id = "default" + if machine.material.getId() not in ("empty", "empty_material"): + # TODO: find the ID that's suitable for this extruder + pass + else: + material_id = "empty_material" + extruder_stack.setMaterialById(material_id) + + quality_id = "default" + if machine.quality.getId() not in ("empty", "empty_quality"): + # TODO: find the ID that's suitable for this extruder + pass + else: + quality_id = "empty_quality" + extruder_stack.setQualityById(quality_id) + + if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"): extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id) if extruder_quality_changes_container: - quality_changes_id = extruder_quality_changes_container[0].getId() + extruder_quality_changes_container = extruder_quality_changes_container[0] + quality_changes_id = extruder_quality_changes_container.getId() extruder_stack.setQualityChangesById(quality_changes_id) + else: + # Some extruder quality_changes containers can be created at runtime as files in the qualities + # folder. Those files won't be loaded in the registry immediately. So we also need to search + # the folder to see if the quality_changes exists. + extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName()) + if extruder_quality_changes_container: + quality_changes_id = extruder_quality_changes_container.getId() + extruder_stack.setQualityChangesById(quality_changes_id) + + if not extruder_quality_changes_container: + Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]", + machine.qualityChanges.getName(), extruder_stack.getId()) self.addContainer(extruder_stack) return extruder_stack + def _findQualityChangesContainerInCuraFolder(self, name): + quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) + + instance_container = None + + for item in os.listdir(quality_changes_dir): + file_path = os.path.join(quality_changes_dir, item) + if not os.path.isfile(file_path): + continue + + parser = configparser.ConfigParser() + try: + parser.read([file_path]) + except: + # skip, it is not a valid stack file + continue + + if not parser.has_option("general", "name"): + continue + + if parser["general"]["name"] == name: + # load the container + container_id = os.path.basename(file_path).replace(".inst.cfg", "") + + instance_container = InstanceContainer(container_id) + with open(file_path, "r") as f: + serialized = f.read() + instance_container.deserialize(serialized, file_path) + self.addContainer(instance_container) + break + + return instance_container + # Fix the extruders that were upgraded to ExtruderStack instances during addContainer. # The stacks are now responsible for setting the next stack on deserialize. However, # due to problems with loading order, some stacks may not have the proper next stack diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 9bbea044cf..156883ade3 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -41,9 +41,20 @@ class CuraContainerStack(ContainerStack): def __init__(self, container_id: str, *args, **kwargs): super().__init__(container_id, *args, **kwargs) - self._empty_instance_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + self._container_registry = ContainerRegistry.getInstance() + + self._empty_instance_container = self._container_registry.getEmptyInstanceContainer() + + self._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] + self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] + self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] + self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0] self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] + self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes + self._containers[_ContainerIndexes.Quality] = self._empty_quality + self._containers[_ContainerIndexes.Material] = self._empty_material + self._containers[_ContainerIndexes.Variant] = self._empty_variant self.containersChanged.connect(self._onContainersChanged) @@ -456,7 +467,7 @@ class CuraContainerStack(ContainerStack): else: search_criteria["definition"] = "fdmprinter" - if self.material != self._empty_instance_container: + if self.material != self._empty_material: search_criteria["name"] = self.material.name else: preferred_material = definition.getMetaDataEntry("preferred_material") @@ -503,7 +514,7 @@ class CuraContainerStack(ContainerStack): else: search_criteria["definition"] = "fdmprinter" - if self.quality != self._empty_instance_container: + if self.quality != self._empty_quality: search_criteria["name"] = self.quality.name else: preferred_quality = definition.getMetaDataEntry("preferred_quality")