diff options
author | Stan Seibert <stan@mtrr.org> | 2012-01-17 16:04:10 -0500 |
---|---|---|
committer | tlatorre <tlatorre@uchicago.edu> | 2021-05-09 08:42:38 -0700 |
commit | f48cd1e05b73e99ee4ca7e77e3219509544168ce (patch) | |
tree | 43f04656320194505fae8a5090bd273532d50c31 /test | |
parent | dcb773e98db1d38ed616315cb3cf27ca17ebd441 (diff) | |
download | chroma-f48cd1e05b73e99ee4ca7e77e3219509544168ce.tar.gz chroma-f48cd1e05b73e99ee4ca7e77e3219509544168ce.tar.bz2 chroma-f48cd1e05b73e99ee4ca7e77e3219509544168ce.zip |
BVH and BVHLayer classes with unittests.
These classes will be the data types used by the new BVH generation code.
Diffstat (limited to 'test')
-rw-r--r-- | test/test_bvh.py | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/test/test_bvh.py b/test/test_bvh.py new file mode 100644 index 0000000..5372f6e --- /dev/null +++ b/test/test_bvh.py @@ -0,0 +1,159 @@ +import unittest +from chroma.bvh import BVH, BVHLayerSlice, WorldCoords, uint4, \ + OutOfRangeError, unpack_nodes +import numpy as np +from numpy.testing import assert_array_max_ulp, assert_array_equal, \ + assert_approx_equal + +def lslice(layer_bounds, layer_number): + '''Returns a slice object for retrieving a particular layer in an + array of nodes.''' + return slice(layer_bounds[layer_number], layer_bounds[layer_number+1]) + +class TestWorldCoords(unittest.TestCase): + def setUp(self): + self.coords = WorldCoords([-1,-1,-1], 0.1) + + def test_fixed_to_world(self): + f = [0, 1, 100] + assert_array_max_ulp(self.coords.fixed_to_world(f), + [-1.0, -0.9, 9.0], dtype=np.float32) + + def test_world_to_fixed(self): + w = [-1.0, -0.9, 9.0] + assert_array_equal(self.coords.world_to_fixed(w), + [0, 1, 100]) + + + def test_fixed_array_to_world(self): + f = [[0, 1, 100], + [20, 40, 60], + [210, 310, 410]] + + assert_array_max_ulp(self.coords.fixed_to_world(f), + [[-1.0, -0.9, 9.0], + [1.0, 3.0, 5.0], + [20.0, 30.0, 40.0]], + dtype=np.float32) + + def test_world_array_to_fixed(self): + w = [[-1.0, -0.9, 9.0], + [1.0, 3.0, 5.0], + [20.0, 30.0, 40.0]] + assert_array_equal(self.coords.world_to_fixed(w), + [[0, 1, 100], + [20, 40, 60], + [210, 310, 410]]) + + def test_out_of_range(self): + with self.assertRaises(OutOfRangeError): + self.coords.world_to_fixed([-2.0, 0.0, 0.0]) + with self.assertRaises(OutOfRangeError): + self.coords.world_to_fixed([0.0, 1e9, 0.0]) + +def create_bvh(): + # 3 layer binary tree + degree = 2 + world_coords = WorldCoords(np.array([-1.0,-1.0,-1.0]), 0.1) + layer_bounds = [0, 1, 3, 7] + nodes = np.empty(shape=layer_bounds[-1], dtype=uint4) + + # bottom layer + layer = lslice(layer_bounds, 2) + nodes['x'][layer] = [ 0x00010000, 0x00020001, + 0x00010000, 0x00010000] + nodes['y'][layer] = [ 0x00010000, 0x00010000, + 0x00020001, 0x00010000] + nodes['z'][layer] = [ 0x00010000, 0x00010000, + 0x00010000, 0x00020001] + nodes['w'][layer] = 0x80000000 # leaf nodes + + # middle layer + layer = lslice(layer_bounds, 1) + nodes['x'][layer] = [ 0x00020000, 0x00010000 ] + nodes['y'][layer] = [ 0x00010000, 0x00020000 ] + nodes['z'][layer] = [ 0x00010000, 0x00020000 ] + nodes['w'][layer] = [ 0x00000003, 0x00000005 ] + + # top layer + layer = lslice(layer_bounds, 0) + nodes['x'][layer] = [ 0x00020000 ] + nodes['y'][layer] = [ 0x00020000 ] + nodes['z'][layer] = [ 0x00020000 ] + nodes['w'][layer] = [ 0x00000001 ] + + layer_offsets = list(layer_bounds[:-1]) # trim last entry + bvh = BVH(degree=degree, world_coords=world_coords, + nodes=nodes, layer_offsets=layer_offsets) + + return bvh + +def test_unpack_nodes(): + bvh = create_bvh() + + layer = bvh.get_layer(2) + unpack = unpack_nodes(layer.nodes) + assert_array_equal(unpack['xlo'], [0, 1, 0, 0]) + assert_array_equal(unpack['xhi'], [1, 2, 1, 1]) + assert_array_equal(unpack['ylo'], [0, 0, 1, 0]) + assert_array_equal(unpack['yhi'], [1, 1, 2, 1]) + assert_array_equal(unpack['zlo'], [0, 0, 0, 1]) + assert_array_equal(unpack['zhi'], [1, 1, 1, 2]) + assert unpack['leaf'].all() + + layer = bvh.get_layer(1) + unpack = unpack_nodes(layer.nodes) + assert_array_equal(unpack['xlo'], [0, 0]) + assert_array_equal(unpack['xhi'], [2, 1]) + assert_array_equal(unpack['ylo'], [0, 0]) + assert_array_equal(unpack['yhi'], [1, 2]) + assert_array_equal(unpack['zlo'], [0, 0]) + assert_array_equal(unpack['zhi'], [1, 2]) + assert_array_equal(unpack['child'], [3, 5]) + assert not unpack['leaf'].any() + + layer = bvh.get_layer(0) + unpack = unpack_nodes(layer.nodes) + assert_array_equal(unpack['xlo'], [0]) + assert_array_equal(unpack['xhi'], [2]) + assert_array_equal(unpack['ylo'], [0]) + assert_array_equal(unpack['yhi'], [2]) + assert_array_equal(unpack['zlo'], [0]) + assert_array_equal(unpack['zhi'], [2]) + assert_array_equal(unpack['child'], [1]) + assert not unpack['leaf'].any() + + +class TestBVH(unittest.TestCase): + def setUp(self): + self.bvh = create_bvh() + + def test_len(self): + self.assertEqual(len(self.bvh), 7) + + def test_layer_count(self): + self.assertEqual(self.bvh.layer_count(), 3) + + def test_get_layer(self): + layer = self.bvh.get_layer(0) + self.assertEqual(len(layer), 1) + + layer = self.bvh.get_layer(1) + self.assertEqual(len(layer), 2) + + layer = self.bvh.get_layer(2) + self.assertEqual(len(layer), 4) + +class TestBVHLayer(unittest.TestCase): + def setUp(self): + self.bvh = create_bvh() + + def test_area(self): + layer = self.bvh.get_layer(2) + assert_approx_equal(layer.area(), 4*6*0.1**2) + + layer = self.bvh.get_layer(1) + assert_approx_equal(layer.area(), (4*2+2 + 4*2+2*4)*0.1**2) + + layer = self.bvh.get_layer(0) + assert_approx_equal(layer.area(), (6*2*2)*0.1**2) |