Cura/cura/Settings/ExtruderStack.py
Arjen Hiemstra a7bf205dbc Turn GlobalStack's extruders property into a dict
We do not load the extruders in a fixed order, thus we cannot assume
that addExtruder is called in the right order. This means that index 0
of the extruders is not necessarily the extruder with position 0. So
instead, use the extruder position as a dict key.

Contributes to CURA-3738
2017-05-17 10:58:28 +02:00

95 lines
3.7 KiB
Python

# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from typing import Any, TYPE_CHECKING, Optional
from UM.Decorators import override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface
from . import Exceptions
from .CuraContainerStack import CuraContainerStack
from .ExtruderManager import ExtruderManager
if TYPE_CHECKING:
from cura.Settings.GlobalStack import GlobalStack
## Represents an Extruder and its related containers.
#
#
class ExtruderStack(CuraContainerStack):
def __init__(self, container_id, *args, **kwargs):
super().__init__(container_id, *args, **kwargs)
self.addMetaDataEntry("type", "extruder_train") # For backward compatibility
## Overridden from ContainerStack
#
# This will set the next stack and ensure that we register this stack as an extruder.
@override(ContainerStack)
def setNextStack(self, stack: ContainerStack) -> None:
super().setNextStack(stack)
stack.addExtruder(self)
self.addMetaDataEntry("machine", stack.id)
# For backward compatibility: Register the extruder with the Extruder Manager
ExtruderManager.getInstance().registerExtruder(self, stack.id)
@override(ContainerStack)
def getNextStack(self) -> Optional["GlobalStack"]:
return super().getNextStack()
@classmethod
def getLoadingPriority(cls) -> int:
return 3
## Overridden from ContainerStack
#
# It will perform a few extra checks when trying to get properties.
#
# The two extra checks it currently does is to ensure a next stack is set and to bypass
# the extruder when the property is not settable per extruder.
#
# \throws Exceptions.NoGlobalStackError Raised when trying to get a property from an extruder without
# having a next stack set.
@override(ContainerStack)
def getProperty(self, key: str, property_name: str) -> Any:
if not self._next_stack:
raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
if not super().getProperty(key, "settable_per_extruder"):
return self.getNextStack().getProperty(key, property_name)
limit_to_extruder = super().getProperty(key, "limit_to_extruder")
if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name)
if result is not None:
return result
return super().getProperty(key, property_name)
@override(CuraContainerStack)
def _getMachineDefinition(self) -> ContainerInterface:
if not self.getNextStack():
raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
return self.getNextStack()._getMachineDefinition()
@override(CuraContainerStack)
def deserialize(self, contents: str) -> None:
super().deserialize(contents)
stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", ""))
if stacks:
self.setNextStack(stacks[0])
extruder_stack_mime = MimeType(
name = "application/x-cura-extruderstack",
comment = "Cura Extruder Stack",
suffixes = ["extruder.cfg"]
)
MimeTypeDatabase.addMimeType(extruder_stack_mime)
ContainerRegistry.addContainerTypeByName(ExtruderStack, "extruder_stack", extruder_stack_mime.name)