CURA-4400 set extruder numbers of settings to an enabled extruder; added SettingOverrideDecorator by default in CuraSceneNode

This commit is contained in:
Jack Ha 2018-02-28 15:50:37 +01:00
parent f28bed9b4f
commit 11bad271d3
4 changed files with 67 additions and 22 deletions

View file

@ -1,9 +1,12 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from copy import deepcopy
from typing import List from typing import List
from UM.Application import Application from UM.Application import Application
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from copy import deepcopy
from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
## Scene nodes that are models are only seen when selecting the corresponding build plate ## Scene nodes that are models are only seen when selecting the corresponding build plate
@ -11,6 +14,8 @@ from cura.Settings.ExtrudersModel import ExtrudersModel
class CuraSceneNode(SceneNode): class CuraSceneNode(SceneNode):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if "no_setting_override" not in kwargs:
self.addDecorator(SettingOverrideDecorator()) # now we always have a getActiveExtruderPosition, unless explicitly disabled
self._outside_buildarea = False self._outside_buildarea = False
def setOutsideBuildArea(self, new_value): def setOutsideBuildArea(self, new_value):

View file

@ -52,6 +52,8 @@ class MachineManager(QObject):
self._current_quality_group = None self._current_quality_group = None
self._current_quality_changes_group = None self._current_quality_changes_group = None
self._default_extruder_position = "0" # to be updated when extruders are switched on and off
self.machine_extruder_material_update_dict = collections.defaultdict(list) self.machine_extruder_material_update_dict = collections.defaultdict(list)
self._error_check_timer = QTimer() self._error_check_timer = QTimer()
@ -696,6 +698,39 @@ class MachineManager(QObject):
if containers: if containers:
return containers[0].definition.getId() return containers[0].definition.getId()
## Update extruder number to a valid value when the number of extruders are changed, or when an extruder is changed
def correctExtruderSettings(self):
definition_changes_container = self._global_container_stack.definitionChanges
extruder_count = definition_changes_container.getProperty("machine_extruder_count", "value")
# reset all extruder number settings whose value is no longer valid
for setting_instance in self._global_container_stack.userChanges.findInstances():
setting_key = setting_instance.definition.key
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
continue
old_value = self._global_container_stack.userChanges.getProperty(setting_key, "value")
if int(old_value) >= extruder_count:
self._global_container_stack.userChanges.removeInstance(setting_key)
Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid", setting_key, old_value)
if not self._global_container_stack.extruders[str(old_value)].isEnabled:
self._global_container_stack.userChanges.removeInstance(setting_key)
Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid (2)", setting_key, old_value)
for setting_key in self._global_container_stack.definition.getAllKeys():
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
continue
if setting_key == "support_infill_extruder_nr":
print("asdf")
current_value = self._global_container_stack.getProperty(setting_key, "value")
if current_value is None:
continue
if current_value == "-1":
continue
if not self._global_container_stack.extruders[str(current_value)].isEnabled:
self._global_container_stack.userChanges.setProperty(setting_key, "value", str(self._default_extruder_position))
Logger.log("d", "Change [%s] to [%s] because its value [%s] is not valid", setting_key, self._default_extruder_position, current_value)
## Set the amount of extruders on the active machine (global stack) ## Set the amount of extruders on the active machine (global stack)
# \param extruder_count int the number of extruders to set # \param extruder_count int the number of extruders to set
def setActiveMachineExtruderCount(self, extruder_count): def setActiveMachineExtruderCount(self, extruder_count):
@ -709,16 +744,10 @@ class MachineManager(QObject):
if extruder_count == previous_extruder_count: if extruder_count == previous_extruder_count:
return return
# reset all extruder number settings whose value is no longer valid definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
for setting_instance in self._global_container_stack.userChanges.findInstances():
setting_key = setting_instance.definition.key
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
continue
old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value")) self.updateDefaultExtruder()
if old_value >= extruder_count: self.correctExtruderSettings()
self._global_container_stack.userChanges.removeInstance(setting_key)
Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value)
# Check to see if any objects are set to print with an extruder that will no longer exist # Check to see if any objects are set to print with an extruder that will no longer exist
root_node = Application.getInstance().getController().getScene().getRoot() root_node = Application.getInstance().getController().getScene().getRoot()
@ -729,8 +758,6 @@ class MachineManager(QObject):
if extruder_nr is not None and int(extruder_nr) > extruder_count - 1: if extruder_nr is not None and int(extruder_nr) > extruder_count - 1:
node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId()) node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId())
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
# Make sure one of the extruder stacks is active # Make sure one of the extruder stacks is active
extruder_manager.setActiveExtruderIndex(0) extruder_manager.setActiveExtruderIndex(0)
@ -765,11 +792,26 @@ class MachineManager(QObject):
extruder = self._global_container_stack.extruders.get(str(position)) extruder = self._global_container_stack.extruders.get(str(position))
return extruder return extruder
def updateDefaultExtruder(self):
extruder_items = sorted(self._global_container_stack.extruders.items())
new_default_position = "0"
for position, extruder in extruder_items:
if extruder.isEnabled:
new_default_position = position
break
self._default_extruder_position = new_default_position
@pyqtProperty(str, notify = extruderChanged)
def defaultExtruderPosition(self):
return self._default_extruder_position
@pyqtSlot(int, bool) @pyqtSlot(int, bool)
def setExtruderEnabled(self, position: int, enabled) -> None: def setExtruderEnabled(self, position: int, enabled) -> None:
extruder = self.getExtruder(position) extruder = self.getExtruder(position)
extruder.setEnabled(enabled) extruder.setEnabled(enabled)
if enabled == False:
self.updateDefaultExtruder()
self.correctExtruderSettings()
self.extruderChanged.emit() self.extruderChanged.emit()
def _onMachineNameChanged(self): def _onMachineNameChanged(self):

View file

@ -81,7 +81,8 @@ class ProcessSlicedLayersJob(Job):
Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged) Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
new_node = CuraSceneNode() # The no_setting_override is here because adding the SettingOverrideDecorator will trigger a reslice
new_node = CuraSceneNode(no_setting_override = True)
new_node.addDecorator(BuildPlateDecorator(self._build_plate_number)) new_node.addDecorator(BuildPlateDecorator(self._build_plate_number))
# Force garbage collection. # Force garbage collection.

View file

@ -110,7 +110,6 @@ class StartSliceJob(Job):
return return
stack = Application.getInstance().getGlobalContainerStack() stack = Application.getInstance().getGlobalContainerStack()
extruder_stack_id_to_position = {} # a lookup table because we need the position, not the id.
if not stack: if not stack:
self.setResult(StartJobResult.Error) self.setResult(StartJobResult.Error)
return return
@ -131,7 +130,6 @@ class StartSliceJob(Job):
return return
for position, extruder_stack in stack.extruders.items(): for position, extruder_stack in stack.extruders.items():
extruder_stack_id_to_position[extruder_stack.getId()] = position
material = extruder_stack.findContainer({"type": "material"}) material = extruder_stack.findContainer({"type": "material"})
if material: if material:
if material.getMetaDataEntry("compatible") == False: if material.getMetaDataEntry("compatible") == False:
@ -200,8 +198,7 @@ class StartSliceJob(Job):
continue continue
if getattr(node, "_outside_buildarea", False) and is_non_printing_mesh: if getattr(node, "_outside_buildarea", False) and is_non_printing_mesh:
continue continue
node_extruder_id = node.callDecoration("getActiveExtruder") node_position = node.callDecoration("getActiveExtruderPosition")
node_position = extruder_stack_id_to_position.get(node_extruder_id, "0")
if not stack.extruders[str(node_position)].isEnabled: if not stack.extruders[str(node_position)].isEnabled:
continue continue
@ -391,11 +388,11 @@ class StartSliceJob(Job):
# limit_to_extruder property. # limit_to_extruder property.
def _buildGlobalInheritsStackMessage(self, stack): def _buildGlobalInheritsStackMessage(self, stack):
for key in stack.getAllKeys(): for key in stack.getAllKeys():
extruder = int(round(float(stack.getProperty(key, "limit_to_extruder")))) extruder_position = int(round(float(stack.getProperty(key, "limit_to_extruder"))))
if extruder >= 0 and stack.extruders[str(extruder)].isEnabled: #Set to a specific extruder. if extruder_position >= 0: # Set to a specific extruder.
setting_extruder = self._slice_message.addRepeatedMessage("limit_to_extruder") setting_extruder = self._slice_message.addRepeatedMessage("limit_to_extruder")
setting_extruder.name = key setting_extruder.name = key
setting_extruder.extruder = extruder setting_extruder.extruder = extruder_position
Job.yieldThread() Job.yieldThread()
## Check if a node has per object settings and ensure that they are set correctly in the message ## Check if a node has per object settings and ensure that they are set correctly in the message