123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- from PyQt6.QtCore import QObject, QUrl
- from PyQt6.QtGui import QDesktopServices
- from typing import List, cast
- from UM.Event import CallFunctionEvent
- from UM.FlameProfiler import pyqtSlot
- from UM.Math.Vector import Vector
- from UM.Scene.Selection import Selection
- from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
- from UM.Operations.GroupedOperation import GroupedOperation
- from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
- from UM.Operations.TranslateOperation import TranslateOperation
- import cura.CuraApplication
- from cura.Operations.SetParentOperation import SetParentOperation
- from cura.MultiplyObjectsJob import MultiplyObjectsJob
- from cura.Settings.SetObjectExtruderOperation import SetObjectExtruderOperation
- from cura.Settings.ExtruderManager import ExtruderManager
- from cura.Operations.SetBuildPlateNumberOperation import SetBuildPlateNumberOperation
- from UM.Logger import Logger
- from UM.Scene.SceneNode import SceneNode
- class CuraActions(QObject):
- def __init__(self, parent: QObject = None) -> None:
- super().__init__(parent)
- @pyqtSlot()
- def openDocumentation(self) -> None:
-
-
-
- event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/resources/manuals/software?utm_source=cura&utm_medium=software&utm_campaign=dropdown-documentation")], {})
- cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
- @pyqtSlot()
- def openBugReportPage(self) -> None:
- event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues/new/choose")], {})
- cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
- @pyqtSlot()
- def homeCamera(self) -> None:
- """Reset camera position and direction to default"""
- scene = cura.CuraApplication.CuraApplication.getInstance().getController().getScene()
- camera = scene.getActiveCamera()
- if camera:
- diagonal_size = cura.CuraApplication.CuraApplication.getInstance().getBuildVolume().getDiagonalSize()
- camera.setPosition(Vector(-80, 250, 700) * diagonal_size / 375)
- camera.setPerspective(True)
- camera.lookAt(Vector(0, 0, 0))
- @pyqtSlot()
- def centerSelection(self) -> None:
- """Center all objects in the selection"""
- operation = GroupedOperation()
- for node in Selection.getAllSelectedObjects():
- current_node = node
- parent_node = current_node.getParent()
- while parent_node and parent_node.callDecoration("isGroup"):
- current_node = parent_node
- parent_node = current_node.getParent()
-
- bbox = current_node.getBoundingBox()
- if bbox:
- center_y = current_node.getWorldPosition().y - bbox.bottom
- else:
- center_y = 0
-
- center_operation = TranslateOperation(current_node, Vector(0, center_y, 0), set_position = True)
- operation.addOperation(center_operation)
- operation.push()
- @pyqtSlot(int)
- def multiplySelection(self, count: int) -> None:
- """Multiply all objects in the selection
- :param count: The number of times to multiply the selection.
- """
- min_offset = cura.CuraApplication.CuraApplication.getInstance().getBuildVolume().getEdgeDisallowedSize() + 2
- job = MultiplyObjectsJob(Selection.getAllSelectedObjects(), count, min_offset = max(min_offset, 8))
- job.start()
- @pyqtSlot()
- def deleteSelection(self) -> None:
- """Delete all selected objects."""
- if not cura.CuraApplication.CuraApplication.getInstance().getController().getToolsEnabled():
- return
- removed_group_nodes = []
- op = GroupedOperation()
- nodes = Selection.getAllSelectedObjects()
- for node in nodes:
- op.addOperation(RemoveSceneNodeOperation(node))
- group_node = node.getParent()
- if group_node and group_node.callDecoration("isGroup") and group_node not in removed_group_nodes:
- remaining_nodes_in_group = list(set(group_node.getChildren()) - set(nodes))
- if len(remaining_nodes_in_group) == 1:
- removed_group_nodes.append(group_node)
- op.addOperation(SetParentOperation(remaining_nodes_in_group[0], group_node.getParent()))
- op.addOperation(RemoveSceneNodeOperation(group_node))
-
- cura.CuraApplication.CuraApplication.getInstance().getController().getScene().sceneChanged.emit(node)
- op.push()
- @pyqtSlot(str)
- def setExtruderForSelection(self, extruder_id: str) -> None:
- """Set the extruder that should be used to print the selection.
- :param extruder_id: The ID of the extruder stack to use for the selected objects.
- """
- operation = GroupedOperation()
- nodes_to_change = []
- for node in Selection.getAllSelectedObjects():
-
- if node.callDecoration("isGroup"):
- for grouped_node in BreadthFirstIterator(node):
- if grouped_node.callDecoration("getActiveExtruder") == extruder_id:
- continue
- if grouped_node.callDecoration("isGroup"):
- continue
- nodes_to_change.append(grouped_node)
- continue
-
- if node.callDecoration("getActiveExtruder") == extruder_id:
- continue
- nodes_to_change.append(node)
- if not nodes_to_change:
-
-
-
- ExtruderManager.getInstance().resetSelectedObjectExtruders()
- return
- for node in nodes_to_change:
- operation.addOperation(SetObjectExtruderOperation(node, extruder_id))
- 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()
- root = cura.CuraApplication.CuraApplication.getInstance().getController().getScene().getRoot()
- nodes_to_change = []
- for node in Selection.getAllSelectedObjects():
- parent_node = node
- while parent_node.getParent() != root:
- parent_node = cast(SceneNode, parent_node.getParent())
- for single_node in BreadthFirstIterator(parent_node):
- nodes_to_change.append(single_node)
- if not nodes_to_change:
- Logger.log("d", "Nothing to change.")
- return
- for node in nodes_to_change:
- operation.addOperation(SetBuildPlateNumberOperation(node, build_plate_nr))
- operation.push()
- Selection.clear()
- def _openUrl(self, url: QUrl) -> None:
- QDesktopServices.openUrl(url)
|