diff options
Diffstat (limited to 'cura/PickingPass.py')
-rw-r--r-- | cura/PickingPass.py | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/cura/PickingPass.py b/cura/PickingPass.py index 75ee21ef41..eb190be16d 100644 --- a/cura/PickingPass.py +++ b/cura/PickingPass.py @@ -1,14 +1,16 @@ -# Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional, TYPE_CHECKING from UM.Qt.QtApplication import QtApplication +from UM.Logger import Logger from UM.Math.Vector import Vector from UM.Resources import Resources from UM.View.RenderPass import RenderPass from UM.View.GL.OpenGL import OpenGL +from UM.View.GL.ShaderProgram import InvalidShaderProgramError from UM.View.RenderBatch import RenderBatch from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -16,11 +18,15 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator if TYPE_CHECKING: from UM.View.GL.ShaderProgram import ShaderProgram -## A RenderPass subclass that renders a the distance of selectable objects from the active camera to a texture. -# The texture is used to map a 2d location (eg the mouse location) to a world space position -# -# Note that in order to increase precision, the 24 bit depth value is encoded into all three of the R,G & B channels class PickingPass(RenderPass): + """A :py:class:`Uranium.UM.View.RenderPass` subclass that renders a the distance of selectable objects from the + active camera to a texture. + + The texture is used to map a 2d location (eg the mouse location) to a world space position + + .. note:: that in order to increase precision, the 24 bit depth value is encoded into all three of the R,G & B channels + """ + def __init__(self, width: int, height: int) -> None: super().__init__("picking", width, height) @@ -31,7 +37,11 @@ class PickingPass(RenderPass): def render(self) -> None: if not self._shader: - self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "camera_distance.shader")) + try: + self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "camera_distance.shader")) + except InvalidShaderProgramError: + Logger.error("Unable to compile shader program: camera_distance.shader") + return width, height = self.getSize() self._gl.glViewport(0, 0, width, height) @@ -44,14 +54,20 @@ class PickingPass(RenderPass): # Fill up the batch with objects that can be sliced. ` for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax. if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible(): - batch.addItem(node.getWorldTransformation(), node.getMeshData()) + batch.addItem(node.getWorldTransformation(copy = False), node.getMeshData(), normal_transformation=node.getCachedNormalMatrix()) self.bind() batch.render(self._scene.getActiveCamera()) self.release() - ## Get the distance in mm from the camera to at a certain pixel coordinate. def getPickedDepth(self, x: int, y: int) -> float: + """Get the distance in mm from the camera to at a certain pixel coordinate. + + :param x: x component of coordinate vector in pixels + :param y: y component of coordinate vector in pixels + :return: distance in mm from the camera to pixel coordinate + """ + output = self.getOutput() window_size = self._renderer.getWindowSize() @@ -66,8 +82,14 @@ class PickingPass(RenderPass): distance = (distance & 0x00ffffff) / 1000. # drop the alpha channel and covert to mm return distance - ## Get the world coordinates of a picked point def getPickedPosition(self, x: int, y: int) -> Vector: + """Get the world coordinates of a picked point + + :param x: x component of coordinate vector in pixels + :param y: y component of coordinate vector in pixels + :return: vector of the world coordinate + """ + distance = self.getPickedDepth(x, y) camera = self._scene.getActiveCamera() if camera: |