Share

Create a simple operator - Arnold Developer Guide

Hello Sphere of Operators

Let's start by creating a simple Operator that creates one or more spheres of a given radius.

See Creating a Simple Plugin for further information about compiling the operators

create_spheres.cpp

#include <ai.h>
#include <sstream>

AI_OPERATOR_NODE_EXPORT_METHODS(OpMethods);


namespace ASTR {
   const AtString radius("radius");
   const AtString num_spheres("num_spheres");
   const AtString sphere("sphere");
};

node_parameters
{
    AiParameterUInt("num_spheres", 1);
    AiParameterFlt("radius", 0.5f);
}

operator_init
{
    return true;
}

operator_cleanup
{
    return true;
}

operator_cook
{
    // get the universe for this operator
    AtUniverse *universe = AiNodeGetUniverse(op);

    unsigned int num_spheres = AiNodeGetUInt(op, ASTR::num_spheres);
    float radius = AiNodeGetFlt(op, ASTR::radius);

    for (unsigned int i = 0; i < num_spheres; ++i)
    {
        std::stringstream node_name;
        node_name << "sphere" << i;

        AtNode* sphere = AiNode(universe, ASTR::sphere, AtString(node_name.str().c_str()));
        AiNodeSetFlt(sphere, ASTR::radius, radius);
    }

    return true;
}

operator_post_cook
{
    return true;
}

node_loader
{
    if (i > 0) return false;

    node->methods = OpMethods;
    node->output_type = AI_TYPE_NONE;
    node->name = AtString("create_spheres");
    node->node_type = AI_NODE_OPERATOR;
    strcpy(node->version, AI_VERSION);

    return true;
} 

create_spehers_example.ass

options
{
 AA_samples 9
 outputs "RGBA RGBA /out/arnold1:gaussian_filter /out/arnold1:jpeg"
 camera "camera"
 GI_diffuse_depth 1
 GI_specular_depth 1
 GI_diffuse_samples 3
 operator "make_spheres"
}

driver_jpeg
{
 name /out/arnold1:jpeg
 filename "simple.jpg"
}

gaussian_filter
{
 name /out/arnold1:gaussian_filter
}

persp_camera
{
    name camera
    matrix 1 1 MATRIX
     1 0 0 0
     0 1 0 0
     0 0 1 0
     0 0 6 1
    fov 70
}

create_spheres
{
    name make_spheres
    radius 1.0
    num_spheres 50
}

simple operator render

The transformation of the spheres depends on how the Operator is cooked. If it's cooked as part of a graph that's connected to the options node the spheres will be at the world origin. If however the Operator is cooked as part of a graph that's connected to a procedural the spheres will inherit the procedural's transform chain.

In the next example, we'll expand on this to create an Operator that also creates spheres, but it also creates a child instance of itself to dynamically keep on making spheres. We'll also explain the benefits of doing this.

Was this information helpful?