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

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

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

NX二次开发 (C++/C#) UF_MODL_trace_a_ray 射线函数的用法_第1张图片

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

#include 

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;
}

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

NX二次开发 (C++/C#) UF_MODL_trace_a_ray 射线函数的用法_第2张图片

最后附上完整代码

//BlogCode_Cpp

// Mandatory UF Includes
#include 
#include 

// Internal Includes
#include 
#include 
#include 
#include 

// Internal+External Includes
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

// Std C++ Includes
#include 
#include 

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 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;
}


顺便附加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);
    }

}

你可能感兴趣的:(算法,c++,开发语言)