The example below shows how to create groups on an input node and query their membership. It will create a cube, marshal it in, and create a point group on the input geometry. It goes on to create a transform SOP, connect the two nodes together, and sets the parameters on the transform SOP such that it affects only the points in the group we created. The scene at this point is dumped, so that we can see the result in Houdini.
Finally, the transform SOP asset is cooked, we then query its geometry for group information and show via output that the group is intact and display the group membership.
#include <iostream>
#include <string>
#define ENSURE_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastError() << std::endl; \
exit( 1 ); \
}
#define ENSURE_COOK_SUCCESS( result ) \
if ( (result) != HAPI_RESULT_SUCCESS ) \
{ \
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl; \
std::cout << getLastCookError() << std::endl; \
exit( 1 ); \
}
static std::string getLastError();
static std::string getLastCookError();
int
main( int argc, char **argv )
{
bool bUseInProcess = false;
if(bUseInProcess)
{
}
else
{
serverOptions.timeoutMs = 3000.0f;
}
&cookOptions,
true,
-1,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr ) );
ENSURE_SUCCESS(
HAPI_CookNode( &session, cubeNode, &cookOptions ) );
int cookStatus;
do
{
}
ENSURE_SUCCESS( cookResult );
ENSURE_COOK_SUCCESS( cookStatus );
float positions[ 24 ] = { 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f };
int vertices[ 24 ] = { 0, 2, 6, 4,
2, 3, 7, 6,
2, 0, 1, 3,
1, 5, 7, 3,
5, 4, 6, 7,
0, 4, 5, 1 };
int face_counts [ 6 ] = { 4, 4, 4, 4, 4, 4 };
int * pointMembership = new int[ groupElementCount ];
for ( int ii = 0; ii < groupElementCount; ++ii )
{
if ( ii % 2 )
{
pointMembership[ ii ] = 1;
}
else
{
pointMembership[ ii ] = 0;
}
}
"pointGroup", pointMembership, 0, groupElementCount ) );
ENSURE_SUCCESS(
HAPI_CreateNode( &session, -1,
"Sop/xform",
"PointGroupManipulator",
false, &xformNode ) );
int groupParmIndex = -1;
int tParmIndex = -1;
for (
int ii = 0; ii < xformInfo.
parmCount; ++ii )
{
std::string parmName = getString( parmInfos[ ii ].nameSH );
if ( parmName == "group" )
{
groupParmIndex = ii;
}
if ( parmName == "t" )
{
tParmIndex = ii;
}
}
if ( groupParmIndex < 0 || tParmIndex < 0 )
{
std::cout << "Error: couldn't find required parameters group or t" << std::endl;
exit( 1 );
}
float tParmValue[ 3 ] = { 0.0f, 1.0f, 0.0f };
ENSURE_SUCCESS(
HAPI_SetParmFloatValues( &session, xformNode, tParmValue, parmInfos[ tParmIndex ].floatValuesIndex, 3 ) );
ENSURE_SUCCESS(
HAPI_CookNode( &session, xformNode, &cookOptions ) );
int xformCookStatus;
do
{
}
ENSURE_SUCCESS( xformCookResult );
ENSURE_COOK_SUCCESS( xformCookStatus );
std::cout << "Number of point groups on xform: " << numGroups << std::endl;
std::cout << numElementsInGroup << " points in pointGroup" << std::endl;
int * membership = new int[ numElementsInGroup ];
"pointGroup", nullptr, membership, 0, numElementsInGroup ) );
for ( int ii = 0; ii < numElementsInGroup; ++ii )
{
if ( membership[ ii ] )
{
std::cout << "Point " << ii << " is in pointGroup" << std::endl;
}
}
return 0;
}
static std::string
getLastError()
{
int bufferLength;
&bufferLength );
char * buffer = new char[ bufferLength ];
std::string result( buffer );
delete [] buffer;
return result;
}
static std::string
getLastCookError()
{
int bufferLength;
&bufferLength );
char * buffer = new char[ bufferLength ];
std::string result( buffer );
delete[] buffer;
return result;
}
static std::string
{
if ( stringHandle == 0 )
{
return "";
}
int bufferLength;
stringHandle,
&bufferLength );
char * buffer = new char[ bufferLength ];
std::string result( buffer );
delete [] buffer;
return result;
}
The HIP file that was saved as part of the program can also be seen here. Note that only points 1,3,5,7 have been moved up by the transform SOP: