← 返回首页

CATIA V5 CAA 自定义特征开发指南

本文面向已经具备 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 目录内容的文本语言。它不是直接“编译成新目录”的一次性源文件,而是用来升级已经存在的目录。官方推荐的目录维护模式是:

  1. 用 CATfctEditorAssistant 创建空 .CATfct 和对应 .osm

  2. 修改 .osm,加入 StartUp、属性和扩展定义。

  3. 用 CATfctEditorAssistant -update-catalog 更新 .CATfct

  4. 再用 -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 表示外部链接;intdoublebooleanstring 是基础值类型。

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 初始化实例

实例创建后还要做三件常见工作:

  1. 用类型接口设置输入属性和默认值。

  2. 对机械特征初始化算法/配置数据,使后续版本和 Build 行为可追踪。

  3. 如果是几何特征,根据 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 要做的事情:

  1. 读取输入属性。

  2. 检查特征激活/停用状态。

  3. 清理旧 update error。

  4. 调用 CGM 或 Mechanical Modeler 服务计算几何结果。

  5. 建立 procedural report,让结果拓扑具备稳定命名和生命周期。

  6. 保存 result、scope 和 algorithm configuration。

  7. 捕获 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/参数机制发布属性时实现。

如果派生自 GSMGeomMechanicalFormFeature 或 MechanicalContextualFeature,部分行为已有默认实现,必须实现的接口会不同。建议按父 StartUp 对照 Mechanical Modeler 的集成表逐项确认。

7.3 非几何特征

非几何特征通常派生自 MechanicalElement。它没有 CATBody 结果,但仍可能需要:

  • CATIParmPublisher

    :发布参数。

  • CATINavigateObject

    :控制规格树导航。

  • CATIContextualSubMenu

    :扩展右键菜单。

  • CATI3DGeoVisu

    或相关可视化接口:如果要在 3D 视图区显示分析框、标注或临时表示。

  • 自定义 factory:创建实例并挂入 MechanicalPart 或 MechanicalSet

CAA 文档中的 MultiMeasure 示例就是一个典型非几何分析特征:它派生自 MechanicalElement,输入一个几何特征,输出长度、面积、体积等参数,并在 3D 视图中显示测量结果。

8. 创建交互命令和工作台入口

有了 factory 和行为接口之后,还需要让用户能创建和编辑特征。常见做法是:

  1. 创建 state command 或 dialog command,完成选择输入、校验、预览和确认。

  2. 在目标工作台创建 add-in,把命令加入 toolbar/menu。

  3. 命令中取得当前 Part 的规格容器,Query factory 接口。

  4. 调用 factory 创建特征。

  5. 用类型接口写入输入属性。

  6. 按业务规则将实例插入当前 Body、Ordered Geometrical Set、Geometrical Set 或 MechanicalSet。

  7. 触发 update 或让 CATIA 后续统一更新。

编辑已有实例时,CATIEdit 通常负责启动同一套命令,只是命令进入 edit mode,并从类型接口读取已有属性作为初始值。

9. 构建、运行和验证

一个最小开发闭环如下:

  1. 在 CAA workspace 中创建 framework/module。

  2. 放置 .CATfct.CATNls、图标到 CNext/resources/...

  3. 编写 PublicInterfaces、LocalInterfaces、src、dictionary、Imakefile/mj 文件。

  4. 构建模块。

  5. 刷新运行时视图,确保 .CATfct 在 OS_directory/resources/graphic

  6. 启动 CATIA,确认自定义命令出现。

  7. 创建特征,保存 CATPart,关闭再打开,确认实例可恢复。

  8. 修改输入,执行 Update,确认结果、错误提示和 Replace 行为正确。

  9. 在缺少插件或目录的环境中验证 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 语法、documentcontainerfeature、属性类型和 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 里怎么活”。

评论