mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-16 11:17:49 -06:00
CURA-4104 added first sucky build plate selection options
This commit is contained in:
parent
74a7f02166
commit
5b368fbfd5
7 changed files with 179 additions and 2 deletions
2
cura/BuildPlateModel.py
Normal file
2
cura/BuildPlateModel.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
cura/Operations/SetBuildPlateNumberOperation.py
Normal file
27
cura/Operations/SetBuildPlateNumberOperation.py
Normal file
|
@ -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
cura/Scene/BuildPlateDecorator.py
Normal file
34
cura/Scene/BuildPlateDecorator.py
Normal file
|
@ -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()
|
|
@ -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; }
|
||||||
|
|
|
@ -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; }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue