Basic DeepOps

NUKE has an API for accessing Deep Data. This is similar to the regular Iop interface, but operating on Deep data rather than regular 2D Data.

There is an interface DeepOp, analogous to Iop, which roughly corresponds as follows:

2D type/field/method

Deep equivalent

class Iop

DeepOp

class IopInfo

DeepInfo

class Row

DeepPlane / DeepOutputPlane

class Pixel

DeepPixel / DeepOutPixel

Iop::info_

DeepOp::_deepInfo

Iop::_validate()

DeepOp::_validate

Iop::_request()

DeepOp::getDeepRequests

Iop::engine()

DeepOp::doDeepEngine()

It should be noted that DeepOp is not in fact an Op itself. This is to allow Iops to also implement the DeepOp interface (which is done by ScanlineRender). Typically, Deep Ops which operate only on deep data inherit from DeepOnlyOp, which brings in Op and DeepOp, but this should only be used as a thing to inherit from and never expected as an input.

DeepOp::_validate(bool for_real)

This is the same function as Iop::_validate. A hybrid implementation should set both Iop::info_ and _deepInfo.

_deepInfo is like iopInfo, but contains only the bounding box, the format, and the channels.

DeepOp::getDeepRequests(DD::Image::Box box, const DD::Image::ChannelSet &channels, int count, std::vector<RequestData> &reqData)

This function is like Iop::_request. This is the least similar Op because it should not recursively call deepRequest() on its inputs. Instead, it should build up RequestData objects and place them in reqData. Each RequestData object corresponds to a call to request() on an Iop or deepRequest on a DeepOp.

This was intentional so that, in future, request state management could be extracted from the DeepOps and placed into some kind of deep manager.

bool DeepOp::doDeepEngine(DD::Image::Box box, const DD::Image::ChannelSet &channels, DeepOutputPlane &plane)

This function is like Iop::engine(). It is supposed to initialize and fill DeepOutputPlane with the data representing the bounding box and channels. Unlike engine() it has a return value - which is true to indicate success, and false to indicate that the processing was aborted (either because aborted() returned true, or because deepEngine() on one of the inputs returned false).

A trivial implementation might be as follows:

plane = DeepOutputPlane(channels, box)
for (Box::iterator it = box.begin();
     it != box.end();
     it++) {
  plane.addHole();
}

This adds ‘holes’, or 0 samples, for each pixel in the plane. Each pixel can have 0 or more samples, which have all of the channels specified in channels. An implementation that adds 1 sample, with all values set to 1 would be:

plane = DeepOutputPlane(channels, box)
for (Box::iterator it = box.begin();
     it != box.end();
     it++) {
  DeepOutPixel pixel;
  foreach(z, channels)
    pixel.push_back(1);
  plane.addPixel(pixel);
}