123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- from UM.Logger import Logger
- from PyQt5.QtCore import Qt, pyqtSlot, QObject
- from PyQt5.QtWidgets import QApplication
- from UM.Scene.Camera import Camera
- from cura.ObjectsModel import ObjectsModel
- from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
- from UM.Application import Application
- from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
- from UM.Scene.SceneNode import SceneNode
- from UM.Scene.Selection import Selection
- from UM.Signal import Signal
- class CuraSceneController(QObject):
- activeBuildPlateChanged = Signal()
- def __init__(self, objects_model: ObjectsModel, multi_build_plate_model: MultiBuildPlateModel) -> None:
- super().__init__()
- self._objects_model = objects_model
- self._multi_build_plate_model = multi_build_plate_model
- self._active_build_plate = -1
- self._last_selected_index = 0
- self._max_build_plate = 1 # default
- Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlate) # it may be a bit inefficient when changing a lot simultaneously
- def updateMaxBuildPlate(self, *args):
- if args:
- source = args[0]
- else:
- source = None
- if not isinstance(source, SceneNode) or isinstance(source, Camera):
- return
- max_build_plate = self._calcMaxBuildPlate()
- changed = False
- if max_build_plate != self._max_build_plate:
- self._max_build_plate = max_build_plate
- changed = True
- if changed:
- self._multi_build_plate_model.setMaxBuildPlate(self._max_build_plate)
- build_plates = [{"name": "Build Plate %d" % (i + 1), "buildPlateNumber": i} for i in range(self._max_build_plate + 1)]
- self._multi_build_plate_model.setItems(build_plates)
- if self._active_build_plate > self._max_build_plate:
- build_plate_number = 0
- if self._last_selected_index >= 0: # go to the buildplate of the item you last selected
- item = self._objects_model.getItem(self._last_selected_index)
- if "node" in item:
- node = item["node"]
- build_plate_number = node.callDecoration("getBuildPlateNumber")
- self.setActiveBuildPlate(build_plate_number)
- # self.buildPlateItemsChanged.emit() # TODO: necessary after setItems?
- def _calcMaxBuildPlate(self):
- max_build_plate = 0
- for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()):
- if node.callDecoration("isSliceable"):
- build_plate_number = node.callDecoration("getBuildPlateNumber")
- if build_plate_number is None:
- build_plate_number = 0
- max_build_plate = max(build_plate_number, max_build_plate)
- return max_build_plate
- ## Either select or deselect an item
- @pyqtSlot(int)
- def changeSelection(self, index):
- modifiers = QApplication.keyboardModifiers()
- ctrl_is_active = modifiers & Qt.ControlModifier
- shift_is_active = modifiers & Qt.ShiftModifier
- if ctrl_is_active:
- item = self._objects_model.getItem(index)
- node = item["node"]
- if Selection.isSelected(node):
- Selection.remove(node)
- else:
- Selection.add(node)
- elif shift_is_active:
- polarity = 1 if index + 1 > self._last_selected_index else -1
- for i in range(self._last_selected_index, index + polarity, polarity):
- item = self._objects_model.getItem(i)
- node = item["node"]
- Selection.add(node)
- else:
- # Single select
- item = self._objects_model.getItem(index)
- node = item["node"]
- build_plate_number = node.callDecoration("getBuildPlateNumber")
- if build_plate_number is not None and build_plate_number != -1:
- self.setActiveBuildPlate(build_plate_number)
- Selection.clear()
- Selection.add(node)
- self._last_selected_index = index
- @pyqtSlot(int)
- def setActiveBuildPlate(self, nr):
- if nr == self._active_build_plate:
- return
- Logger.log("d", "Select build plate: %s" % nr)
- self._active_build_plate = nr
- Selection.clear()
- self._multi_build_plate_model.setActiveBuildPlate(nr)
- self._objects_model.setActiveBuildPlate(nr)
- self.activeBuildPlateChanged.emit()
- @staticmethod
- def createCuraSceneController():
- objects_model = Application.getInstance().getObjectsModel()
- multi_build_plate_model = Application.getInstance().getMultiBuildPlateModel()
- return CuraSceneController(objects_model = objects_model, multi_build_plate_model = multi_build_plate_model)
|