三维仿真对模型要求
科研、教学、工程的三维视景仿真往往使用实际产品、实际物体或建筑、管道、机械装置、车辆等复杂的三维模型展示模拟的物理运动和动力学过程。因此VPython内置的基础模型难以满足三维仿真对模型复杂度的要求。研究如何将UG、SolidWorks、CATIA、3DMax等建模软件中设计的复杂模型导入VPython中是利用VPython开发三维仿真软件的重要一步,这一步不能实现,就不能使用VPython进行三维仿真。
复杂模型导入VPython的原理
建模软件中设计的复杂模型往往由数万甚至数百万的三角片面组成模型表面,先从建模软件中将这些三角片面的顶点坐标和片面向量数据导出到文本文件或二进制数据文件中,在Python中读入文件数据,根据数据利用VPython的三角面基础模型triangle重现数据中的三角片面,注意三角片面的向量都是指向模型物体外侧,才能完成光照计算使该三角片面可见,否则该片面只能从模型内部空间看到,外部看该片面成为一个“洞”。
模型数据文件导出
在三维设计软件中设计图1所示飞机模型,以UG导出模型数据到STL文件为例讲解导出步骤:
图1
在UG中执行“文件>导出>STL”,如图2,输出类型可以选择二进制或文本,为了观察导出的数据,本例选择文本,实际使用可选择二进制减小模型文件大小。三角形公差和相邻公差不易设置太小,太小使三角形数量太多,增加模型加载时间和资源占用。本例中三角形公差和相邻公差都设置为0.5,在UG中对模型的分割见图3。导出STL的其他步骤点击“确定”按钮即可。
图2
图3
将输出的STL文件命名为plane.txt,图4中红色方框中为一个三角面,normal为三角面的方向向量,三个vertex为三角形的三个顶点,每个vertex有三个数据,为顶点的三维坐标值。
图4
模型数据导入与渲染
使用numpy-stl读取建模软件导出的STL文件中的顶点数据。
安装numpy-stl库在Anaconda命令终端中输入:
pip install numpy-stl
读入STL文件数据,画模型的代码如下,生成的模型如视频1。
# -*- coding: utf-8 -*-
import pandas as pd
from vpython import *
from stl import mesh
#从stl文件中读取数据构建模型////////////////////////////////
#file:stl文件名
#makeComp:是否构建compound,True输出compound,False输出0
#tail:是否有尾迹
#model_color:模型颜色
def FileToModel(file,makeComp=False,tail=False,model_color=vec(0.5,0.5,0.5)):
temp_mesh = mesh.Mesh.from_file(file) #STL数据读入temp_mesh
tris=[]
num=int(temp_mesh.normals.size/3) #三角面数量
for a in range(num):
aa = temp_mesh.vectors[a][0] #三角面顶点1
bb = temp_mesh.vectors[a][1] #三角面顶点2
cc = temp_mesh.vectors[a][2] #三角面顶点3
nn = temp_mesh.normals[a] #三角面方向向量
#建立三角形三个顶点,normal顶点方向向量,colord顶点颜色
a = vertex(pos=vector(aa[0], aa[1], aa[2]),normal=vector(nn[0], nn[1], nn[2]),color=model_color)
b = vertex(pos=vector(bb[0], bb[1], bb[2]),normal=vector(nn[0], nn[1], nn[2]),color=model_color)
c = vertex(pos=vector(cc[0], cc[1], cc[2]),normal=vector(nn[0], nn[1], nn[2]),color=model_color)
t=triangle(v0=a,v1=b,v2=c) #由三个顶点生成三角面
tris.append(t) #三角面数组
if makeComp==True:
tt=compound(tris,make_trail=tail) #将三角面组成组件
return tt
return 0
def main():
#测试代码,生成plane.txt对应的飞机
target=FileToModel('plane.txt',tail=False,model_color=vec(1,1,0))
if __name__ == '__main__':
main()
视频1——plane
图5
视频1中的飞机模型原点在飞机头部,原因是在UG中建模时原点设置在飞机头部,如图5。飞机的原点一般应设置在飞机质心上或气动力作用点上,大概在主翼中部。修改飞机模型原点有两种方法:
方法一:在UG中移动模型,如图6。
方法二:在建立三角面时,所有顶点增加一个偏移量,将模型质心移动到坐标系原点上,代码如下。模型原点移动后的视频见视频2。
p=vector(0,-650,0)
a = vertex(pos=vector(aa[0], aa[1], aa[2])+p,normal=vector(nn[0], nn[1], nn[2]),color=model_color)
b = vertex(pos=vector(bb[0], bb[1], bb[2])+p,normal=vector(nn[0], nn[1], nn[2]),color=model_color)
c = vertex(pos=vector(cc[0], cc[1], cc[2])+p,normal=vector(nn[0], nn[1], nn[2]),color=model_color)
视频2——plane2移动原点
结束语
以上完成了复杂模型导入VPython,并对模型原点进行了调整。
下一节介绍在场景中画坐标系的方法,有了坐标系,模型的运动有了参照,便于清晰体现模型的运动过程。