diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 3c4d776df8..41dec309d9 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -142,6 +142,23 @@ class CuraApplication(QtApplication): ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.UserInstanceContainer) ContainerRegistry.getInstance().addResourceType(self.ResourceTypes.MachineStack) + # Add empty variant, material and quality containers. + # Since they are empty, they should never be serialized and instead just programmatically created. + # We need them to simplify the switching between materials. + empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() + empty_variant_container = copy.deepcopy(empty_container) + empty_variant_container._id = "empty_variant" + empty_variant_container.addMetaDataEntry("type", "variant") + ContainerRegistry.getInstance().addContainer(empty_variant_container) + empty_material_container = copy.deepcopy(empty_container) + empty_material_container._id = "empty_material" + empty_material_container.addMetaDataEntry("type", "material") + ContainerRegistry.getInstance().addContainer(empty_material_container) + empty_quality_container = copy.deepcopy(empty_container) + empty_quality_container._id = "empty_quality" + empty_quality_container.addMetaDataEntry("type", "quality") + ContainerRegistry.getInstance().addContainer(empty_quality_container) + ContainerRegistry.getInstance().load() Preferences.getInstance().addPreference("cura/active_mode", "simple") diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index c3b57ca8d0..4bd42c9c9d 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -22,6 +22,10 @@ class MachineManagerModel(QObject): self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) + self._empty_variant_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_variant")[0] + self._empty_material_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_material")[0] + self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] + Preferences.getInstance().addPreference("cura/active_machine", "") active_machine_id = Preferences.getInstance().getValue("cura/active_machine") @@ -74,28 +78,26 @@ class MachineManagerModel(QObject): new_global_stack.addMetaDataEntry("type", "machine") UM.Settings.ContainerRegistry.getInstance().addContainer(new_global_stack) - empty_container = UM.Settings.ContainerRegistry.getInstance().getEmptyInstanceContainer() - - variant_instance_container = empty_container + variant_instance_container = self._empty_variant_container if definition.getMetaDataEntry("has_variants"): - variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", empty_container) + variant_instance_container = self._getPreferredContainer(definition, "preferred_variant", self._empty_variant_container) - if variant_instance_container == empty_container: + if variant_instance_container == self._empty_variant_container: variants = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = definition.id) if variants: variant_instance_container = variants[0] - if variant_instance_container == empty_container: + if variant_instance_container == self._empty_variant_container: Logger.log("w", "Machine %s defines it has variants but no variants found", definition.id) - material_instance_container = empty_container + material_instance_container = self._empty_material_container if definition.getMetaDataEntry("has_materials"): - material_instance_container = self._getPreferredContainer(definition, "preferred_material", empty_container) + material_instance_container = self._getPreferredContainer(definition, "preferred_material", self._empty_material_container) - if material_instance_container == empty_container: + if material_instance_container == self._empty_material_container: materials = None if definition.getMetaDataEntry("has_machine_materials"): - if variant_instance_container != empty_container: + if variant_instance_container != self._empty_material_container: materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id, variant = variant_instance_container.id) else: materials = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition.id) @@ -105,9 +107,11 @@ class MachineManagerModel(QObject): if materials: material_instance_container = materials[0] - quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", empty_container) + if material_instance_container == self._empty_material_container: + Logger.log("w", "Machine %s defines it has materials but no matererials found", definition.id) - if quality_instance_container == empty_container: + quality_instance_container = self._getPreferredContainer(definition, "preferred_quality", self._empty_quality_container) + if quality_instance_container == self._empty_quality_container: if definition.getMetaDataEntry("has_machine_quality"): if material_instance_container: qualities = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "quality", definition = definition.id, material = material_instance_container.id) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 0851261877..dee6f2b64c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -51,6 +51,20 @@ class StartSliceJob(Job): def getSliceMessage(self): return self._slice_message + ## Check if a stack has any errors. + ## returns true if it has errors, false otherwise. + def _checkStackForErrors(self, stack): + if stack is None: + return False + + for key in stack.getAllKeys(): + validation_state = stack.getProperty(key, "validationState") + if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + return True + Job.yieldThread() + return False + ## Runs the job that initiates the slicing. def run(self): stack = Application.getInstance().getGlobalContainerStack() @@ -59,30 +73,18 @@ class StartSliceJob(Job): return # Don't slice if there is a setting with an error value. - for key in stack.getAllKeys(): - validation_state = stack.getProperty(key, "validationState") - if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): - Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - self.setResult(StartJobResult.SettingError) - return - - Job.yieldThread() + if self._checkStackForErrors(stack): + self.setResult(StartJobResult.SettingError) + return # Don't slice if there is a per object setting with an error value. for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is not SceneNode or not node.isSelectable(): continue - node_stack = node.callDecoration("getStack") - if node_stack: - for key in node_stack.getAllKeys(): - validation_state = node_stack.getProperty(key, "validationState") - if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError): - Logger.log("w", "Per object setting %s is not valid, but %s. Aborting slicing.", key, validation_state) - self.setResult(StartJobResult.SettingError) - return - - Job.yieldThread() + if self._checkStackForErrors(node.callDecoration("getStack")): + self.setResult(StartJobResult.SettingError) + return with self._scene.getSceneLock(): # Remove old layer data.