Here’s the table of contents for the API Reference
Writing an Arnold-based app: |
Core data structures: |
Writing plug-in extensions: |
Writing shaders:
|
Here’s the table of contents for the API Reference
Writing an Arnold-based app: |
Core data structures: |
Writing plug-in extensions: |
Writing shaders:
|
If you’re using the Arnold API to update ASS files (for example, to change paths), you need to load all the plugins (aka shaders) that are referenced by the ASS file. Otherwise, the unknown nodes are skipped on load, and therefore won’t be in any ASS file you write.
For example, if you set ARNOLD_PLUGIN_PATH to point to the locations of the MtoA shaders and any custom shaders you use, then you could do something like this:
from arnold import * import os AiBegin() AiMsgSetConsoleFlags(AI_LOG_ALL) AiLoadPlugins( os.getenv( 'ARNOLD_PLUGIN_PATH' ) ) AiASSLoad("original.1001.ass", AI_NODE_ALL) # # Do your edits here # AiASSWrite("edited.1001.ass", AI_NODE_ALL, False) AiEnd()
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; }