许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  NX二次开发(C++/C#):UF_MODL_trace_a_ray射线函数用法详解

NX二次开发(C++/C#):UF_MODL_trace_a_ray射线函数用法详解

阅读数 3
点赞 0
article_banner

UF_MODL_trace_a_ray 函数 可以指定一个点和方向来发射射线,并指定允许被射线击中的实体,通过此函数可以分析出一些模型的几何属性。

先在 NX 中创建一个方块和一个点用于测试


接下来创建工程,UF_MODL_trace_a_ray函数在uf_modl.h头文件中

#include <uf_modl.h>


void MyClass::do_it(){	//先获取到部件中的点和实体	Point* pt_1st = *(theSession->Parts()->Work()->Points()->begin());	Body* body_1st = *(theSession->Parts()->Work()->Bodies()->begin()); 	//然后设定射线函数的参数:	int num_bodies = 1;   //允许被射线击中的实体的数量,这里直接给1,实际上可以给变量 	tag_t* bodies = new tag_t(body_1st->Tag());  //接受射线的实体列表 	double origin[3] = {						pt_1st->Coordinates().X,						pt_1st->Coordinates().Y,						pt_1st->Coordinates().Z	};  //定义射线的发射源(即pt_1st的坐标) 	double direction[3] = { 1,0,0 }; //定义射线的发射方向向量 	double transform[16]; //定义转置坐标系矩阵。参数说明中有告知使用UF_MTX4_identity进行初始化	UF_MTX4_identity(transform); 	int num_desired = 0; //定义最大击中数量。 0代表不设限 	int num_results;  //返回值:击中数量 	UF_MODL_ray_hit_point_info_t* hit_list; //返回值:射线函数运行结果结构体 	UF_MODL_trace_a_ray(num_bodies , bodies , origin , direction , transform , num_desired , &num_results , &hit_list); 	//判断num_results是否大于零 来确定射线是否击中目标	if( num_results > 0 )	{		char info[1024];		sprintf_s(info , "击中数量:[%d], 击中目标体tag值:[%d]" , num_results , hit_list->hit_body);		lw->Open();		lw->WriteLine(info); 		//还可以进一步判断一些几何属性,例如:如果击中数量==2 ,那么使用击中点信息即可计算出该实体的厚度		if( num_results == 2 )		{			double* p1 = hit_list[0].hit_point;			double* p2 = hit_list[1].hit_point;			double distance = sqrtf(powf(p1[0] - p2[0] , 2) + powf(p1[1] - p2[1] , 2) + powf(p1[2] - p2[2] , 2)); 			//输出信息			sprintf_s(info , "击中点p1坐标:[X=%.2f] [Y=%.2f] [Z=%.2f]\n击中点p2坐标:[X=%.2f] [Y=%.2f] [Z=%.2f]\n两击中点的距离值:[%.2f]" , p1[0] , p1[1] , p1[2] , p2[0] , p2[1] , p2[2] , distance);			lw->WriteLine(info);		}	} 	//释放内存	delete[]bodies;}

编译后运行并查看运行结果:


最后附上 完整代码

//BlogCode_Cpp // 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>#include <uf_obj.h> // 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.h>#include <uf_mtx.h>#include <NXOpen/Part.hxx>#include <NXOpen/Point.hxx>#include <NXOpen/PointCollection.hxx> // 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:	Part* workPart , * displayPart;	NXMessageBox* mb;	ListingWindow* lw;}; //------------------------------------------------------------------------------// 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(); 	workPart = theSession->Parts()->Work();	displayPart = theSession->Parts()->Display(); } //------------------------------------------------------------------------------// 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(){	//先获取到部件中的点和实体	Point* pt_1st = *(theSession->Parts()->Work()->Points()->begin());	Body* body_1st = *(theSession->Parts()->Work()->Bodies()->begin()); 	//然后设定射线函数的参数:	int num_bodies = 1;   //允许被射线击中的实体的数量,这里直接给1,实际上可以给变量 	tag_t* bodies = new tag_t(body_1st->Tag());  //接受射线的实体列表 	double origin[3] = {						pt_1st->Coordinates().X,						pt_1st->Coordinates().Y,						pt_1st->Coordinates().Z	};  //定义射线的发射源(即pt_1st的坐标) 	double direction[3] = { 1,0,0 }; //定义射线的发射方向向量 	double transform[16]; //定义转置坐标系矩阵。参数说明中有告知使用UF_MTX4_identity进行初始化	UF_MTX4_identity(transform); 	int num_desired = 0; //定义最大击中数量。 0代表不设限 	int num_results;  //返回值:击中数量 	UF_MODL_ray_hit_point_info_t* hit_list; //返回值:射线函数运行结果结构体 	UF_MODL_trace_a_ray(num_bodies , bodies , origin , direction , transform , num_desired , &num_results , &hit_list); 	//判断num_results是否大于零 来确定射线是否击中目标	if( num_results > 0 )	{		char info[1024];		sprintf_s(info , "击中数量:[%d], 击中目标体tag值:[%d]" , num_results , hit_list->hit_body);		lw->Open();		lw->WriteLine(info); 		//还可以进一步判断一些几何属性,例如:如果击中数量==2 ,那么使用击中点信息即可计算出该实体的厚度		if( num_results == 2 )		{			double* p1 = hit_list[0].hit_point;			double* p2 = hit_list[1].hit_point;			double distance = sqrtf(powf(p1[0] - p2[0] , 2) + powf(p1[1] - p2[1] , 2) + powf(p1[2] - p2[2] , 2)); 			//输出信息			sprintf_s(info , "击中点p1坐标:[X=%.2f] [Y=%.2f] [Z=%.2f]\n击中点p2坐标:[X=%.2f] [Y=%.2f] [Z=%.2f]\n两击中点的距离值:[%.2f]" , p1[0] , p1[1] , p1[2] , p2[0] , p2[1] , p2[2] , distance);			lw->WriteLine(info);		}	} 	//释放内存	delete[]bodies;} //------------------------------------------------------------------------------// Entry point(s) for unmanaged internal NXOpen C/C++ programs//------------------------------------------------------------------------------// Explicit Executionextern "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;}  


顺便附加C#版本的代码:

            //定义UFUN函数入口            UFSession theUFsession = UFSession.GetUFSession();             //先获取到部件中的点和实体            Point3d pt_1st = theSession.Parts.Work.Points.ToArray()[0].Coordinates;            Body body_1st = theSession.Parts.Work.Bodies.ToArray()[0];             //定义转置坐标系矩阵。参数说明中有告知使用UF_MTX4_identity进行初始化            double[] transform = new double[16];            theUFsession.Mtx4.Identity(transform);             theUFsession.Modl.TraceARay(1, new Tag[] { body_1st.Tag }, new double[] { pt_1st.X, pt_1st.Y, pt_1st.Z }, new double[] { 1, 0, 0 }, transform, 0, out int num_result, out UFModl.RayHitPointInfo[] hit_list);             //判断num_results是否大于零 来确定射线是否击中目标            if (num_result > 0)            {                theUfSession.Ui.OpenListingWindow();                theUfSession.Ui.WriteListingWindow($"击中数量:[{num_result}], 击中目标体tag值:[{hit_list[0].hit_body}]\n");                 //还可以进一步判断一些几何属性,例如:如果击中数量==2 ,那么使用击中点信息即可计算出该实体的厚度                if (num_result == 2)                {                    double[] p1 = hit_list[0].hit_point;                    double[] p2 = hit_list[1].hit_point;                    theUfSession.Ui.WriteListingWindow($"击中点p1坐标:[X={p1[0]}] [Y={p1[1]}] [Z={p1[2]}]\n");                    theUfSession.Ui.WriteListingWindow($"击中点p2坐标:[X={p2[0]}] [Y={p2[1]}] [Z={p2[2]}]\n");                    double distance = Math.Sqrt(Math.Pow(p1[0] - p2[0], 2) + Math.Pow(p1[1] - p2[1], 2) + Math.Pow(p1[2] - p2[2], 2));                    theUfSession.Ui.WriteListingWindow($"两击中点的距离值:[{distance}]");                }            }

C#版本的完整代码:

using NXOpen;using NXOpen.UF;using System;using System.Linq;using System.Collections.Generic; public class Program{    // class members    private static Session theSession;    private static UI theUI;    private static UFSession theUfSession;    public static Program theProgram;    public static bool isDisposeCalled;      public Program()    {        try        {            theSession = Session.GetSession();            theUI = UI.GetUI();            theUfSession = UFSession.GetUFSession();            isDisposeCalled = false;        }        catch (NXOpen.NXException ex)        {         }    }     public static int Main(string[] args)    {        int retValue = 0;        try        {            theProgram = new Program();            //定义UFUN函数入口            UFSession theUFsession = UFSession.GetUFSession();             //先获取到部件中的点和实体            Point3d pt_1st = theSession.Parts.Work.Points.ToArray()[0].Coordinates;            Body body_1st = theSession.Parts.Work.Bodies.ToArray()[0];             //定义转置坐标系矩阵。参数说明中有告知使用UF_MTX4_identity进行初始化            double[] transform = new double[16];            theUFsession.Mtx4.Identity(transform);             theUFsession.Modl.TraceARay(1, new Tag[] { body_1st.Tag }, new double[] { pt_1st.X, pt_1st.Y, pt_1st.Z }, new double[] { 1, 0, 0 }, transform, 0, out int num_result, out UFModl.RayHitPointInfo[] hit_list);             //判断num_results是否大于零 来确定射线是否击中目标            if (num_result > 0)            {                theUfSession.Ui.OpenListingWindow();                theUfSession.Ui.WriteListingWindow($"击中数量:[{num_result}], 击中目标体tag值:[{hit_list[0].hit_body}]\n");                 //还可以进一步判断一些几何属性,例如:如果击中数量==2 ,那么使用击中点信息即可计算出该实体的厚度                if (num_result == 2)                {                    double[] p1 = hit_list[0].hit_point;                    double[] p2 = hit_list[1].hit_point;                    theUfSession.Ui.WriteListingWindow($"击中点p1坐标:[X={p1[0]}] [Y={p1[1]}] [Z={p1[2]}]\n");                    theUfSession.Ui.WriteListingWindow($"击中点p2坐标:[X={p2[0]}] [Y={p2[1]}] [Z={p2[2]}]\n");                    double distance = Math.Sqrt(Math.Pow(p1[0] - p2[0], 2) + Math.Pow(p1[1] - p2[1], 2) + Math.Pow(p1[2] - p2[2], 2));                    theUfSession.Ui.WriteListingWindow($"两击中点的距离值:[{distance}]");                }            }            theProgram.Dispose();        }        catch (NXOpen.NXException ex)        {         }        return retValue;    }      public void Dispose()    {        try        {            if (isDisposeCalled == false)            {             }            isDisposeCalled = true;        }        catch (NXOpen.NXException ex)        {         }    }     public static int GetUnloadOption(string arg)    {        return System.Convert.ToInt32(Session.LibraryUnloadOption.Immediately);    } } 


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空