NX二次开发

入门

环境准备

  1. NX12.0

  2. 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,运行即可

01.png

02.png

入口函数

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

image-20200331215318948

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 所示给出了一个应用开发程序的目录结构,开发者可以根据

实际情况做适当调整。

创建第一个用户界面程序

  1. nx–>文件–>所有应用模块–>开发人员–>NX6中定制用户界面的样式
  2. 保存文件到workdir(推荐的文件夹名:其中包含application和startup两个文件夹),保存时选择编程语言为c,存放到application文件夹中。
  3. vs2015创建新nx项目,删除原有的源文件,右键项目–>添加–>添加现有项,找到application文件夹中的头文件(.h)和源文件(.c)确定
  4. 修改源文件后缀.c–>.cpp(使用c++作为开发语言)
  5. 取消源文件的注释(MENUBAR HOOKUP HELP Example注释下的ufsta,DIALOG CREATION FROM A USER EXIT HELP Example下的 修改函数名为ufusr)
  6. 设置环境变量UGII_VENDOR_DIR:C:\workplace\NX\NXDEV2.0\workdir(值为application的上一级)
  7. 生成解决方案
  8. 重启nx
  9. 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的类库,使用的资源是这三个文件夹中的

image-20200407202351787

设置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;
};