DD::Image::Iop Class Reference

Iop is the base class for all the image operators. More...

Inherits DD::Image::Op, and DD::Image::IopInfoOwner.

Inherited by DD::Image::Black, DD::Image::Blur, DD::Image::Convolve, DD::Image::DownRez, DD::Image::FileIop, DD::Image::HConvolve, DD::Image::Material, DD::Image::NoIop, DD::Image::NukeWrapper, DD::Image::PixelIop, DD::Image::PlanarIop, DD::Image::Render, DD::Image::SolidShader, DD::Image::Transform, DD::Image::UpRez, DD::Image::VConvolve, DD::Image::WireframeShader, and TextureSampler.

List of all members.

Classes

class  PixelCallbackI

Public Member Functions

void fetchPlane (ImagePlane &imagePlane)
virtual PlanarIgetPlanarI ()
virtual void force_validate (bool for_real=true)
IopImpl * pImpl ()
virtual ~Iop ()
bool test_input (int, Op *) const
Opdefault_input (int) const
Iopinput (int n) const
Iopinput (int n, int m) const
Iopinput0 () const
Iopinput1 () const
Cache * cache () const
bool cached () const
void cached (bool b)
virtual void in_channels (int, ChannelSet &) const
ChannelMask out_channels () const
int raw_channels_from () const
virtual bool pass_transform () const
void request (int x, int y, int r, int t, ChannelMask channels, int count)
void request (DD::Image::Box box, ChannelMask channels, int count)
void request (ChannelMask channels, int count)
void _copyState (Iop *input)
const BoxrequestedBox () const
ChannelMask requested_channels () const
ChannelMask multi_requested_channels () const
int requested_count () const
void get (int y, int x, int r, ChannelMask, Row &)
void at (int x, int y, Pixel &out)
float at (int x, int y, Channel)
ChannelSet peek (int x, int y, int r, int t, Pixel &out)
bool peek (int x, int y, int w, int h, ChannelMask pixelChannels, PixelCallbackI &callback)
virtual TransformgetTransform ()
virtual bool set_texturemap (ViewerContext *, bool gl=true)
virtual void unset_texturemap (ViewerContext *)
virtual bool shade_GL (ViewerContext *, GeoInfo &)
virtual void vertex_shader (VertexContext &)
virtual void fragment_shader (const VertexContext &, Pixel &out)
virtual void displacement_shader (const VertexContext &vtx, VArray &out)
virtual float displacement_bound () const
virtual void blending_shader (const Pixel &in, Pixel &out)
virtual void render_state (GeoInfoRenderState &state)
virtual void sample (float cx, float cy, float w, float h, Filter *, Pixel &out)
void sample (float cx, float cy, float w, float h, Pixel &out)
virtual void sample (const Vector2 &center, const Vector2 &dU, const Vector2 &dV, Filter *filter, Pixel &out)
void sample (const Vector2 &center, const Vector2 &dU, const Vector2 &dV, Pixel &out)
virtual float sample_shadowmap (Iop *map, bool map_is_one_over_z, float cx, float cy, float W, float H, Filter *filter, float Pz)
void build_handles (ViewerContext *)
virtual void inputsAttached ()
virtual void gpuEngine_useTextureTransform (bool useTransform)
 GPU support code.
virtual void gpuEngine_setupTextureTransform (const Matrix4 &postOpTransform)
virtual const char * gpuEngine_decl () const
virtual const char * gpuEngine_body () const
virtual Hash gpuEngine_shader_hash_at (double time)
virtual int gpuEngine_getNumRequiredTexUnits () const
virtual void gpuEngine_GL_begin (GPUContext *context)
virtual void gpuEngine_GL_end (GPUContext *context)
virtual IopviewerPassThrough () const

Static Public Member Functions

static Iopdefault_input (const OutputContext &)
static Opdefault_input (const Op *op)
static Channel channel (const char *name)
static const char * channel_name (Channel c)

Static Public Attributes

static bool sPreserveCaches

Protected Member Functions

 Iop (Node *node)
virtual void _invalidate ()
virtual void _validate (bool for_real)
virtual void _request (int x, int y, int r, int t, ChannelMask, int count)
virtual void _open ()
virtual void engine (int y, int x, int r, ChannelMask, Row &)=0
virtual void _close ()
virtual void doFetchPlane (ImagePlane &imagePlane)
bool inUse () const
void copy_info (int input)
void copy_info (int input, ChannelMask)
void copy_info ()
void clear_info ()
void merge_info (int input=0)
void merge_info (int input, ChannelMask)
void mergeFrameRange (int input)
void set_out_channels (ChannelMask m)
void set_out_channels (ChannelSetInit m)
void set_out_channels (Channel z)
void raw_channels_from (int n)
void set_out_channels (ChannelMask m, int n)
IopasIop (Op *op) const
template<class TileType >
void doSample (float cx, float cy, float w, float h, Filter *, Pixel &out)
template<class TileType >
float do_sample_shadowmap (Iop *map, bool map_is_one_over_z, float cx, float cy, float W, float H, Filter *filter, float Pz)

Protected Attributes

ChannelSet out_channels_
 protected so validate() can directly modify it
int raw_channels_from_

Friends

class Cache
class Interest
class GeneralTile
std::ostream & operator<< (std::ostream &, const Iop &)

Detailed Description

Iop is the base class for all the image operators.

The base class is not usable. Several pure virtual functions must be defined by a subclass to make an operator that works.


Constructor & Destructor Documentation

Iop::Iop ( Node *  node) [protected]

The constructor is protected so only subclasses can create the base class. The info() is filled in with default values for an empty image with no channels and format Format::None.

References DD::Image::Op::disallowNoTrees(), DD::Image::GeneralInfo::first_frame(), DD::Image::Info2D::full_size_format(), DD::Image::IopInfoOwner::info_, DD::Image::GeneralInfo::last_frame(), DD::Image::Mask_All, DD::Image::Format::None, out_channels_, DD::Image::Box::set(), and DD::Image::Op::slowness().

Iop::~Iop ( ) [virtual]

The destructor destroys the cache if there is one.


Member Function Documentation

void Iop::fetchPlane ( ImagePlane imagePlane)

Fetch an image plane. Ops that want an image plane should pass an empty image plane with the appropriate size and channels, and then this will be filled. This is a relatively low-level function. See PlanarI and PlanarIop for a larger structure built around this.

Note that the area must be a subset of the region of definition as specified in info().

This function may perform caching, and calls doFetchPlane() to fetch the actual.

References doFetchPlane(), DD::Image::IopInfoOwner::info(), DD::Image::Op::open(), DD::Image::Box::r(), DD::Image::Box::t(), DD::Image::Box::x(), and DD::Image::Box::y().

Referenced by DD::Image::NukeWrapper::doFetchPlane(), and DD::Image::GeneralTile::GeneralTile().

virtual PlanarI* DD::Image::Iop::getPlanarI ( ) [inline, virtual]

whether this Iop prefers planar or row-based access.

if it prefers planar access return a pointer to the interface to do planar size queries

Reimplemented in DD::Image::NukeWrapper, and DD::Image::Read.

Referenced by DD::Image::GeneralTile::GeneralTile(), and DD::Image::NukeWrapper::getPlanarI().

void Iop::force_validate ( bool  for_real = true) [virtual]

Acts as though valid() is off and does validate(). Thus you can be certain that _validate() is called.

This is re-implemnted from Op, and calls the base class version, as well as doing some extra Iop-specific work to propagate Info from input to output when the Op is in error.

Reimplemented from DD::Image::Op.

References copy_info(), and DD::Image::Op::input0().

void Iop::_validate ( bool  for_real) [protected, virtual]

The subclass-dependent portion of validate(). This is called by validate() after checking to see if it is needed.

This must set the contents of info_. Usually this is done by calling validate() on some input and then assigning that to info_, and then possibly modifying that information. You should use the copy_info(), merge_info(), and init_merge_info() methods if possible to set the info, or maybe Iop::Info::clear(), and then modify the results as needed:

         copy_info();
         \\ sample modifications of data, see plugin source code for more:
         info_.turn_on(Mask_RGB);
         info_.merge(*(info_.format));

An operator can also detect that it will not do anything to some channels and call set_out_channels(). If you set this to Mask_None then this will prevent _request(), _open() and engine() from being called. Besides being faster this often makes coding a plugin easier because you don't have to worry about the degenerate cases except in _validate():

         if (gain == 1) {
          set_out_channels(Mask_None);
         } else {
          set_out_channels(Mask_All);
         }

If something is wrong you can call error(). This will throw an exception and _validate() will not be called again until invalidate() is done.

for_real is true if Nuke is going to ask for image data from the operator. Otherwise it is only doing this to get the frame range, format or other information from the info_. If it is false you should try very hard to avoid anything expensive such as opening files and you must avoid producing errors that don't happen on every frame since that would prevent dissolves operators from fading out inputs during the time they produce errors.

For many operators the action is the same whether for_real is true or false. If you don't use any inputs and cannot avoid opening a file and want to avoid opening it twice, recursively call yourself like this. This is what Read operators do if they don't have the format and channels set yet:

 if (!for_real) {validate(true); return;} 

The default version merges the info from all the inputs and then turns on the channels in out_channels() if it is not Mask_All.

Reimplemented from DD::Image::Op.

Reimplemented in DD::Image::DrawIop, DD::Image::IllumShader, DD::Image::NoIop, DD::Image::NukeWrapper, DD::Image::Read, DD::Image::Render, DD::Image::RenderScene, DD::Image::Transform, DD::Image::UpRez, and DD::Image::Write.

References DD::Image::ChannelSet::all(), copy_info(), DD::Image::IopInfoOwner::info_, DD::Image::Op::inputs(), merge_info(), and out_channels_.

void Iop::_request ( int  x,
int  y,
int  r,
int  t,
ChannelMask  channels,
int  count 
) [protected, virtual]

The subclass-dependent portion of request(). This is called by request() if the new request is larger than what has already been requested this pass. _validate(true) will already have been called.

This should call request() on any inputs that are going to be used. Usually it will modify the arguments slightly:

 input0().request(x-1, y-1, r+1, t+1, channels, count); 

If you are going to randomly access the input, you should request it's entire bounding box:

 input0().request(channels, count); 

count indicates approximately how many times engine() will be called for each value of y. You should pass it unchanged or multiply it by a value greater or equal to 1 if your engine() asks for more than one input line. This is used to set up caching by knowing how many times a line will be needed. count may be zero to indicate that a previous request is being expanded with more area or more channels.

The default implementation requests the same area from each input. You will need to change this if your operator does random access, possibly to call the request() method that takes no area and thus accesses the format. It uses in_channels() to figure out what channels to ask for.

Reimplemented in DD::Image::DownRez, DD::Image::IllumShader, DD::Image::NoIop, DD::Image::NukeWrapper, DD::Image::PlanarIop, DD::Image::Render, DD::Image::RenderScene, DD::Image::UpRez, and DD::Image::Write.

References DD::Image::IopInfoOwner::channels(), in_channels(), input(), DD::Image::Op::inputs(), out_channels(), and request().

Referenced by request().

void Iop::_open ( ) [protected, virtual]

This used to do something but does not now. It is still recommended that any subclasses call this in their _open().

Reimplemented from DD::Image::Op.

Reimplemented in DD::Image::NukeWrapper, DD::Image::PlanarIop, and DD::Image::Read.

void Iop::engine ( int  y,
int  x,
int  r,
ChannelMask  channels,
Row row 
) [protected, pure virtual]

Calculate the image for this line and write the result to the row.

y, x, r, and channels have already been clipped to the requested() box and requested_channels() (which also means they are clipped to the box and channels set by _validate()).

This is not called if the intersection of channels() and out_channels() is Mask_None.

You must fill all the requested channels. If your operator does not modify a channel then you should copy it unchanged from input0().

The default version prints an error. Unless your operator sets out_channels to none always (this is true in some cases) you have to implement this.

Implemented in DD::Image::Material, DD::Image::NoIop, DD::Image::NukeWrapper, DD::Image::PixelIop, DD::Image::PlanarIop, DD::Image::Read, DD::Image::Render, and DD::Image::Write.

References DD::Image::Op::debug().

void Iop::_close ( ) [protected, virtual]

At one time this destroyed the cache. That's no good anymore as it throws away data when the automatic file close is done by nuke. Instead it only deletes it if valid is false.

Reimplemented from DD::Image::Op.

Reimplemented in DD::Image::NukeWrapper, and DD::Image::Read.

References DD::Image::Op::valid().

void Iop::doFetchPlane ( ImagePlane imagePlane) [protected, virtual]

Fetch an image plane. This is the function that Iops that should override. This can be called for any plane with any arbitrary bounds, channel. Either implement all of these (ImagePlane::copyIntersection helps here), or call the default implementation for a fallback.

By default this is not cached, so that multiple identical calls to fetchPlane will result in multiple identical calls to doFetchPlane. Use PlanarIop if you want a base class to manage caching of these for you.

no data from src, set to zero

Reimplemented in DD::Image::NukeWrapper, DD::Image::PlanarIop, and DD::Image::Read.

References DD::Image::Op::aborted(), DD::Image::ImagePlane::chanStride(), DD::Image::ChannelSet::contains(), DD::Image::Row::get(), DD::Image::Box::h(), DD::Image::IopInfoOwner::info(), DD::Image::Box::r(), DD::Image::ImagePlane::rowStride(), DD::Image::Box::t(), DD::Image::IopInfoOwner::w(), DD::Image::Box::w(), DD::Image::ImagePlane::writable(), DD::Image::Box::x(), and DD::Image::Box::y().

Referenced by fetchPlane().

void Iop::copy_info ( int  input) [protected]

Same as copy_info(n, Mask_All), indicating you are interested in all the channels the operator provides.

References DD::Image::IopInfoOwner::info(), DD::Image::IopInfoOwner::info_, input(), DD::Image::Op::real_valid(), and DD::Image::Op::validate().

void Iop::copy_info ( int  input,
ChannelMask  channels 
) [protected]

Most _validate() functions can call this to get the information from one of their inputs. They can then modify the info_ (such as changing the bounding box or adding or removing channels) or use merge_info() to get information from other inputs.

channels is what channels of this input you use. The bounding box and ydirection are only changed if these intersect the channels available from the input. Also if it is none it will avoid opening files or testing for errors on that input.

Equivalent code that you can put into _validate() is:

         input(n)->validate(channels && for_real);
         info_ = input0().info();
         channels = intersect(channels, info_.channels());
         info_.channels(channels);
         if (!channels) {
          info_.set(0,0,1,1);
          info_.ydirection_(0);
         }

References DD::Image::IopInfo::black_outside(), DD::Image::IopInfoOwner::channels(), DD::Image::IopInfoOwner::info(), DD::Image::IopInfoOwner::info_, input(), DD::Image::Op::real_valid(), DD::Image::Box::set(), DD::Image::Op::validate(), and DD::Image::IopInfo::ydirection().

void Iop::clear_info ( ) [protected]

If you call this, then the first merge_info() you call will instead do a copy_info(). This is useful for an operator that has to iterate through all its inputs and is not sure which ones it is using. Warning: the value in info_ is bad after this call; you must call copy_info(), merge_info(), or assign some new value to info_ before your _validate() function returns.

References DD::Image::IopInfoOwner::info_, and DD::Image::Box::set().

void Iop::merge_info ( int  input,
ChannelMask  channels 
) [protected]

Merge the info from input n into this info. This is for use by _validate() in operators that take several inputs.

This will call validate() on the input, passing true if for_real is on and channels in non-zero.

If the output of that input intersects channels it will merge those channels and the bounding box and ydirection in.

The formats are unchanged.

If you have called clear_info() this instead does copy_info(). This is for conveniece for writing a loop that merges a large number of inputs.

References DD::Image::IopInfo::accessPreference(), DD::Image::IopInfo::black_outside(), DD::Image::IopInfoOwner::channels(), copy_info(), DD::Image::IopInfoOwner::info(), DD::Image::IopInfoOwner::info_, input(), DD::Image::Box::merge(), DD::Image::Op::real_valid(), DD::Image::Op::validate(), DD::Image::Box::w(), and DD::Image::IopInfo::ydirection().

void Iop::mergeFrameRange ( int  input) [protected]

Union the current and this input's frame ranges (ignoring either one if they are "empty" which is indicated by the last frame being less or equal to the first). This is the normal action by Nuke operators when merging sequences of different frame ranges.

References DD::Image::IopInfoOwner::first_frame(), DD::Image::GeneralInfo::first_frame(), DD::Image::IopInfoOwner::info(), DD::Image::IopInfoOwner::info_, input(), DD::Image::IopInfoOwner::last_frame(), and DD::Image::GeneralInfo::last_frame().

template<class TileType >
void Iop::doSample ( float  cx,
float  cy,
float  w,
float  h,
Filter filter,
Pixel out 
) [protected]
template<class TileType >
float Iop::do_sample_shadowmap ( Iop map,
bool  map_is_one_over_z,
float  cx,
float  cy,
float  W,
float  H,
Filter filter,
float  Pz 
) [protected]
bool Iop::test_input ( int  n,
Op op 
) const [virtual]

By default Iops only allow other Iops to be hooked to the input. You can override this if you have an image operation that takes data other than images as input. Make sure you cast back after calling input0() or other things that assume the inputs are Iops.

Reimplemented from DD::Image::Op.

Reimplemented in DD::Image::NukeWrapper.

Referenced by DD::Image::NukeWrapper::test_input().

Op * Iop::default_input ( int  n) const [virtual]

Returns a Black operator with the format set to the Nuke user's choice for default format. This means that by default an Iop with a disconnected input gets a black image of the expected size.

If the library is used by a program other than Nuke this will return null! Most operators assume inputs are not null, so you must connect them yourself.

Reimplemented from DD::Image::Op.

Reimplemented in DD::Image::IllumShader, and DD::Image::NukeWrapper.

References DD::Image::Op::outputContext().

Referenced by DD::Image::Read::_validate(), DD::Image::NukeWrapper::default_input(), DD::Image::Write::execute(), and DD::Image::Op::getViewableModes().

Iop * Iop::default_input ( const OutputContext context) [static]

This static function returns the same op that default_input(int) returns. This is useful so that non-Iop subclasses can get the same Black iop, which is mostly useful for finding out the user's default format or frame range settings.

Op * DD::Image::Iop::default_input ( const Op op) [inline, static]

Returns default_input(op->outputContext()). Provided for back-compatibility.

References default_input(), and DD::Image::Op::outputContext().

Referenced by default_input().

Iop & DD::Image::Iop::input1 ( ) const [inline]

Fast inline method of getting input(1). This casts on the assumption that the input is another Iop. Also notice that this returns a reference rather than a pointer, this is for back compatibility.

Reimplemented from DD::Image::Op.

References DD::Image::Op::input1().

Referenced by DD::Image::IllumShader::_request(), DD::Image::IllumShader::_validate(), DD::Image::DrawIop::_validate(), and DD::Image::DrawIop::pixel_engine().

DD::Image::Cache DD::Image::Iop::cache ( ) const [inline]

Return a pointer to the cache object being used by the Iop, or null if there is not cache object. This object is created automatically by open() if cached() is true or if there are multiple requests for data, or by at() or Tile or Interest objects.

Calling invalidate() does not destroy the Cache object, but does destroy all the stored pixels. This is the majority of the memory used by a Cache, but the object itself is approximately the size of one row of pixels and should be destroyed if you really are done using the Iop.

The Cache object is destroyed and the pointer cleared when the Iop is destroyed, or when _close() is called.

Referenced by at(), get(), peek(), and DD::Image::Row::release().

bool DD::Image::Iop::cached ( ) const [inline]

Returns the last value sent to cached(bool).

Reimplemented from DD::Image::Op.

Referenced by get(), and request().

void DD::Image::Iop::cached ( bool  b) [inline]

If this is true then a cache is created by _open() when the first pixel is requested. The cache is modified so lines are never thrown away (?).

If you turn this off the old data will remain in the cache and may still be returned, but new data will not be added and lines in the cache may be thrown away when the memory is needed. To free it either call invalidate() or call close().

Reimplemented from DD::Image::Op.

void Iop::in_channels ( int  input,
ChannelSet mask 
) const [virtual]

Return the set of channels needed from input n to output the channels in mask. This is done by modifying mask in-place to the new value. This is only used by PixelIop and by the default versions of _request() currently, though it is recommended that an Iop implement it.

To make it easier to write, you can assume that at least one of the channels in out_channels() is set in mask.

The default version returns mask unchanged. This is only correct for operators where there is not cross-talk between channels. A typical case is where the red output depends on all three of red, green, and blue, and same for green and blue. In this case you would implement it like this:

         void MyIop::in_channels(int, ChannelSet& mask) const {
         mask += (Mask_RGB);
         }

If you completely replace a channel, you don't need it from the input, so turn it off in the mask. For instance if you write your own rgb channels, do this:

         void MyIop::in_channels(int, ChannelSet& mask) const {
         mask -= (Mask_RGB);
         }

Reimplemented in DD::Image::ColorLookup, and DD::Image::NukeWrapper.

Referenced by DD::Image::RenderScene::_request(), _request(), DD::Image::NukeWrapper::engine(), and DD::Image::NukeWrapper::in_channels().

ChannelMask DD::Image::Iop::out_channels ( ) const [inline]

This is the set of channels that the operator modifies, all other channels are assumed to be copied unchanged from the raw_channels_from() input. Nuke will skip calling engine() if the requested channels does not intersect this set. Note that it will call engine() with channels that are not in this set, as long as some channels are in it.

Subclasses use set_out_channels() to change this. They can either do it in the constructor, or in _validate().

By default this returns Mask_All.

Referenced by DD::Image::NukeWrapper::_open(), _request(), DD::Image::NukeWrapper::_validate(), at(), DD::Image::PixelIop::engine(), get(), DD::Image::PlanarI::getRequestedPlaneFromChannel(), DD::Image::Interest::inputIop(), peek(), and request().

bool Iop::pass_transform ( ) const [virtual]

Return true if it is okay to move a transformation that is before this operator to after it. This is true of color correctors or any other operator where pixels don't move and the calculation does not depend on the position of pixels. Nuke may use this to concatenate multiple TransformIop into a single one.

This must work without _validate() being called! It probably should return a constant true or false.

The base class returns false.

Reimplemented in DD::Image::NoIop.

void Iop::request ( int  x,
int  y,
int  r,
int  t,
ChannelMask  channels,
int  count 
)

Call this to indicate the area that will be requested from this Iop. This calls validate(), and then calls _request() which will usually recursively call request() on each input.

All calls to request() are unioned together and intersected with the info() produced by validate(). All subsequent calls to get pixels (by get(), Tile and Interest constructors, or by calling at()) are clamped to this area. Missing channels return zero, positions outside the box return the pixel from the nearest edge of the box.

Although usually you want the request box to cover everything you will ask for, an operator may limit the size to avoid causing huge amounts of data to be cached. For instance some transforms request extremely large areas but reduce them to smaller than a single pixel, limiting the sampled area to only the non-scaled part of the input image and replicating the edge pixels will not degrade the transformed image significantly and will use far less memory.

This is used to set up the automatic caching. The region is used to determine how much data to store in the cache. The count argument is used to indicate that engine() will be called more than once for a given y value. A count of N and calling request() N times have identical behavior. A count of zero indicates that a previous request() call is being expanded in area (zero acts like 1 if this is the first call). Caches are placed by analyizing the slowness() and resulting counts of all the Iops (the current algorithim is simple and just turns on the cache on all operators with a count greater than one).

Calling Op::forget_request() will make the next request() reset the accumulated area. You may also want to call cache_new_pass() to indicate that all caches can be reused even if the data in them is still good.

References _request(), DD::Image::Op::aborted(), cached(), DD::Image::IopInfoOwner::channels(), DD::Image::Memory::clipToCacheLimit(), DD::Image::Op::debug(), DD::Image::Op::error(), DD::Image::Box::h(), DD::Image::IopInfoOwner::info_, input(), MAX(), MIN(), out_channels(), DD::Image::Op::print_name(), DD::Image::IopInfoOwner::r(), DD::Image::Box::r(), DD::Image::Op::real_valid(), request(), DD::Image::Op::requested(), DD::Image::Box::set(), DD::Image::Op::setRequested(), DD::Image::IopInfoOwner::t(), DD::Image::Box::t(), DD::Image::Op::validate(), DD::Image::Box::w(), DD::Image::Op::warning(), DD::Image::IopInfoOwner::x(), DD::Image::Box::x(), DD::Image::IopInfoOwner::y(), and DD::Image::Box::y().

Referenced by _copyState(), DD::Image::Write::_request(), DD::Image::UpRez::_request(), DD::Image::RenderScene::_request(), DD::Image::Render::_request(), DD::Image::NukeWrapper::_request(), DD::Image::NoIop::_request(), _request(), DD::Image::IllumShader::_request(), DD::Image::DownRez::_request(), DD::Image::Scene::evaluate_lights(), request(), DD::Image::ToBuffer::to_buffer(), and DD::Image::Scene::validate().

void Iop::request ( ChannelMask  channels,
int  count 
)

Use this to request that you will be randomly-accessing the input image and don't really know the area needed yet.

The current version will request a rectangle of the size of the format, but it will be moved to contain the bounding box if possible. This seems to match what is expected from random access in most cases. If you know you need a larger area you can calculate it yourself and call the other version of request().

References DD::Image::Format::height(), DD::Image::IopInfoOwner::info_, DD::Image::Box::r(), DD::Image::IopInfoOwner::r(), DD::Image::Op::real_valid(), request(), DD::Image::Box::t(), DD::Image::IopInfoOwner::t(), DD::Image::Op::validate(), DD::Image::Format::width(), DD::Image::Box::x(), DD::Image::IopInfoOwner::x(), DD::Image::Box::y(), and DD::Image::IopInfoOwner::y().

void Iop::_copyState ( Iop input)
const Box & DD::Image::Iop::requestedBox ( ) const [inline]

The union of all the boxes passed to request(), intersected with the box from info(). This is the area that will be stored in a cache, also the engine() will never be called for data outside this box.

Referenced by DD::Image::GeneralTile::getRequestBox(), and DD::Image::Interest::Interest().

ChannelMask DD::Image::Iop::requested_channels ( ) const [inline]

The union of all channels passed to request() intersected with the channels reported in info(). These are the channels that will be stored in a cache.

Referenced by DD::Image::PlanarI::getRequestedPlaneFromChannel().

int DD::Image::Iop::requested_count ( ) const [inline]

The sum of all the count arguments passed to request().

void Iop::get ( int  y,
int  x,
int  r,
ChannelMask  channels,
Row row 
)

Fill the row with the output of the Iop. At least the range x through r of each of channels is set to the output of the operator.

WARNING: the other channels, and data outside x..r, may change!!! The implementation can change pointers to point at cached data, reuse the row to read input data, and the row may be reallocated to make it's space larger. Do not assume any data, or any pointers to data, is preserved or valid after calling this. THIS IS NOT A MERGE!!! If you wish to merge data you must use a second row and then copy the data yourself.

If possible, buffer pointers are changed to point at the cached data, so no copying is done. If this is not possible, writable() is called for each channel needed and the data is calculated and written to these locations (note that writable() will reuse any buffer already assigned there).

The region is clamped to the requested() box before being passed to the engine, and the pixels at the edges of this area are replicated to fill the rest of the region.

If aborted() is true this clears the row to zero and returns quickly.

References DD::Image::Op::aborted(), DD::Image::IopInfoOwner::black_outside(), cache(), cached(), DD::Image::IopInfoOwner::channels(), DD::Image::Op::Class(), DD::Image::ChannelSet::contains(), DD::Image::Op::create(), DD::Image::Row::erase(), DD::Image::IopInfoOwner::format(), get(), DD::Image::IopInfoOwner::info_, input(), input0(), DD::Image::Format::name(), DD::Image::Row::offset(), out_channels(), DD::Image::Op::print_name(), DD::Image::Box::r(), DD::Image::IopInfoOwner::r(), DD::Image::Row::range(), DD::Image::Row::release(), DD::Image::Op::slowness(), DD::Image::Box::t(), DD::Image::Row::writable(), DD::Image::IopInfoOwner::x(), DD::Image::Box::x(), DD::Image::IopInfoOwner::y(), and DD::Image::Box::y().

Referenced by DD::Image::Write::engine(), DD::Image::PixelIop::engine(), DD::Image::NukeWrapper::engine(), DD::Image::NoIop::engine(), DD::Image::Row::get(), get(), DD::Image::Write::inputnget(), and DD::Image::DrawIop::pixel_engine().

void Iop::at ( int  x,
int  y,
Pixel out 
)

Returns several channels of a pixel in the image. The channels to compute are specified in the Pixel object. Unrequested channels (including Chan_Black) are unchanged.

The x and y are clamped to the requested() area, and any channels not in requested_channels() will return zero.

It can be faster to create and reuse an Interest object for this, as that avoids the overhead of locking/unlocking the cache for each call.

It may be faster to use sample() as some operators, such as Transform, implement their own versions that back-translate the coordinates and call their input directly.

References DD::Image::Op::aborted(), at(), cache(), DD::Image::Box::clampx(), DD::Image::Box::clampy(), DD::Image::Op::create(), input(), out_channels(), DD::Image::IopInfoOwner::x(), and DD::Image::IopInfoOwner::y().

Referenced by at(), do_sample_shadowmap(), DD::Image::LightOp::get_shadowing(), and DD::Image::Transform::sample().

float Iop::at ( int  x,
int  y,
Channel  channel 
)

Return a single channel of a pixel in the image.

The x and y are clamped to the requested() area, and any channels not in requested_channels() will return zero.

This is the slowest method of getting data from the image, but it is easy to call and does not require any range checks. For faster methods use get() to read an entire row, or use an Interest() for random access.

References DD::Image::Op::aborted(), at(), cache(), channel(), DD::Image::Box::clampx(), DD::Image::Box::clampy(), DD::Image::Op::create(), input(), out_channels(), and DD::Image::IopInfoOwner::y().

ChannelSet Iop::peek ( int  x,
int  y,
int  r,
int  t,
Pixel out 
)

Return the average of any cached pixels found in the specified rectangle. This is used by the viewer color-sampling code. The passed array is indexed by channel number and filled in with the values from the image. Unrequested channels are not changed.

If the operator has been executed recently this will return the average of any pixels that were produced by the last execution. If it has not been executed recently then older pixel values may still be located in memory and the average of these are returned. If it was never executed or the cache memory has been freed or the requested box does not intersect the cache memory then the output value is set to zero and the corresponding bit in the return value is turned off.

The return value is channels with any channels that had no pixels found turned off.

References cache(), input(), out_channels(), and peek().

Referenced by peek().

bool Iop::peek ( int  x,
int  y,
int  w,
int  h,
ChannelMask  pixelChannels,
PixelCallbackI callback 
)

For every pixel found in the specified rectangle call the given interface's process function. Return true of at least one pixel was given to the callback.

This is used by the viewer color-sampling code for more-expensive image pixels analysis such as

  • min color
  • max color
  • median
  • mode

References cache(), input(), out_channels(), and peek().

bool Iop::set_texturemap ( ViewerContext ctx,
bool  gl = true 
) [virtual]

Set the OpenGL current 2D texture map to draw a reduced-resolution version of this image. Returns false if the texture map cannot be created or is not yet available, in which case you should draw your OpenGL preview some other way, such as with solid colors.

The first time this is called this will probably return false. However this will signal Nuke to produce the down-rez image needed by the texture map using parallel threads. When this image is done, Nuke will redraw the viewer, and your drawing code can call this and it will get the texture map.

If gl is false, this tests for the existence and triggers the generation of the texturemap, but does not do any OpenGL calls. This can be used to test if the texture will work or to trigger the generation of the texture before it is actually needed.

To allow arbitrary bounding boxes and the output of Transform to be texturemapped, this function may mess with the OpenGL texture matrix. Be sure to reset this and disable texture mapping by calling unset_texturemap(). To reproduce the treatment of edge pixels by Iop, this will set GL_CLAMP_TO_BORDER (GL_CLAMP on Windows, unfortunately).

If DDImage is not linked with Nuke, this will return false always.

Reimplemented in DD::Image::Transform.

Referenced by DD::Image::Transform::build_handles(), DD::Image::Render::build_handles(), DD::Image::Transform::draw_handle(), and DD::Image::Transform::set_texturemap().

void Iop::unset_texturemap ( ViewerContext ctx) [virtual]

Undo anything set_texturemap did. The default one turns off texturemapping and resets the texture matrix to the identity.

Reimplemented in DD::Image::IllumShader.

Referenced by DD::Image::Transform::draw_handle(), and DD::Image::IllumShader::unset_texturemap().

bool Iop::shade_GL ( ViewerContext ctx,
GeoInfo geo 
) [virtual]

Shade the provided geometry object using this Iop as a material. Return false if it cannot correctly draw this object in OpenGL, in which case a solid-shaded version will be drawn.

This function is usually only overridden by the Material subclass, but it is a method on Iop so that an Iop can be used as a shader to texture-map it's image on the object.

The default version does:

         if (set_texturemap(ctx)) {
          geo.draw_solid(ctx);
          unset_texturemap(ctx);
          return true;
         } else {
          return false;
         }
See also:
set_texturemap, vertex_shader, fragment_shader

Reimplemented in DD::Image::Black, DD::Image::IllumShader, and DD::Image::Material.

void Iop::vertex_shader ( VertexContext vtx) [virtual]

Modify the vertex of any 3D geometry that this image is being applied as a shader to. This can change channels such as uv and xyz to achieve special effects like point displacement, uv projection, normal warping, etc. Or it can add extra channels to interpret by the fragment_shader.

This function is usually only overridden by the Material subclass, but it is a method on Iop so that an Iop can be used as a shader to texture-map it's image on the object. The default version does nothing.

See also:
shade_GL, fragment_shader

Reimplemented in DD::Image::IllumShader, DD::Image::Material, and DD::Image::SolidShader.

References DD::Image::Box3::expand(), DD::Image::CameraOp::LENS_ORTHOGRAPHIC, DD::Image::Scene::lights, DD::Image::Matrix4::transform(), and DD::Image::VertexContext::vP.

Referenced by DD::Image::ParticlesSprite::tessellateSprite(), and DD::Image::IllumShader::vertex_shader().

void Iop::fragment_shader ( const VertexContext vtx,
Pixel out 
) [virtual]

Change the value of the out Pixel as though the result of the surface shading.

This function is usually only overridden by the Material subclass, but it is a method on Iop so that an Iop can be used as a shader to texture-map its image on the object. The default version takes the UV, if any, scales it to the format, and calls sample(). If any lights exist in the scene, a default diffuse shading is applied.

See also:
shade_GL, vertex_shader

Reimplemented in DD::Image::Black, DD::Image::Material, and DD::Image::SolidShader.

References DD::Image::VertexContext::blending_shader, DD::Image::VertexContext::sample(), and DD::Image::VertexContext::texture_sampling.

void Iop::displacement_shader ( const VertexContext vtx,
VArray out 
) [virtual]

Do the displacement...

References DD::Image::VertexContext::vP.

float Iop::displacement_bound ( ) const [virtual]
void Iop::blending_shader ( const Pixel in,
Pixel out 
) [virtual]

Perform the composition of the surface sample over the background pixel. This function is called for every sample from the back to the front sample.

The default version implement the pre-multiplied alpha compositing (Pixel::over).

void Iop::sample ( float  cx,
float  cy,
float  w,
float  h,
Filter filter,
Pixel out 
) [virtual]

Sample a rectangular area. Note that cx,cy is the center of the rectangle, not the corner.

Reimplemented in DD::Image::Transform.

Referenced by DD::Image::RenderScene::projection_matrix(), DD::Image::VertexContext::sample(), and DD::Image::Transform::sample().

void Iop::sample ( float  cx,
float  cy,
float  w,
float  h,
Pixel out 
)

Same except the filter argument is a default Cubic filter.

void Iop::sample ( const Vector2 center,
const Vector2 dU,
const Vector2 dV,
Filter filter,
Pixel out 
) [virtual]

Sample a parallelogram. It is centered on center and the length of the two axis are given by dU and dV. The channels requested by channels are put into out.

Note that the Transform subclass has its own implementation that skips any motion blur. This is so that the 3D renderer can add motionblur and it does not get doubled.

The default implementation turns the parallelogram into a rectangle of the same area and calls the rectangle sample() function.

Reimplemented in DD::Image::Transform.

void Iop::sample ( const Vector2 center,
const Vector2 dU,
const Vector2 dV,
Pixel out 
)

Same except the filter argument is a default Cubic filter.

Channel DD::Image::Iop::channel ( const char *  name) [inline, static]

Same as DD::Image::getChannel(), this method is provided for back-compatibility.

References DD::Image::getChannel().

Referenced by at(), DD::Image::Reader::channel(), and DD::Image::DrawIop::pixel_engine().

const char * DD::Image::Iop::channel_name ( Channel  c) [inline, static]

Same as DD::Image::getName(Channel), this method is provided for back-compatibility.

References DD::Image::getName().

Referenced by DD::Image::Reader::channel_name().

virtual void DD::Image::Iop::gpuEngine_useTextureTransform ( bool  useTransform) [inline, virtual]

GPU support code.

Interface to tell the op whether to transform texture coordinates if it happens to sample any textures in its fragment shader.

The base class implementation is empty, it's up to derived classes that might want to do this to provide an implementation appropriate to them (which may just mean setting some flag).

See also:
gpuEngine_setupTextureTransform
virtual void DD::Image::Iop::gpuEngine_setupTextureTransform ( const Matrix4 postOpTransform) [inline, virtual]

Interface for setting up the optional texture coordinate transform. This provides a matrix that's assumed to contain the concatenation of any transforms that exist in the op tree *after* this op.

The base class implementation is empty, it's up to derived classes that might want to use texture coordinate transforms to provide an appropriate implementation.

See also:
gpuEngine_useTextureTransform
const char * Iop::gpuEngine_decl ( ) const [virtual]

Return the declaration portion of the OpenGL implementation. Returning NULL is the same as empty string. When this string is used, the sequence "$$" is replaced by a prefix to de-clash the string against other instances of the same Op class (or instances of other classes that happen to use the same name for a uniform, etc).

The sequence $name$ is replaced with the value of the knob of that name (currently only single floating point values are supported, or $name.x$ for a single field of a multi-value knob).

const char * Iop::gpuEngine_body ( ) const [virtual]

Return the body portion of the OpenGL implementation. This is a modified version of GLSL. Returning NULL means the Op has no GPU implementation and has to be run on the main processor. When this string is used, the sequence "$$" is replaced by a prefix to de-clash the string against other instances of the same Op class (or instances of other classes that happen to use the same name for a uniform, etc).

The sequence $name$ is replaced with the value of the knob of that name (currently only single floating point values are supported, or $name.x$ for a single field of a multi-value knob).

There are also two custom variables: IN and OUT. IN is a sampler containing the data computed in the main processor. OUT is the cumulative result of all GPU operations and the effective output of the Op (gl_FragColor will be overwritten). An example is "OUT = OUT * $gain$;".

Hash Iop::gpuEngine_shader_hash_at ( double  time) [virtual]

Returns a hash dependent on the shader source code, for the specified time. Note that this is not necessarily a hash _of_ the source code, the guarantee is merely that it varies deterministically as the source code varies. In practice, the shader source may depend on some of the Op's knobs, so the hash may just be of those knob values, evaluated at the specified time, and the function will not in general need to generate/know the full source.

The default implementation just returns a default constructed Hash object, sub-classes should override this appropriately.

Ideally, for performance reasons, the source shouldn't be time or even knob dependent and knob values should be handled with GL uniforms. However, there are situations where that's impractical and may even harm render performance merely to cater for knobs that in practice are rarely animated. Hence this function's support for time dependence.

For an example override see the Grade plugin code in the NDK examples.

int Iop::gpuEngine_getNumRequiredTexUnits ( ) const [virtual]

This method returns the number of texture units that the iop requires for GPU processing. The base class version is zero; override if your op uses more. Note that not setting this value correctly can result in the GPU processing unexpectedly running out of texture units and causing rendering problems.

void Iop::gpuEngine_GL_begin ( GPUContext context) [virtual]

Called before rendering this node when the gpuEngine_body() will be used. This can be used to bind textures, etc. If an error occurs in this method, it can throw an exception, which will be caught by the GPU setup code.

void Iop::gpuEngine_GL_end ( GPUContext context) [virtual]

Called after rendering this node when the gpuEngine_body() will be used. This can be used to unbind textures, etc.

virtual Iop* DD::Image::Iop::viewerPassThrough ( ) const [inline, virtual]

override this to return input0() if you want your Iop to be disregarded when directly connected to a Viewer. The Viewer will follow the chain of Iops until it reaches one that returns NULL. For implementation by the DiskCache node etc.


Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  ,
const Iop  
) [friend]

Not implemented in the library but you can define it