CREO Toolkit二次开发-使用程序选中对象
本文介绍如何使用程序完成对象选取的功能。
Toolkit中使用ProSelection
记录Creo运行过程中选择的对象。ProSelect
是一个高频使用的选择对象函数,但是需要用户自己操作选择,显然无法胜任自动化或者批处理相关工作的要求。所幸Toolkit还提供了ProSelbufferClear
和ProSelbufferSelectionAdd
函数用于清空和添加会话中的ProSelection
,使得使用程序完成对象选取变得可能。
1.函数说明
ProSelbufferClear
清空当前Creo会话中所选的对象,使用非常简单,没有参数:
1 | status = ProSelbufferClear(); |
ProSelbufferSelectionAdd
可以用过程序的方式将对象添加到会话选择的对象中,其参数为对应的ProSelection
对象:
1 | status = ProSelbufferSelectionAdd(selection); |
通常来说我们需要选取的特征(装配体中组件)以ProModelitem
类型进行保存,Toolkit提供了ProSelectionAlloc
函数完成了从ProModelitem
到ProSelection
的转换。该函数有三个参数,第一个参数 ProAsmcomppath* p_cmp_path
仅对装配体中组件中需要指定,对应组件装配树路径,第二个参数ProModelitem* p_mdl_itm
为需要转换的ProModelitem
对象,第三个参数 ProSelection* p_selection
对应转换得到的ProSelection
对象,示例代码如下:
1 | //零件状态下使用 |
2.选择零件的特征
选择零件的特征必须要获得其对应的ProModelitem
对象。本文作为测试,以选定所有的坐标系特征为例,首选通过ProSolidFeatVisit
获取所有坐标系特征:
1 | ProError status; |
ProSolidFeatVisit
对应的过滤函数和动作函数如下:
1 | ProError FeatVisitActFn(ProFeature *p_feature, ProError status, ProAppData p_features) |
所获取的坐标系特征ProFeature
均保存在p_feature
数组中,对其进行遍历,使用ProSelectionAlloc
创建ProSelection
对象并使用ProSelbufferSelectionAdd
完成将坐标系对象添加到会话选择中:
1 | status = ProArraySizeGet(p_features, &n_size); |
使用程序选中所有坐标系特征如图1所示:
图1 使用程序选中所有坐标系特征
3.选择装配体的组件
选择装配体的组件ProAsmcomp
相对选择零件的特征ProFeature
复杂,体现在构造ProSelection
时ProSelectionAlloc
需要指定其装配树路径ProAsmcomppath
。ProAsmcomppath
在官方文档描述如下:
The object ProAsmcomppath is one of the main ingredients in the ProSelection object, as described in The Selection Object.
所以比较遗憾,直接从组件ProAsmcomp
获取其ProAsmcomppath
只能使用ProSelect
或者访问Selbuffe中的ProSelection
,而这之前都是需要人工手动操作完成,与使用程序选中对象的操作明显相违背。
幸好Toolkit提供了ProSolidDispCompVisit
用于遍历装备体已显示组件并可获取其ProAsmcomppath
,因此配合ProSolidFeatVisit
遍历装备体组件获取其ProAsmcomp
,通过查找定位两者信息,即可完成ProSelectionAlloc
参数的获取。
首先给出ProSolidFeatVisit
遍历记录装配树所有已显示节点ProAsmcomp
的代码,其对应的过滤函数和动作函数如下:
1 | ProError AsmCompVisitFilter(ProFeature *feature, ProAppData app_data) |
所获取的组件特征ProAsmcomp
均保存在p_comps
数组中:
1 | status = ProArrayAlloc(0, sizeof(ProModelitem), 1, (ProArray *)&p_comps); |
ProSolidDispCompVisit
遍历记录装配树所有已显示节点ProAsmcomppath
过滤函数这里默认访问所有节点,过滤函数可以设为NULL或者默认返回所有节点:
1 | ProError AsmCompPathVisitFilter(ProAsmcomppath *p_path, ProSolid solid, ProAppData app_data) |
ProSolidDispCompVisit
访问函数比ProSolidFeatVisit
稍显复杂,多了的第三个参数ProBoolean down
官方解释如下:
Use PRO_B_TRUE when going down to this component and PRO_B_FALSE when going up from this component.
实际测试下,在遍历对应的子装配节点,会同时访问按照装配树访问其父节点和子节点,当该参数为PRO_B_TRUE
时访问子节点,PRO_B_FALSE
则访问其父节点,两个操作依次进行,如果全部记录会造成数据混乱。另外访问函数是直接遍历所有节点,不需要像ProSolidFeatVisit
那样使用递归的方式访问子装配体的节点。故我们在此进行过滤,只访问向下的子节点,访问函数代码如下:
1 | ProError AsmCompPathVisitActFn(ProAsmcomppath *path, ProSolid solid, ProBoolean down, ProAppData p_comppaths) |
所获取的组件特征ProAsmcomppath
均保存在p_comppaths
数组中:
1 | status = ProArrayAlloc(0, sizeof(ProAsmcomppath), 1, (ProArray *)&p_comppaths); |
对比发现,两个数组长度不同,p_comppaths
长度比p_comps
长度多1,原因在于p_comppaths
还记录了最上层装配体根节点。实际代码编写中发现,ProSelectionAlloc
第一个参数是p_comps
父节点的ProAsmcomppath
而非其本身,所以p_comppaths
数组第一个记录的根节点很重要不能删除。另外ProSelectionAlloc
前两个参数如果不对应会返回PRO_TK_BAD_INPUTS
,如果此时执行ProSelbufferSelectionAdd
会导致Creo异常退出。在实际操作时,可以定义一个记录装配体树形结构数据结构同时保存节点位置和其对应的p_comppaths
比p_comps
以便完成选取对应的组件功能。本文仅做测试,没有记录p_comppaths
和p_comps
的对应关系,故使用双循环遍历后判断添加,效率很低,仅做演示,作为全选的功能够用了:
1 | for (j = 0; j < n_pathsize; j++) |
使用程序选中所有组件如图2所示:
图2 使用程序选中所有组件
完整代码可在Github.com下载。代码在VS2010,Creo 2.0 M060 X64下编译通过。