diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5ce358080c..57d4773cb3 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1038,7 +1038,6 @@ class CuraApplication(QtApplication): # Initialize UI state controller.setActiveStage("PrepareStage") - controller.setActiveView("SolidView") controller.setCameraTool("CameraTool") controller.setSelectionTool("SelectionTool") @@ -2089,9 +2088,7 @@ class CuraApplication(QtApplication): is_non_sliceable = "." + file_extension in self._non_sliceable_extensions if is_non_sliceable: - # Need to switch first to the preview stage and then to layer view - self.callLater(lambda: (self.getController().setActiveStage("PreviewStage"), - self.getController().setActiveView("SimulationView"))) + self.callLater(lambda: (self.getController().setActiveStage("PreviewStage"))) block_slicing_decorator = BlockSlicingDecorator() node.addDecorator(block_slicing_decorator) diff --git a/cura/Stages/CuraStage.py b/cura/Stages/CuraStage.py index 869ed309dc..8c207db8ad 100644 --- a/cura/Stages/CuraStage.py +++ b/cura/Stages/CuraStage.py @@ -1,6 +1,8 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from typing import Optional + from PyQt6.QtCore import pyqtProperty, QUrl from UM.Stage import Stage @@ -13,8 +15,8 @@ from UM.Stage import Stage # * The MainComponent is the component that will be drawn starting from the bottom of the stageBar and fills the rest # of the screen. class CuraStage(Stage): - def __init__(self, parent = None) -> None: - super().__init__(parent) + def __init__(self, parent = None, active_view: Optional[str] = "SolidView") -> None: + super().__init__(parent, active_view = active_view) @pyqtProperty(str, constant = True) def stageId(self) -> str: diff --git a/plugins/PaintTool/PaintTool.py b/plugins/PaintTool/PaintTool.py index 7b77b02a9d..6417960d7c 100644 --- a/plugins/PaintTool/PaintTool.py +++ b/plugins/PaintTool/PaintTool.py @@ -59,7 +59,8 @@ class PaintTool(Tool): self.setExposedProperties("PaintType", "BrushSize", "BrushColor", "BrushShape", "BrushExtruder") - Selection.selectionChanged.connect(self._updateIgnoreUnselectedObjects) + Selection.selectionChanged.connect(self._updateActiveView) + self._controller.activeViewChanged.connect(self._updateIgnoreUnselectedObjects) def _createBrushPen(self) -> QPen: pen = QPen() @@ -307,14 +308,9 @@ class PaintTool(Tool): # Make sure the displayed values are updated if the bounding box of the selected mesh(es) changes if event.type == Event.ToolActivateEvent: - controller.setActiveView("PaintTool") # Because that's the plugin-name, and the view is registered to it. - self._updateIgnoreUnselectedObjects() return True if event.type == Event.ToolDeactivateEvent: - controller.setActiveView("SolidView") - CuraApplication.getInstance().getRenderer().getRenderPass("selection").setIgnoreUnselectedObjects(False) - CuraApplication.getInstance().getRenderer().getRenderPass("selection_faces").setIgnoreUnselectedObjects(False) return True if event.type == Event.MouseReleaseEvent and self._controller.getToolsEnabled(): @@ -407,6 +403,9 @@ class PaintTool(Tool): return False + def getRequiredExtraRenderingPasses(self) -> list[str]: + return ["selection_faces", "picking_selected"] + @staticmethod def _updateScene(node: SceneNode = None): if node is None: @@ -414,11 +413,10 @@ class PaintTool(Tool): if node is not None: Application.getInstance().getController().getScene().sceneChanged.emit(node) - def getRequiredExtraRenderingPasses(self) -> list[str]: - return ["selection_faces", "picking_selected"] + def _updateActiveView(self): + self.setActiveView("PaintTool" if len(Selection.getAllSelectedObjects()) == 1 else None) def _updateIgnoreUnselectedObjects(self): - if self._controller.getActiveTool() is self: - ignore_unselected_objects = len(Selection.getAllSelectedObjects()) == 1 - CuraApplication.getInstance().getRenderer().getRenderPass("selection").setIgnoreUnselectedObjects(ignore_unselected_objects) - CuraApplication.getInstance().getRenderer().getRenderPass("selection_faces").setIgnoreUnselectedObjects(ignore_unselected_objects) \ No newline at end of file + ignore_unselected_objects = self._controller.getActiveView().name == "PaintTool" + CuraApplication.getInstance().getRenderer().getRenderPass("selection").setIgnoreUnselectedObjects(ignore_unselected_objects) + CuraApplication.getInstance().getRenderer().getRenderPass("selection_faces").setIgnoreUnselectedObjects(ignore_unselected_objects) \ No newline at end of file diff --git a/plugins/PaintTool/PaintView.py b/plugins/PaintTool/PaintView.py index e7d5125ebb..b9d1f572f8 100644 --- a/plugins/PaintTool/PaintView.py +++ b/plugins/PaintTool/PaintView.py @@ -9,9 +9,9 @@ from PyQt6.QtGui import QImage, QColor, QPainter from cura.CuraApplication import CuraApplication from cura.BuildVolume import BuildVolume +from cura.CuraView import CuraView from Machines.Models.ExtrudersModel import ExtrudersModel from UM.PluginRegistry import PluginRegistry -from UM.View.View import View from UM.View.GL.ShaderProgram import ShaderProgram from UM.View.GL.Texture import Texture from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -23,7 +23,7 @@ from UM.Math.Color import Color catalog = i18nCatalog("cura") -class PaintView(View): +class PaintView(CuraView): """View for model-painting.""" UNDO_STACK_SIZE = 1024 @@ -34,7 +34,7 @@ class PaintView(View): self.value: int = value def __init__(self) -> None: - super().__init__() + super().__init__(use_empty_menu_placeholder = True) self._paint_shader: Optional[ShaderProgram] = None self._current_paint_texture: Optional[Texture] = None self._current_bits_ranges: tuple[int, int] = (0, 0) @@ -51,8 +51,6 @@ class PaintView(View): application.engineCreatedSignal.connect(self._makePaintModes) self._scene = application.getController().getScene() - self._solid_view = None - self._extruders_model: Optional[ExtrudersModel] = None def _makePaintModes(self): @@ -219,18 +217,6 @@ class PaintView(View): if self._current_paint_type not in self._paint_modes: return - if self._solid_view is None: - plugin_registry = PluginRegistry.getInstance() - solid_view = plugin_registry.getPluginObject("SolidView") - if isinstance(solid_view, View): - self._solid_view = solid_view - - display_objects = Selection.getAllSelectedObjects().copy() - if len(display_objects) != 1 and self._solid_view is not None: - # Display the classic view until a single object is selected - self._solid_view.beginRendering() - return - self._checkSetup() renderer = self.getRenderer() @@ -241,7 +227,7 @@ class PaintView(View): paint_batch = renderer.createRenderBatch(shader=self._paint_shader) renderer.addRenderBatch(paint_batch) - for node in display_objects: + for node in Selection.getAllSelectedObjects(): paint_batch.addItem(node.getWorldTransformation(copy=False), node.getMeshData(), normal_transformation=node.getCachedNormalMatrix()) self._current_paint_texture = node.callDecoration("getPaintTexture") self._paint_shader.setTexture(0, self._current_paint_texture) diff --git a/plugins/PreviewStage/PreviewStage.py b/plugins/PreviewStage/PreviewStage.py index 88f432ef9b..3f1a4423b2 100644 --- a/plugins/PreviewStage/PreviewStage.py +++ b/plugins/PreviewStage/PreviewStage.py @@ -24,25 +24,6 @@ class PreviewStage(CuraStage): super().__init__(parent) self._application = application self._application.engineCreatedSignal.connect(self._engineCreated) - self._previously_active_view = None # type: Optional[View] - - def onStageSelected(self) -> None: - """When selecting the stage, remember which was the previous view so that - - we can revert to that view when we go out of the stage later. - """ - self._previously_active_view = self._application.getController().getActiveView() - - def onStageDeselected(self) -> None: - """Called when going to a different stage (away from the Preview Stage). - - When going to a different stage, the view should be reverted to what it - was before. Normally, that just reverts it to solid view. - """ - - if self._previously_active_view is not None: - self._application.getController().setActiveView(self._previously_active_view.getPluginId()) - self._previously_active_view = None def _engineCreated(self) -> None: """Delayed load of the QML files. diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 083fc73bf1..5d339e7f74 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -172,13 +172,20 @@ class SimulationView(CuraView): self._updateSliceWarningVisibility() self.activityChanged.emit() - def getSimulationPass(self) -> SimulationPass: + def getSimulationPass(self) -> Optional[SimulationPass]: if not self._layer_pass: + renderer = self.getRenderer() + if renderer is None: + return None + # Currently the RenderPass constructor requires a size > 0 # This should be fixed in RenderPass's constructor. self._layer_pass = SimulationPass(1, 1) self._compatibility_mode = self._evaluateCompatibilityMode() self._layer_pass.setSimulationView(self) + self._layer_pass.setEnabled(False) + renderer.addRenderPass(self._layer_pass) + return self._layer_pass def getCurrentLayer(self) -> int: @@ -734,11 +741,14 @@ class SimulationView(CuraView): # Make sure the SimulationPass is created layer_pass = self.getSimulationPass() + if layer_pass is None: + return False + renderer = self.getRenderer() if renderer is None: return False - renderer.addRenderPass(layer_pass) + layer_pass.setEnabled(True) # Make sure the NozzleNode is add to the root nozzle = self.getNozzleNode() @@ -778,7 +788,7 @@ class SimulationView(CuraView): return False if self._layer_pass is not None: - renderer.removeRenderPass(self._layer_pass) + self._layer_pass.setEnabled(False) if self._composite_pass: self._composite_pass.setLayerBindings(cast(List[str], self._old_layer_bindings)) self._composite_pass.setCompositeShader(cast(ShaderProgram, self._old_composite_shader)) diff --git a/resources/qml/ViewsSelector.qml b/resources/qml/ViewsSelector.qml index e76e5dbb67..b0e31ac532 100644 --- a/resources/qml/ViewsSelector.qml +++ b/resources/qml/ViewsSelector.qml @@ -38,7 +38,7 @@ Cura.ExpandablePopup { if (activeView == null) { - UM.Controller.setActiveView(viewModel.getItem(0).id) + UM.Controller.activeStage.setActiveView(viewModel.getItem(0).id) } } @@ -110,7 +110,7 @@ Cura.ExpandablePopup onClicked: { toggleContent() - UM.Controller.setActiveView(id) + UM.Controller.activeStage.setActiveView(id) } } }