HDK
|
A Generator COP is one of the easiest COPs to create because you don't need to worry about fetching image data from inputs. This makes creating the COP a bit less complex than other nodes, since all that needs to be done is to cache any parameters and constant data for the cook, and then cook each tile.
This example of a COP generator creates scalable random white noise.
The generator uses the Image and Sequence tabs to control the basic sequence parameters, such as resolution and frame range. It is also maskable, with controls for this in the Mask tab. These features are provided by the parent class COP2_Generator and its parent, COP2_MaskOp.
TIL_Plane and TIL_Tile are needed for most COPs. UT_SysClone and UT_Math are used for this specific example, and the rest is used for general OP cooking (evaluating parms, installing the custom OP).
This next section sets up the parameters and local variables for the node. There are two parameters and no local variables. The parameters reside in a switcher. COP2_GENERATOR_SWITCHER is a macro which generates tabs for the Image and Sequence pages.
The OP_TemplatePair joins our short template list to the default Generator's template list, which contains all the normal generator parameters for the Image and Sequence tabs.
These methods are responsible for creating and destroying our COP. Normally, not much needs to be done in either the constructor or destructor. Generators usually derive from COP2_Generator, which provides the Image and Sequence tabs for manipulating all the sequence information. If this information is generated in a different way (file, device, etc), you may want to avoid these tabs and derive directly from COP2_MaskOp instead, which provides the Mask tab and masking capabilities. If this isn't desired, you can simply derive directly from COP2_Node.
This method determines all the sequence information based on the default parameters in the Image and Sequence tabs. If you didn't derive from COP2_Generator, your method may look more like:
This specifies the minimum parameters needed for a sequence - the frame rate, resolution and aspect ratio, and plane composition. This is a sample of how you would do this manually, though generally these wouldn't be constant values, but derived from a file or parameter.
The next method, newContextData(), creates a custom object derived from COP2_ContextData, which was declared in the header as:
In this instance, it just caches the two parameters so that they are not evaluated in the generateTiles() method, which is called multiple times in different threads. Parameter evaluation is not yet threadsafe. You can also cache precomputed data which would be the same for all tiles (filter kernels, geometry, etc).
Next up is generateTile(). The COP engine passes you a list of tiles to cook.
The first part of the generateTile() method grabs the context data object that newContextData() allocated earlier in the cook. This will be used to reference all the parameters evaluated earlier.
Next, the macro FOR_EACH_UNCOOKED_TILE() is used to loop over the tiles in the list. This macro specifically avoids tiles may already be cooked in the tilelist (which is possible as caching is done on a per-tile basis).
This examples allocates a small block of floats and writes the output to that, and then calls the convenience method COP2_Node::writeFPtoTile() to convert and copy the data to the tile, doing any data conversions required.
The data generated is simply some random numbers based on a seed, and scaled by a vector4 amplitude.
That's all the code needed to generate image data on a cook. Finally, the COP just needs to register itself in the COP table.
This COP has 0-2 inputs, an optional input for masking and an optional input for inline generation. COP2_Generator gives you the option to generate a new plane alongside existing planes in the input, or generate output for a plane and combine it with the input's plane in a simple way (add, multiply, max, etc).
The Mask input is used by COP2_Generator's parent class, COP2_MaskOp. It restricts output to the area defined by the mask.
If you do not derive from COP2_Generator, the input range should be 0-1 (if deriving from COP2_MaskOp) or 0-0 (COP2_Node). If you need to add a required input for your COP, then it may be more appropriate to make the COP a filter.