Here is a typical RSL plugin function, which computes "a = b + c" for floating-point values.
RSLEXPORT int add(RslContext* rslContext, int argc, const RslArg** argv) { RslFloatIter a(argv[0]); RslFloatIter b(argv[1]); RslFloatIter c(argv[2]); int n = argv[0]->NumValues(); for (int i = 0; i < n; ++i) { *a = *b + *c; ++a; ++b; ++c; // Note: pre-incr is faster than post-incr. } return 0; }
An iterator can be used without regard to whether the argument data is uniform or varying: incrementing an iterator for a uniform argument has no effect. The number of iterations is typically determined by the number of values in the result argument (argv[0]->NumValues()), which might be one if all the arguments are uniform. Plugin functions that return values via output arguments must take the detail of all the arguments into account, however:
int n = RslArg::NumValues(argc, argv);
An alternative interface is available for RSL plugin functions that requires access to all the grid data (e.g. for block copies that might include data for inactive points). Here is an example:
RslArg* A = argv[0]; RslArg* B = argv[1]; RslArg* C = argv[2]; float *aData, *bData, *cData; int aStride, bStride, cStride; A->GetData(&aData, &aStride); B->GetData(&bData, &bStride); C->GetData(&cData, &cStride); unsigned int numPoints; const RslRunFlag* runFlags = rslContext->GetRunFlags(&numPoints); for(int i = 0; i < numPoints; ++i) { if (runFlags[i]) *aData = *bData + *cData; aData += aStride; bData += bStride; cData += cStride; }