Creating a Command with Options in the "Tools Palette" Toolbar-如何实现 CATIAfrCmdPaletteOptions 并完成选项定义

摘要
本文介绍状态命令如何在命令运行期间,向专用工具栏中添加各类选项。该专用工具栏称作工具选项板,其中的选项本质为命令头。文中同时说明选项的定义方法与使用方式。
  • 本实例学习要点
  • CAADegCreateBoxCmd 示例程序
    • CAADegCreateBoxCmd 功能说明  
    • CAADegCreateBoxCmd 启动方法  
    • CAADegCreateBoxCmd 源码路径  
  • 分步实现流程
  • 小结
  • 参考资料

通过本示例你将学到的内容
工具选项板是一类特殊工具栏,在以下两种场景下会动态刷新:

  1.     切换进入工作台时:工作台实现了CATIAfrPaletteOptions接口。
    工作台激活后,选项板自动载入命令头;工作台退出后,对应命令头从工具栏移除。
  2.     运行独占 / 共享型命令时:命令实现CATIAfrCmdPaletteOptions接口。
    命令激活时可添加命令头,取消命令后自动移除。针对状态命令,还能为某一特定状态单独挂载命令头,退出该状态即自动清理;整段命令结束后,所有关联选项按钮失效。

本示例用于演示CATIAfrCmdPaletteOptions接口的实现方法,以及借助CATAfrCheckHeaderAccessor类创建选项的开发流程。

CAADegCreateBoxCmd 示例

CAADegCreateBoxCmd 是 CAADialogEngine.edu 开发框架下的示例程序,用于演示 ApplicationFrame 框架的功能特性。
 

CAADegCreateBoxCmd 示例功能说明

CAADegCreateBoxCmd 是用于创建立方体的状态命令,该命令注册在 CAAGeometry 文档对应的「CAA V5:几何创建」工作台中。
立方体由宽 (W)、深 (D)、高 (H) 三个尺寸参数定义,CAADegCreateBoxCmd 命令支持用户创建三种不同类型的立方体:
图 1 - 左侧视图

图片

 图 1 - 中间视图

图片

 图 1 - 右侧视图

图片

 

  • P1 为首个拾取点,用作基准参考点。
  • P2 是第二个拾取点,与 P1 共同确定立方体的宽度。
用户此时结束命令,生成正方体(见图 1 左)。
  •  继续指定第三个点 P3,P2 与 P3 间距定义深度。
用户在此结束命令,生成深度与高度相等的平行六面体(见图 1 中)。
  •  再指定第四个点 P4,P3 与 P4 间距定义高度。
长宽高三参数各不相同,生成普通平行六面体(见图 1 右)。
用户可通过工具选项板内的选项切换三种长方体创建模式,该选项板就是「工具面板」工具栏。下图展示了本状态命令所添加的工具栏及图标:

图片

 圆圈圈出的三个图标可供用户选择创建:

  • 正方体:

    图片

  • 深度与高度相等的平行六面体:

    图片

  • 普通长宽高互不相等的平行六面体:

    图片

这三个图标不会始终显示在选项板中,显示状态由当前交互步骤决定:
  1. 拾取 P1 点后,三个图标全部展示;
  2. 选中 P2 点时,第一个图标立即从选项板隐藏,用户无法再创建正方体,仅剩余后两个图标可用,只能生成平行六面体;
  3. 指定 P3 点后,全部图标隐藏,用户只能创建长宽高各不相同的常规平行六面体。

图片在命令运行周期内已存在。

  • 图标高亮:长方体基准原点为模型坐标系原点 (0,0,0)
  • 图标常态显示:长方体基准原点为首个拾取点

 CAADegCreateBoxCmd 是一款状态交互命令,依据下述 UML 状态图在三维空间创建立方体。

图 3

图片

 

CAADegCreateBoxCmd 示例启动方法

如需了解本示例的详细启动步骤,请查阅《CAAGeometry 示例》文档中标题为CAAGeometry 示例启动方式的章节。
之后在执行 mkrun 命令的终端窗口中,命令行不要输入模块名,替换输入 CNEXT。CATIA 程序启动就绪后,按如下步骤操作:
  • 在【文件】菜单栏中点击【新建】
  • 在弹出的新建对话框选中【CAAGeometry】,点击【确定】
  • 点击【点】命令,创建若干参考点
  • 点击【长方体】命令    
    • 拾取第一个点
    • 拾取第二个点
  • 点击【长方体】命令
    • 点击图片(图标处于高亮选中状态)
    • 拾取第一个点
    • 拾取第二个点
  • 点击【长方体】
    • 拾取一个点  
    • 点击图片
    • 拾取第二个点 

    • 点击图片(图标不再高亮显示)
    • 指定一点定义深度(深度等同于高度)

  • 点击长方体命令
    • 拾取第一个点
    • 拾取第二个点  
    • 点击图片
    • 指定一点定义深度

    • 指定一点定义高度

CAADegCreateBoxCmd 代码位置

CAADegCreateBoxCmd 示例由多个类组成,这些类位于 CAADialogEngine.edu 框架CAADegGeoCommands.m 模块中:
  • CAADegCreateBoxCmd 类

该类为状态命令类,实现了 CATIAfrCmdPaletteOptions 接口,供终端用户创建立方体。
  • CAADegBoxPaletteChoiceCmd 类

三个图标图片这三个图标对应三种复选标题。一个复选标题会分别针对勾选状态与取消勾选状态各启动一个命令标题,这两个命令标题均用于启动 CAADegBoxPaletteChoiceCmd 命令。

  • CAADegBoxCreationChoiceNotification 类

该通知类由前述 CATCommand 命令发送,用来告知 CAADegCreateBoxCmd 类某个复选按钮已被点击;通知内携带被选中按钮的编号。
  •  Windows 系统路径:安装根目录 \CAADialogEngine.edu\CAADegGeoCommands.m
  • Unix 系统路径:安装根目录 / CAADialogEngine.edu/CAADegGeoCommands.m/
其中安装根目录指 CAA 安装光盘的安装目录。

分步说明

CAADegCreateBoxCmd 分为四个逻辑实现步骤:
  1. 定义 CAADegCreateBoxCmd 类
  2. 定义选型参数
  3. 实现 CATIAfrCmdPaletteOptions 接口
  4. 调用选型参数

定义 CAADegCreateBoxCmd 类

CAADegCreateBoxCmd 类属于状态交互命令
  1. 编写头文件:CAADegCreateBoxCmd.h
  2. 编写源文件:CAADegCreateBoxCmd.cpp
  1. 编写 CAADegCreateBoxCmd.h 头文件

...

// 引入DialogEngine框架头文件
#include "CATStateCommand.h"   
...
// CAADegCreateBoxCmd类继承自状态命令基类CATStateCommand
class CAADegCreateBoxCmd : public CATStateCommand
{
  // 声明命令资源映射
  CmdDeclareResource(CAADegCreateBoxCmd,CATStateCommand);
  // CAA类声明宏
  CATDeclareClass ;

  public :
    // 构造函数
    CAADegCreateBoxCmd();
    // 虚析构函数
    virtual ~CAADegCreateBoxCmd();  
    ...
    // 获取面板状态对应的命令头列表
    virtual CATLISTP(CATCommandHeader) GetPaletteStateOptions() ;
    // 获取面板常规选型命令头列表
    virtual CATLISTP(CATCommandHeader) GetPaletteOptions() ;

  private :
    ...
    // 构建命令状态机流程图(交互拾取逻辑)
    virtual void BuildGraph() ;
    // 校验面板选型按钮
    CATBoolean  CheckChoice(void * iChoice);
    // 根据拾取坐标生成长方体
    CATBoolean  CreateBox(void * iDummy);
    ...
    // 面板选型变更的消息回调函数
    void BoxCreationChoiceChange (CATCommand        * iPublisher,
                  CATNotification      * iNotification,
                  CATCommandClientData   iUsefulData);

  private :
   ...
    // 当前选中的长方体创建方式编号
    int                            _CurrentBoxCreationTypeChoice ;

    // 二点创盒复选框命令头访问器
    CATAfrCheckHeaderAccessor    * _pTwoPointsCmdHdr ;
    // 三点创盒复选框命令头访问器
    CATAfrCheckHeaderAccessor    * _pThreePointsCmdHdr ;
    // 四点创盒复选框命令头访问器
    CATAfrCheckHeaderAccessor    * _pFourPointsCmdHdr ;
    // 原点模式复选框命令头访问器
    CATAfrCheckHeaderAccessor    * _pOriginCheckHdr ;
};

...

本类继承自CATStateCommand类,包含以下内容:

  • 两类宏定义
  1. CmdDeclareResource:该宏用于为状态命令绑定资源文件。
  2. CATDeclareClass:所有组件类都必须添加此宏。
  • 成员函数(部分详解)
  1. GetPaletteStateOptions、GetPaletteOptionsCATIAfrCmdPaletteOptions接口的实现函数。
  2. BuildGraph:用于实现命令状态流程图的核心函数。
  3. CheckChoice:条件判定函数,用来区分三种长方体创建方式,详见「选型应用 - 定义长方体创建方式」章节。
  4. CreateBox:动作函数,在模型中生成长方体实体,详见「选型应用 - 定位新建长方体」章节。
  5. BoxCreationChoiceChange:回调函数,勾选三种创建方式任一图标时,刷新面板图标状态,详见「三个图标互斥管理」章节。

以及以下成员变量(数据)

  • _CurrentBoxCreationTypeChoice:用于保存当前激活的复选按钮索引值的变量,取值范围为 1 到 3图片
  • _pTwoPointsCmdHdr、_pThreePointsCmdHdr、_pFourPointsCmdHdr:三个指针,用于访问对应长方体创建方式选型的命令头。

  • _pOriginCheckHdr:指针,用于访问控制长方体原点设置选型的复选命令头。

该类还包含其他成员函数与成员变量,更多细节请参考源码。

  1. 定义 CAADegCreateBoxCmd.cpp 源文件

源文件开头内容如下:
...
//引入命令头相关头文件
#include <CATCommandHeader.h>
//声明命令头资源
MacDeclareHeader(CAADegCreateBoxPaletteHeader) ;

//CAA类实现宏:CAADegCreateBoxCmd为实现类,父类是CATStateCommand
CATImplementClass(CAADegCreateBoxCmd, Implementation,CATStateCommand, CATNull);

...

//动态创建类所需头文件
#include "CATCreateExternalObject.h"
//注册类的动态创建工厂
CATCreateClass(CAADegCreateBoxCmd);
...
  • MacDeclareHeader宏用于生成CAADegCreateBoxPaletteHeader类,该类继承自CATCommandHeader,相关说明见「定义选型」章节。
  • CATImplementClass宏通过Implementation关键字声明CAADegCreateBoxCmd是组件主类,并且以 OM 机制继承于CATStateCommand
  • CATCreateClass宏让命令头可以通过命令名称动态实例化该命令对象。

定义面板选型

选型是挂载在命令面板工具栏上的命令头实例,在 CAADegCreateBoxCmd 类的构造函数中完成各命令头的定义。关于命令头创建的细节与注意事项,可参阅技术文档《命令头》。
本状态命令创建并使用两类选型。
  • 设定长方体创建方式的选型

该选型包含三个命令头实例:CAADegTwoPointsBoxHdr、CAADegThreePointsBoxHdr、CAADegFourPointsBoxHdr。文档仅对第一个命令头的创建过程进行说明,剩余两个均采用相同创建逻辑。
三个图标互斥控制章节中,会介绍如何借助这三个命令头模拟单选按钮效果。
  • 新长方体定位选型

该选型仅用到一个复选命令头实例:CAADegOriginBoxHdr。
 
上述两类选型所用的命令头均为复选命令头。由于复选命令头是未对外暴露的内部类,CATAfrCheckHeaderAccessor类对它的创建与访问做了封装。该访问器的构造函数会先检索当前编辑器绑定的命令头列表,仅在目标复选命令头不存在时才新建实例。因此无论实例化多少个CATAfrCheckHeaderAccessor对象,其内部接口最终都指向当前编辑器里唯一的复选命令头实体。
补充说明:参考示例工程CAAAfrViewerFeedbackHdr,该用例演示了在插件环境中如何使用CATAfrCheckHeaderAccessor类。
 
  1. 定义长方体创建方式的选型
...
 CATCommandHeader * pCmd = NULL ;
  // 根据名称获取已存在的命令头
  ::CATAfrGetCommandHeader("CAADegTwoPointsBoxHdr",pCmd);
 
  // 创建复选命令头访问器,绑定两点创盒命令头
  _pTwoPointsCmdHdr = new CATAfrCheckHeaderAccessor("CAADegTwoPointsBoxHdr");
 
  // 若命令头不存在,则新建勾选、取消勾选两套命令头资源
  if ( NULL == pCmd )
  {
     // 生成【勾选状态】命令头,绑定触发命令CAADegBoxPaletteChoiceCmd,附加参数1
     new CAADegCreateBoxPaletteHeader
                          ("CAADegTwoPointsBoxCheckHdr",
                          "CAADegGeoCommands",
                          "CAADegBoxPaletteChoiceCmd", (void *) 1);

     // 生成【取消勾选状态】命令头,绑定同一触发命令,附加参数1
     new CAADegCreateBoxPaletteHeader
                          ("CAADegTwoPointsBoxUncheckHdr",
                          "CAADegGeoCommands",
                          "CAADegBoxPaletteChoiceCmd", (void *) 1);
 
     // 为访问器绑定勾选、取消勾选对应的命令头
     _pTwoPointsCmdHdr->SetCheckCommand("CAADegTwoPointsBoxCheckHdr");
     _pTwoPointsCmdHdr->SetUncheckCommand("CAADegTwoPointsBoxUncheckHdr");

     // 关联图标、文字等资源文件
     _pTwoPointsCmdHdr->SetResourceFile("CAADegCreateBoxPaletteHeader");
     
     // 初始设置为勾选状态,不触发勾选回调
     _pTwoPointsCmdHdr->SetCheck(TRUE,FALSE);
  }
...
_pTwoPointsCmdHdr 是新建的CATAfrCheckHeaderAccessor类型指针。该指针将在状态命令内用于管控三个图标之间的互斥逻辑,详情参见「三个图标互斥管理」章节。
但在实例化CATAfrCheckHeaderAccessor对象前,需要调用全局函数CATAfrGetCommandHeader获取复选命令头指针。若当前编辑环境下该复选命令头从未创建,该函数返回空指针。此种场景下,在构造完CATAfrCheckHeaderAccessor之后需要完成以下操作:
  • 分别创建勾选、取消勾选两种状态对应的命令头实例
    CAADegCreateBoxPaletteHeader类由MacDeclareHeader宏自动生成,详见「定义 CAADegCreateBoxCmd.cpp」章节。CAADegTwoPointsBoxCheckHdrCAADegTwoPointsBoxUncheckHdr这两个命令头实例,会调用位于CAADegGeoCommands动态库中的CAADegBoxPaletteChoiceCmd命令;末尾入参1是传给该命令的自定义参数,另外两种创盒方式对应的复选命令头会使用不同参数值,参考「三个图标互斥管理」章节。

CAADegTwoPointsBoxCheckHdrCAADegTwoPointsBoxUncheckHdr属于无界面展示的命令头,不会在菜单栏、工具栏、右键菜单上显示,因此二者没有配置图标、提示文本与简短帮助信息。

  • 通过 SetCheckCommand 绑定勾选状态对应的命令头 CAADegTwoPointsBoxCheckHdr
    复选框被勾选时,就会触发执行CAADegTwoPointsBoxCheckHdr绑定的命令。
  • 通过 SetUncheckCommand 绑定取消勾选状态对应的命令头 CAADegTwoPointsBoxUncheckHdr
    复选框取消勾选时,就会触发执行CAADegTwoPointsBoxUncheckHdr绑定的命令。
  • 为 CAADegTwoPointsBoxHdr 命令头关联资源文件
    CAADialogEngine.edu框架目录下的CNext/resources/msgcatalog文件夹中,可以找到两个资源文件:
    • CAADegCreateBoxPaletteHeader.CATNls:存放提示信息、悬浮短帮助等文本资源
    • CAADegCreateBoxPaletteHeader.CATRsc:存放图标名称配置
  • 调用 SetCheck 方法初始化复选框默认状态
    第一个入参TRUE代表该复选框默认勾选;第二个入参FALSE表示初始化时不发送通知、不刷新界面。剩余另外两个复选框初始化时第一个入参填FALSE(默认未勾选)。
    补充说明:该初始化逻辑仅在命令头首次创建时执行。后续再次启动本命令时,命令头已存在并保留上次勾选状态,不会重复初始化。
  1. 新建长方体定位选型

...

 pCmd = NULL ;
  // 根据名称获取原点选项对应的命令头
  ::CATAfrGetCommandHeader("CAADegOriginBoxHdr",pCmd);
 
  // 创建原点复选框访问器
  _pOriginCheckHdr = new CATAfrCheckHeaderAccessor("CAADegOriginBoxHdr");
 
  // 命令头首次创建时绑定资源文件
  if ( NULL == pCmd)
  {  
      _pOriginCheckHdr->SetResourceFile("CAADegCreateBoxCmd");
  }

...

_pOriginCheckHdr 是新建的CATAfrCheckHeaderAccessor类型指针,该指针会在CreateBox函数中使用,详见「选型应用」章节。
在创建CATAfrCheckHeaderAccessor实例前,需调用全局函数CATAfrGetCommandHeader获取复选命令头指针。若当前编辑环境中尚未创建该复选命令头,函数返回空值。此种情况下,构造完CATAfrCheckHeaderAccessor后仅需指定资源文件名即可。在CAADialogEngine.edu框架的CNext/resources/msgcatalog目录下存在两个资源文件:CAADegCreateBoxCmd.CATNlsCAADegCreateBoxCmd.CATRsc;前者存放帮助说明、悬浮短提示等文本信息,后者配置图标名称。
该复选命令头点击后不会触发任何命令,仅用于保存自身勾选状态。
 
  1. 三个图标之间的互斥逻辑处理

点击任意一个图标时图片随即触发执行CAADegBoxPaletteChoiceCmd命令,该命令发送消息通知CAADegCreateBoxCmd状态命令。

...
// 构造函数:接收外部传入的参数(长方体创建模式标识)
CAADegBoxPaletteChoiceCmd::CAADegBoxPaletteChoiceCmd(void *iArgument):
                   CATCommand(NULL,"CAADegBoxPaletteChoiceCmd")
{
   // 将无类型指针参数转换为整型(1=两点创盒、2=三点创盒、3=四点创盒)
   int value = (int) iArgument;
 
   // 定义创盒选择通知对象
   CAADegBoxCreationChoiceNotification * pNotification = NULL;
   // 创建通知实例
   pNotification = new CAADegBoxCreationChoiceNotification();
   // 将选中的创盒模式存入通知
   pNotification->SetChoice(value);
   
   // 向父命令(CAADegCreateBoxCmd)发送选择通知
   SendNotification(GetFather(), pNotification);

   // 指针置空,避免野指针
   pNotification = NULL;

   // 请求延迟销毁当前命令(CAA标准命令生命周期管理)
   RequestDelayedDestruction();
}
...

 

  • iArgumentCATCommandHeader构造函数传入的参数,通知对象会保存该数值并传递给CAADegCreateBoxCmd命令,详情参见「定义长方体创建方式的选型」小节。
  • 通知被发送至CAADegBoxPaletteChoiceCmd命令的父对象;该父对象为空,也就是当前命令选择器。和它共用同一个父对象的主命令CAADegCreateBoxCmd,会接收这条通知。
  • 需要注意:通知发送后并没有手动释放pNotification。该通知创建时启用了CATNotificationDeleteOn标识,代表通知会在下一个事务结束时自动销毁,即收发双方的命令交互完成后即刻回收。
  • 最后调用RequestDelayedDestruction(请求延迟析构)。在命令构造函数内调用该函数必须遵守三条强制规范:
  1. 该类不会被任何类继承;
  2. 构造完毕后不会再调用本类的任何成员方法(一般不对外暴露公有接口来保证);
  3. RequestDelayedDestruction必须是构造函数的最后一行代码。

CAADegCreateBoxCmd命令的BuildGraph方法中,已声明一个回调方法,用于在CAADegBoxCreationChoiceNotification类通知被发送时接收通知。

...
AddAnalyseNotificationCB(NULL, "CAADegBoxCreationChoiceNotification",
                (CATCommandMethod)&CAADegCreateBoxCmd::BoxCreationChoiceChange,
                            NULL);

...

  • 第一个 NULL:(通知发送源,空代表监听全部发送方)
  • CAADegBoxCreationChoiceNotification:通知类名
  • BoxCreationChoiceChange:回调函数名
  • 末尾 NULL:回调函数无自定义入参

BoxCreationChoiceChange方法将另外两个复选按钮置为取消勾选状态。

...

// 长方体创建方式选择变更回调函数
void CAADegCreateBoxCmd::BoxCreationChoiceChange (CATCommand  * iPublisher,
                                    CATNotification      * iNotification,
                                    CATCommandClientData   iUsefulData)
{
    ...
    // 将通用通知对象转换为自定义的创盒选择通知类型
    CAADegBoxCreationChoiceNotification * pNotif = NULL;
    pNotif = (CAADegBoxCreationChoiceNotification *)iNotification;
    
    int value = 0;
    // 从通知中获取用户选择的创盒模式编号
    HRESULT rc = pNotif->GetChoice(value);
    ...
    {
        // 选择【两点创盒】,取消另外两个选项的勾选状态
        if (value == 1)
        {
            _pThreePointsCmdHdr->SetCheck(FALSE, FALSE);
            _pFourPointsCmdHdr->SetCheck(FALSE, FALSE);
        }
        // 选择【三点创盒】,取消另外两个选项的勾选状态
        if (value == 2)
        {
            _pTwoPointsCmdHdr->SetCheck(FALSE, FALSE);
            _pFourPointsCmdHdr->SetCheck(FALSE, FALSE);
        }
        // 选择【四点创盒】,取消另外两个选项的勾选状态
        if (value == 3)
        {
            _pTwoPointsCmdHdr->SetCheck(FALSE, FALSE);
            _pThreePointsCmdHdr->SetCheck(FALSE, FALSE);
        }
        // 保存当前选中的创盒模式
        _CurrentBoxCreationTypeChoice = value;
...

GetChoice用于获取最后被激活的复选按钮标识。成员变量_CurrentBoxCreationTypeChoice保存当前启用的创建选项,其用法详见「选型使用 —— 定义长方体创建方式」小节。

实现 CATIAfrCmdPaletteOptions 接口

CAADegCreateBoxCmd类通过TIE_CATIAfrCmdPaletteOptions宏声明实现CATIAfrCmdPaletteOptions接口。
...
#include "TIE_CATIAfrCmdPaletteOptions.h"
TIE_CATIAfrCmdPaletteOptions(CAADegCreateBoxCmd);
...
该接口包含两个方法:
  • GetPaletteOptions:获取面板选型参数
  • GetPaletteStateOptions:获取面板选型状态

 

  1. 获取面板选项
 该方法在命令被激活时触发调用,正因如此,此命令必须设为独占型或共享型命令 [9]。
在本示例中,需要添加至命令面板的选项,是由对应图标所代表的命令头。图片
...
// 获取面板可配置选项列表
CATLISTP(CATCommandHeader) CAADegCreateBoxCmd::GetPaletteOptions()
{
   // 定义命令头列表,用于存放面板选项
   CATLISTP(CATCommandHeader) PaletteOptions;

   CATCommandHeader * pCmd = NULL ;
   // 根据名称获取【原点定位】复选框对应的命令头
   ::CATAfrGetCommandHeader("CAADegOriginBoxHdr",pCmd);

   if ( NULL != pCmd )
   {
       // 将该命令头添加进面板选项集合
       PaletteOptions.Append(pCmd);
       pCmd = NULL ;
   }
   // 返回面板选项集合,CATIA框架据此在命令面板生成对应勾选控件
   return PaletteOptions ;
}
...
PaletteOptions是待返回的命令头实例指针列表。全局函数CATAfrGetCommandHeader可依据命令头名称获取其实例指针,函数首个入参即为命令头名称,该命令头由当前编辑环境对应的链表统一管理 [6]。
CAADegOriginBoxHdr是复选类型命令头,用于控制新建长方体是否以模型坐标原点为基准创建。有关该命令头的创建细节,请参阅「选型定义」章节。
  1. 获取面板状态选项

该方法在状态命令切换至任意状态时都会被调用。多数场景下,本方法作用是获取当前状态名,再依据状态名称,把对应命令头实例指针添加到返回列表中。
...
CATLISTP(CATCommandHeader) CAADegCreateBoxCmd::GetPaletteStateOptions()
{
   // 定义状态专属面板选项列表
   CATLISTP(CATCommandHeader) PaletteStateOptions;

   // 获取当前所处交互状态
   CATDialogState * pCurrentState = GetCurrentState();
   if ( NULL != pCurrentState )
   {
      // 读取状态资源标识名称
      CATString StateName = pCurrentState->GetResourceID();
     
      // 当前为【拾取宽度点】状态
      if ( !strcmp("stWidthPointId",StateName) )
      {
         // stWidthPointId 状态处理分支
      }else if ( !strcmp("stDepthPointId" ,StateName) )
      {
         // stDepthPointId 状态处理分支(源码未展开细节)
      }
   }
   return PaletteStateOptions ;
}
...
GetCurrentState:获取当前交互状态指针;
GetResourceID:获取状态的资源 ID,该 ID 是创建状态AddDialogState、初始状态GetInitialState接口的唯一入参。
BuildGraph 方法中,创建了四个状态:
...
// 获取初始状态:角点
CATDialogState *stCornerPoint = GetInitialState("stCornerPointId");

// 添加对话框状态:宽度点
CATDialogState *stWidthPoint = AddDialogState("stWidthPointId");

// 添加对话框状态:深度点
CATDialogState *stDepthPoint = AddDialogState("stDepthPointId");

// 添加对话框状态:高度点
CATDialogState *stHeightPoint = AddDialogState("stHeightPointId");
...
stCornerPoint为拾取 P1 的交互状态,stWidthPoint为拾取 P2 的交互状态,stDepthPoint用于指定 P3,stHeightPoint用于指定 P4。四个点位说明详见图 1,UML 状态图参见图 3。进入stWidthPoint(拾取宽度点)状态时,命令面板载入全部三个图标选项图片 ;切换至stDepthPoint(拾取深度点)状态后,仅保留后两个图标选项。图片

 以下是处理标识为 stWidthPointId 状态的代码:

...
          CATCommandHeader * pCmd = NULL ;
          // 获取两点创盒对应的命令头
          ::CATAfrGetCommandHeader("CAADegTwoPointsBoxHdr",pCmd);
          if ( NULL != pCmd )
          {
             // 添加到状态面板选项列表
             PaletteStateOptions.Append(pCmd);
             pCmd = NULL ;
          }

          // 获取三点创盒对应的命令头
          ::CATAfrGetCommandHeader("CAADegThreePointsBoxHdr",pCmd);
          if ( NULL != pCmd )
          {
             PaletteStateOptions.Append(pCmd);
             pCmd = NULL ;
          }

          // 获取四点创盒对应的命令头
          ::CATAfrGetCommandHeader("CAADegFourPointsBoxHdr",pCmd);
          if ( NULL != pCmd )
          {
             PaletteStateOptions.Append(pCmd);
             pCmd = NULL ;
          }
...

前文定义的PaletteStateOptions是存储命令头实例指针的链表。全局函数CATAfrGetCommandHeader能够依据命令头名称获取其实例指针,函数第一个入参即为命令头名称,该命令头由当前编辑环境对应的管理链表维护 [8]。
处于本状态时,全部长方体创建方式均可选用。CAADegTwoPointsBoxHdrCAADegThreePointsBoxHdrCAADegFourPointsBoxHdr这三个命令头均为复选类型,分别用来设定采用两点、三点、四点方式生成新长方体。各类命令头的创建细节请查阅「选型定义」章节。

选型使用

该状态命令定义了两类选型:
  1. 控制新建长方体的定位方式
  2. 定义长方体的创建方式
两类选型在命令的不同逻辑环节中生效使用。
  1. 设置长方体的生成基点
CreateBox 是命令抵达最终交互状态时执行的动作函数,该函数会在当前 CAA 几何文档中新建一个CAASysCuboid长方体元素 [1]。长方体生成完成后(生成逻辑本文不赘述),需要指定长方体的坐标原点。
...
      CATMathPoint CornerPoint ;    // 长方体角点
      CATMathPoint BoxOrigin ;      // 长方体基准原点

      FindBoxCornerPoint(CornerPoint);  // 获取拾取的长方体角点

      // 原点勾选控件不存在 或 勾选框未勾选时
      if ( NULL == _pOriginCheckHdr )
      {
          BoxOrigin = CornerPoint ;
      } else if ( FALSE == _pOriginCheckHdr->IsChecked() )
      {
         BoxOrigin = CornerPoint ;
      }
...
FindBoxCornerPoint为本类内部方法,用于获取首个拾取点 P1 的坐标(见图 1)。
_pOriginCheckHdrCATAfrCheckHeaderAccessor类型指针,关联复选命令头CAADegOriginBoxHdr,详情参阅「选型定义」章节。若该复选框处于勾选(高亮)状态,长方体以首拾取点为创建原点;反之则采用 CATMathPoint 默认坐标 (0,0,0)。
  1. 定义长方体创建方式
该选型在CheckChoice条件判断函数中使用。状态图(图 3)中标注星号的状态跳转,依靠此函数判定是否允许跳转
以下为绑定CheckChoice条件函数的状态跳转代码:
...
// 从宽度点状态→深度点状态的跳转
CATDialogTransition *pState2Transition1= AddTransition
  (
     stWidthPoint,
     stDepthPoint,
     // 条件:宽度点拾取完成 + CheckChoice传入参数4校验通过
     AndCondition(IsOutputSetCondition(_daPathElementWidthPoint),
                  Condition((ConditionMethod) & CAADegCreateBoxCmd::CheckChoice,(void*)4)),
     // 跳转执行动作:保存宽度数据
     Action((ActionMethod) & CAADegCreateBoxCmd::AcquisitionWidth)
  ) ;

// 从宽度点直接结束、生成实体(两点创盒,参数1)
CATDialogTransition *pState2Transition3 = AddTransition
  (
     stWidthPoint,
     NULL,
     AndCondition(IsOutputSetCondition(_daPathElementWidthPoint),
                  Condition((ConditionMethod) & CAADegCreateBoxCmd::CheckChoice,(void*)1)),
     Action((ActionMethod) & CAADegCreateBoxCmd::CreateBox)
  ) ;

// 深度点→高度点(四点创盒,参数3)
CATDialogTransition *pState3Transition1= AddTransition
  (
     stDepthPoint,
     stHeightPoint,
     AndCondition(IsOutputSetCondition(_daIndicationDepthPoint),
                  Condition((ConditionMethod) & CAADegCreateBoxCmd::CheckChoice,(void*)3)),
     Action((ActionMethod) & CAADegCreateBoxCmd::AcquisitionDepth)
  ) ;

// 深度点直接结束、生成实体(三点创盒,参数2)
CATDialogTransition *pState3Transition3 = AddTransition
  (
     stDepthPoint,
     NULL,
     AndCondition(IsOutputSetCondition(_daIndicationDepthPoint),
                  Condition((ConditionMethod) & CAADegCreateBoxCmd::CheckChoice,(void*)2)),
     Action((ActionMethod) & CAADegCreateBoxCmd::CreateBox)
  ) ;
...
  • 拾取到 P2 点时即触发 pState2Transition1 跳转(详见图 1)。-并且任一选项处于高亮勾选状态图片
  • 拾取 P2 点后即可触发pState2Transition3跳转(详见图 1)。 -并且该选项处于高亮勾选状态。图片

  •   拾取指定 P3 点位后触发pState3Transition1跳转(详见图 1)。-并且该选项处于高亮勾选状态。图片

  •   拾取指定 P3 点后触发pState3Transition3跳转(详见图 1)。-并且该选项处于高亮勾选状态。图片

 

CheckChoice方法会结合传入的状态标识参数(AddTransition 的最后一个入参)当前面板已勾选的复选按钮做条件判定。

...

// 状态跳转条件校验函数
CATBoolean CAADegCreateBoxCmd::CheckChoice(void *iChoice)
{
    CATBoolean Test = FALSE ;    // 跳转许可标记,默认不允许跳转
    int Choice = (int) iChoice ;// 入参转为整型,代表当前跳转分支编号
    
    // 分支编号=4,且当前创建模式大于1时,允许跳转
    if ( ( 4 == Choice  ) && ( _CurrentBoxCreationTypeChoice > 1 ) )
    {
        Test = TRUE;
    }
    // 选中的创盒模式和跳转分支编号一致,允许跳转
    else if ( _CurrentBoxCreationTypeChoice == Choice )
    {
       Test = TRUE;
    }
    return Test ;
}

...

_CurrentBoxCreationTypeChoice是成员变量,用于保存当前启用的复选选项。该变量在构造函数中初始化,并在BoxCreationChoiceChange方法中实时更新。
满足判定条件时,CheckChoice函数返回TRUE(允许跳转),不满足则返回FALSE(禁止跳转)

 

 

 

posted @ 2026-06-03 14:13  Breadss  阅读(8)  评论(0)    收藏  举报