From 92389365b693b27f99782c154c3b3a0888bd1cab Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Sep 2016 16:36:45 +0200 Subject: [PATCH 01/10] If a machine inherits qualities, it tries to select the correct variant ID's as well CURA-2424 --- cura/Settings/MachineManager.py | 7 +++---- resources/qml/Menus/NozzleMenu.qml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 450e7606b9..ec8b423007 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -860,14 +860,13 @@ class MachineManager(QObject): def _updateVariantContainer(self, definition): if not definition.getMetaDataEntry("has_variants"): return self._empty_variant_container - + machine_definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(definition) containers = [] preferred_variant = definition.getMetaDataEntry("preferred_variant") if preferred_variant: - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id, id = preferred_variant) - + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id, id = preferred_variant) if not containers: - containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id) if containers: return containers[0] diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index f377690219..44f8cc8c85 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -52,7 +52,7 @@ Menu filter: { "type": "variant", - "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine + "definition": Cura.MachineManager.activeQualityDefinitionId //Only show variants of this machine } } MenuItem { From 46dd4f6093e393938a8a51679d3e4e2f466d5576 Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Wed, 21 Sep 2016 16:50:57 +0200 Subject: [PATCH 02/10] Fix for duplicating quality changes profiles on the UM2. Contributes to CURA-2414 Quality changes profiles are created incorrectly --- cura/QualityManager.py | 2 +- cura/Settings/ContainerManager.py | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 9d7eac8a05..1ef79f2b86 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -83,7 +83,7 @@ class QualityManager: filter_by_material = machine_definition.getMetaDataEntry("has_materials") # Stick the material IDs in a set - if material_containers is None: + if material_containers is None or len(material_containers) == 0: filter_by_material = False else: material_ids = set() diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index a0648587c2..0ef2660549 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -587,24 +587,17 @@ class ContainerManager(QObject): def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances): UM.Logger.log("d", "Attempting to duplicate the quality %s", quality_name) - # Try Quality + if base_name is None: + base_name = quality_name + + # Try to find a Quality with the name. containers = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances) if containers: container = containers[0] - if base_name is None: - base_name = quality_name return self._duplicateQualityForMachineType(container, base_name, machine_definition) - # Try quality changes. - containers = QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition, material_instances) - if containers: - container = containers[0] - if base_name is None: - base_name = quality_name - return self._duplicateQualityChangesForMachineType(container, base_name, machine_definition) - else: - UM.Logger.log("d", "Unable to duplicate the quality %s, because it doesn't exist.", quality_name) - return "" + # Assume it is a quality changes. + return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition) # Duplicate a quality profile def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition): @@ -631,10 +624,10 @@ class ContainerManager(QObject): return new_change_instances # Duplicate a quality changes container - def _duplicateQualityChangesForMachineType(self, quality_changes_container, base_name, machine_definition): + def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition): new_change_instances = [] - for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_container.getName(), - machine_definition, None): + for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name, + machine_definition, []): new_unique_id = self._createUniqueId(container.getId(), base_name) new_container = container.duplicate(new_unique_id, base_name) new_change_instances.append(new_container) From a94d98dfed831828811ca61085525c62162ca45e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 21 Sep 2016 17:28:38 +0200 Subject: [PATCH 03/10] X3D reader no longer creates critical exceptions in the rest of cura CURA-2083 --- plugins/X3DReader/X3DReader.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/plugins/X3DReader/X3DReader.py b/plugins/X3DReader/X3DReader.py index f1c217da9d..4ce21f3f8c 100644 --- a/plugins/X3DReader/X3DReader.py +++ b/plugins/X3DReader/X3DReader.py @@ -78,12 +78,17 @@ class X3DReader(MeshReader): builder.setIndices(numpy.concatenate([shape.faces for shape in self.shapes])) builder.calculateNormals() builder.setFileName(file_name) - - scene = SceneNode() - scene.setMeshData(builder.build()) - scene.setSelectable(True) - scene.setName(file_name) - scene.getBoundingBox() + mesh_data = builder.build() + + # Manually try and get the extents of the mesh_data. This should prevent nasty NaN issues from + # leaving the reader. + mesh_data.getExtents() + + node = SceneNode() + node.setMeshData(mesh_data) + node.setSelectable(True) + node.setName(file_name) + else: return None @@ -91,7 +96,7 @@ class X3DReader(MeshReader): Logger.logException("e", "Exception in X3D reader") return None - return scene + return node # ------------------------- XML tree traversal From 9501f9b17c93ba260de324dafea7526b4bda71fc Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 14:36:25 +0200 Subject: [PATCH 04/10] Make VersionUpgradeManager a singleton This way we can access the manager from anywhere, without adding a getter to CuraApplication or something. Contributes to issue CURA-844. --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a4d2043146..702f8d6078 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -112,7 +112,7 @@ class CuraApplication(QtApplication): ## Initialise the version upgrade manager with Cura's storage paths. import UM.VersionUpgradeManager #Needs to be here to prevent circular dependencies. - self._version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager( + UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions( { ("quality", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"), ("machine_stack", UM.Settings.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"), From c1a593c3d8d1500452790d4dd51efad7817ab408 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 17:07:37 +0200 Subject: [PATCH 05/10] Create new user profile upon upgrading machine instance This defines a new configuration type: 'user', for the user profile. Contributes to issue CURA-844. --- cura/CuraApplication.py | 3 ++- .../VersionUpgrade21to22/MachineInstance.py | 24 ++++++++++++++++++- .../VersionUpgrade21to22/__init__.py | 4 ++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 702f8d6078..7e6ef472c0 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -116,7 +116,8 @@ class CuraApplication(QtApplication): { ("quality", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"), ("machine_stack", UM.Settings.ContainerStack.Version): (self.ResourceTypes.MachineStack, "application/x-uranium-containerstack"), - ("preferences", UM.Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences") + ("preferences", UM.Preferences.Version): (Resources.Preferences, "application/x-uranium-preferences"), + ("user", UM.Settings.InstanceContainer.Version): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer") } ) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 6510d34cb1..4ceecee83d 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -2,9 +2,11 @@ # Cura is released under the terms of the AGPLv3 or higher. import UM.VersionUpgrade #To indicate that a file is of incorrect format. +import UM.VersionUpgradeManager #To schedule more files to be upgraded. import configparser #To read config files. import io #To write config files to strings as if they were files. +import os.path #To get the path to write new user profiles to. ## Creates a new machine instance instance by parsing a serialised machine # instance in version 1 of the file format. @@ -92,8 +94,28 @@ class MachineInstance: if has_machine_qualities: #This machine now has machine-quality profiles. active_material += "_" + variant_materials #That means that the profile was split into multiple. + #Create a new user profile and schedule it to be upgraded. + user_profile = configparser.ConfigParser(interpolation = None) + user_profile["general"] = { + "version": "2", + "name": self._name + "_current_settings", + "definition": type_name + } + user_profile["metadata"] = { + "type": "user", + "machine": self._name + } + user_profile["values"] = {} + + version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() + user_storage = next(iter(version_upgrade_manager.getStoragePaths("user"))) + user_profile_file = os.path.join(user_storage, self._name + "_current_settings") + with open(user_profile_file, "w") as file_handle: + user_profile.write(file_handle) + version_upgrade_manager.upgradeExtraFile(user_storage, self._name + "_current_settings", "user") + containers = [ - "", #The current profile doesn't know the definition ID when it was upgraded, only the instance ID, so it will be invalid. Sorry, your current settings are lost now. + self._name + "_current_settings", #The current profile doesn't know the definition ID when it was upgraded, only the instance ID, so it will be invalid. Sorry, your current settings are lost now. active_quality_changes, active_quality, active_material, diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py index 86cfda6b90..f2803ca62f 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py @@ -35,6 +35,10 @@ def getMetaData(): "preferences": { "get_version": upgrade.getCfgVersion, "location": {"."} + }, + "user": { + "get_version": upgrade.getCfgVersion, + "location": {"./user"} } } } From d962cad347f8defcdc656abb4a1599d72dac025a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 17:21:44 +0200 Subject: [PATCH 06/10] Ensure directory exists to store user profile in Create it if it doesn't exist. Also fix up the directory to be absolute instead of relative. Contributes to issue CURA-844. --- .../VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 4ceecee83d..d78e7152c6 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -3,6 +3,7 @@ import UM.VersionUpgrade #To indicate that a file is of incorrect format. import UM.VersionUpgradeManager #To schedule more files to be upgraded. +import UM.Resources #To get the config storage path. import configparser #To read config files. import io #To write config files to strings as if they were files. @@ -108,8 +109,10 @@ class MachineInstance: user_profile["values"] = {} version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() - user_storage = next(iter(version_upgrade_manager.getStoragePaths("user"))) + user_storage = os.path.join(UM.Resources.getDataStoragePath(), next(iter(version_upgrade_manager.getStoragePaths("user")))) user_profile_file = os.path.join(user_storage, self._name + "_current_settings") + if not os.path.exists(user_storage): + os.makedirs(user_storage) with open(user_profile_file, "w") as file_handle: user_profile.write(file_handle) version_upgrade_manager.upgradeExtraFile(user_storage, self._name + "_current_settings", "user") From 7d41c1dcb38f36e1cca5a4a4d27d1ebff2964988 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 17:26:12 +0200 Subject: [PATCH 07/10] Give canonical name to user settings All user profiles are named Current settings, so we should just give it the same name as well. Contributes to issue CURA-844. --- plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index d78e7152c6..bd174bea43 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -99,7 +99,7 @@ class MachineInstance: user_profile = configparser.ConfigParser(interpolation = None) user_profile["general"] = { "version": "2", - "name": self._name + "_current_settings", + "name": "Current settings", "definition": type_name } user_profile["metadata"] = { From ebb95070834d7946bb3aacc20fc52685a1791fe3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 17:29:08 +0200 Subject: [PATCH 08/10] Add extension to new file The upgrade plug-in can do this because he know that he's upgrading to version 2.3. Contributes to issue CURA-844. --- plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index bd174bea43..71646b45f7 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -110,7 +110,7 @@ class MachineInstance: version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() user_storage = os.path.join(UM.Resources.getDataStoragePath(), next(iter(version_upgrade_manager.getStoragePaths("user")))) - user_profile_file = os.path.join(user_storage, self._name + "_current_settings") + user_profile_file = os.path.join(user_storage, self._name + "_current_settings.inst.cfg") if not os.path.exists(user_storage): os.makedirs(user_storage) with open(user_profile_file, "w") as file_handle: From 3f85ac264c7b673c3db5fb0a83509136098aac61 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 21 Sep 2016 17:34:13 +0200 Subject: [PATCH 09/10] Properly serialise the machine instance name Otherwise we get spaces and unescaped plusses in the file name of the user profile. Contributes to issue CURA-844. --- .../VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 71646b45f7..222af84d3a 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -8,6 +8,7 @@ import UM.Resources #To get the config storage path. import configparser #To read config files. import io #To write config files to strings as if they were files. import os.path #To get the path to write new user profiles to. +import urllib #To serialise the user container file name properly. ## Creates a new machine instance instance by parsing a serialised machine # instance in version 1 of the file format. @@ -110,12 +111,12 @@ class MachineInstance: version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() user_storage = os.path.join(UM.Resources.getDataStoragePath(), next(iter(version_upgrade_manager.getStoragePaths("user")))) - user_profile_file = os.path.join(user_storage, self._name + "_current_settings.inst.cfg") + user_profile_file = os.path.join(user_storage, urllib.parse.quote_plus(self._name) + "_current_settings.inst.cfg") if not os.path.exists(user_storage): os.makedirs(user_storage) with open(user_profile_file, "w") as file_handle: user_profile.write(file_handle) - version_upgrade_manager.upgradeExtraFile(user_storage, self._name + "_current_settings", "user") + version_upgrade_manager.upgradeExtraFile(user_storage, urllib.parse.quote_plus(self._name), "user") containers = [ self._name + "_current_settings", #The current profile doesn't know the definition ID when it was upgraded, only the instance ID, so it will be invalid. Sorry, your current settings are lost now. From d8b1486637636142e2c082c2e31903b8f6d97360 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Wed, 21 Sep 2016 17:54:47 +0200 Subject: [PATCH 10/10] doc: better documentation of limit_to_extruder and resolve properties in the JSON (CURA-2308) --- cura/CuraApplication.py | 9 +++++++++ plugins/CuraEngineBackend/Cura.proto | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7e6ef472c0..09f04d9a2d 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -86,10 +86,19 @@ class CuraApplication(QtApplication): # Need to do this before ContainerRegistry tries to load the machines SettingDefinition.addSupportedProperty("settable_per_mesh", DefinitionPropertyType.Any, default = True, read_only = True) SettingDefinition.addSupportedProperty("settable_per_extruder", DefinitionPropertyType.Any, default = True, read_only = True) + # this setting can be changed for each group in one-at-a-time mode SettingDefinition.addSupportedProperty("settable_per_meshgroup", DefinitionPropertyType.Any, default = True, read_only = True) SettingDefinition.addSupportedProperty("settable_globally", DefinitionPropertyType.Any, default = True, read_only = True) + + # From which stack the setting would inherit if not defined per object (handled in the engine) + # AND for settings which are not settable_per_mesh: + # which extruder is the only extruder this setting is obtained from SettingDefinition.addSupportedProperty("limit_to_extruder", DefinitionPropertyType.Function, default = "-1") + + # For settings which are not settable_per_mesh and not settable_per_extruder: + # A function which determines the glabel/meshgroup value by looking at the values of the setting in all (used) extruders SettingDefinition.addSupportedProperty("resolve", DefinitionPropertyType.Function, default = None) + SettingDefinition.addSettingType("extruder", None, str, Validator) SettingFunction.registerOperator("extruderValues", cura.Settings.ExtruderManager.getExtruderValues) diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index d5407f22c8..4eab500f0a 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -13,7 +13,7 @@ message Slice repeated ObjectList object_lists = 1; // The meshgroups to be printed one after another SettingList global_settings = 2; // The global settings used for the whole print job repeated Extruder extruders = 3; // The settings sent to each extruder object - repeated SettingExtruder limit_to_extruder = 4; //From which stack the setting would inherit if not defined in a stack. + repeated SettingExtruder limit_to_extruder = 4; // From which stack the setting would inherit if not defined per object } message Extruder