This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
beam_vtk.py
336 lines (251 loc) · 11.6 KB
/
beam_vtk.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
import vtk
import Settings
import math
from beam import Main
import beam
import numpy as np
class Node(object):
"""
For rendering the node points as a sphere
"""
boxDepth = 2
height = 1
num_points_per_poly = 4
def __init__(self):
self.__polyData = vtk.vtkPolyData()
self.__sphere = vtk.vtkSphereSource()
self.__mapper = vtk.vtkPolyDataMapper()
self.__transform = vtk.vtkTransform()
self.__actor = vtk.vtkActor()
self.__sphere.SetRadius(.2)
self.__mapper.SetInputConnection(self.__sphere.GetOutputPort())
self.__actor.SetUserTransform(self.__transform)
self.__actor.SetMapper(self.__mapper)
self.__actor.GetProperty().SetColor(1, 0, 0)
# Attributes for rendering the beam shape. Not implemented,
# but a good next step
# @ben: this is a starting place to introduce a beam (or box) around each
# sphere object. These objects are not used yet, but I wanted to
# attributes needed to create the green polygon shape
# This VTK example would be a good place to look at how polygons are
# introduced:
#
# https://lorensen.github.io/VTKExamples/site/Python/GeometricObjects/Polygon/
#
# @ben: the purpose for defining a polygon object here is to map the object displacement
# to a sphere. The polygon objects could also be inside it's own seperate class ...
self.__cell = vtk.vtkCellArray()
self.__data = vtk.vtkPolyData()
self.__polygon_mapper = vtk.vtkPolyDataMapper()
self.__polygon_actor = vtk.vtkActor()
self.__polygon_filter = vtk.vtkTransformPolyDataFilter()
self.__polygon_transform = vtk.vtkTransform()
self.__points = vtk.vtkPoints()
self.__polygons = vtk.vtkCellArray() # we have 6 sides to each beam box.
self.__indices = []
self.__lines = vtk.vtkCellArray()
# This is overgeneralized because a beam
# is really a shell (4 sides) except for
# end points. But it is valid for now.
# Get node point actor
def get_actor(self):
return self.__actor
def get_poly_actor(self):
return self.__polygon_actor
# Generates all node specific actors and adds to renderer
def add_poly_actor_to_renderer(self, renderer, next_node, x_val, y_val):
node_actor = self.get_actor()
renderer.AddActor(node_actor)
self.update_position(x_val, y_val, 0)
# Add back side quad data
self.get_fb_quad_points(next_node, -1)
# Add front side quad data
self.get_fb_quad_points(next_node, 1)
# Add bottom side quad data
self.get_top_quad_points(next_node, -self.height)
# Add top side quad data
self.get_top_quad_points(next_node, self.height)
# Add left side quad data
self.add_lr_side_quad_data(next_node, -1)
# Add right side quad data
self.add_lr_side_quad_data(next_node, 1)
# Update nodes polyData
self.__polyData.SetLines(self.__lines)
self.__polyData.SetPolys(self.__polygons)
self.__polyData.SetPoints(self.__points)
# Set Transformation/Filter/Mapper properties
self.__polygon_mapper.SetInputData(self.__polyData)
self.__polygon_filter.SetInputData(self.__polyData)
self.__polygon_filter.SetTransform(self.__polygon_transform)
self.__polygon_actor.SetMapper(self.__polygon_mapper)
self.__polygon_actor.GetProperty().SetLineWidth(2)
self.__polygon_actor.GetProperty().SetColor(0, 1, 0)
renderer.AddActor(self.__polygon_actor)
# Add front or back side quad data
def get_fb_quad_points(self, nextNode, zMod):
node_center = self.get_actor().GetCenter()
node_x = node_center[0]
node_y = node_center[1]
# Non rendered last point
next_node_x = Settings.x_vals[-1]
next_node_y = Settings.shared_main.eval_current_function(next_node_x, Settings.current_t_val)
if nextNode is not None:
next_node_x = nextNode.get_actor().GetCenter()[0]
next_node_y = nextNode.get_actor().GetCenter()[1]
dx = math.fabs(next_node_x - node_x) / 2
depth = self.boxDepth * zMod
# Side quad points
points = vtk.vtkPoints()
points.SetNumberOfPoints(4)
points.SetPoint(0, node_x - dx, node_y - self.height, depth)
points.SetPoint(1, node_x + dx, next_node_y - self.height, depth)
points.SetPoint(2, node_x + dx, next_node_y + self.height, depth)
points.SetPoint(3, node_x - dx, node_y + self.height, depth)
self.add_quad_data(points)
# Add top quad data
def get_top_quad_points(self, next_node, height, last=False):
node_center = self.get_actor().GetCenter()
node_x = node_center[0]
node_y = node_center[1]
next_node_x = Settings.x_vals[-1]
next_node_y = Settings.shared_main.eval_current_function(next_node_x, Settings.current_t_val)
if next_node is not None:
next_node_center = next_node.get_actor().GetCenter()
next_node_x = next_node_center[0]
next_node_y = next_node_center[1]
dx = math.fabs(next_node_x - node_x) / 2
# Top Quad Points
points = vtk.vtkPoints()
points.SetNumberOfPoints(4)
if last:
height *=-1
points.SetPoint(0, node_x - dx, node_y + height, self.boxDepth)
points.SetPoint(1, node_x + dx, next_node_y + height, self.boxDepth)
points.SetPoint(2, node_x + dx, next_node_y + height, -self.boxDepth)
points.SetPoint(3, node_x - dx, node_y + height, -self.boxDepth)
self.add_quad_data(points)
# Get actor for left or right side quad
def add_lr_side_quad_data(self, next_node, dx_mod):
node_center = self.get_actor().GetCenter()
node_x = node_center[0]
node_y = node_center[1]
next_node_x = Settings.x_vals[-1]
next_node_y = Settings.shared_main.eval_current_function(next_node_x, Settings.current_t_val)
if next_node is not None:
next_node_center = next_node.get_actor().GetCenter()
next_node_x = next_node_center[0]
next_node_y = next_node_center[1]
dx = math.fabs((next_node_x - node_x) / 2) * dx_mod
# Side quad points
points = vtk.vtkPoints()
points.SetNumberOfPoints(4)
if dx_mod > 0:
points.SetPoint(0, node_x + dx, next_node_y - self.height, self.boxDepth)
points.SetPoint(1, node_x + dx, next_node_y + self.height, self.boxDepth)
points.SetPoint(2, node_x + dx, next_node_y + self.height, -self.boxDepth)
points.SetPoint(3, node_x + dx, next_node_y - self.height, -self.boxDepth)
else:
points.SetPoint(0, node_x + dx, node_y - self.height, self.boxDepth)
points.SetPoint(1, node_x + dx, node_y + self.height, self.boxDepth)
points.SetPoint(2, node_x + dx, node_y + self.height, -self.boxDepth)
points.SetPoint(3, node_x + dx, node_y - self.height, -self.boxDepth)
self.add_quad_data(points)
# Return quad actor with either wireframe or filled based on "transparent" flag
def add_quad_data(self, points):
# Each point index is ((the index of its poly) * (num points in poly)) + (relative id of point)
poly_index = self.__polygons.GetNumberOfCells()
id_base = poly_index * self.num_points_per_poly
# Generates ID Lists for adding quad points
point_id_list = vtk.vtkIdList()
rel_id_list = vtk.vtkIdList()
for rel_id in range(self.num_points_per_poly):
rel_id_list.InsertNextId(rel_id)
index = id_base + rel_id
self.__indices.append(index)
point_id_list.InsertNextId(index)
# Insert quad points to node points
self.__points.InsertPoints(point_id_list, rel_id_list, points)
# Create the polygon
polygon = vtk.vtkPolygon()
polygon.GetPointIds().SetNumberOfIds(self.num_points_per_poly) # make a quad
polygon.GetPointIds().SetId(0, id_base + 0)
polygon.GetPointIds().SetId(1, id_base + 1)
polygon.GetPointIds().SetId(2, id_base + 2)
polygon.GetPointIds().SetId(3, id_base + 3)
self.__lines.InsertNextCell(self.num_points_per_poly + 1)
self.__lines.InsertCellPoint(id_base + 0)
self.__lines.InsertCellPoint(id_base + 1)
self.__lines.InsertCellPoint(id_base + 2)
self.__lines.InsertCellPoint(id_base + 3)
self.__lines.InsertCellPoint(id_base + 0)
self.__polygons.InsertNextCell(polygon)
def update_position(self, x, y, z):
self.__transform.Identity()
self.__transform.Translate(x, y, z)
def update_polygon_position(self, y, next_node):
self.__lines.Reset()
self.__polygons.Reset()
self.__points.Reset()
# Add back side quad data
self.get_fb_quad_points(next_node, -1)
# Add front side quad data
self.get_fb_quad_points(next_node, 1)
# Add bottom side quad data
self.get_top_quad_points(next_node, -self.height)
# Add top side quad data
self.get_top_quad_points(next_node, self.height)
# Add left side quad data
self.add_lr_side_quad_data(next_node, -1)
# Add right side quad data
self.add_lr_side_quad_data(next_node, 1)
# Update nodes polyData
self.__polyData.SetLines(self.__lines)
self.__polyData.SetPolys(self.__polygons)
self.__polyData.SetPoints(self.__points)
class vtkUpdate:
def __init__(self, main_window, x_index):
self.x_index = x_index
self.nodes = Settings.nodes
self.main_window = main_window
self.cam_position_index = None
self.cam_focal_index = None
self.camera = None
self.d_vals = [0, 0, 0]
def set_mode(self, val):
#Settings.mode = val
Settings.shared_main.set_function_param(0, val)
def set_omega(self, val):
#Settings.omega = val
Settings.shared_main.set_function_param(1, val)
def set_camera_indicies(self, pos_idx, foc_idx):
self.cam_position_index = pos_idx
self.cam_focal_index = foc_idx
def set_camera_delta_vals(self, deltas):
self.d_vals = deltas
def execute(self):
i = self.x_index
y = Settings.shared_main.eval_func_for_xvals(Settings.x_vals, Settings.current_t_val)
for i in range(len(self.nodes)):
node = self.nodes[i]
next_node = None
if i < (len(self.nodes) - 1):
self.nodes[i + 1].update_position(i + 1, y[i + 1], 0)
next_node = self.nodes[i + 1]
node.update_position(i, y[i], 0)
node.update_polygon_position(y[i], next_node)
camera = self.main_window.active_camera
is_offset = (np.linalg.norm(self.d_vals) != 0)
if self.cam_position_index == i:
camera.SetPosition(i + self.d_vals[0], y[i] + self.d_vals[1], self.d_vals[2])
print("Camera Pos: ", camera.GetPosition())
print(i)
if is_offset:
camera.SetFocalPoint(i, y[i], 0)
if not is_offset:
if self.cam_focal_index == i:
camera.SetFocalPoint(node.get_actor().GetCenter())
print("Camera Focal: ", camera.GetFocalPoint())
print(i)
Settings.current_t_val += Settings.t_val_step
# print("Current Time: ", beam.current_t_val)
self.main_window.ren_window.Render()