capytaine 2.3.1__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- capytaine/__about__.py +16 -0
- capytaine/__init__.py +36 -0
- capytaine/bem/__init__.py +0 -0
- capytaine/bem/airy_waves.py +111 -0
- capytaine/bem/engines.py +441 -0
- capytaine/bem/problems_and_results.py +600 -0
- capytaine/bem/solver.py +594 -0
- capytaine/bodies/__init__.py +4 -0
- capytaine/bodies/bodies.py +1221 -0
- capytaine/bodies/dofs.py +19 -0
- capytaine/bodies/predefined/__init__.py +6 -0
- capytaine/bodies/predefined/cylinders.py +151 -0
- capytaine/bodies/predefined/rectangles.py +111 -0
- capytaine/bodies/predefined/spheres.py +70 -0
- capytaine/green_functions/FinGreen3D/.gitignore +1 -0
- capytaine/green_functions/FinGreen3D/FinGreen3D.f90 +3589 -0
- capytaine/green_functions/FinGreen3D/LICENSE +165 -0
- capytaine/green_functions/FinGreen3D/Makefile +16 -0
- capytaine/green_functions/FinGreen3D/README.md +24 -0
- capytaine/green_functions/FinGreen3D/test_program.f90 +39 -0
- capytaine/green_functions/LiangWuNoblesse/.gitignore +1 -0
- capytaine/green_functions/LiangWuNoblesse/LICENSE +504 -0
- capytaine/green_functions/LiangWuNoblesse/LiangWuNoblesseWaveTerm.f90 +751 -0
- capytaine/green_functions/LiangWuNoblesse/Makefile +16 -0
- capytaine/green_functions/LiangWuNoblesse/README.md +2 -0
- capytaine/green_functions/LiangWuNoblesse/test_program.f90 +28 -0
- capytaine/green_functions/__init__.py +2 -0
- capytaine/green_functions/abstract_green_function.py +64 -0
- capytaine/green_functions/delhommeau.py +507 -0
- capytaine/green_functions/hams.py +204 -0
- capytaine/green_functions/libs/Delhommeau_float32.cpython-313-x86_64-linux-gnu.so +0 -0
- capytaine/green_functions/libs/Delhommeau_float64.cpython-313-x86_64-linux-gnu.so +0 -0
- capytaine/green_functions/libs/__init__.py +0 -0
- capytaine/io/__init__.py +0 -0
- capytaine/io/bemio.py +153 -0
- capytaine/io/legacy.py +328 -0
- capytaine/io/mesh_loaders.py +1086 -0
- capytaine/io/mesh_writers.py +692 -0
- capytaine/io/meshio.py +38 -0
- capytaine/io/wamit.py +479 -0
- capytaine/io/xarray.py +668 -0
- capytaine/matrices/__init__.py +16 -0
- capytaine/matrices/block.py +592 -0
- capytaine/matrices/block_toeplitz.py +325 -0
- capytaine/matrices/builders.py +89 -0
- capytaine/matrices/linear_solvers.py +232 -0
- capytaine/matrices/low_rank.py +395 -0
- capytaine/meshes/__init__.py +6 -0
- capytaine/meshes/clipper.py +465 -0
- capytaine/meshes/collections.py +342 -0
- capytaine/meshes/geometry.py +409 -0
- capytaine/meshes/mesh_like_protocol.py +37 -0
- capytaine/meshes/meshes.py +890 -0
- capytaine/meshes/predefined/__init__.py +6 -0
- capytaine/meshes/predefined/cylinders.py +314 -0
- capytaine/meshes/predefined/rectangles.py +261 -0
- capytaine/meshes/predefined/spheres.py +62 -0
- capytaine/meshes/properties.py +276 -0
- capytaine/meshes/quadratures.py +80 -0
- capytaine/meshes/quality.py +448 -0
- capytaine/meshes/surface_integrals.py +63 -0
- capytaine/meshes/symmetric.py +462 -0
- capytaine/post_pro/__init__.py +6 -0
- capytaine/post_pro/free_surfaces.py +88 -0
- capytaine/post_pro/impedance.py +92 -0
- capytaine/post_pro/kochin.py +54 -0
- capytaine/post_pro/rao.py +60 -0
- capytaine/tools/__init__.py +0 -0
- capytaine/tools/cache_on_disk.py +26 -0
- capytaine/tools/deprecation_handling.py +18 -0
- capytaine/tools/lists_of_points.py +52 -0
- capytaine/tools/lru_cache.py +49 -0
- capytaine/tools/optional_imports.py +27 -0
- capytaine/tools/prony_decomposition.py +150 -0
- capytaine/tools/symbolic_multiplication.py +149 -0
- capytaine/tools/timer.py +66 -0
- capytaine/ui/__init__.py +0 -0
- capytaine/ui/cli.py +28 -0
- capytaine/ui/rich.py +5 -0
- capytaine/ui/vtk/__init__.py +3 -0
- capytaine/ui/vtk/animation.py +329 -0
- capytaine/ui/vtk/body_viewer.py +28 -0
- capytaine/ui/vtk/helpers.py +82 -0
- capytaine/ui/vtk/mesh_viewer.py +461 -0
- capytaine-2.3.1.dist-info/LICENSE +674 -0
- capytaine-2.3.1.dist-info/METADATA +750 -0
- capytaine-2.3.1.dist-info/RECORD +93 -0
- capytaine-2.3.1.dist-info/WHEEL +6 -0
- capytaine-2.3.1.dist-info/entry_points.txt +3 -0
- capytaine.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- capytaine.libs/libgomp-e985bcbb.so.1.0.0 +0 -0
- capytaine.libs/libmvec-2-583a17db.28.so +0 -0
- capytaine.libs/libquadmath-2284e583.so.0.0.0 +0 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
"""3D display of a mesh with VTK.
|
|
2
|
+
Based on meshmagick <https://github.com/LHEEA/meshmagick> by François Rongère.
|
|
3
|
+
"""
|
|
4
|
+
# Copyright (C) 2017-2019 Matthieu Ancellin, based on the work of François Rongère
|
|
5
|
+
# See LICENSE file at <https://github.com/mancellin/capytaine>
|
|
6
|
+
|
|
7
|
+
import datetime
|
|
8
|
+
from itertools import cycle
|
|
9
|
+
from os import getcwd
|
|
10
|
+
|
|
11
|
+
from capytaine.ui.vtk.helpers import compute_vtk_polydata
|
|
12
|
+
from capytaine.tools.optional_imports import import_optional_dependency
|
|
13
|
+
|
|
14
|
+
vtk = import_optional_dependency("vtk")
|
|
15
|
+
|
|
16
|
+
__year__ = datetime.datetime.now().year
|
|
17
|
+
|
|
18
|
+
COLORS = cycle([(1, 1, 0), (1, 0, 1), (1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 1)])
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MeshViewer:
|
|
22
|
+
"""This class implements a viewer based on VTK"""
|
|
23
|
+
def __init__(self):
|
|
24
|
+
|
|
25
|
+
# Building renderer
|
|
26
|
+
self.renderer = vtk.vtkRenderer()
|
|
27
|
+
self.renderer.SetBackground(0.7706, 0.8165, 1.0)
|
|
28
|
+
|
|
29
|
+
# Building render window
|
|
30
|
+
self.render_window = vtk.vtkRenderWindow()
|
|
31
|
+
self.render_window.SetSize(1024, 768)
|
|
32
|
+
self.render_window.SetWindowName("Mesh viewer")
|
|
33
|
+
self.render_window.AddRenderer(self.renderer)
|
|
34
|
+
|
|
35
|
+
# Building interactor
|
|
36
|
+
self.render_window_interactor = vtk.vtkRenderWindowInteractor()
|
|
37
|
+
self.render_window_interactor.SetRenderWindow(self.render_window)
|
|
38
|
+
self.render_window_interactor.GetInteractorStyle().SetCurrentStyleToTrackballCamera()
|
|
39
|
+
self.render_window_interactor.AddObserver('KeyPressEvent', self.on_key_press, 0.0)
|
|
40
|
+
|
|
41
|
+
# Building axes view
|
|
42
|
+
axes = vtk.vtkAxesActor()
|
|
43
|
+
widget = vtk.vtkOrientationMarkerWidget()
|
|
44
|
+
widget.SetOrientationMarker(axes)
|
|
45
|
+
self.widget = widget
|
|
46
|
+
|
|
47
|
+
self.widget.SetInteractor(self.render_window_interactor)
|
|
48
|
+
self.widget.SetEnabled(1)
|
|
49
|
+
self.widget.InteractiveOn()
|
|
50
|
+
|
|
51
|
+
# Building command annotations
|
|
52
|
+
command_text = ("left mouse : rotate\n"
|
|
53
|
+
"right mouse : zoom\n"
|
|
54
|
+
"middle mouse : pan\n"
|
|
55
|
+
"ctrl+left mouse : spin\n"
|
|
56
|
+
"n : (un)show normals\n"
|
|
57
|
+
"b : (un)show axes box\n"
|
|
58
|
+
"f : focus on the mouse cursor\n"
|
|
59
|
+
"r : reset view\n"
|
|
60
|
+
"s : surface representation\n"
|
|
61
|
+
"w : wire representation\n"
|
|
62
|
+
"h : (un)show Oxy plane\n"
|
|
63
|
+
"x : save\n"
|
|
64
|
+
"c : screenshot\n"
|
|
65
|
+
"q : quit")
|
|
66
|
+
|
|
67
|
+
corner_annotation = vtk.vtkCornerAnnotation()
|
|
68
|
+
corner_annotation.SetLinearFontScaleFactor(2)
|
|
69
|
+
corner_annotation.SetNonlinearFontScaleFactor(1)
|
|
70
|
+
corner_annotation.SetMaximumFontSize(20)
|
|
71
|
+
corner_annotation.SetText(3, command_text)
|
|
72
|
+
corner_annotation.GetTextProperty().SetColor(0., 0., 0.)
|
|
73
|
+
self.renderer.AddViewProp(corner_annotation)
|
|
74
|
+
|
|
75
|
+
copyright_text = (f"Capytaine — Copyright 2017-{__year__} University College Dublin\n"
|
|
76
|
+
f"based on Meshmagick Viewer — Copyright 2014-{__year__}, École Centrale de Nantes")
|
|
77
|
+
|
|
78
|
+
copyright_annotation = vtk.vtkCornerAnnotation()
|
|
79
|
+
copyright_annotation.SetLinearFontScaleFactor(0.5)
|
|
80
|
+
copyright_annotation.SetNonlinearFontScaleFactor(1)
|
|
81
|
+
copyright_annotation.SetMaximumFontSize(12)
|
|
82
|
+
copyright_annotation.SetText(1, copyright_text)
|
|
83
|
+
copyright_annotation.GetTextProperty().SetColor(0., 0., 0.)
|
|
84
|
+
self.renderer.AddViewProp(copyright_annotation)
|
|
85
|
+
|
|
86
|
+
self.polydatas = []
|
|
87
|
+
self.normals = []
|
|
88
|
+
self.axes = []
|
|
89
|
+
self.oxy_plane = None
|
|
90
|
+
|
|
91
|
+
# DISPLAY OF A MESH
|
|
92
|
+
|
|
93
|
+
def add_polydata(self, polydata, color=(1, 1, 0), representation='surface'):
|
|
94
|
+
"""Add a polydata object to the viewer
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
polydata : vtkPolyData
|
|
99
|
+
the object to be added
|
|
100
|
+
color : array_like, optional
|
|
101
|
+
the color of the object. Default is yellow (1, 1, 0)
|
|
102
|
+
representation : str
|
|
103
|
+
the representation mode of the object ('surface' or 'wireframe'). Default is 'surface'.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
assert isinstance(polydata, vtk.vtkPolyData)
|
|
107
|
+
assert representation in ('surface', 'wireframe')
|
|
108
|
+
|
|
109
|
+
self.polydatas.append(polydata)
|
|
110
|
+
|
|
111
|
+
# Building mapper
|
|
112
|
+
mapper = vtk.vtkPolyDataMapper()
|
|
113
|
+
mapper.SetInputData(polydata)
|
|
114
|
+
|
|
115
|
+
# Building actor
|
|
116
|
+
actor = vtk.vtkActor()
|
|
117
|
+
actor.SetMapper(mapper)
|
|
118
|
+
|
|
119
|
+
# Properties setting
|
|
120
|
+
actor.GetProperty().SetColor(color)
|
|
121
|
+
actor.GetProperty().EdgeVisibilityOn()
|
|
122
|
+
actor.GetProperty().SetEdgeColor(0, 0, 0)
|
|
123
|
+
actor.GetProperty().SetLineWidth(1)
|
|
124
|
+
actor.GetProperty().SetPointSize(10)
|
|
125
|
+
if representation == 'wireframe':
|
|
126
|
+
actor.GetProperty().SetRepresentationToWireframe()
|
|
127
|
+
|
|
128
|
+
self.renderer.AddActor(actor)
|
|
129
|
+
self.renderer.Modified()
|
|
130
|
+
|
|
131
|
+
def add_mesh(self, mesh, color=None, representation='surface'):
|
|
132
|
+
vtk_polydata = compute_vtk_polydata(mesh)
|
|
133
|
+
if color is None:
|
|
134
|
+
color = next(COLORS)
|
|
135
|
+
self.add_polydata(vtk_polydata, color=color, representation=representation)
|
|
136
|
+
|
|
137
|
+
# ADD MORE DETAILS
|
|
138
|
+
|
|
139
|
+
def add_oxy_plane(self):
|
|
140
|
+
"""Displays the Oxy plane"""
|
|
141
|
+
|
|
142
|
+
one_mesh_in_the_viewer = self.polydatas[0]
|
|
143
|
+
|
|
144
|
+
plane = vtk.vtkPlaneSource()
|
|
145
|
+
(xmin, xmax, ymin, ymax, _, _) = one_mesh_in_the_viewer.GetBounds()
|
|
146
|
+
|
|
147
|
+
dx = max(0.1 * (xmax - xmin), 0.1)
|
|
148
|
+
dy = max(0.1 * (ymax - ymin), 0.1)
|
|
149
|
+
|
|
150
|
+
plane.SetOrigin(xmin - dx, ymax + dy, 0)
|
|
151
|
+
plane.SetPoint1(xmin - dx, ymin - dy, 0)
|
|
152
|
+
plane.SetPoint2(xmax + dx, ymax + dy, 0)
|
|
153
|
+
plane.Update()
|
|
154
|
+
polydata = plane.GetOutput()
|
|
155
|
+
|
|
156
|
+
mapper = vtk.vtkPolyDataMapper()
|
|
157
|
+
mapper.SetInputData(polydata)
|
|
158
|
+
|
|
159
|
+
actor = vtk.vtkActor()
|
|
160
|
+
actor.SetMapper(mapper)
|
|
161
|
+
|
|
162
|
+
color = [0., 102. / 255, 204. / 255]
|
|
163
|
+
actor.GetProperty().SetColor(color)
|
|
164
|
+
actor.GetProperty().SetEdgeColor(0, 0, 0)
|
|
165
|
+
actor.GetProperty().SetLineWidth(1)
|
|
166
|
+
|
|
167
|
+
self.renderer.AddActor(actor)
|
|
168
|
+
self.renderer.Modified()
|
|
169
|
+
self.oxy_plane = actor
|
|
170
|
+
|
|
171
|
+
def show_normals(self):
|
|
172
|
+
"""Shows the normals of the current objects"""
|
|
173
|
+
|
|
174
|
+
for polydata in self.polydatas:
|
|
175
|
+
normals = vtk.vtkPolyDataNormals()
|
|
176
|
+
normals.ConsistencyOff()
|
|
177
|
+
normals.ComputeCellNormalsOn()
|
|
178
|
+
normals.SetInputData(polydata)
|
|
179
|
+
normals.Update()
|
|
180
|
+
|
|
181
|
+
normals_at_centers = vtk.vtkCellCenters()
|
|
182
|
+
normals_at_centers.SetInputConnection(normals.GetOutputPort())
|
|
183
|
+
|
|
184
|
+
arrows = vtk.vtkArrowSource()
|
|
185
|
+
arrows.SetTipResolution(16)
|
|
186
|
+
arrows.SetTipLength(0.5)
|
|
187
|
+
arrows.SetTipRadius(0.1)
|
|
188
|
+
|
|
189
|
+
glyph = vtk.vtkGlyph3D()
|
|
190
|
+
glyph.SetSourceConnection(arrows.GetOutputPort())
|
|
191
|
+
glyph.SetInputConnection(normals_at_centers.GetOutputPort())
|
|
192
|
+
glyph.SetVectorModeToUseNormal()
|
|
193
|
+
glyph.SetScaleModeToScaleByVector()
|
|
194
|
+
glyph.SetScaleFactor(1) # FIXME: may be too big ...
|
|
195
|
+
# glyph.SetVectorModeToUseNormal()
|
|
196
|
+
# glyph.SetVectorModeToUseVector()
|
|
197
|
+
# glyph.SetScaleModeToDataScalingOff()
|
|
198
|
+
glyph.Update()
|
|
199
|
+
|
|
200
|
+
glyph_mapper = vtk.vtkPolyDataMapper()
|
|
201
|
+
glyph_mapper.SetInputConnection(glyph.GetOutputPort())
|
|
202
|
+
|
|
203
|
+
glyph_actor = vtk.vtkActor()
|
|
204
|
+
glyph_actor.SetMapper(glyph_mapper)
|
|
205
|
+
|
|
206
|
+
self.renderer.AddActor(glyph_actor)
|
|
207
|
+
self.normals.append(glyph_actor)
|
|
208
|
+
|
|
209
|
+
def show_axes(self):
|
|
210
|
+
"""Shows the axes around the main object"""
|
|
211
|
+
|
|
212
|
+
tprop = vtk.vtkTextProperty()
|
|
213
|
+
tprop.SetColor(0., 0., 0.)
|
|
214
|
+
tprop.ShadowOn()
|
|
215
|
+
|
|
216
|
+
axes = vtk.vtkCubeAxesActor2D()
|
|
217
|
+
axes.SetInputData(self.polydatas[0])
|
|
218
|
+
|
|
219
|
+
axes.SetCamera(self.renderer.GetActiveCamera())
|
|
220
|
+
axes.SetLabelFormat("%6.4g")
|
|
221
|
+
axes.SetFlyModeToOuterEdges()
|
|
222
|
+
axes.SetFontFactor(0.8)
|
|
223
|
+
axes.SetAxisTitleTextProperty(tprop)
|
|
224
|
+
axes.SetAxisLabelTextProperty(tprop)
|
|
225
|
+
# axes.DrawGridLinesOn()
|
|
226
|
+
|
|
227
|
+
self.renderer.AddViewProp(axes)
|
|
228
|
+
self.axes.append(axes)
|
|
229
|
+
|
|
230
|
+
def save(self):
|
|
231
|
+
"""Saves the main object in a 'mmviewer_save.vtp' vtp file is the current folder"""
|
|
232
|
+
|
|
233
|
+
writer = vtk.vtkXMLPolyDataWriter()
|
|
234
|
+
writer.SetDataModeToAscii()
|
|
235
|
+
writer.SetFileName('mmviewer_save.vtp')
|
|
236
|
+
|
|
237
|
+
for polydata in self.polydatas:
|
|
238
|
+
writer.SetInputData(polydata)
|
|
239
|
+
writer.Write()
|
|
240
|
+
|
|
241
|
+
print("File 'mmviewer_save.vtp' written in %s" % getcwd())
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
def screenshot(self):
|
|
245
|
+
"""Saves a screenshot of the current window in a file screenshot.png"""
|
|
246
|
+
w2if = vtk.vtkWindowToImageFilter()
|
|
247
|
+
w2if.SetInput(self.render_window)
|
|
248
|
+
w2if.Update()
|
|
249
|
+
|
|
250
|
+
writer = vtk.vtkPNGWriter()
|
|
251
|
+
writer.SetFileName("screenshot.png")
|
|
252
|
+
writer.SetInputData(w2if.GetOutput())
|
|
253
|
+
writer.Write()
|
|
254
|
+
|
|
255
|
+
print("File 'screenshot.png' written in %s" % getcwd())
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
# INTERACTION
|
|
259
|
+
|
|
260
|
+
def show(self):
|
|
261
|
+
"""Show the viewer"""
|
|
262
|
+
self.renderer.ResetCamera()
|
|
263
|
+
self.render_window.Render()
|
|
264
|
+
self.render_window_interactor.Start()
|
|
265
|
+
|
|
266
|
+
def on_key_press(self, obj, event):
|
|
267
|
+
"""Event trig at keystroke"""
|
|
268
|
+
key = obj.GetKeySym()
|
|
269
|
+
|
|
270
|
+
if key == 'n':
|
|
271
|
+
if self.normals:
|
|
272
|
+
# self.normals = False
|
|
273
|
+
for actor in self.normals:
|
|
274
|
+
self.renderer.RemoveActor(actor)
|
|
275
|
+
self.renderer.Render()
|
|
276
|
+
self.normals = []
|
|
277
|
+
else:
|
|
278
|
+
self.show_normals()
|
|
279
|
+
self.renderer.Render()
|
|
280
|
+
|
|
281
|
+
elif key == 'b':
|
|
282
|
+
if self.axes:
|
|
283
|
+
for axis in self.axes:
|
|
284
|
+
self.renderer.RemoveActor(axis)
|
|
285
|
+
self.axes = []
|
|
286
|
+
else:
|
|
287
|
+
self.show_axes()
|
|
288
|
+
|
|
289
|
+
elif key == 'x':
|
|
290
|
+
self.save()
|
|
291
|
+
|
|
292
|
+
elif key == 'c':
|
|
293
|
+
self.screenshot()
|
|
294
|
+
|
|
295
|
+
elif key == 'h':
|
|
296
|
+
if self.oxy_plane:
|
|
297
|
+
self.renderer.RemoveActor(self.oxy_plane)
|
|
298
|
+
self.oxy_plane = None
|
|
299
|
+
else:
|
|
300
|
+
self.add_oxy_plane()
|
|
301
|
+
|
|
302
|
+
elif key == 'e' or key == 'q':
|
|
303
|
+
self.render_window_interactor.GetRenderWindow().Finalize()
|
|
304
|
+
self.render_window_interactor.TerminateApp()
|
|
305
|
+
|
|
306
|
+
def finalize(self):
|
|
307
|
+
"""Cleanly close the viewer"""
|
|
308
|
+
del self.render_window
|
|
309
|
+
del self.render_window_interactor
|
|
310
|
+
|
|
311
|
+
# =======================================
|
|
312
|
+
# =======================================
|
|
313
|
+
# =======================================
|
|
314
|
+
|
|
315
|
+
# OTHER METHODS THAT ARE CURRENTLY UNUSED
|
|
316
|
+
|
|
317
|
+
def add_point(self, pos, color=(0, 0, 0)):
|
|
318
|
+
"""Add a point to the viewer
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
pos : array_like
|
|
323
|
+
The point's position
|
|
324
|
+
color : array_like, optional
|
|
325
|
+
The RGB color required for the point. Default is (0, 0, 0) corresponding to black.
|
|
326
|
+
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
vtkPolyData
|
|
330
|
+
"""
|
|
331
|
+
|
|
332
|
+
assert len(pos) == 3
|
|
333
|
+
|
|
334
|
+
p = vtk.vtkPoints()
|
|
335
|
+
v = vtk.vtkCellArray()
|
|
336
|
+
|
|
337
|
+
i = p.InsertNextPoint(pos)
|
|
338
|
+
v.InsertNextCell(1)
|
|
339
|
+
v.InsertCellPoint(i)
|
|
340
|
+
|
|
341
|
+
pd = vtk.vtkPolyData()
|
|
342
|
+
pd.SetPoints(p)
|
|
343
|
+
pd.SetVerts(v)
|
|
344
|
+
|
|
345
|
+
self.add_polydata(pd, color=color)
|
|
346
|
+
|
|
347
|
+
return pd
|
|
348
|
+
|
|
349
|
+
def add_line(self, p0, p1, color=(0, 0, 0)):
|
|
350
|
+
"""Add a line to the viewer
|
|
351
|
+
|
|
352
|
+
Parameters
|
|
353
|
+
----------
|
|
354
|
+
p0 : array_like
|
|
355
|
+
position of one end point of the line
|
|
356
|
+
p1 : array_like
|
|
357
|
+
position of a second end point of the line
|
|
358
|
+
color : array_like, optional
|
|
359
|
+
RGB color of the line. Default is black (0, 0, 0)
|
|
360
|
+
|
|
361
|
+
Returns
|
|
362
|
+
-------
|
|
363
|
+
vtkPolyData
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
assert len(p0) == 3 and len(p1) == 3
|
|
367
|
+
|
|
368
|
+
points = vtk.vtkPoints()
|
|
369
|
+
points.InsertNextPoint(p0)
|
|
370
|
+
points.InsertNextPoint(p1)
|
|
371
|
+
|
|
372
|
+
line = vtk.vtkLine()
|
|
373
|
+
line.GetPointIds().SetId(0, 0)
|
|
374
|
+
line.GetPointIds().SetId(1, 1)
|
|
375
|
+
|
|
376
|
+
lines = vtk.vtkCellArray()
|
|
377
|
+
lines.InsertNextCell(line)
|
|
378
|
+
|
|
379
|
+
lines_pd = vtk.vtkPolyData()
|
|
380
|
+
lines_pd.SetPoints(points)
|
|
381
|
+
lines_pd.SetLines(lines)
|
|
382
|
+
|
|
383
|
+
self.add_polydata(lines_pd, color=color)
|
|
384
|
+
|
|
385
|
+
return lines_pd
|
|
386
|
+
|
|
387
|
+
def add_vector(self, point, value, scale=1, color=(0, 0, 0)):
|
|
388
|
+
"""Add a vector to the viewer
|
|
389
|
+
|
|
390
|
+
Parameters
|
|
391
|
+
----------
|
|
392
|
+
point : array_like
|
|
393
|
+
starting point position of the vector
|
|
394
|
+
value : float
|
|
395
|
+
the magnitude of the vector
|
|
396
|
+
scale : float, optional
|
|
397
|
+
the scaling to apply to the vector for better visualization. Default is 1.
|
|
398
|
+
color : array_like
|
|
399
|
+
The color of the vector. Default is black (0, 0, 0)
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
points = vtk.vtkPoints()
|
|
403
|
+
idx = points.InsertNextPoint(point)
|
|
404
|
+
|
|
405
|
+
vert = vtk.vtkCellArray()
|
|
406
|
+
vert.InsertNextCell(1)
|
|
407
|
+
vert.InsertCellPoint(idx)
|
|
408
|
+
pd_point = vtk.vtkPolyData()
|
|
409
|
+
pd_point.SetPoints(points)
|
|
410
|
+
pd_point.SetVerts(vert)
|
|
411
|
+
|
|
412
|
+
arrow = vtk.vtkArrowSource()
|
|
413
|
+
arrow.SetTipResolution(16)
|
|
414
|
+
arrow.SetTipLength(0.1)
|
|
415
|
+
arrow.SetTipRadius(0.02)
|
|
416
|
+
arrow.SetShaftRadius(0.005)
|
|
417
|
+
|
|
418
|
+
vec = vtk.vtkFloatArray()
|
|
419
|
+
vec.SetNumberOfComponents(3)
|
|
420
|
+
v0, v1, v2 = value / scale
|
|
421
|
+
vec.InsertTuple3(idx, v0, v1, v2)
|
|
422
|
+
pd_point.GetPointData().SetVectors(vec)
|
|
423
|
+
|
|
424
|
+
g_glyph = vtk.vtkGlyph3D()
|
|
425
|
+
# g_glyph.SetScaleModeToDataScalingOff()
|
|
426
|
+
g_glyph.SetVectorModeToUseVector()
|
|
427
|
+
g_glyph.SetInputData(pd_point)
|
|
428
|
+
g_glyph.SetSourceConnection(arrow.GetOutputPort())
|
|
429
|
+
g_glyph.SetScaleModeToScaleByVector()
|
|
430
|
+
# g_glyph.SetScaleFactor(10)
|
|
431
|
+
g_glyph.ScalingOn()
|
|
432
|
+
g_glyph.Update()
|
|
433
|
+
|
|
434
|
+
g_glyph_mapper = vtk.vtkPolyDataMapper()
|
|
435
|
+
g_glyph_mapper.SetInputConnection(g_glyph.GetOutputPort())
|
|
436
|
+
|
|
437
|
+
g_glyph_actor = vtk.vtkActor()
|
|
438
|
+
g_glyph_actor.SetMapper(g_glyph_mapper)
|
|
439
|
+
g_glyph_actor.GetProperty().SetColor(color)
|
|
440
|
+
|
|
441
|
+
self.renderer.AddActor(g_glyph_actor)
|
|
442
|
+
|
|
443
|
+
def add_plane(self, center, normal):
|
|
444
|
+
"""Add a plane to the viewer
|
|
445
|
+
|
|
446
|
+
Parameters
|
|
447
|
+
----------
|
|
448
|
+
center : array_like
|
|
449
|
+
The origin of the plane
|
|
450
|
+
normal : array_like
|
|
451
|
+
The normal of the plane
|
|
452
|
+
"""
|
|
453
|
+
|
|
454
|
+
plane = vtk.vtkPlaneSource()
|
|
455
|
+
plane.SetCenter(center)
|
|
456
|
+
plane.SetNormal(normal)
|
|
457
|
+
|
|
458
|
+
mapper = vtk.vtkPolyDataMapper()
|
|
459
|
+
mapper.SetInputData(plane.GetOutput())
|
|
460
|
+
|
|
461
|
+
# FIXME: terminer l'implementation et l'utiliser pour le plan de la surface libre
|