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
|
import numpy as np
from bvh import *
class Geometry(object):
"""
Geometry object.
"""
def __init__(self):
self.materials = []
self.mesh = np.empty(0)
self.inside = np.empty(0)
self.outside = np.empty(0)
def add_mesh(self, mesh, inside, outside):
"""
Add a triangle mesh.
Args:
- mesh: array of shape (n,3,3)
Array of vertices for a closed mesh with n triangles.
- inside: Material
Material inside the mesh.
- outside: Material
Material outside the mesh.
"""
if len(mesh.shape) != 3 or mesh.shape[1] != 3 or mesh.shape[2] != 3:
raise Exception('shape mismatch')
if inside not in self.materials:
self.materials.append(inside)
if outside not in self.materials:
self.materials.append(outside)
self.inside.resize(self.inside.size+mesh.shape[0])
self.inside[-mesh.shape[0]:] = np.tile(self.materials.index(inside), mesh.shape[0])
self.outside.resize(self.outside.size+mesh.shape[0])
self.outside[-mesh.shape[0]:] = np.tile(self.materials.index(outside), mesh.shape[0])
self.mesh.resize((self.mesh.shape[0]+mesh.shape[0],3,3))
self.mesh[-mesh.shape[0]:] = mesh
def build(self, bits=16):
order, zvalues = morton_order(self.mesh, bits)
zvalues = zvalues[order]
self.mesh = self.mesh[order]
self.inside = self.inside[order]
self.outside = self.outside[order]
leafs = []
for z in sorted(set(zvalues)):
mask = (zvalues == z)
leafs.append(Leaf(self.mesh[mask], 3*np.where(mask)[0][0], z))
layers = []
layers.append(leafs)
while True:
zvalues = np.array([node.zvalue for node in layers[-1]])
bit_shifted_zvalues = zvalues >> 1
nodes = []
for z in sorted(set(bit_shifted_zvalues)):
mask = (bit_shifted_zvalues == z)
nodes.append(Node(list(compress(layers[-1], mask)), z))
layers.append(nodes)
if len(nodes) == 1:
break
layers.reverse()
nodes = []
for layer in layers:
for node in layer:
nodes.append(node)
self.lower_bound = np.empty((len(nodes),3))
self.upper_bound = np.empty((len(nodes),3))
self.child_map = np.empty(len(nodes))
self.child_len = np.empty(len(nodes))
self.first_leaf = -1
for i, node in enumerate(nodes):
self.lower_bound[i] = node.lower_bound
self.upper_bound[i] = node.upper_bound
self.child_len[i] = node.size
if isinstance(node, Node):
for j, child in enumerate(nodes):
if child is node.children[0]:
self.child_map[i] = j
break
if isinstance(node, Leaf):
self.child_map[i] = node.mesh_idx
if self.first_leaf == -1:
self.first_leaf = i
|