PythonOcc实战——step文件导入、格式转换、动画展示

本文主要是实现从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文件导入之后,结果如下图所示:

PythonOcc实战——step文件导入、格式转换、动画展示_第1张图片

实际上,代码中的变量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文件导入并经过模型文件格式转换之后,结果如下图所示:

PythonOcc实战——step文件导入、格式转换、动画展示_第2张图片

四连杆机构的运动形式是一种具有给定运动形式,在动画展示的过程中各个零件的运动状态是要满足一定的函数关系。要研究的连杆机构基本参数为: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α+83cosθ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. {α=arccos7348cosθ 3cosθ8arccos37348cosθ 98cosθγ=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_())

PythonOcc实战——step文件导入、格式转换、动画展示_第3张图片

这是一种暂时妥协的方法。由于类似于Solidworks这样的3维软件可以做到定义约束和连接关系之后,可以直接鼠标拖动控制连杆机构运动。还是要继续深入学习occ中的ais连接函数的应用。

你可能感兴趣的:(PythonOcc,python,cad,animation)