基于C/C++的UG二次开发流程

2024-05-01 1250阅读

文章目录

  • 基于C/C++的UG二次开发流程
    • 1 环境搭建
      • 1.1 新建工程
      • 1.2 项目属性设置
      • 1.3 添加入口函数并生成dll文件
      • 1.4 执行程序
      • 1.5 ufsta入口
        • 1.5.1 创建程序部署目录结构
        • 1.5.2 创建菜单文件
        • 1.5.3 设置系统环境变量
        • 1.5.4 制作对话框
        • 1.5.5 创建代码
        • 1.5.6 部署和执行

          基于C/C++的UG二次开发流程

          1 环境搭建

          UG/Open API(UG 开放应用程序接口),也称 User Function(用户函数,简称 UF)。

          UF 的编程可以采用标准 C 或 C++两种方式作为开发语言(这里我们使用C++)。

          针对程序运行的环境不同,UF 程序又分为外部 UF 和内部 UF 两种形式。

          外部 UF 程序是可执行程序(*.EXE)。优点是不必启动 UG,属于后台运行,缺点是不能实现用户的交互操作。一般多用于 Part 文件大量创建、存取和管理或控制出图,而不适用于用户交互性的几何建模和修改。

          内部 UF 是以**动态链接库(*.DLL)**的形式创建并编译的。UG 调用内部 UF 的方式有两种,一种是启动 UG 后,点击菜单:【文件】→【执行】→【NX 打开】,从中选择需要执行的 DLL 文件(程序入口点:ufusr),另一种则是从用户创建的菜单中(Menu Script)调出用户定制的界面(UI Styler)来运行(程序入口点:ufsta)。内部 UF在用户的交互、屏幕选取等的复杂操作上具有优势。

          下文中我们主要介绍内部UF程序的开发。

          1.1 新建工程

          启动VS2022,由于是内部UF的开发,新建动态链接库(DLL)项目。

          基于C/C++的UG二次开发流程

          1.2 项目属性设置

          基于C/C++的UG二次开发流程

          基于C/C++的UG二次开发流程

          基于C/C++的UG二次开发流程

          libufun.lib
          libugopenint.lib
          libvmathpp.lib
          libnxopencpp.lib
          libnxopenuicpp.lib
          

          1.3 添加入口函数并生成dll文件

          新建项目后,VS2022会默认生成framework.h、pch.h、pch.cpp、dllmain.cpp文件。接下来我们只需要修改dllmain.cpp,修改后内容如下:

          // dllmain.cpp : 定义 DLL 应用程序的入口点。
          #include "pch.h"
          #include "uf.h"				// 包含常用 UF 函数的声明
          #include "uf_modl.h"		// 包含建模相关的 UF 函数声明
          #include "uf_ui.h"			// 包含界面操作相关的 UF 函数声明
          #include 
          #define UF_CALL(X) (report( __FILE__, __LINE__, #X, (X)))
          // 用于程序调试
          static int report(char* file, int line, char* call, int irc)
          {
          	if (irc)
          	{
          		char msg[133];
          		printf("%s, line %d: %s\n", file, line, call);
          		(UF_get_fail_message(irc, msg)) ?
          			printf("returned a %d\n", irc) :
          			printf("returned error %d: %s\n", irc, msg);
          	}
          	return(irc);
          }
          // 实际工作函数
          static void do_ugopen_api(void)
          {
          	/* 用户在此编写自己的 UF 程序 */
          	/* 下面示例为创建长方体 */
          	UF_FEATURE_SIGN sign = UF_NULLSIGN;
          	double block_orig[3] = { 0.0,0.0,0.0 }; // 原点
          	char* block_len[3] = { "1","2","3" };	// 三边长
          	tag_t blk_obj;
          	UF_CALL(UF_MODL_create_block1(sign, block_orig, block_len, &blk_obj)); // 调用UF_MODL_create_block1函数创建长方体
          }
          void ufusr(char* param, int* retcode, int paramLen)
          {
          	if (!UF_CALL(UF_initialize()))//获取二次开发许可 
          	{
          		do_ugopen_api();//实际工作函数 
          		UF_CALL(UF_terminate());//释放二次开发许可 
          	}
          	else
          	{
          		uc1601("获取开发许可失败,退出!", 1);//获取二次开发许可失败,提示用户 
          	}
          }
          // 卸载函数
          int ufusr_ask_unload(void)
          {
          	return (UF_UNLOAD_IMMEDIATELY);//完成操作后立即从内存中卸载
          }
          

          修改属性页,将符合模式改为否,防止编译运行报错“const char *“ 类型的实参与 “char *“ 类型的形参不兼容。

          参考文章:「VS」“const char *“ 类型的实参与 “char *“ 类型的形参不兼容

          基于C/C++的UG二次开发流程

          最后点击运行,即可得到内部UF的dll文件。

          基于C/C++的UG二次开发流程

          1.4 执行程序

          打开UG,新建一个part文件。Ctrl+U打开上一步生成的DLL文件(test.dll)。UG 会执行此动态库中的入口函数ufusr,在 UG 建模工作区中生成一个长方体。

          基于C/C++的UG二次开发流程

          1.5 ufsta入口

          在上面我们执行内部UF程序的方法是从ufusr入口进入(即Ctrl+U执行DLL文件),接下来我们介绍从ufsta入口进入的方法(即UI交互执行对应回调函数)。

          1.5.1 创建程序部署目录结构

          首先创建一个工作目录,其中分别再创建两个子目录“startup”和“application”。前者用来存放菜单文件(*.men)和动态库文件(*.dll),后者存放对话框文件(*.dlg)。

          基于C/C++的UG二次开发流程-

          1.5.2 创建菜单文件

          在startup目录下创建一个菜单文件(test_ufsta.men),内容如下:

          VERSION 120
          EDIT UG_GATEWAY_MAIN_MENUBAR
          HIDE UG_HELP
          !一级菜单编辑,在帮助菜单后
          BEFORE UG_HELP
           CASCADE_BUTTON MENU_TestUfsta
           LABEL TestUfsta
          END_OF_BEFORE 
          !二级菜单编辑
          MENU MENU_TestUfsta 
           BUTTON BUTTON_TestUfsta 
           LABEL 测试ufsta 
           ACTIONS TestUfsta.dlg
          END_OF_MENU
          
          1.5.3 设置系统环境变量

          新建一个环境变量UGII_USER_DIR,将上面的程序工作目录作为值。

          基于C/C++的UG二次开发流程

          新建完成后,打开UG,点击菜单,即可得到我们想要的效果。

          如果出现中文乱码的问题,将men文件采用ANSI编码保存即可解决。

          基于C/C++的UG二次开发流程

          1.5.4 制作对话框

          UG中提供了UI Styler模块用于制作对话框UI,支持图形化操作,自动生成代码框架(类似于Qt Designer)。该模块的打开方式如下(需要先打开一个部件):

          基于C/C++的UG二次开发流程

          我们便可以得到一个最基础的对话框,左下角为预览效果,左上角为控件对象层级树,右边为控件对象属性。

          基于C/C++的UG二次开发流程

          点击界面上方工具栏中的按钮,即可在对话框中添加一个按钮。

          基于C/C++的UG二次开发流程

          接着我们将按钮的标签更改成一个我们想要名称,最后点击保存,选择使用的语言(这里选择C++),文件名为TestUfsta.dlg,保存到application目录下,

          基于C/C++的UG二次开发流程

          • xxx.dlg。对话框资源文件。

          • xxx.hxx。对此对话框编程使用的头文件。

          • xxx_template.c。对此对话框编程使用的代码框架。

            1.5.5 创建代码

            和ufusr入口一样,新建一个命名为TestUfsta的DLL工程,将上一步生成的xxx.h文件拷贝到工程目录下,再将xxx_template.c文件中的一个宏定义和两个静态变量,以及ufsta(UF 的入口点)、CHANGE_apply_cb(对话框上【apply】按钮的回调函数)、CHANGE_action_0_act_cb(对话框上用户定制的【创建长方体】按钮的回调函数)三个函数复制到TestUfsta.cpp中。修改后内容如下:

            #include  
            #include  
            #include  
            #include  
            #include  
            #include  
            #include  
            #include 
            #include 
            #include "TestUfsta.h"
            #define CHANGE_CB_COUNT ( 2 + 1 ) /* Add 1 for the terminator */
            #define UF_CALL(X) (report( __FILE__, __LINE__, #X, (X)))
            // 用于程序调试
            static int report(char* file, int line, char* call, int irc)
            {
                if (irc)
                {
                    char msg[133];
                    printf("%s, line %d: %s\n", file, line, call);
                    (UF_get_fail_message(irc, msg)) ?
                        printf("returned a %d\n", irc) :
                        printf("returned error %d: %s\n", irc, msg);
                }
                return(irc);
            }
            // 实际工作函数
            static void do_ugopen_api(void)
            {
                /* 用户在此编写自己的 UF 程序 */
                /* 下面示例为创建长方体 */
                UF_FEATURE_SIGN sign = UF_NULLSIGN;
                double block_orig[3] = { 0.0,0.0,0.0 }; // 原点
                char* block_len[3] = { "1","2","3" };	// 三边长
                tag_t blk_obj;
                UF_CALL(UF_MODL_create_block1(sign, block_orig, block_len, &blk_obj)); // 调用UF_MODL_create_block1函数创建长方体
            }
            static UF_STYLER_callback_info_t CHANGE_cbs[CHANGE_CB_COUNT] =
            {
             {UF_STYLER_DIALOG_INDEX, UF_STYLER_APPLY_CB        , 0, CHANGE_apply_cb},
             {CHANGE_ACTION_0       , UF_STYLER_ACTIVATE_CB     , 0, CHANGE_action_0_act_cb},
             {UF_STYLER_NULL_OBJECT, UF_STYLER_NO_CB, 0, 0 }
            };
            static UF_MB_styler_actions_t actions[] = {
                { "TestUfsta.dlg",  NULL,   CHANGE_cbs,  UF_MB_STYLER_IS_NOT_TOP },
                { NULL,  NULL,  NULL,  0 } /* This is a NULL terminated list */
            };
            extern void ufsta(char* param, int* retcode, int rlen)
            {
                int  error_code;
                if ((UF_initialize()) != 0)
                    return;
                if ((error_code = UF_MB_add_styler_actions(actions)) != 0)
                {
                    char fail_message[133];
                    UF_get_fail_message(error_code, fail_message);
                    printf("%s\n", fail_message);
                }
                UF_terminate();
                return;
            }
            int CHANGE_apply_cb(int dialog_id,
                void* client_data,
                UF_STYLER_item_value_type_p_t callback_data)
            {
                /* Make sure User Function is available. */
                if (UF_initialize() != 0)
                    return (UF_UI_CB_CONTINUE_DIALOG);
                /* ---- Enter your callback code here ----- */
                UF_terminate();
                /* Callback acknowledged, do not terminate dialog                 */
                /* A return value of UF_UI_CB_EXIT_DIALOG will not be accepted    */
                /* for this callback type.  You must respond to your apply button.*/
                return (UF_UI_CB_CONTINUE_DIALOG);
            }
            int CHANGE_action_0_act_cb(int dialog_id,
                void* client_data,
                UF_STYLER_item_value_type_p_t callback_data)
            {
                /* Make sure User Function is available. */
                if (UF_initialize() != 0)
                    return (UF_UI_CB_CONTINUE_DIALOG);
                /* ---- Enter your callback code here ----- */
                do_ugopen_api();
                UF_terminate();
                /* Callback acknowledged, do not terminate dialog */
                return (UF_UI_CB_CONTINUE_DIALOG);
                /* or Callback acknowledged, terminate dialog.    */
                /* return ( UF_UI_CB_EXIT_DIALOG );               */
            }
            

            运行生成DLL。

            对于VS2022,新建DLL工程后会默认生成和使用pch.h作为预编译头文件,为了不必要的麻烦,我们将工程属性设置为不使用预编译头文件,即可删除pch相关的文件。

            基于C/C++的UG二次开发流程

            1.5.6 部署和执行

            将所生成的DLL文件拷贝到startup目录下,打开UG即可成功运行。

            基于C/C++的UG二次开发流程

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]