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

相关文章

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

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

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

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

OCC开发_变高箱梁全桥建模

概述     上一篇文章《OCC开发_箱梁梁体建模》中详细介绍了箱梁梁体建模的过程。但是,对于实际桥梁,截面可能存在高度、腹板厚度、顶底板厚度变化,全桥的结构中心线存在平曲线和竖曲线。针对实际情况,通过一个截面拉伸来实现全桥建模显然不可能。因此,针对变高箱梁,本文新的思路来实现全桥建模。 思路 上一篇文章通过一个截面拉伸生成几何体的方式行不通,我们可以通过不同面来形成棱柱的方式实现。具体步骤

17 通过ref代替DOM用来获取元素和组件的引用

重点 ref :官网给出的解释是: ref: 用于注册对元素或子组件的引用。引用将在父组件的$refs 对象下注册。如果在普通DOM元素上使用,则引用将是该元素;如果在子组件上使用,则引用将是组件实例: <!-- vm.$refs.p will be the DOM node --><p ref="p">hello</p><!-- vm.$refs.child will be the c

Clion不识别C代码或者无法跳转C语言项目怎么办?

如果是中文会显示: 此时只需要右击项目,或者你的源代码目录,将这个项目或者源码目录标记为项目源和头文件即可。 英文如下:

读Spring实战(第四版)概括—装配Bean

很久很久以前读过Spring实战(第三版),因为第三版和第四部差异还是特别明显的,在整体思想上有了比较重大的改变,比如用注解和JavaConfig替换Xml以及现在非常火热的Springboot在书的最后也有提到。OK,开始看书,书本的第一章讲了一下Spring存在的目的(简化Java开发)和Spring的功能,以及Spring3->Spring4增加了哪些功能,那我就从第二章开始概括本书,以给我

初步了解VTK装配体

VTK还不太了解,根据资料, vtk.vtkAssembly 是 VTK库中的一个重要类,允许通过将多个vtkActor对象组合在一起来创建复杂的3D模型。 import vtkimport mathfrom vtk.util.colors import *filenames = ["cylinder.stl","sphere.stl","torus.stl"]dt = 1.0renW

BERN2(生物医学领域)命名实体识别与命名规范化工具

BERN2: an advanced neural biomedical named entity recognition and normalization tool 《Bioinformatics》2022 1 摘要 NER和NEN:在生物医学自然语言处理中,NER和NEN是关键任务,它们使得从生物医学文献中自动提取实体(如疾病和药物)成为可能。 BERN2:BERN2是一个工具,

【Spring Boot】 SpringBoot自动装配-Condition

目录 一、前言二、 定义2.1 @Conditional2.2 Condition2.2.1 ConditionContext 三、 使用说明3.1 创建项目3.1.1 导入依赖3.1.2 添加配置信息3.1.3 创建User类3.1.4 创建条件实现类3.1.5 修改启动类 3.2 测试3.2.1 当user.enable=false3.2.2 当user.enable=true 3.3

在项目中,控制权限保存时,如果多次修改权限,该如何写?

在项目中,控制权限保存时,如果多次修改权限,该如何写? 错误代码: package cn.itcast.crm.service.impl;import java.util.List;import javax.annotation.Resource;import org.apache.commons.lang.xwork.StringUtils;import org.springfr