-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathOrientedGlyphCF.xml
140 lines (114 loc) · 6.79 KB
/
OrientedGlyphCF.xml
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
<ServerManagerConfiguration>
<ProxyGroup name="filters">
<SourceProxy name="OrientedGlyph" class="vtkPythonProgrammableFilter" label="Oriented Glyph">
<Documentation
long_help="Place a glyph at each point using two vectors for orientation"
short_help="Place a glyph at each point using two vectors for orientation">
</Documentation>
<InputProperty
name="Input"
clean_command="RemoveAllInputs"
command="AddInputConnection"
multiple_input="1">
<ProxyGroupDomain name="groups">
<Group name="sources"/>
<Group name="filters"/>
</ProxyGroupDomain>
<DataTypeDomain name="input_type">
<DataType value="vtkUnstructuredGrid"/>
</DataTypeDomain>
</InputProperty>
<IntVectorProperty
name="dbg"
label="dbg"
initial_string="dbg"
command="SetParameter"
animateable="1"
default_values="999"
number_of_elements="1">
<Documentation></Documentation>
</IntVectorProperty>
<StringVectorProperty
name="forward"
label="forward"
initial_string="forward"
command="SetParameter"
animateable="1"
default_values="velocity"
number_of_elements="1">
<Documentation></Documentation>
</StringVectorProperty>
<DoubleVectorProperty
name="scale"
label="scale"
initial_string="scale"
command="SetParameter"
animateable="1"
default_values="1.0"
number_of_elements="1">
<Documentation></Documentation>
</DoubleVectorProperty>
<StringVectorProperty
name="up"
label="up"
initial_string="up"
command="SetParameter"
animateable="1"
default_values="Normals"
number_of_elements="1">
<Documentation></Documentation>
</StringVectorProperty>
<DoubleVectorProperty
name="xscale"
label="xscale"
initial_string="xscale"
command="SetParameter"
animateable="1"
default_values="1.0"
number_of_elements="1">
<Documentation></Documentation>
</DoubleVectorProperty>
<DoubleVectorProperty
name="yscale"
label="yscale"
initial_string="yscale"
command="SetParameter"
animateable="1"
default_values="1.0"
number_of_elements="1">
<Documentation></Documentation>
</DoubleVectorProperty>
<DoubleVectorProperty
name="zscale"
label="zscale"
initial_string="zscale"
command="SetParameter"
animateable="1"
default_values="1.0"
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 time import time
from vtk.numpy_interface import dataset_adapter as dsa
from vtk.util import numpy_support as ns

ipoints = inputs[0]
number_of_glyphs = ipoints.GetNumberOfPoints()

glyph = inputs[1]

glyph_points = [scale*xscale, scale*yscale, scale*zscale] * glyph.Points
points_per_glyph = glyph_points.shape[0]

cells_per_glyph = len(glyph.CellTypes)

if forward not in ipoints.PointData.keys():
 print('can\'t find forward array')
 return

U = ipoints.PointData[forward]

if up not in ipoints.PointData.keys():
 print('can\'t find up array')
 return

V = ipoints.PointData[up]

W = dsa.VTKArray(np.cross(U, V))

l = np.linalg.norm(U, axis=1)
U = U / np.where(l == 0, 1.0, l)
l = np.linalg.norm(U, axis=1)
V = V / np.where(l == 0, 1.0, l)
l = np.linalg.norm(W, axis=1)
W = W / np.where(l == 0, 1.0, l)

P = ipoints.Points

p = P[0]
u = U[0]
v = V[0]
w = W[0]

xpts = glyph_points[:,0][:,np.newaxis]
ypts = glyph_points[:,1][:,np.newaxis]
zpts = glyph_points[:,2][:,np.newaxis]

opoints = []
for i,p,u,v,w in zip(range(len(P)), P, U, V, W):
 opoints.append(p + xpts*u + ypts*v + zpts*w)

opolys = [glyph.Cells.reshape(-1,4)]

ijk = glyph.Cells.reshape((-1,4))[:,1:4]

for i in range(1, len(P)):
 nijk = np.column_stack(([3]*ijk.shape[0], ijk + i*points_per_glyph))
 opolys.append(nijk)

opoints = dsa.numpyTovtkDataArray(np.vstack(opoints))

ids = [np.array([i]*points_per_glyph) for i in range(len(P))]
ids = dsa.numpyTovtkDataArray(np.vstack(ids).flatten(), name='ID')

oug = vtk.vtkUnstructuredGrid()

pts = vtk.vtkPoints()
pts.SetData(opoints)
oug.SetPoints(pts)

ct = np.hstack([glyph.CellTypes for i in range(number_of_glyphs)])
co = np.hstack([glyph.CellLocations + i*len(glyph.Cells) for i in range(number_of_glyphs)])
opolys = np.hstack(opolys).astype('i8')

ct = dsa.numpyTovtkDataArray(ct)
co = dsa.numpy_support.numpy_to_vtkIdTypeArray(co)
opolys = ns.numpy_to_vtkIdTypeArray(opolys)

ca = vtk.vtkCellArray()
ca.SetCells(number_of_glyphs*cells_per_glyph, opolys)

oug.SetCells(ct, co, ca)
oug.GetPointData().AddArray(ids)

oug.GetPointData().AddArray(dsa.numpyTovtkDataArray(np.vstack([glyph.PointData['Normals'] for i in range(number_of_glyphs)]), name='Normals'))

if 'Texture Coordinates' in glyph.PointData.keys(): 
 a = np.vstack([glyph.PointData['Texture Coordinates'] for	 i in range(len(ipoints.Points))])
 oug.GetPointData().SetTCoords(dsa.numpyTovtkDataArray(a))

for n in ipoints.PointData.keys():
 if n != 'Normals':
 a = [[ipoints.PointData[n][i]]*points_per_glyph for i in range(number_of_glyphs)]
 oug.GetPointData().AddArray(dsa.numpyTovtkDataArray(np.concatenate(a), name=n))

self.GetUnstructuredGridOutput().Initialize()
self.GetUnstructuredGridOutput().ShallowCopy(oug)

return
"
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>