NX二次开发源码分享:NXOpen C++创建UDO的过程
NX二次开发源码分享:NXOpen C++创建UDO的过程
UDO的创建是NX二次开发中最高深的一部分内容,通过这个实例,你可以看到如何注册UDO的回调函数,如何创建UDO,定义UDO的编辑,UDO的信息显示等内容!
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <uf.h>
#include <uf_ui.h>
#include <uf_exit.h>
#include <uf_disp.h>
static void ECHO(char *format, ...)
{
char msg;
va_list args;
va_start(args, format);
vsprintf(msg, format, args);
va_end(args);
UF_UI_open_listing_window();
UF_UI_write_listing_window(msg);
UF_print_syslog(msg, FALSE);
}
#define UF_CALL(X) (report_error( __FILE__, __LINE__, #X, (X)))
static int report_error( char *file, int line, char *call, int irc)
{
if (irc)
{
char err;
UF_get_fail_message(irc, err);
ECHO("*** ERROR code %d at line %d in %s:\n",
irc, line, file);
ECHO("+++ %s\n", err);
ECHO("%s;\n", call);
}
return(irc);
}
#include <NXOpen/Session.hxx>
#include <NXOpen/Part.hxx>
#include <NXOpen/PartCollection.hxx>
#include <NXOpen/Callback.hxx>
#include <NXOpen/NXException.hxx>
#include <NXOpen/UI.hxx>
#include <NXOpen/Selection.hxx>
#include <NXOpen/LogFile.hxx>
#include <NXOpen/NXObjectManager.hxx>
#include <NXOpen/ListingWindow.hxx>
#include <NXOpen/View.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedClass.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedClassManager.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedObject.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedObjectManager.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedEvent.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedDisplayEvent.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedLinkEvent.hxx>
#include <NXOpen/UserDefinedObjects_UserDefinedObjectDisplayContext.hxx>
using namespace NXOpen;
using namespace NXOpen::UserDefinedObjects;
//static variables
static NXOpen::Session* theSession = NULL;
static UI* theUI = NULL;
static UserDefinedClass* myUDOclass = NULL;
//------------------------------------------------------------------------------
// Callback Name: myDisplayCB
// This is a callback method associated with displaying a UDO.
// This same callback is registered for display, select, fit, and attention point
//------------------------------------------------------------------------------
extern int myDisplayCB(UserDefinedDisplayEvent*displayEvent)
{
try
{
// Get the doubles used to define the selected screen position for this UDO.
std::vector<double> myUDOdoubles = displayEvent->UserDefinedObject()->GetDoubles();
// Use the doubles to define points of a triangle
std::vector<Point3d> myPoints(4);
myPoints.X = myUDOdoubles + 0;
myPoints.Y = myUDOdoubles + 0;
myPoints.Z = myUDOdoubles + 0;
myPoints.X = myUDOdoubles + 100;
myPoints.Y = myUDOdoubles + 0;
myPoints.Z = myUDOdoubles + 0;
myPoints.X = myUDOdoubles + 0;
myPoints.Y = myUDOdoubles + 100;
myPoints.Z = myUDOdoubles + 0;
myPoints.X = myUDOdoubles + 0;
myPoints.Y = myUDOdoubles + 0;
myPoints.Z = myUDOdoubles + 0;
// Display the triangle
displayEvent->DisplayContext()->DisplayPolyline(myPoints);
// Display the text next to the triangle
Point3d myPt = Point3d(myUDOdoubles + 100, myUDOdoubles, myUDOdoubles);
displayEvent->DisplayContext()->DisplayText("C++ UDO", myPt, UserDefinedObjectDisplayContext::TextRefBottomLeft);
// UserDefinedObjectDisplayContext::DisplayFacets fails - see PR 6731653
// This demonstrates using UF_DISP_display_facets as a work around
double normals = { 0,0,1, 0,0,1, 0,0,1 };
double vertices = { myUDOdoubles, myUDOdoubles, myUDOdoubles,
myUDOdoubles + 100, myUDOdoubles, myUDOdoubles,
myUDOdoubles, myUDOdoubles + 100, myUDOdoubles };
UF_DISP_facet_t facets = { vertices, normals };
void *context = displayEvent->DisplayContext()->GetHandle();
UF_initialize();
UF_CALL(UF_DISP_display_facets(facets, 3, 1, UF_DISP_TRIANGLE, context));
UF_terminate();
}
catch (NXException ex)
{
ECHO("Caught exception: %s\n", ex.Message());
}
return 0;
}
//------------------------------------------------------------------------------
// Callback Name: myEditCB
// This is a callback method associated with editing a UDO.
//------------------------------------------------------------------------------
extern int myEditCB(UserDefinedEvent* editEvent)
{
try
{
// required for calls to legacy UF routines
// such as UF_DISP_add_item_to_display
UF_initialize();
View* myView = NULL;
Point3d myCursor(0,0,0);
// highlight the current udo we are about to edit
// this is helpful if multiple udo's were on the selection
// list when the user decided to edit them
editEvent->UserDefinedObject()->Highlight();
// ask the user to select a new origin for this UDO
Selection::DialogResponse myResponse = theUI->SelectionManager()->SelectScreenPosition("Select New Origin for C++ UDO", &myView, &myCursor);
// we are done asking the user for input... unhighlight the udo
editEvent->UserDefinedObject()->Unhighlight();
// use the new screen position (if the user picked one)
if( myResponse == Selection::DialogResponsePick )
{
std::vector<double> myUDOdoubles(3);
myUDOdoubles = myCursor.X;
myUDOdoubles = myCursor.Y;
myUDOdoubles = myCursor.Z;
// store the newly selected origin with the udo
editEvent->UserDefinedObject()->SetDoubles(myUDOdoubles);
// add the udo to the display list manually
// this will force the udo display to regenerate
// immediately and show the changes we just made
UF_DISP_add_item_to_display(editEvent->UserDefinedObject()->GetTag());
}
UF_terminate();
} catch (NXException ex)
{
ECHO("Caught exception: %s\n", ex.Message());
} return 0;
}
//------------------------------------------------------------------------------
// Callback Name: myInfoCB
// This is a callback method associated with querying information for a UDO.
// The information is printed in the listing window.
//------------------------------------------------------------------------------
extern int myInfoCB(UserDefinedEvent* infoEvent)
{
try
{
ListingWindow* theLW = theSession->ListingWindow();
char msg;
theLW->Open();
theLW->WriteLine(" ");
theLW->WriteLine("------------------------------------------------------------");
theLW->WriteLine("Begin Custom Information");
theLW->WriteLine(" ");
sprintf( msg, "UDO Class Name: '%s'", infoEvent->UserDefinedObject()->UserDefinedClass()->ClassName().GetLocaleText() );
theLW->WriteLine(msg);
sprintf( msg, "UDO Friendly Name: '%s'", infoEvent->UserDefinedObject()->UserDefinedClass()->FriendlyName().GetLocaleText() );
theLW->WriteLine(msg);
std::vector<double> myUDOdoubles = infoEvent->UserDefinedObject()->GetDoubles();
sprintf( msg, "myUDOdoubles(0) = %f", myUDOdoubles );
theLW->WriteLine(msg);
sprintf( msg, "myUDOdoubles(1) = %f", myUDOdoubles );
theLW->WriteLine(msg); sprintf( msg, "myUDOdoubles(2) = %f", myUDOdoubles );
theLW->WriteLine(msg);
theLW->WriteLine(" ");
theLW->WriteLine("End Custom Information");
}
catch (NXException ex)
{
ECHO("Caught exception: %s\n", ex.Message());
}
return 0;
}
//------------------------------------------------------------------------------
// initUDO
// Checks to see which (if any) of the application's static variables are
// uninitialized, and sets them accordingly.
// Initializes the UDO class and registers all of its callback methods.
//------------------------------------------------------------------------------
static int initUDO( bool alertUser)
{
try
{
if (theSession == NULL)
{
theSession = Session::GetSession();
}
if( theUI == NULL )
{
theUI = UI::GetUI();
}
if (myUDOclass == NULL)
{
if (alertUser)
{
ListingWindow*
theLW = theSession->ListingWindow();
theLW->Open();
theLW->WriteLine("Registering C++ UDO Class");
}
// Define your custom UDO class
myUDOclass = theSession->UserDefinedClassManager()->CreateUserDefinedObjectClass("Sample_Cpp_UDO", "Sample C++ UDO");
// Setup properties on the custom UDO class
myUDOclass->SetAllowQueryClassFromName(UserDefinedClass::AllowQueryClassOn);
// Register callbacks for the UDO class
myUDOclass->AddDisplayHandler(make_callback(&myDisplayCB));
myUDOclass->AddAttentionPointHandler(make_callback(&myDisplayCB));
myUDOclass->AddFitHandler(make_callback(&myDisplayCB));
myUDOclass->AddSelectionHandler(make_callback(&myDisplayCB));
myUDOclass->AddEditHandler(make_callback(&myEditCB));
myUDOclass->AddInformationHandler(make_callback(&myInfoCB));
// Add this class to the list of object types available for selection in NX.
// If you skip this step you won't be able to select UDO's of this class,
// even though you registered a selection callback.
theUI->SelectionManager()->SetSelectionStatusOfUserDefinedClass(myUDOclass, true);
}
}
catch (NXException ex)
{
ECHO("Caught exception: %s\n", ex.Message());
}
return 0;
}
//------------------------------------------------------------------------------
// ufusr (Explicit Activation)
// This entry point is used to activate the application explicitly, as in
// "File->Execute UG/Open->NX Open..."
//------------------------------------------------------------------------------
extern void ufusr( char *parm, int *returnCode, int rlen )
{
try
{
// required for calls to legacy UF routines
// such as UF_DISP_add_item_to_display
UF_initialize();
// initialize the UDO - if we didn't load this library at
// startup, here is our second chance to load it
initUDO(true);
// if we don't have any parts open create one
BasePart* myBasePart = theSession->Parts()->BaseDisplay();
if( myBasePart == NULL)
{
myBasePart = theSession->Parts()->NewBaseDisplay("test_cpp_udo.prt", BasePart::UnitsMillimeters);
}
View* myView = NULL;
Point3d myCursor(0,0,0);
// ask the user to select an origin for this UDO
Selection::DialogResponse myResponse = theUI->SelectionManager()->SelectScreenPosition("Select Origin of C++ UDO", &myView, &myCursor);
if( myResponse == Selection::DialogResponsePick )
{
// The user selected a point - go ahead and create the udo
UserDefinedObjectManager* myUDOmanager = myBasePart->UserDefinedObjectManager();
UserDefinedObject* firstUDO = myUDOmanager->CreateUserDefinedObject(myUDOclass);
// set the color property of the udo - just for fun :)
firstUDO->SetColor(36);
// store the origin selected by the user with the udo
std::vector<double> myUDOdoubles(3);
myUDOdoubles = myCursor.X;
myUDOdoubles = myCursor.Y;
myUDOdoubles = myCursor.Z;
firstUDO->SetDoubles(myUDOdoubles);
// add the udo to the display list manually
// this will force the udo to display immediately
UF_DISP_add_item_to_display(firstUDO->GetTag());
}
UF_terminate();
}
catch (const NXOpen::NXException& ex)
{
ECHO("Caught exception: %s\n", ex.Message());
}
}
//------------------------------------------------------------------------------
// ufsta
// Entrypoint used when program is loaded automatically
// as NX starts up. Note this application must be placed in a
// special folder for NX to find and load it during startup.
// Refer to the NX Open documentation for more details on how
// NX finds and loads applications during startup.
//------------------------------------------------------------------------------
extern void ufsta( char *param, int *returnCode, int rlen )
{
try
{
initUDO(false);
}
catch (const NXOpen::NXException& ex)
{
ECHO("Caught exception: %s\n", ex.Message());
}
}
//------------------------------------------------------------------------------
// ufusr_ask_unload
// Make sure you specify AtTermination for the unload option.
// If you unload the library before the NX Session Terminates
// bad things could happen when we try to execute a udo
// callback that no longer exists in the session.
//------------------------------------------------------------------------------
extern int ufusr_ask_unload( void )
{
return (int)Session::LibraryUnloadOptionAtTermination;
}
页:
[1]