基于 C++ 的 UG/NX 二次开发环境配置

基于 C++ 的 UG/NX 二次开发环境配置

参考教程:

UG/NX二次开发环境配置方法(nx1980+vs2019)-CSDN博客

NX二次开发VS环境搭建 - 怡宁塑胶模具设计 - 博客园 (cnblogs.com)

NX/UG二次开发环境配置方法—史上最详细版(以NX11.0和Visual Studio 2017为例)_nx二次开发-CSDN博客

在Windows系统以“管理员身份”打开某软件/文件_打开txt文件要管理权限怎么处理-CSDN博客

当前使用 NX2023Visual Studio 2022,NX2023 是 NX2007 系列的更新版本。

1. 配置 Visual Studio

默认此前已经完成了 NX2023Visual Studio 的安装,安装路径如下所示:

  • NX2023 安装路径:D:\NX2023
  • VS2022 安装路径:D:\VisualStudio\2022

为什么要配置Visual Studio呢?其实不配置也可以,我们可以建一个空项目,然后手动修改该项目属性,添加附加包含目录、附加库目录等,使其包含 NXOpen 的相关库函数,但是每次创建项目都要修改属性是一件很麻烦的事情,于是就有了配置Visual Studio这个操作。

配置Visual Studio就是让我们在创建项目时可以直接选择以模板向导的方式创建一个项目,这种方式创建出来的项目已经自动帮我们配置好了所有属性,可以直接写代码编译运行了。

1.1 拷贝 VB、VC、VC#

打开NX安装目录下的D:\NX2007\UGOPEN\vs_files,里面有三个文件VB、VC、VC#,如下图所示,右键复制下来。

打开Visual Studio的安装目录D:\VisualStudio\2022\Community,里面也有VB、VC、VC#三个文件,在空白处粘贴,之前复制的三个文件会和这个目录下的VB、VC、VC#进行合并,如下图所示。

勾选”为所有当前项目执行此操作“,点击”继续

1.2 修改 VC 中的 NXOpenCPP.vsz 和 NXOpen.vsz 版本号

用记事本打开文件夹

D:\VisualStudio\2022\Community\VC\vcprojects

中的NXOpenCPP.vszNXOpen.vsz文件,将其中的版本号修改为17.0,然后保存,如下图所示。

  • 如果你是其他的VS版本,可参照如下版本对照表。

取消勾选”只读

搜索”记事本“,并选择”固定到开始屏幕

点击”文件“,选择”打开“,D:\VisualStudio\2022\Community\VC\vcprojects\NXOpenCPP.vsz

修改 NXOpenCPP.vsz 中的版本号为 17.0

修改 NXOpen.vsz 中的版本号为 17.0

1.3 修改 VB 中的 NXOpen_VB.vsz 版本号

同理将D:\VisualStudio\2022\Community\VB\VBProjects文件夹下的NXOpen_VB.vsz文件的版本号也修改为17.0

1.4 修改 VC# 中的 NXOpen_VCS.vsz 版本号

D:\VisualStudio\2022\Community\VC#\CSharpProjects文件夹下的NXOpen_VCS.vsz文件的版本号也修改为17.0

1.5 修改 IDE/VC 中的 NXOpenCPP.vsz 和 NXOpen.vsz 版本号

此时打开Visual Studio会发现,创建VBVC#项目时,已经出现了可供选择的模板向导,但是创建VC项目时却没有模板向导选项,其实原因在于真正的VC文件夹位于VS安装目录下的D:\VisualStudio\2022\Community\Common7\IDE路径下。

此时我们只需要重新将 NX 安装目录D:\NX2007\UGOPEN\vs_files里面的VC文件右键复制下来,然后粘贴到路径D:\VisualStudio\2022\Community\Common7\IDE

并同样修改D:\VisualStudio\2022\Community\Common7\IDE\VC\vcprojects

里面的NXOpenCPP.vszNXOpen.vsz文件的版本号。

1.6 模板向导测试

到这里,打开Visual Studio,创建 VC 项目时就会看到模板向导选项,如下图所示。点击”创建新项目(N)

选择”NXOpen C++ Wicard“,点击”下一步

点击”创建

出现NXOpenCPP Wizard向导界面,说明已经安装成功。

2. 添加环境变量

添加环境变量的目的是:NX 在启动后会自动加载我们设置的用户目录,读取里面的菜单文件和动态链接库文件等,从而实现二次开发的功能。

先随便在一个目录下建立一个文件夹,最好是便于访问的目录,例如我就是在D盘建立了一个NXOPEN文件夹,在NXOPEN下再新建startupapplication两个文件夹。

  • startup文件夹用来存放菜单文件;
  • application文件夹用来存放对话框文件.dlx和动态链接库文件.dll,如下图所示。

接下来添加环境变量:

在搜索栏中,输入”高级系统设置“,点击”查看高级系统设置“。

点击”环境变量

点击”系统变量(S)“下的”新建“,

变量名设为UGII_USER_DIR,变量值设为刚刚新建的那个文件夹,我这里是D:\NXOPEN,然后点击确定,环境变量就添加好了。

3. 测试

接下来做一个简单的测试,实现一个块的创建。

在之前建立的文件夹D:\NXOPEN\startup下新建一个menu.men文件,首先点击文件夹上方的”查看“,勾选”文件扩展名

创建记事本,

在记事本中添加如下内容,并保存。

VERSION 120
EDIT UG_GATEWAY_MAIN_MENUBAR

AFTER UG_HELP
	CASCADE_BUTTON MyTOOLS
	LABEL MyTools
END_OF_AFTER

MENU MyTOOLS
	BUTTON MyTOOLS_BUTTON1
	LABEL create_block
	BITMAP block
	ACTIONS create_block.dll
END_OF_MENU

并将记事本的名称修改为menu.men,弹出框提示”确定要更改吗?“,选择”

打开Visual Studio,选择“创建新项目(N)

选择“NXOpen C++ Wizard”,点击“下一步”:

设置项目名称“create_clock”,保存位置为”D:\

NXOpenCPP Wizard向导页面中,选择”Finish

即可打开如下图所示的项目界面:

打开create_block.cpp文件,在头文件处加一行代码

#include <uf_modl_primitives.h>

然后找到do_it()函数,在do_it()函数中添加如下代码:

void MyClass::do_it()
{

	// TODO: add your code here
	//将以下代码复制到你的do_it()函数中
	UF_initialize();
	double origin[3] = { 0.0, 0.0, 0.0 };
	char * edge_len[3] = { "40", "60", "80" };
	tag_t blk_obj_id = NULL_TAG;
	UF_MODL_create_block1(UF_NULLSIGN, origin, edge_len, &blk_obj_id);
	UF_terminate();
}

  • create_block.cpp 完整代码

    //create_clock
    
    // Mandatory UF Includes
    #include <uf.h>
    #include <uf_object_types.h>
    
    // Internal Includes
    #include <NXOpen/ListingWindow.hxx>
    #include <NXOpen/NXMessageBox.hxx>
    #include <NXOpen/UI.hxx>
    
    // Internal+External Includes
    #include <NXOpen/Annotations.hxx>
    #include <NXOpen/Assemblies_Component.hxx>
    #include <NXOpen/Assemblies_ComponentAssembly.hxx>
    #include <NXOpen/Body.hxx>
    #include <NXOpen/BodyCollection.hxx>
    #include <NXOpen/Face.hxx>
    #include <NXOpen/Line.hxx>
    #include <NXOpen/NXException.hxx>
    #include <NXOpen/NXObject.hxx>
    #include <NXOpen/Part.hxx>
    #include <NXOpen/PartCollection.hxx>
    #include <NXOpen/Session.hxx>
    #include <uf_modl_primitives.h>
    
    // Std C++ Includes
    #include <iostream>
    #include <sstream>
    
    using namespace NXOpen;
    using std::string;
    using std::exception;
    using std::stringstream;
    using std::endl;
    using std::cout;
    using std::cerr;
    
    //------------------------------------------------------------------------------
    // NXOpen c++ test class 
    //------------------------------------------------------------------------------
    class MyClass
    {
        // class members
    public:
        static Session *theSession;
        static UI *theUI;
    
        MyClass();
        ~MyClass();
    
    	void do_it();
    	void print(const NXString &);
    	void print(const string &);
    	void print(const char*);
    
    private:
    	BasePart *workPart, *displayPart;
    	NXMessageBox *mb;
    	ListingWindow *lw;
    	LogFile *lf;
    };
    
    //------------------------------------------------------------------------------
    // Initialize static variables
    //------------------------------------------------------------------------------
    Session *(MyClass::theSession) = NULL;
    UI *(MyClass::theUI) = NULL;
    
    //------------------------------------------------------------------------------
    // Constructor 
    //------------------------------------------------------------------------------
    MyClass::MyClass()
    {
    
    	// Initialize the NX Open C++ API environment
    	MyClass::theSession = NXOpen::Session::GetSession();
    	MyClass::theUI = UI::GetUI();
    	mb = theUI->NXMessageBox();
    	lw = theSession->ListingWindow();
    	lf = theSession->LogFile();
    
        workPart = theSession->Parts()->BaseWork();
    	displayPart = theSession->Parts()->BaseDisplay();
    	
    }
    
    //------------------------------------------------------------------------------
    // Destructor
    //------------------------------------------------------------------------------
    MyClass::~MyClass()
    {
    }
    
    //------------------------------------------------------------------------------
    // Print string to listing window or stdout
    //------------------------------------------------------------------------------
    void MyClass::print(const NXString &msg)
    {
    	if(! lw->IsOpen() ) lw->Open();
    	lw->WriteLine(msg);
    }
    void MyClass::print(const string &msg)
    {
    	if(! lw->IsOpen() ) lw->Open();
    	lw->WriteLine(msg);
    }
    void MyClass::print(const char * msg)
    {
    	if(! lw->IsOpen() ) lw->Open();
    	lw->WriteLine(msg);
    }
    
    //------------------------------------------------------------------------------
    // Do something
    //------------------------------------------------------------------------------
    void MyClass::do_it()
    {
    
    	// TODO: add your code here
    	//将以下代码复制到你的do_it()函数中
    	UF_initialize();
    	double origin[3] = { 0.0, 0.0, 0.0 };
    	char* edge_len[3] = { "40", "60", "80" };
    	tag_t blk_obj_id = NULL_TAG;
    	UF_MODL_create_block1(UF_NULLSIGN, origin, edge_len, &blk_obj_id);
    	UF_terminate();
    	
    }
    
    //------------------------------------------------------------------------------
    // Entry point(s) for unmanaged internal NXOpen C/C++ programs
    //------------------------------------------------------------------------------
    //  Explicit Execution
    extern "C" DllExport void ufusr( char *parm, int *returnCode, int rlen )
    {
        try
        {
    		// Create NXOpen C++ class instance
    		MyClass *theMyClass;
    		theMyClass = new MyClass();
    		theMyClass->do_it();
    		delete theMyClass;
    	}
        catch (const NXException& e1)
        {
    		UI::GetUI()->NXMessageBox()->Show("NXException", NXOpen::NXMessageBox::DialogTypeError, e1.Message());
        }
    	catch (const exception& e2)
        {
    		UI::GetUI()->NXMessageBox()->Show("Exception", NXOpen::NXMessageBox::DialogTypeError, e2.what());
        }
    	catch (...)
        {
    		UI::GetUI()->NXMessageBox()->Show("Exception", NXOpen::NXMessageBox::DialogTypeError, "Unknown Exception.");
        }
    }
    
    //------------------------------------------------------------------------------
    // Unload Handler
    //------------------------------------------------------------------------------
    extern "C" DllExport int ufusr_ask_unload()
    {
    	// Unloads the image when the application completes
    	return (int)Session::LibraryUnloadOptionImmediately;	
    	
    }
    
    

点击”解决方案‘create block’,右键,选择“生成解决方案(B)

会在该项目路径...\create_block\x64\Debug下生成一个create_block.dll文件,将该.dll文件复制到二次开发目录D:\NXOPEN\application下,如图所示:

打开NX软件,点击左上角的文件,选择“新建”,

点击“确定

即可得到如下界面

Ctrl+U打开上一步生成的DLL文件(create_block.dll)。

NX 会执行此动态库中的入口函数ufusr

会在“信息”框中提示Warning,可以忽略

NX 建模工作区中生成一个长方体。

posted on 2024-10-30 10:00  守望者与托养者  阅读(20)  评论(0编辑  收藏  举报