summaryrefslogtreecommitdiff
path: root/chroma/bvh/grid.py
diff options
context:
space:
mode:
Diffstat (limited to 'chroma/bvh/grid.py')
-rw-r--r--chroma/bvh/grid.py50
1 files changed, 34 insertions, 16 deletions
diff --git a/chroma/bvh/grid.py b/chroma/bvh/grid.py
index 9ac0306..6fcb3dd 100644
--- a/chroma/bvh/grid.py
+++ b/chroma/bvh/grid.py
@@ -5,7 +5,9 @@ from chroma.gpu.bvh import create_leaf_nodes, merge_nodes_detailed, concatenate_
MAX_CHILD = 2**(32 - CHILD_BITS) - 1
-@profile
+def count_unique_in_sorted(a):
+ return (np.ediff1d(a) > 0).sum() + 1
+
def make_recursive_grid_bvh(mesh, target_degree=3):
'''Returns a BVH created using a 'recursive grid' method.
@@ -24,7 +26,7 @@ def make_recursive_grid_bvh(mesh, target_degree=3):
argsort = morton_codes.argsort()
leaf_nodes = leaf_nodes[argsort]
morton_codes = morton_codes[argsort]
-
+ morton_codes >>= 12
# Create parent layers
layers = [leaf_nodes]
while len(layers[0]) > 1:
@@ -33,27 +35,43 @@ def make_recursive_grid_bvh(mesh, target_degree=3):
# Figure out how many bits to shift in morton code to achieve desired
# degree
nnodes = len(top_layer)
- nunique = len(np.unique(morton_codes))
- while nnodes / float(nunique) < target_degree and nunique > 1:
- morton_codes >>= 1
- nunique = len(np.unique(morton_codes))
+
+ #nunique = count_unique_in_sorted(morton_codes)
+ #while nnodes / float(nunique) < target_degree and nunique > 1:
+ # morton_codes >>= 1
+ # nunique = count_unique_in_sorted(morton_codes)
+ morton_codes >>= 3
+ nunique = count_unique_in_sorted(morton_codes)
# Determine the grouping of child nodes into parents
parent_morton_codes, first_child = np.unique(morton_codes, return_index=True)
+ #assert (np.sort(parent_morton_codes) == parent_morton_codes).all()
first_child = first_child.astype(np.int32)
nchild = np.ediff1d(first_child, to_end=nnodes - first_child[-1])
# Expand groups that have too many children
- print 'Expanding %d parent nodes' % (np.count_nonzero(nchild > MAX_CHILD))
- while nchild.max() > MAX_CHILD:
- index = nchild.argmax()
- new_first = np.arange(first_child[index], first_child[index]+nchild[index], MAX_CHILD)
- first_child = np.concatenate([first_child[:index],
- new_first,
- first_child[index+1:]])
- parent_morton_codes = np.concatenate([parent_morton_codes[:index],
- np.repeat(parent_morton_codes[index], len(new_first)),
- parent_morton_codes[index+1:]])
+ excess_children = np.argwhere(nchild > MAX_CHILD)
+ if len(excess_children) > 0:
+ print 'Expanding %d parent nodes' % len(excess_children)
+ parent_morton_parts = np.split(parent_morton_codes, excess_children)
+ first_child_parts = np.split(first_child, excess_children)
+ nchild_parts = np.split(nchild, excess_children)
+
+ new_parent_morton_parts = parent_morton_parts[:1]
+ new_first_child_parts = first_child_parts[:1]
+
+ for morton_part, first_part, nchild_part in zip(parent_morton_parts[1:],
+ first_child_parts[1:],
+ nchild_parts[1:]):
+ extra_first = np.arange(first_part[0],
+ first_part[0]+nchild_part[0],
+ MAX_CHILD)
+ new_first_child_parts.extend([extra_first, first_part[1:]])
+ new_parent_morton_parts.extend([np.repeat(parent_morton_codes[0],
+ len(extra_first)), morton_part[1:]])
+
+ parent_morton_codes = np.concatenate(new_parent_morton_parts)
+ first_child = np.concatenate(new_first_child_parts)
nchild = np.ediff1d(first_child, to_end=nnodes - first_child[-1])
if nunique > 1: # Yes, I'm pedantic