Write the Cook Method
Declaring a New Operator
In order that your SOP can be found by Houdini, it must be added to
the existing operators. This is done through the newSopOperator(...)
method. This function simply creates a new OP_Operator type and adds
it to the incoming operator table. Let's look at an example as we
go through and describe the different parts of the operator.
void
newSopOperator(OP_OperatorTable *table)
{
table->addOperator(
new OP_Operator("star", // Internal name
"Star", // UI name
SOP_Star::myConstructor, // SOP constructor
SOP_Star::myTemplateList, // Parameters
0, // Min # of inputs
0, // Max # of inputs
SOP_Star::myVariables, // Local variables
OP_FLAG_GENERATOR) // generator/source
);
}
The OP_Operator has eight parts.
1. The Internal Name
This is used as the initial name of the SOP when it is first created.
i.e. the first star SOP we add will be named star1.
2. UI name
This will be the label of the SOP in the parameter dialog. It has no use
internally.
3. SOP Constructor
The method to construct the SOP.
4. Parameters
This is the list of the parameters used in the SOP.
5. Min # of Inputs
The minimum number of inputs for the SOP. If it is a generator there
are usually no inputs coming in. (However, there are cases like the box
and add SOPs where it is desirable to have inputs.) If it is a filter
type then this entry will be at least one.
6. Max # of Inputs
The maximum number of sources allowed for the SOP. This specifies how
many possible inputs the SOP can have at one time. i.e. the merge SOP
allows for 9999 total inputs.
7. Local Variables
This is a list of local variables that are used within the SOP. i.e.
you may want to declare $PT, or $NPT for the point number and the
total number of points in the SOP. If you have no local variables then
enter a 0 here.
8. Generator/Source Flag
If the SOP is to be a generator SOP (i.e. generates geometry) then
this flag must be set to OP_FLAG_GENERATOR. If you wish it to be a filter
then nothing needs to be entered as it is the default.
Defining the Parameters
Parameters are defined through a parameter list. You should read
Using Parameters for a complete
description of parameters before looking at the following example.
static PRM_Name divisionName("divs", "Star Divisions");
static PRM_Name negativeName("nradius", "Negative Radius");
static PRM_Default fiveDefault(5); // Default to 5 divisions
PRM_Template
SOP_Star::myTemplateList[] = {
PRM_Template(PRM_INT_J, 1, &divisionName, &fiveDefault),
PRM_Template(PRM_TOGGLE, 1, &negativeName),
PRM_Template(PRM_XYZ_J, 3, &PRMcenterName),
PRM_Template(PRM_ORD, 1, &PRMorientName, 0, &PRMplaneMenu),
PRM_Template()
};
This will produce four parameters. The first parameter is an integer value
with an animatable parameter (_J). Its name internally is divs. This
is specified by the first part of the divisionName. divs will also
be the name of the channel that is created. The UI name is Star Divisions
given be the second field of the divisionName. The default entry is
specified by the fourth entry which is 5.
The next parameter is a toggle field named nradius.
The third parameter actually is a vector of three. Its name is given
by PRMcenterName which indicates that it is a commonly defined name found
in PRM_Shared.h. The channel name prefix in this case is t.
Given it is a PRM_XYZ_J type and has a vector size greator than one
a suffix will be added to each. So that the three channels created would
be named tx, ty, and tz.
The final parameter is an ordinal type. Ordinal types are usually menu
types. It is very similar to the interger type except ordinals are not
animatable. Here the name is again taken from PRM_Shared.h. The
fifth entry PRMplaneMenu, specifies a menu. PRMplaneMenu is also
defined in PRM_Shared.h. From the header file it can be seen that
PRM_ChoiceList consists of the text entries XY, YZ, and ZX. A menu
will be created that consists of these entries. The channel value
will be stored as an integer from 0 to 2 depending on the menu item
selected.
Writing the Cook Method
The cook method basically comes in two flavours. Cooks that have
inputs and those that don't. All cooking involves evaluating the
parameters, processing the geometry and returning the status. If
the SOP has inputs then it is slightly different in that the
inputs must be locked through the lockInputs call. This ensures
that the incoming geometry is up to date and will not change over the
course of the cook. After the cooking is done and just before returning
be sure to call unlockInputs as not calling this will lead to
bad results.
Below are the two common examples of cooking SOPs.
Generator example:
OP_ERROR
SOP_Star::cookMySop(OP_Context &context)
{
float time;
time = context.myTime;
// evaluate parameters
tx = CENTERX(time);
ty = CENTERY(time);
tz = CENTERZ(time);
...
// check for errors
if (error() < UT_ERROR_ABORT)
{
// clear the geometry
gdp->clearAndDestroy();
// create new geometry through the gdp
gdp->...;
...
gdp->...;
}
return error();
}
Filter example:
OP_ERROR
SOP_Star::cookMySop(OP_Context &context)
{
float time;
time = context.myTime;
// make sure the inputs are up to date
if (lockInputs(context) >= UT_ERROR_ABORT) return error();
// evaluate parameters
tx = CENTERX(time);
ty = CENTERY(time);
tz = CENTERZ(time);
...
// check for errors
if (error() < UT_ERROR_ABORT)
{
// make a copy of the geometry
gdp->duplicateSource(which_source, time); or
gdp->duplicateChangedSource(which_source, time);
// modify the geometry through the gdp
gdp->...;
...
gdp->...;
}
// unlock the inputs
unlockInputs();
return error();
}
Please see the SOP_Node base
class for more information on the class and its methods.
Table of Contents
Operators |
Surface Operations |
Particle Operations |
Composite Operators |
Channel Operators
Material & Texture |
Objects |
Command and Expression |
Render Output |
Mantra Shaders |
Utility Classes |
Geometry Library |
Image Library |
Clip Library
Customizing UI |
Questions & Answers
Copyright © 2004 Side Effects Software Inc.
477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7