Windows系统下QT+OpenCasCAD仿真开发

2023-05-16

背景

最近开发了一个六自由度机械臂调姿平台的控制软件,集成了API激光跟踪仪和KUKA机器人,实现了根据产品的测量位姿驱动仿真环境中模型并且实现模型间的碰撞检测。
其中KUKA机器人的控制可以参考笔者以前的博客:
https://blog.csdn.net/iamqianrenzhan/article/details/103115580
关于API激光跟踪仪的基本使用方法,将会在后续博客中介绍。本文主要是关于OpenCasCAD的使用,以及在qt中的配置。

OpenCasCAD简介

Open CASCADE(简称OCC)平台是由法国Matra Datavision公司开发的CAD/CAE/CAM软件平台。开源OCC对象库是一个面向对象C++类库,用于快速开发设计领域的专业应用程序。
OCC主要用于开发二维和三维几何建模应用程序,包括通用的或专业的计算机辅助设计CAD系统、制造或分析领域的应用程序、仿真应用程序或图形演示工具。OCC通过有机组织的C++库文件提供了六个模块。可视化模块作为OCC的核心部分,是可视化技术的具体体现。

OpenCasCAD的安装与自行编译

官网提供:可以在OpenCasCAD网站下载最新版
https://www.opencascade.com/content/latest-release
如果官网下载太慢,可以下载笔者上传的版本。
https://download.csdn.net/download/iamqianrenzhan/11982847
这个是安装版本,下载后可以直接使用。因为该安装版本也包含源码,也可以自行编译。自行编译参考笔者以前的博客:
https://blog.csdn.net/iamqianrenzhan/article/details/79558781
或者直接参考官网
https://www.opencascade.com/doc/occt-7.4.0/overview/html/occt_dev_guides__building_msvc.html
如果要用qt进行开发,最好在编译时把qt的版本修改为自己所用的版本。

Qt工程的建立

Qt工程主要参考了github上一个工程:
https://github.com/eryar/occQt

在pro文件中

QT       +=  opengl

INCLUDEPATH += C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc

LIBS += -LC:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\win64\vc14\lib

DEFINES += WNT

LIBS += -lTKernel -lTKMath -lTKV3d -lTKOpenGl \
        -lTKBRep -lTKIGES -lTKSTL -lTKVRML -lTKSTEP -lTKSTEPAttr -lTKSTEP209 \
        -lTKSTEPBase -lTKGeomBase -lTKGeomAlgo -lTKG3d -lTKG2d \
        -lTKXSBase -lTKShHealing -lTKHLR -lTKTopAlgo -lTKMesh -lTKPrim \
        -lTKCDF -lTKBool -lTKBO -lTKFillet -lTKOffset -lTKLCAF -lTKService

模型导入

新建一个管理模型导入导出的类:

class Standard_EXPORT ImportExport
{
public:
    ImportExport();

public :
    static void ReadIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext,
                         Handle(AIS_Shape)& aShape);
    static void ReadSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext,
                         Handle(AIS_Shape)& aShape);
};

目前这个类中只有两种格式模式的导入,后续会增加多种格式的导入和导出。

Stp文件导入

回传aShape参数是为了分别对导入的模型进行颜色设置,删除,移动等操作。

void ImportExport::ReadSTEP(const Handle(AIS_InteractiveContext)& anInteractiveContext,
                            Handle(AIS_Shape)& aShape)
{
    //Handle(TopTools_HSequenceOfShape) aSequence = ImportExport::ReadSTEP();
    Handle(TopTools_HSequenceOfShape) aSequence= new TopTools_HSequenceOfShape();

    QString fileName = QFileDialog::getOpenFileName(nullptr,
                                                    QObject::tr("read a stp file"),
                                                    "E:",
                                                    QObject::tr("STEP Files(*.stp *.step)"));
    qDebug() << fileName;
    if(fileName.isNull())
    {
        qDebug() << "没有选择文件";
        std::cout << "没有选择文件" <<std::endl;
        return;
    }
    std::string test = fileName.toStdString();  //必须要把toStdString和data函数分开写。
    Standard_CString aFileName = test.data();

    //IFSelect_ReturnStatus ReturnStatus = ReadSTEP(aFileName,aSequence);
    aSequence->Clear();

    // create additional log file
    STEPControl_Reader aReader;
    IFSelect_ReturnStatus status = aReader.ReadFile(aFileName);
    if(status !=IFSelect_RetDone)
    {
        switch (status)
        {
        case IFSelect_RetError:
            std::cout << "Not a valid Step file" << std::endl;
            break;
        case IFSelect_RetFail :
            std::cout << "Reading has failed" << std::endl;
            break;
        case IFSelect_RetVoid :
            std::cout << "Nothing to transfer" << std::endl;
            break;
        default:
            break;
        }
        return;
    }

    aReader.WS()->MapReader()->SetTraceLevel(2); // increase default trace level

    Standard_Boolean failsonly = Standard_False;
    aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);

    // Root transfers
    Standard_Integer nbr = aReader.NbRootsForTransfer();
    aReader.PrintCheckTransfer (failsonly, IFSelect_ItemsByEntity);
    for ( Standard_Integer n = 1; n<=nbr; n++)
    {
        Standard_Boolean ok = aReader.TransferRoot(n);
    }

    // Collecting resulting entities
    Standard_Integer nbs = aReader.NbShapes();
    if (nbs == 0) return;

    for (Standard_Integer i=1; i<=nbs; i++)
        aSequence->Append(aReader.Shape(i));

    //Handle_AIS_Shape aShape;

    if (!aSequence.IsNull())
    {
        for(int i=1;i<= aSequence->Length();i++)
        {
            aShape = new AIS_Shape(aSequence->Value(i));

            anInteractiveContext->SetColor(aShape,Quantity_NOC_YELLOW,Standard_False);
            anInteractiveContext->SetMaterial(aShape,Graphic3d_NOM_PLASTIC,Standard_False);
            anInteractiveContext->SetDisplayMode(aShape,1,Standard_False);
            //anInteractiveContext->SetTransparency(aShape,0.2,Standard_False);
            anInteractiveContext->Display(aShape, Standard_False);
        }
    }
}

Igs文件导入

void ImportExport::ReadIGES(const Handle(AIS_InteractiveContext)& anInteractiveContext,
                            Handle(AIS_Shape)& aShape)
{
    //Handle(TopTools_HSequenceOfShape) aSequence = ImportExport::ReadIGES();
    Handle(TopTools_HSequenceOfShape) aSequence = new TopTools_HSequenceOfShape();

    QString fileName = QFileDialog::getOpenFileName(nullptr,
                                                    QObject::tr("read a igs file"),
                                                    "E:",
                                                    QObject::tr("IGES Files(*.iges *.igs)"));
    if(fileName.isNull())
    {
        qDebug() << "没有选择文件";
        std::cout << "没有选择文件" << std::endl;
        return;
    }
    qDebug() << fileName;
    std::string test = fileName.toStdString();  //必须要把toStdString和data函数分开写。
    Standard_CString aFileName = test.data();

    //Standard_Integer status = ReadIGES(aFileName,aSequence);
    IGESControl_Reader Reader;
    Standard_Integer status = Reader.ReadFile(aFileName);

    if (status != IFSelect_RetDone)
    {
        std::cout << "Error : The file is not read" << std::endl;
        qDebug() << "Error : The file is not read";
        return;
    }
    Reader.TransferRoots();
    TopoDS_Shape tShape = Reader.OneShape();
    aSequence->Append(tShape);

    //Handle_AIS_Shape aShape;

    if (!aSequence.IsNull())
    {
        for(int i=1;i<= aSequence->Length();i++)
        {
            aShape = new AIS_Shape(aSequence->Value(i));
            anInteractiveContext->SetColor(aShape,Quantity_NOC_YELLOW,Standard_False);
            anInteractiveContext->SetMaterial(aShape,Graphic3d_NOM_PLASTIC,Standard_False);
            anInteractiveContext->SetDisplayMode(aShape,1,Standard_False);
            //anInteractiveContext->SetTransparency(aShape,0.2,Standard_False);
            anInteractiveContext->Display(aShape, Standard_False);
        }
    }
}

位姿驱动

这里提供两种方法,一种是提供12个参数的其次RT矩阵,一个是提供6个参数的ABCXYZ参数。

void OccView::SetModelLocation(Handle(AIS_Shape)& aShape,gp_Trsf trsf)
{
    Handle_AIS_InteractiveObject Current(aShape);
    if(!Current.IsNull())
    {
        myContext->SetLocation(Current,trsf);
        myContext->Update(Current,Standard_True);  //等价于这句话 myContext->UpdateCurrentViewer();//窗口更新
    }
}

//设置当前对象的位置
void OccView::OccView::SetModelLocation_Matrix(Handle(AIS_Shape)& aShape, double* matrixTemp)
{
    gp_Trsf trsf;
    trsf.SetValues(matrixTemp[0],matrixTemp[1],matrixTemp[2], matrixTemp[3],
            matrixTemp[4],matrixTemp[5],matrixTemp[6], matrixTemp[7],
            matrixTemp[8],matrixTemp[9],matrixTemp[10],matrixTemp[11]);

    SetModelLocation(aShape,trsf);
}

//通过YPR角度设置当前对象的位置
void OccView::SetModelLocation_Euler(Handle(AIS_Shape)& aShape, double* pTemp)
{
    pTemp[0] = pTemp[0]/180*M_PI;
    pTemp[1] = pTemp[1]/180*M_PI;
    pTemp[2] = pTemp[2]/180*M_PI;

    //设置欧拉角
    gp_Trsf aTrsf_Rotation;
    gp_Quaternion aQ;
    aQ.SetEulerAngles(gp_YawPitchRoll,pTemp[0],pTemp[1],pTemp[2]);
    aTrsf_Rotation.SetRotation(aQ);
    
    //设置平移向量
    gp_Trsf aTrsf_Translation;
    gp_Vec theVectorOfTrans(pTemp[3],pTemp[4],pTemp[5]);
    aTrsf_Translation.SetTranslation(theVectorOfTrans);
    gp_Trsf trsf = aTrsf_Translation * aTrsf_Rotation;

    SetModelLocation(aShape,trsf);
}

碰撞检测

这里碰撞检测使用bool交操作,对两个模型进行bool交操作,根据交集结果进行是否碰撞判断。

bool OccView::IsCommon()
{
    //从AIS类型获得TOPO类型
    if(m_AISTargetBody.IsNull() || m_AISMoveBody.IsNull())
    {
        qDebug() << "no model imported";
        return false;
    }

    m_TppoTargetBody = m_AISTargetBody->Shape();
    m_TopoMoveBody = m_AISMoveBody->Shape();

    //没有实时性要求,采用bool求交的方法
    Standard_Boolean bRunParallel;
    Standard_Real aFuzzyValue;
    BRepAlgoAPI_Common aBuilder;

    // perpare the arguments
    TopTools_ListOfShape aLS;
    TopTools_ListOfShape aLT;

    aLS.Append(m_TppoTargetBody_cal);  //xx   m_TppoTargetBody
    aLT.Append(m_TopoMoveBody_cal);  //yy   m_TopoMoveBody

    bRunParallel=Standard_True;
    aFuzzyValue=2.1e-5;

    // set the arguments
    aBuilder.SetArguments(aLS);
aBuilder.SetTools(aLT);

    aBuilder.SetRunParallel(bRunParallel);
    aBuilder.SetFuzzyValue(aFuzzyValue);

    // run the algorithm
    aBuilder.Build();
    if (aBuilder.HasErrors()) 
    {
        std::ofstream fout;
        fout.open("errormessage.txt",std::ios_base::app);
        aBuilder.DumpErrors(fout);
        fout.flush();
        fout.close();
        qDebug() << "error";
        return false;
    }

    // result of the operation aR
    const TopoDS_Shape& aR=aBuilder.Shape();

    Bnd_Box B;
    BRepBndLib::Add(aR, B);

    double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
    if(!B.IsVoid())
    {
        B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
    }
    int nb = aR.NbChildren();

    if(!B.IsVoid())   //交集部分的最小包围box存在,则说明碰撞
    {
        std::cout << "common" << std::endl;
        return true;
    }
    else
    {
        std::cout << "no common" << std::endl;
        return false;
    }
}

最终效果展示

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows系统下QT+OpenCasCAD仿真开发 的相关文章

  • adb重启或关机手机命令

    简介 xff1a 在某些特殊场景中 xff0c 例如手机真机不在身边 xff0c 但已通过adb进行连接 xff0c 可以使用命令进行远程关机或者重启 相关攻略 xff1a adb xff1a 常用命令 adb xff1a win10系统下
  • docker:更换镜像源

    简介 xff1a 因为国内的网络访问问题 xff0c 为加快拉取镜像速度 xff0c 建议设置docker国内镜像源 相关攻略 xff1a win10 xff1a 安装docker和测试安装redis centos7 6 xff1a 安装d
  • 七大顶级Linux桌面比较

    1七大顶级Linux桌面 xff1a Unity 对于开源Linux平台来说 xff0c 如何选择就是首要解决的问题 通常Linux发行版都有默认的桌面成为你的首选 xff0c 但目前可供选择的桌面环境种类繁多 特别是Ubuntu系统一个平
  • Linux:安装go环境

    简介 xff1a Go xff08 又称 Golang xff09 是 Google 的 Robert Griesemer xff0c Rob Pike 及 Ken Thompson 开发的一种静态强类型 编译型语言 Go 语言语法与 C
  • docker应用:搭建私有云盘

    简介 xff1a NextCloud是一个开源的云存储解决方案 xff0c 可以在自己的服务器上搭建个人云存储系统 它提供了与市面上主流云存储服务 xff08 如Dropbox Google Drive xff09 相似的功能 xff0c
  • Flask+A-Frame:交互式全景图展示网站

    简介 xff1a 通过结合 Flask 轻量级 Web 框架与 A Frame 3D 和 VR 技术 xff0c 实现了一个可交互的全景图展示功能 xff0c 用户可以在浏览器中自由观看 旋转和缩放全景图片 项目的核心是使用 Flask 搭
  • OpenCV合成全景图

    简介 xff1a OpenCV 利用特征提取 特征匹配 齐次估计 图像配准和图像融合等技术 xff0c 将一系列图像合成为全景图 OpenCV 和 Pillow 是两个功能强大的 Python 图像处理库 xff0c 但它们在处理全景图拼接
  • BDD行为驱动开发+Python案例解析

    简介 xff1a BDD xff08 Behavior Driven Development xff0c 行为驱动开发 xff09 是一种敏捷软件开发方法 xff0c 它强调软件应该按照预期的行为来开发 BDD的核心理念是使用自然语言编写的
  • 操作系统迭代、Debian安装教程

    前言 最近在考虑公司生产环境操作系统的迭代问题 目前 xff0c 公司业务主要跑在CentOS7和8上面 xff0c 由于CentOS早已停止了7和8的支持 xff0c 新版的CentOS Stream也从RHEL的下游变成了上游 xff0
  • Debian修改DNS

    原文链接 Debian的DNS文件默认为 etc resolv conf 查看当前的DNS cat etc resolv conf 下图中画出的就是当前系统的DNS 如果想修改DNS的话 xff0c 可以直接vim 来修改文件 xff0c
  • 配置JupyterLab远程密码访问

    文章目录 部署环境配置步骤启动和连接访问启动连接访问 有些时候因为某些原因 xff08 如本地机器资源不足 数据不能离网等 xff09 xff0c 需要使用本地电脑连接远程服务器进行开发工作 xff0c 在这里记录下如何在远程Linux上配
  • linux查看 jre 安装目录

    近期对接平安银行项目 xff0c 要求放国密 jar包到jre目录 xff0c 网上也找了一些命令 xff0c 下面这个亲测有用 xff0c 特此记录一下 xff0c 我的系统版本是3 10 0 693 el7 x86 64 步骤 1 使用
  • Python选择网卡发包及接收数据包

    当一台计算机上有多个网卡时 xff0c 需要选择对应IP地址的网卡进行发送数据包或者接受数据包 1 选择网卡发包 xff08 应用scapy xff09 xff1a plface 61 conf route route 34 34 0 为对
  • php 使用 Excel/reader.php, 导入excel到数据库 ,解决The file is not readable。。

    今天小伙伴上传excel到服务器 并导入到数据库中 xff0c 可是文件一直出现 The file is not readable 是哪里的代码抛出的异常呢 xff1f 是Spreadsheet Excel Reader类里面 其中抛出异常
  • “The Language Support for Java server crashed“ 问题解决方案

    The Language Support for Java server crashed 问题解决方案 环境 xff1a Windowsvs code 1 356 14日最新发布的VSCodeJavaInstaller online win
  • (循环读取网易云缓存文件转mp3)

    循环读取网易云缓存文件转mp3 import java io DataInputStream import java io DataOutputStream import java io File import java io FileIn
  • 洛谷P4180 [BJWC2010]严格次小生成树

    传送门 之前写过一次 xff0c 但是理解不深刻 xff0c 复习之后有了更加细节的一些理解 好了进入正题 首先 xff0c 我们需要知道次小生成树一定是在最小生成树的邻集中 xff0c 即次小生成树与最小生成树只会有一条边的差别 所以我们
  • MarkDown学习笔记

    MarkDown学习笔记 目录 MarkDown学习笔记 1 标题2 段落3 文字3 1斜体3 2加粗3 3斜体 43 加粗3 4删除线3 5下划线3 6字体背景 4 分隔线5 扩展语法的说明6 高亮 xff08 需要勾选扩展语法 xff0
  • 格式化标准输出函数printf()与格式化标准输入函数scanf()

    printf 函数与scanf 函数 文章目录 printf 函数与scanf 函数格式化标准输出函数 printf 相关函数 xff1a 返回值参数执行顺序打印较长字符串格式控制符 xff1a 输出缓冲区printf 的标志转义字符类型修
  • 数据在内存中的存储

    数据在内存中的存储 文章目录 数据在内存中的存储计算机中的数据数据类型类型的基本归类整型在内存中的存储原码 反码 补码大小端介绍浮点型在内存中的存储二进制与十进制的转换 计算机要处理的信息是多种多样的 xff0c 如数字 文字 符号 图形

随机推荐

  • 特殊函数--变参函数及相关宏

    特殊函数 变参函数 定义的函数在使用时传入的参数是不定量不定类型 变参函数 include lt stdarg h gt 例子 xff1a printf 34 abc d def c g n 34 num ch xff09 其中 34 ab
  • 进程的内存分布

    Linux 内存分布 C进程的内存布局 Linux和windows都是支持多任务多用户的高级操作系统 进程 xff08 process xff09 xff1a 一段程序的执行过程 对于一个C程序 xff0c 在运行过程中系统对这个进程的内存
  • C语言实现24点游戏算法

    纸牌游戏24点 xff0c 输入4个1到13之间的值 xff0c 通过加减乘除判断是否可以得到24 span class token macro property span class token directive hash span s
  • C语言实现排序与组合

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)

    有一天我的androidHttpURLConnection 报这种错 你看 to reduce latency this class may reuse the same underlying Socket for 懂了吧 xff0c 我们
  • C语言解决四人/多人过桥问题

    参加笔试的时候遇到一道经典的算法题 xff0c 四人过桥问题 当时没写出来 x1f605 四人过桥问题 xff1a 在一个黑夜里 xff0c 有四个人需要过桥 xff0c 每次只能通过两人 xff0c 其中一人必须拿着手电筒 xff1b 但
  • C语言计算某一天是星期几

    span class token comment 1970年1月1日星期四 span span class token macro property span class token directive hash span span cla
  • 七牛云存储,上传一直超时

    今天在使用七牛云存储上传的时候 xff0c 遇到一个奇葩的问题 xff0c 就是一直上传超时 但是直接连接up qiniu com又是能够连接到的 而且iOS的有问题 xff0c android的没有问题 关于七牛云存储 xff1a htt
  • OSI七层网络参考模型详解

    1 什么是 OSI 模型 OSI 描述了计算机系统之间进行网络通信的模型 它是第一个网络通信标准模型 xff0c 在 1980 年代初期被所有主要计算机和电信公司采用 现代 Internet 不是基于 OSI xff0c 而是基于更简单的
  • Python制作简易OCR文字识别系统

    前不久看了一篇 如何使用Python检测和识别车牌 xff1f 用OpenCV对输入图像进行预处理 xff0c 用imutils将原始输入图像裁剪成所需的大小 xff0c 用pytesseract将提取车牌字符转换成字符串 车牌识别 但经实
  • PageHelper和Mybatis-plus分页的使用

    PageHelper和Mybatis plus分页的使用 一 PageHelper 准备sql span class token keyword CREATE span span class token keyword TABLE span
  • [RTC]系统时间NTP和RTC同步,Debian的时区配置

    转自 xff1a linux修改系统时间和linux查看时区 修改时区的方法 jiu 博客园 Debian的时区配置 一 修改时区 1 查看当前时区 命令 xff1a 34 date R 34 2 修改设置Linux服务器时区 方法 A 命
  • Autonomous Driving in Adverse Weather Conditions: A Survey - 恶劣天气条件下的自动驾驶:一项调查 (arXiv 2021)

    Autonomous Driving in Adverse Weather Conditions A Survey 恶劣天气条件下的自动驾驶 xff1a 一项调查 xff08 arXiv 2021 xff09 摘要1 引言2 自动驾驶汽车概
  • C#关于枚举类型Enum的用法详解,很细

    一 关键字enum的定义 enum是C语言中的一个关键字 xff0c enum叫枚举数据类型 xff0c 枚举数据类型描述的是一组整型值的集合 xff08 这句话其实不太妥当 xff09 xff0c 枚举型是预处理指令 define的替代
  • boost b2/bjam 参数说明

    b2 bjam 参数说明 xff1a b2 命令的功能强大 xff0c 用起来也比较复杂 xff0c 因此在使用之前 xff0c 最好先查看一下该命令的帮助 xff1a b2 exe help 以下是一些比较重要的参数说明 xff1a st
  • libssl-dev 安装失败 解决方案

    我本来是要安ettercap dependencs的 xff0c 没看到ettercap下面直接有可以使用的命令 xff0c 我上次看到了 xff0c 也提醒了自己 xff0c 但是这次我多花了5个小时搞定它 xff0c 包括了 ubunt
  • 离线文档浏览工具Zeal的下载和使用

    什么是Zeal xff1f Zeal是一款为软件开发人员提供的离线文档浏览器 截至2022年1月17日 xff0c Zeal可以下载查看207种编程语言或软件工具的帮助文档 Zeal Offline Documentation Browse
  • VS 之error MSB8020: The builds tools for v110_xp......

    VS错误如下 error MSB8020 The builds tools for v110 xp Platform Toolset 61 v110 xp cannot be found To build using the v110 xp
  • Ubuntu/Debian快速重装

    Linux系统更新升级非常快 xff0c 半年甚至几个月就会有新的版本出来 xff0c 虽然向Ubuntu能够自动升级到新的版本 xff0c 但是 xff0c 有时候升级可能效果不太好 xff0c 可能还是愿意选择重装 现在的Linux系统
  • Windows系统下QT+OpenCasCAD仿真开发

    背景 最近开发了一个六自由度机械臂调姿平台的控制软件 xff0c 集成了API激光跟踪仪和KUKA机器人 xff0c 实现了根据产品的测量位姿驱动仿真环境中模型并且实现模型间的碰撞检测 其中KUKA机器人的控制可以参考笔者以前的博客 xff