本文主要是实现从occ模块中导入step文件,并将其中各个零件的模型格式进行转换,最终实现在occ三维环境中动画展示各个零件远动状态。
第一步,在自制Pyqt5的UI中实现加载连杆机构模型。
import sys
import random
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from SelfMadeQTviewer3D import qtViewer3d # 引入自己修改后的Occ3维模型展示模块
from OCC.Extend.DataExchange import read_step_file#STEP文件导入模块
from OCC.Extend.TopologyUtils import TopologyExplorer#STEP文件导入模块后的拓扑几何分析模块
from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.canva = qtViewer3d(self)
self.solidset={}
self.initUI()
def initUI(self):
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
FourBaraction = QAction('&FourBar_Animation', self) # 连杆机构运动动作
FourBaraction.triggered.connect(self.FourBar_Ani) # 链接相关函数
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
AnimationMenu = menubar.addMenu('&Animation')
AnimationMenu.addAction(FourBaraction)
self.setGeometry(100, 50, 1600, 1000)
self.setWindowTitle('PyOcc Packed In Pyqt5')
self.setCentralWidget(self.canva)
self.show()
def STEP_shape(self):
stpshp = read_step_file('FourLinkedBar_ABAQUS.stp')# 读取step文件
return TopologyExplorer(stpshp)# step文件模型解析
def FourBar_Ani(self):
self.canva._display.EraseAll()
self.STEPshp = self.STEP_shape()
i=0
for solid in self.STEPshp.solids():
color = Quantity_Color(random.random(), random.random(),random.random(),Quantity_TOC_RGB)
self.canva._display.DisplayColoredShape(solid, color)
self.canva._display.FitAll()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
简单四连杆机构模型step文件导入之后,结果如下图所示:
实际上,代码中的变量solid是一种Topo_的CAD模型格式,该CAD模型格式不能直接在qtViewer3d中做动画展示,必须经过格式转化,转化成AIS_格式:
import sys
import time
from math import pi
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from SelfMadeQTviewer3D import qtViewer3d # 引入自己修改后的Occ3维模型展示模块
from OCC.Extend.DataExchange import read_step_file#STEP文件导入模块
from OCC.Extend.TopologyUtils import TopologyExplorer#STEP文件导入模块后的拓扑几何分析模块
from OCC.Core.AIS import AIS_Shape#模型文件转化模块
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.canva = qtViewer3d(self)
self.solidset={}
self.initUI()
def initUI(self):
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
FourBaraction = QAction('&FourBar_Animation', self) # 四连杆机构运动动作
FourBaraction.triggered.connect(self.FourBar_Ani) # 链接相关函数
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
AnimationMenu = menubar.addMenu('&Animation')
AnimationMenu.addAction(FourBaraction)
self.setGeometry(100, 50, 1600, 1000)
self.setWindowTitle('PyOcc Packed In Pyqt5')
self.setCentralWidget(self.canva)
self.show()
def STEP_shape(self):
stpshp = read_step_file('FourLinkedBar_ABAQUS.stp')# 读取step文件
return TopologyExplorer(stpshp)# step文件模型解析
def FourBar_Ani(self):
self.canva._display.EraseAll()
self.STEPshp = self.STEP_shape()#导入四连杆机构step文件
i=0
#因为各个零件在运动中的所该发生的运动状态不同,所以必须按照其特征重新索引,方便后期调用。
#实际上,在python中有更好的处理办法,这里只是简单应用。
for solid in self.STEPshp.solids():
i=i+1
if i==1:
self.Bar_450 = AIS_Shape(solid)
if i==2:
self.Bar_150 = AIS_Shape(solid)
if i==3:
self.Bar_500 = AIS_Shape(solid)
self.canva._display.Context.Display(self.Bar_450, False)#self.canva._display.Context是在三维环境中直接显示零件,这个环境只能以
self.canva._display.Context.Display(self.Bar_150, False)#AIS_Shape模型格式放入。
self.canva._display.Context.Display(self.Bar_500, False)
self.canva._display.FitAll()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
简单四连杆机构模型step文件导入并经过模型文件格式转换之后,结果如下图所示:
四连杆机构的运动形式是一种具有给定运动形式,在动画展示的过程中各个零件的运动状态是要满足一定的函数关系。要研究的连杆机构基本参数为:R1=150,R2=450,R3=500,底部固定点之间距离R0=400。本连杆机构可以解析的得到运动状态的表达式:
{ 10 cos γ = 9 cos α + 8 − 3 cos θ 10 sin γ = 9 sin α − 3 sin θ \left\{ \begin{array}{c} 10\cos\gamma = 9\cos\alpha+8-3\cos\theta \\ 10\sin\gamma = 9\sin\alpha-3\sin\theta \end{array} \right. {10cosγ=9cosα+8−3cosθ10sinγ=9sinα−3sinθ
其中的 γ \gamma γ和 α \alpha α是代求的角度值, θ ∈ [ 0 , 2 π ) \theta\in[0,2\pi) θ∈[0,2π)。
通过求解这个方程组,得到
{ α = arccos 3 cos θ − 8 73 − 48 cos θ − arccos 9 − 8 cos θ 3 73 − 48 cos θ γ = arccos 9 sin α − 3 sin θ 10 \left\{ \begin{array}{c} \alpha = \arccos\frac{3\cos\theta-8}{\sqrt{73-48\cos\theta}}-\arccos\frac{9-8\cos\theta}{3\sqrt{73-48\cos\theta}}\\ \gamma = \arccos\frac{9\sin\alpha-3\sin\theta}{10} \end{array} \right. {α=arccos73−48cosθ3cosθ−8−arccos373−48cosθ9−8cosθγ=arccos109sinα−3sinθ
import sys
import time
from math import pi
import numpy as np
import random
from OCC.Core.gp import gp_Ax1, gp_Pnt, gp_Dir, gp_Trsf, gp_Vec # 引入Occ模型几何尺寸元素模块
from OCC.Core.TopLoc import TopLoc_Location # 引入Occ模型定位模块
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox # 引入Occ模型绘制模块
from SelfMadeQTviewer3D import qtViewer3d # 引入自己修改后的Occ3维模型展示模块
from OCC.Extend.DataExchange import read_step_file#STEP文件导入模块
from OCC.Extend.TopologyUtils import TopologyExplorer#STEP文件导入模块后的拓扑几何分析模块
from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB
from OCC.Core.GProp import GProp_GProps#几何模型属性
from OCC.Core.BRepGProp import brepgprop_VolumeProperties#solid几何模型属性
from OCC.Core.TopLoc import TopLoc_Location#重新定位函数
from OCC.Core.AIS import AIS_Shape
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.canva = qtViewer3d(self)
self.solidset={}
step = 0.005
startP=0.5*np.pi
EndP=2*np.pi+0.5*np.pi
self.theta2Ani=np.linspace(startP, EndP, int((EndP-startP)/step), endpoint=True)#构造theta等差数列
#
self.alpha2Ani=self.AlphaTracef(self.theta2Ani)#构造相对于theta的时序alpha
self.gamma2Ani=self.GammaTracef(self.alpha2Ani,self.theta2Ani)#构造相对于theta的时序gamma
self.XX2Ani=self.XTracef(self.theta2Ani,self.alpha2Ani)#构造相对于theta的时序X
self.YY2Ani=self.YTracef(self.theta2Ani,self.alpha2Ani)#构造相对于theta的时序Y
self.ax1 = gp_Ax1(gp_Pnt(400., 0., 0.), gp_Dir(0., 0., 1.))
self.ax2 = gp_Ax1(gp_Pnt(0., 0., 0.), gp_Dir(0., 0., 1.))
self.B1_trsf = gp_Trsf()
self.B2_trsf = gp_Trsf()
self.B3_trsf1 = gp_Trsf()
self.B3_trsf2 = gp_Trsf()
self.initUI()
def initUI(self):
exitAct = QAction('&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
FourBaraction = QAction('&FourBar_Animation', self) # 四连杆机构运动动作
FourBaraction.triggered.connect(self.FourBar_Ani) # 链接相关函数
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
AnimationMenu = menubar.addMenu('&Animation')
AnimationMenu.addAction(FourBaraction)
self.setGeometry(300, 50, 1600, 1000)
self.setWindowTitle('PyOcc Packed In Pyqt5')
self.setCentralWidget(self.canva)
self.show()
def STEP_shape(self):
stpshp = read_step_file('FourLinkedBar_ABAQUS.stp')# 读取step文件
return TopologyExplorer(stpshp)# step文件模型解析
def FourBar_Ani(self):
self.canva._display.EraseAll()
self.STEPshp = self.STEP_shape()
i=0
for solid in self.STEPshp.solids():
i=i+1
# after_Shape=AIS_Shape(solid)
if i==1:
self.Bar_450 = AIS_Shape(solid)
if i==2:
self.Bar_150 = AIS_Shape(solid)
if i==3:
self.Bar_500 = AIS_Shape(solid)
self.canva._display.Context.Display(self.Bar_450, False)
self.canva._display.Context.Display(self.Bar_150, False)
self.canva._display.Context.Display(self.Bar_500, False)
self.canva._display.FitAll()
for j in range(len(self.theta2Ani)):
# 曲柄运动轨迹
self.B1_trsf.SetRotation(self.ax1, self.alpha2Ani[j]-self.alpha2Ani[0])
loc1 = TopLoc_Location(self.B1_trsf)
self.canva._display.Context.SetLocation(self.Bar_450, loc1)
# 摇杆运动轨迹
self.B2_trsf.SetRotation(self.ax2, self.theta2Ani[j]-self.theta2Ani[0])
loc2 = TopLoc_Location(self.B2_trsf)
self.canva._display.Context.SetLocation(self.Bar_150, loc2)
#连杆运动轨迹
self.ax3 = gp_Ax1(gp_Pnt(self.XX2Ani[j], self.YY2Ani[j], 0), gp_Dir(0., 0., 1.))
self.B3_trsf1.SetRotation(self.ax3,self.gamma2Ani[j]-self.gamma2Ani[0])
self.B3_trsf2.SetTranslation(gp_Vec(self.XX2Ani[j]-self.XX2Ani[0],self.YY2Ani[j]-self.YY2Ani[0],0))
loc3 = TopLoc_Location(self.B3_trsf1*self.B3_trsf2)
self.canva._display.Context.SetLocation(self.Bar_500, loc3)
self.canva._display.Context.UpdateCurrentViewer()
def AlphaTracef(self,x):# 摇杆轨迹运动测试函数
return np.where(x/(2*np.pi)-np.trunc(x/(2*np.pi))<=0.5,
np.arccos((3*np.cos(x)-8)/(np.sqrt(73-48*np.cos(x))))-np.arccos((9-8*np.cos(x))/(3*np.sqrt(73-48*np.cos(x)))),
2*np.pi-np.arccos((3*np.cos(x)-8)/(np.sqrt(73-48*np.cos(x))))-np.arccos((9-8*np.cos(x))/(3*np.sqrt(73-48*np.cos(x))))
)
def GammaTracef(self,data_alpha,x):# 连杆轨迹运动测试函数
return np.arccos(0.1*(9*np.cos(data_alpha)+8-3*np.cos(x)))
def XTracef(self,data_theta,data_alpha):# 连杆轨迹运动测试函数
return 0.5*(150*np.cos(data_theta)+400+450*np.cos(data_alpha))
def YTracef(self,data_theta,data_alpha):# 连杆轨迹运动测试函数
return 0.5*(150*np.sin(data_theta)+450*np.sin(data_alpha))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
这是一种暂时妥协的方法。由于类似于Solidworks这样的3维软件可以做到定义约束和连接关系之后,可以直接鼠标拖动控制连杆机构运动。还是要继续深入学习occ中的ais连接函数的应用。