Package: pyminiply
pyminiplyis a Python library for rapidly reading PLY files. It is a
Python wrapper around the fast C++ PLY reading library provided byminiply. Thanks @vilya!The main advantage ofpyminiplyover other PLY reading libraries is
its performance. See the benchmarks below for more details.InstallationThe recommended way to installpyminiplyis via PyPI:pipinstallpyminiplyYou can also clone the repository and install it from source:gitclonehttps://github.com/pyvista/pyminiply.gitcdpyminiplygitsubmoduleupdate--init--recursivepipinstall.UsageLoad in the vertices, indices, normals, UV, and color information from a
PLY file:>>>importpyminiply>>>vertices,indices,normals,uv,color=pyminiply.read("example.ply")>>>verticesarray([[ 5.0000000e-01, -5.0000000e-01, -5.5511151e-17],
       [ 4.0000001e-01, -5.0000000e-01, -4.4408922e-17],
       [ 3.0000001e-01, -5.0000000e-01, -3.3306692e-17],
       ...,
       [-4.2500001e-01,  5.0000000e-01,  4.7184480e-17],
       [-4.7499999e-01,  4.4999999e-01,  5.2735593e-17],
       [-5.0000000e-01,  4.2500001e-01,  5.5511151e-17]], dtype=float32)>>>indicesarray([[   0,  442,  441],
       [ 442,  122,  443],
       [ 443,  121,  441],
       ...,
       [1677,  438, 1679],
       [1679,  439, 1676],
       [1677, 1679, 1676]], dtype=int32)>>>normalsarray([[-1.110223e-16,  0.000000e+00, -1.000000e+00],
       [-1.110223e-16,  0.000000e+00, -1.000000e+00],
       [-1.110223e-16,  0.000000e+00, -1.000000e+00],
       ...,
       [-1.110223e-16,  0.000000e+00, -1.000000e+00],
       [-1.110223e-16,  0.000000e+00, -1.000000e+00],
       [-1.110223e-16,  0.000000e+00, -1.000000e+00]], dtype=float32)>>>uvarray([[0.        , 0.        ],
       [0.1       , 0.        ],
       [0.2       , 0.        ],
       ...,
       [0.92499995, 1.        ],
       [0.975     , 0.95      ],
       [1.        , 0.92499995]], dtype=float32)>>>colorarray([[  0,   0,   0],
       [  0,   0,   0],
       [  0,   0,   0],
       ...,
       [254, 254, 254],
       [254, 254, 254],
       [255, 255, 255]], dtype=uint8)You can also read in the PLY file as aPyVistaPolyData and immediately plot it.>>> import pyminiply
 >>> mesh = pyminiply.read_as_mesh("example.ply")
 >>> mesh
 PolyData (0x7f0653579c00)
   N Cells:    200
   N Points:   121
   N Strips:   0
   X Bounds:   -5.000e-01, 5.000e-01
   Y Bounds:   -5.000e-01, 5.000e-01
   Z Bounds:   -5.551e-17, 5.551e-17
   N Arrays:   2>>>mesh.plot()BenchmarkThe main reason behind writing yet another PLY file reader for Python is
to leverage the highly performantminiplylibrary.There is already an benchmark demonstrating howminiplyoutperforms
in comparison to competing C and C++ libraries atply_io_benchmarkwhen reading PLY files.
The benchmark here shows howpyminiplyperforms relative to other
Python PLY file readers.Here are the timings from reading in a 1,000,000 point binary PLY file:LibraryTime (seconds)pyminiply0.046open3d0.149PyVista
(VTK)0.409meshio0.512plyfile8.939Benchmark source:importtimeimportnumpyasnpimportpyvistaaspvimportpyminiplyimportplyfileimportmeshioimportopen3dfilename='tmp.ply'mesh=pv.Plane(i_resolution=999,j_resolution=999).triangulate()mesh.clear_data()mesh.save(filename)# pyminiplytstart=time.time()pyminiply.read(filename)tend=time.time()-tstart;print(f'pyminiply:{tend:.3f}')# open3dtstart=time.time()open3d.io.read_point_cloud(filename)tend=time.time()-tstart;print(f'open3d:{tend:.3f}')# VTK/PyVistatstart=time.time()pv.read(filename)tend=time.time()-tstart;print(f'VTK/PyVista:{tend:.3f}')tstart=time.time()meshio.read(filename)tend=time.time()-tstart;print(f'meshio:{tend:.3f}')# plyfiletstart=time.time()plyfile.PlyData.read(filename)tend=time.time()-tstart;print(f'plyfile:{tend:.3f}')Comparison with VTK and PyVistaHere’s an additional benchmark comparing VTK/PyVista withpyminiply:importnumpyasnpimporttimeimportpyvistaaspvimportmatplotlib.pyplotaspltimportpyminiplytimes=[]filename='tmp.ply'forresinrange(50,800,50):mesh=pv.Plane(i_resolution=res,j_resolution=res).triangulate().subdivide(2)mesh.clear_data()mesh.save(filename)tstart=time.time()pv_mesh=pv.read(filename)vtk_time=time.time()-tstarttstart=time.time()ply_mesh=pyminiply.read_as_mesh(filename)ply_reader_time=time.time()-tstartassertnp.allclose(pv_mesh['Normals'],ply_mesh['Normals'])assertnp.allclose(pv_mesh.points,ply_mesh.points)assertnp.allclose(pv_mesh._connectivity_array,ply_mesh._connectivity_array)times.append([mesh.n_points,vtk_time,ply_reader_time])print(times[-1])times=np.array(times)plt.figure(1)plt.title('PLY load time')plt.plot(times[:,0],times[:,1],label='VTK')plt.plot(times[:,0],times[:,2],label='pyminiply')plt.xlabel('Number of Points')plt.ylabel('Time to Load (seconds)')plt.legend()plt.figure(2)plt.title('PLY load time (Log-Log)')plt.loglog(times[:,0],times[:,1],label='VTK')plt.loglog(times[:,0],times[:,2],label='pyminiply')plt.xlabel('Number of Points')plt.ylabel('Time to Load (seconds)')plt.legend()plt.show()License and AcknowledgmentsThis project relies onminiplyand credit goes to the original
author for the excellent C++ library. That work is licensed under the
MIT License.The work in this repository is also licensed under the MIT License.SupportIf you are having issues, please feel free to raise anIssue.