BrandMaterialsModel.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
  4. from UM.Qt.ListModel import ListModel
  5. from UM.Logger import Logger
  6. from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
  7. #
  8. # This is an intermediate model to group materials with different colours for a same brand and type.
  9. #
  10. class MaterialsModelGroupedByType(ListModel):
  11. NameRole = Qt.UserRole + 1
  12. ColorsRole = Qt.UserRole + 2
  13. def __init__(self, parent = None):
  14. super().__init__(parent)
  15. self.addRoleName(self.NameRole, "name")
  16. self.addRoleName(self.ColorsRole, "colors")
  17. #
  18. # This model is used to show branded materials in the material drop down menu.
  19. # The structure of the menu looks like this:
  20. # Brand -> Material Type -> list of materials
  21. #
  22. # To illustrate, a branded material menu may look like this:
  23. # Ultimaker -> PLA -> Yellow PLA
  24. # -> Black PLA
  25. # -> ...
  26. # -> ABS -> White ABS
  27. # ...
  28. #
  29. class BrandMaterialsModel(ListModel):
  30. NameRole = Qt.UserRole + 1
  31. MaterialsRole = Qt.UserRole + 2
  32. extruderPositionChanged = pyqtSignal()
  33. def __init__(self, parent = None):
  34. super().__init__(parent)
  35. self.addRoleName(self.NameRole, "name")
  36. self.addRoleName(self.MaterialsRole, "materials")
  37. self._extruder_position = 0
  38. from cura.CuraApplication import CuraApplication
  39. self._machine_manager = CuraApplication.getInstance().getMachineManager()
  40. self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
  41. self._material_manager = CuraApplication.getInstance().getMaterialManager()
  42. self._machine_manager.globalContainerChanged.connect(self._update)
  43. self._material_manager.materialsUpdated.connect(self._update)
  44. self._update()
  45. def setExtruderPosition(self, position: int):
  46. if self._extruder_position != position:
  47. self._extruder_position = position
  48. self.extruderPositionChanged.emit()
  49. @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged)
  50. def extruderPosition(self) -> int:
  51. return self._extruder_position
  52. def _update(self):
  53. Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
  54. global_stack = self._machine_manager.activeMachine
  55. if global_stack is None:
  56. self.setItems([])
  57. return
  58. extruder_position = str(self._extruder_position)
  59. if extruder_position not in global_stack.extruders:
  60. self.setItems([])
  61. return
  62. extruder_stack = global_stack.extruders[str(self._extruder_position)]
  63. available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
  64. extruder_stack)
  65. if available_material_dict is None:
  66. self.setItems([])
  67. return
  68. brand_item_list = []
  69. brand_group_dict = {}
  70. for root_material_id, container_node in available_material_dict.items():
  71. metadata = container_node.metadata
  72. brand = metadata["brand"]
  73. # Only add results for generic materials
  74. if brand.lower() == "generic":
  75. continue
  76. if brand not in brand_group_dict:
  77. brand_group_dict[brand] = {}
  78. material_type = metadata["material"]
  79. if material_type not in brand_group_dict[brand]:
  80. brand_group_dict[brand][material_type] = []
  81. item = {"root_material_id": root_material_id,
  82. "id": metadata["id"],
  83. "name": metadata["name"],
  84. "brand": metadata["brand"],
  85. "material": metadata["material"],
  86. "color_name": metadata["color_name"],
  87. "container_node": container_node
  88. }
  89. brand_group_dict[brand][material_type].append(item)
  90. for brand, material_dict in brand_group_dict.items():
  91. brand_item = {"name": brand,
  92. "materials": MaterialsModelGroupedByType(self)}
  93. material_type_item_list = []
  94. for material_type, material_list in material_dict.items():
  95. material_type_item = {"name": material_type,
  96. "colors": BaseMaterialsModel(self)}
  97. material_type_item["colors"].clear()
  98. # Sort materials by name
  99. material_list = sorted(material_list, key = lambda x: x["name"].upper())
  100. material_type_item["colors"].setItems(material_list)
  101. material_type_item_list.append(material_type_item)
  102. # Sort material type by name
  103. material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"].upper())
  104. brand_item["materials"].setItems(material_type_item_list)
  105. brand_item_list.append(brand_item)
  106. # Sort brand by name
  107. brand_item_list = sorted(brand_item_list, key = lambda x: x["name"].upper())
  108. self.setItems(brand_item_list)