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

相关文章

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

Python验证码识别方式(使用pytesseract库)

《Python验证码识别方式(使用pytesseract库)》:本文主要介绍Python验证码识别方式(使用pytesseract库),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1、安装Tesseract-OCR2、在python中使用3、本地图片识别4、结合playwrigh

Java资源管理和引用体系的使用详解

《Java资源管理和引用体系的使用详解》:本文主要介绍Java资源管理和引用体系的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Java的引用体系1、强引用 (Strong Reference)2、软引用 (Soft Reference)3、弱引用 (W

使用Python和PaddleOCR实现图文识别的代码和步骤

《使用Python和PaddleOCR实现图文识别的代码和步骤》在当今数字化时代,图文识别技术的应用越来越广泛,如文档数字化、信息提取等,PaddleOCR是百度开源的一款强大的OCR工具包,它集成了... 目录一、引言二、环境准备2.1 安装 python2.2 安装 PaddlePaddle2.3 安装

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

使用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. 裁剪与重置图像