diff --git a/stltovoxel/perimeter.py b/stltovoxel/perimeter.py index 497034d..95663b8 100644 --- a/stltovoxel/perimeter.py +++ b/stltovoxel/perimeter.py @@ -1,3 +1,5 @@ +import numpy as np + from . import polygon_repair @@ -16,7 +18,7 @@ def repaired_lines_to_voxels(line_list, pixels, plane_shape): def lines_to_voxels(line_list, pixels): current_line_indices = set() - x = 0.5 + x = 0 i = 0 events = generate_line_events(line_list) while i < len(events): @@ -65,8 +67,7 @@ def paint_y_axis(lines, pixels, x): yi = 0 for target_y, inside_change in target_ys: - # Round causes the center of the voxel to be considered. - target_y = round(target_y) + target_y = int(np.ceil(target_y)) assert target_y >= 0 if inside > 0: # Bulk assign all pixels between yi -> target_y diff --git a/stltovoxel/slice.py b/stltovoxel/slice.py index 9f481a6..f7be209 100644 --- a/stltovoxel/slice.py +++ b/stltovoxel/slice.py @@ -15,7 +15,7 @@ def mesh_to_plane(mesh, bounding_box, parallel): z = 0 i = 0 events = generate_tri_events(mesh) - while i < len(events): + while i < len(events) and z < bounding_box[2]: event_z, status, tri_ind = events[i] if event_z > z: mesh_subset = [mesh[ind] for ind in current_mesh_indices] @@ -128,15 +128,13 @@ def calculate_scale_and_shift(mesh_min, mesh_max, resolution, voxel_size): resolution = bounding_box / voxel_size else: if isinstance(resolution, int): + # Integer resolution means number of slices in z resolution = resolution * bounding_box / bounding_box[2] else: resolution = np.array(resolution) - # Want to use all of the voxels we allocate space for. - # Takes one voxel to start rendering scale = resolution / bounding_box - # If the bounding box int_resolution = np.ceil(resolution).astype(int) - centering_offset = (int_resolution - resolution) / (2 * scale) + centering_offset = (int_resolution - resolution - 1) / (2 * scale) shift = mesh_min - centering_offset return scale, shift, int_resolution diff --git a/test/test_main.py b/test/test_main.py index c971b56..2242a9d 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -63,12 +63,12 @@ def test_sparse_resolution(self): def test_convert_mesh(self): mesh = np.array([ - [[30, 0, 25], [42, 11, 0], [18, 11, 0]], - [[30, 0, 25], [42, -13, 0], [42, 11, 0]], - [[30, 0, 25], [18, -13, 0], [42, -13, 0]], - [[42, -13, 0], [18, -13, 0], [42, 11, 0]], - [[18, -13, 0], [18, 11, 0], [42, 11, 0]], - [[30, 0, 25], [18, 11, 0], [18, -13, 0]], + [[30, 0, 25], [42.5, 12.5, 0], [17.5, 12.5, 0]], + [[30, 0, 25], [42.5, -12.5, 0], [42.5, 12.5, 0]], + [[30, 0, 25], [17.5, -12.5, 0], [42.5, -12.5, 0]], + [[42.5, -12.5, 0], [17.5, -12.5, 0], [42.5, 12.5, 0]], + [[17.5, -12.5, 0], [17.5, 12.5, 0], [42.5, 12.5, 0]], + [[30, 0, 25], [17.5, 12.5, 0], [17.5, -12.5, 0]], ]) voxels, _scale, _shift = convert_mesh(mesh, resolution=10) voxels = voxels.astype(int) @@ -85,7 +85,7 @@ def test_convert_mesh(self): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]) self.assertEqual(expected.shape, voxels[6].shape) - self.assertTrue((expected == voxels[6]).all()) + np.testing.assert_array_equal(expected, voxels[6]) if __name__ == '__main__': diff --git a/test/test_perimeter.py b/test/test_perimeter.py index f6a9efb..4f10cd7 100644 --- a/test/test_perimeter.py +++ b/test/test_perimeter.py @@ -7,20 +7,20 @@ class TestPerimeter(unittest.TestCase): def test_lines_to_pixels(self): test = [[(0, 0, 0), (3, 0, 0)], - [(9, 9, 0), (3, 9, 0)], [(3, 0, 0), (9, 9, 0)], + [(9, 9, 0), (3, 9, 0)], [(3, 9, 0), (0, 0, 0)]] actual = np.zeros((13, 13), dtype=bool) perimeter.lines_to_voxels(test, actual) expected = [ - [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], - [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], - [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], diff --git a/test/test_slice.py b/test/test_slice.py index e27c818..f257fca 100644 --- a/test/test_slice.py +++ b/test/test_slice.py @@ -6,21 +6,46 @@ class TestSlice(unittest.TestCase): def test_calculate_scale_and_shift(self): + scale, shift, res = slice.calculate_scale_and_shift(np.array([-2, -2, -2]), np.array([2, 2, 2]), None, 1.5) + np.testing.assert_array_equal([2/3, 2/3, 2/3], scale) + np.testing.assert_array_almost_equal([-1.5, -1.5, -1.5], shift) + np.testing.assert_array_equal([3, 3, 3], res) + + scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([4, 4, 4]), None, 1.5) + np.testing.assert_array_equal([2/3, 2/3, 2/3], scale) + np.testing.assert_array_almost_equal([0.5, 0.5, 0.5], shift) + np.testing.assert_array_equal([3, 3, 3], res) + + scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([2, 2, 2]), None, 1) + np.testing.assert_array_equal([1, 1, 1], scale) + np.testing.assert_array_almost_equal([0.5, 0.5, 0.5], shift) + np.testing.assert_array_equal([2, 2, 2], res) + + scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([2, 2, 2]), 1, None) + np.testing.assert_array_equal([0.5, 0.5, 0.5], scale) + np.testing.assert_array_equal([1, 1, 1], shift) + np.testing.assert_array_equal([1, 1, 1], res) + scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([21, 21, 20]), 10, None) np.testing.assert_array_equal([0.5, 0.5, 0.5], scale) - np.testing.assert_array_equal([-0.5, -0.5, 0], shift) + np.testing.assert_array_equal([0.5, 0.5, 1], shift) np.testing.assert_array_equal([11, 11, 10], res) scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([20.5, 20.5, 20]), 20, None) np.testing.assert_array_equal([1, 1, 1], scale) - np.testing.assert_array_equal([-0.25, -0.25, 0], shift) + np.testing.assert_array_equal([0.25, 0.25, .5], shift) np.testing.assert_array_equal([21, 21, 20], res) scale, shift, res = slice.calculate_scale_and_shift(np.array([0, 0, 0]), np.array([20.125, 20.125, 20]), 10, None) np.testing.assert_array_equal([0.5, 0.5, 0.5], scale) - np.testing.assert_array_equal([-0.9375, -0.9375, 0.0], shift) + np.testing.assert_array_equal([0.0625, 0.0625, 1], shift) np.testing.assert_array_equal([11, 11, 10], res) + scale, shift, res = slice.calculate_scale_and_shift(np.array([-150, -150, -150]), np.array([150, 150, 150]), 3, None) + np.testing.assert_array_equal([0.01, 0.01, 0.01], scale) + np.testing.assert_array_equal([-100, -100, -100], shift) + np.testing.assert_array_equal([3, 3, 3], res) + def test_where_line_crosses_z(self): p1 = np.array([2, 4, 1]) p2 = np.array([1, 2, 5])