Refactored paint-view into its own thing.

part of CURA-12543
This commit is contained in:
Remco Burema 2025-05-21 21:50:17 +02:00
parent c5592eea83
commit 3ae85e3e2a
5 changed files with 65 additions and 22 deletions

View File

@ -27,7 +27,7 @@ class PaintTool(Tool):
self._cache_dirty = True
@staticmethod
def _get_intersect_ratio_via_pt(a, pt, b, c):
def _get_intersect_ratio_via_pt(a, pt, b, c) -> float:
# compute the intersection of (param) A - pt with (param) B - (param) C
# compute unit vectors of directions of lines A and B
@ -61,12 +61,18 @@ class PaintTool(Tool):
"""
super().event(event)
controller = Application.getInstance().getController()
# Make sure the displayed values are updated if the bounding box of the selected mesh(es) changes
if event.type == Event.ToolActivateEvent:
return False
controller.setActiveStage("PrepareStage")
controller.setActiveView("PaintTool") # Because that's the plugin-name, and the view is registered to it.
return True
if event.type == Event.ToolDeactivateEvent:
return False
controller.setActiveStage("PrepareStage")
controller.setActiveView("SolidView")
return True
if event.type == Event.KeyPressEvent and cast(KeyEvent, event).key == KeyEvent.ShiftKey:
return False
@ -121,10 +127,10 @@ class PaintTool(Tool):
wc /= wt
texcoords = wa * ta + wb * tb + wc * tc
solidview = Application.getInstance().getController().getActiveView()
if solidview.getPluginId() != "SolidView":
paintview = controller.getActiveView()
if paintview.getPluginId() != "PaintTool":
return False
solidview.setUvPixel(texcoords[0], texcoords[1], [255, 128, 0, 255])
paintview.setUvPixel(texcoords[0], texcoords[1], [255, 128, 0, 255])
return True

View File

@ -0,0 +1,42 @@
# Copyright (c) 2025 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
import os
from UM.PluginRegistry import PluginRegistry
from UM.View.View import View
from UM.Scene.Selection import Selection
from UM.View.GL.OpenGL import OpenGL
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
class PaintView(View):
"""View for model-painting."""
def __init__(self) -> None:
super().__init__()
self._paint_shader = None
self._paint_texture = None
def _checkSetup(self):
if not self._paint_shader:
shader_filename = os.path.join(PluginRegistry.getInstance().getPluginPath("PaintTool"), "paint.shader")
self._paint_shader = OpenGL.getInstance().createShaderProgram(shader_filename)
if not self._paint_texture:
self._paint_texture = OpenGL.getInstance().createTexture(256, 256)
self._paint_shader.setTexture(0, self._paint_texture)
def setUvPixel(self, x, y, color) -> None:
self._paint_texture.setPixel(x, y, color)
def beginRendering(self) -> None:
renderer = self.getRenderer()
self._checkSetup()
paint_batch = renderer.createRenderBatch(shader=self._paint_shader)
renderer.addRenderBatch(paint_batch)
node = Selection.getAllSelectedObjects()[0]
if node is None:
return
paint_batch.addItem(node.getWorldTransformation(copy=False), node.getMeshData(), normal_transformation=node.getCachedNormalMatrix())

View File

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher.
from . import PaintTool
from . import PaintView
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("cura")
@ -14,8 +15,16 @@ def getMetaData():
"icon": "Visual",
"tool_panel": "PaintTool.qml",
"weight": 0
},
"view": {
"name": i18n_catalog.i18nc("@item:inmenu", "Paint view"),
"weight": 0,
"visible": False
}
}
def register(app):
return { "tool": PaintTool.PaintTool() }
return {
"tool": PaintTool.PaintTool(),
"view": PaintView.PaintView()
}

View File

@ -42,13 +42,11 @@ class SolidView(View):
super().__init__()
application = Application.getInstance()
application.getPreferences().addPreference(self._show_overhang_preference, True)
application.getPreferences().addPreference(self._paint_active_preference, False)
application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._enabled_shader = None
self._disabled_shader = None
self._non_printing_shader = None
self._support_mesh_shader = None
self._paint_shader = None
self._xray_shader = None
self._xray_pass = None
@ -142,11 +140,6 @@ class SolidView(View):
min_height = max(min_height, init_layer_height)
return min_height
def _setPaintTexture(self):
self._paint_texture = OpenGL.getInstance().createTexture(256, 256)
if self._paint_shader:
self._paint_shader.setTexture(0, self._paint_texture)
def _checkSetup(self):
if not self._extruders_model:
self._extruders_model = Application.getInstance().getExtrudersModel()
@ -175,10 +168,6 @@ class SolidView(View):
self._support_mesh_shader.setUniformValue("u_vertical_stripes", True)
self._support_mesh_shader.setUniformValue("u_width", 5.0)
if not self._paint_shader:
self._paint_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "paint.shader"))
self._setPaintTexture()
if not Application.getInstance().getPreferences().getValue(self._show_xray_warning_preference):
self._xray_shader = None
self._xray_composite_shader = None
@ -216,9 +205,6 @@ class SolidView(View):
self._old_composite_shader = self._composite_pass.getCompositeShader()
self._composite_pass.setCompositeShader(self._xray_composite_shader)
def setUvPixel(self, x, y, color):
self._paint_texture.setPixel(x, y, color)
def beginRendering(self):
scene = self.getController().getScene()
renderer = self.getRenderer()
@ -236,7 +222,7 @@ class SolidView(View):
else:
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0)))
self._enabled_shader.setUniformValue("u_lowestPrintableHeight", self._lowest_printable_height)
disabled_batch = renderer.createRenderBatch(shader = self._paint_shader) #### TODO: put back to 'self._disabled_shader'
disabled_batch = renderer.createRenderBatch(shader = self._disabled_shader)
normal_object_batch = renderer.createRenderBatch(shader = self._enabled_shader)
renderer.addRenderBatch(disabled_batch)
renderer.addRenderBatch(normal_object_batch)