入门
环境准备
NX12.0
visual studio 2015
1)、将,安装路径\NX 12.0\UGOPEN\vs_files\VC\vcprojects
下的文件全部拷贝到vs2015安装路径\VC\vcprojects
下(如果vs2015没有 vcprojects文件夹,说明vs没有安装指定的c++模块的功能,可以在控制面板–》卸载程序,找到指vs2015 右键修改–》选择修改,将C++的功能模块全部选上就行了)
2)、将,安装路径\NX 12.0\UGOPEN\vs_files\VC\VCWizards
下的两个文件夹(NX12_NXOpenCPP、NX12_Open)全部拷贝到vs2015安装路径\VC\VCWizards
下
启动vs2015,文件–》新建项目–》模板–》visual C++里面选择NX12(两个中任选一个)。选择编程语言(默认是C、)C++
第一个二次开发程序
1)
/*****************************************************************************
**
** example_01.cpp
**
** Description:
** Contains Unigraphics entry points for the application.
**
*****************************************************************************/
/* Include files */
#include <stdarg.h>
#include <strstream>
#include <iostream>
using std::ostrstream;
using std::endl;
using std::ends;
using std::cerr;
#include <uf.h>
#include <uf_ui_types.h>
#include <uf_ui.h>
#include <uf_exit.h> //NXOpen for C UFun
static void ECHO(char *format, ...)//允许变参数
{
char msg[UF_UI_MAX_STRING_BUFSIZE];//F12快速转到定义处
va_list args;//变量的列表
va_start(args, format);//获取所有参数
vsnprintf_s(msg, sizeof(msg), _TRUNCATE, format, args);
va_end(args);
UF_UI_open_listing_window();
UF_UI_write_listing_window(msg);//打开窗口
UF_print_syslog(msg, FALSE);//日志文件
}
#define UF_CALL(X) (report_error( __FILE__, __LINE__, #X, (X)))//带参数的宏
/*
__FILE__:当前正在运行的代码的名称(xx.cpp的xx)
__LINE__:程序正在执行的哪一行
#X:正在运行的函数的名称
(X)):函数的返回值
*/
static int report_error( char *file, int line, char *call, int irc)
{
if (irc)
{
char err[133];
/*大部分的UF函数的返回值:如果在手册中没有特别的说明。返回值若为0,表示函数执行成功;
若返回值不为0,通过UF_get_fail_message函数获取函数执行失败的相关信息
NX日志文件帮助-->日志文件
*/
UF_get_fail_message(irc, err);
ECHO("*** ERROR code %d at line %d in %s:\n",
irc, line, file);
ECHO("+++ %s\n", err);
ECHO("%s;\n", call);
}
return(irc);
}
/*****************************************************************************
** Activation Methods
*****************************************************************************/
/* Explicit Activation
** This entry point is used to activate the application explicitly, as in
** "File->Execute UG/Open->User Function..." */
/*
在nx中当用户选择加载.dll文件的时候,动态库会寻找ufusr函数,并执行该函数ufusr,类似main函数,程序的入口
*/
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
/* Initialize the API environment */
/*
UF_CALL调用uf函数,如果uf函数在调用的过程中出现了一些错误
UF_CALL自动捕捉函数的返回的错误代码,根据错误代码获取相应的信息,记录在日志文件和信息窗口中
*/
/*
UF_initialize(),初始化函数。向nx获取运行二次开发程序运行的权限,初始化程序运行的环境
在调用UG/Open API的函数前, 应先调用 UF_initialize()来获得执行许可权限。一般来说,第一个调用 的 UG/open API 函数就是 UF_initialize()。
当不再调用 API 函数的时候, 必须调用 UF_terminate()来释放执行许可权限。
*/
if( UF_CALL(UF_initialize()) ) //初始化
{
/* Failed to initialize */
return;
}
//还可以写成
//if (UF_initialize() != 0) {
//return
//}
/* TODO: Add your application code here */
UF_UI_open_listing_window();
UF_UI_write_listing_window("hello NX");
/* Terminate the API environment */
UF_CALL(UF_terminate());//终止
}
/*****************************************************************************
** Utilities
*****************************************************************************/
/* Unload Handler
** This function specifies when to unload your application from Unigraphics.
** If your application registers a callback (from a MenuScript item or a
** User Defined Object for example), this function MUST return
** "UF_UNLOAD_UG_TERMINATE". */
/*
确保什么时候将程序从nx中卸载
#define UF_UNLOAD_IMMEDIATELY 1 //二次开发程序在运行完毕之后立即从nx释放
#define UF_UNLOAD_SEL_DIALOG 2 //由用户从对话框中进行选择,什么时候释放
#define UF_UNLOAD_UG_TERMINATE 3 //直到nx关闭才释放二次开发程序
2 的话要用户在nx中打开file-->utilities unload shared image
*/
extern int ufusr_ask_unload( void )
{
return( UF_UNLOAD_IMMEDIATELY );
}
生成–》生成解决方案
解决方案在项目根目录/x64Debug下生成
nx运行脚本
打开nx12.0,ctrl+u
选择解决方案xxx.dll,运行即可
入口函数
ufusr
/*
在nx中当用户选择加载.dll文件的时候,动态库会寻找ufusr函数,并执行该函数ufusr,类似main函数,程序的入口
采用了直接激活( Explicit Activation )的user Exit,其入口函数为ufusr()。
直接激活的操作.方式如下:
选择菜单命令File→Exeeute UG/OPEN-→User Function (或按快捷键Ctrl +U),在弹出的Execute User Function对话框中选择DLL
文件,即可执行应用开发程序中的ufusr()函数。这种User Exit只是一
个面向过程的程序处理任务,它有唯一的运行起 止点,程序码在起止点间
顺序进行。ufusr ()的函数体如下所示:
*/
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
/* Initialize the API environment */
/*
UF_CALL调用uf函数,如果uf函数在调用的过程中出现了一些错误
UF_CALL自动捕捉函数的返回的错误代码,根据错误代码获取相应的信息,记录在日志文件和信息窗口中
*/
/*
UF_initialize(),初始化函数。向nx获取运行二次开发程序运行的权限,初始化程序运行的环境
在调用UG/Open API的函数前, 应先调用 UF_initialize()来获得执行许可权限。一般来说,第一个调用 的 UG/open API 函数就是 UF_initialize()。
当不再调用 API 函数的时候, 必须调用 UF_terminate()来释放执行许可权限。
*/
if( UF_CALL(UF_initialize()) ) //初始化,很重要。缺失的话会导致错误
{
/* Failed to initialize */
return;
}
//还可以写成
//if (UF_initialize() != 0) {
//return
//}
/* TODO: Add your application code here */
UF_UI_open_listing_window();
UF_UI_write_listing_window("hello NX");
/* Terminate the API environment */
UF_CALL(UF_terminate());//终止
}
ufget
//打开文件时
/*
*returnCode 默认值是0
我们可以更改默认值变为1,这样的话表示激活用户应用后,系统将不启动UG原有File-->Open File功能
*/
extern DllExport void ufget(char *parm, int *returnCode, int rlen)
{
/* Initialize the API environment */
/*
UF_CALL调用uf函数,如果uf函数在调用的过程中出现了一些错误
UF_CALL自动捕捉函数的返回的错误代码,根据错误代码获取相应的信息,记录在日志文件和信息窗口中
*/
/*
UF_initialize(),初始化函数。向nx获取运行二次开发程序运行的权限,初始化程序运行的环境
在调用UG/Open API的函数前, 应先调用 UF_initialize()来获得执行许可权限。一般来说,第一个调用 的 UG/open API 函数就是 UF_initialize()。
当不再调用 API 函数的时候, 必须调用 UF_terminate()来释放执行许可权限。
*/
if (UF_CALL(UF_initialize())) //初始化,很重要。缺失的话会导致错误
{
/* Failed to initialize */
return;
}
//还可以写成
//if (UF_initialize() != 0) {
//return
//}
/* TODO: Add your application code here */
UF_UI_open_listing_window();
UF_UI_write_listing_window("hello NX");
//*returnCode = 1;//不进行UG系统的操作
//*returnCode = 0;//进行UG系统的操作,默认值
/* Terminate the API environment */
UF_CALL(UF_terminate());//终止
/*需要设置环境变量
点击生成-->生成解决方案;
生成动态库的地址
C:\workplace\NX\NXDEV2.0\example_01\x64\Debug\example_01.dll
设置环境变量
USER_RETRIEVE
C:\workplace\NX\NXDEV2.0\example_01\x64\Debug\example_01.dll
重启nx
我们发现执行了我们编写的代码,并且会继续执行nx原先的操作
*/
/*
在vs2015新建项目时 到 Entry Points窗口时,可以选择From a User Exit
下面有选项 Open Part
点击完成
我们会发现代码中会含有ufget这个函数
*/
}
ufsta
手册
UF:常用的函数
UF_ASSEM:装配
UF_ATTR:属性
UF_CFI:文件
UF_CSYS:坐标系(Coordinate System)
UF_CURVE:曲线操作
UF_DEAW:工程图
UF_DRF:标注、基准
UF_MODL:特征、表达式
UF_MTX:曲面
UF_OBJ:对象
UF_PART:部件文件
UF_STYLER:用户界面
UF_VEC:向量
/*
返回值为多个参数
*/
void f1(int a, int b, int* c, int* d, double* e) {
*c = a + b;
*d = a - b;
*e = (double)a / b;
}
void f2(int a, int b, int& c, int& d, double& e) {
c = a + b;
d = a - b;
e = (double)a / b;
}
int* f3(int a, int b) {
int*p = new int[3];
p[0] = a + b;
p[1] = a - b;
p[2] = (double)a / b;
return p;
}
调用
int* f3(int, int);
int* s = f3(4, 5);
delete[] s;
s = nullptr;
uf_part.h
添加头文件
#include<uf_part.h>
tag_t
对每一个可标识的对象都使用一个tag_t,也就是一个编号进行表示,进行区分
当部件被打开时赋予一个临时的编号,并不保存到部件中去
在nx中查看部件的编号:在菜单栏右键打开,开发人员,进入开发人员菜单
设置环境变量ugii_display_debug:1
重启nx
在内部菜单栏选择:移刀
过滤器选择:面
选择部件的表面
查看信息:属性tag
当我们再次,选择这个面的时候,发现tag属性的值改变了
tag_t part1 = 0;
数据类型
除了 C 语言标准的数据类型外,UG/Open API 还提供了一些自定义的 数据类型,如 tag_t 类型、结构类型(structure type)、枚举类型( enum type)、联合类型(union type)与指针类型(pointer type)等,它们 统一用后缀“_t”表示,且这些数据类型的指针用反缀“_p_t”命名表示。
后缀 | 描述 |
---|---|
_t | 数据类型(data type) |
_p_t | 数据类型的指针(pointer to data type) |
_s | 结构标识(structure tag) |
_u_t | 联合类型(union type) |
_u_p_t | 联合类型的指针(pointer to a union type) |
_f_t | 函数指针(pointer to a function) |
对象分类
打开手册UF_OBJECT_TYPES
可以借助,内部,移刀查看属性:entity_type,entity_subtype,查看类型的编号
创建实体对象
UF_MODL_create_block
添加头文件
#include <uf_modl.h>
/*UF_FEATURE_SIGN枚举类型,列举了布尔操作
UF_NULLSIGN = 0, 没有布尔操作
UF_POSITIVE = 1,
UF_NEGATIVE = 2,
UF_UNSIGNED = 3,
UF_NO_BOOLEAN = 4,
UF_TOP_TARGET = 5,
UF_UNITE = 6,
UF_SUBTRACT = 7,
UF_INTERSECT = 8,
UF_DEFORM_POSITIVE = 9,
UF_DEFORM_NEGATIVE = 10
null_tag:tag_t为空,没有目标体
*/
UF_FEATURE_SIGN sign= UF_NULLSIGN;//没有布尔操作
double origin[] = { 0,0,0 };//原点位置0,0,0
char* lengths[] = { "100","100","100" };//长宽高
tag_t blk_feat = NULL_TAG;
UF_MODL_create_block(sign,null_tag, origin, lengths, &blk_feat);//创建实体
tag_t blk_body = NULL_TAG;
UF_MODL_ask_feat_body(blk_feat,&blk_body);
UF_UI_open_listing_window();
char s1[200];
sprintf_s(s1, "%d\t%d", blk_feat, blk_body);
UF_UI_write_listing_window(s1);//输出实体信息
创建实线对象
#include <uf_curve.h>
#include <string.h>
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//定义起始位置
double start_point[] = {0.0,0.0,0.0};
//定义结束位置
double end_point[] = {100.0,200.0,0.0 };
// 声明结构体
UF_CURVE_line_p_t line_coords=new UF_CURVE_line_s;
// 结构体赋值
memcpy(line_coords->start_point, start_point, sizeof(start_point));
memcpy(line_coords->end_point, end_point,sizeof(end_point));
//line_coords->start_point[0] = 0.0;
//line_coords->start_point[1] = 0.0;
//line_coords->start_point[2] = 0.0;
//line_coords->end_point[0] = 100.0;
//line_coords->end_point[1] = 100.0;
//line_coords->end_point[2] = 100.0;
// 创建部件对象
tag_t line = NULL_TAG;
//创建实线对象
UF_CURVE_create_line(line_coords,&line);
//释放内存
delete line_coords;
UF_CALL(UF_terminate());
}
创建一个Cylinder特征,输出其所在图层和颜色
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//布尔操作
UF_FEATURE_SIGN sign = UF_NULLSIGN;
//原点位置0,0,0
double origin[] = { 0,0,0 };
//高
char * height = "100";
//直径
char * diam = "10";
//方位
double direction[] = { 0,0,1 };
//圆柱对象
tag_t cyl_tag = NULL_TAG;
//创建一个圆柱特征
UF_MODL_create_cylinder(sign, null_tag, origin, height, diam, direction, &cyl_tag);
//实体对象
tag_t blk_body = NULL_TAG;
//输出实体对象
UF_MODL_ask_feat_body(cyl_tag, &blk_body);
//圆柱对象的显示属性
UF_OBJ_disp_props_t dispProps;
//查询属性
UF_OBJ_ask_display_properties(blk_body, &dispProps);
UF_UI_open_listing_window();
//编辑结果
char s1[200];
sprintf_s(s1, "颜色为:%d\n图层为:%d",dispProps.color, dispProps.layer);
//窗体输出结果
UF_UI_write_listing_window(s1);
UF_CALL(UF_terminate());
}
sprintf_s函数可以对结果进行样式控制、
char s1[200];
sprintf_s(s1, "颜色为:%d\n图层为:%d",dispProps.color, dispProps.layer);
UF_UI_write_listing_window(s1);
结构体定义
struct UF_OBJ_disp_props_s {
int layer;
int color;
int blank_status;
int line_width;
int font;
logical highlight_status;
};
typedef struct UF_OBJ_disp_props_s UF_OBJ_disp_props_t,
*UF_OBJ_disp_props_p_t;
UF_OBJ_disp_props_s
使用
.
的方式进行赋值取值*UF_OBJ_disp_props_p_t
使用->的方式进行取值赋值
创建完特征后
//实体对象
tag_t blk_body = NULL_TAG;
//输出实体对象
UF_MODL_ask_feat_body(cyl_tag, &blk_body);
使用这个函数将它变成实体
&:地址
*:内容
在c++中,当申明变量int *p
的时,表示p是一个储存地址的变量;比如int *p=0
,表示p指向地址为00000000的地址单元。当申明指针p之后,再用*p
表示p指向的储存空间的内容;&表示取变量的地址;
创建一个蒸发提并高亮他的上面
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
UF_FEATURE_SIGN sign= UF_NULLSIGN;//没有布尔操作
double origin[] = { 0,0,0 };//原点位置0,0,0
char* lengths[] = { "100","100","100" };//长宽高
tag_t blk_feat = NULL_TAG;
UF_MODL_create_block(sign,null_tag, origin, lengths, &blk_feat);//创建实体
tag_t blk_body = NULL_TAG;
UF_MODL_ask_feat_body(blk_feat,&blk_body);
//UF_UI_open_listing_window();
//char s1[200];
//sprintf_s(s1, "%d\t%d", blk_feat, blk_body);
//UF_UI_write_listing_window(s1);//输出实体信息
uf_list_p_t blkFaces = nullptr;
//返回一个实体的所有面的集合
UF_MODL_ask_body_faces(blk_body,&blkFaces);
int facesCount = 0;
//UF_MODL_ask_list_count(blkFaces,&facesCount);
tag_t obj = NULL_TAG;
int type = 0;
double point[3];
double dir[3];
double box[6];
double radius = 0;
double rad_data = 0;
int norm_dir = 0;
/*for (int i = 0; i < facesCount; i++)
{
UF_MODL_ask_list_item(blkFaces,i,&obj);
UF_MODL_ask_face_data(obj, &type, point, dir, box, &radius, &rad_data, &norm_dir);
if (fabs(dir[0])<tolerancy && fabs(dir[1])<tolerancy && fabs(dir[2]-1)<tolerancy) {
break;
}
}*/
//方法二
uf_list_p_t p = blkFaces;
while (p!=NULL) {
UF_MODL_ask_face_data(p->eid, &type, point, dir, box, &radius, &rad_data, &norm_dir);
if (fabs(dir[0])<tolerancy && fabs(dir[1])<tolerancy && fabs(dir[2] - 1)<tolerancy) {
break;
}
}
if (p->eid != NULL)
{
UF_DISP_set_highlight(p->eid, 1);
}
//UF_DISP_set_highlight(obj, 1);
UF_MODL_delete_list(&blkFaces);
UF_CALL(UF_terminate());
}
创建一个圆柱,打印,圆心坐标
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//布尔操作
UF_FEATURE_SIGN sign = UF_NULLSIGN;
//原点位置0,0,0
double origin[] = { 0,0,0 };
//高
char * height = "100";
//直径
char * diam = "10";
//方位
double direction[] = { 0,0,1 };
//圆柱对象
tag_t cyl_tag = NULL_TAG;
//创建一个圆柱特征
UF_MODL_create_cylinder(sign, null_tag, origin, height, diam, direction, &cyl_tag);
uf_list_p_t blkEdges = nullptr;
//获取edges集合
UF_MODL_ask_feat_edges(cyl_tag,&blkEdges);
UF_UI_open_listing_window();
//遍历集合
while (blkEdges!=NULL)
{
UF_EVAL_p_t point = NULL;
//获取圆点对象
UF_EVAL_initialize(blkEdges->eid, &point);
UF_EVAL_arc_t arc;
//获取圆心信息
UF_EVAL_ask_arc(point, &arc);
char s1[100];
//输出
sprintf_s(s1, "圆心坐标为:(%lf,%lf,%f)\n", arc.center[0], arc.center[1], arc.center[2]);
UF_UI_write_listing_window(s1);
//释放内存
UF_EVAL_free(point);
//下一个
blkEdges = blkEdges->next;
}
//释放内存
UF_MODL_delete_list(&blkEdges);
UF_CALL(UF_terminate());
}
获取所有工作部件的类型
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
tag_t obj = NULL_TAG;
//获得workPart
tag_t workPart = UF_ASSEM_ask_work_part();
//类型为特征
int type = UF_feature_type;
UF_UI_open_listing_window();
//根据特征遍历对象
UF_OBJ_cycle_objs_in_part(workPart, type, &obj);
while (obj != NULL_TAG) {
/*
UF_MODL_ask_feat_name函数已经有返回值了,我们想要他再返回一个值,
就需要使用变参,char ** feature_type就是变参,用以返回一个指针
UF_MODL_ask_feat_name()的第二个参数类型为指针的指针char ** feature_name,用以返回一个指针
在函数内部,首先创建一个临时变量来保存该指针的指针,
之后对该临时变量的值进行赋值,即修改了指针的指针的指向,
赋的值就是一个新的内存地址,这个新的内存地址存储了结果,也就是将结果传了出去
feature_name 为指针变量,指向null(存储的是内存地址)
想要改变feature_name的指向,即改变feature_name的值,就需要将它的地址传过去
&feature_name:获取指针变量feature_name的地址
*/
char * feature_name=NULL;
//查询特征属性
UF_MODL_ask_feat_name(obj,&feature_name);
//输出
UF_UI_write_listing_window(feature_name);
UF_UI_write_listing_window("\n");
//释放内存
UF_free(feature_name);
//查询下一个
UF_OBJ_cycle_objs_in_part(workPart, type, &obj);
}
UF_CALL(UF_terminate());
}
创建表达式
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
/* Initialize the API environment */
if( UF_CALL(UF_initialize()) )
{
return;
}
//定义表达式
char str[] = "Length=25";
//创建表达式
UF_MODL_create_exp(str);
//更新
UF_MODL_update();
//定义表达式值
double rs;
//查询表达式值
UF_MODL_eval_exp("Length", &rs);
char showValue[30];
sprintf_s(showValue,"Length的值为:%lf",rs);
//显示表达式值
uc1601(showValue,1);
//定义修改表达式
char newValue[] = "Length=100";
//修改表达式的值
UF_MODL_edit_exp(newValue);
//更新
UF_MODL_update();
//查询值
UF_MODL_eval_exp("Length", &rs);
char showValue1[50];
sprintf_s(showValue1, "Length修改后的值为:%lf", rs);
//输出表达式值
uc1601(showValue1, 1);
UF_CALL(UF_terminate());
}
UF_CSYS坐标系
uf_csys
UF_CSYS_ask_csys_info 查看坐标系信息
UF_CSYS_ask_matrix_values 查看xyz轴的方向矢量
UF_CSYS_ask_wcs 查看工作坐标系
UF_CSYS_create_csys 新建工作坐标系
UF_CSYS_create_matrix 创建xyz方向矢量
UF_CSYS_set_wcs 设置工作坐标系
UF_VEC向量
UF_VEC3_cross 向量叉乘
UF_VEC3_dot 向量点乘
UF_VEC3_is_equal 判断两个向量是否等价
UF_VEC3_is_parallel 两个方向矢量是否平行
UF_VEC3_is_perpendicular 判断两个向量是否相互垂直
UF_VEC3_negate 向量取反
UF_VEC3_unitize 向量的单位化
UF_MTX矩阵
UF_MTX3_initialize 输入x,y轴向量,进行叉乘计算出z轴方向向量,输出xyz三轴方向向量
UF_MTX3_initialize_x 输入x轴方向矢量,自动构建y和z轴;方向不确定,但是保证两两垂直
UF_MTX3_initialize_z 输入z轴方向矢量,自动构建y和x轴;方向不确定,但是保证两两垂直
UF_MTX3_multiply 两个3X3矩阵相乘
UF_MTX3_rotate_about_axis 给定旋转轴,旋转角度,输出一个3X3矩阵
UF_MTX3_vec_multiply 方向矢量和3X3矩阵相乘的结果
UF_MTX3_x_vec 取出x轴向量
UF_MTX3_y_vec 取出y轴向量
UF_MTX3_z_vec 取出z轴向量
UF_CURVE曲线
UF_CURVE_create_line 创建直线
UF_CURVE_create_line_arc 创建圆弧
UF_CURVE_create_arc_3point 根据三个点创建圆弧
UF_CURVE_create_arc_3tangent 给定三个圆弧创建一个与三个圆弧相切的圆弧
UF_CURVE_create_arc_center_radius 根据圆心半径创建圆
UF_UI
UF_UI_select_with_single_dialog
int UF_UI_select_with_single_dialog
(
char * message,
char * title,
int scope,
UF_UI_sel_init_fn_t init_proc,
void* user_data,
int * response,
tag_t * object,
double cursor [ 3 ] ,
tag_t * view
)
message // 提示窗口提示信息
title 窗口标题
scope对象选择的范围:四个选项 (nx菜单右边两个下拉菜单中的右边的那个)
UF_UI_SEL_SCOPE_NO_CHANGE 选择范围不变 ,用户选择的是啥就是啥
UF_UI_SEL_SCOPE_ANY_IN_ASSEMBLY 装配部件中的所有部件
UF_UI_SEL_SCOPE_WORK_PART 装配中工作部件的指定部件被选定
UF_UI_SEL_SCOPE_WORK_PART_AND_OCC// 工作部件(这个部件配多次装入:如螺钉,这一类零件被选中
init_proc :过滤器 (nx菜单右边两个下拉菜单中的左边的那个)
user_data:
response: 输出参数 ,对话框的用户的选择
UF_UI_BACK 回退
UF_UI_CANCEL 取消
UF_UI_OK 确定
UF_UI_OBJECT_SELECTED 用户通过鼠标进行选择
UF_UI_OBJECT_SELECTED_BY_NAME 通过输入对象的名字
object: 输出对象,用户选中的对象 ,没选中对象就返回NULL_TAG
cursor: 鼠标单击的坐标系
view:视图
--------------------------------------------------------------------
init_proc:过滤器 (函数名可以变化,但是函数原型是不能改变的(返回值,参数列表))
int UF_UI_sel_init_fn_t
(
UF_UI_selection_p_t select_,
void * user_data
)
实例
static int init_proc(
UF_UI_selection_p_t select,
void* user_data)
{
int num_triples = 2;
UF_UI_mask_t mask_triples[] = {
UF_line_type, 0, 0,
UF_solid_type, 0, UF_UI_SEL_FEATURE_ANY_EDGE};
//UF_UI_set_sel_mask设置选择的过滤器
if((UF_CALL(UF_UI_set_sel_mask(select,
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
num_triples, mask_triples))) == 0)
{
return (UF_UI_SEL_SUCCESS);
}
else
{
return (UF_UI_SEL_FAILURE);
}
}
UF_UI_set_sel_mask:常用类型
UF_point_type
UF_line_type
UF_circle_type
UF_conic_type
UF_spline_type
UF_pattern_type
UF_kanji_type
UF_group_type
UF_drafting_entity_type
UF_dimension_type
UF_tabular_note_type
UF_margin_type
UF_coordinate_system_type
UF_plane_type
UF_component_type
UF_datum_axis_type
UF_datum_plane_type
UF_facet_topology_type
UF_view_type
UF_view_set_type
UF_route_control_point_type
UF_route_port_type
UF_route_segment_type
UF_route_part_anchor_type
UF_route_stock_type
UF_analysis_type
UF_traceline_type
UF_constraint_type
UF_solid_type
int UF_UI_set_sel_mask
(
UF_UI_selection_p_t select_,
UF_UI_sel_mask_action_t action,
int num,
UF_UI_mask_t * mask_triples
)
action
UF_UI_SEL_MASK_ENABLE_ALL 所有的都允许 数组不起作用
UF_UI_SEL_MASK_ENABLE_SPECIFIC
UF_UI_SEL_MASK_DISABLE_SPECIFIC 数组中指明的对象不允许使用
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC 把其他的都请除,只允许使用指定的
UF_UI_SEL_MASK_ALL_AND_DISABLE_SPECIFIC
num:表明数组的长度
mask_triples:输入参数:表明是一个结构体数组 :指定对象类型对象的子类型
object_type对象类型
object_subtype对象子类型
solid_type 更详细的划分 (uf_ui下面UF_UI Enumerations的UF_UI #Defines中的宏定义)
c
public static int init_proc(IntPtr select, IntPtr user_data) {
int num = 1;
NXOpen.UF.UFUi.Mask[] mask_triples=new UFUi.Mask[1];
mask_triples[0].object_type = UFConstants.UF_solid_type;
mask_triples[0].object_subtype =0;
mask_triples[0].solid_type = UFConstants.UF_UI_SEL_FEATURE_PLANAR_FACE;
theUfSession.Ui.SetSelMask(select, NXOpen.UF.UFUi.SelMaskAction.SelMaskClearAndEnableSpecific, num, mask_triples);
return 1;
}
int selRes;
Tag selObj;
double[] selCursor=new double[3];
Tag selView;
IntPtr user_data =new IntPtr();
NXOpen.UF.UFUi.SelInitFnT init = new NXOpen.UF.UFUi.SelInitFnT(init_proc);
theUfSession.Ui.SelectWithSingleDialog("请选择planar faces!", "请选择planar faces",
UFConstants.UF_UI_SEL_SCOPE_NO_CHANGE,init,user_data,
out selRes, out selObj, selCursor, out selView);
UF_STYLER
UF_STYLER_ask_value
UF_XS
堆excel的操作
UF_XS_extract_spreadsheet UF_XS_store_spreadsheet
第四章用户界面开发
在用户设定的工程路径下需要建立 UG 系统规定的工程目录结构。
UG 启动时会在规定目录中寻找并加载相应的程序和资源。UG 规定的目录
有 startup、application 和Udo。UG对它们存放的文件做了如下的规定:
( 1 ) Startup 目 录 存 放 UG 启 动 时 需 加 载 的 动 态 链 接 库 文 件
(*.dll)、菜单脚本文件( .men)和用户工具栏脚本文件(.tbr)。
( 2 ) Apphcation 目录存放具体的功能扩展程序文件,如 UIstyler
对话框文件(.dlg)、工具图标文件(.bmp )和位图调色板文件
(*.ubm )。
( 3 ) Udo 目录存放用户定义的数据和链接等。考虑到项目开发的需要
和文档的完整性,除了 UG 系统规定的目录外,还需要建立一些自定义目
录(仅供参考)。这些目录有 Code、Configure 和 Document。这些目录
中存放的文件类型有如下规定:
( 1 ) Code 目录存放具体的程序代码,该目录在新建工程时创建。
( 2 ) Configure 目录存放开发中所必需的配置文件,如文本文件
( *.txt) 、 自 定 义 配 置 文 件 ( *.cfg) 和 电 子 表 格 Excel 文 件
(*.xls )等。Configure 目录的名称可以根据具体的编程需要由开发者
选定,例如 Excel、Temp 等。
( 3 ) Document 目 录 存 放 用 户 的 文 档 文 件 , 如 视 频 演 示 文 件
(.avi)、安装使用说明书(.doc)和软件开发说明书(*.doc)等。
图 2-25 所示给出了一个应用开发程序的目录结构,开发者可以根据
实际情况做适当调整。
创建第一个用户界面程序
- nx–>文件–>所有应用模块–>开发人员–>NX6中定制用户界面的样式
- 保存文件到workdir(推荐的文件夹名:其中包含application和startup两个文件夹),保存时选择编程语言为c,存放到application文件夹中。
- vs2015创建新nx项目,删除原有的源文件,右键项目–>添加–>添加现有项,找到application文件夹中的头文件(.h)和源文件(.c)确定
- 修改源文件后缀.c–>.cpp(使用c++作为开发语言)
- 取消源文件的注释(MENUBAR HOOKUP HELP Example注释下的ufsta,DIALOG CREATION FROM A USER EXIT HELP Example下的 修改函数名为ufusr)
- 设置环境变量UGII_VENDOR_DIR:C:\workplace\NX\NXDEV2.0\workdir(值为application的上一级)
- 生成解决方案
- 重启nx
- ctrl+u加载脚本文件
生成的源文件结构:因为在设计用户界面时选择的从以下场合启动对话框选择的是all
所以会创建三个函数对应三种启动方式
MENUBAR HOOKUP HELP Example从菜单工具条中启动
DIALOG CREATION FROM A CALLBACK HELP Example:/从另一个控件/运行
DIALOG CREATION FROM A USER EXIT HELP Example 注释下函数,需要自己选择入口函数名(ufusr:表示ctrl+u时运行)
事件
int CHANGE_apply_cb 点击apply时触发的事件
第 五章 外部数据访问
KF
KnowledgeFusion知识熔接 知识融合KF
KBE知识工程
作业
作业一
在ufusr中调用uc1601函数
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
/* Initialize the API environment */
if( UF_CALL(UF_initialize()) )
{
/* Failed to initialize */
return;
}
/*
0:将文本输出到状态行
1:将文本放在消息框中
*/
//uc1601("helloworld1", 0);
//uc1601("helloworld",1);
/* TODO: Add your application code here */
/* Terminate the API environment */
UF_CALL(UF_terminate());
}
作业二
针对New Part创建User Exit函数并运行
extern DllExport void ufcre( char *param, int *returnCode, int rlen )
{
//初始化函数
if (UF_CALL(UF_initialize()))
{
return;
}
//弹出消息框
uc1601("正在创建part", 1);
*returnCode = 1;//阻止nx的默认行为,不进行文件创建
//终止
UF_CALL(UF_terminate());
//动态库地址 C:\workplace\NX\NXDEV2.0\TEST\test01\x64\Debug\test01.dll
//设置环境变量USER_CREATE
//重启NX
}
作业三
UF_PART_ask_num_parts函数的作用是查询NX当前有多少个文件被打开; UF_PART_ask_nth_part函数的作用是查询其中的第n个part,返回其tag; UF_PART_ask_part_name函数的作用是查询其name
使用上述函数,将NX中所有打开的部件的名称输出到listing window
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//打开窗口
UF_UI_open_listing_window();
//获取part文件数量
int partNum = UF_PART_ask_num_parts();
for (int i = 0; i < partNum; i++) {
//获取当前part文件
tag_t part = UF_PART_ask_nth_part(i);
//获取文件名
char part_fspec[MAX_FSPEC_BUFSIZE];
UF_PART_ask_part_name(part, part_fspec);
//输出
UF_UI_write_listing_window(part_fspec);
UF_UI_write_listing_window("\n");
}
UF_CALL(UF_terminate());
}
作业四
使用UF_CURVE_create_line创建一条直线
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//定义起始位置
double start_point[] = {0.0,0.0,0.0};
//定义结束位置
double end_point[] = {100.0,200.0,0.0 };
// 声明结构体
UF_CURVE_line_p_t line_coords=new UF_CURVE_line_s;
// 结构体赋值
memcpy(line_coords->start_point, start_point, sizeof(start_point));
memcpy(line_coords->end_point, end_point,sizeof(end_point));
//line_coords->start_point[0] = 0.0;
//line_coords->start_point[1] = 0.0;
//line_coords->start_point[2] = 0.0;
//line_coords->end_point[0] = 100.0;
//line_coords->end_point[1] = 100.0;
//line_coords->end_point[2] = 100.0;
// 创建部件对象
tag_t line = NULL_TAG;
//创建实线对象
UF_CURVE_create_line(line_coords,&line);
//释放内存
delete line_coords;
UF_CALL(UF_terminate());
}
作业五
创建一个Cylinder特征,输出其所在图层和颜色
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//布尔操作
UF_FEATURE_SIGN sign = UF_NULLSIGN;
//原点位置0,0,0
double origin[] = { 0,0,0 };
//高
char * height = "100";
//直径
char * diam = "10";
//方位
double direction[] = { 0,0,1 };
//圆柱对象
tag_t cyl_tag = NULL_TAG;
//创建一个圆柱特征
UF_MODL_create_cylinder(sign, null_tag, origin, height, diam, direction, &cyl_tag);
//实体对象
tag_t blk_body = NULL_TAG;
//输出实体对象
UF_MODL_ask_feat_body(cyl_tag, &blk_body);
//圆柱对象的显示属性
UF_OBJ_disp_props_t dispProps;
//查询属性
UF_OBJ_ask_display_properties(blk_body, &dispProps);
UF_UI_open_listing_window();
//编辑结果
char s1[200];
sprintf_s(s1, "颜色为:%d\n图层为:%d",dispProps.color, dispProps.layer);
//窗体输出结果
UF_UI_write_listing_window(s1);
UF_CALL(UF_terminate());
}
作业六
创建一个Cylinder特征,再输出其两个edge的中心坐标。 需要使用到下列函数:
UF_MODL_create_cylinder UF_MODL_ask_feat_edges UF_EVAL_initialize UF_EVAL_ask_arc
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//布尔操作
UF_FEATURE_SIGN sign = UF_NULLSIGN;
//原点位置0,0,0
double origin[] = { 0,0,0 };
//高
char * height = "100";
//直径
char * diam = "10";
//方位
double direction[] = { 0,0,1 };
//圆柱对象
tag_t cyl_tag = NULL_TAG;
//创建一个圆柱特征
UF_MODL_create_cylinder(sign, null_tag, origin, height, diam, direction, &cyl_tag);
uf_list_p_t blkEdges = nullptr;
//获取edges集合
UF_MODL_ask_feat_edges(cyl_tag,&blkEdges);
UF_UI_open_listing_window();
//遍历集合
while (blkEdges!=NULL)
{
UF_EVAL_p_t point = NULL;
//获取圆点对象
UF_EVAL_initialize(blkEdges->eid, &point);
UF_EVAL_arc_t arc;
//获取圆心信息
UF_EVAL_ask_arc(point, &arc);
char s1[100];
//输出
sprintf_s(s1, "圆心坐标为:(%lf,%lf,%f)\n", arc.center[0], arc.center[1], arc.center[2]);
UF_UI_write_listing_window(s1);
//释放内存
UF_EVAL_free(point);
//下一个
blkEdges = blkEdges->next;
}
//释放内存
UF_MODL_delete_list(&blkEdges);
UF_CALL(UF_terminate());
}
作业七
遍历当前工作部件中所有的特征,将其类型输出到信息窗口中 查询特征类型可以使用UF_MODL_ask_feat_name 或者 UF_MODL_ask_feat_sysname
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
tag_t obj = NULL_TAG;
//获得workPart
tag_t workPart = UF_ASSEM_ask_work_part();
//类型为特征
int type = UF_feature_type;
UF_UI_open_listing_window();
//根据特征遍历对象
UF_OBJ_cycle_objs_in_part(workPart, type, &obj);
while (obj != NULL_TAG) {
/*
UF_MODL_ask_feat_name函数已经有返回值了,我们想要他再返回一个值,
就需要使用变参,char ** feature_type就是变参,用以返回一个指针
UF_MODL_ask_feat_name()的第二个参数类型为指针的指针char ** feature_name,用以返回一个指针
在函数内部,首先创建一个临时变量来保存该指针的指针,
之后对该临时变量的值进行赋值,即修改了指针的指针的指向,
赋的值就是一个新的内存地址,这个新的内存地址存储了结果,也就是将结果传了出去
feature_name 为指针变量,指向null(存储的是内存地址)
想要改变feature_name的指向,即改变feature_name的值,就需要将它的地址传过去
&feature_name:获取指针变量feature_name的地址
*/
char * feature_name=NULL;
//查询特征属性
UF_MODL_ask_feat_name(obj,&feature_name);
//输出
UF_UI_write_listing_window(feature_name);
UF_UI_write_listing_window("\n");
//释放内存
UF_free(feature_name);
//查询下一个
UF_OBJ_cycle_objs_in_part(workPart, type, &obj);
}
UF_CALL(UF_terminate());
}
作业八
将名为”model.prt”的部件设为当前的显示部件(假设其已经在NX中被打开),在其中创建名为”Length”、值为25的表达式; 再将此表达式的值修改为100
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
/* Initialize the API environment */
if( UF_CALL(UF_initialize()) )
{
return;
}
//定义表达式
char str[] = "Length=25";
//创建表达式
UF_MODL_create_exp(str);
//更新
UF_MODL_update();
//定义表达式值
double rs;
//查询表达式值
UF_MODL_eval_exp("Length", &rs);
char showValue[30];
sprintf_s(showValue,"Length的值为:%lf",rs);
//显示表达式值
uc1601(showValue,1);
//定义修改表达式
char newValue[] = "Length=100";
//修改表达式的值
UF_MODL_edit_exp(newValue);
//更新
UF_MODL_update();
//查询值
UF_MODL_eval_exp("Length", &rs);
char showValue1[50];
sprintf_s(showValue1, "Length修改后的值为:%lf", rs);
//输出表达式值
uc1601(showValue1, 1);
UF_CALL(UF_terminate());
}
作业九
UF_UI_select_with_single_dialog,设置对象过滤器,使之只能选择直的边Linar edge,再使用UF_GEXP_create_length查询并输出此edge的长度
/* 使用UF_UI_select_with_single_dialog,设置对象过滤器,使之只能选择直的边Linar edge,
再使用UF_GEXP_create_length查询并输出此edge的长度
*/
//定义过滤器
static int init_proc(UF_UI_selection_p_t select, void* user_data) {
//数组长度
int num_triples = 1;
//定义选择类型Linar edge
UF_UI_mask_t mask_triples[1];
mask_triples[0].object_type = UF_line_type;
mask_triples[0].object_subtype = 0;
mask_triples[0].solid_type = UF_UI_SEL_FEATURE_LINEAR_EDGE;
/*
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC:把其他的都请除,只允许使用指定的
*/
if ((UF_CALL(UF_UI_set_sel_mask(select,UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
num_triples, mask_triples))) == 0)
{
return (UF_UI_SEL_SUCCESS);
}
else
{
return (UF_UI_SEL_FAILURE);
}
}
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//状态栏提示文字
char cue[] = "请选择Linar edge!";
//弹窗标题
char title[] = "选择Linar edge";
//对话框的用户的操作
int response;
tag_t object=NULL_TAG, view;
double cursor[3];
if (!UF_CALL(UF_UI_select_with_single_dialog(cue, title,
UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, NULL,
&response, &object, cursor, &view)))
{
tag_t feature_tag = NULL_TAG;
//表达式对象
tag_t exp_tag = NULL_TAG;
if (object != NULL_TAG){
//创建长度表达式特征
UF_GEXP_create_length(object, NULL_TAG, &feature_tag,&exp_tag);
//长度
double rs;
//通过表达式标识获得表达式值
UF_MODL_ask_exp_tag_value(exp_tag, &rs);
//结果输出
char buf[UF_UI_MAX_STRING_LEN+1];
sprintf(buf, "已选择的Linar edge的长度为%lf\n", rs);
//显示结果
uc1601(buf, 1);
}
//高亮
UF_DISP_set_highlight(object, 0);
}
UF_CALL(UF_terminate());
}
作业十
UF_UI_select_point_collection,构建多个点,在信息窗口输出所有点的坐标值
//作业十:调用函数UF_UI_select_point_collection,构建多个点,在信息窗口输出所有点的坐标值
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//提示信息
char message[]="请选择所有的点";
//点集合
UF_UI_chained_points_p_t points;
//点的个书
int count;
//操作
int response;
//选择点
UF_UI_select_point_collection(message,true, &points, &count, &response);
UF_UI_open_listing_window();
char buf[UF_UI_MAX_STRING_LEN + 1];
sprintf(buf, "共选择了%d个点\n", count);
UF_UI_write_listing_window(buf);
//遍历点的集合输出点的信息
for (int i = 0; i < count; i++) {
char buf[UF_UI_MAX_STRING_LEN + 1];
sprintf(buf, "第%d个点的坐标为:(%lf,%lf,%lf)\n", i, points[i].pt[0], points[i].pt[1], points[i].pt[2]);
UF_UI_write_listing_window(buf);
}
//释放空间
UF_free(points);
UF_CALL(UF_terminate());
}
作业十一
UF_UI_select_with_single_dialog()在当前部件中选择一个实体对象,再使用UF_TRNS中的函数将此实体对象沿Z轴正方向平移100.
//作业十一:使用UF_UI_select_with_single_dialog()在当前部件中选择一个实体对象,
//再使用UF_TRNS中的函数将此实体对象沿Z轴正方向平移100.
//定义过滤器
static int init_proc(UF_UI_selection_p_t select,void* user_data){
int num_triples = 1;
UF_UI_mask_t mask_triples[] = { UF_solid_type,0,0 };
if ((UF_CALL(UF_UI_set_sel_mask(select,
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
num_triples, mask_triples))) == 0)
{
return (UF_UI_SEL_SUCCESS);
}
else
{
return (UF_UI_SEL_FAILURE);
}
}
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
char cue[] = "请选择要移动的实体!";
char title[] = "选择要移动的实体";
int response;
tag_t object, view;
double cursor[3];
if (!UF_CALL(UF_UI_select_with_single_dialog(cue, title,
UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, NULL,
&response, &object, cursor, &view)))
{
if (object != NULL_TAG) {
double translation[3] = { 0.0,0.0,100.0 };//位移距离(x,y,z)
double matrix_value[12] = { 0.0 };//转换矩阵
uf5943(translation, matrix_value);//返回矩阵以执行线性变换,沿着绝对坐标系的X轴Y轴和Z轴。
tag_t objects_array[] = {object};//对象数组
int count = 1;//数组长度
int move_or_copy = 1;//1 -移动 2 - 复制
int dest_layer = 0;//图层
int trace_curves = 2;//轨迹曲线状态1 means on, 2 means off.
tag_t *copies = NULL;//这是当move_or_copy等于1(移动)时不使用。当move_or_copy为2(副本)时,应设置一个为空tag_t
tag_t trace_curve_group = NULL;//当trace_curves=2时,此处设置为null
int status_value = 0;
uf5947(matrix_value, objects_array, &count, &move_or_copy, &dest_layer, &trace_curves, copies, &trace_curve_group, &status_value);
}
UF_DISP_set_highlight(object, 0);
}
UF_CALL(UF_terminate());
}
作业十二
UF_UI_select_with_single_dialog在当前的显示部件中选择片体(sheet body),再为其设置名为s1、实数类型的属性,此属性中包含5个值,分别为1、2 、3、4、5.
//作业十三:使用UF_UI_select_with_single_dialog在当前的显示部件中选择片体(sheet body),
//再为其设置名为s1、实数类型的属性,此属性中包含5个值,分别为1、2 、3、4、5.
//定义过滤器
static int init_proc(UF_UI_selection_p_t select, void* user_data) {
//数组长度
int num_triples = 1;
//定义选择类型sheet body
UF_UI_mask_t mask_triples[1];
mask_triples[0].object_type = UF_solid_type;
mask_triples[0].object_subtype = 0;
mask_triples[0].solid_type = UF_UI_SEL_FEATURE_SHEET_BODY;
/*
UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC:把其他的都请除,只允许使用指定的
*/
if ((UF_CALL(UF_UI_set_sel_mask(select, UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,num_triples, mask_triples))) == 0)
{
return (UF_UI_SEL_SUCCESS);
}
else
{
return (UF_UI_SEL_FAILURE);
}
}
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
//状态栏提示文字
char cue[] = "请选择片体!";
//弹窗标题
char title[] = "选择片体";
//对话框的用户的操作
int response;
tag_t object = NULL_TAG, view;
double cursor[3];
if (!UF_CALL(UF_UI_select_with_single_dialog(cue, title,UF_UI_SEL_SCOPE_NO_CHANGE, init_proc, NULL,
&response, &object, cursor, &view))){
if (object != NULL_TAG) {
//设置一个值
//UF_ATTR_value_s value;
//value.type = UF_ATTR_integer;
//value.value.integer = 1;
//UF_ATTR_assign(object, "s1", value);
//UF_ATTR_value_t v1;
//UF_ATTR_read_value(object,"s1", UF_ATTR_integer, &v1);
//char buf[UF_UI_MAX_STRING_LEN + 1];
//sprintf(buf, "%d\n", v1.value.integer);
//UF_UI_write_listing_window(buf);
//uc1601(buf, 1);
//属性标题
char title[] = "s1";
//定义索引数组
int attr[] = { 1,2,3,4,5 };
//赋值
for (int i = 0; i < 5; i++) {
UF_ATTR_set_integer_user_attribute(object, title, i, attr[i], false);
}
UF_MODL_update();
int value;
bool isfound;
UF_UI_open_listing_window();
for (int i = 0; i < 5; i++) {
//获取s1指定索引的值
UF_ATTR_get_integer_user_attribute(object, title, i, &value, &isfound);
if (isfound) {
char buf[UF_UI_MAX_STRING_LEN + 1];
sprintf(buf, "标题为%s的索引%d的值为%d\n", title,i, value);
UF_UI_write_listing_window(buf);
}
}
}
//高亮
UF_DISP_set_highlight(object, 0);
}
UF_CALL(UF_terminate());
}
作业十三
新建一个文本文件;再创建一个包含多行文本控件的用户界面,在界面的构造函数中读取文件中每行的内容并填充多行文本 输入框;
int CHANGE_action_0_act_cb ( int dialog_id, void * client_data,
UF_STYLER_item_value_type_p_t callback_data)
{
if ( UF_initialize() != 0)
return ( UF_UI_CB_CONTINUE_DIALOG );
//1.从文件中获取值
//加载文件
ifstream myfile("C:\\workplace\\NX\\NXDEV2.0\\TEST\\test13_12\\test13_12\\value.txt");
string line;
int intvalue;
double realvalue;
string strvalue;
string values[10];//将文件中的数值存放到该数组中
int index = 0;
if (myfile) { // 有该文件
while (getline(myfile, line)) { // line中不包括每行的换行符
values[index++] = line;
}
}
//类型转换
intvalue = atoi(values[0].c_str());
realvalue = atof(values[1].c_str());
strvalue = values[2];
UF_STYLER_item_value_type_t value;
//int类型
value.item_id = "INT";
value.item_attr = UF_STYLER_VALUE;
value.value.integer = intvalue;
UF_STYLER_set_value(dialog_id,&value);
//real类型
value.item_id = "REAL";
value.item_attr = UF_STYLER_VALUE;
value.value.real = realvalue;
UF_STYLER_set_value(dialog_id, &value);
//str类型
value.item_id = "STR";
value.item_attr = UF_STYLER_VALUE;
value.value.string = (char*)strvalue.c_str();
UF_STYLER_set_value(dialog_id, &value);
//释放
UF_STYLER_free_value(&value);
UF_terminate ();
return (UF_UI_CB_CONTINUE_DIALOG);
}
12
10.03214
isStr
#include <sstream>
std::stringstream stream1;
stream1 <<"The Selected Option id :"<< value.value.integer;
UF_UI_open_listing_window();
UF_UI_write_listing_window((stream1.str().c_str()));
作业十四:
创建用户界面,其中包含一个单选列表(Option)和两个实数输入框(Radius和Diameter),,其中单选列表用于选择输入cylinder之直径或者半径,设置回调函数响应界面的变化
int CHANGE_value_change ( int dialog_id, void * client_data,
UF_STYLER_item_value_type_p_t callback_data){
if ( UF_initialize() != 0)
return ( UF_UI_CB_CONTINUE_DIALOG );
/*
1.当单选按钮选择的是半径的时候,半径输入框能用,直径输入框禁用
2.当单选按钮选择的是直径的时候,直径输入框能用,半径输入框禁用
*/
//获取单选按钮的值OPTION
UF_STYLER_item_value_type_t value;
value.item_id = "OPTION";
value.item_attr = UF_STYLER_VALUE;
UF_STYLER_ask_value(dialog_id, &value);
UF_UI_option_toggle_t userOption;
userOption = value.value.option_toggle;
//单选选项
int op = userOption.choice;
//选择半径,隐藏直径
if (op == 0) {
value.item_id = "RADIUS";
value.item_attr = UF_STYLER_SENSITIVITY;
value.value.integer = 1;
UF_STYLER_set_value(dialog_id, &value);
value.item_id = "DIAMETER";
value.item_attr = UF_STYLER_SENSITIVITY;
value.value.integer = 0;
UF_STYLER_set_value(dialog_id, &value);
}
else {//选择直径,隐藏半径
value.item_id = "RADIUS";
value.item_attr = UF_STYLER_SENSITIVITY;
value.value.integer = 0;
UF_STYLER_set_value(dialog_id, &value);
value.item_id = "DIAMETER";
value.item_attr = UF_STYLER_SENSITIVITY;
value.value.integer = 1;
UF_STYLER_set_value(dialog_id, &value);
}
UF_terminate ();
return (UF_UI_CB_CONTINUE_DIALOG);
}
作业十五
作业十五:创建如下所示的Excel文件用于存储Blocks的长宽高尺寸;在创建仅包含下拉列表框Option Menu的UI Styler界面,在界面的初始化函数中读取Blocks的型号,即Excel第一列,并以此填充Option Menu;在界面的apply函数中,根据所选的Block型号,创建与其尺寸对应的Block特征
//excel中的四列
string sizeCol[4];
double lengthCol[4];
double widthCol[4];
double heightCol[4];
//wchar_t to string
extern void Wchar_tToString(std::string& szDst, wchar_t *wchar)
{
wchar_t * wText = wchar;
// WideCharToMultiByte的运用
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);
char *psText; // psText为char*的临时数组,作为赋值给std::string的中间变量
psText = new char[dwNum];
// WideCharToMultiByte的再次运用
WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);
szDst = psText;// std::string赋值
delete[]psText;// psText的清除
}
//读取excel,将结果赋值给sizeCol、lengthCol、widthCol、heightCol
void init() {
Book *book = xlCreateBook();
if (book->load(L"C:\\Users\\26069\\Desktop\\学习\\nx二次开发\\资源\\Blocks.xls"))
{
Sheet* sheet = book->getSheet(0);
if (sheet) {
int row, col;
//读取size内容
row = 1;
col = 0;
while (sheet->cellType(row, col) != libxl::CellType::CELLTYPE_EMPTY) {
const wchar_t *sizeValue = sheet->readStr(row, col);
string v1;
Wchar_tToString(v1, (wchar_t *)sizeValue);
sizeCol[row - 1] = v1;
row++;
}
//读取length内容
row = 1;
col = 1;
while (sheet->cellType(row, col) != libxl::CellType::CELLTYPE_EMPTY) {
lengthCol[row - 1] = sheet->readNum(row, col);
row++;
}
//读取width内容
row = 1;
col = 2;
while (sheet->cellType(row, col) != libxl::CellType::CELLTYPE_EMPTY) {
widthCol[row - 1] = sheet->readNum(row, col);
row++;
}
//读取height内容
row = 1;
col = 3;
while (sheet->cellType(row, col) != libxl::CellType::CELLTYPE_EMPTY) {
heightCol[row - 1] = sheet->readNum(row, col);
row++;
}
}
book->release();
}
else {
uc1601("Error",1);
}
}
//为option赋初值
int CHANGE_init_option_menu ( int dialog_id, void * client_data,
UF_STYLER_item_value_type_p_t callback_data){
if ( UF_initialize() != 0)
return ( UF_UI_CB_CONTINUE_DIALOG );
//读取excel
init();
//给OPTION_0赋值
UF_STYLER_item_value_type_t value;
value.item_id = "OPTION_0";
value.item_attr = UF_STYLER_SUBITEM_VALUES;
char* stringsValue[5];
for (int i = 0; i < 4; i++)
{
//要使用new,重新分配内存地址
char *v=new char(100);
strcpy(v, sizeCol[i].c_str());
stringsValue[i] = v;
}
value.value.strings = stringsValue;
value.count = 4;
UF_STYLER_set_value(dialog_id, &value);
UF_STYLER_free_value(&value);
UF_terminate ();
return (UF_UI_CB_CONTINUE_DIALOG);
}
//根据选项创建指定的block
int CHANGE_apply_cb ( int dialog_id, void * client_data,
UF_STYLER_item_value_type_p_t callback_data){
if ( UF_initialize() != 0)
return ( UF_UI_CB_CONTINUE_DIALOG );
//获取option的选项
UF_STYLER_item_value_type_t value;
value.item_id = "OPTION_0";
value.item_attr = UF_STYLER_VALUE;
UF_STYLER_ask_value(dialog_id, &value);
//用户选项
int iItemSelected = value.value.integer;
UF_STYLER_free_value(&value);
//创建实体
UF_FEATURE_SIGN sign = UF_NULLSIGN;//没有布尔操作
double origin[] = { 0,0,0 };//原点位置0,0,0
char length[20];//长表达式
char width[20];//宽表达式
char height[20];//高表达式
//为长宽高表达式赋值
sprintf_s(length, "length=%lf", lengthCol[iItemSelected]);
sprintf_s(width, "width=%lf", widthCol[iItemSelected]);
sprintf_s(height, "height=%lf", heightCol[iItemSelected]);
char* lengths[] = { length,width,height };//长宽高
//创建实体
tag_t blk_feat = NULL_TAG;
UF_MODL_create_block(sign, null_tag, origin, lengths, &blk_feat);//创建实体
UF_terminate ();
return (UF_UI_CB_CONTINUE_DIALOG);
}
使用了libxl这个读取excel的类库,使用的资源是这三个文件夹中的
设置vs环境,引入libxl类库
在项目–>属性中要设置三个地方
C/C++–>常规–>附加包含目录:include_cpp
链接器–>常规–>附加库目录:lib4
–>输入–>附加依赖项增加:libxl.lib值此外还要将bin64中的libxl.dll放到生成的dll的目录下,保持与dll同级
作业十六
作业十六:创建一个直径为20、高为100、原点位于(0,0,0)、方向为Z轴正方向的的Cylinder,在其顶部表面上创建坐标为(0,0,100)、深为40,直径为5的简单孔(UF_MODL_create_simple_hole)
代码不完美,有瑕疵,功能未实现
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize()) )
{
return;
}
/*
作业十六:创建一个直径为20、高为100、原点位于(0,0,0)、方向为Z轴正方向的的Cylinder,
在其顶部表面上创建坐标为(0,0,100)、深为40,直径为5的简单孔(UF_MODL_create_simple_hole)
*/
UF_FEATURE_SIGN sign = UF_NULLSIGN;
double origin[] = { 0,0,0 };
char * height = "100";
char * diam = "20";
double direction[] = { 0,0,1 };
tag_t cyl_obj_id = NULL_TAG;
//创建一个圆柱特征
UF_MODL_create_cylinder(sign, null_tag, origin, height, diam, direction, &cyl_obj_id);
uf_list_p_t face_list;
tag_t face_tag;
int count, i;
UF_MODL_ask_feat_faces(cyl_obj_id, &face_list);//获取所有面
UF_MODL_ask_list_count(face_list, &count);//面的总数
int faceTypes;
for (i = 0; i<count; i++)
{
UF_MODL_ask_list_item(face_list, i, &face_tag);
UF_MODL_ask_face_type(face_tag, &faceTypes);
if (faceTypes != UF_MODL_PLANAR_FACE) {
UF_MODL_delete_list_item(&face_list, face_tag);
}
}
tag_t placement_face = NULL_TAG, thru_face = NULL_TAG;
UF_MODL_ask_list_item(face_list, 1, &placement_face);
UF_MODL_ask_list_item(face_list,0, &thru_face);
UF_MODL_delete_list(&face_list);
double location_hole[3] = { 0, 0, 100 };
double direction_hole[3] = { 0, 0, -1 };
char *diame_hole = "dia =5";
char *depth_hole = "dep=40";
char *angle_hole = "ang=0";
tag_t hole_tag_hole;
UF_MODL_create_simple_hole(location_hole, direction_hole, diame_hole, depth_hole, angle_hole, placement_face, thru_face, &hole_tag_hole);
UF_CALL(UF_terminate());
}
作业十七
调用UF_UI_open_part函数以选择部件,将打开的部件作为子部件加入到当前显示部件的根节点下,方位任定。
static logical my_error_handler
(
UF_UI_err_data_p_t error_fn_data,
char *file_name,
int error,
UF_PART_load_status_t *error_status,
logical *skip_error_disp
);
extern DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
if( UF_CALL(UF_initialize())) {
return;
}
//作业十七:调用UF_UI_open_part函数以选择部件,将打开的部件作为子部件加入到当前显示部件的根节点下,
//方位任定。
//获取显示部件
tag_t displayPart = UF_PART_ask_display_part();
//UF_UI_open_part选择部件
const char *message = "part open error";
UF_UI_err_t error_handler;
//打开prt
error_handler.type = UF_UI_open_part_fun;
error_handler.fun.open = my_error_handler;
error_handler.fun_data.size = strlen(message) + 1;
error_handler.fun_data.data = message;
char file_name[MAX_FSPEC_SIZE + 1] = "";
tag_t part=NULL_TAG;
int response;
UF_PART_load_status_t part_status;
logical use_display_file = FALSE;
UF_UI_open_part(&error_handler, file_name,&use_display_file,&part,&response,&part_status);
//选择文件
if (response == UF_UI_OK) {
//添加装配
double origin[] = { 0,0,0 };
double matrix[] = { 1,0,0,0,1,0 };
tag_t instanceTag = NULL_TAG;
UF_PART_load_status_s partStatus;
UF_ASSEM_add_part_to_assembly(displayPart, file_name, "Entire Part", "", origin, matrix, 0, &instanceTag, &partStatus);//获取instanceTag
}
else{
uc1601("未选择部件文件", 1);
}
if (part_status.statuses != NULL) {
UF_free(part_status.statuses);
}
if (part_status.file_names != NULL) {
UF_free_string_array(part_status.n_parts,
part_status.file_names);
}
UF_CALL(UF_terminate());
}
static logical my_error_handler
(
UF_UI_err_data_p_t error_fn_data,
char *file_name,
int error,
UF_PART_load_status_t *error_status,
logical *skip_error_disp
)
{
fprintf(stderr, "my_error_handler called with:\n"
" error_fn_data->size = %d\n"
" error_fn_data->data = %s\n"
" file_name = %s\n"
" error = %d\n",
error_fn_data->size,
(const char *)error_fn_data->data,
file_name,
error
);
*skip_error_disp = TRUE;
return TRUE;
}
作业十八
:在NXOpen中存在Selection类,调用其中的SelectTaggedObjects方法选择当前work part中的对象,要求设置过滤器使只有planar faces课被选中;将所有被选 中的faces的tag输出到信息窗口(编程语言不限)。
public static int Main(string[] args) {
int retValue = 0;
try {
theProgram = new Program();
/*
作业十八:在NXOpen中存在Selection类,调用其中的SelectTaggedObjects方法选择当前work part中的对象,
要求设置过滤器使只有planar faces课被选中;将所有被选 中的faces的tag输出到信息窗口(编程语言不限)。
*/
theUfSession.Ui.OpenListingWindow();
string message = "请选择planar faces!";
string title = "请选择planar faces";
//工作部件
NXOpen.Selection.SelectionScope scope = NXOpen.Selection.SelectionScope.WorkPart;
NXOpen.Selection.Response res;
bool includeFeatures = false;
bool keepHighlighted = false;
TaggedObject[] objectArray;
NXOpen.Selection.SelectionAction action = NXOpen.Selection.SelectionAction.ClearAndEnableSpecific;
NXOpen.Selection.MaskTriple mtp = new NXOpen.Selection.MaskTriple();
//设置过滤器UF_UI_SEL_FEATURE_PLANAR_FACE
mtp.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_PLANAR_FACE;
NXOpen.Selection.MaskTriple[] maskArray = new Selection.MaskTriple[1] { mtp };
//选择对象
res = theUI.SelectionManager.SelectTaggedObjects(message, title, scope, action, includeFeatures, keepHighlighted, maskArray, out objectArray);
//点击确定
if (res == NXOpen.Selection.Response.Ok) {
theUfSession.Ui.WriteListingWindow("总共选择了" + objectArray.Length+ "个planar faces");
theUfSession.Ui.WriteListingWindow("\n");
int i = 0;
foreach (TaggedObject o in objectArray) {
Face face = o as Face;
theUfSession.Ui.WriteListingWindow("第"+(++i)+ "个planar faces信息为:");
theUfSession.Ui.WriteListingWindow(face.Tag.ToString());
theUfSession.Ui.WriteListingWindow("\n");
}
} else if (res == NXOpen.Selection.Response.Cancel) {
theUI.NXMessageBox.Show("警告信息",NXOpen.NXMessageBox.DialogType.Warning,"没有选择对象");
}
theProgram.Dispose();
} catch (NXOpen.NXException ex) {
// ---- Enter your exception handling code here -----
theUI.NXMessageBox.Show("异常信息", NXOpen.NXMessageBox.DialogType.Warning, ex.ToString());
}
return retValue;
}
作业十九
构建一个包含”Body Collector”和”Select Part from List”控件的用户界面,将选中的实体关联拷贝到指定的部件中,实体拷贝使用UF_WAVE_create_linked_body函数。编程语言不限。
/*作业十九:构建一个包含"Body Collector"和"Select Part from List"控件的用户界面,
* 将选中的实体关联拷贝到指定的部件中,实体拷贝使用UF_WAVE_create_linked_body函数。编程语言不限。*/
public TaggedObject[] bss;
TaggedObject[] bps;
public int update_cb( NXOpen.BlockStyler.UIBlock block){
try {
if(block == bodySelect0){
bss = bodySelect0.GetSelectedObjects();
}else if(block == selectPart0){
bps = selectPart0.GetSelectedObjects();
}
} catch (Exception ex){
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
}
return 0;
}
public int ok_cb(){
int errorCode = 0;
try{
errorCode = apply_cb();
for (int i = 0; i < bps.Length; i++) {
Part part = bps[i] as Part;
for (int j = 0; j < bss.Length; j++) {
Body body = bss[j] as Body;
Tag object_in_part = new Tag();
Tag linked_feature;
theUfSession.Wave.CreateLinkedBody(body.Tag, object_in_part,part.Tag, false, out linked_feature);
//提示
theUI.NXMessageBox.Show("提示信息", NXMessageBox.DialogType.Information, "操作成功!");
}
}
}
catch (Exception ex){
errorCode = 1;
theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
}
return errorCode;
}
作业二十
使用KF创建Block、Cylinder特征,再添加布尔加操作
#! NX/KF 4.0
DefClass: %a2.prt (ug_base_part);
# 部件的根级别动态规则
# 添加或移除该附注下面的子规则和属性
(Child) block1: {
Class, nx_block,
Length, 10,
width, 10,
height, 10
};
(Child) cylinder1: {
Class, nx_cylinder,
diameter, 20.0,
height, 30.0,
direction, Vector(0,0,1),
Boolean_Option_Type, unite,
Boolean_Option_Target_Bodies, {body1:}
};
(Child) body1: {
Class, ug_body,
Feature, {block1:}
};
作业二十一
使用KF创建Block,再将其顶面四使用条边进行倒圆角
#! NX/KF 4.0
DefClass: %a2.prt (ug_base_part);
# Root level dynamic rules of the Part
# Add or remove child rules and attributes below this commment
(Child) b1: {
Class, nx_block,
Length, 10,
Width, 10,
Height, 10
};
(List Modifiable) face1: ug_feature_askFaceClosestToPoint( b1:, point(5,5,10), "use_more_accuracy?", false );
(List Modifiable) edges1: ug_face_askEdges(first( face1:) );
(Number Parameter) Radius: 1.0;
(Child) Blend: {
Class; ug_edge_blend;
Edge_Blend_References; edges1:;
Radius; Radius:;
};
作业二十二
使用KF画首尾相连的三条线,构成一个三角形,再将此三角形进行拉伸
#! NX/KF 4.0
DefClass: %a2.prt (ug_base_part);
# Root level dynamic rules of the Part
# Add or remove child rules and attributes below this commment
(Point Modifiable) Point1: point(0,0,0);
(Point Modifiable) Point2: point(0,100,0);
(Point Modifiable) Point3: point(100,0,0);
(Child) line1: {
Class, nx_line,
Start_Point, point1:,
End_Point, point2:
};
(Child) line2: {
Class, nx_line,
Start_Point, point2:,
End_Point, point3:
};
(Child) line3: {
Class, nx_line,
Start_Point, point1:,
End_Point, point3:
};
(Child) Direction: {
Class; nx_direction;
Vector; vector(0,0,1);
};
(Child) Section2: {
Class; ug_section;
Chain_Rules; {Single_Curves,line1:,line2:,line3:};
};
(Child) Extrude2: {
Class; nx_extrude;
Section; Section2:;
Direction; Direction:;
Draft_Enabled; true;
Draft_Draft_Type; simple_from_profile;
Draft_Draft_Angle; -10;
Limits_Limit_Opt; nonsymmetric_offset;
Limits_Start_Extend_Value; 0;
Limits_End_Extend_Value; 100;
};
作业二十三
使用KF在绝对坐标系的XZ平面内画圆弧,其直径为10,坐标为(50,0,50),再将此圆弧绕Z轴旋转360度
#! NX/KF 4.0
DefClass: %a2.prt (ug_base_part);
# Root level dynamic rules of the Part
# Add or remove child rules and attributes below this commment
(Child) arc: {
Class, nx_arc,
radius, 10,
orientation, {center, point(50,0,50), x_direction, vector(1,0,0), y_direction, vector(0,0,1)}
};
(Child) section: {
Class, ug_section,
Chain_Rules, {Single_Curves, arc:}
};
(Child) direction: {
Class, nx_direction,
Vector, vector(0,0,1)
};
(Child) Point: {
Class, nx_point,
Coordinates, point(0,0,50)
};
(Child) axis: {
Class, nx_axis,
Point, point:,
direction, direction:
};
(Number Parameter) angle_start: 0;
(Number Parameter) angle_end: 360;
(Child) revolve: {
Class, nx_revolve,
section, section:,
axis, axis:,
Limits_Start_Extend_Value, angle_start:,
Limits_End_Extend_Value, angle_end:
};
作业二十四
使用child list创建矩形阵列,行数、列数及行间距、列间距均由外部输入;
#! NX/KF 4.0
DefClass: test24 (ug_base_part);
(integer parameter modifiable)row: 5;
(integer parameter modifiable)col: 3;
(integer parameter modifiable)row_spac: 10;
(integer parameter modifiable)col_spac: 10;
(child list)rs:
{
class, ug_block;
quantity, row:*col:;
origin, Point((mod((child:index: - 1),col:)*col_spac:),round((child:index: - 2)/col:)*row_spac:,0);
};
作业二十五
使用ug_cycleObjectsByType函数遍历当前工作部件中的Edges,并将其Tag输出到信息窗口中。
#! NX/KF 4.0
# 使用ug_cycleObjectsByType函数遍历当前工作部件中的Edges,并将其Tag输出到信息窗口中。
DefClass: test25 (ug_base_part);
# 项目初始化时自动求值
(list) demandvalue: {rs:};
(any)edges1: @{
$partName << ug_askCurrentWorkPart();
$edges<<ug_cycleObjectsByType({ug_edge},$partName);
};
(any)rs: loop
{
for $edge in edges1:;
for $aa is ug_cam_askObjectTag($edge);
do ug_printvalue($aa);
};
作业二十六
使用UIStyler创建用户界面,其中包括一个按键用于选择实体中的边(Edge),要求可选任意类型的边;再向信息窗口输出所选的边的长度。(使用ug_edge类中的total_arc_length属性)
#! NX/KF 4.0
#使用UIStyler创建用户界面,其中包括一个按键用于选择实体中的边(Edge),
#要求可选任意类型的边;再向信息窗口输出所选的边的长度。
#(使用ug_edge类中的total_arc_length属性)
#
DefClass: test26 (ug_base_part);
(list) demandvalue: {rs:};
(list parameter modifiable) select: {};
(list) select_mask: {edge};
(any)rs: loop
{
for $edge in select:;
do ug_printvalue(nth(5,ug_curve_askProperties($edge)));
};
作业二十七
使用%ui_comp及其派生类创建用户界面,选择实体中的边(Edges)和输入直径并创建边倒圆(Blend)。
#! NX/KF 4.0
#使用%ui_comp及其派生类创建用户界面,选择实体中的边(Edges)和
#输入直径并创建边倒圆(Blend)。
DefClass: test27 (ug_base_part %ui_comp);
(list)dialogitems: {selection:,diameter:};
(Child) selection: {
Class, %ui_comp_selection;
Many, true;
SnapPointOverlay, false;
SoUpdateOption, 3;
Label, "Select Objects";
ToolTip, "Select Objects";
Scope, 1;
FilterTriple, {{70,3,1}};
SelectedObjects, {};
SelectedObject, SelectedObjects: ;
};
(Child) diameter: {
Class, %ui_comp_double;
value, 5;
unit, "";
MaximumValue, 1.0e19;
MinimumValue, -1.0e19;
Width, 0;
VisibleDecimals, 2;
};
(Child) new_ug_edge_blend: {
Class, ug_edge_blend;
Edge_Blend_References, selection:SelectedObjects:;
radius, diameter:value:/2;
Smooth_Overflow?, TRUE;
Cliff_Overflow?, TRUE;
Notch_Overflow?, TRUE;
Twist_Patches?, TRUE;
Soften_Vertices?, FALSE;
Blend_Instances?, FALSE;
Overlap_Resolution, Overlap_maintain_and_intersect;
Blend_Order, Order_of_blending_convex_first;
Corner_Setback, Setback_include_with_corner;
};