在CAA(Component Application Architecture)二次开发中,3D Part作为产品结构的核心组件,其独特的聚合规则和生命周期管理逻辑一直是开发中的重点与难点。从核心特性、API应用、实战步骤三个维度,带大家全面掌握3D Part的开发技巧,助力高效构建符合PLM规范的二次开发应用。
一、3D Part核心特性:理解底层设计逻辑
要做好3D Part相关开发,首先需要吃透其底层设计规则——3D Part本质是一种特殊的Product Reference(产品引用),但具备严格的聚合限制和生命周期关联特性,具体核心规则如下:
1. 聚合关系限制(关键开发约束)
-
仅允许聚合一个且唯一的Mono-Instantiable Representation Reference(单实例化表示引用,简称Rep Ref),且该Rep Ref必须是3DShape类型;
-
禁止聚合Product Instance(产品实例),任何尝试在3D Part下实例化产品实例的操作都会失败;
-
支持聚合非3DShape类型的其他Rep Instances(表示实例),但3DShape类型只能有一个;
-
无法直接删除3D Part下唯一的3DShape Rep Inst,强制删除会返回执行失败。
2. 生命周期关联特性
3D Part与其下属的3DShape存在强生命周期绑定:
-
删除3D Part会同步删除其关联的3DShape;
-
对3D Part进行版本控制或复制操作时,其下属3DShape会自动执行相同操作;
-
3DShape的Rep Ref内容类型固定为"Structured Content"(结构化内容),对应V5结构化流类型。
3. 核心标识属性
3D Part的V_usage属性值固定为"3DPart",这是区分3D Part与其他Product Reference的关键标识,开发中可通过该属性快速筛选3D Part类型对象。
二、开发必备API:关键接口与使用场景
文档中明确了开发3D Part相关功能所需的核心API,按功能分类整理如下,方便大家按需调用:
1. 数据查询与加载API
- CATAdpQueryServices:用于构建和执行PLM数据库查询,通过属性-值集合检索3D Part的唯一标识(Identificator);
- CATAdpOpener/CATAdpSaver:PLM组件的加载与保存核心接口,支持将数据库中的3D Part、Rep Ref等组件加载到会话中,或保存会话中的修改;
- CAARetrieveIDofUniquePLMObject:全局工具函数,通过属性集合(如PLM_ExternalID、MajorRevision、V_Name等)获取PLM对象的唯一标识,是数据加载的前置关键步骤。
2. 属性读取API
- CATCkeObjectAttrReadServices:用于读取PLM组件的属性值,核心应用场景是通过
GetValue方法获取3D Part的V_usage属性,验证是否为"3DPart"类型。
3. 产品结构导航与操作API
- CATIPLMRepInstances:管理3D Part下的表示实例,提供
Count(统计实例数量)、AddRepInstance(添加表示实例)、RemoveRepInstance(删除表示实例)等核心方法; - CATIPLMNavRepInstance/CATIPLMNavRepReference:用于导航表示实例与表示引用的关联关系,关键方法包括
GetRepReferenceInstanceOf(获取实例对应的Rep Ref)、IsOnceInstantiable(验证Rep Ref是否为单实例化类型)、GetContentKind(获取Rep Ref的内容类型); - CATIPLMProducts:产品实例化相关接口,
AddProduct方法用于尝试在3D Part下添加产品实例(实际开发中需避免,因会返回失败)。
三、实战开发步骤:从环境搭建到功能验证
结合实际用例,我们整理出完整的3D Part开发流程,涵盖环境配置、核心功能实现、结果验证三个阶段:
1. 前置准备:环境搭建与参数配置
(1)环境要求
-
构建时环境:配置框架依赖,编译模块及其前置依赖;
-
运行时环境:指定PLM仓库地址(Repository)、服务器信息(ServerName:ServerPort/rootURI)、登录凭证(LoginTicket)等核心参数。
(2)输入数据准备
-
导入测试数据:以3dxml文件为例,文件包含预设的3D Part、Rep Ref和Child Ref;
-
自定义数据要求:若使用自定义数据,需确保为VPMReference类型,且必须包含PLM_ExternalID和MajorRevision作为标识属性(保证数据唯一性)。
2. 核心功能实现步骤(附关键代码片段)
以验证3D Part核心特性为例,完整开发流程如下:
步骤1:创建会话并连接PLM仓库
// 核心逻辑:以管理员角色创建会话(修改PLM数据需管理员权限)
CATSession* pSession = NULL;
CreateSession("AdminRole", &pSession);
ConnectToRepository(Repository, Server, LoginTicket, pSession);
关键说明:所有批量处理用例的基础步骤,会话管理详情可参考官方文档《Connecting to V6 Server》。
步骤2:加载3D Part到会话
// 1. 构建属性集合(以V_Name和revision为例)
CATListOfCATUnicodeString iListAttributeName;
CATListOfCATUnicodeString iListAttributeValue;
iListAttributeName.Append("V_Name");
iListAttributeValue.Append("XXXXXXXXXXXXX");
iListAttributeName.Append("revision");
iListAttributeValue.Append("A.1");
// 2. 获取3D Part的唯一标识
CATIAdpPLMIdentificator* opiIDComp = NULL;
CAARetrieveIDofUniquePLMObject(iListAttributeName, iListAttributeValue, "VPMReference", opiIDComp);
// 3. 加载3D Part到会话并插入BAG(生命周期管理容器)
CATOmbLifeCycleRootsBag Bag;
CATAdpOpener AdpOpener(Bag);
CATICkeObject* piCkeObjectOnRoot = NULL;
AdpOpener.CompleteAndOpen(opiIDComp, IID_CATICkeObject, (void**)&piCkeObjectOnRoot);
关键说明:BAG(CATOmbLifeCycleRootsBag)用于管理会话中PLM组件的生命周期,必须将加载的组件插入BAG,避免内存泄漏。
步骤3:验证3D Part核心特性(关键功能示例)
(1)验证V_usage属性
CATIValue_var spValueOnV_usage;
CATUnicodeString strAttrName("V_usage");
CATCkeObjectAttrReadServices::GetValue(piCkeObjectOnRoot, strAttrName, spValueOnV_usage);
CATUnicodeString strV_usageValue;
spValueOnV_usage->AsString(strV_usageValue);
if (strV_usageValue == "3DPart") {
cout << "验证通过:当前组件为3D Part类型" << endl;
}
(2)验证唯一3DShape Rep Inst
CATIPLMRepInstances* piPLMRepInstOnRoot = NULL;
piCkeObjectOnRoot->QueryInterface(IID_CATIPLMRepInstances, (void**)&piPLMRepInstOnRoot);
int iCount = 0;
piPLMRepInstOnRoot->Count(iCount);
if (iCount == 1) {
cout << "验证通过:3D Part下仅存在一个表示实例" << endl;
// 进一步验证是否为单实例化Rep Ref
CATIPrdIterator* piPrdIterator = NULL;
piPLMRepInstOnRoot->Iterator(piPrdIterator);
CATBaseUnknown* pBUOnRepInst = NULL;
piPrdIterator->Next(pBUOnRepInst);
CATIPLMNavRepInstance* piNavRepInst = NULL;
pBUOnRepInst->QueryInterface(IID_CATIPLMNavRepInstance, (void**)&piNavRepInst);
CATIPLMNavRepReference* piNavRepRef = NULL;
piNavRepInst->GetRepReferenceInstanceOf(piNavRepRef);
if (piNavRepRef->IsOnceInstantiable() == S_OK) {
cout << "验证通过:表示实例为单实例化Rep Ref" << endl;
}
}
(3)验证无法删除唯一3DShape
CATIPrdRepInstance* piPrdRepInst = NULL;
piNavRepInst->QueryInterface(IID_CATIPrdRepInstance, (void**)&piPrdRepInst);
HRESULT hr = piPLMRepInstOnRoot->RemoveRepInstance(piPrdRepInst);
if (FAILED(hr)) {
cout << "验证通过:无法删除3D Part下唯一的3DShape" << endl;
}
(4)验证无法添加新3DShape
// 加载待添加的Rep Ref(省略属性构建和标识获取步骤)
CATIPsiRepresentationReference* piPsiRepRefOnNewRepRef = NULL;
opener.CompleteAndOpen(opiIDComp_RepRef, IID_CATIPsiRepresentationReference, (void**)&piPsiRepRefOnNewRepRef);
// 尝试添加新3DShape
CATUnicodeString iRepInstName("NewRepInst");
CATBaseUnknown* oRepInstance = NULL;
hr = piPLMRepInstOnRoot->AddRepInstance(iRepInstName, piPsiRepRefOnNewRepRef, oRepInstance);
if (FAILED(hr) || oRepInstance == NULL) {
cout << "验证通过:无法在3D Part下添加新的3DShape" << endl;
}
步骤4:资源清理
// 清空BAG,卸载所有会话中的PLM组件
Bag.RemoveAll();
// 关闭PLM会话
CloseSession(pSession);
3. 运行用例:命令行参数格式
开发完成后,通过以下命令行执行用例(参数需替换为实际环境配置):
mkrun -c "XXXXXXXX PLM1 ServerName:8080/rootURI LoginTicket123 VPMReference V_Name XXXXXXXX_RepRef revision A.1 V_Name XXXXXXX_ChildRef revision A.1 V_Name XXXXXXX_Root revision A.1 VPMReference"
参数说明:依次指定仓库、服务器、登录凭证、PLM类型、各组件的属性名和属性值,具体参数顺序需严格遵循文档定义。
四、开发避坑指南
- 数据标识唯一性:使用V_Name和revision标识产品时,无法保证唯一性,建议优先使用PLM_ExternalID和MajorRevision作为标识属性;
- BAG使用规范:所有加载到会话的PLM组件必须插入BAG,否则会导致生命周期管理异常,引发内存泄漏;
- 权限控制:修改PLM数据(如删除、版本控制)时,需以管理员角色创建会话,否则会返回权限不足错误;
- 3DXML导入:自定义数据导入时,需确保数据类型为VPMReference或类似类型,且包含必需的标识属性,否则用例会触发参数校验失败。
总结
3D Part作为CAA产品结构开发的核心组件,其开发重点在于严格遵循聚合规则和生命周期关联逻辑,熟练运用数据查询、结构导航、属性读取类API。本文结合官方用例拆解的开发流程,可直接应用于3D Part相关的二次开发场景(如数据验证、结构校验、批量处理等)。
评论