Houdini Engine 1.9
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Materials Sample

For documentation on the materials API, see Materials.

The example below gives an illustration of extracting both the diffuse texture map from the spaceship asset (available from www.orbolt.com), as well as extracting the Mantra rendered image planes of C (diffuse color), A (alpha), and N (normal) in the UV space of the asset.

#include <HAPI/HAPI.h>
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
cout << "failure at " << __FILE__ << ":" << __LINE__ << endl; \
cout << get_last_error() << endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_STATE_READY ) \
{ \
cout << "failure at " << __FILE__ << ":" << __LINE__ << endl; \
cout << get_last_cook_error() << endl; \
exit( 1 ); \
}
static void dump_asset_materials(
int asset_id, const HAPI_AssetInfo &asset_info );
static void dump_part_diffuse_texturemap(
int asset_id, int object_id, int geo_id, int part_id );
static void dump_part_mantra_render(
int asset_id, int object_id, int geo_id, int part_id );
static void extract_image_planes(
int asset_id,
const HAPI_MaterialInfo & material_info,
const char * base_file_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 ] : "C:/test/SideFX__spaceship.otl";
ENSURE_SUCCESS( HAPI_Initialize(
NULL,
/*dso_search_path=*/ NULL,
&cook_options,
/*use_cooking_thread=*/ true,
/*cooking_thread_max_size=*/ -1 ) );
int library_id;
int asset_id;
otl_file,
true,
&library_id ) != HAPI_RESULT_SUCCESS )
{
cout << "Could not load " << otl_file << endl;
exit( 1 );
}
HAPI_StringHandle asset_name_sh;
ENSURE_SUCCESS( HAPI_GetAvailableAssets( library_id, &asset_name_sh, 1 ) );
std::string asset_name = get_string( asset_name_sh );
asset_name.c_str(),
/* cook_on_load */ true,
&asset_id ) != HAPI_RESULT_SUCCESS )
{
cout << "Could not instantiate asset " << asset_name << endl;
exit( 1 );
}
wait_for_cook();
// Retrieve information about the asset.
HAPI_AssetInfo asset_info;
ENSURE_SUCCESS( HAPI_GetAssetInfo( asset_id, &asset_info ) );
// Print information about the geometry contained inside the asset.
dump_asset_materials( asset_id, asset_info );
ENSURE_SUCCESS( HAPI_Cleanup() );
return 0;
}
static void wait_for_cook()
{
int status;
do
{
}
while ( status > HAPI_STATE_MAX_READY_STATE );
ENSURE_COOK_SUCCESS( status );
}
static void dump_asset_materials( int asset_id, const HAPI_AssetInfo &asset_info )
{
HAPI_ObjectInfo * object_infos =
new HAPI_ObjectInfo[ asset_info.objectCount ];
ENSURE_SUCCESS( HAPI_GetObjects(
asset_id, object_infos, /*start=*/ 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(
asset_id, object_info.id, geo_index, &geo_info ) );
for ( int part_index = 0; part_index < geo_info.partCount;
++part_index )
{
dump_part_diffuse_texturemap(
asset_id, object_info.id, geo_info.id, part_index );
dump_part_mantra_render(
asset_id, object_info.id, geo_info.id, part_index );
}
}
}
delete [] object_infos;
}
static int find_parm_index(
HAPI_NodeInfo & node_info,
HAPI_ParmInfo *parm_infos,
const char * parm_name_in )
{
int parm_index = -1;
for ( int i=0; i < node_info.parmCount; ++i )
{
std::string parm_name = get_string( parm_infos[ i ].nameSH );
if ( parm_name == parm_name_in )
{
parm_index = i;
break;
}
}
return parm_index;
}
static void extract_image_planes(
int asset_id,
const HAPI_MaterialInfo & material_info,
const char * base_file_name )
{
HAPI_ImageInfo image_info;
ENSURE_SUCCESS( HAPI_GetImageInfo( asset_id, material_info.id, & image_info ) );
std::string image_format_name = get_string( image_info.imageFileFormatNameSH );
cout << "Image width=" << image_info.xRes << " height=" << image_info.yRes <<
" Format:" << image_format_name << endl;
int num_image_planes;
ENSURE_SUCCESS( HAPI_GetImagePlaneCount( asset_id, material_info.id, &num_image_planes ) );
cout << "Number of image planes" << num_image_planes << endl;
int * image_planes = new int[ num_image_planes ];
HAPI_GetImagePlanes( asset_id, material_info.id, image_planes, num_image_planes );
for ( int ii = 0; ii < num_image_planes; ii++ )
{
std::string image_plane_name = get_string( image_planes[ii] );
cout << "Imange plane [" << ii << "] = " << image_plane_name << endl;
int destination_file_path;
std::string file_name = base_file_name + image_plane_name;
asset_id, material_info.id,
image_plane_name.c_str(),
"C:/test",
file_name.c_str(),
&destination_file_path );
std::string destination_file_path_str = get_string( destination_file_path );
cout << "File written to " << destination_file_path_str << endl;
}
delete[] image_planes;
}
static void dump_part_mantra_render(
int asset_id, int object_id, int geo_id, int part_id )
{
cout << "object " << object_id << ", geo " << geo_id
<< ", part " << part_id << endl;
HAPI_PartInfo part_info;
ENSURE_SUCCESS( HAPI_GetPartInfo(
asset_id, object_id, geo_id, part_id, &part_info ) );
HAPI_MaterialId material_id = -1;
HAPI_MaterialInfo material_info;
asset_id, object_id, geo_id, part_id, NULL, &material_id, 0, 1 );
HAPI_GetMaterialInfo( asset_id, material_id, &material_info );
if ( !material_info.exists )
{
cout << "No material found:" << "object " << object_id << ", geo " << geo_id
<< ", part " << part_id << endl;
return;
}
HAPI_GlobalNodes global_nodes;
HAPI_GetGlobalNodes( &global_nodes );
HAPI_NodeInfo node_info;
ENSURE_SUCCESS( HAPI_GetNodeInfo( global_nodes.mantraRenderer, &node_info ) );
// Get information about all the parameters.
HAPI_ParmInfo *parm_infos = new HAPI_ParmInfo[ node_info.parmCount ];
ENSURE_SUCCESS( HAPI_GetParameters(
global_nodes.mantraRenderer, parm_infos, /*start=*/ 0, node_info.parmCount ) );
int gamma_parm_index = find_parm_index( node_info, parm_infos, "vm_gamma" );
if ( gamma_parm_index >=0 )
{
float gamma_value = 2.2f;
global_nodes.mantraRenderer,
&gamma_value,
parm_infos[gamma_parm_index].floatValuesIndex,
1 );
}
HAPI_RenderMaterialToImage( asset_id, material_info.id, HAPI_SHADER_MANTRA );
extract_image_planes( asset_id, material_info, "spaceship_normal_" );
}
static void dump_part_diffuse_texturemap(
int asset_id, int object_id, int geo_id, int part_id )
{
cout << "object " << object_id << ", geo " << geo_id
<< ", part " << part_id << endl;
HAPI_PartInfo part_info;
ENSURE_SUCCESS( HAPI_GetPartInfo(
asset_id, object_id, geo_id, part_id, &part_info ) );
HAPI_MaterialId material_id = -1;
HAPI_MaterialInfo material_info;
asset_id, object_id, geo_id, part_id, NULL, &material_id, 0, 1 );
HAPI_GetMaterialInfo( asset_id, material_id, &material_info );
if ( !material_info.exists )
{
cout << "No material found:" << "object " << object_id << ", geo " << geo_id
<< ", part " << part_id << endl;
return;
}
HAPI_NodeInfo node_info;
ENSURE_SUCCESS( HAPI_GetNodeInfo( material_info.nodeId, &node_info ) );
// Get information about all the parameters.
HAPI_ParmInfo *parm_infos = new HAPI_ParmInfo[ node_info.parmCount ];
ENSURE_SUCCESS( HAPI_GetParameters(
material_info.nodeId, parm_infos, /*start=*/ 0, node_info.parmCount ) );
int base_color_map_parm_index = find_parm_index(
node_info, parm_infos, "baseColorMap" );
if ( base_color_map_parm_index < 0 )
{
cout << "Could not find parameter for diffuse texture map" << endl;
return;
}
ENSURE_SUCCESS( HAPI_RenderTextureToImage(
asset_id, material_info.id,
parm_infos[ base_color_map_parm_index ].id ) );
extract_image_planes( asset_id, material_info, "spaceship_baseColorMap_" );
}
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( string_handle, &buffer_length ) );
char * buf = new char[ buffer_length ];
ENSURE_SUCCESS( HAPI_GetString( string_handle, buf, buffer_length ) );
std::string result( buf );
delete[] buf;
return result;
}
static std::string get_last_error()
{
int buffer_length;
char * buf = new char[ buffer_length ];
std::string result( buf );
delete[] buf;
return result;
}
static std::string get_last_cook_error()
{
int buffer_length;
char * buf = new char[ buffer_length ];
std::string result( buf );
delete[] buf;
return result;
}