Using Cameras-将一条指令封装为多条面向终端用户的可用指令

摘要

本文介绍如何创建可传入参数的命令。该命令借助相机修改当前窗口的视图方位,传入参数即为选定的视图方位。
  • 本实例学习要点

  • CAAAfrGeoCommands 示例工程

    • CAAAfrGeoCommands 功能说明

    • CAAAfrGeoCommands 运行方法

    • CAAAfrGeoCommands 源码存放路径 

  • 分步实现流程

  • 要点小结

  • 参考文献

 

本实例学习内容

本示例用于演示如何向命令传入参数,以及如何通过相机修改当前窗口的视图方位。

CAAAfrGeoCommands 开发实例

CAAAfrGeoCommands 是CAAApplicationFrame.edu框架下的示例工程,用于演示 ApplicationFrame 应用框架的各项功能。

CAAAfrGeoCommands 实例实现功能

CAAAfrGeoCommands 实例包含多条命令。本文仅介绍用于修改当前窗口视图方位的 CAAAfrChangeViewNormalCmd 命令。该命令隶属于 CAAAfrGeometryWshop 模块,可将当前窗口视图切换为下述任意一种视角。

图片

 从左侧查看 YZ 基准平面,操作路径:视图→法向视图→X 向法向

 

图片

 从右侧查看 ZX 基准平面,菜单路径:视图→法向视图→Y 向法向

图片

 从顶部查看 XY 基准平面,菜单路径:视图→法向视图→Z 向法向

该命令在工作台中通过多个命令头完成实例化,命令头的数量与面向终端用户的命令数量保持一致,也就是和菜单下拉项、工具栏按钮中用来触发本命令的控件数目相同。

 

CAAAfrGeoCommands 实例启动方法

 

如需了解本实例的详细启动步骤,请参阅「CAAGeometry 示例」文档里《CAAGeometry 实例启动方法》章节。本实例专属操作流程如下:

 

无需在命令行输入模块名,直接输入CNEXT启动程序。应用程序启动完成后,执行下述操作:

 

  1. 点击菜单栏:文件→新建
  2. 在新建弹窗中选中【CAAGeometry】,点击确定
  3. 打开视图→法向视图,菜单内包含三条命令:X 向法向、Y 向法向、Z 向法向,分别切换至 YZ 平面正视、ZX 平面正视、XY 平面正视视角。

CAAAfrGeoCommands 源码路径

CAAAfrGeoCommands 示例仅由单个类 CAAAfrChangeViewNormalCmd 构成,该类位于 CAAApplicationFrame.edu 框架的 CAAAfrGeoCommands.m 模块中:
  • Windows 系统路径:安装根目录\CAAApplicationFrame.edu\CAAAfrGeoCommands.m\
  • Unix 系统路径:安装根目录/CAAApplicationFrame.edu/CAAAfrGeoCommands.m/
其中安装根目录为 CAA 安装光盘的安装目录。
除此之外,在 CAAAfrGeometryWshop 工作台中用来注册该命令、并向命令传递参数的命令头,随工作台配置一同定义。

分步实现

创建修改当前窗口视图方位的命令分为三步:
步骤内容实现位置
1 创建命令并保存传入参数 构造函数
2 设置相机坐标轴 Activate(激活)函数
3 创建相机对象并绑定至当前窗口 Activate(激活)函数
 
 

创建命令并保存入参

命令构造函数实现如下:
...
CAAAfrChangeViewNormalCmd::CAAAfrChangeViewNormalCmd(void *iArgument)
                         : CATCommand("ViewNormalId",CATCommandModeExclusive)
{
   _ArgumentCmd = CATPtrToINT32(iArgument) ;
}
...
各命令头在调用该构造函数时会传入参数,该参数用于标识需要作为视线法向的基准平面,参数定义:
  • 1:正视 YZ 平面
  • 2:正视 ZX 平面
  • 3:正视 XY 平面
该参数以整型形式保存在成员变量_ArgumentCmd中。宏CATPtrToINT32用于64 位环境下安全地将指针转为整型。如需查看基于CAAAfrChangeViewNormalCmd类实例化命令头类的相关代码,可参阅参考文献 [1]。
构造入参CATCommandModeExclusive将当前命令设置为独占模式。由于本命令不会修改文档数据,理论上也可配置为共享模式;但该命令为单次执行命令,执行完成前无法调用其他命令,因此选用独占模式。

设置相机坐标轴

Activate 函数首先根据入参数值配置相机坐标轴。
...
CATStatusChangeRC CAAAfrChangeViewNormalCmd::Activate(CATCommand * iFromClient,
                                                      CATNotification * iEvtData)
{
  CATMathDirection direction, zenith;
  CATMathPoint origin(0.f, 0.f, 0.f);

  switch (_ArgumentCmd)
  {
    case 1 : direction.SetCoord(-1.f,0.f,0.f);
             zenith.SetCoord(0.f,0.f,1.f);
             break ;
    case 2 : direction.SetCoord(0.f,-1.f,0.f);
             zenith.SetCoord(0.f,0.f,-1.f);
             break ;
    case 3 : direction.SetCoord(0.f,0.f,-1.f);
             zenith.SetCoord(0.f,1.f,0.f);
             break ;
  }
  ...
}
...
参数取值规则:1 代表平面法向为 X 轴、2 代表平面法向为 Y 轴、3 代表平面法向为 Z 轴。相机坐标轴由视线方向构成。
视线轴连接相机视点与目标点,天顶轴则与视线方向相互垂直。

图片

  •  正视 YZ 平面的相机:视线方向与 X 轴反向(-1,0,0),天顶方向平行于 Z 轴。
  • 正视 ZX 平面的相机:视线方向与 Y 轴反向(0,-1,0),天顶方向与 Z 轴反向(0,0,-1)。
  • 正视 XY 平面的相机:视线方向与 Z 轴反向(0,0,-1),天顶方向平行于 Y 轴。

通过switch分支,将上述各个方向赋值给CATMathDirection类实例。

创建相机并绑定至当前窗口

...
CATFrmLayout *pCurrentLayout = CATFrmLayout::GetCurrentLayout();
if ( pCurrentLayout )
{
  CATFrmWindow *pCurrentWindow = pCurrentLayout->GetCurrentWindow();
  if ( pCurrentWindow )
  {
    CATFrm3DCamera * pCameraImpl = new CATFrm3DCamera("cam3d",
                                                      origin,
                                                      direction,
                                                      zenith);
    CATI3DCamera *pCamera = NULL;                
    HRESULT rc = pCameraImpl->QueryInterface(IID_CATI3DCamera, (void**)&pCamera);
    if (SUCCEEDED(rc))
    {
      pCurrentWindow->SetCurrentCamera(pCamera);
      pCamera->Release();
    }
    pCameraImpl->Release();
  }
}  
return CATStatusChangeRCCompleted;
}

...

为使用设定好的相机坐标轴替换当前窗口的视图方位:

 

首先调用静态方法CATFrmLayout::GetCurrentLayout获取布局管理器,再通过布局对象的GetCurrentWindow拿到当前激活窗口。随后依据传入参数(即终端用户在「视图→法向视图」中选中的菜单项)确定相机原点、视线方向与天顶方向,以此实例化三维相机对象;再通过 COM 查询接口拿到CATI3DCamera接口指针。

 

调用窗口的SetCurrentCamera方法将该接口指针设置为窗口当前相机,窗口视图随即跟随相机参数更新,最后释放相关 COM 接口。函数最终返回命令执行完成标识。

要点小结

命令支持传入参数,由此可实现单个底层命令对外展示为多条用户可用命令,但这类面向用户的功能命令需业务逻辑相近。
 
每条用户命令对应一个独立命令头:由命令头实例化命令实体,并传入匹配用户操作意图的参数;命令内部通过判别参数值,执行对应的功能逻辑。
相机是一类可挂载至窗口的对象,用于配置 / 重置窗口视图参数,包含相机视点位置、视线方向与天顶方向。
posted @ 2026-06-05 11:22  Breadss  阅读(3)  评论(0)    收藏  举报