Browse Source

CURA-4104 added first sucky build plate selection options

Jack Ha 7 years ago
parent
commit
5b368fbfd5

+ 2 - 0
cura/BuildPlateModel.py

@@ -0,0 +1,2 @@
+
+

+ 43 - 0
cura/CuraActions.py

@@ -19,6 +19,11 @@ from cura.MultiplyObjectsJob import MultiplyObjectsJob
 from cura.Settings.SetObjectExtruderOperation import SetObjectExtruderOperation
 from cura.Settings.SetObjectExtruderOperation import SetObjectExtruderOperation
 from cura.Settings.ExtruderManager import ExtruderManager
 from cura.Settings.ExtruderManager import ExtruderManager
 
 
+from cura.Operations.SetBuildPlateNumberOperation import SetBuildPlateNumberOperation
+
+from UM.Logger import Logger
+
+
 class CuraActions(QObject):
 class CuraActions(QObject):
     def __init__(self, parent = None):
     def __init__(self, parent = None):
         super().__init__(parent)
         super().__init__(parent)
@@ -124,5 +129,43 @@ class CuraActions(QObject):
             operation.addOperation(SetObjectExtruderOperation(node, extruder_id))
             operation.addOperation(SetObjectExtruderOperation(node, extruder_id))
         operation.push()
         operation.push()
 
 
+    @pyqtSlot(int)
+    def setBuildPlateForSelection(self, build_plate_nr: int) -> None:
+        Logger.log("d", "Setting build plate number... %d" % build_plate_nr)
+        operation = GroupedOperation()
+
+        nodes_to_change = []
+        for node in Selection.getAllSelectedObjects():
+            # Do not change any nodes that already have the right extruder set.
+            if node.callDecoration("getBuildPlateNumber") == build_plate_nr:
+                continue
+
+            # If the node is a group, apply the active extruder to all children of the group.
+            if node.callDecoration("isGroup"):
+                for grouped_node in BreadthFirstIterator(node):
+                    if grouped_node.callDecoration("getBuildPlateNumber") == build_plate_nr:
+                        continue
+
+                    if grouped_node.callDecoration("isGroup"):
+                        continue
+
+                    nodes_to_change.append(grouped_node)
+                continue
+
+            nodes_to_change.append(node)
+
+        if not nodes_to_change:
+            Logger.log("d", "Nothing to change.")
+            # If there are no changes to make, we still need to reset the selected extruders.
+            # This is a workaround for checked menu items being deselected while still being
+            # selected.
+            #ExtruderManager.getInstance().resetSelectedObjectExtruders()
+            return
+
+        Logger.log("d", "Yes: %s", nodes_to_change)
+        for node in nodes_to_change:
+            operation.addOperation(SetBuildPlateNumberOperation(node, build_plate_nr))
+        operation.push()
+
     def _openUrl(self, url):
     def _openUrl(self, url):
         QDesktopServices.openUrl(url)
         QDesktopServices.openUrl(url)

+ 34 - 2
cura/CuraApplication.py

@@ -1,4 +1,5 @@
 # Copyright (c) 2017 Ultimaker B.V.
 # Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2017 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 # Cura is released under the terms of the LGPLv3 or higher.
 
 
 from PyQt5.QtNetwork import QLocalServer
 from PyQt5.QtNetwork import QLocalServer
@@ -53,6 +54,9 @@ from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
 from cura.Settings.UserProfilesModel import UserProfilesModel
 from cura.Settings.UserProfilesModel import UserProfilesModel
 from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
 from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
 
 
+# research
+from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
+
 from . import PlatformPhysics
 from . import PlatformPhysics
 from . import BuildVolume
 from . import BuildVolume
 from . import CameraAnimation
 from . import CameraAnimation
@@ -376,6 +380,10 @@ class CuraApplication(QtApplication):
 
 
         self._plugin_registry.addSupportedPluginExtension("curaplugin", "Cura Plugin")
         self._plugin_registry.addSupportedPluginExtension("curaplugin", "Cura Plugin")
 
 
+        # research
+        self._num_build_plates = 1  # default
+        self._active_build_plate = 1
+
     def _onEngineCreated(self):
     def _onEngineCreated(self):
         self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider())
         self._engine.addImageProvider("camera", CameraImageProvider.CameraImageProvider())
 
 
@@ -855,6 +863,8 @@ class CuraApplication(QtApplication):
     activityChanged = pyqtSignal()
     activityChanged = pyqtSignal()
     sceneBoundingBoxChanged = pyqtSignal()
     sceneBoundingBoxChanged = pyqtSignal()
     preferredOutputMimetypeChanged = pyqtSignal()
     preferredOutputMimetypeChanged = pyqtSignal()
+    numBuildPlatesChanged = pyqtSignal()
+    activeBuildPlateChanged = pyqtSignal()
 
 
     @pyqtProperty(bool, notify = activityChanged)
     @pyqtProperty(bool, notify = activityChanged)
     def platformActivity(self):
     def platformActivity(self):
@@ -1025,7 +1035,7 @@ class CuraApplication(QtApplication):
             op.push()
             op.push()
             Selection.clear()
             Selection.clear()
 
 
-    ## Reset all translation on nodes with mesh data. 
+    ## Reset all translation on nodes with mesh data.
     @pyqtSlot()
     @pyqtSlot()
     def resetAllTranslation(self):
     def resetAllTranslation(self):
         Logger.log("i", "Resetting all scene translations")
         Logger.log("i", "Resetting all scene translations")
@@ -1150,7 +1160,7 @@ class CuraApplication(QtApplication):
                 job.start()
                 job.start()
             else:
             else:
                 Logger.log("w", "Unable to reload data because we don't have a filename.")
                 Logger.log("w", "Unable to reload data because we don't have a filename.")
-    
+
     ##  Get logging data of the backend engine
     ##  Get logging data of the backend engine
     #   \returns \type{string} Logging data
     #   \returns \type{string} Logging data
     @pyqtSlot(result = str)
     @pyqtSlot(result = str)
@@ -1373,6 +1383,7 @@ class CuraApplication(QtApplication):
         for node in nodes:
         for node in nodes:
             node.setSelectable(True)
             node.setSelectable(True)
             node.setName(os.path.basename(filename))
             node.setName(os.path.basename(filename))
+            node.addDecorator(BuildPlateDecorator())
 
 
             extension = os.path.splitext(filename)[1]
             extension = os.path.splitext(filename)[1]
             if extension.lower() in self._non_sliceable_extensions:
             if extension.lower() in self._non_sliceable_extensions:
@@ -1445,3 +1456,24 @@ class CuraApplication(QtApplication):
                     node = node.getParent()
                     node = node.getParent()
 
 
                 Selection.add(node)
                 Selection.add(node)
+
+    #### research - hacky place for these kind of thing
+    @pyqtSlot(int)
+    def setActiveBuildPlate(self, nr):
+        Logger.log("d", "Select build plate: %s" % nr)
+        self._active_build_plate = nr
+        self.activeBuildPlateChanged.emit()
+
+    @pyqtSlot()
+    def newBuildPlate(self):
+        Logger.log("d", "New build plate")
+        self._num_build_plates += 1
+        self.numBuildPlatesChanged.emit()
+
+    @pyqtProperty(int, notify = numBuildPlatesChanged)
+    def numBuildPlates(self):
+        return self._num_build_plates
+
+    @pyqtProperty(int, notify = activeBuildPlateChanged)
+    def activeBuildPlate(self):
+        return self._active_build_plate

+ 27 - 0
cura/Operations/SetBuildPlateNumberOperation.py

@@ -0,0 +1,27 @@
+# Copyright (c) 2017 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Scene.SceneNode import SceneNode
+from UM.Operations.Operation import Operation
+
+from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
+
+##  Simple operation to set the extruder a certain object should be printed with.
+class SetBuildPlateNumberOperation(Operation):
+    def __init__(self, node: SceneNode, build_plate_nr: int) -> None:
+        self._node = node
+        self._build_plate_nr = build_plate_nr
+        self._previous_build_plate_nr = None
+        self._decorator_added = False
+
+    def undo(self):
+        if self._previous_build_plate_nr:
+            self._node.callDecoration("setBuildPlateNumber", self._previous_build_plate_nr)
+
+    def redo(self):
+        stack = self._node.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
+        if not stack:
+            self._node.addDecorator(SettingOverrideDecorator())
+
+        self._previous_build_plate_nr = self._node.callDecoration("getBuildPlateNumber")
+        self._node.callDecoration("setBuildPlateNumber", self._build_plate_nr)

+ 34 - 0
cura/Scene/BuildPlateDecorator.py

@@ -0,0 +1,34 @@
+from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
+from UM.Scene.Selection import Selection
+
+
+class BuildPlateDecorator(SceneNodeDecorator):
+    def __init__(self):
+        super().__init__()
+        self._build_plate_number = -1
+
+    def setBuildPlateNumber(self, nr):
+        self._build_plate_number = nr
+        # self.getNode().childrenChanged.connect(self._onChildrenChanged)
+
+    def getBuildPlateNumber(self):
+        return self._build_plate_number
+
+    # def setNode(self, node):
+    #     super().setNode(node)
+    #     self.getNode().childrenChanged.connect(self._onChildrenChanged)
+
+    # def _onChildrenChanged(self, node):
+    #     if not self.getNode().hasChildren():
+    #         # A group that no longer has children may remove itself from the scene
+    #         self._old_parent = self.getNode().getParent()
+    #         self.getNode().setParent(None)
+    #         Selection.remove(self.getNode())
+    #     else:
+    #         # A group that has removed itself from the scene because it had no children may add itself back to the scene when a child is added to it
+    #         if not self.getNode().getParent() and self._old_parent:
+    #             self.getNode().setParent(self._old_parent)
+    #             self._old_parent = None
+
+    def __deepcopy__(self, memo):
+        return BuildPlateDecorator()

+ 20 - 0
resources/qml/Menus/ContextMenu.qml

@@ -39,6 +39,26 @@ Menu
         onObjectRemoved: base.removeItem(object)
         onObjectRemoved: base.removeItem(object)
     }
     }
 
 
+    MenuSeparator {}
+    MenuItem {
+        text: "build plate 0";
+        onTriggered: CuraActions.setBuildPlateForSelection(0);
+        checkable: true
+        checked: false
+    }
+    MenuItem {
+        text: "build plate 1";
+        onTriggered: CuraActions.setBuildPlateForSelection(1);
+        checkable: true
+        checked: false
+    }
+    MenuItem {
+        text: "build plate 2";
+        onTriggered: CuraActions.setBuildPlateForSelection(2);
+        checkable: true
+        checked: false
+    }
+
     // Global actions
     // Global actions
     MenuSeparator {}
     MenuSeparator {}
     MenuItem { action: Cura.Actions.selectAll; }
     MenuItem { action: Cura.Actions.selectAll; }

+ 19 - 0
resources/qml/Menus/ViewMenu.qml

@@ -28,6 +28,25 @@ Menu
     }
     }
     ExclusiveGroup { id: group; }
     ExclusiveGroup { id: group; }
 
 
+    MenuSeparator {}
+    MenuItem {
+        text: "build plate 0";
+        onTriggered: CuraApplication.setActiveBuildPlate(0);
+    }
+    MenuItem {
+        text: "build plate 1";
+        onTriggered: CuraApplication.setActiveBuildPlate(1);
+    }
+    MenuItem {
+        text: "build plate 2";
+        onTriggered: CuraApplication.setActiveBuildPlate(2);
+    }
+    ExclusiveGroup { id: buildPlateGroup; }
+
+    MenuItem {
+        text: "New build plate";
+        onTriggered: CuraApplication.newBuildPlate();
+    }
     MenuSeparator {}
     MenuSeparator {}
     MenuItem { action: Cura.Actions.homeCamera; }
     MenuItem { action: Cura.Actions.homeCamera; }
 }
 }