Houdini Engine 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Objects, Geos, and Parts Sample

For documentation on the objects, geos, and parts API, see Objects, Geos, and Parts.

A full program the retrieves and prints data on all objects, geos, and parts on an asset.

#include <HAPI/HAPI.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "failure at " << __FILE__ << ":" << __LINE__ << std::endl; \
std::cout << get_last_error() << std::endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_STATE_READY ) \
{ \
std::cout << "failure at " << __FILE__ << ":" << __LINE__ << std::endl; \
std::cout << get_last_cook_error() << std::endl; \
exit( 1 ); \
}
static void print_asset_info( int asset_id, const HAPI_AssetInfo &asset_info );
static void process_geo_part(
int asset_id, int object_id, int geo_id, int part_id );
static void process_float_attrib(
int asset_id, int object_id, int geo_id, int part_id,
HAPI_AttributeOwner attrib_owner,
const char *attrib_name );
static std::string get_string( HAPI_StringHandle string_handle );
static std::string get_last_error();
static std::string get_last_cook_error();
static void wait_for_cook();
int main( int argc, char **argv )
{
const char *otl_file = argc == 2 ? argv[ 1 ] : "test_asset.otl";
ENSURE_SUCCESS( HAPI_Initialize(
nullptr, // session
&cook_options,
true, // use_cooking_thread
-1, // cooking_thread_stack_size
nullptr, // otl_search_path
nullptr, // dso_search_path
nullptr, // image_dso_search_path
nullptr // audio_dso_search_path
) );
int library_id;
int asset_id;
nullptr,
otl_file,
true,
&library_id ) != HAPI_RESULT_SUCCESS )
{
std::cout << "Could not load " << otl_file << std::endl;
exit( 1 );
}
HAPI_StringHandle asset_name_sh;
ENSURE_SUCCESS( HAPI_GetAvailableAssets(
nullptr, library_id, &asset_name_sh, 1 ) );
std::string asset_name = get_string( asset_name_sh );
nullptr,
asset_name.c_str(),
true,
&asset_id ) != HAPI_RESULT_SUCCESS )
{
std::cout << "Could not instantiate asset " << asset_name << std::endl;
exit( 1 );
}
wait_for_cook();
// Retrieve information about the asset.
HAPI_AssetInfo asset_info;
ENSURE_SUCCESS( HAPI_GetAssetInfo( nullptr, asset_id, &asset_info ) );
// Print information about the geometry contained inside the asset.
print_asset_info( asset_id, asset_info );
ENSURE_SUCCESS( HAPI_Cleanup( nullptr ) );
return 0;
}
static void wait_for_cook()
{
int status;
int update_counter = 0;
do
{
// Alternatively just use a sleep here - but didn't want to
// platform dependent #ifdefs for this sample.
if ( !( update_counter % 20 ) )
{
int statusBufSize = 0;
nullptr,
&statusBufSize ) );
char * statusBuf = NULL;
if ( statusBufSize > 0 )
{
statusBuf = new char[ statusBufSize ];
ENSURE_SUCCESS( HAPI_GetStatusString(
nullptr,
HAPI_STATUS_COOK_STATE, statusBuf, statusBufSize ) );
}
if ( statusBuf )
{
std::string result( statusBuf );
std::cout << "cooking...:" << result << "\n";
delete[] statusBuf;
}
}
update_counter++;
HAPI_GetStatus( nullptr, HAPI_STATUS_COOK_STATE, &status );
}
while ( status > HAPI_STATE_MAX_READY_STATE );
ENSURE_COOK_SUCCESS( status );
}
static void print_asset_info( int asset_id, const HAPI_AssetInfo &asset_info )
{
HAPI_ObjectInfo * object_infos =
new HAPI_ObjectInfo[ asset_info.objectCount ];
ENSURE_SUCCESS( HAPI_GetObjects(
nullptr,
asset_id, object_infos, 0, asset_info.objectCount ) );
for ( int object_index = 0; object_index < asset_info.objectCount;
++object_index )
{
HAPI_ObjectInfo &object_info = object_infos[object_index];
for ( int geo_index = 0; geo_index < object_info.geoCount;
++geo_index )
{
HAPI_GeoInfo geo_info;
ENSURE_SUCCESS( HAPI_GetGeoInfo(
nullptr,
asset_id, object_info.id, geo_index, &geo_info ) );
for ( int part_index = 0; part_index < geo_info.partCount;
++part_index )
{
process_geo_part(
asset_id, object_info.id, geo_info.id, part_index );
}
}
}
delete [] object_infos;
}
static void process_geo_part(
int asset_id, int object_id, int geo_id, int part_id )
{
std::cout << "object " << object_id << ", geo " << geo_id
<< ", part " << part_id << std::endl;
HAPI_PartInfo part_info;
ENSURE_SUCCESS( HAPI_GetPartInfo(
nullptr,
asset_id, object_id, geo_id, part_id, &part_info ) );
// Get the list of attribute names.
int *attrib_names_sh = new int[ part_info.pointAttributeCount ];
ENSURE_SUCCESS( HAPI_GetAttributeNames(
nullptr,
asset_id, object_id, geo_id, part_id,
attrib_names_sh,
part_info.pointAttributeCount ) );
std::cout << "attributes:" << std::endl;
for ( int attrib_index = 0; attrib_index < part_info.pointAttributeCount;
++attrib_index)
{
HAPI_StringHandle string_handle = attrib_names_sh[ attrib_index ];
std::string attrib_name = get_string( string_handle );
std::cout << " " << attrib_name << std::endl;
}
delete [] attrib_names_sh;
std::cout << "point positions:" << std::endl;
process_float_attrib(
asset_id, object_id, geo_id, part_id, HAPI_ATTROWNER_POINT, "P" );
std::cout << "Number of faces: " << part_info.faceCount << std::endl;
int * face_counts = new int[ part_info.faceCount ];
ENSURE_SUCCESS( HAPI_GetFaceCounts(
nullptr, asset_id, object_id, geo_id,
part_id, face_counts, 0, part_info.faceCount ) );
std::cout << "Facecounts:";
for( int ii=0; ii < part_info.faceCount; ii++ )
{
std::cout << face_counts[ii] << ",";
}
std::cout << "\n";
int * vertex_list = new int[ part_info.vertexCount ];
ENSURE_SUCCESS( HAPI_GetVertexList(
nullptr, asset_id, object_id, geo_id,
part_id, vertex_list, 0, part_info.vertexCount ) );
std::cout << "Vertex Indices into Points array:\n";
int curr_index = 0;
for( int ii=0; ii < part_info.faceCount; ii++ )
{
for( int jj=0; jj < face_counts[ii]; jj++ )
{
std::cout
<< "vertex :" << curr_index << ", belonging to face: "
<< ii <<", index: "
<< vertex_list[ curr_index ] << " of points array\n";
curr_index++;
}
}
delete[] face_counts;
delete[] vertex_list;
}
void process_float_attrib(
int asset_id, int object_id, int geo_id, int part_id,
HAPI_AttributeOwner attrib_owner,
const char *attrib_name )
{
// Get the attribute values.
HAPI_AttributeInfo attrib_info;
ENSURE_SUCCESS( HAPI_GetAttributeInfo(
nullptr,
asset_id, object_id, geo_id, part_id, attrib_name,
attrib_owner, &attrib_info ) );
float *attrib_data = new float[
attrib_info.count * attrib_info.tupleSize ];
ENSURE_SUCCESS( HAPI_GetAttributeFloatData(
nullptr,
asset_id, object_id, geo_id, part_id,
attrib_name, &attrib_info, attrib_data,
0, attrib_info.count ) );
for ( int elem_index = 0; elem_index < attrib_info.count; ++elem_index )
{
for ( int tuple_index = 0; tuple_index < attrib_info.tupleSize;
++tuple_index)
{
std::cout << attrib_data[
elem_index * attrib_info.tupleSize + tuple_index ]
<< " ";
}
std::cout << std::endl;
}
delete [] attrib_data;
}
static std::string get_string( HAPI_StringHandle string_handle )
{
// A string handle of 0 means an invalid string handle -- similar to
// a null pointer. Since we can't return NULL, though, return an empty
// string.
if ( string_handle == 0 )
return "";
int buffer_length;
ENSURE_SUCCESS( HAPI_GetStringBufLength(
nullptr, string_handle, &buffer_length ) );
char * buf = new char[ buffer_length ];
ENSURE_SUCCESS( HAPI_GetString(
nullptr, string_handle, buf, buffer_length ) );
std::string result( buf );
delete[] buf;
return result;
}
static std::string get_last_error()
{
int buffer_length;
nullptr,
char * buf = new char[ buffer_length ];
nullptr, HAPI_STATUS_CALL_RESULT, buf, buffer_length );
std::string result( buf );
delete[] buf;
return result;
}
static std::string get_last_cook_error()
{
int buffer_length;
nullptr,
char * buf = new char[ buffer_length ];
nullptr, HAPI_STATUS_CALL_RESULT, buf, buffer_length );
std::string result( buf );
delete[] buf;
return result;
}