-
Notifications
You must be signed in to change notification settings - Fork 1
/
SampleSurfaceCF.py
86 lines (68 loc) · 3.47 KB
/
SampleSurfaceCF.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
## ========================================================================== ##
## Copyright (c) 2019 The University of Texas at Austin. ##
## All rights reserved. ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
## A copy of the License is included with this software in the file LICENSE. ##
## If your copy does not contain the License, you may obtain a copy of the ##
## License at: ##
## ##
## https://www.apache.org/licenses/LICENSE-2.0 ##
## ##
## Unless required by applicable law or agreed to in writing, software ##
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ##
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ##
## See the License for the specific language governing permissions and ##
## limitations under the License. ##
## ##
## ========================================================================== ##
Name = 'RandomSampleSurface'
Label = 'Sample Surface'
Help = 'Sample a surface randomly'
NumberOfInputs = 1
InputDataType = 'vtkPolyData'
OutputDataType = 'vtkUnstructuredGrid'
ExtraXml = ''
Properties = dict(
nsamples = 100
)
def RequestData():
import random
from vtk.numpy_interface import dataset_adapter as dsa
from numpy import cross, ascontiguousarray, array, column_stack, arange
from numpy.linalg import norm
inp = inputs[0]
tf = vtk.vtkTriangleFilter()
tf.SetInputData(inp.VTKObject)
tf.Update()
dobj = dsa.WrapDataObject(tf.GetOutput())
nCells = dobj.GetNumberOfCells()
tris = dobj.GetPolygons().reshape((-1, 4))[:,1:]
points = dobj.GetPoints()
p0 = points[tris[:,0]]
p1 = points[tris[:,1]]
p2 = points[tris[:,2]]
areas = norm(cross(p1-p0, p2-p0), axis=1)/2.0
area_per_sample = sum(areas) / nsamples
samples_per_triangle = [(a / area_per_sample) for a in areas]
samples_per_triangle = [(int(i) + 1) if (random.random() < (i - int(i))) else int(i) for i in samples_per_triangle]
sampled_triangles = [[i]*j for i,j in enumerate(samples_per_triangle)]
sampled_triangles = [j for i in sampled_triangles for j in i]
selected_triangles = tris[sampled_triangles,:]
p = points[selected_triangles[:,0]]
q = points[selected_triangles[:,1]]
r = points[selected_triangles[:,2]]
qp = q - p
rp = r - p
unit = [[random.random(), random.random()] for i in range(len(selected_triangles))]
unit = [u if (u[0]+u[1]) < 1 else [1-u[0], 1-u[1]] for u in unit]
v = [u[0]*q + u[1]*r for u,q,r in zip(unit, qp, rp)]
samples = p + v
output.SetPoints(dsa.VTKArray(samples))
# w0 = array([random.random()/3.0 for t in selected_triangles])
# w1 = array([random.random()/3.0 for t in selected_triangles])
# w2 = 1.0 - (w0 + w1)
# starting_points = points[selected_triangles[:,0]]*w0 + points[selected_triangles[:,1]]*w1 + points[selected_triangles[:,2]]*w2
# npts = len(starting_points)
# output.SetPoints(dsa.VTKArray(starting_points))