ExtruderStack.py 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright (c) 2017 Ultimaker B.V.
  2. # Cura is released under the terms of the AGPLv3 or higher.
  3. from typing import Any, TYPE_CHECKING, Optional
  4. from UM.Decorators import override
  5. from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
  6. from UM.Settings.ContainerStack import ContainerStack
  7. from UM.Settings.ContainerRegistry import ContainerRegistry
  8. from UM.Settings.Interfaces import ContainerInterface
  9. from . import Exceptions
  10. from .CuraContainerStack import CuraContainerStack
  11. from .ExtruderManager import ExtruderManager
  12. if TYPE_CHECKING:
  13. from cura.Settings.GlobalStack import GlobalStack
  14. ## Represents an Extruder and its related containers.
  15. #
  16. #
  17. class ExtruderStack(CuraContainerStack):
  18. def __init__(self, container_id, *args, **kwargs):
  19. super().__init__(container_id, *args, **kwargs)
  20. self.addMetaDataEntry("type", "extruder_train") # For backward compatibility
  21. ## Overridden from ContainerStack
  22. #
  23. # This will set the next stack and ensure that we register this stack as an extruder.
  24. @override(ContainerStack)
  25. def setNextStack(self, stack: ContainerStack) -> None:
  26. super().setNextStack(stack)
  27. stack.addExtruder(self)
  28. self.addMetaDataEntry("machine", stack.id)
  29. # For backward compatibility: Register the extruder with the Extruder Manager
  30. ExtruderManager.getInstance().registerExtruder(self, stack.id)
  31. @override(ContainerStack)
  32. def getNextStack(self) -> Optional["GlobalStack"]:
  33. return super().getNextStack()
  34. @classmethod
  35. def getLoadingPriority(cls) -> int:
  36. return 3
  37. ## Overridden from ContainerStack
  38. #
  39. # It will perform a few extra checks when trying to get properties.
  40. #
  41. # The two extra checks it currently does is to ensure a next stack is set and to bypass
  42. # the extruder when the property is not settable per extruder.
  43. #
  44. # \throws Exceptions.NoGlobalStackError Raised when trying to get a property from an extruder without
  45. # having a next stack set.
  46. @override(ContainerStack)
  47. def getProperty(self, key: str, property_name: str) -> Any:
  48. if not self._next_stack:
  49. raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
  50. if not super().getProperty(key, "settable_per_extruder"):
  51. return self.getNextStack().getProperty(key, property_name)
  52. limit_to_extruder = super().getProperty(key, "limit_to_extruder")
  53. if (limit_to_extruder is not None and limit_to_extruder != "-1") and self.getMetaDataEntry("position") != str(limit_to_extruder):
  54. result = self.getNextStack().extruders[str(limit_to_extruder)].getProperty(key, property_name)
  55. if result is not None:
  56. return result
  57. return super().getProperty(key, property_name)
  58. @override(CuraContainerStack)
  59. def _getMachineDefinition(self) -> ContainerInterface:
  60. if not self.getNextStack():
  61. raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
  62. return self.getNextStack()._getMachineDefinition()
  63. @override(CuraContainerStack)
  64. def deserialize(self, contents: str) -> None:
  65. super().deserialize(contents)
  66. stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", ""))
  67. if stacks:
  68. self.setNextStack(stacks[0])
  69. extruder_stack_mime = MimeType(
  70. name = "application/x-cura-extruderstack",
  71. comment = "Cura Extruder Stack",
  72. suffixes = ["extruder.cfg"]
  73. )
  74. MimeTypeDatabase.addMimeType(extruder_stack_mime)
  75. ContainerRegistry.addContainerTypeByName(ExtruderStack, "extruder_stack", extruder_stack_mime.name)