I’m partial, but I like the Softimage soccer ball better than the Maya soccer ball.

The Softimage soccer ball is the one on the left. I took the ASS file for the soccer ball, did a few search and replace ops, and compiled my first procedural node. It’s pretty trivial, but it illustrates the basic framework. numNodes() returns the number of nodes you’re going to create; Arnold calls getNode() once for each node you create. I’m just creating one node, so I do it in getNode(), but you could also do it in init().
If you’re interested in learning more about the Arnold SDK and procedurals, you can download the SDK (docs included) at solidangle.com.
#include <ai.h>
#include <string.h>
static int init(AtNode *mynode, void **user_ptr )
{
AiMsgInfo( "[soccer] -- greetings!" );
return 1;
}
static int cleanup( void *d )
{
return 1;
}
static int numNodes( void *d )
{
return 1;
}
static AtNode *getNode( void *d, int index )
{
AtByte nsides[540] = {
4, 4, 4, 4, 4,
// ...
4, 4, 4, 4, 4};
unsigned int vidxs[2160] = {
292, 301, 12, 293, 302, 303, 304, 305, 302, 305, 306,
//...
169, 538, 537, 116, 168, 540, 539, 79, 151, 25, 541};
unsigned int nidxs[2160] = {
0, 1, 2, 3, 4, 5, 6, 7, 4, 7, 8, 9, 4, 9, 10, 11, 4,
// ...
1211, 1216, 1215, 1230, 1229, 311, 322, 1231, 312};
float vlist[1626] = {
2.33102179f, 4.68985701f, -7.74118519f, -4.0108633f, -2.08138514f, 8.18039227f,
//...
1.70574367f, 2.03463793f, 9.00535202f, 2.94963598f, 0.0429565944f, 8.85224628f};
float nlist[3696] = {
-0.00219265698f, -0.443717808f, -0.896163881f, -0.112498537f, -0.405027777f, -0.907356858f,
//...
-0.316353977f, -0.846433043f, 0.428335458f, 0.514008343f, -0.00765316607f, 0.857751012f};
AtMatrix m;
AiM4Identity( m );
AtNode *n = AiNode( "polymesh" );
AiNodeSetByte(n, "visibility", 255);
AiNodeSetArray(n, "vlist", AiArrayConvert(1626, 1, AI_TYPE_FLOAT, vlist));
AiNodeSetArray(n, "nsides", AiArrayConvert(540, 1, AI_TYPE_BYTE, nsides));
AiNodeSetArray(n, "vidxs", AiArrayConvert(2160, 1, AI_TYPE_UINT, vidxs));
AiNodeSetArray(n, "nlist", AiArrayConvert(3696, 1, AI_TYPE_FLOAT, nlist));
AiNodeSetArray(n, "nidxs", AiArrayConvert(2160, 1, AI_TYPE_UINT, vidxs));
// AiNodeSetArray(n, "uvidxs", AiArrayConvert(384, 1, AI_TYPE_UINT, uvidxs));
// AiNodeSetArray(n, "uvlist", AiArrayConvert(270, 1, AI_TYPE_FLOAT, uvlist));
AiNodeSetMatrix(n, "matrix", m );
AiNodeSetStr(n, "name", "SISoccerBall");
return n;
};
// --------------------------------------------------------------------------------
// dso hook.
// --------------------------------------------------------------------------------
proc_loader
{
vtable->Init = init;
vtable->Cleanup = cleanup;
vtable->NumNodes = numNodes;
vtable->GetNode = getNode;
strcpy_s(vtable->version, AI_VERSION);
return 1;
}