mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Merge branch 'master' into feature_sync_button
This commit is contained in:
commit
2bf6d071d1
44 changed files with 678 additions and 317 deletions
|
@ -54,6 +54,8 @@ class MachineManager(QObject):
|
|||
self._current_quality_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._error_check_timer = QTimer()
|
||||
|
@ -132,6 +134,7 @@ class MachineManager(QObject):
|
|||
# When the materials lookup table gets updated, it can mean that a material has its name changed, which should
|
||||
# be reflected on the GUI. This signal emission makes sure that it happens.
|
||||
self._material_manager.materialsUpdated.connect(self.rootMaterialChanged)
|
||||
self.rootMaterialChanged.connect(self._onRootMaterialChanged)
|
||||
|
||||
activeQualityGroupChanged = pyqtSignal()
|
||||
activeQualityChangesGroupChanged = pyqtSignal()
|
||||
|
@ -141,6 +144,7 @@ class MachineManager(QObject):
|
|||
activeVariantChanged = pyqtSignal()
|
||||
activeQualityChanged = pyqtSignal()
|
||||
activeStackChanged = pyqtSignal() # Emitted whenever the active stack is changed (ie: when changing between extruders, changing a profile, but not when changing a value)
|
||||
extruderChanged = pyqtSignal()
|
||||
|
||||
globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed.
|
||||
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
|
||||
|
@ -232,7 +236,9 @@ class MachineManager(QObject):
|
|||
|
||||
# Update the local global container stack reference
|
||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
if self._global_container_stack:
|
||||
self.updateDefaultExtruder()
|
||||
self.updateNumberExtrudersEnabled()
|
||||
self.globalContainerChanged.emit()
|
||||
|
||||
# after switching the global stack we reconnect all the signals and set the variant and material references
|
||||
|
@ -385,7 +391,7 @@ class MachineManager(QObject):
|
|||
return False
|
||||
|
||||
if self._global_container_stack.hasErrors():
|
||||
Logger.log("d", "Checking global stack for errors took %0.2f s and we found and error" % (time.time() - time_start))
|
||||
Logger.log("d", "Checking global stack for errors took %0.2f s and we found an error" % (time.time() - time_start))
|
||||
return True
|
||||
|
||||
# Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are
|
||||
|
@ -715,6 +721,8 @@ class MachineManager(QObject):
|
|||
buildplate_compatible = True # It is compatible by default
|
||||
extruder_stacks = self._global_container_stack.extruders.values()
|
||||
for stack in extruder_stacks:
|
||||
if not stack.isEnabled:
|
||||
continue
|
||||
material_container = stack.material
|
||||
if material_container == self._empty_material_container:
|
||||
continue
|
||||
|
@ -772,6 +780,43 @@ class MachineManager(QObject):
|
|||
if containers:
|
||||
return containers[0].definition.getId()
|
||||
|
||||
def getIncompatibleSettingsOnEnabledExtruders(self, container):
|
||||
extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||
result = []
|
||||
for setting_instance in container.findInstances():
|
||||
setting_key = setting_instance.definition.key
|
||||
setting_enabled = self._global_container_stack.getProperty(setting_key, "enabled")
|
||||
if not setting_enabled:
|
||||
# A setting is not visible anymore
|
||||
result.append(setting_key)
|
||||
Logger.log("d", "Reset setting [%s] from [%s] because the setting is no longer enabled", setting_key, container)
|
||||
continue
|
||||
|
||||
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
|
||||
continue
|
||||
|
||||
old_value = container.getProperty(setting_key, "value")
|
||||
if int(old_value) >= extruder_count or not self._global_container_stack.extruders[str(old_value)].isEnabled:
|
||||
result.append(setting_key)
|
||||
Logger.log("d", "Reset setting [%s] in [%s] because its old value [%s] is no longer valid", setting_key, container, old_value)
|
||||
return result
|
||||
|
||||
## Update extruder number to a valid value when the number of extruders are changed, or when an extruder is changed
|
||||
def correctExtruderSettings(self):
|
||||
for setting_key in self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.userChanges):
|
||||
self._global_container_stack.userChanges.removeInstance(setting_key)
|
||||
add_user_changes = self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.qualityChanges)
|
||||
for setting_key in add_user_changes:
|
||||
# Apply quality changes that are incompatible to user changes, so we do not change the quality changes itself.
|
||||
self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position)
|
||||
if add_user_changes:
|
||||
caution_message = Message(catalog.i18nc(
|
||||
"@info:generic",
|
||||
"Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)),
|
||||
lifetime=0,
|
||||
title = catalog.i18nc("@info:title", "Settings updated"))
|
||||
caution_message.show()
|
||||
|
||||
## Set the amount of extruders on the active machine (global stack)
|
||||
# \param extruder_count int the number of extruders to set
|
||||
def setActiveMachineExtruderCount(self, extruder_count):
|
||||
|
@ -785,16 +830,11 @@ class MachineManager(QObject):
|
|||
if extruder_count == previous_extruder_count:
|
||||
return
|
||||
|
||||
# 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
|
||||
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
|
||||
|
||||
old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value"))
|
||||
if 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)
|
||||
self.updateDefaultExtruder()
|
||||
self.updateNumberExtrudersEnabled()
|
||||
self.correctExtruderSettings()
|
||||
|
||||
# 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()
|
||||
|
@ -805,21 +845,19 @@ class MachineManager(QObject):
|
|||
if extruder_nr is not None and int(extruder_nr) > extruder_count - 1:
|
||||
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
|
||||
extruder_manager.setActiveExtruderIndex(0)
|
||||
|
||||
# Move settable_per_extruder values out of the global container
|
||||
# After CURA-4482 this should not be the case anymore, but we still want to support older project files.
|
||||
global_user_container = self._global_container_stack.getTop()
|
||||
global_user_container = self._global_container_stack.userChanges
|
||||
|
||||
# Make sure extruder_stacks exists
|
||||
extruder_stacks = []
|
||||
|
||||
if previous_extruder_count == 1:
|
||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||
global_user_container = self._global_container_stack.getTop()
|
||||
global_user_container = self._global_container_stack.userChanges
|
||||
|
||||
for setting_instance in global_user_container.findInstances():
|
||||
setting_key = setting_instance.definition.key
|
||||
|
@ -828,11 +866,12 @@ class MachineManager(QObject):
|
|||
if settable_per_extruder:
|
||||
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
|
||||
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
|
||||
extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
||||
extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
||||
global_user_container.removeInstance(setting_key)
|
||||
|
||||
# Signal that the global stack has changed
|
||||
Application.getInstance().globalContainerStackChanged.emit()
|
||||
self.forceUpdateAllSettings()
|
||||
|
||||
@pyqtSlot(int, result = QObject)
|
||||
def getExtruder(self, position: int):
|
||||
|
@ -841,6 +880,53 @@ class MachineManager(QObject):
|
|||
extruder = self._global_container_stack.extruders.get(str(position))
|
||||
return extruder
|
||||
|
||||
def updateDefaultExtruder(self):
|
||||
extruder_items = sorted(self._global_container_stack.extruders.items())
|
||||
old_position = self._default_extruder_position
|
||||
new_default_position = "0"
|
||||
for position, extruder in extruder_items:
|
||||
if extruder.isEnabled:
|
||||
new_default_position = position
|
||||
break
|
||||
if new_default_position != old_position:
|
||||
self._default_extruder_position = new_default_position
|
||||
self.extruderChanged.emit()
|
||||
|
||||
def updateNumberExtrudersEnabled(self):
|
||||
definition_changes_container = self._global_container_stack.definitionChanges
|
||||
extruder_count = 0
|
||||
for position, extruder in self._global_container_stack.extruders.items():
|
||||
if extruder.isEnabled:
|
||||
extruder_count += 1
|
||||
definition_changes_container.setProperty("extruders_enabled_count", "value", extruder_count)
|
||||
|
||||
@pyqtProperty(str, notify = extruderChanged)
|
||||
def defaultExtruderPosition(self):
|
||||
return self._default_extruder_position
|
||||
|
||||
## This will fire the propertiesChanged for all settings so they will be updated in the front-end
|
||||
def forceUpdateAllSettings(self):
|
||||
property_names = ["value", "resolve"]
|
||||
for setting_key in self._global_container_stack.getAllKeys():
|
||||
self._global_container_stack.propertiesChanged.emit(setting_key, property_names)
|
||||
|
||||
@pyqtSlot(int, bool)
|
||||
def setExtruderEnabled(self, position: int, enabled) -> None:
|
||||
extruder = self.getExtruder(position)
|
||||
extruder.setEnabled(enabled)
|
||||
self.updateDefaultExtruder()
|
||||
self.updateNumberExtrudersEnabled()
|
||||
self.correctExtruderSettings()
|
||||
# ensure that the quality profile is compatible with current combination, or choose a compatible one if available
|
||||
self._updateQualityWithMaterial()
|
||||
self.extruderChanged.emit()
|
||||
# update material compatibility color
|
||||
self.activeQualityGroupChanged.emit()
|
||||
# update items in SettingExtruder
|
||||
ExtruderManager.getInstance().extrudersChanged.emit(self._global_container_stack.getId())
|
||||
# Make sure the front end reflects changes
|
||||
self.forceUpdateAllSettings()
|
||||
|
||||
def _onMachineNameChanged(self):
|
||||
self.globalContainerChanged.emit()
|
||||
|
||||
|
@ -861,27 +947,32 @@ class MachineManager(QObject):
|
|||
container = extruder.userChanges
|
||||
container.setProperty(setting_name, property_name, property_value)
|
||||
|
||||
@pyqtProperty("QVariantList", notify = rootMaterialChanged)
|
||||
@pyqtProperty("QVariantList", notify = globalContainerChanged)
|
||||
def currentExtruderPositions(self):
|
||||
return sorted(list(self._current_root_material_id.keys()))
|
||||
if self._global_container_stack is None:
|
||||
return []
|
||||
return sorted(list(self._global_container_stack.extruders.keys()))
|
||||
|
||||
@pyqtProperty("QVariant", notify = rootMaterialChanged)
|
||||
def currentRootMaterialId(self):
|
||||
# initial filling the current_root_material_id
|
||||
## Update _current_root_material_id and _current_root_material_name when
|
||||
# the current root material was changed.
|
||||
def _onRootMaterialChanged(self):
|
||||
self._current_root_material_id = {}
|
||||
for position in self._global_container_stack.extruders:
|
||||
self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
|
||||
return self._current_root_material_id
|
||||
|
||||
@pyqtProperty("QVariant", notify = rootMaterialChanged)
|
||||
def currentRootMaterialName(self):
|
||||
# initial filling the current_root_material_name
|
||||
if self._global_container_stack:
|
||||
for position in self._global_container_stack.extruders:
|
||||
self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
|
||||
self._current_root_material_name = {}
|
||||
for position in self._global_container_stack.extruders:
|
||||
if position not in self._current_root_material_name:
|
||||
material = self._global_container_stack.extruders[position].material
|
||||
self._current_root_material_name[position] = material.getName()
|
||||
|
||||
@pyqtProperty("QVariant", notify = rootMaterialChanged)
|
||||
def currentRootMaterialId(self):
|
||||
return self._current_root_material_id
|
||||
|
||||
@pyqtProperty("QVariant", notify = rootMaterialChanged)
|
||||
def currentRootMaterialName(self):
|
||||
return self._current_root_material_name
|
||||
|
||||
## Return the variant names in the extruder stack(s).
|
||||
|
@ -928,9 +1019,9 @@ class MachineManager(QObject):
|
|||
|
||||
# Set quality and quality_changes for each ExtruderStack
|
||||
for position, node in quality_group.nodes_for_extruders.items():
|
||||
self._global_container_stack.extruders[position].quality = node.getContainer()
|
||||
self._global_container_stack.extruders[str(position)].quality = node.getContainer()
|
||||
if empty_quality_changes:
|
||||
self._global_container_stack.extruders[position].qualityChanges = self._empty_quality_changes_container
|
||||
self._global_container_stack.extruders[str(position)].qualityChanges = self._empty_quality_changes_container
|
||||
|
||||
self.activeQualityGroupChanged.emit()
|
||||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
@ -995,6 +1086,8 @@ class MachineManager(QObject):
|
|||
# check material - variant compatibility
|
||||
if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)):
|
||||
for position, extruder in self._global_container_stack.extruders.items():
|
||||
if extruder.isEnabled and not extruder.material.getMetaDataEntry("compatible"):
|
||||
return False
|
||||
if not extruder.material.getMetaDataEntry("compatible"):
|
||||
return False
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue