OCC中如何识别装配体中多次引用的同一零件体

2024-08-31 07:52

本文主要是介绍OCC中如何识别装配体中多次引用的同一零件体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 问题背景

在CAD(计算机辅助设计)系统中,装配体通常由多个零件(或称为组件)组成,这些零件可能在不同的装配体中多次引用或共享。例如,一个标准的螺栓或轴承可能在多个装配体中被使用,而在这些装配体的设计中,这些标准零件可能被多次引用。

在采用CAD二次开发或者基于开源平台Open cascade进行开发时,如何准确地识别这些重复的零件体,是一个重要的问题,本文以Open cascade为例,说明识别同一零件体的方法。

2. 识别思路

在前置的开发工作中,已经获得了装配体中所有的零件体,放在了m_vecChildPartNode变量中,可以通过m_vecChildPartNode[i]->getOCCShape()方法,获得每个零件体的TopoDS_Shape对象,如何判断两个同一引用的零件体的TopoDS_Shape对象“相同”呢?

在此需要明确TopoDS_Shape的构成,在OCC中,TopoDS_Shape是描述一个拓扑对象的基本变量,这个类记录了拓扑对象的三个主要数据:位置、方向和共享对象,具体由如下三个数据成员表示:

① Handle(TopoDS_TShape) myTShape;
② TopLoc_Location myLocation;
③ TopAbs_Orientation myOrient;

每个TopoDS_Shape都引用了一份TopoDS_TShape,并为TopoDS_TShape增加了orientation和locaion信息。结合共享数据结构部分就可以看出,TopoDS TShape包含了真正的几何、拓扑数据。
myOrient 记录了拓扑对象的方向, myLocation记录了一个对象的位置信息。

在一个装配体中,如果引用了某个零件n次,这个零件在内存中会有一个唯一的TopoDS_TShape数据,对应n个TopoDS_Shape数据,n个TopoDS_Shape共享一份共同的几何、拓扑数据,但是其各自都有自己的位置信息和方向信息。这样,OCC通过共享TopoDS_TShape,减少了模型数据占用内存的大小,一些后续的操作(例如查找所有的共边)也得以可行,或者得到简化。

因此,识别装配体中多次引用的同一零件体的基本思路就是,获得零件对应的TopoDS_TShape对象,检查TopoDS_TShape是否相同,如果相同,则可以认为两个零件是同一个零件。

3. 代码实现及注意点

在OCC中,获取TopoDS_Shape引用的TopoDS_TShape的接口如下:

//Returns a handle to the actual shape implementation.
const Handle< TopoDS_TShape >& TopoDS_Shape::TShape()const

据此写了如下代码

for (int i = 0; i < m_vecChildPartNode.size(); i++){TopoDS_Shape partShape = m_vecChildPartNode[i]->getOCCShape();const Handle(TopoDS_TShape)& shape1 = m_vecChildPartNode[i]->getOCCShape().TShape();for (int j = i + 1; j < m_vecChildPartNode.size(); j++) {const Handle(TopoDS_TShape)& shape2 = m_vecChildPartNode[j]->getOCCShape().TShape();// 检查 shape1 和 shape2 是否相同if (shape1 == shape2){std::cout << "第" << i << "个PartNode和第" << j << "个PartNode的TopoDS_TShape完全相同。" << std::endl;}}
}

但是运行发现,上述代码运行不正确,检测到所有的零件的TopoDS_TShape都是相同的,输出shape1、shape2的地址,都是000000,这是什么原因造成的?该如何解决呢?

先看最终的解决办法如下:

for (int i = 0; i < m_vecChildPartNode.size(); i++){TopoDS_Shape partShape = m_vecChildPartNode[i]->getOCCShape();Handle(TopoDS_TShape) shape1 = m_vecChildPartNode[i]->getOCCShape().TShape();for (int j = i + 1; j < m_vecChildPartNode.size(); j++) {Handle(TopoDS_TShape) shape2 = m_vecChildPartNode[j]->getOCCShape().TShape();// 检查 shape1 和 shape2 是否相同if (shape1 == shape2){std::cout << "第" << i << "个PartNode和第" << j << "个PartNode的TopoDS_TShape完全相同。" << std::endl;}}
}

只需要把原代码中的 const Handle(TopoDS_TShape) &shape1 和 const Handle(TopoDS_TShape) &shape2 改为Handle(TopoDS_TShape) shape1 和 Handle(TopoDS_TShape) shape2 即可。

下面解释原因:

在c++中,Handle(TopoDS_TShape) shape1 和 Handle(TopoDS_TShape) shape2 是值拷贝的形式,意味着 shape1 和 shape2 是独立的智能指针对象,它们分别指向不同的内存区域或相同的对象。而const Handle(TopoDS_TShape) &shape1 和 const Handle(TopoDS_TShape) &shape2 中,shape1 和 shape2 成为对原智能指针对象的引用。因为它们是引用,因此它们指向相同的智能指针对象。

那么为什么引用和拷贝的结果完全不同呢?

Handle(TopoDS_TShape)是 Open CASCADE 的智能指针类,类似于 C++ 的标准智能指针,如 std::shared_ptr。当使用 Handle(TopoDS_TShape) shape1 和 Handle(TopoDS_TShape) shape2 时,你在函数调用时创建了 shape1 和 shape2 的拷贝。这意味着每个 Handle 都有自己的内部指针,可能指向相同的对象,也可能指向不同的对象。每个 Handle 对象都管理着自己的引用计数和资源。

const Handle(TopoDS_TShape) &是 Handle 类的引用,const 关键字表示引用的是常量,不能修改引用的对象。当使用 const Handle(TopoDS_TShape) &shape1 和 const Handle(TopoDS_TShape) &shape2 时,shape1 和 shape2 是对函数传入的 Handle 对象的引用,而不是拷贝。引用不会创建新的 Handle 对象,它们只是指向原来的 Handle 对象。因此,上面第一段代码输出的shape1 和 shape2的地址均为0000000,指向同一个 未创建的Handle 对象,任何 shape1 和 shape2 的比较都相同。

这篇关于OCC中如何识别装配体中多次引用的同一零件体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123314

相关文章

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Pytorch微调BERT实现命名实体识别

《Pytorch微调BERT实现命名实体识别》命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它涉及识别和分类文本中的关键实体,BERT是一种强大的语言表示模型,在各种NLP任务中显著... 目录环境准备加载预训练BERT模型准备数据集标记与对齐微调 BERT最后总结环境准备在继续之前,确

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SpringBoot项目中Maven剔除无用Jar引用的最佳实践

《SpringBoot项目中Maven剔除无用Jar引用的最佳实践》在SpringBoot项目开发中,Maven是最常用的构建工具之一,通过Maven,我们可以轻松地管理项目所需的依赖,而,... 目录1、引言2、Maven 依赖管理的基础概念2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda