1
1
import os
2
2
import random
3
- import vtk
4
3
5
- import dash
6
- import dash_vtk
7
- from dash_vtk .utils import to_mesh_state , presets
8
4
5
+ import dash
9
6
import dash_bootstrap_components as dbc
10
7
import dash_html_components as html
11
8
import dash_core_components as dcc
12
9
13
10
from dash .dependencies import Input , Output , State
14
11
12
+ import dash_vtk
13
+ from dash_vtk .utils import to_mesh_state , preset_as_options
15
14
16
- def toDropOption (name ):
17
- return { 'label' : name , 'value' : name }
15
+ import vtk
18
16
19
17
# -----------------------------------------------------------------------------
20
18
# VTK Pipeline
21
19
# -----------------------------------------------------------------------------
22
20
23
- # Figure out file path to load
24
- data_basedir = os .path .join (os .path .dirname (__file__ ), 'data' )
25
- bike_filename = os .path .join (data_basedir , 'bike.vtp' )
26
- tunnel_filename = os .path .join (data_basedir , 'tunnel.vtu' )
21
+ class Viz ():
22
+ def __init__ (self , data_directory ):
23
+ self .color_range = [0 , 1 ]
24
+ bike_filename = os .path .join (data_directory , 'bike.vtp' )
25
+ tunnel_filename = os .path .join (data_directory , 'tunnel.vtu' )
26
+
27
+ # Seeds settings
28
+ self .resolution = 10
29
+ self .point1 = [- 0.4 , 0 , 0.05 ]
30
+ self .point2 = [- 0.4 , 0 , 1.5 ]
31
+
32
+ # VTK Pipeline setup
33
+ bikeReader = vtk .vtkXMLPolyDataReader ()
34
+ bikeReader .SetFileName (bike_filename )
35
+ bikeReader .Update ()
36
+ self .bike_mesh = to_mesh_state (bikeReader .GetOutput ())
27
37
28
- # Seed positions
29
- point1 = [ - 0.4 , 0 , 0.05 ]
30
- point2 = [ - 0.4 , 0 , 1.5 ]
38
+ tunnelReader = vtk . vtkXMLUnstructuredGridReader ()
39
+ tunnelReader . SetFileName ( tunnel_filename )
40
+ tunnelReader . Update ()
31
41
32
- # VTK Pipeline setup
33
- bikeReader = vtk . vtkXMLPolyDataReader ( )
34
- bikeReader . SetFileName ( bike_filename )
35
- bikeReader . Update ( )
42
+ self . lineSeed = vtk . vtkLineSource ()
43
+ self . lineSeed . SetPoint1 ( * self . point1 )
44
+ self . lineSeed . SetPoint2 ( * self . point2 )
45
+ self . lineSeed . SetResolution ( self . resolution )
36
46
37
- tunnelReader = vtk .vtkXMLUnstructuredGridReader ()
38
- tunnelReader .SetFileName (tunnel_filename )
39
- tunnelReader .Update ()
47
+ streamTracer = vtk .vtkStreamTracer ()
48
+ streamTracer .SetInputConnection (tunnelReader .GetOutputPort ())
49
+ streamTracer .SetSourceConnection (self .lineSeed .GetOutputPort ())
50
+ streamTracer .SetIntegrationDirectionToForward ()
51
+ streamTracer .SetIntegratorTypeToRungeKutta45 ()
52
+ streamTracer .SetMaximumPropagation (3 )
53
+ streamTracer .SetIntegrationStepUnit (2 )
54
+ streamTracer .SetInitialIntegrationStep (0.2 )
55
+ streamTracer .SetMinimumIntegrationStep (0.01 )
56
+ streamTracer .SetMaximumIntegrationStep (0.5 )
57
+ streamTracer .SetMaximumError (0.000001 )
58
+ streamTracer .SetMaximumNumberOfSteps (2000 )
59
+ streamTracer .SetTerminalSpeed (0.00000000001 )
40
60
41
- lineSeed = vtk .vtkLineSource ()
42
- lineSeed .SetPoint1 (* point1 )
43
- lineSeed .SetPoint2 (* point2 )
44
- lineSeed .SetResolution (50 )
61
+ self .tubeFilter = vtk .vtkTubeFilter ()
62
+ self .tubeFilter .SetInputConnection (streamTracer .GetOutputPort ())
63
+ self .tubeFilter .SetRadius (0.01 )
64
+ self .tubeFilter .SetNumberOfSides (6 )
65
+ self .tubeFilter .CappingOn ()
66
+ self .tubeFilter .Update ()
45
67
46
- streamTracer = vtk .vtkStreamTracer ()
47
- streamTracer .SetInputConnection (tunnelReader .GetOutputPort ())
48
- streamTracer .SetSourceConnection (lineSeed .GetOutputPort ())
49
- streamTracer .SetIntegrationDirectionToForward ()
50
- streamTracer .SetIntegratorTypeToRungeKutta45 ()
51
- streamTracer .SetMaximumPropagation (3 )
52
- streamTracer .SetIntegrationStepUnit (2 )
53
- streamTracer .SetInitialIntegrationStep (0.2 )
54
- streamTracer .SetMinimumIntegrationStep (0.01 )
55
- streamTracer .SetMaximumIntegrationStep (0.5 )
56
- streamTracer .SetMaximumError (0.000001 )
57
- streamTracer .SetMaximumNumberOfSteps (2000 )
58
- streamTracer .SetTerminalSpeed (0.00000000001 )
68
+ def updateSeedPoints (self , p1_y , p2_y , resolution ):
69
+ self .point1 [1 ] = p1_y
70
+ self .point2 [1 ] = p2_y
71
+ self .resolution = resolution
59
72
60
- tubeFilter = vtk .vtkTubeFilter ()
61
- tubeFilter .SetInputConnection (streamTracer .GetOutputPort ())
62
- tubeFilter .SetRadius (0.01 )
63
- tubeFilter .SetNumberOfSides (6 )
64
- tubeFilter .CappingOn ()
65
- tubeFilter .Update ()
73
+ self .lineSeed .SetPoint1 (* self .point1 )
74
+ self .lineSeed .SetPoint2 (* self .point2 )
75
+ self .lineSeed .SetResolution (resolution )
66
76
67
- def updateTubesGeometry (field_name ):
68
- tubeFilter .Update ()
69
- streamlineState = to_mesh_state (tubeFilter .GetOutput (), field_name )
70
- colorRange = streamlineState ['field' ]['dataRange' ]
77
+ def getTubesMesh (self , color_by_field_name ):
78
+ self .tubeFilter .Update ()
79
+ ds = self .tubeFilter .GetOutput ()
80
+ mesh_state = to_mesh_state (ds , color_by_field_name )
81
+ self .color_range = mesh_state ['field' ]['dataRange' ]
82
+ return mesh_state
71
83
72
- return [streamlineState , colorRange ]
84
+ def getBikeMesh (self ):
85
+ return self .bike_mesh
73
86
74
- streamline_mesh_state , color_range = updateTubesGeometry ('p' )
75
- bike_mesh_state = to_mesh_state (bikeReader .GetOutput ())
87
+ def getColorRange (self ):
88
+ return self .color_range
89
+
90
+ def getSeedState (self ):
91
+ return {
92
+ 'point1' : self .point1 ,
93
+ 'point2' : self .point2 ,
94
+ 'resolution' : self .resolution ,
95
+ }
76
96
77
97
# -----------------------------------------------------------------------------
78
98
# GUI setup
79
99
# -----------------------------------------------------------------------------
80
100
81
101
app = dash .Dash (__name__ , external_stylesheets = [dbc .themes .BOOTSTRAP ])
82
102
server = app .server
103
+ viz = Viz (os .path .join (os .path .dirname (__file__ ), 'data' ))
104
+
105
+ # -----------------------------------------------------------------------------
106
+ # 3D Viz
107
+ # -----------------------------------------------------------------------------
83
108
84
109
vtk_view = dash_vtk .View (
85
110
id = "vtk-view" ,
@@ -89,18 +114,18 @@ def updateTubesGeometry(field_name):
89
114
children = [
90
115
dash_vtk .Mesh (
91
116
id = "bike" ,
92
- state = bike_mesh_state ,
117
+ state = viz . getBikeMesh () ,
93
118
)
94
119
],
95
120
),
96
121
dash_vtk .GeometryRepresentation (
97
122
id = "tubes-rep" ,
98
123
colorMapPreset = "erdc_rainbow_bright" ,
99
- colorDataRange = color_range ,
124
+ colorDataRange = viz . getColorRange () ,
100
125
children = [
101
126
dash_vtk .Mesh (
102
127
id = "tubes-mesh" ,
103
- state = streamline_mesh_state ,
128
+ state = viz . getTubesMesh ( 'p' ) ,
104
129
)
105
130
],
106
131
),
@@ -115,13 +140,17 @@ def updateTubesGeometry(field_name):
115
140
dash_vtk .Algorithm (
116
141
id = "seed-line" ,
117
142
vtkClass = "vtkLineSource" ,
118
- state = { 'point1' : point1 , 'point2' : point2 } ,
143
+ state = viz . getSeedState () ,
119
144
)
120
145
],
121
146
)
122
147
]
123
148
)
124
149
150
+ # -----------------------------------------------------------------------------
151
+ # Control UI
152
+ # -----------------------------------------------------------------------------
153
+
125
154
controls = dbc .Col (children = [
126
155
dbc .Card (
127
156
[
@@ -180,7 +209,7 @@ def updateTubesGeometry(field_name):
180
209
html .P ("Color Preset" ),
181
210
dcc .Dropdown (
182
211
id = "preset" ,
183
- options = list ( map ( toDropOption , presets )) ,
212
+ options = preset_as_options ,
184
213
value = "erdc_rainbow_bright" ,
185
214
),
186
215
]
@@ -189,11 +218,14 @@ def updateTubesGeometry(field_name):
189
218
),
190
219
])
191
220
221
+ # -----------------------------------------------------------------------------
222
+ # App UI
223
+ # -----------------------------------------------------------------------------
192
224
193
225
app .layout = dbc .Container (
194
226
fluid = True ,
195
227
children = [
196
- html .H1 ("Demo of dash_vtk.CFD " ),
228
+ html .H1 ("dash_vtk rendering with VTK processing " ),
197
229
html .Hr (),
198
230
dbc .Row (
199
231
[
@@ -216,7 +248,7 @@ def updateTubesGeometry(field_name):
216
248
)
217
249
218
250
# -----------------------------------------------------------------------------
219
- # Handle seeds
251
+ # Handle controls
220
252
# -----------------------------------------------------------------------------
221
253
222
254
@app .callback (
@@ -236,21 +268,13 @@ def updateTubesGeometry(field_name):
236
268
],
237
269
)
238
270
def update_seeds (y1 , y2 , resolution , colorByField , presetName ):
239
- point1 [1 ] = y1
240
- point2 [1 ] = y2
241
-
242
- lineSeed .SetPoint1 (* point1 )
243
- lineSeed .SetPoint2 (* point2 )
244
- lineSeed .SetResolution (resolution )
245
-
246
- tube_state , colorRange = updateTubesGeometry (colorByField )
247
-
271
+ viz .updateSeedPoints (y1 , y2 , resolution )
248
272
return [
249
- { "point1" : point1 , "point2" : point2 , "resolution" : resolution } ,
250
- tube_state ,
251
- colorRange ,
273
+ viz . getSeedState () ,
274
+ viz . getTubesMesh ( colorByField ) ,
275
+ viz . getColorRange () ,
252
276
presetName ,
253
- random .random (),
277
+ random .random (), # trigger a render
254
278
]
255
279
256
280
# -----------------------------------------------------------------------------
0 commit comments