For documentation on the asset inputs APIs, see Curves.
The Curve Node
Below is a sample that creates a NURBS curve with 4 control points.
#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_CreateNode( &session, -1,
"sop/curve",
"NURBS",
false, &curveNode ) );
ENSURE_SUCCESS(
HAPI_CookNode ( &session, curveNode, &cookOptions ) );
int cookStatus;
do
{
}
ENSURE_SUCCESS( cookResult );
ENSURE_COOK_SUCCESS( cookStatus );
int coordsParmIndex = -1;
int typeParmIndex = -1;
for (
int i = 0; i < curveNodeInfo.
parmCount; i++)
{
std::string parmName = getString( parmInfos[i].nameSH );
if ( parmName == "coords" )
{
coordsParmIndex = i;
}
if ( parmName == "type" )
{
typeParmIndex = i;
}
}
if ( coordsParmIndex == -1 || typeParmIndex == -1 )
{
std::cout << "Failure at " << __FILE__ << ": " << __LINE__ << std::endl;
std::cout << "Could not find coords/type parameter on curve node" << std::endl;
}
int typeValue = 1;
ENSURE_SUCCESS(
HAPI_SetParmStringValue( &session, curveNode,
"-4,0,4 -4,0,-4 4,0,-4 4,0,4", parm.
id, 0 ) );
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 output file, when opened in Houdini, shows the following:
Curve Marshalling
For documentation on curve marshaling, see Curve Marshalling.
The following code uses curve marshaling to create the same curve as in The Curve Node example:
#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, newNode, &cookOptions ) );
int cookStatus;
do
{
std::cout << "Waiting on cook." << std::endl;
}
ENSURE_SUCCESS( cookResult );
ENSURE_COOK_SUCCESS( cookStatus );
int curveCount = 4;
float curveKnots[ 8 ] = { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f };
float positions [ 12 ] = { -4.0f, 0.0f, 4.0f,
-4.0f, 0.0f, -4.0f,
4.0f, 0.0f, -4.0f,
4.0f, 0.0f, 4.0f };
ENSURE_SUCCESS(
HAPI_SaveHIPFile( &session,
"examples/curve_marshall.hip",
true ) );
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;
}
Curve Output
For documentation on curve outputs, see Curve Output.
The code sample below shows loading the above asset via code and displaying information about the curve.
#include <iostream>
#include <string>
#include <vector>
#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)
{
const char * hdaFile = argc == 2 ? argv[ 1 ] : "examples/nurbs_curve.hda";
&cookOptions,
true,
-1,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr ) );
int assetCount;
if (assetCount > 1)
{
std::cout << "Should only be loading 1 asset here" << std::endl;
exit ( 1 );
}
std::string assetName = getString( assetSh );
ENSURE_SUCCESS(
HAPI_CreateNode( &session, -1, assetName.c_str(),
"Loaded Asset",
false, &nodeId ) );
ENSURE_SUCCESS(
HAPI_CookNode( &session, nodeId, &cookOptions ) );
int cookStatus;
do
{
}
ENSURE_SUCCESS( cookResult );
ENSURE_COOK_SUCCESS( cookStatus );
int childCount;
for ( int i = 0; i < childCount; ++i )
{
{
continue;
}
for (
int partIndex = 0; partIndex < geoInfo.
partCount; ++partIndex )
{
{
printCurveInfo( objInfo, geoInfo, partInfo );
}
}
}
char in;
std::cout << "Enter some input to exit" << std::endl;
std::cin >> in;
return 0;
}
{
std::cout <<
"Object Node: " << objInfo.
nodeId <<
", Geometry Node: " << geoInfo.
nodeId <<
", Part ID: " << partInfo.
id << std::endl;
std::cout << "curve mesh type = Linear" << std::endl;
std::cout << "curve mesh type = Bezier" << std::endl;
std::cout << "curve mesh type = Nurbs" << std::endl;
else
std::cout << "curve mesh type = Unknown" << std::endl;
std::cout <<
"curve count: " << curveInfo.
curveCount << std::endl;
int vertexOffset = 0, knotOffset = 0;
for (
int curveIndex = 0; curveIndex < curveInfo.
curveCount; ++curveIndex )
{
std::cout <<
"Curve " << curveIndex + 1 <<
" of " << curveInfo.
curveCount << std::endl;
int numVertices;
std::cout << "Number of vertices : " << numVertices << std::endl;
int order;
{
}
else
{
}
std::cout << "Curve Order: " << order << std::endl;
if ( numVertices < order )
{
std::cout << "Not enough vertcies on curve " << curveIndex + 1 << " of "
<< curveInfo.
curveCount <<
": skipping to next curve" << std::endl;
vertexOffset += numVertices * 4;
knotOffset += numVertices + order;
continue;
}
-1, &pArray.front(), 0, attrInfoP.
count ) );
for ( int j = 0; j < numVertices; j++ )
{
std::cout << "CV " << j + 1 << ": " << pArray[ j * 3 + 0 ] << ","
<< pArray[ j * 3 + 1 ] << ","
<< pArray[ j * 3 + 2 ] << std::endl;
}
{
std::vector< float > knots;
knots.resize( numVertices + order );
knotOffset, numVertices + order ) );
for( int j = 0; j < numVertices + order; j++ )
{
std::cout
<< "knot " << j + 1
<< ": " << knots[ j ] << std::endl;
}
}
vertexOffset += numVertices * 4;
knotOffset += numVertices + order;
}
}
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;
}