Basic DeepOps
=============

NUKE 6.3 introduces an API for accessing Deep Data.  This is similar to the regular Iop interace, but 
operating on Deep data rather than regular 2d Data.

There is an interface DeepOp, which is analagous to Iop.  Roughly the correspondences are 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 the ScanlineRender).  Typically Deep ops which operate only on deep
data would inherit from DeepOnlyOp, which brings in Op and DeepOp but this should only be used as a thing
to inherit from and particularly never expected as an input.

.. cpp:function:: 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.

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

  This function is like Iop::_request.  It is the most different, 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 will correspond to a call to request() on
  an Iop or deepRequest on a DeepOp that should be made.

  This has been done this way so that in future request state management could be extracted out
  of the DeepOps, nd put into some kind of deep manager.

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

  This function is like Iop::engine().  It is supposed to initialise and fill DeepOutputPlane with the
  data representing the box and channels.  Unlike engine() it has a return value - which should be 
  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:

  .. code-block:: c

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

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

  .. code-block:: c

    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);
    }

