CATPathElementAgent 详细使用指南

1. 概述

CATPathElementAgent是 CATIA CAA 二次开发中一个核心的对话框代理类,主要用于在三维查看器中交互式地选择元素。它是实现用户与三维几何场景(如产品结构、点、线、面等)进行交互的基础。

2. 核心功能与方法

2.1 创建实例

通过构造函数创建代理实例。建议为其指定一个具有明确意义的唯一标识符。

CATPathElementAgent* _pSelectObjectEleAgent = new CATPathElementAgent("SelectNeedMoveProduct");

2.2 设置选择过滤器

这是控制代理能选择何种对象的关键,主要有两种方式:

a) 按几何维度过滤

在构造函数中直接指定要选择的几何元素的维度,这是一种快速过滤方法。

// 选择面(二维几何)
_MyAgentFace = new CATPathElementAgent("Surface", CATIMfBiDimResult::ClassName(), CATDlgEngRepeat);

常见的维度接口:

  • CATIMfZeroDimResult: 点(0维)

  • CATIMfMonoDimResult: 线(1维)

  • CATIMfBiDimResult: 面(2维)

  • CATIMfTriDimResult: 体(3维)

  • CATIMfInfiniteResult: 无限元素(如平面)

b) 按特定接口类型过滤

通过 AddElementTypeSetElementType方法,指定元素必须实现的接口类型。这种方式更精确,可以灵活组合。

  • 选择特定几何类型

    _pSelectObjectEleAgent->AddElementType(CATIGSMPoint::ClassName()); // 点
    _pSelectObjectEleAgent->AddElementType(CATIGSMLine::ClassName());  // 线
    _pSelectObjectEleAgent->AddElementType(CATIGSMPlane::ClassName()); // 平面
    
  • 选择产品对象

    _pSelectObjectEleAgent->SetElementType(CATIProduct::ClassId()); // 产品
    
  • 允许多种类型:可以多次调用 AddElementType来允许选择多种不同类型的对象。

    _pSelectObjectEleAgent->AddElementType(CATIProduct::ClassId());
    _pSelectObjectEleAgent->AddElementType(CATISurface::ClassName());
    

2.3 设置代理行为

通过 SetBehavior方法组合不同的标志位,定义代理的交互反馈模式。

_pSelectObjectEleAgent->SetBehavior(
    CATDlgEngRepeat |          // 允许重复选择,无需取消后重新激活命令
    CATDlgEngWithPSOHSO |       // 鼠标悬停时高亮可选对象(PSO),选中后保持高亮(HSO)
    CATDlgEngWithPrevaluation | // 进行预评估,确保选择的有效性
    CATDlgEngWithCSO |          // 在选择时创建临时图形(CSO),例如绘制预览线
    CATDlgEngWithUndo           // 支持撤销操作
);

2.4 获取选择结果

这是两个关键方法的区别,对于后续操作至关重要:

方法 返回值 获取内容 主要用途
GetElementValue() CATBaseUnknown* 用户直接选择的单个对象本身 直接操作该对象(如获取几何数据、属性)
GetValue() CATPathElement* 从文档根节点到所选对象的完整结构路径 需要了解对象在产品结构中的上下文关系
  • 使用 GetElementValue(最常见):

    CATBaseUnknown* pSelectedObject = _pSelectObjectEleAgent->GetElementValue();
    if (pSelectedObject != NULL) {
        // 查询具体接口,如 CATIProduct
        CATIProduct* pProduct = NULL;
        HRESULT hr = pSelectedObject->QueryInterface(IID_CATIProduct, (void**)&pProduct);
        if (SUCCEEDED(hr)) {
            // 使用 pProduct 进行操作...
            pProduct->Release(); // 务必释放!
        }
    }
    
  • 使用 GetValue(需要路径信息时):

    CATPathElement* pPath = _pSelectObjectEleAgent->GetValue();
    if (pPath != NULL) {
        // 操作路径...
        pPath->Release(); // 务必释放!
    }
    

3. 集成到状态机命令

CATIA 的交互命令通常基于状态机模型。CATPathElementAgent需要被集成到状态机中才能工作。

  1. 创建或获取状态
CATDialogState *pInitialState = GetInitialState("请选择产品");
  1. 将代理添加到状态:一个状态可以包含多个代理。
pInitialState->AddDialogAgent(_pSelectObjectEleAgent);
  1. 添加状态转换:定义当代理被成功赋值(用户做出有效选择)后,状态机如何跳转以及执行什么动作。
AddTransition(
   pInitialState,      // 来源状态
   pNextState,         // 目标状态(或 NULL 结束命令)
   IsOutputSetCondition(_pSelectObjectEleAgent), // 触发条件:代理输出被设置
   Action((ActionMethod) &MyCmd::ActionAfterSelection) // 触发的回调函数
);

4. 完整代码流程示例

下面的代码片段展示了在一个状态命令中集成 CATPathElementAgent的典型流程:

// 1. 创建代理
_pSelectAgent = new CATPathElementAgent("MySelectionAgent");
if (_pSelectAgent != NULL) {
    // 2. 设置过滤器(例如,只选产品)
    _pSelectAgent->AddElementType(CATIProduct::ClassId());
    // 3. 设置行为
    _pSelectAgent->SetBehavior(CATDlgEngRepeat | CATDlgEngWithPSOHSO);
}

// 4. 集成到状态机
CATDialogState *pState = GetInitialState("InitialState");
pState->AddDialogAgent(_pSelectAgent);

// 5. 定义状态转换
AddTransition(pState, NULL,
              IsOutputSetCondition(_pSelectAgent),
              Action((ActionMethod) &MyCommand::OnSelectionMade));

// ... 在回调函数中处理选择结果
void MyCommand::OnSelectionMade() {
    CATBaseUnknown* pSelected = _pSelectAgent->GetElementValue();
    if (pSelected != NULL) {
        // ... 处理所选对象
    }
}

5. 进阶用法与最佳实践

5.1 创建通用选择函数

为了提高代码复用性,可以创建一个通用的函数来初始化和配置代理。

void MyStateCommand::SetupSelectionAgent(CATPathElementAgent*& agent, 
                                        const char* agentId, 
                                        IID iFilterInterface,
                                        CATDialogState* state,
                                        ActionMethod callback) {
    agent = new CATPathElementAgent(agentId);
    agent->AddElementType(iFilterInterface);
    agent->SetBehavior(CATDlgEngRepeat | CATDlgEngWithPSOHSO);
    state->AddDialogAgent(agent);
    AddTransition(state, state, 
                  IsOutputSetCondition(agent), 
                  Action((ActionMethod) callback));
}

5.2 内存管理

  • 对象释放:通过 GetElementValueGetValue获得的接口指针,在使用完毕后必须调用 Release()方法释放。

  • 代理销毁:在命令的析构函数中,应调用代理的 RequestDelayedDestruction()方法以确保其被安全销毁。

5.3 错误处理

在选择操作前后,应添加适当的检查,例如检查获取的指针是否为 NULL,以及 QueryInterface是否成功。

希望这份详细的文档能帮助你全面掌握 CATPathElementAgent的使用。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容