本文面向已经具备 CATIA V5 CAA C++ 开发环境的读者,说明如何开发一个 V5 自定义特征。这里的“自定义特征”不是单纯的 C++ 类,而是由三部分共同组成:存放在 .CATfct 目录中的 StartUp 数据模型、挂接在 StartUp 或容器上的 CAA 行为实现、以及用于创建和编辑实例的 factory/命令入口。
1. 先理解几个核心概念
StartUp
StartUp 是特征实例的原型,描述该类特征的继承关系、输入属性、输出属性和持久化结构。运行时创建特征时,CATIA 实际上是从某个 StartUp 实例化出一个 feature object。
在 OSM 中,一个 StartUp 通常写成:
feature MyCompanyCombinedCurve GeometricalElement3D@`MechMod.feat` #startup {
specobject Curve1 #in
specobject Direction1 #in
specobject Curve2 #in
specobject Direction2 #in
int Deactivate #in
}
上例表示 MyCompanyCombinedCurve 派生自 DS 提供的 MechMod.feat 中的 GeometricalElement3D StartUp,并声明了四个输入对象和一个控制状态属性。
.CATfct 目录
.CATfct 是 CAA 客户自定义 StartUp 的目录文件。它类似“数据模型库”,包含 StartUp,而不是可执行代码。DS 自带目录一般是 .feat,客户扩展目录使用 .CATfct。
目录必须放入运行时视图的 resources/graphic 中。通常开发态文件放在你的 framework 下:
YourFramework/CNext/resources/graphic/MyFeatureCatalog.CATfct
构建运行时视图后,它会被复制到:
workspace_root/OS_directory/resources/graphic
因为所有目录通过 CATGraphicPath 查找,代码和命令中一般只写目录名,不写绝对路径。
OSM
OSM 是描述 .CATfct 目录内容的文本语言。它不是直接“编译成新目录”的一次性源文件,而是用来升级已经存在的目录。官方推荐的目录维护模式是:
-
用
CATfctEditorAssistant创建空.CATfct和对应.osm。 -
修改
.osm,加入 StartUp、属性和扩展定义。 -
用
CATfctEditorAssistant -update-catalog更新.CATfct。 -
再用
-describe-as-osm从新目录导出下一轮编辑用的.osm。
不要长期维护一份脱离当前 .CATfct 的手写 OSM。目录一旦升级后,应重新导出 OSM 再继续修改。
Client ID
.CATfct 创建时必须指定 Client ID。以后无论用工具更新目录,还是在 C++ 代码中访问目录,都必须使用同一个 Client ID。Client ID 创建后不能修改。
2. 选择要派生的基础 StartUp
自定义特征首先要回答:它在 CATIA 里应当像什么东西?
常见选择如下:
| 目标 | 推荐派生 StartUp | 说明 |
|---|---|---|
| 线框或曲面特征 | GeometricalElement3D或 GSMGeom |
适合 Shape Design 中的几何结果。GSMGeom 可继承更多 GSD 行为,GeometricalElement3D 更基础。 |
| 实体成形特征 | MechanicalFormFeature |
例如类似 Pad、Groove 这类先生成形状再与 PartBody 运算的特征。 |
| 实体上下文特征 | MechanicalContextualFeature |
例如圆角、倒角这类结果依赖目标拓扑局部上下文的特征。 |
| 非几何分析/业务特征 | MechanicalElement |
没有几何结果,但需要出现在规格树、参与机械模型机制。 |
| 聚合容器 | GSMTool或 MechanicalSet |
用于承载几何特征或非几何特征集合。 |
选择父 StartUp 会影响后续必须实现的接口、实例能插入的位置、更新机制、Replace 行为、图标和上下文菜单等。
3. 建立 .CATfct 目录
CATfctEditorAssistant 在本安装库中位于:
win_b64/code/bin/CATfctEditorAssistant.exe
实际使用时建议进入 CAA 构建环境,例如通过 mkrun -c sh 或 mkrun -c cmd,确保 CATGraphicPath、运行时视图和 CAA 环境变量已经正确设置。
3.1 创建空目录
CATfctEditorAssistant -create-new-catalog ^
-catalog-name MyFeatureCatalog.CATfct ^
-with-client-id MyCompanyClientId ^
-into-directory .
这个命令创建的是空目录,不会把已有 OSM 直接变成目录。生成后会得到空的 .CATfct 和 .osm。
创建完成后,把 .CATfct 放到 framework 的 CNext/resources/graphic,并刷新运行时视图。
3.2 编写 OSM
一个最小目录结构如下:
document `MyFeatureCatalog.CATfct` {
container CATFeatCont #root {
feature MyCompanyMeasure MechanicalElement@`MechMod.feat` #startup {
specobject InputFeature #in
double Length #out
}
}
}
关键点:
-
document名称要包含
.CATfct,因为点号不符合普通标识符规则,所以通常放在反引号中。 -
一个目录只有一个
container CATFeatCont #root。 -
feature的第一个名字就是 late type,后续 C++ DataExtension 也会用它作为扩展目标。
-
父 StartUp 在其他目录中时,用如下形式表示:
Parent@`Catalog.feat`
Parent@`Catalog.CATfct`
-
#startup表示该 feature 是可实例化的 StartUp。
-
#in是输入规格,
#out是结果,#neutral是中性属性。 -
specobject表示指向其他规格对象的引用;
component表示聚合;external表示外部链接;int、double、boolean、string是基础值类型。
3.3 更新目录
CATfctEditorAssistant -update-catalog ^
-catalog-name MyFeatureCatalog.CATfct ^
-with-client-id MyCompanyClientId ^
-with-osm .\MyFeatureCatalog.osm ^
-into-directory .
注意:更新时工具会先从运行时视图中按目录名查找旧 .CATfct,再把更新后的结果写到 -into-directory 指定位置。因此被更新的旧目录必须已经在 resources/graphic 运行时视图中。
3.4 导出下一轮 OSM
CATfctEditorAssistant -describe-as-osm ^
-catalog-name MyFeatureCatalog.CATfct ^
-with-client-id MyCompanyClientId ^
-as MyFeatureCatalog.osm ^
-into-directory .
导出的 OSM 中可能包含 #number 后缀和 uuid。不要手工删除或修改这些标识,否则后续升级可能失败。
4. 本地化名称和图标
如果不提供 NLS,规格树里通常会显示 StartUp 标识符。目录对应的 NLS 文件名为:
MyFeatureCatalogNLS.CATNls
放置位置:
YourFramework/CNext/resources/msgcatalog
内容示例:
MyCompanyMeasure="Company Measure";
简单机械特征可以只提供图标文件,命名规则为:
I_StartUpName.bmp
例如:
I_MyCompanyMeasure.bmp
图标通常放在 CNext/resources/graphic。
5. 创建“类型接口”访问自定义属性
StartUp 中新增的属性不建议散落在业务代码中直接按字符串访问。更稳妥的做法是创建一个 interface of type,用它封装该特征自己的输入、输出和状态访问。
例如:
classExportedByMyFeature MyCompanyIMeasure : public CATBaseUnknown
{
CATDeclareInterface;
public:
virtual HRESULT SetInputFeature(CATBaseUnknown *inputFeature)= 0;
virtual HRESULT GetInputFeature(CATBaseUnknown *&outputFeature)= 0;
virtual HRESULT GetLength(double &length)= 0;
};
实现类作为 StartUp late type 的 DataExtension:
#include"TIE_MyCompanyIMeasure.h"
TIE_MyCompanyIMeasure(MyCompanyEMeasure);
CATImplementClass(
MyCompanyEMeasure,
DataExtension,
CATBaseUnknown,
MyCompanyMeasure);
最后在 interface dictionary 中声明该 StartUp 实现了接口,例如:
MyCompanyMeasure MyCompanyIMeasure libMyFeature
这样 command、factory、Build 行为都可以通过 MyCompanyIMeasure 设置或读取属性,而不依赖散乱的属性名字符串。
6. 创建 factory 实例化 StartUp
自定义特征通常需要一个 factory 接口,用来从 Part 的规格容器中创建实例。Mechanical Modeler 文档推荐将 factory 作为 CATPrtCont 的 DataExtension。
6.1 factory 接口
classExportedByMyFeature MyCompanyIMeasureFactory : public CATBaseUnknown
{
CATDeclareInterface;
public:
virtual HRESULT CreateMeasure(
CATBaseUnknown *inputFeature,
CATISpecObject **createdFeature)= 0;
};
6.2 在 CATPrtCont 上实现 factory
#include"TIE_MyCompanyIMeasureFactory.h"
TIE_MyCompanyIMeasureFactory(MyCompanyEMeasureFactory);
CATImplementClass(
MyCompanyEMeasureFactory,
DataExtension,
CATBaseUnknown,
CATPrtCont);
dictionary 示例:
CATPrtCont MyCompanyIMeasureFactory libMyFeature
6.3 用 Feature Modeler facade 实例化
在 V5/V6 backport 风格示例中,实例化目录 StartUp 常见流程如下:
CATUnicodeString clientId("MyCompanyClientId");
CATUnicodeString partnerId("MyCompanyMechanicalApp");
CATUnicodeString catalogName("MyFeatureCatalog");
CATFmCredentials credentials;
HRESULT rc = credentials.RegisterAsApplicationBasedOn(
CATFmFeatureModelerID,
partnerId);
if (SUCCEEDED(rc))
{
rc = credentials.RegisterAsCatalogOwner(catalogName, clientId);
}
CATFmContainerFacade containerFacade(credentials, this);
CATUnicodeString startupName = "`MyCompanyMeasure`@`MyFeatureCatalog.CATfct`";
CATFmStartUpFacade startupFacade(credentials, startupName);
CATFmFeatureFacade featureFacade;
if (SUCCEEDED(rc))
{
rc = startupFacade.InstantiateIn(containerFacade, featureFacade);
}
较老的 Mechanical Modeler 资料中也会看到 CATOsmSUHandler 的写法:
CATOsmSUHandler startupHandler(
"MyCompanyMeasure",
"MyCompanyClientId",
"MyFeatureCatalog.CATfct");
CATISpecObject_var createdFeature;
HRESULT rc = startupHandler.Instanciate(createdFeature, container);
实际项目应以目标 CATIA 版本和本地 CAA 示例采用的 API 为准,不要混用两套实例化风格。
6.4 初始化实例
实例创建后还要做三件常见工作:
-
用类型接口设置输入属性和默认值。
-
对机械特征初始化算法/配置数据,使后续版本和 Build 行为可追踪。
-
如果是几何特征,根据
CATIInputDescription获取并保存 feature type,用于 BackUp/StartUp 场景。
factory 本身通常只负责创建实例和初始化属性,不直接把实例插入几何集、Body 或 MechanicalSet。插入位置最好交给上层命令或专门服务处理。
7. 实现更新和 V5 行为接口
StartUp 只定义数据结构。要让特征像真正的 V5 特征一样工作,还需要在 late type 上实现行为接口。
7.1 几何结果 Build
对于线框、曲面或实体特征,最关键的是 Build 行为。V5/V6 backport 示例使用 CATIFmFeatureBehaviorCustomization::Build 来构造结果;较早资料中会看到 CATIBuild,实体成形特征还可能涉及 CATIBuildShape。
典型 Build 要做的事情:
-
读取输入属性。
-
检查特征激活/停用状态。
-
清理旧 update error。
-
调用 CGM 或 Mechanical Modeler 服务计算几何结果。
-
建立 procedural report,让结果拓扑具备稳定命名和生命周期。
-
保存 result、scope 和 algorithm configuration。
-
捕获 CATError 并生成清晰的 update error。
Combined Curve 官方示例中,Build 通过两条曲线和两个方向生成两个临时拉伸面,再求交得到 wireframe 结果。
7.2 几何特征常见接口
如果派生自 GeometricalElement3D,官方资料列出的关键接口包括:
| 接口 | 作用 |
|---|---|
CATIFmFeatureBehaviorCustomization或 CATIBuild |
更新时构造特征结果。 |
CATIReplace |
定义输入替换行为。 |
CATIMf3DBehavior |
声明特征是 surface/wireframe/solid/datum 等几何类型。 |
CATIMf3DBehavior2 |
体特征需要时声明 volume 行为。 |
CATIInputDescription |
描述输入、插入有序集合的规则和 feature type。 |
CATIMechanicalProperties |
管理激活/停用状态。 |
CATIEdit |
响应 Definition/Edit,启动编辑命令。 |
CATIContextualSubMenu |
扩展右键菜单。 |
CATIIcon |
特殊情况下自定义图标;简单场景可只提供 I_StartUpName.bmp。 |
CATIParmPublisher |
需要向 Knowledge/参数机制发布属性时实现。 |
如果派生自 GSMGeom、MechanicalFormFeature 或 MechanicalContextualFeature,部分行为已有默认实现,必须实现的接口会不同。建议按父 StartUp 对照 Mechanical Modeler 的集成表逐项确认。
7.3 非几何特征
非几何特征通常派生自 MechanicalElement。它没有 CATBody 结果,但仍可能需要:
-
CATIParmPublisher:发布参数。
-
CATINavigateObject:控制规格树导航。
-
CATIContextualSubMenu:扩展右键菜单。
-
CATI3DGeoVisu或相关可视化接口:如果要在 3D 视图区显示分析框、标注或临时表示。
-
自定义 factory:创建实例并挂入
MechanicalPart或MechanicalSet。
CAA 文档中的 MultiMeasure 示例就是一个典型非几何分析特征:它派生自 MechanicalElement,输入一个几何特征,输出长度、面积、体积等参数,并在 3D 视图中显示测量结果。
8. 创建交互命令和工作台入口
有了 factory 和行为接口之后,还需要让用户能创建和编辑特征。常见做法是:
-
创建 state command 或 dialog command,完成选择输入、校验、预览和确认。
-
在目标工作台创建 add-in,把命令加入 toolbar/menu。
-
命令中取得当前 Part 的规格容器,Query factory 接口。
-
调用 factory 创建特征。
-
用类型接口写入输入属性。
-
按业务规则将实例插入当前 Body、Ordered Geometrical Set、Geometrical Set 或 MechanicalSet。
-
触发 update 或让 CATIA 后续统一更新。
编辑已有实例时,CATIEdit 通常负责启动同一套命令,只是命令进入 edit mode,并从类型接口读取已有属性作为初始值。
9. 构建、运行和验证
一个最小开发闭环如下:
-
在 CAA workspace 中创建 framework/module。
-
放置
.CATfct、.CATNls、图标到CNext/resources/...。 -
编写 PublicInterfaces、LocalInterfaces、src、dictionary、Imakefile/mj 文件。
-
构建模块。
-
刷新运行时视图,确保
.CATfct在OS_directory/resources/graphic。 -
启动 CATIA,确认自定义命令出现。
-
创建特征,保存 CATPart,关闭再打开,确认实例可恢复。
-
修改输入,执行 Update,确认结果、错误提示和 Replace 行为正确。
-
在缺少插件或目录的环境中验证 BackUp/StartUp 行为,至少确认模型不会崩溃。
10. 常见坑
| 问题 | 典型原因 | 处理建议 |
|---|---|---|
CATfctEditorAssistant -update-catalog找不到目录 |
旧 .CATfct 不在运行时视图 |
先把目录放到 CNext/resources/graphic 并刷新 RTV,或确认 CATGraphicPath。 |
| 目录访问失败 | Client ID 不一致 | 创建、更新、C++ 访问必须使用同一个 Client ID。 |
| 后续升级失败 | 手工改了导出 OSM 中的 #number 或 uuid |
从当前 .CATfct 重新 describe-as-osm,只做允许的增量修改。 |
| 已保存模型无法兼容 | 删除了 StartUp 或属性 | 已发布目录尽量只新增,不删除、不改语义;必要时做迁移策略。 |
| 规格树显示内部名 | 缺少 CatalogNameNLS.CATNls |
在 resources/msgcatalog 中添加 NLS 文件。 |
| 图标不显示 | 文件名不符合 I_StartUpName.bmp 或未进入运行时视图 |
检查命名、路径和 mkrtv 输出。 |
| Update 不调用或结果不稳定 | Build 接口/dictionary 未正确注册,或未建立 procedural report | 检查 DataExtension、TIE、dictionary、Build 实现和结果管理。 |
| 右键编辑不可用 | 未实现 CATIEdit 或 contextual menu |
为 late type 增加相应 DataExtension 和 dictionary 声明。 |
11. 推荐阅读的本地 CAADoc 页面
以下路径均来自安装库:
-
CAADoc/Doc/online/CAAOsmTechArticles/CAAOsmTaUnderstandingCatalogs.htm:StartUp catalog、Client ID、
.CATfct与.feat的基本概念。 -
CAADoc/Doc/online/CAAOsmTechArticles/CAAOsmTaMaintainingCatalogs.htm:
CATfctEditorAssistant的命令格式和目录维护模式。 -
CAADoc/Doc/online/CAAOsmTechArticles/CAAOsmTaModelingStartUps.htm:OSM 语法、
document、container、feature、属性类型和 facet。 -
CAADoc/Doc/online/CAAMmrTechArticles/CAAMmrCreatingNewFeat.htm:从 Mechanical StartUp 派生新特征、类型接口和 factory 的总体流程。
-
CAADoc/Doc/online/CAAMmrTechArticles/CAAMmrFeatureIntegration.htm:新机械特征接入 V5 所需的行为接口。
-
CAADoc/Doc/online/CAAV5V6MmrUseCases/CAAV5V6ExtMmrCombinedCurveOverview.htm:创建新几何特征 Combined Curve 的完整案例总览。
-
CAADoc/Doc/online/CAAV5V6MmrUseCases/CAAV5V6ExtMmrCombCrvCatalog.htm:Combined Curve 的
.CATfct和 OSM 创建流程。 -
CAADoc/Doc/online/CAAV5V6MmrUseCases/CAAV5V6ExtMmrCombinedCurveFactory.htm:用 factory 创建 Combined Curve StartUp 实例。
-
CAADoc/Doc/online/CAAV5V6MmrUseCases/CAAV5V6ExtMmrCombinedCurveBuild.htm:几何特征 Build 结果、procedural report 和 update error 处理。
-
CAADoc/Doc/online/CAAV5V6MmrUseCases/CAAV5V6ExtMmrMultiMeasureOverview.htm:派生
MechanicalElement/MechanicalSet的非几何分析特征案例。
12. 总结
开发 CATIA V5 自定义特征的正确路径是:先用 OSM 和 CATfctEditorAssistant 定义稳定的 StartUp 目录,再用 CAA DataExtension 为 late type 和 CATPrtCont 补上类型接口、factory、Build、Replace、Edit 等行为,最后通过命令和工作台入口把实例创建、属性编辑、插入位置和 update 流程串起来。.CATfct 决定“这个特征是什么”,C++ 行为决定“它在 V5 里怎么活”。
评论