def sphere_into_ellipsoid(img_path): """See if we can turn a sphere into an ellipse by changing the radius of vertices The point cloud (ellipse) should have more points than the initial mesh. When the intial mesh is coarse the resulting mesh will also be heavily faceted, but this will avoid the big holes, and large changes in depth """ # define the sphere vs, fs = wavefront.ellipsoid_mesh(1, 1, 1, density=20, subdivisions=1) ve, fe = wavefront.ellipsoid_mesh(2, 3, 4, density=20, subdivisions=1) mfig = graphics.mayavi_figure(offscreen=True) mesh = graphics.mayavi_addMesh(mfig, vs, fs) ms = mesh.mlab_source index = 0 # in a loop add each vertex of the ellipse into the sphere mesh for jj in range(2): for ii, pt in enumerate(ve): index += 1 filename = os.path.join( img_path, 'sphere_ellipsoid_' + str(index).zfill(6) + '.jpg') graphics.mlab.savefig(filename, magnification=4) mesh_param = wavefront.polyhedron_parameters(vs, fs) vs, fs = wavefront.radius_mesh_incremental_update( pt, vs, fs, mesh_param, max_angle=np.deg2rad(10)) ms.reset(x=vs[:, 0], y=vs[:, 1], z=vs[:, 2], triangles=fs) graphics.mayavi_addPoint(mfig, pt) vs, fs = wavefront.mesh_subdivide(vs, fs, 1) ms.reset(x=vs[:, 0], y=vs[:, 1], z=vs[:, 2], triangles=fs) return 0
def test_radius_sphere_into_ellipse(): """See if we can turn a sphere into an ellipse by changing the radius of vertices The point cloud (ellipse) should have more points than the initial mesh. When the intial mesh is coarse the resulting mesh will also be heavily faceted, but this will avoid the big holes, and large changes in depth """ # define the sphere vs, fs = wavefront.ellipsoid_mesh(1, 1, 1, density=10, subdivisions=0) ve, fe = wavefront.ellipsoid_mesh(2, 3, 4, density=10, subdivisions=2) mfig = graphics.mayavi_figure() mesh = graphics.mayavi_addMesh(mfig, vs, fs) ms = mesh.mlab_source # in a loop add each vertex of the ellipse into the sphere mesh for pt in ve: vs, fs = wavefront.radius_mesh_incremental_update(pt, vs, fs) ms.reset(x=vs[:, 0], y=vs[:, 1], z=vs[:, 2], triangles=fs) input('Enter for mesh subdivision') vs, fs = wavefront.mesh_subdivide(vs, fs, 1) ms.reset(x=vs[:, 0], y=vs[:, 1], z=vs[:, 2], triangles=fs) input('Enter for second round of updating') ve, fe = wavefront.ellipsoid_mesh(2, 3, 4, density=20, subdivisions=2) for pt in ve: vs, fs = wavefront.radius_mesh_incremental_update(pt, vs, fs) ms.reset(x=vs[:, 0], y=vs[:, 1], z=vs[:, 2], triangles=fs) return vs, fs
def cube_into_sphere(img_path): """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(offscreen=True) mesh = graphics.mayavi_addMesh(mfig, vc, fc) ms = mesh.mlab_source index = 0 for ii in range(5): for jj, pt in enumerate(vs): index += 1 filename = os.path.join( img_path, 'cube_sphere_' + str(index).zfill(6) + '.jpg') graphics.mlab.savefig(filename, magnification=4) mesh_param = wavefront.polyhedron_parameters(vc, fc) vc, fc = wavefront.radius_mesh_incremental_update( pt, vc, fc, mesh_param, max_angle=np.deg2rad(5)) ms.reset(x=vc[:, 0], y=vc[:, 1], z=vc[:, 2], triangles=fc) graphics.mayavi_addPoint(mfig, pt) vc, fc = wavefront.mesh_subdivide(vc, fc, 1) ms.reset(x=vc[:, 0], y=vc[:, 1], z=vc[:, 2], triangles=fc) return 0
class TestSubdivision(): v, f = wavefront.ellipsoid_mesh(1, 2, 3, density=20, subdivisions=1) poly_ellip = wavefront.meshtopolydata(v, f) def test_polydata_subdivision_loop(self): poly_out = wavefront.polydata_subdivide(self.poly_ellip, 1, 'loop') v, f = wavefront.polydatatomesh(poly_out) np.testing.assert_allclose(v.shape[0], 1146) np.testing.assert_allclose(f.shape[0], self.f.shape[0] * 4) def test_polydata_subdivision_butterfly(self): poly_out = wavefront.polydata_subdivide(self.poly_ellip, 1, 'butterfly') v, f = wavefront.polydatatomesh(poly_out) np.testing.assert_allclose(v.shape[0], 1146) np.testing.assert_allclose(f.shape[0], self.f.shape[0] * 4) def test_mesh_subdivision_loop(self): v, f = wavefront.mesh_subdivide(self.v, self.f, 1, 'loop') np.testing.assert_allclose(v.shape[0], 1146) np.testing.assert_allclose(f.shape[0], self.f.shape[0] * 4) def test_mesh_subdivision_butterfly(self): v, f = wavefront.mesh_subdivide(self.v, self.f, 1, 'butterfly') np.testing.assert_allclose(v.shape[0], 1146) np.testing.assert_allclose(f.shape[0], self.f.shape[0] * 4)
class TestCartesianAndSphericalTransformation(): v, f = wavefront.ellipsoid_mesh(1, 2, 3) spherical = wavefront.cartesian2spherical(v) verts_transformed = wavefront.spherical2cartesian(spherical) def test_transformation_equal(self): np.testing.assert_array_almost_equal(self.v, self.verts_transformed, decimal=3) def test_single_vector_cartesian2spherical(self): spherical = wavefront.cartesian2spherical(np.array([1, 0, 0])) np.testing.assert_allclose(spherical, (1, 0, 0)) def test_single_vector_spherical2cartesian(self): cartesian = wavefront.spherical2cartesian(np.array([1, 0, 0])) np.testing.assert_allclose(cartesian, (1, 0, 0))
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 vtk_mesh_subdivision(): """Subdivide a mesh into more triangles The subdivisions are increasing the faces by 4^# subdivisions """ # get the polydata for a mesh v, f = wavefront.ellipsoid_mesh(1, 2, 3, density=20) polydata = wavefront.meshtopolydata(v, f) # subdivide using appropriate filter smooth_loop = vtk.vtkLoopSubdivisionFilter() smooth_loop.SetNumberOfSubdivisions(1) # can define the number of subdivisions smooth_loop.SetInputData(polydata) smooth_loop.Update() poly_loop = vtk.vtkPolyData() poly_loop.ShallowCopy(smooth_loop.GetOutput()) smooth_butterfly = vtk.vtkButterflySubdivisionFilter() smooth_butterfly.SetNumberOfSubdivisions(3) smooth_butterfly.SetInputData(polydata) smooth_butterfly.Update() poly_butterfly = vtk.vtkPolyData() poly_butterfly.ShallowCopy(smooth_butterfly.GetOutput()) # Create a mapper and actor for initial dataset mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(polydata) actor = vtk.vtkActor() actor.SetMapper(mapper) # Create a mapper and actor for smoothed dataset (vtkLoopSubdivisionFilter) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(smooth_loop.GetOutputPort()) actor_loop = vtk.vtkActor() actor_loop.SetMapper(mapper) actor_loop.SetPosition(3, 0, 0) # Create a mapper and actor for smoothed dataset (vtkButterflySubdivisionFilter) mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(smooth_butterfly.GetOutputPort()) actor_butterfly = vtk.vtkActor() actor_butterfly.SetMapper(mapper) actor_butterfly.SetPosition(6, 0, 0) # Visualise renderer = vtk.vtkRenderer() renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(renderer) renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) # Add actors and render renderer.AddActor(actor) renderer.AddActor(actor_loop) renderer.AddActor(actor_butterfly) renderer.SetBackground(1, 1, 1) # Background color white renderWindow.SetSize(800, 800) renderWindow.Render() renderWindowInteractor.Start() # output to a new v, f array # convert polydata to numpy v_loop, f_loop = wavefront.polydatatomesh(poly_loop) v_butterfly, f_butterfly = wavefront.polydatatomesh(poly_butterfly) print('Original #V : {} #F : {}'.format(v.shape[0], f.shape[0])) print('Loop #V : {} #F : {}'.format(v_loop.shape[0], f_loop.shape[0])) print('BFly #V : {} #F : {}'.format(v_butterfly.shape[0], f_butterfly.shape[0]))