ObjectsModel.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from PyQt5.QtCore import QTimer
  4. from UM.Application import Application
  5. from UM.Qt.ListModel import ListModel
  6. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
  7. from UM.Scene.SceneNode import SceneNode
  8. from UM.Scene.Selection import Selection
  9. from UM.Preferences import Preferences
  10. from UM.i18n import i18nCatalog
  11. catalog = i18nCatalog("cura")
  12. ## Keep track of all objects in the project
  13. class ObjectsModel(ListModel):
  14. def __init__(self):
  15. super().__init__()
  16. Application.getInstance().getController().getScene().sceneChanged.connect(self._updateDelayed)
  17. Preferences.getInstance().preferenceChanged.connect(self._updateDelayed)
  18. self._update_timer = QTimer()
  19. self._update_timer.setInterval(100)
  20. self._update_timer.setSingleShot(True)
  21. self._update_timer.timeout.connect(self._update)
  22. self._build_plate_number = -1
  23. def setActiveBuildPlate(self, nr):
  24. self._build_plate_number = nr
  25. self._update()
  26. def _updateDelayed(self, *args):
  27. self._update_timer.start()
  28. def _update(self, *args):
  29. nodes = []
  30. filter_current_build_plate = Preferences.getInstance().getValue("view/filter_current_build_plate")
  31. active_build_plate_number = self._build_plate_number
  32. group_nr = 1
  33. for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
  34. if not isinstance(node, SceneNode):
  35. continue
  36. if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"):
  37. continue
  38. if node.getParent() and node.getParent().callDecoration("isGroup"):
  39. continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
  40. if not node.callDecoration("isSliceable") and not node.callDecoration("isGroup"):
  41. continue
  42. node_build_plate_number = node.callDecoration("getBuildPlateNumber")
  43. if filter_current_build_plate and node_build_plate_number != active_build_plate_number:
  44. continue
  45. if not node.callDecoration("isGroup"):
  46. name = node.getName()
  47. else:
  48. name = catalog.i18nc("@label", "Group #{group_nr}").format(group_nr = str(group_nr))
  49. group_nr += 1
  50. if hasattr(node, "isOutsideBuildArea"):
  51. is_outside_build_area = node.isOutsideBuildArea()
  52. else:
  53. is_outside_build_area = False
  54. nodes.append({
  55. "name": name,
  56. "isSelected": Selection.isSelected(node),
  57. "isOutsideBuildArea": is_outside_build_area,
  58. "buildPlateNumber": node_build_plate_number,
  59. "node": node
  60. })
  61. nodes = sorted(nodes, key=lambda n: n["name"])
  62. self.setItems(nodes)
  63. self.itemsChanged.emit()
  64. @staticmethod
  65. def createObjectsModel():
  66. return ObjectsModel()