一般情况下,VS版本和UG版本需对应版本来开发,但本人较懒,而且习惯了现有VS2019版本+QT5.12版本,不想再折腾,所以在此基础上进行摸索。网络上基于QT编程的UG二次开发相关资料虽然很少,但也极大的帮助我快速建立了开发环境以及后续一些列配置工作。

一、工具:

编程工具:VS2019+QT5.12(VS和QT的安装和配置,请自行百度)

UG版本:UG11.0

二、项目创建:

打开VS2019,创建新项目,选择Qt Class Library,进入下一步

ug二次开发教程 java ug软件二次开发_ug二次开发教程 java

填写项目名称和项目存储路径,点击创建

ug二次开发教程 java ug软件二次开发_ug二次开发教程 java_02

选择64位版本,模块选择Core、GUI、Widgts

ug二次开发教程 java ug软件二次开发_qt_03

创建后,默认模板如下

ug二次开发教程 java ug软件二次开发_visual studio_04

三、相关配置:

需要把UG二次开发所需的头文件目录包含进去

ug二次开发教程 java ug软件二次开发_#include_05

运行库设置为多线程,否则可能其他电脑或用户运行会有问题。

ug二次开发教程 java ug软件二次开发_c++_06

添加库目录,即UG文件夹下的UGOPEN文件夹,所有库文件都在这个文件夹内

ug二次开发教程 java ug软件二次开发_qt_07

添加依赖项,不知道具体需要用到那些依赖项的话,就把UGOPEN文件夹内的所有库文件都填进去

ug二次开发教程 java ug软件二次开发_c++_08

生成DLL文件后,进行自动签名。数字签名是为了让其他电脑的正版UG可以正常调用,否则可能会出错。(signcpp.exe位于GUOPEN文件夹内)

ug二次开发教程 java ug软件二次开发_c++_09

四、程序测试

加入相关头文件,其中uf.h是入口函数 ufusr 和卸载函数 ufusr_ask_unload 需要用到的,uf_ui.h是uc1601()需要用到的,NXSigningResource.cpp是生成DLL后进行签名需要用到的文件,代码如下截图。

ug二次开发教程 java ug软件二次开发_c++_10

编译生成DLL后,打开UG,按CTRL+U打开执行函数对话框,选择生成的DLL文件,点击OK按钮

ug二次开发教程 java ug软件二次开发_ug二次开发教程 java_11

成功生成如下消息框

ug二次开发教程 java ug软件二次开发_qt_12

右击项目,选择添加QT类,进入界面后选择Qt Widgets Class

ug二次开发教程 java ug软件二次开发_#include_13

ug二次开发教程 java ug软件二次开发_ug二次开发教程 java_14

ug二次开发教程 java ug软件二次开发_ug二次开发教程 java_15

然后在项目下生成了三个文件

ug二次开发教程 java ug软件二次开发_visual studio_16

双击QtDlg.ui进行编辑,添加按钮和其他控件等,保存后退出,如下图

ug二次开发教程 java ug软件二次开发_#include_17

QtDlg.h代码:

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QtDlg.h"
#include <uf.h>
#include <uf_ui.h>
#include <uf_modl.h>
#include <uf_styler.h>


class QtDlg : public QWidget
{
	Q_OBJECT

public:
	QtDlg(QWidget *parent = Q_NULLPTR);
	~QtDlg();
	tag_t CreateLuomao(double);
	void selectData();
private:
	Ui::QtDlg ui;

public slots:
	void on_pushButton_clicked();
	void m_CreateBlock();
	void m_CreateCylinder();
};



#define UF_CALL(X) (report( __FILE__, __LINE__, #X, (X)))
static int report(char* file, int line, char* call, int irc)
{
    if (irc)
    {
        char err[133], msg[133];
        sprintf(msg, "*** ERROR code %d at line %d in %s:\n+++ ", irc, line, file);
        UF_get_fail_message(irc, err);
        UF_print_syslog(msg, FALSE);
        UF_print_syslog(err, FALSE);
        UF_print_syslog("\n", FALSE);
        UF_print_syslog(call, FALSE);
        UF_print_syslog(";\n", FALSE);
        if (!UF_UI_open_listing_window())
        {
            UF_UI_write_listing_window(msg);
            UF_UI_write_listing_window(err);
            UF_UI_write_listing_window("\n");
            UF_UI_write_listing_window(call);
            UF_UI_write_listing_window(";\n");
        }
    }
    return(irc);
}

struct LuomaoData
{
    //对边距离
    double S;

    //对角距离
    double E;

    //单边长
    double L;

    //锥体顶部直径
    char* D1;

    //厚度
    char* K;

    //锥体底部直径
    char* D2;
};

QtDlg.cpp代码:

#include "QtDlg.h"
#include <uf_part.h>
#include <uf_vec.h>

#if _MSC_VER >=1600    // MSVC2015>1899,对于MSVC2010以上版本都可以使用
#pragma execution_character_set("utf-8")  //设置编码格式为utf-8,可能会出现乱码
#endif

LuomaoData luomao_data;

QtDlg::QtDlg(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
	//QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(m_CreateBlock()));
    QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(m_CreateCylinder()));
	setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint);
}

QtDlg::~QtDlg()
{
}



void QtDlg::on_pushButton_clicked()
{
	ui.label->setText("UG二次开发测试!");
}

void QtDlg::m_CreateBlock()
{
	UF_FEATURE_SIGN Sign = UF_NULLSIGN;//设置布尔
	double Corner_pt[3] = { 0.0, 0.0, 0.0 };//设置原点
	char* Edge_Len[3] = { "100", "100", "100" };//设置长宽高
	tag_t BlkTag = NULL_TAG;
	UF_MODL_create_block1(Sign, Corner_pt, Edge_Len, &BlkTag);
	//QMessageBox::information(NULL, "提示:", "创建成功!");
}

void QtDlg::m_CreateCylinder()
{
	char charD[256], charH[256];
	QString len = ui.lineEdit->text();
	QString D = ui.comboBox->currentText();
	double point[3] = { 0,0,0 }, centroid[3] = { 0,0,0 }, distance = 0;
	sprintf(charD, "%4s", D.toLatin1().data());
	sprintf(charH, "%4s", len.toLatin1().data());

	UF_FEATURE_SIGN sign = UF_NULLSIGN;//布尔方式 : 布尔 无
	//UF_NULLSIGN    //布尔 无
	//UF_POSITIVE    //布尔 求和
	//UF_NEGATIVE    //布尔 求差
	//UF_UNSIGNED    //布尔 求交
	double dPoint1[3] = { 0,0,0 };    //圆柱底面圆心
	double dVector[3] = { 0,0,1 };   //圆柱方向
	tag_t  body1 = NULL_TAG, body2 = NULL_TAG;  //圆柱特征标签
	UF_MODL_create_cylinder(sign, NULL_TAG, dPoint1, charH, charD, dVector, &body1);  //创建圆柱
	UF_MODL_ask_feat_body(body1, &body1);   //查找特整体

	if (body1 != NULL_TAG)
	{
		//UF_MODL_ask_feat_body(body1, &body1);   //查找特整体
		//UF_MODL_ask_feat_body(cyl_tag, &cyl_tag);
		//倒角
		uf_list_p_t edges;
		tag_t edge_id[2], feature_obj_id = NULL_TAG;
		UF_MODL_ask_body_edges(body1, &edges);
		UF_MODL_ask_list_item(edges, 0, &edge_id[0]);
		UF_MODL_ask_list_item(edges, 1, &edge_id[1]);
		UF_MODL_create_list(&edges);
		UF_CURVE_ask_centroid(edge_id[0], centroid);
		UF_VEC3_distance(centroid, point, &distance);
		if (distance > 0.01)
		{
			UF_MODL_put_list_item(edges, edge_id[1]);
		}
		UF_CURVE_ask_centroid(edge_id[1], centroid);
		UF_VEC3_distance(centroid, point, &distance);
		if (distance > 0.01)
		{
			UF_MODL_put_list_item(edges, edge_id[0]);
		}
		UF_MODL_create_chamfer(1, "1", "1", "45", edges, &feature_obj_id);
	}

	body2 = CreateLuomao(len.toDouble());

	if (body1 != NULL_TAG && body2 != NULL_TAG)
	{
		UF_MODL_operations(body1, body2, UF_POSITIVE);	//布尔合并
	}
}

//由正六边形拉伸体和圆锥体进行布尔交运算得到。在坐标中定义正六边形六个点的坐标,然后按次序连接成线,合为一体后进行拉伸,然后与圆锥体求布尔交得到。
tag_t QtDlg::CreateLuomao(double H)    
{
	//略..............................
}

void QtDlg::selectData()
{
       //略..............................
}

UgModelTest.cpp文件修改为以下截图中代码

ug二次开发教程 java ug软件二次开发_qt_18

显示窗口的代码是以下这几行, w.show() 放在ufusr函数内执行。

int argc = 0;
QApplication a(argc, 0);
QtDlg w;

w.show();

编译运行生成DLL,UG调用结果如下:

ug二次开发教程 java ug软件二次开发_c++_19

ug二次开发教程 java ug软件二次开发_c++_20

 

 

五、未完待续。。。。在下一篇幅讲述由QT编译生成的DLL在其他电脑上如何被UG正常调用。