ExtruderConfigurationModel.py 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. # Copyright (c) 2024 UltiMaker
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from typing import Optional
  4. from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
  5. from cura.PrinterOutput.FormatMaps import FormatMaps
  6. from .MaterialOutputModel import MaterialOutputModel
  7. class ExtruderConfigurationModel(QObject):
  8. extruderConfigurationChanged = pyqtSignal()
  9. def __init__(self, position: int = -1) -> None:
  10. super().__init__()
  11. self._position: int = position
  12. self._material: Optional[MaterialOutputModel] = None
  13. self._hotend_id: Optional[str] = None
  14. def setPosition(self, position: int) -> None:
  15. self._position = position
  16. @pyqtProperty(int, fset = setPosition, notify = extruderConfigurationChanged)
  17. def position(self) -> int:
  18. return self._position
  19. def setMaterial(self, material: Optional[MaterialOutputModel]) -> None:
  20. if material is None or self._material == material:
  21. return
  22. self._material = material
  23. self.extruderConfigurationChanged.emit()
  24. @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
  25. def activeMaterial(self) -> Optional[MaterialOutputModel]:
  26. return self._material
  27. @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged)
  28. def material(self) -> Optional[MaterialOutputModel]:
  29. return self._material
  30. def setHotendID(self, hotend_id: Optional[str]) -> None:
  31. if self._hotend_id != hotend_id:
  32. self._hotend_id = ExtruderConfigurationModel.applyNameMappingHotend(hotend_id)
  33. self.extruderConfigurationChanged.emit()
  34. @staticmethod
  35. def applyNameMappingHotend(hotendId) -> str:
  36. if hotendId in FormatMaps.EXTRUDER_NAME_MAP:
  37. return FormatMaps.EXTRUDER_NAME_MAP[hotendId]
  38. return hotendId
  39. @pyqtProperty(str, fset = setHotendID, notify = extruderConfigurationChanged)
  40. def hotendID(self) -> Optional[str]:
  41. return self._hotend_id
  42. def isValid(self) -> bool:
  43. """This method is intended to indicate whether the configuration is valid or not.
  44. The method checks if the mandatory fields are or not set
  45. At this moment is always valid since we allow to have empty material and variants.
  46. """
  47. return True
  48. def __str__(self) -> str:
  49. message_chunks = []
  50. message_chunks.append("Position: " + str(self._position))
  51. message_chunks.append("-")
  52. message_chunks.append("Material: " + self.activeMaterial.type if self.activeMaterial else "empty")
  53. message_chunks.append("-")
  54. message_chunks.append("HotendID: " + self.hotendID if self.hotendID else "empty")
  55. return " ".join(message_chunks)
  56. def __eq__(self, other) -> bool:
  57. if not isinstance(other, ExtruderConfigurationModel):
  58. return False
  59. if self._position != other.position:
  60. return False
  61. # Empty materials should be ignored for comparison
  62. if self.activeMaterial is not None and other.activeMaterial is not None:
  63. if self.activeMaterial.guid != other.activeMaterial.guid:
  64. if self.activeMaterial.guid == "" and other.activeMaterial.guid == "":
  65. # At this point there is no material, so it doesn't matter what the hotend is.
  66. return True
  67. else:
  68. return False
  69. if self.hotendID != other.hotendID:
  70. return False
  71. return True
  72. # Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is
  73. # unique within a set
  74. def __hash__(self):
  75. return hash(self._position) ^ (hash(self._material.guid) if self._material is not None else hash(0)) ^ hash(self._hotend_id)