-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSampleStreamlinesInTime.xml
More file actions
78 lines (62 loc) · 6.65 KB
/
SampleStreamlinesInTime.xml
File metadata and controls
78 lines (62 loc) · 6.65 KB
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
<ServerManagerConfiguration>
<ProxyGroup name="filters">
<SourceProxy name="SampleStreamlinesInTime" class="vtkPythonProgrammableFilter" label="Sample Streamlines In Time">
<Documentation
long_help="One sample at of each pathline at t (0 to 1) of the way along"
short_help="One sample at of each pathline at t (0 to 1) of the way along">
</Documentation>
<InputProperty
name="Input"
command="SetInputConnection">
<ProxyGroupDomain name="groups">
<Group name="sources"/>
<Group name="filters"/>
</ProxyGroupDomain>
<DataTypeDomain name="input_type">
<DataType value="vtkUnstructuredGrid"/>
</DataTypeDomain>
</InputProperty>
<IntVectorProperty
name="nt"
label="nt"
initial_string="nt"
command="SetParameter"
animateable="1"
default_values="1"
number_of_elements="1">
<Documentation></Documentation>
</IntVectorProperty>
<DoubleVectorProperty
name="t"
label="t"
initial_string="t"
command="SetParameter"
animateable="1"
default_values="0.5"
number_of_elements="1">
<Documentation></Documentation>
</DoubleVectorProperty>
<!-- Output data type: "vtkUnstructuredGrid" -->
<IntVectorProperty command="SetOutputDataSetType"
default_values="4"
name="OutputDataSetType"
number_of_elements="1"
panel_visibility="never">
<Documentation>The value of this property determines the dataset type
for the output of the programmable filter.</Documentation>
</IntVectorProperty>
<StringVectorProperty
name="Script"
command="SetScript"
number_of_elements="1"
default_values="import numpy as np
from vtk.numpy_interface import dataset_adapter as dsa
from math import ceil, floor

sl = self.GetUnstructuredGridInput() # The streamlines
nsl = dsa.WrapDataObject(sl) # wrap with a Python interface

itime = nsl.PointData['IntegrationTime'] # the time component of the streamlines

nv = nsl.Cells[nsl.CellLocations] # number of verts in each line
ns = nsl.CellLocations + 1 # index of first vertex in each line
ne = ns + nv # index one past the last vertex

lines = [nsl.Cells[i:j] for i,j in zip(ns, ne)] # divide into distinct lines
 # lines[i] is a list of the ids of the
 # vertices that comprise each streamline

# Get length (in integration time) of longest line. Note - this assumes that the 
# forward- and backward- integrations are combined into one streamline (see JoinStreamlines)

mint = itime[lines[0][0]]
maxt = itime[lines[0][-1]]
maxlen = itime[lines[0][-1]] - itime[lines[0][0]]
if len(lines) > 1:
 for i in range(1, len(lines)):
 mt = itime[lines[i][-1]] - itime[lines[i][0]]
 if mt > maxlen:
 maxlen = mt;
 if mint > itime[lines[i][0]]: mint = itime[lines[i][0]]
 if maxt < itime[lines[i][-1]]: maxt = itime[lines[i][-1]]

# dt is the distance between samples in integration time - nt samples distributed along longest line

dt = (maxt - mint) / nt

# destination arrays for streamline points and any point-dependent data - eg. orientation data

iarrays = {'points': nsl.Points} # initialize source arrays with input points
oarrays = {'points': []} # initialize destination arrays with (empty) points

for n in nsl.PointData.keys(): 
 iarrays[n] = nsl.PointData[n] # add input point data arrays to source arrays
 oarrays[n] = [] # add empty destination arrays 

# for each sample time...

for it in range(nt):

 sample_t = mint + (it + t) * dt # the point in time to interpolate at

 for i,line in enumerate(lines): # for each input line...

 # if this sample time is in the range for the current line...

 if sample_t >= itime[line[0]] and sample_t <= itime[line[-1]]:

 # index of first elt greater than sample_x (or 0, in which case we use the last)

 interval_end = np.argmax(itime[line] > sample_t) # linear search?
 if interval_end == 0: interval_end = len(line) - 1

 # get indices of points and point-dependent data at either end of the interval
 endi = line[interval_end]
 starti = line[interval_end - 1]

 # interpolant value in interval
 d = (sample_t - itime[starti]) / (itime[endi] - itime[starti]) # interpolant in interval

 for n in iarrays: # for each array we are interpolating...
 ia = iarrays[n] # input array
 sv = ia[starti] # start values
 ev = ia[endi] # end values
 v = sv + d*(ev - sv) # interpolation
 oarrays[n].append(v)

# create an output vtkUnstructured data with the interpolated points and data

ptsa = np.concatenate(oarrays['points']).reshape((-1, 3)).astype('f4')
oug = vtk.vtkUnstructuredGrid()

op = vtk.vtkPoints()
op.SetNumberOfPoints(ptsa.shape[0])

for i, p in enumerate(ptsa):
 op.InsertPoint(i, p[0], p[1], p[2])


oug.SetPoints(op)

for n in oarrays:
 if n != 'points':
 if oarrays[n][0].__class__ == dsa.VTKArray:
 ncomp = len(oarrays[n][0])
 a = dsa.numpyTovtkDataArray(np.concatenate(oarrays[n]).reshape((-1, ncomp)))
 else:
 a = dsa.numpyTovtkDataArray(oarrays[n])
 a.SetName(n)
 oug.GetPointData().AddArray(a)

ct = dsa.numpyTovtkDataArray(np.array([vtk.VTK_VERTEX]*oug.GetNumberOfPoints()).astype('u1'))
co = dsa.numpy_support.numpy_to_vtkIdTypeArray(np.array(range(0, 2*oug.GetNumberOfPoints(), 2)))

ca = vtk.vtkCellArray()
for i in range(oug.GetNumberOfPoints()):
 ca.InsertNextCell(1, [i])

oug.SetCells(ct, co, ca)

self.GetUnstructuredGridOutput().ShallowCopy(oug)
"
panel_visibility="advanced">
<Hints>
<Widget type="multi_line"/>
</Hints>
<Documentation>This property contains the text of a python program that
the programmable source runs.</Documentation>
</StringVectorProperty>
</SourceProxy>
</ProxyGroup>
</ServerManagerConfiguration>