Parsing Parameters

return to main index


Many of the RiXXX procedures installed by a RifPlugin have a list of arguments that conclude with a parameter list consisting of three items.
For example,

    AttributeV(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]);

    RtInt nvals is a count of the number of parameters,
    RtToken tokens[] is an array of the names of the parameters, and
    RtPointer params[] is an array of the values of the parameters.

For example, if this rib statement,

    Attribute "visibility" "int transmission" [0] "int specular" [0] "int diffuse" [0]

were "processed" by the Rif shown in listing 1 then,
    the value of nvals would be 3,
    the tokens array would be the strings, "int transmission", "int specular" and "int diffuse", and
    the params array would have integer values of 0, 0 and 0.

Param Datatypes

Of course, not all Attributes have integer parameter values. Consequently the "params" arg cannot be declared as,

    RtInt params[]

but is declared generically as

    RtPointer params[]

so that "params" can be an array of pointers that reference any datatype. The tricky part is determining the datatype of a specific token in the "tokens" array. Fortunately, the RifPlugin API has a function called RifGetDeclaration that neatly figures out token datatypes. Listing 1 provides an example of how this function, in the context of an Attribute rif, can be used. For more information on this topic refer to,
    Plug-in Rif Filters: Parsing Parameters

Listing 1 (ParamEcho.cpp)

#include <string>
#include <RixInterfaces.h>
#include "RifPlugin.h"
#include <rx.h>
class ParamEcho : public RifPlugin {
    virtual ~ParamEcho() { };
    virtual RifFilter &GetFilter() { return m_self; }
        RifFilter       m_self;      // reference to an instance of our class
        RixMessages        *m_msg;
        static RtVoid    attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]);
// Entry point required by PRMan
RifPlugin *RifPluginManufacture(int argc, char **argv) {
    return new ParamEcho();
// Constructor
ParamEcho::ParamEcho() {
    m_self.AttributeV = attribute;
    m_self.Filtering = RifFilter::k_Continue;
    RixContext    *rixContext = RxGetRixContext();
    m_msg = (RixMessages*) rixContext->GetRixInterface(k_RixMessages);
// Echo the text/data of each Attribute statement.     
RtVoid ParamEcho::attribute(RtToken name, RtInt nvals, RtToken tokens[], RtPointer params[]) {
    std::string message("Attribute ");
    message = message + "\"" + name + "\"";
    char      buff[256];
    RtFloat *fptr;
    for(int n = 0; n < nvals; n++) {
        message = message + " \"" + tokens[n] + "\" ";
        RifTokenType     tokType;
        RifTokenDetail     tokDetail;
        RtInt             arraylen;
        // Here is the nifty helper function - RifGetDeclaration()
        RtInt result = RifGetDeclaration(tokens[n], &tokType, &tokDetail, &arraylen);
        if(result == 0) {
            fptr = NULL;
            switch(tokType) {
                case k_RifFloat:     
                        sprintf(buff, "[%1.4f]", *(RtFloat*)params[n]); 
                case k_RifPoint:
                        fptr = (RtFloat*)params[n];
                case k_RifColor:
                        fptr = (RtFloat*)params[n];
                case k_RifVector:
                        fptr = (RtFloat*)params[n];
                case k_RifNormal:
                        fptr = (RtFloat*)params[n];
                case k_RifMatrix:
                        fptr = (RtFloat*)params[n];
                        sprintf(buff, "[%1.4f %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f\
                                        %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f]", 
                        (*fptr)++, (*fptr)++, (*fptr)++, (*fptr)++,
                        (*fptr)++, (*fptr)++, (*fptr)++, (*fptr)++,
                        (*fptr)++, (*fptr)++, (*fptr)++, (*fptr)++,
                        (*fptr)++, (*fptr)++, (*fptr)++, (*fptr));
                        fptr = NULL;
                case k_RifInteger:
                        sprintf(buff, "[%d]", *(RtInt*)params[n]); 
                case k_RifString:
                        sprintf(buff, "[\"%s\"]", *(RtToken*)params[n]); 
                        sprintf(buff, "[unhandled type]");
            if(fptr != NULL)
                sprintf(buff, "[%1.4f %1.4f %1.4f]", (*fptr)++, (*fptr)++, *fptr); 
            message += std::string(buff);
    // Pass through the attribute
    RiAttributeV(name, nvals, tokens, params);
    // Echo the Attribute params
    ParamEcho *self = static_cast<ParamEcho*>(RifGetCurrentPlugin());

© 2002- Malcolm Kesson. All rights reserved.