class TestDistanceToEdgesCubeOutsideFixedSingle(): pt_out = np.array([1, 0.5, 0.5]) ast = asteroid.Asteroid('castalia', 256, 'mat') v, f = wavefront.read_obj('./integration/cube.obj') ast = ast.loadmesh(v, f, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_edges(pt_out, v, f, normal_face, edge_vertex_map, edge_face_map, vf_map) D_exp = 0.5 P_exp = np.array([0.5, 0.5, 0.5]) V_exp = [7, 4] E_exp = [7, 4] F_exp = [6, 7] def test_distance(self): np.testing.assert_allclose(self.D, self.D_exp) def test_point(self): np.testing.assert_array_almost_equal(self.P, self.P_exp) def test_vertex(self): np.testing.assert_allclose(self.V, self.V_exp) def test_edge(self): np.testing.assert_allclose(self.E, self.E_exp) def test_face(self): np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToEdgesCubeOutsideEdge(): pt_out = np.array([0.6, 0.6, 0.6]) v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') ast = asteroid.Asteroid('castalia', 256, 'mat') ast = ast.loadmesh(v_cube, f_cube, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube, normal_face, edge_vertex_map, edge_face_map, vf_map) D_exp = P_exp = E_exp = F_exp = [] def test_distance(self): np.testing.assert_allclose(self.D, self.D_exp) def test_point(self): np.testing.assert_allclose(self.P, np.empty(shape=(0, 3))) def test_vertex(self): np.testing.assert_allclose(self.V, np.empty(shape=(0, 2))) def test_edge(self): np.testing.assert_allclose(self.E, np.empty(shape=(0, 2))) def test_face(self): np.testing.assert_allclose(self.F, self.F_exp)
class TestCenterOfFace(): v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') cof = wavefront.center_of_face(v_cube, f_cube) def test_size(self): np.testing.assert_allclose(self.cof.shape, self.f_cube.shape)
class TestDistanceToVerticesCubeOutsideRandom(): """Ranom location that is always outside the cube """ pt_out = np.random.uniform(0.51 * np.sqrt(3), 1) * sphere.rand(2) v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') ast = asteroid.Asteroid('castalia', 256, 'mat') ast = ast.loadmesh(v_cube, f_cube, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_vertices(pt_out, v_cube, f_cube, normal_face, edge_vertex_map, edge_face_map, vf_map) def test_distance(self): np.testing.assert_allclose(np.isfinite(self.D), True) def test_point(self): np.testing.assert_allclose(len(self.P) >= 3, True) def test_vertex(self): np.testing.assert_allclose(np.isfinite(self.V), True) def test_edge(self): np.testing.assert_allclose(np.isfinite(self.E), True) def test_face(self): np.testing.assert_allclose(len(self.F) >= 1, True)
class TestDistanceToEdgesCubeInside(): pt_out = np.array([0.4, 0.4, 0.2]) v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') ast = asteroid.Asteroid('castalia', 256, 'mat') ast = ast.loadmesh(v_cube, f_cube, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube, normal_face, edge_vertex_map, edge_face_map, vf_map) D_exp = -0.1 * np.sqrt(2) * np.ones_like(D) P_exp = np.array([[0.5, 0.5, 0.2], [0.5, 0.5, 0.2]]) V_exp = np.array([[6, 7], [7, 6]]) E_exp = np.array([[6, 7], [7, 6]]) F_exp = np.array([[4, 6], [4, 6]]) def test_distance(self): np.testing.assert_allclose(self.D, self.D_exp) def test_point(self): np.testing.assert_allclose(self.P, self.P_exp) def test_vertex(self): np.testing.assert_allclose(self.V, self.V_exp) def test_edge(self): for E, E_exp in zip(self.E, self.E_exp): np.testing.assert_allclose(E, E_exp) def test_face(self): np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToEdgesCubeSurfaceSingle(): pt_out = np.array([0.5, 0.4, 0.3]) v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') ast = asteroid.Asteroid('castalia', 256, 'mat') ast = ast.loadmesh(v_cube, f_cube, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube, normal_face, edge_vertex_map, edge_face_map, vf_map) D_exp = 0.1 / 2 * np.sqrt(2) P_exp = np.array([0.5, 0.35, 0.35]) V_exp = np.array([4, 7]) E_exp = np.array([4, 7]) F_exp = np.array([6, 7]) def test_distance(self): np.testing.assert_allclose(self.D, self.D_exp) def test_point(self): np.testing.assert_allclose(self.P, self.P_exp) def test_vertex(self): np.testing.assert_allclose(self.V, self.V_exp) def test_edge(self): np.testing.assert_allclose(self.E, self.E_exp) def test_face(self): np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToMeshCubeVertex(): v, f = wavefront.read_obj('./integration/cube.obj') mesh_parameters = wavefront.polyhedron_parameters(v, f) pt = np.array([1, 0.5, 0.5]) D, P, V, E, F, primitive = wavefront.distance_to_mesh( pt, v, f, mesh_parameters) D_exp = 0.5 P_exp = np.array([0.5, 0.5, 0.5]) V_exp = np.array(7) E_exp = np.array([[7, 2], [7, 4], [7, 1], [6, 7], [7, 3], [7, 6], [5, 7], [7, 5], [3, 7], [2, 7], [4, 7], [1, 7]]) F_exp = np.array([4, 5, 6, 7, 10, 11]) primitive_exp = 'vertex' def test_distance(self): np.testing.assert_allclose(self.D, self.D_exp) def test_point(self): np.testing.assert_array_almost_equal(self.P, self.P_exp) def test_vertex(self): np.testing.assert_allclose(self.V, self.V_exp) def test_edge(self): np.testing.assert_allclose(self.E, self.E_exp) def test_face(self): np.testing.assert_allclose(self.F, self.F_exp) def test_primitive(self): np.testing.assert_string_equal(self.primitive, self.primitive_exp)
def test_face_insertion(pt=np.array([1, 0.1, 0])): v, f = wavefront.read_obj('./integration/cube.obj') mesh_parameters = wavefront.polyhedron_parameters(v, f) D, P, V, E, F, primitive = wavefront.distance_to_mesh( pt, v, f, mesh_parameters) nv, nf = wavefront.face_insertion(pt, v, f, D, P, V, E, F) mfig = graphics.mayavi_figure() graphics.mayavi_addMesh(mfig, nv, nf)
def test_complete_controller(self): v, f = wavefront.read_obj('./data/shape_model/CASTALIA/castalia.obj') mesh = mesh_data.MeshData(v, f) rmesh = reconstruct.ReconstructMesh(mesh) cont = controller.Controller() cont.explore_asteroid(self.state, rmesh) print(cont.get_posd())
class TestStats: v, f = wavefront.read_obj('./integration/cube.obj') mesh = mesh_data.MeshData(v, f) def test_volume_vertices(self): np.testing.assert_allclose(stats.volume(self.v, self.f), 1) def test_volume_mesh(self): np.testing.assert_allclose(stats.volume(self.mesh), 1)
class TestDistanceToVerticesCubeOutsideFixedMultiple(): """This point is equally close to an entire face of the cube So there are 4 vertices equidistant from pt """ pt_out = np.array([1, 0, 0]) v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') ast = asteroid.Asteroid('castalia', 256, 'mat') ast = ast.loadmesh(v_cube, f_cube, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_vertices(pt_out, v_cube, f_cube, normal_face, edge_vertex_map, edge_face_map, vf_map) D_exp = np.ones_like(D) * 0.5 * np.sqrt(3) P_exp = np.array([[0.5, -0.5, -0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5], [0.5, 0.5, 0.5]]) V_exp = np.array([4, 5, 6, 7]) E_exp = np.array([ np.array([[6, 4], [7, 4], [4, 0], [4, 6], [5, 4], [0, 4], [4, 7], [4, 5]]), np.array([[5, 0], [5, 1], [5, 7], [5, 4], [1, 5], [7, 5], [4, 5], [0, 5]]), np.array([[6, 0], [6, 4], [4, 6], [6, 2], [6, 7], [7, 6], [0, 6], [2, 6]]), np.array([[7, 2], [7, 4], [7, 1], [6, 7], [7, 3], [7, 6], [5, 7], [7, 5], [3, 7], [2, 7], [4, 7], [1, 7]]) ]) F_exp = np.array([ list([0, 6, 7, 8]), list([7, 8, 9, 10]), list([0, 1, 4, 6]), list([4, 5, 6, 7, 10, 11]) ]) def test_distance(self): np.testing.assert_allclose(np.absolute(self.D), self.D_exp) def test_point(self): np.testing.assert_allclose(self.P, self.P_exp) def test_vertex(self): np.testing.assert_allclose(self.V, self.V_exp) def test_edge(self): for E, E_exp in zip(self.E, self.E_exp): np.testing.assert_allclose(E, E_exp) def test_face(self): for F, F_exp in zip(self.F, self.F_exp): np.testing.assert_allclose(F, F_exp)
def test_distance_to_mesh(pt=np.random.uniform(0.8, 1.5) * sphere.rand(2)): """Test out the point processing function """ v, f = wavefront.read_obj('./integration/cube.obj') mesh_parameters = wavefront.polyhedron_parameters(v, f) D, P, V, E, F, primitive = wavefront.distance_to_mesh( pt, v, f, mesh_parameters) plot_data(pt, v, f, D, P, V, E, F, 'Min Primitive: ' + primitive) return D, P, V, E, F, primitive
class TestVertexFaceMap(): v_cube, f_cube = wavefront.read_obj('./integration/cube.obj') vf_map = wavefront.vertex_face_map(v_cube, f_cube) def test_size(self): np.testing.assert_allclose(len(self.vf_map), self.v_cube.shape[0]) def test_each_vertex_inside_a_face(self): for faces in self.vf_map: np.testing.assert_allclose(len(faces) >= 1, True)
class TestGeodesic: # generate some random unit vectors pt = np.random.rand(3) pt = pt / np.linalg.norm(pt) v, _ = wavefront.read_obj('./data/shape_model/ITOKAWA/itokawa_high.obj') def test_central_angle(self): csigma = geodesic.central_angle(self.pt, self.v) psigma = wavefront.spherical_distance(self.pt, self.v) np.testing.assert_allclose(csigma, psigma)
def main(input_file): mfig = graphics.mayavi_figure() v, f = wavefront.read_obj(input_file) mesh = graphics.mayavi_addMesh(mfig, v, f, color=(1, 0, 0), representation='wireframe') graphics.mayavi_addMesh(mfig, v, f, representation='surface') graphics.mlab.view(*(0, 90, 2.76, np.array([0, 0, 0]))) print(input_file.split('.')) graphics.mayavi_savefig(mfig, '/tmp/isotropic.jpg', magnification=4)
def test_translation_controller_minimum_uncertainty(self): v, f = wavefront.read_obj('./data/shape_model/CASTALIA/castalia.obj') # create a mesh mesh = mesh_data.MeshData(v, f) rmesh = reconstruct.ReconstructMesh(mesh) tran_cont = controller.TranslationController() tran_cont.minimize_uncertainty(self.state, rmesh) np.testing.assert_allclose(tran_cont.get_posd().shape, (3, )) np.testing.assert_allclose(tran_cont.get_veld(), np.zeros(3)) np.testing.assert_allclose(tran_cont.get_acceld(), np.zeros(3))
class TestReconstruction(): filename = './data/shape_model/ITOKAWA/itokawa_low.obj' ratio = 0.5 v, f = wavefront.read_obj(filename) dv, df = wavefront.decimate_numpy(v, f, ratio) rv, rf = wavefront.reconstruct_numpy(v) def test_reconstruct_vertices(self): np.testing.assert_allclose(self.v.shape[1], self.rv.shape[1]) def test_reconstruct_faces(self): np.testing.assert_allclose(self.f.shape[1], self.rf.shape[1])
class TestSphericalMeshUpdate(): """Test out the spherical mesh update function """ v, f = wavefront.read_obj('./integration/cube.obj') weight = np.full(v.shape[0], 1) max_angle = 1 def test_mesh_update(self): pt = np.array([1, 1, 1]) nv, nw = wavefront.spherical_incremental_mesh_update(pt, self.v, self.f, self.weight, self.max_angle) np.testing.assert_allclose(nv[-1, :], pt) np.testing.assert_allclose(nw[-1], 0)
class TestMeshData: v, f = wavefront.read_obj('./integration/cube.obj') mesh = mesh_data.MeshData(v, f) def test_vertices(self): np.testing.assert_allclose(self.mesh.get_verts(), self.v) def test_faces(self): np.testing.assert_allclose(self.mesh.get_faces(), self.f) def test_update_mesh(self): v, f = wavefront.read_obj('./data/shape_model/CASTALIA/castalia.obj') self.mesh.update_mesh(v, f) np.testing.assert_allclose(self.mesh.get_verts(), v) np.testing.assert_allclose(self.mesh.get_faces(), f)
class TestDecimation(): """Ensure decimation is working properly """ filename = './data/shape_model/ITOKAWA/itokawa_low.obj' ratio = 0.5 v, f = wavefront.read_obj(filename) dv, df = wavefront.decimate_numpy(v, f, ratio) def test_ensure_vertices_ratio(self): np.testing.assert_array_less(self.dv.shape[0], self.v.shape[0]) def test_ensure_faces_ratio(self): np.testing.assert_array_less(self.df.shape[0], self.f.shape[0]) def test_ensure_polyhedron_is_closed(self): pass
def test_closest_edge_plot_cube(pt=np.random.uniform(0.9, 1.5) * sphere.rand(2)): ast = asteroid.Asteroid('castalia', 256, 'mat') v, f = wavefront.read_obj('./integration/cube.obj') ast = ast.loadmesh(v, f, 'cube') edge_vertex_map = ast.asteroid_grav['edge_vertex_map'] edge_face_map = ast.asteroid_grav['edge_face_map'] normal_face = ast.asteroid_grav['normal_face'] vf_map = ast.asteroid_grav['vertex_face_map'] D, P, V, E, F = wavefront.distance_to_edges(pt, v, f, normal_face, edge_vertex_map, edge_face_map, vf_map) plot_data(pt, v, f, D, P, V, E, F, '') return D, P, V, E, F
def raycasting_visualization(): v, f = wavefront.read_obj('./data/shape_model/ITOKAWA/itokawa_low.obj') caster = raycaster.RayCaster.loadmesh(v, f) renderer = vtk.vtkRenderer() pSource = np.array([-2.0, 0, 0]) pTarget = np.array([2, 0, 0]) intersections = caster.castray(pSource, pTarget) for p in intersections: vtk_addPoint(renderer, p, color=[0, 0, 1], radius=0.01) vtk_addPoly(renderer, caster.polydata) vtk_show(renderer)
class TestMeshDist: # load the vertices, faces v, f = wavefront.read_obj('./integration/cube.obj') # create a mesh mesh = mesh_data.MeshData(v, f) mesh_dist = cgal.MeshDistance(mesh) caster = cgal.RayCaster(mesh) pt = np.array([2, 0, 0], dtype=np.float64) # pass to distance function def test_minimum_distance(self): dist = self.caster.minimum_distance(self.pt) np.testing.assert_allclose(dist, 1.5) def test_intersection_raycasting(self): intersections = self.caster.castray( self.pt, np.array([0, 0, 0], dtype=np.float64))
def test_normal_face_plot(): """Plot the normals to the faces on a mesh and view in Mayavi """ v, f = wavefront.read_obj('./integration/cube.obj') normal_face = wavefront.normal_face(v, f) cof = wavefront.center_of_face(v, f) mfig = graphics.mayavi_figure() _ = graphics.mayavi_addMesh(mfig, v, f) for p1, u in zip(cof, normal_face): graphics.mayavi_addPoint(mfig, p1, radius=0.1, color=(1, 0, 0)) graphics.mayavi_addLine(mfig, p1, u + p1) graphics.mayavi_addTitle(mfig, 'Normals to each face', color=(0, 0, 0), size=0.5)
class TestFaceInsertion(): v, f = wavefront.read_obj('./integration/cube.obj') pt = np.array([1, 0.1, 0]) mesh_parameters = wavefront.polyhedron_parameters(v, f) D, P, V, E, F, primitive = wavefront.distance_to_mesh( pt, v, f, mesh_parameters) nv, nf = wavefront.face_insertion(pt, v, f, D, P, V, E, F) # expected solutions nv_exp = np.array([[-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], [-0.5, 0.5, -0.5], [-0.5, 0.5, 0.5], [0.5, -0.5, -0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5], [0.5, 0.5, 0.5], [1., 0.1, 0.]]) nf_exp = np.array([[0, 6, 4], [0, 2, 6], [0, 3, 2], [0, 1, 3], [2, 7, 6], [2, 3, 7], [4, 7, 5], [0, 4, 5], [0, 5, 1], [1, 5, 7], [1, 7, 3], [4, 6, 8], [6, 7, 8], [7, 4, 8]]) def test_vertices(self): np.testing.assert_allclose(self.nv, self.nv_exp) def test_faces(self): np.testing.assert_allclose(self.nf, self.nf_exp) def test_vertices_shape(self): np.testing.assert_allclose(self.nv.shape, (self.v.shape[0] + 1, 3))
def test_radius_mesh_update_cube(pt=np.array([1, 0, 0])): """Update the mesh by modifying the radius of the closest point """ # load the cube v, f = wavefront.read_obj('./integration/cube.obj') mesh_parameters = wavefront.polyhedron_parameters(v, f) # pick a point nv, nf = wavefront.radius_mesh_incremental_update(pt, v, f, mesh_parameters, max_angle=np.deg2rad(10)) # plot the new mesh mfig = graphics.mayavi_figure() graphics.mayavi_addMesh(mfig, nv, nf) graphics.mayavi_addPoint(mfig, pt) graphics.mayavi_points3d(mfig, v, color=(0, 1, 0)) return nv, nf
def test_reconstruct(): """Read a OBJ file, reconstruct it's surface using VTK and plot """ filename = './data/shape_model/ITOKAWA/itokawa_low.obj' ratio = 0.5 v, f = wavefront.read_obj(filename) dv, df = wavefront.decimate_numpy(v, f, ratio) rv, rf = wavefront.reconstruct_numpy(v) # create some figures orig_fig = mlab.figure() reconstruct_fig = mlab.figure() _ = graphics.draw_polyhedron_mayavi(v, f, orig_fig) mlab.title('Original OBJ') _ = graphics.draw_polyhedron_mayavi(rv, rf, reconstruct_fig) mlab.title('Reconstructed OBJ') # display both and complete test print('Now compare the two images')
def test_radius_cube_into_sphere(): """Transform a cube into a sphere """ vc, fc = wavefront.read_obj('./integration/cube.obj') vs, fs = wavefront.ellipsoid_mesh(2, 2, 2, density=10, subdivisions=0) mfig = graphics.mayavi_figure() mesh = graphics.mayavi_addMesh(mfig, vc, fc) graphics.mayavi_points3d(mfig, vc, color=(0, 1, 0)) ms = mesh.mlab_source for ii in range(5): for pt in vs: mesh_param = wavefront.polyhedron_parameters(vc, fc) vc, fc = wavefront.radius_mesh_incremental_update( pt, vc, fc, mesh_param, max_angle=np.deg2rad(45)) ms.reset(x=vc[:, 0], y=vc[:, 1], z=vc[:, 2], triangles=fc) graphics.mayavi_addPoint(mfig, pt) input('Mesh subdivison') vc, fc = wavefront.mesh_subdivide(vc, fc, 1) ms.reset(x=vc[:, 0], y=vc[:, 1], z=vc[:, 2], triangles=fc)
def test_point_insertion_random(): num_points = 100 nv, nf = wavefront.read_obj('./integration/cube.obj') # loop over random points and add them to the cube for ii in range(num_points): pt = np.random.uniform(0.6, 0.7) * sphere.rand(2) mesh_parameters = wavefront.polyhedron_parameters(nv, nf) D, P, V, E, F, primitive = wavefront.distance_to_mesh( pt, nv, nf, mesh_parameters) if primitive == 'vertex': nv, nf = wavefront.vertex_insertion(pt, nv, nf, D, P, V, E, F) elif primitive == 'edge': nv, nf = wavefront.edge_insertion(pt, nv, nf, D, P, V, E, F) elif primitive == 'face': nv, nf = wavefront.face_insertion(pt, nv, nf, D, P, V, E, F) mfig = graphics.mayavi_figure() mesh = graphics.mayavi_addMesh(mfig, nv, nf)
def cube_mesh_with_vertices_edges_faces(img_path): """Plot the example cube with all faces, vertices, and edges """ filename = os.path.join(img_path, 'cube_mesh.jpg') size = (800 * 1.618, 800) # read the cube v, f = wavefront.read_obj('./integration/cube.obj') # create the figure mfig = graphics.mayavi_figure(size=size, bg=(1, 1, 1)) # draw the mesh mesh = graphics.mayavi_addMesh(mfig, v, f, color=(0.5, 0.5, 0.5), representation='surface') # draw all the vertices points = graphics.mayavi_points3d(mfig, v, scale_factor=0.1, color=(0, 0, 1)) # draw the edges mesh_edges = graphics.mayavi_addMesh(mfig, v, f, color=(1, 0, 0), representation='mesh') graphics.mlab.view(azimuth=view['azimuth'], elevation=view['elevation'], distance=view['distance'], focalpoint=view['focalpoint'], figure=mfig) # save the figure to eps graphics.mlab.savefig(filename, magnification=4)