mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-09 23:05:01 -06:00
Merge branch 'master' into CURA-5334_extruder_def_for_all
This commit is contained in:
commit
3761123513
710 changed files with 272858 additions and 117101 deletions
|
@ -313,7 +313,6 @@ class ContainerManager(QObject):
|
|||
|
||||
self._machine_manager.blurSettings.emit()
|
||||
|
||||
global_stack = self._machine_manager.activeMachine
|
||||
current_quality_changes_name = global_stack.qualityChanges.getName()
|
||||
current_quality_type = global_stack.quality.getMetaDataEntry("quality_type")
|
||||
extruder_stacks = list(global_stack.extruders.values())
|
||||
|
@ -324,6 +323,7 @@ class ContainerManager(QObject):
|
|||
if quality_changes.getId() == "empty_quality_changes":
|
||||
quality_changes = self._quality_manager._createQualityChanges(current_quality_type, current_quality_changes_name,
|
||||
global_stack, stack)
|
||||
self._container_registry.addContainer(quality_changes)
|
||||
stack.qualityChanges = quality_changes
|
||||
|
||||
if not quality_changes or self._container_registry.isReadOnly(quality_changes.getId()):
|
||||
|
@ -468,7 +468,7 @@ class ContainerManager(QObject):
|
|||
container_list = [n.getContainer() for n in quality_changes_group.getAllNodes() if n.getContainer() is not None]
|
||||
self._container_registry.exportQualityProfile(container_list, path, file_type)
|
||||
|
||||
__instance = None
|
||||
__instance = None # type: ContainerManager
|
||||
|
||||
@classmethod
|
||||
def getInstance(cls, *args, **kwargs) -> "ContainerManager":
|
||||
|
|
|
@ -5,7 +5,7 @@ import os
|
|||
import re
|
||||
import configparser
|
||||
|
||||
from typing import Optional
|
||||
from typing import cast, Optional
|
||||
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
|
@ -26,7 +26,7 @@ from UM.Resources import Resources
|
|||
from . import ExtruderStack
|
||||
from . import GlobalStack
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
import cura.CuraApplication
|
||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||
from cura.ReaderWriters.ProfileReader import NoProfileException
|
||||
|
||||
|
@ -57,7 +57,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
|
||||
if isinstance(container, InstanceContainer) and type(container) != type(self.getEmptyInstanceContainer()):
|
||||
# Check against setting version of the definition.
|
||||
required_setting_version = CuraApplication.SettingVersion
|
||||
required_setting_version = cura.CuraApplication.CuraApplication.SettingVersion
|
||||
actual_setting_version = int(container.getMetaDataEntry("setting_version", default = 0))
|
||||
if required_setting_version != actual_setting_version:
|
||||
Logger.log("w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}.".format(container_id = container.getId(), actual_setting_version = actual_setting_version, required_setting_version = required_setting_version))
|
||||
|
@ -260,7 +260,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
profile_id = ContainerRegistry.getInstance().uniqueName(global_stack.getId() + "_extruder_" + str(idx + 1))
|
||||
profile = InstanceContainer(profile_id)
|
||||
profile.setName(quality_name)
|
||||
profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||
profile.addMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion)
|
||||
profile.addMetaDataEntry("type", "quality_changes")
|
||||
profile.addMetaDataEntry("definition", expected_machine_definition)
|
||||
profile.addMetaDataEntry("quality_type", quality_type)
|
||||
|
@ -356,13 +356,15 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
return catalog.i18nc("@info:status", "Profile is missing a quality type.")
|
||||
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_stack is None:
|
||||
return None
|
||||
definition_id = getMachineDefinitionIDForQualitySearch(global_stack.definition)
|
||||
profile.setDefinition(definition_id)
|
||||
|
||||
# Check to make sure the imported profile actually makes sense in context of the current configuration.
|
||||
# This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
|
||||
# successfully imported but then fail to show up.
|
||||
quality_manager = CuraApplication.getInstance()._quality_manager
|
||||
quality_manager = cura.CuraApplication.CuraApplication.getInstance()._quality_manager
|
||||
quality_group_dict = quality_manager.getQualityGroupsForMachineDefinition(global_stack)
|
||||
if quality_type not in quality_group_dict:
|
||||
return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)
|
||||
|
@ -465,7 +467,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id, new_global_quality_changes = None, create_new_ids = True):
|
||||
new_extruder_id = extruder_id
|
||||
|
||||
application = CuraApplication.getInstance()
|
||||
application = cura.CuraApplication.CuraApplication.getInstance()
|
||||
|
||||
extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
|
||||
if not extruder_definitions:
|
||||
|
@ -485,7 +487,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
definition_changes_name = definition_changes_id
|
||||
definition_changes = InstanceContainer(definition_changes_id, parent = application)
|
||||
definition_changes.setName(definition_changes_name)
|
||||
definition_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||
definition_changes.addMetaDataEntry("setting_version", application.SettingVersion)
|
||||
definition_changes.addMetaDataEntry("type", "definition_changes")
|
||||
definition_changes.addMetaDataEntry("definition", extruder_definition.getId())
|
||||
|
||||
|
@ -514,7 +516,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
user_container.setName(user_container_name)
|
||||
user_container.addMetaDataEntry("type", "user")
|
||||
user_container.addMetaDataEntry("machine", machine.getId())
|
||||
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||
user_container.addMetaDataEntry("setting_version", application.SettingVersion)
|
||||
user_container.setDefinition(machine.definition.getId())
|
||||
user_container.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
|
||||
|
||||
|
@ -587,7 +589,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
extruder_quality_changes_container = InstanceContainer(container_id, parent = application)
|
||||
extruder_quality_changes_container.setName(container_name)
|
||||
extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes")
|
||||
extruder_quality_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||
extruder_quality_changes_container.addMetaDataEntry("setting_version", application.SettingVersion)
|
||||
extruder_quality_changes_container.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
|
||||
extruder_quality_changes_container.addMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type"))
|
||||
extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId())
|
||||
|
@ -675,7 +677,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
return extruder_stack
|
||||
|
||||
def _findQualityChangesContainerInCuraFolder(self, name):
|
||||
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityChangesInstanceContainer)
|
||||
quality_changes_dir = Resources.getPath(cura.CuraApplication.CuraApplication.ResourceTypes.QualityChangesInstanceContainer)
|
||||
|
||||
instance_container = None
|
||||
|
||||
|
@ -731,3 +733,9 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
extruder_stack.setNextStack(machines[0])
|
||||
else:
|
||||
Logger.log("w", "Could not find machine {machine} for extruder {extruder}", machine = extruder_stack.getMetaDataEntry("machine"), extruder = extruder_stack.getId())
|
||||
|
||||
#Override just for the type.
|
||||
@classmethod
|
||||
@override(ContainerRegistry)
|
||||
def getInstance(cls, *args, **kwargs) -> "CuraContainerRegistry":
|
||||
return cast(CuraContainerRegistry, super().getInstance(*args, **kwargs))
|
|
@ -1,15 +1,12 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os.path
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from typing import Any, cast, List, Optional, Union
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Decorators import override
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
@ -39,19 +36,19 @@ from . import Exceptions
|
|||
# This also means that operations on the stack that modifies the container ordering is prohibited and
|
||||
# will raise an exception.
|
||||
class CuraContainerStack(ContainerStack):
|
||||
def __init__(self, container_id: str):
|
||||
def __init__(self, container_id: str) -> None:
|
||||
super().__init__(container_id)
|
||||
|
||||
self._container_registry = ContainerRegistry.getInstance()
|
||||
self._container_registry = ContainerRegistry.getInstance() #type: ContainerRegistry
|
||||
|
||||
self._empty_instance_container = self._container_registry.getEmptyInstanceContainer()
|
||||
self._empty_instance_container = self._container_registry.getEmptyInstanceContainer() #type: InstanceContainer
|
||||
|
||||
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._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] #type: InstanceContainer
|
||||
self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] #type: InstanceContainer
|
||||
self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] #type: InstanceContainer
|
||||
self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0] #type: InstanceContainer
|
||||
|
||||
self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))]
|
||||
self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] #type: List[Union[InstanceContainer, DefinitionContainer]]
|
||||
self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes
|
||||
self._containers[_ContainerIndexes.Quality] = self._empty_quality
|
||||
self._containers[_ContainerIndexes.Material] = self._empty_material
|
||||
|
@ -76,7 +73,7 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The user changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setUserChanges, notify = pyqtContainersChanged)
|
||||
def userChanges(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.UserChanges]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.UserChanges])
|
||||
|
||||
## Set the quality changes container.
|
||||
#
|
||||
|
@ -89,12 +86,12 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The quality changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setQualityChanges, notify = pyqtContainersChanged)
|
||||
def qualityChanges(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.QualityChanges]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.QualityChanges])
|
||||
|
||||
## Set the quality container.
|
||||
#
|
||||
# \param new_quality The new quality container. It is expected to have a "type" metadata entry with the value "quality".
|
||||
def setQuality(self, new_quality: InstanceContainer, postpone_emit = False) -> None:
|
||||
def setQuality(self, new_quality: InstanceContainer, postpone_emit: bool = False) -> None:
|
||||
self.replaceContainer(_ContainerIndexes.Quality, new_quality, postpone_emit = postpone_emit)
|
||||
|
||||
## Get the quality container.
|
||||
|
@ -102,12 +99,12 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The quality container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setQuality, notify = pyqtContainersChanged)
|
||||
def quality(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.Quality]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.Quality])
|
||||
|
||||
## Set the material container.
|
||||
#
|
||||
# \param new_material The new material container. It is expected to have a "type" metadata entry with the value "material".
|
||||
def setMaterial(self, new_material: InstanceContainer, postpone_emit = False) -> None:
|
||||
def setMaterial(self, new_material: InstanceContainer, postpone_emit: bool = False) -> None:
|
||||
self.replaceContainer(_ContainerIndexes.Material, new_material, postpone_emit = postpone_emit)
|
||||
|
||||
## Get the material container.
|
||||
|
@ -115,7 +112,7 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The material container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setMaterial, notify = pyqtContainersChanged)
|
||||
def material(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.Material]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.Material])
|
||||
|
||||
## Set the variant container.
|
||||
#
|
||||
|
@ -128,7 +125,7 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The variant container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setVariant, notify = pyqtContainersChanged)
|
||||
def variant(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.Variant]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.Variant])
|
||||
|
||||
## Set the definition changes container.
|
||||
#
|
||||
|
@ -141,7 +138,7 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The definition changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(InstanceContainer, fset = setDefinitionChanges, notify = pyqtContainersChanged)
|
||||
def definitionChanges(self) -> InstanceContainer:
|
||||
return self._containers[_ContainerIndexes.DefinitionChanges]
|
||||
return cast(InstanceContainer, self._containers[_ContainerIndexes.DefinitionChanges])
|
||||
|
||||
## Set the definition container.
|
||||
#
|
||||
|
@ -154,7 +151,7 @@ class CuraContainerStack(ContainerStack):
|
|||
# \return The definition container. Should always be a valid container, but can be equal to the empty InstanceContainer.
|
||||
@pyqtProperty(QObject, fset = setDefinition, notify = pyqtContainersChanged)
|
||||
def definition(self) -> DefinitionContainer:
|
||||
return self._containers[_ContainerIndexes.Definition]
|
||||
return cast(DefinitionContainer, self._containers[_ContainerIndexes.Definition])
|
||||
|
||||
@override(ContainerStack)
|
||||
def getBottom(self) -> "DefinitionContainer":
|
||||
|
@ -189,13 +186,9 @@ class CuraContainerStack(ContainerStack):
|
|||
# \param key The key of the setting to set.
|
||||
# \param property_name The name of the property to set.
|
||||
# \param new_value The new value to set the property to.
|
||||
# \param target_container The type of the container to set the property of. Defaults to "user".
|
||||
def setProperty(self, key: str, property_name: str, new_value: Any, target_container: str = "user") -> None:
|
||||
container_index = _ContainerIndexes.TypeIndexMap.get(target_container, -1)
|
||||
if container_index != -1:
|
||||
self._containers[container_index].setProperty(key, property_name, new_value)
|
||||
else:
|
||||
raise IndexError("Invalid target container {type}".format(type = target_container))
|
||||
def setProperty(self, key: str, property_name: str, property_value: Any, container: "ContainerInterface" = None, set_from_cache: bool = False) -> None:
|
||||
container_index = _ContainerIndexes.UserChanges
|
||||
self._containers[container_index].setProperty(key, property_name, property_value, container, set_from_cache)
|
||||
|
||||
## Overridden from ContainerStack
|
||||
#
|
||||
|
@ -310,15 +303,15 @@ class CuraContainerStack(ContainerStack):
|
|||
#
|
||||
# \return The ID of the definition container to use when searching for instance containers.
|
||||
@classmethod
|
||||
def _findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainer) -> str:
|
||||
def _findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainerInterface) -> str:
|
||||
quality_definition = machine_definition.getMetaDataEntry("quality_definition")
|
||||
if not quality_definition:
|
||||
return machine_definition.id
|
||||
return machine_definition.id #type: ignore
|
||||
|
||||
definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = quality_definition)
|
||||
if not definitions:
|
||||
Logger.log("w", "Unable to find parent definition {parent} for machine {machine}", parent = quality_definition, machine = machine_definition.id)
|
||||
return machine_definition.id
|
||||
Logger.log("w", "Unable to find parent definition {parent} for machine {machine}", parent = quality_definition, machine = machine_definition.id) #type: ignore
|
||||
return machine_definition.id #type: ignore
|
||||
|
||||
return cls._findInstanceContainerDefinitionId(definitions[0])
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
||||
from UM.Application import Application # To get the global container stack to find the current machine.
|
||||
import cura.CuraApplication #To get the global container stack to find the current machine.
|
||||
from UM.Logger import Logger
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
|
@ -16,7 +16,7 @@ from UM.Settings.SettingInstance import SettingInstance
|
|||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
||||
|
||||
from typing import Optional, List, TYPE_CHECKING, Union
|
||||
from typing import Optional, List, TYPE_CHECKING, Union, Dict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
|
@ -36,14 +36,13 @@ class ExtruderManager(QObject):
|
|||
|
||||
super().__init__(parent)
|
||||
|
||||
self._application = Application.getInstance()
|
||||
self._application = cura.CuraApplication.CuraApplication.getInstance()
|
||||
|
||||
self._extruder_trains = {} # Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
|
||||
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
|
||||
self._selected_object_extruders = []
|
||||
self._addCurrentMachineExtruders()
|
||||
|
||||
#Application.getInstance().globalContainerStackChanged.connect(self._globalContainerStackChanged)
|
||||
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
|
||||
|
||||
## Signal to notify other components when the list of extruders for a machine definition changes.
|
||||
|
@ -60,42 +59,47 @@ class ExtruderManager(QObject):
|
|||
# \return The unique ID of the currently active extruder stack.
|
||||
@pyqtProperty(str, notify = activeExtruderChanged)
|
||||
def activeExtruderStackId(self) -> Optional[str]:
|
||||
if not Application.getInstance().getGlobalContainerStack():
|
||||
if not self._application.getGlobalContainerStack():
|
||||
return None # No active machine, so no active extruder.
|
||||
try:
|
||||
return self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
||||
return self._extruder_trains[self._application.getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId()
|
||||
except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
|
||||
return None
|
||||
|
||||
## Return extruder count according to extruder trains.
|
||||
@pyqtProperty(int, notify = extrudersChanged)
|
||||
def extruderCount(self):
|
||||
if not Application.getInstance().getGlobalContainerStack():
|
||||
if not self._application.getGlobalContainerStack():
|
||||
return 0 # No active machine, so no extruders.
|
||||
try:
|
||||
return len(self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()])
|
||||
return len(self._extruder_trains[self._application.getGlobalContainerStack().getId()])
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
## Gets a dict with the extruder stack ids with the extruder number as the key.
|
||||
@pyqtProperty("QVariantMap", notify = extrudersChanged)
|
||||
def extruderIds(self):
|
||||
def extruderIds(self) -> Dict[str, str]:
|
||||
extruder_stack_ids = {}
|
||||
|
||||
global_stack_id = Application.getInstance().getGlobalContainerStack().getId()
|
||||
global_container_stack = self._application.getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
global_stack_id = global_container_stack.getId()
|
||||
|
||||
if global_stack_id in self._extruder_trains:
|
||||
for position in self._extruder_trains[global_stack_id]:
|
||||
extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId()
|
||||
if global_stack_id in self._extruder_trains:
|
||||
for position in self._extruder_trains[global_stack_id]:
|
||||
extruder_stack_ids[position] = self._extruder_trains[global_stack_id][position].getId()
|
||||
|
||||
return extruder_stack_ids
|
||||
|
||||
@pyqtSlot(str, result = str)
|
||||
def getQualityChangesIdByExtruderStackId(self, extruder_stack_id: str) -> str:
|
||||
for position in self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()]:
|
||||
extruder = self._extruder_trains[Application.getInstance().getGlobalContainerStack().getId()][position]
|
||||
if extruder.getId() == extruder_stack_id:
|
||||
return extruder.qualityChanges.getId()
|
||||
global_container_stack = self._application.getGlobalContainerStack()
|
||||
if global_container_stack is not None:
|
||||
for position in self._extruder_trains[global_container_stack.getId()]:
|
||||
extruder = self._extruder_trains[global_container_stack.getId()][position]
|
||||
if extruder.getId() == extruder_stack_id:
|
||||
return extruder.qualityChanges.getId()
|
||||
return ""
|
||||
|
||||
## Changes the active extruder by index.
|
||||
#
|
||||
|
@ -132,7 +136,7 @@ class ExtruderManager(QObject):
|
|||
selected_nodes = []
|
||||
for node in Selection.getAllSelectedObjects():
|
||||
if node.callDecoration("isGroup"):
|
||||
for grouped_node in BreadthFirstIterator(node):
|
||||
for grouped_node in BreadthFirstIterator(node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
if grouped_node.callDecoration("isGroup"):
|
||||
continue
|
||||
|
||||
|
@ -141,7 +145,7 @@ class ExtruderManager(QObject):
|
|||
selected_nodes.append(node)
|
||||
|
||||
# Then, figure out which nodes are used by those selected nodes.
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = self._application.getGlobalContainerStack()
|
||||
current_extruder_trains = self._extruder_trains.get(global_stack.getId())
|
||||
for node in selected_nodes:
|
||||
extruder = node.callDecoration("getActiveExtruder")
|
||||
|
@ -164,7 +168,7 @@ class ExtruderManager(QObject):
|
|||
|
||||
@pyqtSlot(result = QObject)
|
||||
def getActiveExtruderStack(self) -> Optional["ExtruderStack"]:
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = self._application.getGlobalContainerStack()
|
||||
|
||||
if global_container_stack:
|
||||
if global_container_stack.getId() in self._extruder_trains:
|
||||
|
@ -175,7 +179,7 @@ class ExtruderManager(QObject):
|
|||
|
||||
## Get an extruder stack by index
|
||||
def getExtruderStack(self, index) -> Optional["ExtruderStack"]:
|
||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_container_stack = self._application.getGlobalContainerStack()
|
||||
if global_container_stack:
|
||||
if global_container_stack.getId() in self._extruder_trains:
|
||||
if str(index) in self._extruder_trains[global_container_stack.getId()]:
|
||||
|
@ -186,7 +190,9 @@ class ExtruderManager(QObject):
|
|||
def getExtruderStacks(self) -> List["ExtruderStack"]:
|
||||
result = []
|
||||
for i in range(self.extruderCount):
|
||||
result.append(self.getExtruderStack(i))
|
||||
stack = self.getExtruderStack(i)
|
||||
if stack:
|
||||
result.append(stack)
|
||||
return result
|
||||
|
||||
def registerExtruder(self, extruder_train, machine_id):
|
||||
|
@ -252,14 +258,14 @@ class ExtruderManager(QObject):
|
|||
support_bottom_enabled = False
|
||||
support_roof_enabled = False
|
||||
|
||||
scene_root = Application.getInstance().getController().getScene().getRoot()
|
||||
scene_root = self._application.getController().getScene().getRoot()
|
||||
|
||||
# If no extruders are registered in the extruder manager yet, return an empty array
|
||||
if len(self.extruderIds) == 0:
|
||||
return []
|
||||
|
||||
# Get the extruders of all printable meshes in the scene
|
||||
meshes = [node for node in DepthFirstIterator(scene_root) if isinstance(node, SceneNode) and node.isSelectable()]
|
||||
meshes = [node for node in DepthFirstIterator(scene_root) if isinstance(node, SceneNode) and node.isSelectable()] #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for mesh in meshes:
|
||||
extruder_stack_id = mesh.callDecoration("getActiveExtruder")
|
||||
if not extruder_stack_id:
|
||||
|
@ -301,10 +307,10 @@ class ExtruderManager(QObject):
|
|||
|
||||
# The platform adhesion extruder. Not used if using none.
|
||||
if global_stack.getProperty("adhesion_type", "value") != "none":
|
||||
extruder_nr = str(global_stack.getProperty("adhesion_extruder_nr", "value"))
|
||||
if extruder_nr == "-1":
|
||||
extruder_nr = Application.getInstance().getMachineManager().defaultExtruderPosition
|
||||
used_extruder_stack_ids.add(self.extruderIds[extruder_nr])
|
||||
extruder_str_nr = str(global_stack.getProperty("adhesion_extruder_nr", "value"))
|
||||
if extruder_str_nr == "-1":
|
||||
extruder_str_nr = self._application.getMachineManager().defaultExtruderPosition
|
||||
used_extruder_stack_ids.add(self.extruderIds[extruder_str_nr])
|
||||
|
||||
try:
|
||||
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
||||
|
@ -335,7 +341,7 @@ class ExtruderManager(QObject):
|
|||
# The first element is the global container stack, followed by any extruder stacks.
|
||||
# \return \type{List[ContainerStack]}
|
||||
def getActiveGlobalAndExtruderStacks(self) -> Optional[List[Union["ExtruderStack", "GlobalStack"]]]:
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = self._application.getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return None
|
||||
|
||||
|
@ -347,7 +353,7 @@ class ExtruderManager(QObject):
|
|||
#
|
||||
# \return \type{List[ContainerStack]} a list of
|
||||
def getActiveExtruderStacks(self) -> List["ExtruderStack"]:
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = self._application.getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return []
|
||||
|
||||
|
@ -420,7 +426,7 @@ class ExtruderManager(QObject):
|
|||
# If no extruder has the value, the list will contain the global value.
|
||||
@staticmethod
|
||||
def getExtruderValues(key):
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
|
||||
result = []
|
||||
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
|
||||
|
@ -455,7 +461,7 @@ class ExtruderManager(QObject):
|
|||
# If no extruder has the value, the list will contain the global value.
|
||||
@staticmethod
|
||||
def getDefaultExtruderValues(key):
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
context = PropertyEvaluationContext(global_stack)
|
||||
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
||||
context.context["override_operators"] = {
|
||||
|
@ -488,7 +494,7 @@ class ExtruderManager(QObject):
|
|||
## Return the default extruder position from the machine manager
|
||||
@staticmethod
|
||||
def getDefaultExtruderPosition() -> str:
|
||||
return Application.getInstance().getMachineManager().defaultExtruderPosition
|
||||
return cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition
|
||||
|
||||
## Get all extruder values for a certain setting.
|
||||
#
|
||||
|
@ -513,7 +519,7 @@ class ExtruderManager(QObject):
|
|||
@staticmethod
|
||||
def getExtruderValue(extruder_index, key):
|
||||
if extruder_index == -1:
|
||||
extruder_index = int(Application.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
extruder_index = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
|
||||
|
||||
if extruder:
|
||||
|
@ -522,7 +528,7 @@ class ExtruderManager(QObject):
|
|||
value = value(extruder)
|
||||
else:
|
||||
# Just a value from global.
|
||||
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
||||
value = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack().getProperty(key, "value")
|
||||
|
||||
return value
|
||||
|
||||
|
@ -551,7 +557,7 @@ class ExtruderManager(QObject):
|
|||
if isinstance(value, SettingFunction):
|
||||
value = value(extruder, context = context)
|
||||
else: # Just a value from global.
|
||||
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value", context = context)
|
||||
value = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack().getProperty(key, "value", context = context)
|
||||
|
||||
return value
|
||||
|
||||
|
@ -564,7 +570,7 @@ class ExtruderManager(QObject):
|
|||
# \return The effective value
|
||||
@staticmethod
|
||||
def getResolveOrValue(key):
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
resolved_value = global_stack.getProperty(key, "value")
|
||||
|
||||
return resolved_value
|
||||
|
@ -578,7 +584,7 @@ class ExtruderManager(QObject):
|
|||
# \return The effective value
|
||||
@staticmethod
|
||||
def getDefaultResolveOrValue(key):
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
context = PropertyEvaluationContext(global_stack)
|
||||
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
|
||||
context.context["override_operators"] = {
|
||||
|
@ -591,7 +597,7 @@ class ExtruderManager(QObject):
|
|||
|
||||
return resolved_value
|
||||
|
||||
__instance = None
|
||||
__instance = None # type: ExtruderManager
|
||||
|
||||
@classmethod
|
||||
def getInstance(cls, *args, **kwargs) -> "ExtruderManager":
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Any, TYPE_CHECKING, Optional
|
||||
from typing import Any, Dict, TYPE_CHECKING, Optional
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Decorators import override
|
||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
|
@ -13,6 +12,8 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
|
|||
from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
|
||||
from UM.Util import parseBool
|
||||
|
||||
import cura.CuraApplication
|
||||
|
||||
from . import Exceptions
|
||||
from .CuraContainerStack import CuraContainerStack, _ContainerIndexes
|
||||
from .ExtruderManager import ExtruderManager
|
||||
|
@ -25,7 +26,7 @@ if TYPE_CHECKING:
|
|||
#
|
||||
#
|
||||
class ExtruderStack(CuraContainerStack):
|
||||
def __init__(self, container_id: str):
|
||||
def __init__(self, container_id: str) -> None:
|
||||
super().__init__(container_id)
|
||||
|
||||
self.addMetaDataEntry("type", "extruder_train") # For backward compatibility
|
||||
|
@ -50,14 +51,14 @@ class ExtruderStack(CuraContainerStack):
|
|||
def getNextStack(self) -> Optional["GlobalStack"]:
|
||||
return super().getNextStack()
|
||||
|
||||
def setEnabled(self, enabled):
|
||||
def setEnabled(self, enabled: bool) -> None:
|
||||
if "enabled" not in self._metadata:
|
||||
self.addMetaDataEntry("enabled", "True")
|
||||
self.setMetaDataEntry("enabled", str(enabled))
|
||||
self.enabledChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify = enabledChanged)
|
||||
def isEnabled(self):
|
||||
def isEnabled(self) -> bool:
|
||||
return parseBool(self.getMetaDataEntry("enabled", "True"))
|
||||
|
||||
@classmethod
|
||||
|
@ -113,7 +114,7 @@ class ExtruderStack(CuraContainerStack):
|
|||
limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
|
||||
if limit_to_extruder is not None:
|
||||
if limit_to_extruder == -1:
|
||||
limit_to_extruder = int(Application.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
limit_to_extruder = str(limit_to_extruder)
|
||||
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
|
||||
if str(limit_to_extruder) in self.getNextStack().extruders:
|
||||
|
@ -142,7 +143,7 @@ class ExtruderStack(CuraContainerStack):
|
|||
if stacks:
|
||||
self.setNextStack(stacks[0])
|
||||
|
||||
def _onPropertiesChanged(self, key, properties):
|
||||
def _onPropertiesChanged(self, key: str, properties: Dict[str, Any]) -> None:
|
||||
# When there is a setting that is not settable per extruder that depends on a value from a setting that is,
|
||||
# we do not always get properly informed that we should re-evaluate the setting. So make sure to indicate
|
||||
# something changed for those settings.
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from collections import defaultdict
|
||||
import threading
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from typing import Any, Dict, Optional, Set, TYPE_CHECKING
|
||||
from PyQt5.QtCore import pyqtProperty
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Decorators import override
|
||||
|
||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.SettingInstance import InstanceState
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.Interfaces import PropertyEvaluationContext
|
||||
from UM.Logger import Logger
|
||||
import cura.CuraApplication
|
||||
|
||||
from . import Exceptions
|
||||
from .CuraContainerStack import CuraContainerStack
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
|
||||
## Represents the Global or Machine stack and its related containers.
|
||||
#
|
||||
class GlobalStack(CuraContainerStack):
|
||||
def __init__(self, container_id: str):
|
||||
def __init__(self, container_id: str) -> None:
|
||||
super().__init__(container_id)
|
||||
|
||||
self.addMetaDataEntry("type", "machine") # For backward compatibility
|
||||
|
@ -34,7 +35,7 @@ class GlobalStack(CuraContainerStack):
|
|||
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
||||
# if the resolve function tried to access the same property it is a resolve for.
|
||||
# Per thread we have our own resolving_settings, or strange things sometimes occur.
|
||||
self._resolving_settings = defaultdict(set) # keys are thread names
|
||||
self._resolving_settings = defaultdict(set) #type: Dict[str, Set[str]] # keys are thread names
|
||||
|
||||
## Get the list of extruders of this stack.
|
||||
#
|
||||
|
@ -94,6 +95,7 @@ class GlobalStack(CuraContainerStack):
|
|||
context.pushContainer(self)
|
||||
|
||||
# Handle the "resolve" property.
|
||||
#TODO: Why the hell does this involve threading?
|
||||
if self._shouldResolve(key, property_name, context):
|
||||
current_thread = threading.current_thread()
|
||||
self._resolving_settings[current_thread.name].add(key)
|
||||
|
@ -106,7 +108,7 @@ class GlobalStack(CuraContainerStack):
|
|||
limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
|
||||
if limit_to_extruder is not None:
|
||||
if limit_to_extruder == -1:
|
||||
limit_to_extruder = int(Application.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
limit_to_extruder = int(cura.CuraApplication.CuraApplication.getInstance().getMachineManager().defaultExtruderPosition)
|
||||
limit_to_extruder = str(limit_to_extruder)
|
||||
if limit_to_extruder is not None and limit_to_extruder != "-1" and limit_to_extruder in self._extruders:
|
||||
if super().getProperty(key, "settable_per_extruder", context):
|
||||
|
@ -155,7 +157,7 @@ class GlobalStack(CuraContainerStack):
|
|||
|
||||
## Perform some sanity checks on the global stack
|
||||
# Sanity check for extruders; they must have positions 0 and up to machine_extruder_count - 1
|
||||
def isValid(self):
|
||||
def isValid(self) -> bool:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = self.getId())
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import collections
|
||||
import time
|
||||
#Type hinting.
|
||||
from typing import List, Dict, TYPE_CHECKING, Optional
|
||||
from typing import Any, Callable, List, Dict, TYPE_CHECKING, Optional
|
||||
|
||||
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
|
||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||
|
@ -15,20 +14,22 @@ from UM.Signal import Signal
|
|||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM import Util
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Signal import postponeSignals, CompressTechnique
|
||||
|
||||
import cura.CuraApplication
|
||||
from cura.Machines.ContainerNode import ContainerNode #For typing.
|
||||
from cura.Machines.QualityChangesGroup import QualityChangesGroup #For typing.
|
||||
from cura.Machines.QualityGroup import QualityGroup #For typing.
|
||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||
from cura.PrinterOutputDevice import PrinterOutputDevice
|
||||
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
|
||||
from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel
|
||||
from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel
|
||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
||||
from cura.Settings.ExtruderManager import ExtruderManager
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
|
||||
|
@ -40,29 +41,31 @@ catalog = i18nCatalog("cura")
|
|||
if TYPE_CHECKING:
|
||||
from cura.Settings.CuraContainerStack import CuraContainerStack
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
from cura.Machines.MaterialManager import MaterialManager
|
||||
from cura.Machines.QualityManager import QualityManager
|
||||
from cura.Machines.VariantManager import VariantManager
|
||||
|
||||
class MachineManager(QObject):
|
||||
|
||||
def __init__(self, parent = None):
|
||||
def __init__(self, parent: QObject = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
self._active_container_stack = None # type: Optional[ExtruderManager]
|
||||
self._global_container_stack = None # type: Optional[GlobalStack]
|
||||
|
||||
self._current_root_material_id = {} # type: Dict[str, str]
|
||||
self._current_quality_group = None
|
||||
self._current_quality_changes_group = None
|
||||
self._current_quality_group = None # type: Optional[QualityGroup]
|
||||
self._current_quality_changes_group = None # type: Optional[QualityChangesGroup]
|
||||
|
||||
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) #type: Dict[str, List[Callable[[], None]]]
|
||||
|
||||
self._instance_container_timer = QTimer()
|
||||
self._instance_container_timer = QTimer() #type: QTimer
|
||||
self._instance_container_timer.setInterval(250)
|
||||
self._instance_container_timer.setSingleShot(True)
|
||||
self._instance_container_timer.timeout.connect(self.__emitChangedSignals)
|
||||
|
||||
self._application = Application.getInstance()
|
||||
self._application = cura.CuraApplication.CuraApplication.getInstance() #type: cura.CuraApplication.CuraApplication
|
||||
self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
self._application.getContainerRegistry().containerLoadComplete.connect(self._onContainersChanged)
|
||||
|
||||
|
@ -74,14 +77,14 @@ class MachineManager(QObject):
|
|||
self.globalContainerChanged.connect(self.activeQualityChangesGroupChanged)
|
||||
self.globalContainerChanged.connect(self.activeQualityGroupChanged)
|
||||
|
||||
self._stacks_have_errors = None # type:Optional[bool]
|
||||
self._stacks_have_errors = None # type: Optional[bool]
|
||||
|
||||
self._empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
||||
self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0]
|
||||
self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0]
|
||||
self._empty_material_container = ContainerRegistry.getInstance().findContainers(id = "empty_material")[0]
|
||||
self._empty_quality_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
|
||||
self._empty_quality_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality_changes")[0]
|
||||
self._empty_container = CuraContainerRegistry.getInstance().getEmptyInstanceContainer() #type: InstanceContainer
|
||||
self._empty_definition_changes_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0] #type: InstanceContainer
|
||||
self._empty_variant_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_variant")[0] #type: InstanceContainer
|
||||
self._empty_material_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_material")[0] #type: InstanceContainer
|
||||
self._empty_quality_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_quality")[0] #type: InstanceContainer
|
||||
self._empty_quality_changes_container = CuraContainerRegistry.getInstance().findContainers(id = "empty_quality_changes")[0] #type: InstanceContainer
|
||||
|
||||
self._onGlobalContainerChanged()
|
||||
|
||||
|
@ -99,8 +102,6 @@ class MachineManager(QObject):
|
|||
|
||||
self._application.getPreferences().addPreference("cura/active_machine", "")
|
||||
|
||||
self._global_event_keys = set()
|
||||
|
||||
self._printer_output_devices = [] # type: List[PrinterOutputDevice]
|
||||
self._application.getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
|
||||
# There might already be some output devices by the time the signal is connected
|
||||
|
@ -116,15 +117,15 @@ class MachineManager(QObject):
|
|||
|
||||
self._material_incompatible_message = Message(catalog.i18nc("@info:status",
|
||||
"The selected material is incompatible with the selected machine or configuration."),
|
||||
title = catalog.i18nc("@info:title", "Incompatible Material"))
|
||||
title = catalog.i18nc("@info:title", "Incompatible Material")) #type: Message
|
||||
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId)
|
||||
containers = CuraContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) #type: List[InstanceContainer]
|
||||
if containers:
|
||||
containers[0].nameChanged.connect(self._onMaterialNameChanged)
|
||||
|
||||
self._material_manager = self._application.getMaterialManager()
|
||||
self._variant_manager = self._application.getVariantManager()
|
||||
self._quality_manager = self._application.getQualityManager()
|
||||
self._material_manager = self._application.getMaterialManager() #type: MaterialManager
|
||||
self._variant_manager = self._application.getVariantManager() #type: VariantManager
|
||||
self._quality_manager = self._application.getQualityManager() #type: QualityManager
|
||||
|
||||
# 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.
|
||||
|
@ -164,7 +165,7 @@ class MachineManager(QObject):
|
|||
|
||||
def setInitialActiveMachine(self) -> None:
|
||||
active_machine_id = self._application.getPreferences().getValue("cura/active_machine")
|
||||
if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id):
|
||||
if active_machine_id != "" and CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id):
|
||||
# An active machine was saved, so restore it.
|
||||
self.setActiveMachine(active_machine_id)
|
||||
|
||||
|
@ -215,7 +216,10 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtProperty(int, constant=True)
|
||||
def totalNumberOfSettings(self) -> int:
|
||||
return len(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0].getAllKeys())
|
||||
general_definition_containers = CuraContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")
|
||||
if not general_definition_containers:
|
||||
return 0
|
||||
return len(general_definition_containers[0].getAllKeys())
|
||||
|
||||
def _onGlobalContainerChanged(self) -> None:
|
||||
if self._global_container_stack:
|
||||
|
@ -355,7 +359,7 @@ class MachineManager(QObject):
|
|||
def setActiveMachine(self, stack_id: str) -> None:
|
||||
self.blurSettings.emit() # Ensure no-one has focus.
|
||||
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
container_registry = CuraContainerRegistry.getInstance()
|
||||
|
||||
containers = container_registry.findContainerStacks(id = stack_id)
|
||||
if not containers:
|
||||
|
@ -381,7 +385,7 @@ class MachineManager(QObject):
|
|||
# \param metadata_filter \type{dict} list of metadata keys and values used for filtering
|
||||
@staticmethod
|
||||
def getMachine(definition_id: str, metadata_filter: Dict[str, str] = None) -> Optional["GlobalStack"]:
|
||||
machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
for machine in machines:
|
||||
if machine.definition.getId() == definition_id:
|
||||
return machine
|
||||
|
@ -625,11 +629,13 @@ class MachineManager(QObject):
|
|||
## Check if a container is read_only
|
||||
@pyqtSlot(str, result = bool)
|
||||
def isReadOnly(self, container_id: str) -> bool:
|
||||
return ContainerRegistry.getInstance().isReadOnly(container_id)
|
||||
return CuraContainerRegistry.getInstance().isReadOnly(container_id)
|
||||
|
||||
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
|
||||
@pyqtSlot(str)
|
||||
def copyValueToExtruders(self, key: str) -> None:
|
||||
if self._active_container_stack is None or self._global_container_stack is None:
|
||||
return
|
||||
new_value = self._active_container_stack.getProperty(key, "value")
|
||||
extruder_stacks = [stack for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())]
|
||||
|
||||
|
@ -641,6 +647,8 @@ class MachineManager(QObject):
|
|||
## Copy the value of all manually changed settings of the current extruder to all other extruders.
|
||||
@pyqtSlot()
|
||||
def copyAllValuesToExtruders(self) -> None:
|
||||
if self._active_container_stack is None or self._global_container_stack is None:
|
||||
return
|
||||
extruder_stacks = list(self._global_container_stack.extruders.values())
|
||||
for extruder_stack in extruder_stacks:
|
||||
if extruder_stack != self._active_container_stack:
|
||||
|
@ -704,7 +712,7 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtSlot(str, str)
|
||||
def renameMachine(self, machine_id: str, new_name: str) -> None:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
container_registry = CuraContainerRegistry.getInstance()
|
||||
machine_stack = container_registry.findContainerStacks(id = machine_id)
|
||||
if machine_stack:
|
||||
new_name = container_registry.createUniqueName("machine", machine_stack[0].getName(), new_name, machine_stack[0].definition.getName())
|
||||
|
@ -718,23 +726,23 @@ class MachineManager(QObject):
|
|||
|
||||
# activate a new machine before removing a machine because this is safer
|
||||
if activate_new_machine:
|
||||
machine_stacks = ContainerRegistry.getInstance().findContainerStacksMetadata(type = "machine")
|
||||
machine_stacks = CuraContainerRegistry.getInstance().findContainerStacksMetadata(type = "machine")
|
||||
other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id]
|
||||
if other_machine_stacks:
|
||||
self.setActiveMachine(other_machine_stacks[0]["id"])
|
||||
|
||||
metadata = ContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0]
|
||||
metadata = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)[0]
|
||||
network_key = metadata["um_network_key"] if "um_network_key" in metadata else None
|
||||
ExtruderManager.getInstance().removeMachineExtruders(machine_id)
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
|
||||
containers = CuraContainerRegistry.getInstance().findInstanceContainersMetadata(type = "user", machine = machine_id)
|
||||
for container in containers:
|
||||
ContainerRegistry.getInstance().removeContainer(container["id"])
|
||||
ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
CuraContainerRegistry.getInstance().removeContainer(container["id"])
|
||||
CuraContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
|
||||
# If the printer that is being removed is a network printer, the hidden printers have to be also removed
|
||||
if network_key:
|
||||
metadata_filter = {"um_network_key": network_key}
|
||||
hidden_containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
hidden_containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
if hidden_containers:
|
||||
# This reuses the method and remove all printers recursively
|
||||
self.removeMachine(hidden_containers[0].getId())
|
||||
|
@ -802,14 +810,17 @@ class MachineManager(QObject):
|
|||
|
||||
## Get the Definition ID of a machine (specified by ID)
|
||||
# \param machine_id string machine id to get the definition ID of
|
||||
# \returns DefinitionID (string) if found, None otherwise
|
||||
# \returns DefinitionID if found, None otherwise
|
||||
@pyqtSlot(str, result = str)
|
||||
def getDefinitionByMachineId(self, machine_id: str) -> str:
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
||||
def getDefinitionByMachineId(self, machine_id: str) -> Optional[str]:
|
||||
containers = CuraContainerRegistry.getInstance().findContainerStacks(id = machine_id)
|
||||
if containers:
|
||||
return containers[0].definition.getId()
|
||||
return None
|
||||
|
||||
def getIncompatibleSettingsOnEnabledExtruders(self, container: InstanceContainer) -> List[str]:
|
||||
if self._global_container_stack is None:
|
||||
return []
|
||||
extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||
result = [] # type: List[str]
|
||||
for setting_instance in container.findInstances():
|
||||
|
@ -834,6 +845,8 @@ class MachineManager(QObject):
|
|||
|
||||
## Update extruder number to a valid value when the number of extruders are changed, or when an extruder is changed
|
||||
def correctExtruderSettings(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
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)
|
||||
|
@ -851,6 +864,8 @@ class MachineManager(QObject):
|
|||
## 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: int) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
extruder_manager = self._application.getExtruderManager()
|
||||
|
||||
definition_changes_container = self._global_container_stack.definitionChanges
|
||||
|
@ -869,7 +884,7 @@ class MachineManager(QObject):
|
|||
|
||||
# Check to see if any objects are set to print with an extruder that will no longer exist
|
||||
root_node = self._application.getController().getScene().getRoot()
|
||||
for node in DepthFirstIterator(root_node):
|
||||
for node in DepthFirstIterator(root_node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
if node.getMeshData():
|
||||
extruder_nr = node.callDecoration("getActiveExtruderPosition")
|
||||
|
||||
|
@ -884,7 +899,7 @@ class MachineManager(QObject):
|
|||
global_user_container = self._global_container_stack.userChanges
|
||||
|
||||
# Make sure extruder_stacks exists
|
||||
extruder_stacks = []
|
||||
extruder_stacks = [] #type: List[ExtruderStack]
|
||||
|
||||
if previous_extruder_count == 1:
|
||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||
|
@ -912,6 +927,8 @@ class MachineManager(QObject):
|
|||
return extruder
|
||||
|
||||
def updateDefaultExtruder(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
extruder_items = sorted(self._global_container_stack.extruders.items())
|
||||
old_position = self._default_extruder_position
|
||||
new_default_position = "0"
|
||||
|
@ -924,6 +941,8 @@ class MachineManager(QObject):
|
|||
self.extruderChanged.emit()
|
||||
|
||||
def updateNumberExtrudersEnabled(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
definition_changes_container = self._global_container_stack.definitionChanges
|
||||
machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||
extruder_count = 0
|
||||
|
@ -936,6 +955,8 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtProperty(int, notify = numberExtrudersEnabledChanged)
|
||||
def numberExtrudersEnabled(self) -> int:
|
||||
if self._global_container_stack is None:
|
||||
return 1
|
||||
return self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
|
||||
|
||||
@pyqtProperty(str, notify = extruderChanged)
|
||||
|
@ -945,6 +966,8 @@ class MachineManager(QObject):
|
|||
## This will fire the propertiesChanged for all settings so they will be updated in the front-end
|
||||
@pyqtSlot()
|
||||
def forceUpdateAllSettings(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
property_names = ["value", "resolve", "validationState"]
|
||||
for container in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
|
||||
|
@ -954,8 +977,9 @@ class MachineManager(QObject):
|
|||
@pyqtSlot(int, bool)
|
||||
def setExtruderEnabled(self, position: int, enabled: bool) -> None:
|
||||
extruder = self.getExtruder(position)
|
||||
if not extruder:
|
||||
if not extruder or self._global_container_stack is None:
|
||||
Logger.log("w", "Could not find extruder on position %s", position)
|
||||
return
|
||||
|
||||
extruder.setEnabled(enabled)
|
||||
self.updateDefaultExtruder()
|
||||
|
@ -991,6 +1015,8 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtSlot(str, str, str)
|
||||
def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
for key, extruder in self._global_container_stack.extruders.items():
|
||||
container = extruder.userChanges
|
||||
container.setProperty(setting_name, property_name, property_value)
|
||||
|
@ -999,6 +1025,8 @@ class MachineManager(QObject):
|
|||
# \param setting_name The ID of the setting to reset.
|
||||
@pyqtSlot(str)
|
||||
def resetSettingForAllExtruders(self, setting_name: str) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
for key, extruder in self._global_container_stack.extruders.items():
|
||||
container = extruder.userChanges
|
||||
container.removeInstance(setting_name)
|
||||
|
@ -1041,6 +1069,8 @@ class MachineManager(QObject):
|
|||
# for all stacks in the currently active machine.
|
||||
#
|
||||
def _setEmptyQuality(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
self._current_quality_group = None
|
||||
self._current_quality_changes_group = None
|
||||
self._global_container_stack.quality = self._empty_quality_container
|
||||
|
@ -1052,12 +1082,14 @@ class MachineManager(QObject):
|
|||
self.activeQualityGroupChanged.emit()
|
||||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
||||
def _setQualityGroup(self, quality_group, empty_quality_changes: bool = True) -> None:
|
||||
def _setQualityGroup(self, quality_group: Optional[QualityGroup], empty_quality_changes: bool = True) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
if quality_group is None:
|
||||
self._setEmptyQuality()
|
||||
return
|
||||
|
||||
if quality_group.node_for_global.getContainer() is None:
|
||||
if quality_group.node_for_global is None or quality_group.node_for_global.getContainer() is None:
|
||||
return
|
||||
for node in quality_group.nodes_for_extruders.values():
|
||||
if node.getContainer() is None:
|
||||
|
@ -1081,14 +1113,15 @@ class MachineManager(QObject):
|
|||
self.activeQualityGroupChanged.emit()
|
||||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
||||
def _fixQualityChangesGroupToNotSupported(self, quality_changes_group):
|
||||
def _fixQualityChangesGroupToNotSupported(self, quality_changes_group: QualityChangesGroup) -> None:
|
||||
nodes = [quality_changes_group.node_for_global] + list(quality_changes_group.nodes_for_extruders.values())
|
||||
containers = [n.getContainer() for n in nodes if n is not None]
|
||||
for container in containers:
|
||||
container.setMetaDataEntry("quality_type", "not_supported")
|
||||
if container:
|
||||
container.setMetaDataEntry("quality_type", "not_supported")
|
||||
quality_changes_group.quality_type = "not_supported"
|
||||
|
||||
def _setQualityChangesGroup(self, quality_changes_group):
|
||||
def _setQualityChangesGroup(self, quality_changes_group: QualityChangesGroup) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return #Can't change that.
|
||||
quality_type = quality_changes_group.quality_type
|
||||
|
@ -1132,21 +1165,25 @@ class MachineManager(QObject):
|
|||
self.activeQualityGroupChanged.emit()
|
||||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
||||
def _setVariantNode(self, position, container_node):
|
||||
if container_node.getContainer() is None:
|
||||
def _setVariantNode(self, position: str, container_node: ContainerNode) -> None:
|
||||
if container_node.getContainer() is None or self._global_container_stack is None:
|
||||
return
|
||||
self._global_container_stack.extruders[position].variant = container_node.getContainer()
|
||||
self.activeVariantChanged.emit()
|
||||
|
||||
def _setGlobalVariant(self, container_node):
|
||||
def _setGlobalVariant(self, container_node: ContainerNode) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
self._global_container_stack.variant = container_node.getContainer()
|
||||
if not self._global_container_stack.variant:
|
||||
self._global_container_stack.variant = self._application.empty_variant_container
|
||||
|
||||
def _setMaterial(self, position, container_node = None):
|
||||
def _setMaterial(self, position: str, container_node: ContainerNode = None) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
if container_node and container_node.getContainer():
|
||||
self._global_container_stack.extruders[position].material = container_node.getContainer()
|
||||
root_material_id = container_node.metadata["base_file"]
|
||||
root_material_id = container_node.getMetaDataEntry("base_file", None)
|
||||
else:
|
||||
self._global_container_stack.extruders[position].material = self._empty_material_container
|
||||
root_material_id = None
|
||||
|
@ -1155,18 +1192,19 @@ class MachineManager(QObject):
|
|||
self._current_root_material_id[position] = root_material_id
|
||||
self.rootMaterialChanged.emit()
|
||||
|
||||
def activeMaterialsCompatible(self):
|
||||
def activeMaterialsCompatible(self) -> bool:
|
||||
# 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
|
||||
if self._global_container_stack is not None:
|
||||
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
|
||||
|
||||
## Update current quality type and machine after setting material
|
||||
def _updateQualityWithMaterial(self, *args):
|
||||
def _updateQualityWithMaterial(self, *args: Any) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
Logger.log("i", "Updating quality/quality_changes due to material change")
|
||||
|
@ -1205,7 +1243,7 @@ class MachineManager(QObject):
|
|||
current_quality_type, quality_type)
|
||||
self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = True)
|
||||
|
||||
def updateMaterialWithVariant(self, position: Optional[str]):
|
||||
def updateMaterialWithVariant(self, position: Optional[str]) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
if position is None:
|
||||
|
@ -1213,8 +1251,8 @@ class MachineManager(QObject):
|
|||
else:
|
||||
position_list = [position]
|
||||
|
||||
for position in position_list:
|
||||
extruder = self._global_container_stack.extruders[position]
|
||||
for position_item in position_list:
|
||||
extruder = self._global_container_stack.extruders[position_item]
|
||||
|
||||
current_material_base_name = extruder.material.getMetaDataEntry("base_file")
|
||||
current_variant_name = None
|
||||
|
@ -1232,28 +1270,28 @@ class MachineManager(QObject):
|
|||
material_diameter)
|
||||
|
||||
if not candidate_materials:
|
||||
self._setMaterial(position, container_node = None)
|
||||
self._setMaterial(position_item, container_node = None)
|
||||
continue
|
||||
|
||||
if current_material_base_name in candidate_materials:
|
||||
new_material = candidate_materials[current_material_base_name]
|
||||
self._setMaterial(position, new_material)
|
||||
self._setMaterial(position_item, new_material)
|
||||
continue
|
||||
|
||||
# The current material is not available, find the preferred one
|
||||
material_node = self._material_manager.getDefaultMaterial(self._global_container_stack, position, current_variant_name)
|
||||
if material_node is not None:
|
||||
self._setMaterial(position, material_node)
|
||||
self._setMaterial(position_item, material_node)
|
||||
|
||||
## Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new
|
||||
# instance with the same network key.
|
||||
@pyqtSlot(str)
|
||||
def switchPrinterType(self, machine_name: str) -> None:
|
||||
# Don't switch if the user tries to change to the same type of printer
|
||||
if self.activeMachineDefinitionName == machine_name:
|
||||
if self._global_container_stack is None or self.self.activeMachineDefinitionName == machine_name:
|
||||
return
|
||||
# Get the definition id corresponding to this machine name
|
||||
machine_definition_id = ContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId()
|
||||
machine_definition_id = CuraContainerRegistry.getInstance().findDefinitionContainers(name = machine_name)[0].getId()
|
||||
# Try to find a machine with the same network key
|
||||
new_machine = self.getMachine(machine_definition_id, metadata_filter = {"um_network_key": self.activeMachineNetworkKey})
|
||||
# If there is no machine, then create a new one and set it to the non-hidden instance
|
||||
|
@ -1275,6 +1313,8 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtSlot(QObject)
|
||||
def applyRemoteConfiguration(self, configuration: ConfigurationModel) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self.switchPrinterType(configuration.printerType)
|
||||
|
@ -1309,7 +1349,7 @@ class MachineManager(QObject):
|
|||
|
||||
## Find all container stacks that has the pair 'key = value' in its metadata and replaces the value with 'new_value'
|
||||
def replaceContainersMetadata(self, key: str, value: str, new_value: str) -> None:
|
||||
machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
machines = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
for machine in machines:
|
||||
if machine.getMetaDataEntry(key) == value:
|
||||
machine.setMetaDataEntry(key, new_value)
|
||||
|
@ -1322,18 +1362,18 @@ class MachineManager(QObject):
|
|||
# Check if the connect_group_name is correct. If not, update all the containers connected to the same printer
|
||||
if self.activeMachineNetworkGroupName != group_name:
|
||||
metadata_filter = {"um_network_key": self.activeMachineNetworkKey}
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
for container in containers:
|
||||
container.setMetaDataEntry("connect_group_name", group_name)
|
||||
|
||||
## This method checks if there is an instance connected to the given network_key
|
||||
def existNetworkInstances(self, network_key: str) -> bool:
|
||||
metadata_filter = {"um_network_key": network_key}
|
||||
containers = ContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
containers = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine", **metadata_filter)
|
||||
return bool(containers)
|
||||
|
||||
@pyqtSlot("QVariant")
|
||||
def setGlobalVariant(self, container_node):
|
||||
def setGlobalVariant(self, container_node: ContainerNode) -> None:
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self._setGlobalVariant(container_node)
|
||||
|
@ -1341,7 +1381,9 @@ class MachineManager(QObject):
|
|||
self._updateQualityWithMaterial()
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def setMaterialById(self, position, root_material_id):
|
||||
def setMaterialById(self, position: str, root_material_id: str) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
machine_definition_id = self._global_container_stack.definition.id
|
||||
position = str(position)
|
||||
extruder_stack = self._global_container_stack.extruders[position]
|
||||
|
@ -1364,12 +1406,14 @@ class MachineManager(QObject):
|
|||
|
||||
@pyqtSlot(str, str)
|
||||
def setVariantByName(self, position: str, variant_name: str) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
machine_definition_id = self._global_container_stack.definition.id
|
||||
variant_node = self._variant_manager.getVariantNode(machine_definition_id, variant_name)
|
||||
self.setVariant(position, variant_node)
|
||||
|
||||
@pyqtSlot(str, "QVariant")
|
||||
def setVariant(self, position: str, container_node):
|
||||
def setVariant(self, position: str, container_node: ContainerNode) -> None:
|
||||
position = str(position)
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
|
@ -1391,7 +1435,7 @@ class MachineManager(QObject):
|
|||
self.setQualityGroup(quality_group)
|
||||
|
||||
@pyqtSlot(QObject)
|
||||
def setQualityGroup(self, quality_group, no_dialog = False):
|
||||
def setQualityGroup(self, quality_group: QualityGroup, no_dialog: bool = False) -> None:
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self._setQualityGroup(quality_group)
|
||||
|
@ -1401,11 +1445,11 @@ class MachineManager(QObject):
|
|||
self._application.discardOrKeepProfileChanges()
|
||||
|
||||
@pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
|
||||
def activeQualityGroup(self):
|
||||
def activeQualityGroup(self) -> Optional[QualityGroup]:
|
||||
return self._current_quality_group
|
||||
|
||||
@pyqtSlot(QObject)
|
||||
def setQualityChangesGroup(self, quality_changes_group, no_dialog = False):
|
||||
def setQualityChangesGroup(self, quality_changes_group: QualityChangesGroup, no_dialog: bool = False) -> None:
|
||||
self.blurSettings.emit()
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self._setQualityChangesGroup(quality_changes_group)
|
||||
|
@ -1415,18 +1459,20 @@ class MachineManager(QObject):
|
|||
self._application.discardOrKeepProfileChanges()
|
||||
|
||||
@pyqtSlot()
|
||||
def resetToUseDefaultQuality(self):
|
||||
def resetToUseDefaultQuality(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self._setQualityGroup(self._current_quality_group)
|
||||
for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
|
||||
stack.userChanges.clear()
|
||||
|
||||
@pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)
|
||||
def activeQualityChangesGroup(self):
|
||||
def activeQualityChangesGroup(self) -> Optional[QualityChangesGroup]:
|
||||
return self._current_quality_changes_group
|
||||
|
||||
@pyqtProperty(str, notify = activeQualityGroupChanged)
|
||||
def activeQualityOrQualityChangesName(self):
|
||||
def activeQualityOrQualityChangesName(self) -> str:
|
||||
name = self._empty_quality_container.getName()
|
||||
if self._current_quality_changes_group:
|
||||
name = self._current_quality_changes_group.name
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from UM.Application import Application
|
||||
|
@ -9,7 +12,6 @@ from .CuraContainerStack import CuraContainerStack
|
|||
|
||||
|
||||
class PerObjectContainerStack(CuraContainerStack):
|
||||
|
||||
@override(CuraContainerStack)
|
||||
def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
|
||||
if context is None:
|
||||
|
@ -20,7 +22,7 @@ class PerObjectContainerStack(CuraContainerStack):
|
|||
|
||||
# Return the user defined value if present, otherwise, evaluate the value according to the default routine.
|
||||
if self.getContainer(0).hasProperty(key, property_name):
|
||||
if self.getContainer(0)._instances[key].state == InstanceState.User:
|
||||
if self.getContainer(0).getProperty(key, "state") == InstanceState.User:
|
||||
result = super().getProperty(key, property_name, context)
|
||||
context.popContainer()
|
||||
return result
|
||||
|
@ -53,13 +55,13 @@ class PerObjectContainerStack(CuraContainerStack):
|
|||
return result
|
||||
|
||||
@override(CuraContainerStack)
|
||||
def setNextStack(self, stack: CuraContainerStack):
|
||||
def setNextStack(self, stack: CuraContainerStack) -> None:
|
||||
super().setNextStack(stack)
|
||||
|
||||
# trigger signal to re-evaluate all default settings
|
||||
for key, instance in self.getContainer(0)._instances.items():
|
||||
for key in self.getContainer(0).getAllKeys():
|
||||
# only evaluate default settings
|
||||
if instance.state != InstanceState.Default:
|
||||
if self.getContainer(0).getProperty(key, "state") != InstanceState.Default:
|
||||
continue
|
||||
|
||||
self._collectPropertyChanges(key, "value")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List
|
||||
|
||||
from PyQt5.QtCore import QObject, QTimer, pyqtProperty, pyqtSignal
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
@ -13,6 +14,7 @@ from UM.Logger import Logger
|
|||
# speed settings. If all the children of print_speed have a single value override, changing the speed won't
|
||||
# actually do anything, as only the 'leaf' settings are used by the engine.
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Settings.SettingInstance import InstanceState
|
||||
|
||||
|
@ -157,7 +159,7 @@ class SettingInheritanceManager(QObject):
|
|||
stack = self._active_container_stack
|
||||
if not stack: #No active container stack yet!
|
||||
return False
|
||||
containers = []
|
||||
containers = [] # type: List[ContainerInterface]
|
||||
|
||||
## Check if the setting has a user state. If not, it is never overwritten.
|
||||
has_user_state = stack.getProperty(key, "state") == InstanceState.User
|
||||
|
|
|
@ -9,7 +9,6 @@ from UM.Signal import Signal, signalemitter
|
|||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Logger import Logger
|
||||
from UM.Util import parseBool
|
||||
|
||||
from UM.Application import Application
|
||||
|
||||
|
@ -40,7 +39,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
user_container = InstanceContainer(container_id = self._generateUniqueName())
|
||||
user_container.addMetaDataEntry("type", "user")
|
||||
self._stack.userChanges = user_container
|
||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0)
|
||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||
|
||||
self._is_non_printing_mesh = False
|
||||
self._is_non_thumbnail_visible_mesh = False
|
||||
|
@ -49,25 +48,13 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
|
||||
Application.getInstance().getContainerRegistry().addContainer(self._stack)
|
||||
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onNumberOfExtrudersEnabledChanged)
|
||||
Application.getInstance().getMachineManager().numberExtrudersEnabledChanged.connect(self._onNumberOfExtrudersEnabledChanged)
|
||||
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack)
|
||||
self.activeExtruderChanged.connect(self._updateNextStack)
|
||||
self._updateNextStack()
|
||||
|
||||
def _generateUniqueName(self):
|
||||
return "SettingOverrideInstanceContainer-%s" % uuid.uuid1()
|
||||
|
||||
def _onNumberOfExtrudersEnabledChanged(self, *args, **kwargs):
|
||||
if not parseBool(self._extruder_stack.getMetaDataEntry("enabled", "True")):
|
||||
# switch to the first extruder that's available
|
||||
global_stack = Application.getInstance().getMachineManager().activeMachine
|
||||
for _, extruder in sorted(list(global_stack.extruders.items())):
|
||||
if parseBool(extruder.getMetaDataEntry("enabled", "True")):
|
||||
self._extruder_stack = extruder
|
||||
self._updateNextStack()
|
||||
break
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
## Create a fresh decorator object
|
||||
deep_copy = SettingOverrideDecorator()
|
||||
|
@ -82,7 +69,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
deep_copy._stack.replaceContainer(0, instance_container)
|
||||
|
||||
# Properly set the right extruder on the copy
|
||||
deep_copy.setActiveExtruder(self._extruder_stack.getId())
|
||||
deep_copy.setActiveExtruder(self._extruder_stack)
|
||||
|
||||
# use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh"
|
||||
# has not been updated yet.
|
||||
|
@ -95,7 +82,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
#
|
||||
# \return An extruder's container stack.
|
||||
def getActiveExtruder(self):
|
||||
return self._extruder_stack.getId()
|
||||
return self._extruder_stack
|
||||
|
||||
## Gets the signal that emits if the active extruder changed.
|
||||
#
|
||||
|
@ -137,16 +124,20 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
# kept up to date.
|
||||
def _updateNextStack(self):
|
||||
if self._extruder_stack:
|
||||
if self._stack.getNextStack():
|
||||
old_extruder_stack_id = self._stack.getNextStack().getId()
|
||||
else:
|
||||
old_extruder_stack_id = ""
|
||||
extruder_stack = ContainerRegistry.getInstance().findContainerStacks(id = self._extruder_stack)
|
||||
if extruder_stack:
|
||||
if self._stack.getNextStack():
|
||||
old_extruder_stack_id = self._stack.getNextStack().getId()
|
||||
else:
|
||||
old_extruder_stack_id = ""
|
||||
|
||||
self._stack.setNextStack(self._extruder_stack)
|
||||
# Trigger slice/need slicing if the extruder changed.
|
||||
if self._stack.getNextStack().getId() != old_extruder_stack_id:
|
||||
Application.getInstance().getBackend().needsSlicing()
|
||||
Application.getInstance().getBackend().tickle()
|
||||
self._stack.setNextStack(extruder_stack[0])
|
||||
# Trigger slice/need slicing if the extruder changed.
|
||||
if self._stack.getNextStack().getId() != old_extruder_stack_id:
|
||||
Application.getInstance().getBackend().needsSlicing()
|
||||
Application.getInstance().getBackend().tickle()
|
||||
else:
|
||||
Logger.log("e", "Extruder stack %s below per-object settings does not exist.", self._extruder_stack)
|
||||
else:
|
||||
self._stack.setNextStack(Application.getInstance().getGlobalContainerStack())
|
||||
|
||||
|
@ -154,14 +145,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||
#
|
||||
# \param extruder_stack_id The new extruder stack to print with.
|
||||
def setActiveExtruder(self, extruder_stack_id):
|
||||
if self._extruder_stack.getId() == extruder_stack_id:
|
||||
return
|
||||
|
||||
global_stack = Application.getInstance().getMachineManager().activeMachine
|
||||
for extruder in global_stack.extruders.values():
|
||||
if extruder.getId() == extruder_stack_id:
|
||||
self._extruder_stack = extruder
|
||||
break
|
||||
self._extruder_stack = extruder_stack_id
|
||||
self._updateNextStack()
|
||||
ExtruderManager.getInstance().resetSelectedObjectExtruders()
|
||||
self.activeExtruderChanged.emit()
|
||||
|
|
|
@ -39,12 +39,12 @@ class SimpleModeSettingsManager(QObject):
|
|||
global_stack = self._machine_manager.activeMachine
|
||||
|
||||
# check user settings in the global stack
|
||||
user_setting_keys.update(set(global_stack.userChanges.getAllKeys()))
|
||||
user_setting_keys.update(global_stack.userChanges.getAllKeys())
|
||||
|
||||
# check user settings in the extruder stacks
|
||||
if global_stack.extruders:
|
||||
for extruder_stack in global_stack.extruders.values():
|
||||
user_setting_keys.update(set(extruder_stack.userChanges.getAllKeys()))
|
||||
user_setting_keys.update(extruder_stack.userChanges.getAllKeys())
|
||||
|
||||
# remove settings that are visible in recommended (we don't show the reset button for those)
|
||||
for skip_key in self.__ignored_custom_setting_keys:
|
||||
|
@ -70,12 +70,12 @@ class SimpleModeSettingsManager(QObject):
|
|||
global_stack = self._machine_manager.activeMachine
|
||||
|
||||
# check quality changes settings in the global stack
|
||||
quality_changes_keys.update(set(global_stack.qualityChanges.getAllKeys()))
|
||||
quality_changes_keys.update(global_stack.qualityChanges.getAllKeys())
|
||||
|
||||
# check quality changes settings in the extruder stacks
|
||||
if global_stack.extruders:
|
||||
for extruder_stack in global_stack.extruders.values():
|
||||
quality_changes_keys.update(set(extruder_stack.qualityChanges.getAllKeys()))
|
||||
quality_changes_keys.update(extruder_stack.qualityChanges.getAllKeys())
|
||||
|
||||
# check if the qualityChanges container is not empty (meaning it is a user created profile)
|
||||
has_quality_changes = len(quality_changes_keys) > 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue