Slightly optimize and refactor the w.i.p. paint-tool.

Just enought so that the truly ugly things are out of it.

part of CURA-12543
This commit is contained in:
Remco Burema 2025-05-21 15:19:07 +02:00
parent 19ea88a8ce
commit c5592eea83

View File

@ -8,6 +8,7 @@ from PyQt6.QtCore import Qt
from UM.Application import Application from UM.Application import Application
from UM.Event import Event, MouseEvent, KeyEvent from UM.Event import Event, MouseEvent, KeyEvent
from UM.Scene.Selection import Selection
from UM.Tool import Tool from UM.Tool import Tool
from cura.PickingPass import PickingPass from cura.PickingPass import PickingPass
@ -21,10 +22,9 @@ class PaintTool(Tool):
self._shortcut_key = Qt.Key.Key_P self._shortcut_key = Qt.Key.Key_P
""" self._node_cache = None
# CURA-5966 Make sure to render whenever objects get selected/deselected. self._mesh_transformed_cache = None
Selection.selectionChanged.connect(self.propertyChanged) self._cache_dirty = True
"""
@staticmethod @staticmethod
def _get_intersect_ratio_via_pt(a, pt, b, c): def _get_intersect_ratio_via_pt(a, pt, b, c):
@ -49,6 +49,9 @@ class PaintTool(Tool):
intersect = ((a + solved[0] * udir_a) + (b + solved[1] * udir_b)) * 0.5 intersect = ((a + solved[0] * udir_a) + (b + solved[1] * udir_b)) * 0.5
return numpy.linalg.norm(pt - intersect) / numpy.linalg.norm(a - intersect) return numpy.linalg.norm(pt - intersect) / numpy.linalg.norm(a - intersect)
def _nodeTransformChanged(self, *args) -> None:
self._cache_dirty = True
def event(self, event: Event) -> bool: def event(self, event: Event) -> bool:
"""Handle mouse and keyboard events. """Handle mouse and keyboard events.
@ -78,32 +81,33 @@ class PaintTool(Tool):
if not camera: if not camera:
return False return False
evt = cast(MouseEvent, event) node = Selection.getAllSelectedObjects()[0]
ppass = PickingPass(self._selection_pass._width, self._selection_pass._height)
ppass.render()
pt = ppass.getPickedPosition(evt.x, evt.y).getData()
self._selection_pass._renderObjectsMode() # TODO: <- Fix this!
node_id = self._selection_pass.getIdAtPosition(evt.x, evt.y)
if node_id is None:
return False
node = Application.getInstance().getController().getScene().findObject(node_id)
if node is None: if node is None:
return False return False
self._selection_pass._renderFacesMode() # TODO: <- Fix this! if node != self._node_cache:
if self._node_cache is not None:
self._node_cache.transformationChanged.disconnect(self._nodeTransformChanged)
self._node_cache = node
self._node_cache.transformationChanged.connect(self._nodeTransformChanged)
if self._cache_dirty:
self._cache_dirty = False
self._mesh_transformed_cache = self._node_cache.getMeshDataTransformed()
if not self._mesh_transformed_cache:
return False
evt = cast(MouseEvent, event)
self._selection_pass.renderFacesMode()
face_id = self._selection_pass.getFaceIdAtPosition(evt.x, evt.y) face_id = self._selection_pass.getFaceIdAtPosition(evt.x, evt.y)
if face_id < 0: if face_id < 0:
return False return False
meshdata = node.getMeshDataTransformed() # TODO: <- don't forget to optimize, if the mesh hasn't changed (transforms) then it should be reused! ppass = PickingPass(camera.getViewportWidth(), camera.getViewportHeight())
if not meshdata: ppass.render()
return False pt = ppass.getPickedPosition(evt.x, evt.y).getData()
va, vb, vc = meshdata.getFaceNodes(face_id) va, vb, vc = self._mesh_transformed_cache.getFaceNodes(face_id)
ta, tb, tc = node.getMeshData().getFaceUvCoords(face_id) ta, tb, tc = node.getMeshData().getFaceUvCoords(face_id)
# 'Weight' of each vertex that would produce point pt, so we can generate the texture coordinates from the uv ones of the vertices. # 'Weight' of each vertex that would produce point pt, so we can generate the texture coordinates from the uv ones of the vertices.
@ -120,7 +124,6 @@ class PaintTool(Tool):
solidview = Application.getInstance().getController().getActiveView() solidview = Application.getInstance().getController().getActiveView()
if solidview.getPluginId() != "SolidView": if solidview.getPluginId() != "SolidView":
return False return False
solidview.setUvPixel(texcoords[0], texcoords[1], [255, 128, 0, 255]) solidview.setUvPixel(texcoords[0], texcoords[1], [255, 128, 0, 255])
return True return True