Open C++ Programmer's Guide > Open C++ Classes > Object Classes
Object Classes: Create, Read/Write, Tags, Parts, Prototypes, Curves/Edges
Create
Leaf-node Open C++ classes represent actual NX object types (e.g. UgArc for
arcs, UgExpression for expressions) — these are "instantiable" classes: you
create an object of that type by invoking a static create() method. Example:
UgPart *pWorkPart = UgSession::getWorkPart ( );
UgExpression *pExpr;
pExpr = UgExpression::create ( "diameter", 4.25 , pWorkPart );
double diaValue = pExpr->evaluate ( );
NX objects are always referenced by pointer — the C++ constructor is
protected, so you can't construct one directly; you always get a pointer back
from create(). This conserves memory and keeps your C++ objects in sync
with NX's own internal model state.
UgAssemblyNode is the one exception: it's created via
UgPart::addPart(), not its own create():
UgPart *pWorkPart = UgSession::getWorkPart ( );
UgAssemblyNode *pNode;
pNode = pWorkPart->addPart ( "component.prt", "", "", CoordSys ( ), -1 );
Some classes overload create() for alternate ways to build an object (e.g.
UgExpression::create can take a name+value, an expression built from another
expression, or a std::string). The last argument to every create method is
always the optional part context — the part that will own the new object.
If omitted, the new object is owned by the current work part; supply it
explicitly if you want the object owned by some other part.
Read/Write Access
Once you have a pointer to an NX object you can call any method defined on its class or base classes to inquire or modify it, e.g.:
pArc->setRadius ( 2.5 );
double len = pArc->computeArcLength ( );
int layer = pArc->getLayer ( );
setRadius() is defined directly on UgArc; computeArcLength() is
inherited from a base curve-evaluation class and getLayer() from the base
displayable-object class.
Converting to/from Tags
Open C++ can interoperate with legacy Open C (UF) code by converting between
Open C++ pointers and Open C tags: UgObject::find(tag) returns a pointer
(you'll typically dynamic_cast it to the specific subtype you expect — see
Dynamic Casting below), and pObj->getTag() converts back to a tag.
tag_t tag1, tag2;
UF_UI_select_single ( ..., &tag1, ... ); // traditional Open C call
UgObject *pObj = UgObject::find ( tag1 );
if ( pObj ) {
UgLine *pLine = dynamic_cast <UgLine *> pObj;
if ( pLine ) {
pLine->setColor ( Red );
tag2 = pLine->getTag ( ); // tag2 == tag1
}
}
Parts
UgPart holds methods that apply to an entire NX part: create/open/save/close
a part, and access/modify part attributes and other part-file data. (Closing
one part is a UgPart method; closing all parts is on UgSession.)
UgPart *pPart = UgPart::open ( "valve.prt" );
bool isItMetric = pPart->isMillimeters ( );
UgObject::find()/getTag() also work for converting UgPart pointers
to/from part tags. To iterate every object in a part regardless of class, use
UgPart::iterateFirst() / iterateNext():
UgPart *pWorkPart = UgSession::getWorkPart ( );
UgTypedObject *pCurObj;
for ( pCurObj = pWorkPart->iterateFirst ( ); pCurObj;
pCurObj = pWorkPart->iterateNext ( pCurObj ) ) {
std::string name = pCurObj->getName ( );
}
Because iteration must return a pointer applicable to any typed NX object,
iterateFirst/iterateNext return a base UgTypedObject* — cast to a more
specific type (see Dynamic Casting) to call type-specific methods. The
template UgIterator class (see Template Classes) offers an alternative
iteration style.
Prototypes and Occurrences
"Prototype" vs. "occurrence" describes how NX objects are accessed within an assembly context: a prototype is the actual geometric object in a component part; an occurrence orients the prototype within the assembly. Iterating via Open C++ can surface both prototypes and occurrences. You may read and modify a prototype's geometry, but an occurrence is read-only for its defining geometry — attempting to edit an occurrence requires first resolving to its prototype.
Curves and Edges
NX has distinct object types for free-standing wireframe curves (lines, arcs,
splines) and edge curves belonging to solid/sheet bodies — but Open C++
unifies their evaluation: since both inherit from UgEvaluatableObject, you
can write generic code that treats them identically:
UgEvaluatableObject *pObj1, *pObj2; // could be either a wireframe curve or an edge
double len1 = pObj1->computeArcLength ( );
double len2 = pObj2->computeArcLength ( );
std::vector<CurveCurveIntersectionPoint> iPts;
iPts = pObj1->computeIntersectionPoints ( pObj2 );
Point coordinates/normals at arbitrary locations are available via an
Evaluator object from UgEvaluatableObject::askEvaluator(). If you need
type-specific data (e.g. radius) without knowing whether an object is a
wireframe arc or a circular solid edge, dynamic_cast to Arc*:
Arc *pArc = dynamic_cast < Arc * > pCircularObj->askCurve ( );
double radius = pArc->getRadius ( );
If you already know an object is a UgArc, you can access curve data
directly without an intermediate cast.
Source: https://docs.sw.siemens.com/en-US/doc/209349590/PL20220512394070742.open_c_plus_plus_program · retrieved Tue Jul 07 2026 00:00:00 GMT+0000 (Coordinated Universal Time)