mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-12-28 10:10:27 -07:00
Merge branch 'CURA-12660_painting-UI-improvements' into CURA-12449_handling-painted-models-map
This commit is contained in:
commit
08a9bbe52c
7 changed files with 34 additions and 60 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
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)
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue