实例:NX二次开发抽取平面以及标准柱面中心线

一、概述

        最近体验许多外挂,包括胡波外挂、星空外挂及模圣等都有抽取面的中心线,由于刚刚学习,我尝试看看能不能做出来,本博客代码没有封装函数,代码有待改进,但基本可以实现相应的功能。

二、案例实现的功能

1、可以抽取平面的中心线,主要利用面上的UV线;

2、可以抽取柱面的中心线,这里方法有很多我的思路是识别柱面上的两个圆弧,获得两段圆弧的中心坐标,然后连线。

3、适用范围:目前有三类

图1 平面类型

图2 圆柱面类型

图3 标准圆弧类型

非标准圆弧类型目前只想到用抽取虚拟曲线来实现,下一篇博客写

三、代码说明以及详细注解

//NXOpen_CreateFaceCentreLine

// 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>

// Std C++ Includes
#include <iostream>
#include <sstream>

//用户定义
#include "uf_all.h"
#include <vector>
using namespace NXOpen;
using std::string;
using std::exception;
using std::stringstream;
using std::endl;
using std::cout;
using std::cerr;

static  int   init_proc(UF_UI_selection_p_t select, void *user_data)
{
	int  errorCode = 0;
	int  num_triples = 1; //选择类型 数量
	UF_UI_mask_t mask_triples[1] = { { UF_face_type , 0,0 }    //定义选择面类型

	};
	errorCode = UF_UI_set_sel_mask(select,
		UF_UI_SEL_MASK_CLEAR_AND_ENABLE_SPECIFIC,
		num_triples,
		mask_triples);
	if (errorCode == 0)
	{
		return UF_UI_SEL_SUCCESS;
	}
	else
	{
		return UF_UI_SEL_FAILURE;
	}
}
//------------------------------------------------------------------------------
// 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
	L10:
	// TODO: add your code here
	int response = 0;
	tag_t object = NULL_TAG;
	double cursor[3];
	tag_t view = NULL_TAG;
	UF_UI_select_with_single_dialog("提示:请选择面", "选择面", UF_UI_SEL_SCOPE_WORK_PART, init_proc, NULL, &response, &object, cursor, &view);
	if (response == UF_UI_OK || response == UF_UI_OBJECT_SELECTED || response == UF_UI_OBJECT_SELECTED_BY_NAME)
	{
		UF_DISP_set_highlight(object, 0);
		//判断面的类型
		int faceType = 0;
		UF_MODL_ask_face_type(object, &faceType);
		if (faceType == UF_MODL_CYLINDRICAL_FACE)
		{
			//面找边
			uf_list_p_t list;
			tag_t edge1Tag = NULL_TAG;
			tag_t edge1Tag2 = NULL_TAG;
			UF_CURVE_line_t line1;
			tag_t line1TAG = NULL_TAG;
			int count = 0;
			UF_MODL_ask_face_edges(object, &list);//得到面的边
			UF_MODL_ask_list_count(list, &count);//查询链表数量
			std::vector<tag_t> edgeTAG;
			for (int j = 0; j < count; j++)
			{
				UF_MODL_ask_list_item(list, j, &edge1Tag);//得到边的tag

				//判断边的类型
				int edge_type;
				UF_MODL_ask_edge_type(edge1Tag, &edge_type);
				if (edge_type == UF_MODL_CIRCULAR_EDGE)
				{
					/*****************************************
					UF_MODL_LINEAR_EDGE					线性边
					UF_MODL_CIRCULAR_EDGE				圆形边
					UF_MODL_ELLIPTICAL_EDGE				椭圆形边		
					UF_MODL_INTERSECTION_EDGE			相交边
					UF_MODL_SPLINE_EDGE					样条边
					UF_MODL_SP_CURVE_EDGE				曲线边
					UF_MODL_FOREIGN_EDGE				外边缘
					UF_MODL_CONST_PARAMETER_EDGE		参数边
					UF_MODL_TRIMMED_CURVE_EDGE			裁剪曲线边
					******************************************/
					edgeTAG.push_back(edge1Tag);
				}			

				if (edgeTAG.size() == 2)
				{
					//UF_CURVE_ask_centroid(edgeTAG[0], centroid1);//得到第一条边的中心坐标
					//UF_CURVE_ask_centroid(edgeTAG[1], centroid2);//得到第二条边的中心坐标
					UF_CURVE_arc_t arc_coords1, arc_coords2;
					UF_CURVE_ask_arc_data(edgeTAG[0], &arc_coords1);
					UF_CURVE_ask_arc_data(edgeTAG[1], &arc_coords2);
					
					double douMatrixValue1[9];
					UF_CSYS_ask_matrix_values(arc_coords1.matrix_tag, douMatrixValue1);
					double douPoint1[3];
					UF_MTX3_vec_multiply_t(arc_coords1.arc_center, douMatrixValue1, douPoint1);
					double douMatrixValue2[9];
					UF_CSYS_ask_matrix_values(arc_coords2.matrix_tag, douMatrixValue2);
					double douPoint2[3];
					UF_MTX3_vec_multiply_t(arc_coords2.arc_center, douMatrixValue2, douPoint2);

					//画直线
					line1.start_point[0] = douPoint1[0];
					line1.start_point[1] = douPoint1[1];
					line1.start_point[2] = douPoint1[2];
					line1.end_point[0] = douPoint2[0];
					line1.end_point[1] = douPoint2[1];
					line1.end_point[2] = douPoint2[2];

					UF_CURVE_create_line(&line1, &line1TAG);

					UF_OBJ_set_color(line1TAG, 186);
					UF_OBJ_set_font(line1TAG, UF_OBJ_FONT_CENTERLINE);
					//移动放置图层
					UF_OBJ_set_layer(line1TAG, 5);					
				}
			
			}

			UF_free(list);
			goto L10;
		}
		else if (faceType == UF_MODL_PLANAR_FACE)
		{
			double uv_min_max1[4];
			UF_MODL_ask_face_uv_minmax(object, uv_min_max1);
			double parameter1 = (uv_min_max1[0] + uv_min_max1[1]) / 2;
			double parameter2 = (uv_min_max1[2] + uv_min_max1[3]) / 2;
			tag_t * isocurve_id1, *isocurve_id2;
			int isocurve_cnt1 = 0;
			int isocurve_cnt2 = 0;
			UF_MODL_create_isocurve(object, 1, parameter1, 0.01, &isocurve_id1, &isocurve_cnt1);
			UF_MODL_create_isocurve(object, 2, parameter2, 0.01, &isocurve_id2, &isocurve_cnt2);

			UF_OBJ_set_color(isocurve_id1[0], 186);
			UF_OBJ_set_color(isocurve_id2[0], 186);
			UF_OBJ_set_font(isocurve_id1[0], UF_OBJ_FONT_CENTERLINE);
			UF_OBJ_set_font(isocurve_id2[0], UF_OBJ_FONT_CENTERLINE);
			//移动放置图层
			UF_OBJ_set_layer(isocurve_id1[0], 5);
			UF_OBJ_set_layer(isocurve_id2[0], 5);
			UF_free(isocurve_id1);
			UF_free(isocurve_id2);


			double param[2] = { 0 };
			param[0] = parameter1;
			param[1] = parameter2;
			double point[3] = { 0 };
			double u1[3] = { 0 };
			double v1[3] = { 0 };
			double u2[3] = { 0 };
			double v2[3] = { 0 };
			double unit_norm[3] = { 0 };
			double radii[2] = { 0 };
			UF_MODL_ask_face_props(object, param, point, u1, v1, u2, v2, unit_norm, radii);
			tag_t facePoint;
			UF_CURVE_create_point(point, &facePoint);

			goto L10;
		}
		else
		{
			uc1601("请正确选择面!", 1);
			goto L10;
		}
	}
}

//------------------------------------------------------------------------------
// Entry point(s) for unmanaged internal NXOpen C/C++ programs
//------------------------------------------------------------------------------
//  Explicit Execution
extern "C" DllExport void ufusr( char *parm, int *returnCode, int rlen )
{
	UF_initialize();
    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.");
    }
	UF_terminate();
}


//------------------------------------------------------------------------------
// Unload Handler
//------------------------------------------------------------------------------
extern "C" DllExport int ufusr_ask_unload()
{
	return (int)NXOpen::Session::LibraryUnloadOptionImmediately;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/418699.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Sora 原理与技术实战笔记一

b 站视频合集 【AIX组队学习】Sora原理与技术实战&#xff1a;Sora技术路径详解 Sora 技术报告&#xff08;OpenAI&#xff09; huggingsd 文生图视频系列的一个开源项目 最强视频生成模型Sora相关技术解析 https://github.com/lichao-sun/SoraReview 惊艳效果&#xff1a; 长…

Ps:路径面板

Ps菜单&#xff1a;窗口/路径 Window/Paths “路径”面板 Paths Panel提供了一系列功能&#xff0c;使用户能够创建、编辑、保存和利用路径。 ◆ ◆ ◆ 路径分类 在“路径”面板上的路径可分为五大类。 常规路径 Saved Path 也称“已保存的路径”&#xff0c;指的是已经存储在…

Python进阶学习:Pandas--DataFrame--如何把几列数据合并成新的一列

Python进阶学习&#xff1a;Pandas–DataFrame–如何把几列数据合并成新的一列 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…

SpringMVC的配置2种(本质上还是一样的,实现的接口不同)

第一种SpringInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer 看第一种配置 package com.xxx.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SpringInitConfig ext…

减少页面加载时间:提升用户体验的关键

✨✨ 祝屏幕前的您天天开心&#xff0c;每天都有好运相伴。我们一起加油&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一、为什么页面加载时间重要&#xff1f; 二、如何减少页面加载时间&#xff1f; …

Google发布Genie硬杠Sora:通过大量无监督视频训练最终生成可交互虚拟世界

前言 Sora 问世才不到两个星期&#xff0c;谷歌的世界模型也来了&#xff0c;能力看似更强大(嗯&#xff0c;看似)&#xff1a;它生成的虚拟世界自主可控 第一部分 首个基础世界模型Genie 1.1 Genie是什么 Genie是第一个以无监督方式从未标记的互联网视频中训练的生成式交互…

UDP数据报套接字编程入门

目录 1.TCP和UDP的特点及区别 1.1TCP的特点 1.2UDP的特点 1.3区别 2.UDP Socket的api的介绍 2.1DatagramSocket API 2.2DatagramPacket API 3.回显客户端与服务器 3.1回显服务器 3.1.1UdpEchoServer类的创建 3.1.2服务器的运行方法start() 3.1.3main部分 3.1.4.完整…

nginx反向代理之缓存 客户端IP透传 负载均衡

一 缓存功能 缓存功能可以加速访问&#xff0c;如果没有缓存关闭后端服务器后&#xff0c;图片将无法访问&#xff0c;缓存功能默认关闭&#xff0c;需要开启。 相关选项&#xff1a; ​ proxy_cache zone_name | off; 默认off #指明调用的缓存&#xff0c;或关闭缓存机制;C…

【C++初阶】第四站:类和对象(下)(理解+详解)

前言&#xff1a; 本篇知识点&#xff1a;初始化列表、explicit关键字、static成员、友元、内部类、匿名对象、编译器的优化 专栏&#xff1a;C初阶 目录 再谈构造函数 1️⃣构造函数体赋值 2️⃣初始化列表 explicit关键字 static成员 1.static概念 2.static特性 面试…

Docker技术概论(4):Docker CLI 基本用法解析

Docker技术概论&#xff08;4&#xff09; Docker CLI 基本用法解析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

NC65 零预算控制规则 数据库表关系

NC65 零预算控制规则 数据库表关系 SELECT t1.createdby, t1.objname, t2.ctrlname, t2.pk_parent, t3.billtype, t3.nameidx, t3.pk_obj FROM tb_rule_formula t1 left join tb_ctrlformula t2 on t1.pk_obj t2.pk_parent left join tb_ctrlscheme t3 on t3.pk_ctrlformula …

Mysql安装教程

一、下载 点开下面的链接&#xff1a;https://dev.mysql.com/downloads/mysql/ 点击Download 就可以下载对应的安装包了, 安装包如下: 二、解压 下载完成后我们得到的是一个压缩包&#xff0c;将其解压&#xff0c;我们就可以得到MySQL 8.0.31 的软件本体了(就是一个文件夹…

Tomcat布署及优化-----JDK和Tomcat

1.Tomcat简介 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;Tomcat 属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试 JSP 程序的首选。一般来说&…

Vivado Vitis 2023.2 环境配置 Git TCL工程管理 MicroBlaze和HLS点灯测试

文章目录 本篇概要Vivado Vitis 环境搭建Vivado 免费标准版 vs 企业版Vivado Windows 安装Vivado 安装更新 Vivado 工程操作GUI 创建工程打开已有工程从已有工程创建, 重命名工程GUI导出TCL, TCL复原工程TCL命令 Vivado 版本控制BlinkTcl脚本新建导出重建工程纯Verilog BlinkTc…

抖音视频批量下载软件说明|视频采集挖掘工具

操作步骤如下&#xff1a; 打开抖音批量下载工具&#xff0c;进入软件界面的第一个选项卡页面。在搜索框中输入需要搜索的视频关键词&#xff0c;例如"汽车配件"&#xff0c;然后点击"开启抓取"按钮开始搜索。软件将开始搜索并显示与关键词相关的视频内容…

祖传代码:历史的宝藏与现代的挑战

程序员是如何看待“祖传代码”的&#xff1f; 程序员眼中的“祖传代码”&#xff0c;就像一本古老而神秘的魔法书&#xff0c;藏着无穷的智慧和技巧&#xff0c;有些代码像家传宝贝&#xff0c;有些像祖传秘方。快来分享一下你遇到的“祖传代码”吧~ 一、祖传代码的历史与文…

算法------(13)KMP

例题&#xff1a;&#xff08;1&#xff09;AcWing 831. KMP字符串 。。其实写完也不太理解。。随便写点吧 KMP就是求next数组和运用next的数组的过程。相比传统匹配模式一次更新一单位距离的慢速方法&#xff0c;next数组可以让下表字符串一次更新n - next【n】个距离&#x…

三天学会阿里分布式事务框架Seata-seata事务日志mysql持久化配置

锋哥原创的分布式事务框架Seata视频教程&#xff1a; 实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;_哔哩哔哩_bilibili实战阿里分布式事务框架Seata视频教程&#xff08;无废话&#xff0c;通俗易懂版&#xff09;共计10条视频&…

虚拟机中Linux的安装与初始化配置(更新时间24/3/1)

先问三个问题 vm虚拟机安装了吗&#xff1f;点击此处跳转虚拟机安装教程Linux镜像下载了吗&#xff1f;点击此处跳转Linux镜像下载教程新建Linux虚拟机配置了吗&#xff1f;点击此处跳转新建虚拟机的配置教程 顺序是&#xff1a;下载虚拟机–>下载Linux镜像–>新建Linux配…

python63-Python的循环之循环使用else

Python的循环都可以定义else代码块&#xff0c;当循环条件为False 时&#xff0c;程序会执行else代码块。如下代码示范了为while循环定义else代码块。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…
最新文章