PrinterConfigurationModel.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright (c) 2025 UltiMaker
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
  4. from typing import List
  5. from UM.Settings.ContainerRegistry import ContainerRegistry
  6. from UM.Settings.DefinitionContainer import DefinitionContainer
  7. MYPY = False
  8. if MYPY:
  9. from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
  10. class PrinterConfigurationModel(QObject):
  11. configurationChanged = pyqtSignal()
  12. def __init__(self) -> None:
  13. super().__init__()
  14. self._printer_type = ""
  15. self._extruder_configurations = [] # type: List[ExtruderConfigurationModel]
  16. self._buildplate_configuration = ""
  17. def setPrinterType(self, printer_type: str) -> None:
  18. self._printer_type = printer_type
  19. @pyqtProperty(str, fset = setPrinterType, notify = configurationChanged)
  20. def printerType(self) -> str:
  21. return self._printer_type
  22. def setExtruderConfigurations(self, extruder_configurations: List["ExtruderConfigurationModel"]) -> None:
  23. if self._extruder_configurations != extruder_configurations:
  24. self._extruder_configurations = extruder_configurations
  25. for extruder_configuration in self._extruder_configurations:
  26. extruder_configuration.extruderConfigurationChanged.connect(self.configurationChanged)
  27. self.configurationChanged.emit()
  28. @pyqtProperty("QVariantList", fset = setExtruderConfigurations, notify = configurationChanged)
  29. def extruderConfigurations(self):
  30. return self._extruder_configurations
  31. def setBuildplateConfiguration(self, buildplate_configuration: str) -> None:
  32. if self._buildplate_configuration != buildplate_configuration:
  33. self._buildplate_configuration = buildplate_configuration
  34. self.configurationChanged.emit()
  35. @pyqtProperty(str, fset = setBuildplateConfiguration, notify = configurationChanged)
  36. def buildplateConfiguration(self) -> str:
  37. return self._buildplate_configuration
  38. def isValid(self) -> bool:
  39. """This method is intended to indicate whether the configuration is valid or not.
  40. The method checks if the mandatory fields are or not set
  41. """
  42. if not self._extruder_configurations:
  43. return False
  44. for configuration in self._extruder_configurations:
  45. if configuration is None:
  46. return False
  47. return self._printer_type != ""
  48. def hasAnyMaterialLoaded(self) -> bool:
  49. if not self.isValid():
  50. return False
  51. for configuration in self._extruder_configurations:
  52. if configuration.activeMaterial and configuration.activeMaterial.type != "empty":
  53. return True
  54. return False
  55. @pyqtProperty("QStringList", constant=True)
  56. def validCoresForPrinterType(self) -> List[str]:
  57. printers = ContainerRegistry.getInstance().findContainersMetadata(
  58. ignore_case=True, type="machine", name=self._printer_type, container_type=DefinitionContainer)
  59. id = printers[0]["id"] if len(printers) > 0 and "id" in printers[0] else ""
  60. definitions = ContainerRegistry.getInstance().findContainersMetadata(
  61. ignore_case=True, type="variant", definition=id+"*")
  62. return [x["name"] for x in definitions]
  63. def __str__(self):
  64. message_chunks = []
  65. message_chunks.append("Printer type: " + self._printer_type)
  66. message_chunks.append("Extruders: [")
  67. for configuration in self._extruder_configurations:
  68. message_chunks.append(" " + str(configuration))
  69. message_chunks.append("]")
  70. if self._buildplate_configuration is not None:
  71. message_chunks.append("Buildplate: " + self._buildplate_configuration)
  72. return "\n".join(message_chunks)
  73. def __eq__(self, other):
  74. if not isinstance(other, PrinterConfigurationModel):
  75. return False
  76. if self.printerType != other.printerType:
  77. return False
  78. if self.buildplateConfiguration != other.buildplateConfiguration:
  79. return False
  80. if len(self.extruderConfigurations) != len(other.extruderConfigurations):
  81. return False
  82. for self_extruder, other_extruder in zip(sorted(self._extruder_configurations, key=lambda x: x.position), sorted(other.extruderConfigurations, key=lambda x: x.position)):
  83. if self_extruder != other_extruder:
  84. return False
  85. return True
  86. def __hash__(self):
  87. """The hash function is used to compare and create unique sets. The configuration is unique if the configuration
  88. of the extruders is unique (the order of the extruders matters), and the type and buildplate is the same.
  89. """
  90. extruder_hash = hash(0)
  91. first_extruder = None
  92. for configuration in self._extruder_configurations:
  93. extruder_hash ^= hash(configuration)
  94. if configuration.position == 0:
  95. first_extruder = configuration
  96. # To ensure the correct order of the extruders, we add an "and" operation using the first extruder hash value
  97. if first_extruder:
  98. extruder_hash &= hash(first_extruder)
  99. return hash(self._printer_type) ^ extruder_hash ^ hash(self._buildplate_configuration)