-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
MeasureToolHandle.py
92 lines (71 loc) · 3.04 KB
/
MeasureToolHandle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Copyright (c) 2023 Aldo Hoeben / fieldOfView
# MeasureTool is released under the terms of the AGPLv3 or higher.
from UM.Mesh.MeshData import MeshData, calculateNormalsFromIndexedVertices
from UM.Scene.ToolHandle import ToolHandle
from UM.Math.Vector import Vector
from UM.View.GL.OpenGL import OpenGL
from UM.Resources import Resources
import trimesh
import numpy
from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .MeasureTool import MeasureTool
class MeasureToolHandle(ToolHandle):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self._name = "MeasureToolHandle"
self._handle_width = 2
self._selection_mesh = MeshData()
self._tool = None # type: Optional[MeasureTool]
def setTool(self, tool: "MeasureTool") -> None:
self._tool = tool
def buildMesh(self) -> None:
mesh = self._toMeshData(
trimesh.creation.icosphere(subdivisions=2, radius=self._handle_width / 2)
)
self.setSolidMesh(mesh)
def render(self, renderer) -> bool:
if not self._shader:
self._shader = OpenGL.getInstance().createShaderProgram(
Resources.getPath(Resources.Shaders, "toolhandle.shader")
)
if self._auto_scale:
active_camera = self._scene.getActiveCamera()
if active_camera.isPerspective():
camera_position = active_camera.getWorldPosition()
dist = (camera_position - self.getWorldPosition()).length()
scale = dist / 400
else:
view_width = active_camera.getViewportWidth()
current_size = view_width + (
2 * active_camera.getZoomFactor() * view_width
)
scale = current_size / view_width * 5
self.setScale(Vector(scale, scale, scale))
if self._solid_mesh and self._tool:
for position in [self._tool.getPointA(), self._tool.getPointB()]:
self.setPosition(Vector(position.x(), position.y(), position.z()))
renderer.queueNode(
self, mesh=self._solid_mesh, overlay=False, shader=self._shader
)
return True
def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData:
tri_faces = tri_node.faces
tri_vertices = tri_node.vertices
indices = []
vertices = []
index_count = 0
face_count = 0
for tri_face in tri_faces:
face = []
for tri_index in tri_face:
vertices.append(tri_vertices[tri_index])
face.append(index_count)
index_count += 1
indices.append(face)
face_count += 1
vertices = numpy.asarray(vertices, dtype=numpy.float32)
indices = numpy.asarray(indices, dtype=numpy.int32)
normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
mesh_data = MeshData(vertices=vertices, indices=indices, normals=normals)
return mesh_data