Object (OBJ) nodes are Houdini's transform nodes. They can contain other OBJ nodes or geometry (SOP) nodes (Geos).
Query
Given a HAPI_NodeId that represents an OBJ node, you can get the HAPI_ObjectInfo via HAPI_GetObjectInfo() with that node id.
To get all the object nodes inside another node, usually the asset node, simply call HAPI_ComposeObjectList(). This will create an internal list of OBJ node ids by recursively looking for geometry type OBJ nodes, nodes that contain geometry, or leaf OBJ nodes. This function will return you the object_count
which you can use to create an array of HAPI_ObjectInfo and then fill it with HAPI_GetComposedObjectList().
HAPI_GetComposedObjectList() is actually a specialized version of HAPI_ComposeChildNodeList() that is recursive
, looks for HAPI_NODETYPE_OBJ, and uses the HAPI_NODEFLAGS_OBJ_GEOMETRY flag.
Here's an example of using these functions:
hapiTestSession, "HAPI_Test_Objects_ObjectTypes.otl",
false, &library_id );
HAPI_TEST_ASSERT( library_id >= 0 );
hapiTestSession, -1, "Object/HAPI_Test_Objects_ObjectTypes",
nullptr, true, &node_id );
int child_count = 0;
HAPI_TEST_ASSERT( child_count == 2 );
std::vector< HAPI_NodeId > child_node_ids( child_count );
hapiTestSession, node_id, child_node_ids.data(), child_count );
int object_count = 0;
hapiTestSession, node_id, nullptr, &object_count );
HAPI_TEST_ASSERT( object_count == 2 );
std::vector< HAPI_ObjectInfo > object_infos( object_count );
hapiTestSession, node_id, object_infos.data(), 0, object_count );
for ( int i = 0; i < child_count; ++i )
HAPI_TEST_ASSERT( object_infos[ i ].nodeId == child_node_ids[ i ] );
Object Transforms
Since OBJ nodes are really just fancy transforms, we provide special functions to easily get this transform.
You can get the transform on a single object node by calling HAPI_GetObjectTransform(). However, it's usually more efficient to get the transforms on a lot of object nodes at once. To do this, after the same call to HAPI_ComposeObjectList() from above in Query, you can call HAPI_GetComposedObjectTransforms(). Both HAPI_GetComposedObjectList() and HAPI_GetComposedObjectTransforms() use HAPI_ComposeObjectList() to get the internal object list created.
Here's an example of getting transforms on a bunch of object nodes:
hapiTestSession, "HAPI_Test_Objects_Transforms_Simple.otl",
false, &library_id );
HAPI_TEST_ASSERT( library_id >= 0 );
hapiTestSession, -1, "Object/HAPI_Test_Objects_Transforms_Simple",
nullptr, true, &node_id );
int object_count = 0;
hapiTestSession, node_id, nullptr, &object_count );
HAPI_TEST_ASSERT( object_count == 1 );
std::vector< HAPI_Transform > transforms( object_count );
hapiTestSession, node_id,
transforms.data(),
0, object_count );
HAPI_TEST_ASSERT( approx( transform.
position[ 0 ], 1.0f ) );
HAPI_TEST_ASSERT( approx( transform.
position[ 1 ], 2.0f ) );
HAPI_TEST_ASSERT( approx( transform.
position[ 2 ], 3.0f ) );
HAPI_TEST_ASSERT( approx( transform.
scale[ 0 ], 0.7f ) );
HAPI_TEST_ASSERT( approx( transform.
scale[ 1 ], 0.8f ) );
HAPI_TEST_ASSERT( approx( transform.
scale[ 2 ], 0.9f ) );
HAPI_TEST_ASSERT( approx( transform.
shear[ 0 ], 0.1f ) );
HAPI_TEST_ASSERT( approx( transform.
shear[ 1 ], 0.11f ) );
HAPI_TEST_ASSERT( approx( transform.
shear[ 2 ], 0.12f ) );