Overview
 
A User Defined Object is patterned after object oriented programming and contains customer defined data.  The UDO can be linked or associated with NX objects.  As the associated NX object changes, the UDO can be kept up to date.  UDOs enable third party vendors and users to augment their part files with customer specific application data.
 
A UDO can contain the following data:


Additionally, all UDOs within a class may have their own methods to allow them to display, be selected, and obtain real-time notification during update and delete events.  The methods are registered as callback functions which occur at key events in an NX session. 
 
Warning:
It is important to ensure that the required libraries (containing the UDO’s classes and methods) are present in the environment before opening a part that contains a UDO.  NX will not issue any warning or notification about such missing libraries.  Classes and methods can be automatically loaded into NX during system initialization.


Update UDO's if they were created earlier than NX5

Due to an enhancement to User Defined Objects (UDOs) in NX 5, all part files that contain UDOs that were created before NX 5 need to be opened and saved in version NX 5, or later.

The refile_part utility can be used to upgrade parts in batch mode. This avoids errors that may occur when partial loading is used to open an assembly with components containing UDOs created in earlier versions of NX.
 
Sample Code
The files for two sample programs can be found in the ugopen directory. 
 
The first sample is an internal Open C API program that creates an Occurrenceable UDO.  The UDO is displayed as a circle centered on the face of a block.
See Occurrenceable UDO Sample for detailed instructions on how to compile, link and run this sample program.
 
 
The second sample is an internal Open C API program that associates notes with drawing views. 
The files for the example code are:
ufx_udo.h
ufx_udo_methods.c
ufx_udo_application.c
add_assoc_notes.men
assoc_notes.men
 
 
 
UDO Name
UDOs belong to a class and have a class name assigned to them during creation of the class.  There is also a “user friendly” name that can display which can be different from the actual class name.  The class name should not match the name of any NX object.  A class name should be specified as unique to a particular application so that there is no collision of class names from other applications.
 
The former Generic Entity (Object) is automatically upgraded to a UDO during part conversion.  Its UDO class name matches the sprintf string:
“Generic Entity – Subtype %d”
where the integer corresponds to the subtype for the existing geometric entity.  Therefore the class name for an existing generic entity with a subtype of 15 would be:
            “Generic Entity – Subtype 15”
You create the class and specify the name with UF_UDOBJ_create_class.  However, once a class is created, you can only access the class name through the query functions:
            UF_UDOBJ_ask_udo_data
and
            UF_UDOBJ_ask_class_data
 
 
 
UDO Status
An integer status value (1-7) is set for each UDO by NX in the absence of user defined methods.  You can obtain the status with the query function UF_UDOBJ_ask_udo_data and the value can be reset to zero with UF_UDOBJ_clear_udo_status.  The description for each status value is given in the following table.
 
 


 
 
Status Value

 
UDO is out of date

 
Due to Addition or Deletion of Links to the UDO

Due to Update being performed on Associated Objects in the Absence of a UDO Method

Due to Deletion of Associated Objects in the Absence of a UDO Method

0

No

 

 

 

1

Yes

Yes

 

 

2

Yes

 

Yes

 

3

Yes

Yes

Yes

 

4

Yes

 

 

Yes

5

Yes

Yes

 

Yes

6

Yes

 

Yes

Yes

7

Yes

Yes

Yes

Yes

 
NOTE: If user defined methods are used, then only status values 0 and 1 can occur.
 
 
 
Free Form Data
There are predefined areas for data types (integers, doubles, and strings) that are controlled exclusively by the user (NX has no knowledge of the content or use of these areas and does not perform any validation on these areas).  These areas are arrays that can contain any number of valid data element types.
 
There are functions for adding, editing, deleting, and querying the area for each data type.
 
 
 
Convertible Data
There are data areas (unlike the free form areas) that are converted automatically from English to Metric or vice versa when the part file is converted.  These convertible data areas are arrays of elements which represent:
 
There are functions for adding, editing, deleting, and querying each one of the convertible data areas.
 
 
 
Links to NX Objects
You can link a UDO to other NX objects using any one of five different linking mechanisms.  Each of the five link mechanisms has features that affect the behavior of NX during update and delete events.  The first four of the five link mechanisms are described in the link_type field of UF_UDOBJ_link_s and the quick reference table below.  The fifth linking mechanism is called a UDO owning link.
 
 
 

 
If:

 
UDO is Deleted
 

Associated Object
is Deleted

UDO is Updated

Associated Object is Updated

What happens to:

 
Link

Associated Object

 
Link

 
UDO

Associated Object

 
UDO

Link type 1

Removed

Nothing

Removed

Deleted

Nothing*

Updated

Link type 2

Removed

Deleted

Nothing

Nothing

Nothing*

Nothing

Link type 3

Removed

Nothing

Removed

Updated

Nothing*

Updated

Link type 4

Removed

Nothing

Removed

Nothing

Nothing*

Nothing

 
Owning Link

 
Removed

Nothing (if AssocObj is a solid body) / Deleted (otherwise)

 
NA-The AssocObj cannot be deleted directly

 
Nothing*

 
Nothing

*However, you can cause the associated object to update by registering an update function to the UDO class.
 
Restrictions for Link Type 2
Link Type 2 can not be used to link User Defined Objects to features, solid faces, or solid edges.
 
NOTE: Cyclical links (regardless of type) are not allowed. For example, if UDO_A is linked to UDO_B, then UDO_B can not be linked back to UDO_A.
 

Figure 1 Cyclical links are not allowed
 
 
UDO Owning Link
A UDO owning link links a UDO with an NX object.  A UDO with owning links has some unique interactive selection qualities.  Interactively, when you select an NX object, that is referenced to a UDO by an owning link, you are directly selecting both the associated UDO and the NX object itself.  For example, if you perform an Infoŕ Object on an NX spline that is referenced by an UDO owning link, then the information you receive is from both the associated UDO and the spline. 
 
There are times where you may not want to select both the owned object, and the owning UDO.  For example, if your UDO computes the knot points of a spline, and then creates the spline as an owned object, you may want to allow selection of the spline so that it can be used in modeling to create an extrusion.  In this case you would want to set your UDO class to allow the selection of owned objects.
 
The selection behavior can be changed by calling UF_UDOBJ_set_owned_object_selection.  If the behavior is set to UF_UDOBJ_ALLOW_SELECTION with UF_UDOBJ_set_owned_object_selection and you select the owned object, if the owning UDO is also selectable, the Up One Level button will become active.  Now if you select the Up One Level button, you will in effect select both the owned object and the owning UDO (assuming the class selection filters allow their selections).  If the UDO is not eligible for selection, picking the owned object will select the owned object only, and the Up One Level button will not activate.  Notice that the class selection filter can still be used to filter out selections.  If the filter is set to filter out the type of the owned object, then picking the UDO will result in the selection of only the UDO and the owned object will not be selected.  
 
A UDO can have more than one owning link.  For example, UDO_A can have owning links to the following NX objects: NX_obj1, NX_obj2, and NX_obj3.  Selection of UDO_A will result in the selection of all three objects, provided they are all selectable.  Although a UDO can have owning links to more than one NX object, the converse is not true.  An NX object can only be owned by one UDO.
 
UDOs can own other UDOs, so you can have the chain:
            UDO1 owns UDO2 owns UDO3 owns point1
 
For a detailed discussion on the selection behavior of such cases, please see the Selection of UDOs with owning links.
 
The UDO owning links have similar properties to link types 1-4 which are as follows:
 
You should use the following routines to handle UDO owning links rather than use the regular link routines.
            UF_UDOBJ_add_owning_links
            UF_UDOBJ_ask_owned_objects
            UF_UDOBJ_ask_owning_udo
            UF_UDOBJ_delete_owning_link
UF_UDOBJ_is_owned
 
 
 
Events for UDOs
UDOs can participate in certain NX events through registered callback functions which are referred to as methods.  The methods are function pointers which are arguments to the callback registration functions.
 
There are five events that trigger callbacks for UDO participation:
 
 
 
Display
NX has no knowledge of how or where a UDO should be displayed, so a callback occurs to allow users the opportunity to display the UDO in its desired format and at the correct location with respect to the absolute coordinate system.  The actual display is processed as a result of a series of primitive display routines within the context of the callback.
 
The primitive display functions allow you to display:
 
The absence of an assigned method means that the UDO can not participate in display events.  If any of the display methods are to be used, then they all should be used.  Note that the display methods should not perform any operations other than the primitive display functions listed above.  In particular, you should never use the following routines in any display callback function:
 
The callback format for all three display events is the same.  The inputs should include the tag of the UDO that is to be affected and a display context pointer.  The display context pointer should be passed through to the primitive display routines and can be queried to determine the state of display and what is expected from the callback (i.e. display, attention point, or fit).
 
The same function can be used for all three methods because they al have the same basic code structure.  If there is something special that needs to be done in only one of the cases, or only under special circumstances, the routine UF_DISP_ask_display_context can be used to determine the actual cause and condition of the callback.
 
 
 
Selection
There are two types of selection available to UDOs.  The first type of selection is single selection.  The second type of selection is class selection.  Like display, the absence of an assigned method means that the UDO can not participate in selection.  If any of the selection methods are to be used, then all of them should be used
 
The single selection implementation is identical to that of the display routines outlined above.  NX knows that a UDO exists in the vicinity of the screen pick, but needs to determine whether or not to select a UDO depending on the selection method.  The UDO selection callback informs NX of the location of the UDO via the display primitives outlined above.  Then NX internal algorithms decide whether to select the UDO or not.  The method is registered with NX via UF_UDOBJ_register_select_cb.
 
The class selection interface is enabled via UF_UI_add_to_class_sel and disabled via UF_UI_delete_from_class_sel.  These routines either add or delete the user friendly name associated with a UDO class to the class selection dialog.  This enables filtering on the particular UDO class.  (The user friendly name is associated with the class at the time the class is created.  See UDO Name).  The following interactive NX functions have class selection enabled for UDO selection.
 
 
 
Update
The mechanism within NX that keeps all of the objects up to date as the model changes is called the update mechanism.
 
As objects change in the data model, other objects need to be notified about those changes so they keep up to date with respect to the model.  For example, if a dimension is assigned to the height of a block and the block’s height changes, the dimension needs to be notified so that it can reflect the new height.  As objects are involved in the update mechanism, they are examined for associations with other objects (such as types 1 and 3 described in the structure UF_UDOBJ_link_s) that require those objects to be updated in addition to the original object.  If any such associations are found, the associated objects are added to the list of items to be updated, and the process continues.  (This is why cyclic relationships are not allowed as mentioned earlier in the Links section.)  Each item on the update list is then accessed and processed during update.
 
The update method available with UDOs is called when an object associated to a UDO with either a link type 1 or a link type 3 association passed through update.  By definition associated objects going through update that are linked to a UDO, with link type 2, 4,  or with an owning link do not add the UDO to the update list.  Therefore, an associated object with link type 2, or 4, or owning link does not invoke the update method. 
 
The update method takes in the tag of the UDO that is passing through update, and if known, the link of type UF_UDOBJ_link_p_t that sent the UDO to update (if unknown, this can be a null pointer).  The method is registered with NX via UF_UDOBJ_register_update_cb.
 
If a UDO is linked to a number of NX objects using link types 1 or 3 and has an update callback registered, an update of the UDO will be caused by changes to any one (or more) of the linked NX objects.  The update callback will be called only after all of the associated objects are updated.  In other words, the UDO’s registered callback is called only once per update cycle, regardless of how many associated objects are modified.  The assoc_ug_tag field of the callback’s link (update_cause ) parameter contains only one of the object tags which may have changed.  The callback should assume that everything that the UDO depends on has changed and update itself accordingly.
 
While within the update callback, you may freely query the data model.  You may also edit the free form data areas in the UDO.  Additionally, you may display a dialog (in internal Open C API) to inform the NX user of the affect the edit may have on the UDO.  If you display any dialogs be sure you use UF_UI_lock_ug_access and UF_UI_unlock_ug_access.
 
However, there are restrictions on the types of actions that can be performed during the context of this callback.  These restrictions are necessary to keep the context of the system correct and because the update mechanism can not cope with recursive invocations.  The restrictions are:
 
 
 
Delete
As objects associated to the UDO are deleted from the model, it may be necessary to realign data in the free form data areas or in the convertible data areas to reflect the removal of the associated objects from the data model.  The notification during the delete callback should enable this realignment.  The UDO receives this notification of the deletion of an associated object only if the UDO itself is not being deleted.  The delete method is only available for UDO's with link type 2 or link type 3.
 
 
Is Occurrenceable
When a UDO is created in the component part of an assembly, this function determines if the UDO will display when the component part is not the current displayed part.
 
 
 
Selection of UDOs with Owning Links
There are two scenarios with the selection of UDOs that have owning links, depending on how the selection of its owned object is set.
 
Selection of any object is controlled by the selection filter.  Therefore, if any of the owned objects is not selectable, then the owned object would not be selected when the owning UDO is selected.  However the unselectable owned object would pre-highlight to show that is owned by the UDO.
 
Consider the following example of three UDOs where:
The following table lists the objects selected when you pick an object, go Up One Level, go Up Two Levels (by selecting Up One Level two times), and go Up Three Levels.  The selection depends on whether or not the object is selectable, and whether or not the owned object selection is allowed for each UDO.  The example assumes that the class selection filter allows the selection of points, and the three UDOs.
 
 

Owned Object Selection Allowed for:

Selection of Point-3

Selection of Point-3/ Up One Level

Selection of Point-3/ Up Two Levels

Selection of Point-3/ Up Three Levels

UDO-1
UDO-2
UDO-3

Point-3

Point-3,
UDO-3

Point-3,
UDO-3,
Point-2,
UDO-2

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

UDO-1
UDO-2

Point-3,
UDO-3

Point-3,
UDO-3,
Point-2,
UDO-2

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

UDO-1
UDO-3

Point-3

Point-3,
UDO-3,
Point-2,
UDO-2

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

UDO-1

Point-3,
UDO-3,
Point-2,
UDO-2

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

NA

UDO-2
UDO-3

Point-3

Point-3,
UDO-3

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

UDO-2

Point-3,
UDO-3

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

NA

UDO-3

Point-3

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

NA

 

Point-3,
UDO-3,
Point-2,
UDO-2,
Point-1,
UDO-1

NA

NA

NA

 
 
 
 
Automatic Loading at Startup
Classes and methods can be automatically loaded into NX during system initialization for both an interactive session and an external Open C API program.  To load the classes and methods automatically create a user directory with startup, application, and udo subdirectories. Once the user directory structure is created, add the base directory to the custom_dirs.dat file found in the $UGII_BASE_DIR/ugii/ugmenu.  Then, place the libraries in the “udo” directory.  
 
For example, if you add the directory “/user/myhome” to custom_dirs.dat, then you place your libraries in the directory “/user/myhome/udo”.

Figure 2 UDO Subdirectory
 
Warning:
If you place a shared library in the udo directory for both interactive NX and for external Open C API programs, then your shared library cannot contain any calls to the internal only routines.
 
The directories present in the custom_dirs.dat file are processed in order, and the shared libraries found in them are loaded.  In order to load the shared library, the library must contain a ufsta entry point.
 
Additionally, your shared library must have the correct file extension for a particular platform as follows:
 
Loading takes place during NX initialization.  Thus, the loading of a shared library occurs before any parts are loaded, and (if in interactive mode) before a user interface is present.
 
Consequently, you should not:
 
The creation of UDO classes and the registration of the methods is all we recommend during this period of the system’s initialization.  In an external Open C API program, initialization occurs at UF_initialize.
 
Since classes can be created at an time during an NX session, you are not required to use this mechanism.  However, this mechanism guarantees that classes and methods are present for and applied to all parts loaded within a session.
 
 
 
UDO Features
To create a UDO feature:
 
The UDO links define parents of the UDO feature while the owning objects define its children.  It is important to ensure that the UDO data model is correct with respect to timestamp creation.  The primary difference between a UDO and a UDO feature is that the UDO updates last.  For example, if you create links to modeling objects that were created after the UDO you will get errors during update.
 
As you create features, the system assigns a time stamp for each feature.  When a feature is modified, the update is controlled by the ordering of the timestamps.
 
Features are listed in the order in which they were created, as indicated by the time stamp (the number in parenthesis at the end of the name).  The time stamp also indicates the order in which features will be evaluated when the model is updated.
 
For example:
  1. create feature BLOCK(0)
  2. create feature TAPER(1)
  3. create UDO

 
The UDO updates after the last feature to update, in this example, after TAPER(1).  If we create feature HOLLOW(2), then the UDO updates after HOLLOW(2).
 
If the UDO references the edge of the block then it updates via the final state of this edge.  That is, after the taper has been applied.
 
UDO features update in feature order.
Fore example,
  1. create feature BLOCK(0)
  2. create feature UDO(1)
  3. create feature TAPER(2)

 
The UDO now updates right after BLOCK(0) and right before TAPER(2).  If the UDO referenced the edge of a block, then it would update via the intermediate state of the edge (before the taper was applied).   In this example, you would most likely have wanted to create a UDO and not a UDO feature since the final state of the model is probably what you want the UDO to reference.
 
However, if any of the owned objects of the UDO are going to be referenced by other features, then a UDO feature must be created or else the feature update will be incorrect.
 
For example:
  1. create feature BLOCK(0)
  2. create feature UDO(1)
  3. create feature SWEEP(2)

 
First the block updates.  Then the UDO updates its owned objects.  In this case it is a line which is used as a path for the sweep.  Then the sweep updates.
 
In general, UDOs update after feature update and UDO features update during feature update.
 
If you wish to, you may use UDO callbacks.  The UDO feature does not place any limitations of the implementation of callbacks.
 
Interactively, the UDO feature appears in the following feature menus:
 
To make a UDO dependent on an expression, use UF_MODL_create_exp_tag to create the expression tag.  Then call UF_SO_create_scalar_exp to create a smart scalar from the expression.  Finally, link the smart scalar to the UDO object corresponding to the UDO feature using a link type of 1 or 3 with UF_UDOBJ_add_links. If a UDO feature depends on expressions, then the expressions can be edited through Edit Parameters.