图书馆可以轻松阅读、编写和修改二进制和ASCII STL文件。

numpy-stl的Python项目详细描述


numpy-stl test statusnumpy-stl Pypi versionnumpy-stl code coveragehttps://img.shields.io/pypi/pyversions/mt-940.svg

使处理stl文件(和一般的3d对象)快速的简单库 而且很简单。

由于所有的操作都严重依赖于numpy,这是最快的 提供了用于python的stl编辑库。

安装要求:

安装:

pip安装numpy stl

初始用法:

  • stl2bin your_ascii_stl_file.stl new_binary_stl_file.stl
  • stl2ascii your_binary_stl_file.stl new_ascii_stl_file.stl
  • stl your_ascii_stl_file.stl new_binary_stl_file.stl

贡献:

捐款总是受欢迎的。请查看指南开始: https://github.com/WoLpH/numpy-stl/blob/develop/CONTRIBUTING.rst

快速启动

importnumpyfromstlimportmesh# Using an existing stl file:your_mesh=mesh.Mesh.from_file('some_file.stl')# Or creating a new mesh (make sure not to overwrite the `mesh` import by# naming it `mesh`):VERTICE_COUNT=100data=numpy.zeros(VERTICE_COUNT,dtype=mesh.Mesh.dtype)your_mesh=mesh.Mesh(data,remove_empty_areas=False)# The mesh normals (calculated automatically)your_mesh.normals# The mesh vectorsyour_mesh.v0,your_mesh.v1,your_mesh.v2# Accessing individual points (concatenation of v0, v1 and v2 in triplets)assert(your_mesh.points[0][0:3]==your_mesh.v0[0]).all()assert(your_mesh.points[0][3:6]==your_mesh.v1[0]).all()assert(your_mesh.points[0][6:9]==your_mesh.v2[0]).all()assert(your_mesh.points[1][0:3]==your_mesh.v0[1]).all()your_mesh.save('new_stl_file.stl')

使用matplotlib绘图同样简单:

fromstlimportmeshfrommpl_toolkitsimportmplot3dfrommatplotlibimportpyplot# Create a new plotfigure=pyplot.figure()axes=mplot3d.Axes3D(figure)# Load the STL files and add the vectors to the plotyour_mesh=mesh.Mesh.from_file('tests/stl_binary/HalfDonut.stl')axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))# Auto scale to the mesh sizescale=your_mesh.points.flatten(-1)axes.auto_scale_xyz(scale,scale,scale)# Show the plot to the screenpyplot.show()

修改网格对象

fromstlimportmeshimportmathimportnumpy# Create 3 faces of a cubedata=numpy.zeros(6,dtype=mesh.Mesh.dtype)# Top of the cubedata['vectors'][0]=numpy.array([[0,1,1],[1,0,1],[0,0,1]])data['vectors'][1]=numpy.array([[1,0,1],[0,1,1],[1,1,1]])# Front facedata['vectors'][2]=numpy.array([[1,0,0],[1,0,1],[1,1,0]])data['vectors'][3]=numpy.array([[1,1,1],[1,0,1],[1,1,0]])# Left facedata['vectors'][4]=numpy.array([[0,0,0],[1,0,0],[1,0,1]])data['vectors'][5]=numpy.array([[0,0,0],[0,0,1],[1,0,1]])# Since the cube faces are from 0 to 1 we can move it to the middle by# substracting .5data['vectors']-=.5# Generate 4 different meshes so we can rotate them latermeshes=[mesh.Mesh(data.copy())for_inrange(4)]# Rotate 90 degrees over the Y axismeshes[0].rotate([0.0,0.5,0.0],math.radians(90))# Translate 2 points over the X axismeshes[1].x+=2# Rotate 90 degrees over the X axismeshes[2].rotate([0.5,0.0,0.0],math.radians(90))# Translate 2 points over the X and Y pointsmeshes[2].x+=2meshes[2].y+=2# Rotate 90 degrees over the X and Y axismeshes[3].rotate([0.5,0.0,0.0],math.radians(90))meshes[3].rotate([0.0,0.5,0.0],math.radians(90))# Translate 2 points over the Y axismeshes[3].y+=2# Optionally render the rotated cube facesfrommatplotlibimportpyplotfrommpl_toolkitsimportmplot3d# Create a new plotfigure=pyplot.figure()axes=mplot3d.Axes3D(figure)# Render the cube facesforminmeshes:axes.add_collection3d(mplot3d.art3d.Poly3DCollection(m.vectors))# Auto scale to the mesh sizescale=numpy.concatenate([m.pointsforminmeshes]).flatten(-1)axes.auto_scale_xyz(scale,scale,scale)# Show the plot to the screenpyplot.show()

扩展网格对象

fromstlimportmeshimportmathimportnumpy# Create 3 faces of a cubedata=numpy.zeros(6,dtype=mesh.Mesh.dtype)# Top of the cubedata['vectors'][0]=numpy.array([[0,1,1],[1,0,1],[0,0,1]])data['vectors'][1]=numpy.array([[1,0,1],[0,1,1],[1,1,1]])# Front facedata['vectors'][2]=numpy.array([[1,0,0],[1,0,1],[1,1,0]])data['vectors'][3]=numpy.array([[1,1,1],[1,0,1],[1,1,0]])# Left facedata['vectors'][4]=numpy.array([[0,0,0],[1,0,0],[1,0,1]])data['vectors'][5]=numpy.array([[0,0,0],[0,0,1],[1,0,1]])# Since the cube faces are from 0 to 1 we can move it to the middle by# substracting .5data['vectors']-=.5cube_back=mesh.Mesh(data.copy())cube_front=mesh.Mesh(data.copy())# Rotate 90 degrees over the X axis followed by the Y axis followed by the# X axiscube_back.rotate([0.5,0.0,0.0],math.radians(90))cube_back.rotate([0.0,0.5,0.0],math.radians(90))cube_back.rotate([0.5,0.0,0.0],math.radians(90))cube=mesh.Mesh(numpy.concatenate([cube_back.data.copy(),cube_front.data.copy(),]))# Optionally render the rotated cube facesfrommatplotlibimportpyplotfrommpl_toolkitsimportmplot3d# Create a new plotfigure=pyplot.figure()axes=mplot3d.Axes3D(figure)# Render the cubeaxes.add_collection3d(mplot3d.art3d.Poly3DCollection(cube.vectors))# Auto scale to the mesh sizescale=cube_back.points.flatten(-1)axes.auto_scale_xyz(scale,scale,scale)# Show the plot to the screenpyplot.show()

从顶点和面列表创建网格对象

importnumpyasnpfromstlimportmesh# Define the 8 vertices of the cubevertices=np.array([\
    [-1,-1,-1],[+1,-1,-1],[+1,+1,-1],[-1,+1,-1],[-1,-1,+1],[+1,-1,+1],[+1,+1,+1],[-1,+1,+1]])# Define the 12 triangles composing the cubefaces=np.array([\
    [0,3,1],[1,3,2],[0,4,7],[0,7,3],[4,5,6],[4,6,7],[5,1,2],[5,2,6],[2,3,6],[3,7,6],[0,1,5],[0,5,4]])# Create the meshcube=mesh.Mesh(np.zeros(faces.shape[0],dtype=mesh.Mesh.dtype))fori,finenumerate(faces):forjinrange(3):cube.vectors[i][j]=vertices[f[j],:]# Write the mesh to file "cube.stl"cube.save('cube.stl')

评估网格属性(体积、重心、惯性)

importnumpyasnpfromstlimportmesh# Using an existing closed stl file:your_mesh=mesh.Mesh.from_file('some_file.stl')volume,cog,inertia=your_mesh.get_mass_properties()print("Volume                                  = {0}".format(volume))print("Position of the center of gravity (COG) = {0}".format(cog))print("Inertia matrix at expressed at the COG  = {0}".format(inertia[0,:]))print("                                          {0}".format(inertia[1,:]))print("                                          {0}".format(inertia[2,:]))

组合多个STL文件

importmathimportstlfromstlimportmeshimportnumpy# find the max dimensions, so we can know the bounding box, getting the height,# width, length (because these are the step size)...deffind_mins_maxs(obj):minx=maxx=miny=maxy=minz=maxz=Noneforpinobj.points:# p contains (x, y, z)ifminxisNone:minx=p[stl.Dimension.X]maxx=p[stl.Dimension.X]miny=p[stl.Dimension.Y]maxy=p[stl.Dimension.Y]minz=p[stl.Dimension.Z]maxz=p[stl.Dimension.Z]else:maxx=max(p[stl.Dimension.X],maxx)minx=min(p[stl.Dimension.X],minx)maxy=max(p[stl.Dimension.Y],maxy)miny=min(p[stl.Dimension.Y],miny)maxz=max(p[stl.Dimension.Z],maxz)minz=min(p[stl.Dimension.Z],minz)returnminx,maxx,miny,maxy,minz,maxzdeftranslate(_solid,step,padding,multiplier,axis):if'x'==axis:items=0,3,6elif'y'==axis:items=1,4,7elif'z'==axis:items=2,5,8else:raiseRuntimeError('Unknown axis %r, expected x, y or z'%axis)# _solid.points.shape == [:, ((x, y, z), (x, y, z), (x, y, z))]_solid.points[:,items]+=(step*multiplier)+(padding*multiplier)defcopy_obj(obj,dims,num_rows,num_cols,num_layers):w,l,h=dimscopies=[]forlayerinrange(num_layers):forrowinrange(num_rows):forcolinrange(num_cols):# skip the position where original being copied isifrow==0andcol==0andlayer==0:continue_copy=mesh.Mesh(obj.data.copy())# pad the space between objects by 10% of the dimension being# translatedifcol!=0:translate(_copy,w,w/10.,col,'x')ifrow!=0:translate(_copy,l,l/10.,row,'y')iflayer!=0:translate(_copy,h,h/10.,layer,'z')copies.append(_copy)returncopies# Using an existing stl file:main_body=mesh.Mesh.from_file('ball_and_socket_simplified_-_main_body.stl')# rotate along Ymain_body.rotate([0.0,0.5,0.0],math.radians(90))minx,maxx,miny,maxy,minz,maxz=find_mins_maxs(main_body)w1=maxx-minxl1=maxy-minyh1=maxz-minzcopies=copy_obj(main_body,(w1,l1,h1),2,2,1)# I wanted to add another related STL to the final STLtwist_lock=mesh.Mesh.from_file('ball_and_socket_simplified_-_twist_lock.stl')minx,maxx,miny,maxy,minz,maxz=find_mins_maxs(twist_lock)w2=maxx-minxl2=maxy-minyh2=maxz-minztranslate(twist_lock,w1,w1/10.,3,'x')copies2=copy_obj(twist_lock,(w2,l2,h2),2,2,1)combined=mesh.Mesh(numpy.concatenate([main_body.data,twist_lock.data]+[copy.dataforcopyincopies]+[copy.dataforcopyincopies2]))combined.save('combined.stl',mode=stl.Mode.ASCII)# save as ASCII

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
无法将XML加载到属性对象Java中   java如何判断当前线程是否为事件分派线程   java如何在带有CouchbaseTemplate的Spring数据Couchbase中使用密钥前缀   java将JSON数组存储在不同的列表或数组中   java OpenCV检测最大矩形会产生令人费解的结果   java正则表达式获取选项卡式值及其频率   安卓致命异常:主java。lang.NullPointerException   java有没有一种方法可以使用CLI(命令行界面)使用junit测试用例测试我的项目的jar文件?   Java数组属性   java我应该升级到CGLIB 3.0吗?   用户界面什么Java GUI框架适合第一个GUI项目?   java如何使用tomcat、mysql和jdbc驱动程序在internet上发布我的jsp项目   java计数字符串中非重叠出现的次数   通用域名格式。太阳网httpserver Java httpserver基本身份验证问题   java Android WebView:只显示网页的一半   将json字符串转换为java中的对象列表   io使用Java在目录中查找第一个文件   if语句如何在java游戏中使用switch和case?