Expand/Collapse Specification Tree Nodes-如何在特征树中移除对象
摘要
本示例学习要点
CAACafSpecTree 示例程序
- 程序功能说明
- 程序运行方法
- 代码存放路径
操作步骤
简述
参考资料
本示例学习内容
本示例旨在讲解如何展开与折叠特征树节点。特征树由节点图谱构成,采用模型 - 视图 - 控制器(MVC)架构管理,各模块说明如下:
模型(M):模型元素实现了 CATINavigateObject 接口 [1]。
控制器(C):为 CATNavigController 类的实例。
视图(V):节点图谱在专属查看器中展示(该类未对外暴露),不参与特征树的节点导航操作。
本示例基于 CATFrmNavigWindow 类中的节点图谱开发。CATFrmNavigWindow 是 CATFrmGraphAnd3DWindow 类的基类,而后者也是零件窗口、装配窗口的基类。通过本示例,你将掌握以下操作:
从 CATFrmNavigWindow 类中获取控制器;
借助图谱控制器,获取与对象(特征)关联的图形节点;
实现节点的展开与折叠。
CAACafSpecTree 示例程序
CAACafSpecTree 功能说明

展开 / 折叠模式

再次选中 Point.2,该节点就会被折叠。
全部展开
从选中对象开始,将特征树完全展开。示例如下:
图 3:选中 Part1 后的效果

该命令默认使用第一种模式(展开 / 折叠)。若要启用第二种模式,需导出变量 CAACafSpecTreeExpandMode,具体操作参见运行 CAACafSpecTree章节。
运行 CAACafSpecTree
- Windows 系统 安装根目录 \CAAMechanicalModeler.edu\CAAMechanicalModelerEduRscCNext.m\src\CNext\code\dictionary\
- UNIX 系统安装根目录 / CAAMechanicalModeler.edu/CAAMechanicalModelerEduRscCNext.m/src/CNext/code/dictionary/
#CAAMmrPartWksAddin CATIWorkbenchAddin libCAAMmrPartWksAddin
#CAAMmrPartWksAddin CATIPrtWksAddin libCAAMmrPartWksAddin
以上两行配置对应零件工作台插件,该插件隶属于 CAAMechanicalModeler.edu 框架下的 CAAMmrPartWksAddin.m 模块,作用是在零件文档界面中添加上文的展开 / 折叠命令。
- 点击文件菜单,选择新建
- 在新建文档对话框中选中零件,点击确定
- 依次创建点、直线、凸台等特征
- 点击工具菜单,选择展开 / 折叠命令
- 在特征树中选取对象
- 在三维视图中选取对象
- 点击开始菜单,选择退出
- Windows 系统:
set CAACafSpecTreeExpandMode=CAACafSpecTreeExpandAllNodes - UNIX 系统:
export CAACafSpecTreeExpandMode=CAACafSpecTreeExpandAllNodes
- 点击文件菜单,选择新建
- 在新建文档窗口中选择零件,点击确定
- 创建点、直线、凸台等特征
- 点击工具菜单,选择展开 / 折叠
- 在特征树中选中对象
- 点击开始菜单,选择退出
CAACafSpecTree 代码位置
-
CAACafCollapseExpandCmd 类
LocalInterfaces 目录与 src 目录,本文对源文件添加了详尽注释。- Windows 路径:安装根目录 \CAACATIAApplicationFrm.edu\CAACafSpecTree.m\
- Unix 路径:安装根目录 / CAACATIAApplicationFrm.edu/CAACafSpecTree.m/
-
CAAMmrPartWksAdn 类
- Windows 路径: 安装根目录 \CAAMechanicalModeler.edu\CAAMmrPartWksAddin.m\
- Unix 路径:安装根目录 / CAAMechanicalModeler.edu/CAAMmrPartWksAddin.m/
实现步骤
- 获取 CATNavigController 类实例
- 实现 BuildGraph 方法
- 展开特征树至选中对象节点
- 对选中对象节点执行展开 / 折叠操作
- 从选中对象开始展开全部节点
获取 CATNavigController 类实例
if ( NULL != pLayout )
{
CATFrmWindow * pCurrentWindow = pLayout->GetCurrentWindow();
if ( NULL != pCurrentWindow )
{
if ( 1 == pCurrentWindow->IsAKindOf("CATFrmNavigGraphicWindow") )
{
CATFrmNavigGraphicWindow * pFrmNavigGraphicWindow =
(CATFrmNavigGraphicWindow*) pCurrentWindow ;
CATNavigBox * pNavigBox = NULL ;
pNavigBox = pFrmNavigGraphicWindow->GetNavigBox();
if ( NULL != pNavigBox )
{
_pNavigController = pNavigBox->GetController();
}
}
}
}
GetCurrentWindow 方法可获取当前活动窗口。若需要展开当前文档所有窗口内的节点图谱,请参考框架相关文档 [4],其中介绍了如何获取一份文档对应的全部窗口。_pNavigController 是本命令类中定义的成员变量,类型为 CATNavigController。
实现 BuildGraph 方法
- 创建交互代理
- 创建状态
- 根据交互代理定义状态间的跳转关系
...
_daObjectToExpandNode = new CATPathElementAgent("SelObjectToExpandNodeId");
_daObjectToExpandNode->AddElementType(IID_CATINavigateObject);
_daObjectToExpandNode->SetBehavior(CATDlgEngRepeat | CATDlgEngWithPSOHSO );
CATDialogState *stGetObjState = GetInitialState("stGetObjStateId");
stGetObjState->AddDialogAgent(_daObjectToExpandNode);
CATDialogTransition *pTransition = AddTransition
(
stGetObjState,
stGetObjState,
IsLastModifiedAgentCondition(_daObjectToExpandNode),
Action((ActionMethod) & CAACafCollapseExpandCmd::ExpandObject)
);
...
_daObjectToExpandNode 是拾取代理,用于在特征树或三维视图中选取对象。通过 AddElementType 方法限定,所选对象必须实现 CATINavigateObject 接口 [5]。CATDlgEngWithPSOHSO 行为表示选中对象后将其高亮显示;CATDlgEngRepeat 行为支持重复使用该代理,无需重复初始化。stGetObjState,状态标识为 stGetObjStateId。ExpandObject 方法。展开特征树至选中对象
ExpandObject 方法的第一步是获取选中对象。对拾取代理 _daObjectToExpandNode 调用 GetValue 方法,可得到 CATPathElement 类实例指针,以此获取选中对象的完整路径。{
CATPathElement * pObjPath = _daObjectToExpandNode->GetValue();
CATBaseUnknown * pObjectToExpand = NULL;
if ( NULL != pObjPath)
{
if ( pObjPath->GetSize() > 0 )
{
// 选取路径的末端节点
pObjectToExpand = (*pObjPath)[pObjPath->GetSize()-1];
}
...
pObjectToExpand 是路径的叶子节点。若该对象在特征树中未显示,则需要将其展开展示。想要查看对象的下级内容,前提是该对象本身必须处于可见状态,下方代码将具体说明实现方式。for ( int j = 0 ; j <= pObjPath->GetSize()-2 ; j++)
{
// 获取当前层级的父对象
CATBaseUnknown * pFatherObjectToExpand = (*pObjPath)[j];
CATListValCATBaseUnknown_var * pNodeList = NULL ;
// 通过特征树控制器获取该父对象对应的所有关联节点
pNodeList = _pNavigController->GetAssociatedElements(pFatherObjectToExpand);
if ( NULL != pNodeList )
{
// 获取节点总数
int nbNodes = pNodeList->Size();
// 逐个遍历节点
for ( int k= 1 ; k <= nbNodes ; k++ )
{
CATIGraphNode_var graphNode = (*pNodeList)[k];
if ( NULL_var != graphNode )
{
// 判断节点是否处于折叠状态
if ( 0 == graphNode->IsExpanded() )
{
// 转为导航元素接口
CATINavigElement_var spNavigElement = graphNode ;
if ( NULL_var != spNavigElement )
{
// 执行节点展开后的后续处理
spNavigElement->ProcessAfterExpand();
pFatherObjectToExpand 就是当前待检查的节点。GetAssociatedElements 方法,可获取入参对象对应的关联节点(在产品装配中,单个零件可被多次实例化)。节点可通过 CATIGraphNode 或 CATINavigElement 两个接口进行操作:前者提供 IsExpanded 方法,用于判断节点的展开状态;若节点处于折叠状态,则可调用后者的 ProcessAfterExpand 方法将其展开。_pExpandMode 执行对应逻辑:要么从该节点开始展开所有下级节点(详见从选中对象展开全部节点章节),要么仅对当前节点执行单次展开或折叠操作(详见展开 / 折叠选中节点章节)。(0==strcmp("CAACafSpecTreeExpandAllNodes",_pExpandMode)) )
{
ExpandAllNode(pObjectToExpand);
}else
{
ExpandCollapseNode(pObjectToExpand);
}
展开 / 折叠选中对象节点
iObject 是选中路径的叶子节点,详见前文章节。本逻辑不会预先判断节点展开状态,直接调用 ProcessAfterExpand 方法:若节点处于折叠状态则执行展开,若已展开则执行折叠。{
...
CATListValCATBaseUnknown_var * pNodeList = NULL ;
// 获取当前对象对应的所有关联节点
pNodeList = _pNavigController->GetAssociatedElements(iObject);
if ( NULL != pNodeList )
{
int nbNodes = pNodeList->Size();
// 遍历所有关联节点
for ( int i= 1 ; i <= nbNodes ; i++ )
{
CATBaseUnknown_var spNode = (*pNodeList)[i];
if ( NULL_var != spNode )
{
// 转换为导航元素接口
CATINavigElement_var spNavigElement = spNode ;
if ( NULL_var != spNavigElement )
{
// 切换节点展开/折叠状态
spNavigElement->ProcessAfterExpand();
...
}
...
从选中对象展开所有节点
iObject 是选取路径的叶子节点,仅当叶子节点未展开时,才会调用 ProcessAfterExpand 方法。{
if ( NULL_var != iObject )
{
CATListValCATBaseUnknown_var * pNodeList = NULL ;
pNodeList = _pNavigController->GetAssociatedElements(iObject);
if ( NULL != pNodeList )
{
int nbNodes = pNodeList->Size();
for ( int i= 1 ; i <= nbNodes ; i++ )
{
CATIGraphNode_var graphNode = (*pNodeList)[i];
if ( NULL_var != graphNode )
{
if ( 0 == graphNode->IsExpanded() )
{
CATINavigElement_var spNavigElement = graphNode ;
if ( NULL_var != spNavigElement )
{
spNavigElement->ProcessAfterExpand();
...
if ( NULL_var != spNavigateObject )
{
CATListValCATBaseUnknown_var* pListChild = NULL ;
pListChild = spNavigateObject->GetChildren();
if ( NULL != pListChild )
{
for ( int t = 1 ; t <= pListChild->Size() ; t++)
{
CATBaseUnknown_var spOnChild = (*pListChild)[t];
ExpandAllNode(spOnChild);
}
}
}
...

浙公网安备 33010602011771号