DD::Image::Op Class Referenceabstract

Base class of all the things that can be created by Nuke nodes. More...

Inherited by DD::Image::AxisOp, DD::Image::DeepOnlyOp, DD::Image::GeoOp, and DD::Image::Iop.


class  Description

Public Types

enum  HandlesMode { eNoHandles, eHandlesUncooked, eHandlesCooked, eHandlesMax }
enum  PrevalidateResult { eFinished, eCancelled, eAbandoned }
 This is a tribool return value. Do not extend.
enum  HandleType {
  eNone, eMouseLeftClick, eMouseRightClick, eMouseMove,
  eMouseDrag, eMouseRelease, eSelectionChanged, eSelectionChangeFinished,
  eHandleDragTranslate, eHandleDragRotate, eHandleDragScale, eHandleDragPivot,
enum  ViewableModes { eViewableMode2D, eViewableMode3D, eViewableMode3D_2DReference }
enum  GenerateType {
enum  NodeContext { eNodeGraph, eTimeline, eOpGraph }
enum  StatusFlags { StatusNone, StatusModal, StatusUseCallback }
enum  PopUpScheme {
  ePU_Never, ePU_Done, ePU_Once, ePU_Default,
 Pop-up schemes determine when pop-up messages are displayed for op errors. More...
enum  VersionComponents { eMajor, eMinor, ePoint, eRevision }
typedef std::pair< int, DD::Image::Op * > Output
 Combination of input number and pointer to Op.
typedef std::set< OutputOutputSet
 Set of all outputs from this Op.
typedef std::map< Hash, std::vector< unsigned int > > ItemSelectionList
typedef bool( EventCallback) (Op *op, EventContext eventCtx)
using VersionInfo = std::tuple< int, int, int, int >

Public Member Functions

PrevalidateResult preValidate (ViewerContext *ctx=nullptr, PreValidateContext *=nullptr)
OprootOp () const
bool preValidateAborted (int treeStartingVersion, PrevalidateResult &result) const
const OutputSetgetOutputs () const
 return all the outputs of this node
virtual void setInputsValid (bool nowValid)
 set whether the input ops are valid (are for the right context)
bool inputsValid () const
 return whether the input ops are valid (are for the right context)
virtual bool can_clone () const
 returns whether or not an op can be cloned in the dag
bool haveHash () const
 return true if the hash() value is meaningful and globally unique
virtual std::vector< DD::Image::OutputContextgetPrevVersionsWanted () const
virtual const MetaData::Bundle_fetchMetaData (const char *keyname)
const MetaData::BundlefetchMetaData (const char *keyname)
Node * node () const
DD::Image::NodeI * getNode () const
void node (Node *v)
OpfirstOp () const
void firstOp (Op *v)
Opparent () const
void parent (Op *lpOp)
virtual void detach ()
 node has been deleted in DAG
virtual void attach ()
 node has been created in DAG
virtual void pre_write_knobs ()
virtual void knobs (Knob_Callback)
int replace_knobs (Knob *afterthis, int n, void(*f)(void *, Knob_Callback), void *, const char *fileExt=nullptr)
int add_knobs (void(*f)(void *, Knob_Callback), void *, Knob_Callback)
void set_unlicensed ()
Knobknob (const char *name) const
Knobknob (int) const
bool pushed () const
bool panel_visible () const
bool node_disabled () const
bool node_selected () const
unsigned node_gl_color () const
void * field (const char *name)
void * field (const char *name, int &type)
void * set_field (const char *name, const void *source, int size)
void * get_field (const char *name, void *dest, int size)
void beginHandle (HandleType command, ViewerContext *ctx, EventCallback *cb, int index, float x=0, float y=0, float z=0, ViewerContext::Cursor cursor=ViewerContext::kNoCursor)
void endHandle (ViewerContext *ctx)
virtual int knob_changed (Knob *)
virtual int knob_change_finished (Knob *knob, bool changedByUser=true)
void addTime (OpTimer::Category category, long long microsecondsCPU, long long microsecondsWall, bool isTopLevel=true)
void getPerformanceInfo (OpTimer::Category category, OpTimer::PerformanceInfo &info) const
 return the amount of CPU time taken by this op
virtual bool inputs_clockwise () const
 whether unconnected inputs on the DAG should be arranged clockwise or anticlockwise (default)
virtual std::vector< int > input_order () const
virtual int inputArrows (int nodeInputs) const
bool script_command (const char *command, bool py=true, bool eval=true) const
bool script_expand (const char *str) const
HandlesMode anyHandles (ViewerContext *ctx)
virtual void build_handles (ViewerContext *)
void add_draw_handle (ViewerContext *)
virtual void draw_handle (ViewerContext *)
virtual void add_input_handle (int input, ViewerContext *)
void add_op_handle (ViewerContext *ctx)
void add_knob_handle (Knob *, ViewerContext *)
virtual int getViewableModes () const
virtual int optional_input () const
virtual int minimum_inputs () const
virtual int maximum_inputs () const
virtual bool test_input (int, Op *) const
int inputs () const
int node_inputs () const
Opnode_input (int, GenerateType=OUTPUT_OP) const
Opnode_input (int, GenerateType, const DD::Image::OutputContext *outputContext) const
Opinput_op (int n=0) const
virtual void inputs (int n)
Opinput (int) const
int inputNumber (int input, int offset) const
Opinput (int input, int offset) const
Opinput0 () const
 return the primary input More...
Opinput1 () const
 return the second input, if it exists More...
const std::vector< Op * > & getInputs () const
const std::vector< Op * > & getChildren () const
virtual void set_input (int i, Op *op, int input, int offset)
void set_input0 (Op *op)
void set_input (int i, Op *op)
void set_input (int i, Op &op)
void set_input (int input, int offset, Op *op)
const OutputContextoutputContext () const
virtual void setOutputContext (const OutputContext &c)
virtual void append (Hash &)
virtual float uses_input (int) const
virtual void build_splits ()
virtual int split_input (int) const
virtual const OutputContextinputContext (int n, int offset, OutputContext &) const
virtual const OutputContextinputUIContext (int n, OutputContext &) const
virtual Opdefault_input (int) const
const Hashhash () const
virtual bool frameTransformImplemented () const
virtual bool frameTransformDownstream (const OutputContext &context, unsigned int input, float inFrame, float &outFrame) const
virtual bool frameTransformUpstream (const OutputContext &context, unsigned int input, float outFrame, float &inFrame) const
virtual DopeItemFlags::Mask getDopeItemFlags () const
virtual bool shouldHideInDopeSheet (Knob *knob) const
virtual DD::Image::KnobgetDopeItemKnob () const
virtual ViewSet viewsProduced () const
virtual ViewSet viewsWantOn (int i) const
virtual ViewSet splitForViews () const
bool requested () const
void setRequested ()
void forgetRequestShallow ()
void forget_request ()
void forget_request (std::set< Op * > &forgotten)
virtual const char * node_shape () const
DD::Image::Hash curveHash () const
bool opCurrent () const
virtual unsigned node_color () const
virtual const char * node_help () const =0
virtual const char * input_label (int, char *) const
virtual std::string input_longlabel (int) const
void node_redraw ()
void print_name (std::ostream &o) const
NodeContext nodeContext () const
std::string node_name () const
void invalidateSameHash ()
bool invalidate ()
bool invalidate (const Hash &hash)
bool update (const Box *=nullptr)
void asapUpdate ()
void asapUpdate (const Box &box, int direction=0)
void validate (bool for_real=true)
virtual void force_validate (bool for_real=true)
void update_handles () const
bool valid () const
 Returns true if it has been validated - including if there was an error. More...
bool real_valid () const
 Returns true if it has been real-validated - including if there was an error. More...
bool inErrorState () const
bool inInvalidState () const
bool opened () const
void open ()
void unopen ()
bool running () const
void running (bool v)
bool not_closed () const
void close ()
void callCloseAfter (double seconds)
void copyState (Op *input)
bool cached () const
void cached (bool b)
virtual bool inUse () const
virtual Executableexecutable ()
void setKnobsToContext (const OutputContext &)
void gotoContext (const OutputContext &, bool update)
void progressFraction (double fraction, StatusFlags flags=StatusNone)
void progressFraction (int a, int b, StatusFlags flags=StatusNone)
void progressMessage (const char *fmt,...)
void progressModalMessage (const char *fmt,...)
void progressDismiss ()
int slowness () const
void slowness (int newval)
virtual bool firstEngineRendersWholeRequest () const
virtual bool updateUI (const OutputContext &context)
const Formatinput_format () const
const OutputContextuiContext () const
void error (const char *fmt,...)
void warning (const char *fmt,...)
void critical (const char *fmt,...)
void debug (const char *fmt,...)
void abort () const
 Abort all trees the op is in.
bool aborted () const
 True if one of the trees the op is in was aborted; ops should check this while processing and return quickly when true.
void cancel () const
 Cancel all trees the op is in. Make sure you also call abort() to stop processing.
bool cancelled () const
 True if one of the trees the op is in was cancelled (by user interaction)
bool addToTree (OpTree *lpTree)
 Returns true if the op was added to the tree, or false if its reference count increased.
bool removeFromTree (OpTree *lpTree)
 Returns false if the op was removed from the tree, or true if its reference count decreased.
bool isInTree (OpTree *lpTree) const
 Checks if an op is in a particular tree, for debugging purposes.
bool isInAnyTree () const
 Checks if an op is in any tree at all.
OpTreeHandlergetTreeHandler () const
 Returns the treeHandler for a given Op.
bool hasError () const
bool opOrChildHasError () const
const OpgetErroredOp () const
void setPopUpScheme (PopUpScheme lScheme)
PopUpScheme getPopUpScheme () const
bool arePopUpsEnabled ()
 Returns whether a pop-up should be enabled for the next message, modifying internal data when necessary.
OpMessageHandlergetMsgHandler ()
const OpMessageHandlergetMsgHandler () const
std::string getDebugInfo () const
 Returns a string of debug information about the op. For internal use.
std::string getDetailedDebugInfo () const
bool tryValidate (bool for_real=true)
virtual Iopiop ()
 Cast to an Iop. This is much cheaper and safer than using dynamic_cast.
virtual const Iopiop () const
virtual GeoOpgeoOp ()
 Cast to a GeoOp. This is much cheaper and safer than using dynamic_cast.
virtual const GeoOpgeoOp () const
virtual ParticleOpparticleOp ()
 Cast to a ParticleOp. This is much cheaper and safer than using dynamic_cast.
virtual const ParticleOpparticleOp () const
virtual DeepOnlyOpdeepOnlyOp ()
 Cast to a DeepOnlyOp. This is much cheaper and safer than using dynamic_cast.
virtual const DeepOnlyOpdeepOnlyOp () const
virtual std::string getLibraryName () const
 Return a label and version string to display library version info for the Node.
virtual VersionInfo getLibraryVersion () const
virtual OpHints opHints () const
 Return hints to control when and how this op will be evaluated by the top-down system.
virtual const char * Class () const =0
const std::string libraryDisplayName () const
virtual const char * displayName () const
virtual std::string docsPath () const
virtual bool onAction (const ViewerContext *c, const DD::Image::Flags f, void *d)
Opget (const Description *description)

Static Public Member Functions

static int treeVersion ()
 get the current tree version
static bool nukeBusy ()
 is nuke processing something on a parallel thread?
static Opcreate (Node *node, const char *name, Op *p_op)
static Opcreate (const char *name, Op *p_op)
static void resetTimers ()
 reset all the performance timers
static void setTimingEnabled (bool enabled)
 turn performance timing on or off
static bool isTimingEnabled ()
 return whether performance timing is on or not
static const char * script_result (bool py=false)
static void script_unlock ()
static void all_forget_request ()
static void new_request_pass ()
static double callPendingClose (double seconds)
static void clearPendingClose ()
static Operror_op ()
static const char * error_message ()
static void clearAbortAndError ()
 To be removed.
static void SetDefaultPopUpEnable (bool lEnable)
 This is used by Nuke to indicate when ops using the default pop-up scheme should show pop-ups. Not recommended for customisation.
static std::string getVersionInfoStr (const VersionInfo &versionInfo)
static const Descriptionfind_description (const char *name, const Op *op_)
static int message_f (char t, const char *,...)
static int message_vf (char t, const char *, va_list)
static void add_timeout (float t, TimeoutHandler, void *v=nullptr)
static void repeat_timeout (float t, TimeoutHandler, void *=nullptr)
static bool has_timeout (TimeoutHandler, void *=nullptr)
static void remove_timeout (TimeoutHandler, void *=nullptr)

Public Attributes

const MetaData::BundlemetaCache
Hash metaCacheHash

Static Public Attributes

static unsigned current_request_pass
static void(* node_redraw_cb )(const Op *)
static void(* print_name_cb )(std::ostream &, const Op *)
static void(* status_callback )(const Op *, float, float, const char *, StatusFlags)
static constexpr int kInvalidVersion
static constexpr VersionInfo kUnsetVersion

Protected Member Functions

 Op (Node *node)
 The constructor is protected so only subclasses can create the base class.
virtual void _invalidate ()
virtual void _validate (bool for_real)
virtual void _open ()
virtual void _close ()
Opcreate (Node *node, const char *name)
Opcreate (const char *name)
HandlesMode anyInputHandles (ViewerContext *)
 return if any of the inputs (recursively) wish to draw handles More...
HandlesMode anyKnobHandles (ViewerContext *)
 return if any of the knobs on this node wish to draw handles More...
void build_input_handles (ViewerContext *)
void build_knob_handles (ViewerContext *)
void disallowNoTrees ()
 Call this to tell the op that it should always have op trees for normal behaviour (for internal use)
virtual HandlesMode doAnyHandles (ViewerContext *ctx)
virtual PrevalidateResult doPreValidate (ViewerContext *ctx=nullptr, PreValidateContext *=nullptr)

Protected Attributes

bool _haveHash
 whether the _hash actually has been set by a call to invalidate(Hash) ever.


class EngineContext

Detailed Description

Base class of all the things that can be created by Nuke nodes.

Nuke will create these things, hook their inputs to other ones, manage animation and store animated values into these by calling the knobs() function, and delete these when the node is destroyed.

Nuke will also invisibly manage multiple copies hidden inside a single node, where each copy is at a different time. This allows a later operator to ask for several time samples and merge them together in order to get motion blur.

Member Typedef Documentation

typedef std::map<Hash, std::vector<unsigned int> > DD::Image::Op::ItemSelectionList

The following are utility structures for use in the handle callbacks ItemSelectionList is returned to the callback for eMouseDrag events. For each GeoInfo object which is part of the current selection, this maps the GeoSelection::geoID of the GeoInfo to a vector of indices of selected vertices for that object.

Member Enumeration Documentation

Enumeration for the use of doAnyHandles(). the values are defined non-consectively so that that eHandles | eHandlesCooked == eHandlesCooked


no handles are needed


handles are needed, but generate_tree does not necessarily need calling


handles are needed, and generate_tree needs to be called, to cook out the


This op can be viewed in 2D.


This op can be viewed in 3D.


This op should be viewed in 3D with a 2D wipe overlay.


Return op with no knobs stored or inputs built.


Return tree but maybe at a different OutputContext.


Same as ANY_CONTEXT but skip disabled ops.


Same as INPUT_OP, but avoid setting uiContext.


Returns op tree for right context. Skips disabled ops on inputs (but not main op)


Returns op tree for right context. Skips disabled ops.


Returns op tree for right context, with skipping, and replaces PostageStamp/TextureMap ops.


Don't try to make a tree, but try to set uiContext on the nodes as if we had.


part of the node graph ( Nuke )


part of a timeline effect ( Hiero )

part of an op graph (NukeEngine)

Flags to alter the behaviour of status_callback

Pop-up schemes determine when pop-up messages are displayed for op errors.


Don't ever display pop-ups for this op.


Previously only one pop-up was to display (ePU_Once), and it's now been shown.


Display only the next pop-up for this op.


Display pop-ups according to the Nuke default: while loading scripts or changing knobs.


Display every pop-up for this op.

Member Function Documentation

void Op::_invalidate ( )

Operator-specific part of invalidate(). It will be called only if valid() was on. Recommended that this not be used for anything, it is provided for back-compatibility only. Instead you should implement close() and have that delete cached data if valid() is false. The default version does nothing.

Reimplemented in DD::Image::NukeWrapper.

Referenced by invalidateSameHash().

void Op::_validate ( bool  for_real)
void Op::_open ( )

The Op-dependent portion of open(). This is called if it has not been called since the last invalidate(). For iops this is called just before the first call to engine(). It's purpose is to delay expensive setup until the very last moment. Usually it will open data files or calculate lookup tables. It can call error() to abort all the processing, if for instance your data files are missing.

All _open() calls are done inside a single locked mutex, so there are no multithreading issues even if several instances of a plugin, or several different plugins, try to update a shared data structure.

The default does nothing.

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

Referenced by open().

void Op::_close ( )

The subclass-dependent portion of close(). This will be called by close(). It will be called irregardless of valid state or whether you flagged an error during _open() or _validate().

For back-compatibility, Nuke calls this after 5.0 seconds of idle time. Future versions may not call this at all unless callCloseAfter() is done, so you should add callCloseAfter(5.0) to your plugins to retain compatibility.

Typically _close() will close files, destroy cached data, and call close() on internal operators. It should not destroy any data that it might have returned pointers to (i.e. metadata, cached images, etc) unless valid() is false. To make sure internal caches are destroyed, it should call both invalidate() and close() on any internal Op instances.

Despite the name, this is not the opposite of open(). open() is undone by invalidate(). This may be called multiple times after open() and may be called before open() is ever called.

The default implementation does nothing.

Reimplemented in DD::Image::Iop, DD::Image::Read, DD::Image::NukeWrapper, DD::Image::ReadGeo, and DD::Image::WriteGeo.

Referenced by close().

Op * Op::create ( Node *  node,
const char *  name 

Create a new instance of some Op by name. This is assumed to be an internal part of this Op and the new Op's parent() is set to this. This works by calling find_description() and if that succeeds it calles the constructor() function in the description.

An Op can use this to create any other operator, even one in a plugin, as part of itself. You should do this inside _validate() and not inside the constructor so that any errors can be reported correctly. If there is a problem finding a plugin or loading it this will call error() with an appropriate error message and return zero. You should quit in this case, perhaps setting some flags so that further calls to your object will not crash.

You will need to cast the result if you want to use it. For instance if it is an Iop you should use dynamic_cast<Iop*> on it. If this does not work (returning a zero) you should call error() with an appropriate message and give up.

The name passed in is not the necessarily the name that that the node has in the UI: instead it is the name returned by the Class() function in C++ and Python for the node. (For example, the regular Merge node's internal name is "Merge2", and "Merge" refers to the original Merge node, left in for compatibility.

If you have a header file or other description of the object you can store settings into it using methods from the header file. If you do not have the header file you can still use the field() method to put values into it.

References DD::Image::Op::Description::constructor(), error(), find_description(), and parent().

Op::HandlesMode Op::anyInputHandles ( ViewerContext ctx)

return if any of the inputs (recursively) wish to draw handles

Convenience function for doAnyHandles() to call.

Referenced by doAnyHandles().

Op::HandlesMode Op::anyKnobHandles ( ViewerContext ctx)

return if any of the knobs on this node wish to draw handles

Convenience function for doAnyHandles() to call. This will check if the user interface window is open. If so it will go through all the knobs, and if Knob::build_handle() returns true it returns true

References DD::Image::Knob::build_handle(), eHandlesUncooked, and knob().

Referenced by doAnyHandles().

void Op::build_input_handles ( ViewerContext ctx)

Convenience function for build_handles() to call. This will call add_input_handle() on each input to the operator.

References add_input_handle().

Referenced by DD::Image::Transform::build_handles(), DD::Image::AxisOp::build_handles(), build_handles(), and DD::Image::GeoOp::build_matrix_handles().

void Op::build_knob_handles ( ViewerContext ctx)
Op::HandlesMode Op::doAnyHandles ( ViewerContext ctx)

Function to be implemented by subclasses who implement build_handles. Should return eHandlesCooked or eHandlesUncooked if a call to build_handles might add handles to be drawn, or eNoHandles, if no handles need drawing. The default implementation of this returns the maximum of the values that anyInputHandles() or anyKnobHandles() return

Subclasses that call build_input_handles from build_handles() should make anyInputHandles contribute towards the result with operator| - similarly, subclasses which call build_knob_handles() should return a value from this if anyKnobHandles() returns a value.

Note that at the time that doAnyHandles has been called, the Op tree and inputs has not been generated, and knob values on this Op have not been stored. If the result of this needs to depend upon knob values, fetch the values out with knob("knobName")->get_value().

If this function returns cooked then it will (possibly expensively) generate an op tree, including storing the knob values, and then call build_handles upon that. If it returns uncooked then it can skip the op generation step, and will just call build_handles on an op, assuming that the op can use any arbitrary outputContext and does not need to have had its knobs cooked. (The uiContext() should be correct)

If in previous versions you returned 'true' from this function, you should return eHandlesCooked.

Reimplemented in DD::Image::RenderScene.

References anyInputHandles(), anyKnobHandles(), and eHandlesMax.

Referenced by DD::Image::RenderScene::doAnyHandles().

Op::PrevalidateResult Op::preValidate ( ViewerContext ctx = nullptr,
PreValidateContext pvc = nullptr 

preValidate step to perform any potentially expensive steps before validate(). This is cancellable, and will return eCancalled/eAbandoned if the user cancelled or abandoned it. (In the event of a cancellation a subsequent validate will still work, but will do the additional work).

References DD::Image::ViewerContext::connected(), and doPreValidate().

Referenced by doPreValidate().

Op * Op::rootOp ( ) const

return the root for this Op. IMPORTANT: this may return NULL depending of the state of this Op i.e. inside a set_field() call

Referenced by DD::Image::InternalOCIOOp::updateColorManagementSetting(), and DD::Image::InternalOCIOOp::updateOCIOKnobValues().

bool Op::preValidateAborted ( int  treeStartingVersion,
PrevalidateResult result 
) const

returns true if user has aborted or cancelled. leaves result in parameter, otherwise returns false.

References cancelled(), and treeVersion().

const MetaData::Bundle & Op::_fetchMetaData ( const char *  keyname)

Implement this to supply metadata. by default it will pass through to fetchMetaData on input(0). The reference should be to an internal object that should remain valid until the Op is invalidated: returning a reference to the return value of another Op's fetchMetaData is acceptable.

the key parameter will in future be used to allow only one piece of metadata to be calculated: presently nuke ignores it, and it is safe for plugins to ignore.

Reimplemented in DD::Image::Read.

References fetchMetaData(), and input().

Referenced by fetchMetaData().

const MetaData::Bundle & Op::fetchMetaData ( const char *  keyname)

Call this to fetch a metadata bundle containing the particular keyname, or NULL to fetch all available metadata. You may get back all available data even if you had specified a particular item.

References _fetchMetaData(), and hash().

Referenced by _fetchMetaData().

void DD::Image::Op::node ( Node *  v)

Sets the Nuke user interface node this operator belongs to. Nuke uses this to report errors. Warning: do not attempt to set both parent() and node(), they use the same memory location!

const Op * DD::Image::Op::parent ( ) const
void Op::knobs ( Knob_Callback  callback)

Define the "knobs" that will be presented in the control panel for the operator.

Normally you call callback once for each Knob you want on the panel. The file Knobs.h describes a number of type-safe wrapper functions that you should use instead of calling callback directly. This file also documents all the existing built-in types.

When knobs are being created callback takes an enumeration value that defines the type of knob being created, and the name, label, and arbitrary extra data to pass to the constructor, and a pointer to data that may (depending on the knob type) be used to get a default value.

When data is being stored callback ignores all the arguments except the pointer, this is then passed to the store() method of the knob that was created last time.

Use of only the enumerated types avoids the need to link with Nuke, thus allowing your image operator to be used with other programs that only use the DDImage libarary.

If desired a custom Knob may be created. In this case your operator will only work as a plugin to Nuke. This function must call the makeKnobs() function on the callback object and if true it should call the constructor for the custom knob. If false it should call callback, you can pass 0 for all the arguments except the pointer, which will be passed to the store() method of your Knob.

Reimplemented in DD::Image::Transform, DD::Image::NukeWrapper, DD::Image::DeepAccumPixelOp, DD::Image::IllumShader, DD::Image::NoIop, and DD::Image::SourceGeo.

Referenced by field(), and DD::Image::NukeWrapper::knobs().

int Op::replace_knobs ( Knob afterthis,
int  n,
void(*)(void *, Knob_Callback)  f,
void *  v,
const char *  fileExt = nullptr 

Change the set of knobs this node has, by deleting n knobs after the afterthis knob, then inserting new knobs produced by calling the function f. The return value is the number of knobs created by f, which you probably want to save and pass to the next call.

If n is zero or negative then this only creates knobs. If f is null then this only destroys knobs.

Currently the old knobs are completly destroyed. Future versions may try to match up the new knobs with the old ones and preserve the values and widgets.

Your knobs() function should also call f by using add_knobs(). You also need to pick a knob that controls the rest of the knobs and set the Knob::KNOB_CHANGED_ALWAYS flag on it so that you can change the set of knobs on any changes.

Referenced by DD::Image::FileOp::add_extra_knobs(), and DD::Image::FileOp::replace_knobs().

int Op::add_knobs ( void(*)(void *, Knob_Callback)  f,
void *  v,
Knob_Callback  cb 

Call f() and return how many knobs it created. This should be called inside a knobs() function to create the original set of knobs that will be changed by replace_knobs(), and to store the values into the current set of knobs. This will return zero if the callback is not creating knobs.

Referenced by DD::Image::FileOp::extra_knobs(), and DD::Image::FileOp::replaceable_knobs().

void Op::set_unlicensed ( )

Disable all knobs on the node that this op belongs to, other than the ones on the Node tab. This can be called at the end of your knobs() method to ensure that all knobs are disabled (for example, if a license check is failed).

Knob * Op::knob ( const char *  name) const

Find and return a Knob on the control panel for the node that controls this Op. Returns null if there is no knob with the given name.

If knobs() has not been called, you may not get knobs you think should exist. This will happen if this Op was created directly by another Op. If such a controlling op wants to change the stored data, it should use the field() method to get the pointer to where to store it, rather than trying to change the value of a knob.

If DDImage is not being used by Nuke this will return null. However field() will still work.

Referenced by DD::Image::ReadGeo::_validate(), DD::Image::Write::_validate(), anyKnobHandles(), DD::Image::Read::append(), DD::Image::ParticleOp::appendSimulationCurve(), DD::Image::RenderScene::build_handles(), build_knob_handles(), DD::Image::AxisOp::enableAxisKnobs(), DD::Image::AxisOp::enableKnobs(), DD::Image::Executable::frameRangeKnobsChanged(), DD::Image::AxisOp::isGuiInteractive(), DD::Image::Write::isWrite(), DD::Image::DrawIop::knob_changed(), DD::Image::GeoOp::knob_changed(), DD::Image::NukeWrapper::knob_changed(), DD::Image::LookAt::knobChanged(), DD::Image::InternalOCIOOp::nodePanelShown(), DD::Image::RecursiveUseFilesystem(), DD::Image::Write::set_file_type(), DD::Image::Executable::skipForContext(), DD::Image::InternalOCIOOp::updateColorManagementSetting(), and DD::Image::InternalOCIOOp::updateOCIOKnobValues().

Knob * Op::knob ( int  n) const

Find a knob by index number. If the index number is larger than the number of knobs then null is returned. By starting at zero and incrementing until this returns null you will get every Knob known about.

bool Op::pushed ( ) const

Returns true if any knob is Knob::pushed(), meaning the user is holding it down with the mouse. Currently only implemented for the handles in the viewer, but the intention is to make it work for widgets in the control panels, too. This is used by Transform to enable the texture map preview.

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

bool Op::panel_visible ( ) const

Returns true if the control panel for the node is open. This can be used to turn the visiblility of handles on/off.

Referenced by DD::Image::Transform::build_handles(), DD::Image::Render::build_handles(), and DD::Image::Write::updateDefaultLUT().

bool Op::node_selected ( ) const
unsigned Op::node_gl_color ( ) const

Returns the color selected by the user to draw things in the viewer. The return value is of the form 0xrrggbb00.

Referenced by DD::Image::GeoOp::get_geometry(), and DD::Image::GeoOp::update_geometry_hashes().

void * Op::field ( const char *  name)

Locate the memory that will be stored into by the knob with the given name and return a pointer to it. Returns null if not found.

This works by calling knobs() with a special callback function that examines each callback for the correct name. This is not particularily fast so you may want to store the retuned pointer somewhere.

This will work even if knob() does not work. It will work for internal Op instances made with create() or by direct construction that are not visible to the user and have no knobs.

Referenced by get_field(), and set_field().

void * Op::field ( const char *  name,
int &  type 

Same as the other field(), but if the field is found then type is set to an enumeration (defined in Knobs.h) for the type of knob. This can be used to do type-safety tests of the storage location.

References knobs().

void * Op::set_field ( const char *  name,
const void *  source,
int  size 

Copy data to a field in an extremely type unsafe manner. Basically this does memcpy(field(name),data,size). Make sure you know what you are doing. Returns the field or null if the field was not found.

References field().

void * Op::get_field ( const char *  name,
void *  dest,
int  size 

Copy data from a field in an extremely type unsafe manner. Basically this does memcpy(data,field(name),size). Make sure you know what you are doing. Returns the field or null if the field was not found.

References field().

void Op::beginHandle ( HandleType  command,
ViewerContext ctx,
EventCallback *  cb,
int  index,
float  x = 0,
float  y = 0,
float  z = 0,
ViewerContext::Cursor  cursor = ViewerContext::kNoCursor 

Callback handling. Used to register callbacks to receive Viewer events listed in the HandleType callback. The op must implement an add_draw_handle call from it's build_handles to ensure that draw_handle gets called. The op can then register callbacks from within it's draw_handle to receive these events.

int Op::knob_changed ( Knob )

Whenever the user moves a Knob this is called with a pointer to the Knob, on one of the Ops controlled by that Knob. The purpose is to automatically enable/disable or set the values of other knobs.

Do not assume this is called on all instances of your Op! It will not be in cases of clones or multiple frame numbers in Nuke. So storing results in this call is wrong! To get values out of knobs you must either rely on them being stored and validate() being called, or you must ask for them using knob(name)->value().

You must return non-zero if you do anything. Returning zero indicates that there is no need to call this on the same knob again. Base class returns zero always.

Reimplemented in DD::Image::ReadGeo, DD::Image::NukeWrapper, DD::Image::GeoOp, and DD::Image::DrawIop.

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

void Op::addTime ( OpTimer::Category  category,
long long  microsecondsCPU,
long long  microsecondsWall,
bool  isTopLevel = true 

add the amount of time /microseconds/ to the debug info. Avoid doing this manually, try to use the OpTimer class instead.

References addTime(), and parent().

Referenced by addTime().

int Op::inputArrows ( int  nodeInputs) const

overriden by Ops to specify the number of input arrows to display on the DAG the op has not been stored/generated. nodeInputs is how many inputs are connected to the node right now (or rather, the index of the first unconnected input). Returning -1 (which the default implementation always does) indicates that the DAG should use its default behaviour.

bool Op::script_command ( const char *  command,
bool  py = true,
bool  eval = true 
) const

Execute the string in Nuke's scripting language. Returns true on success, false if there is an error. The resulting output (either text or an error message) is in script_result(). You must call script_unlock() after you are done looking at the result, if you want to keep it around you should copy it to your own memory.

References node().

bool Op::script_expand ( const char *  str) const

"expand" the string in Nuke's scripting language. Returns true on success, false if there is an error. The resulting output (either the expanded text or an error message) is in script_result(). You must call script_unlock() after you are done looking at the result, if you want to keep it around you should copy it to your own memory.

The current version replaces backslash sequences, executes "[command]" and inserts the result, and replaces $variable with global tcl variables. It also will produce strange results if the DDString.has mismatched quotes or curly braces in it.

If the string does not contain any special characters then result is set directly to it. Be aware of this if you attempt to delete string.

This is very similar to script_command("return string") except it avoids some quoting problems and is much faster in the common case where there are no commands.

References node().

const char * Op::script_result ( bool  py = false)

The result of the most recent script_command() or script_expand(). For multithreading this buffer is protected by a recursive lock that is set by calling script_command() or script_expand(). You must call script_unlock() to release the lock.

void Op::script_unlock ( )

Allow the memory for script_result() to the most recent script_command() or script_expand() to be reused. You must call this exactly once for every call to script_command() or script_expand()!

void Op::build_handles ( ViewerContext ctx)

Construct a list of callbacks to draw handles for this Op. Because handles are drawn much more often than they are changed a great deal of time is saved by searching and building a list of the functions to call.

The default implementation recursively calls all the input ops (with build_input_handles()) and then calls all the knobs (with build_knob_handles()).

If the op wants to draw a custom GL interface such as outlines or even texture maps, it must call ViewerContext::add_draw_handle() with pointers to routines to be executed to draw the OpenGL. The convenience function Op::add_draw_handle() will cause the virtual function draw_handle() to be called for this.

The op can also mess with the transformation in the context, switch the viewer between 2D and 3D, and do other modifications to the OpenGl state. Look at Transform, AxisOp and DrawIop for different ways of implementing this.

Reimplemented in DD::Image::Render, DD::Image::NukeWrapper, DD::Image::GeoOp, DD::Image::AxisOp, DD::Image::Transform, DD::Image::RenderScene, and DD::Image::TransformGeo.

References build_input_handles(), and build_knob_handles().

void Op::add_draw_handle ( ViewerContext ctx)
void Op::draw_handle ( ViewerContext ctx)

Default single method for drawing handles. Simple operators can override this and override build_handles() to call add_op_handle() and then the base class version of build_handles().

Reimplemented in DD::Image::NukeWrapper, DD::Image::LightOp, DD::Image::AxisOp, DD::Image::Transform, DD::Image::DrawIop, DD::Image::CameraOp, and DD::Image::ComplexLightOp.

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

void Op::add_input_handle ( int  input,
ViewerContext ctx 

Call build_handles() on an input to this op. The input numbers are the user-visible numbers (not the result of split_inputs().

This is better than calling build_handles() on the input directly, as it checks to see if the operator was visited already (not doing this can make it exponentially slow when there are many splits and joins in a script), and it saves and restores parts of the ctx like the transform so they can be changed by the operator, and it skips added operators like PostageStamp that should not be visible to the user.

Special values for input: -1 means do this op, -2 means do each inputs where uses_input() is non-zero.

Reimplemented in DD::Image::ParticleOp.

Referenced by DD::Image::ParticleOp::add_input_handle(), DD::Image::TransformGeo::build_handles(), build_input_handles(), and DD::Image::GeoOp::build_matrix_handles().

void Op::add_knob_handle ( Knob knob,
ViewerContext ctx 

Same as knob->add_draw_handle(ctx). This is for back-compatibility only.

References DD::Image::Knob::add_draw_handle().

int Op::getViewableModes ( ) const

Return a bitmask of the suggested viewable modes supported for this op.

The return value should a bitmask of or'ed together values from the ViewableModes enum.

The Nuke viewer will automatically switch to 3D or 2D modes when connected to an op that is only vieweable in a single mode.

The default implementation does the following:

returns eViewableMode3D for ops that are not Iops or convertable to Iops. returns eViewableMode2D for Iops or ops that can be convertible to Iops, and if all their inputs are the same type as the op. returns ( eViewableMode2D | eViewableMode3D ) for Iops or ops that can be convertible to Iops if they have mixed inputs

References DD::Image::Iop::default_input(), eViewableMode2D, eViewableMode3D, inputs(), outputContext(), and test_input().

int Op::optional_input ( ) const

Index of the first "optional" input. The inputs between this number and minimum_inputs() are displayed differently in Nuke to indicate that it is ok for them to not be connected. Used by the mask inputs. The default version returns minimum_inputs(), which means there are no optional inputs.

Reimplemented in DD::Image::NukeWrapper.

References minimum_inputs().

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

int Op::minimum_inputs ( ) const

The minimum number of input connections the operator can have. Default is inputs().

Reimplemented in DD::Image::NukeWrapper.

References inputs().

Referenced by DD::Image::NukeWrapper::NukeWrapper(), and optional_input().

int Op::maximum_inputs ( ) const

The maximum number of input connections the operator can have. There may be more inputs() if split_input() is used. The default return value is inputs().

Reimplemented in DD::Image::NukeWrapper.

References inputs().

Referenced by input_label(), and DD::Image::NukeWrapper::maximum_inputs().

bool Op::test_input ( int  n,
Op op 
) const

This virtual function lets an operator decide what kinds of things to connect to the input. It can use any test wanted, but usually uses RTTI dynamic_cast<class*> to see if the Op is the correct subclass. If this returns false, then Nuke will use default_input() to generate the op that will be connected to this input.

If you implement split_input() n is the user-visible input number, but set_input() will be called with the split input number.

The default version returns false, so you can't hook anything up.

Reimplemented in DD::Image::Iop, DD::Image::NukeWrapper, DD::Image::GeoOp, DD::Image::AxisOp, DD::Image::TransformGeo, and DD::Image::DeepFilterOp.

Referenced by getViewableModes().

int Op::node_inputs ( ) const

Current number of inputs that the user sees in the Nuke DAG. This may be different than inputs() if you implement split_input().

Referenced by DD::Image::ParticleOp::appendSimulationCurve().

Op * Op::node_input ( int  i,
Op::GenerateType  type = OUTPUT_OP 
) const

Return an op tree that could be connected to input n. This allows you to peek at your input ops before validate() is called, such as in knobs() or in the constructor. Or you can use this to peek at an input after uses_input() returns zero or split_input() returns zero or negative.

n is the user-visible input number. If you implement split_input() this may be different than input(n), but it is the same as input(n,0).

type determines what exactly is in the returned op.

  • Op::OUTPUT_OP returns an Op that you can call Class() on but not much else. Knob values have not been stored in it and no inputs are hooked up.
  • Op::ANY_CONTEXT will return an op created for this version of the tree but it may return it set to a different OutputContext. This lets you call almost anything but you cannot depend on any animated values being correct.
  • Op::INPUT_OP is like ANY_CONTEXT but skips disabled nodes so it returns the actual op that will be used to create data. Used by code that wants to peek at the output data, such as the format or frame range, but does not require the exact correct frame number or view.
  • Op::EXECUTABLE forces the OutputContext to be a certain value. Don't use this as I have not decided what this certain value is yet (may be uiContext(), outputContext(), or inputContext()...)
  • Op::EXECUTABLE_INPUT both forces the OutputContext and skips disabled nodes, and also inserts hidden ops used to generate Postage stamps and texture maps. This is as close as possible to the actual Op that will be connected to this input.

If the input is not connected, OUTPUT_OP will return NULL, since this is commonly used to check if an input is connected. Note that if default_input(n) returns NULL, you cannot distinguish a disconnected input from an input connected to a Switch or other non-op node that is itself disconnected.

All other values for type return default_input(n) if the input is not connected.

Except for type of OUTPUT_OP, this is slow, and if the context it uses is wrong, it will cause extra instances of the entire Op tree to be generated, which can be very wasteful depending on the Op.

See also
node_inputs(), DD::Image::Execute

Referenced by DD::Image::RenderScene::build_handles(), DD::Image::Write::execute(), DD::Image::Write::isWrite(), DD::Image::DrawIop::knob_changed(), and DD::Image::NukeWrapper::knob_changed().

Op * DD::Image::Op::input_op ( int  n = 0) const

Same as node_input(n, INPUT_OP), this is provided for back-compatibility

void Op::inputs ( int  n)

Change the number returned by inputs(). Actually resizes array. New entries are NULL; old ones have removeOutput called on them if set.

References input(), and set_input().

int Op::inputNumber ( int  input,
int  offset 
) const

Calculate the "flat" input number from the user-visible input number and an index into the values returned by split_input(). This is the same as n+offset of you do not implement split_input(). offset is assumed to be less than abs(split_input(n)).

References split_input().

Referenced by DD::Image::NukeWrapper::_validate(), input(), and set_input().

Op * Op::input ( int  input,
int  offset 
) const

Same as input(inputNumber(n, offset));

References input(), and inputNumber().

Op * DD::Image::Op::input0 ( ) const
void Op::input1 ( ) const

return the second input, if it exists

Fast inline method of getting input(1) if it is not null. Warning: this may crash if input(1) is null.

Fast inline method of setting input(1).

Referenced by DD::Image::Iop::input1().

const std::vector<Op*>& DD::Image::Op::getInputs ( ) const

Returns a reference to a vector of all inputs, including input0 and other_inputs. Note that this may contain null pointers if some in between inputs are disconnected.

Referenced by DD::Image::Write::execute().

const std::vector<Op*>& DD::Image::Op::getChildren ( ) const

Returns a reference to a vector of all child ops. Avoid using this; it is only really public for op tree traversal.

void Op::set_input ( int  i,
Op op,
int  input,
int  offset 

Set input(n). This does not change inputs(), even if n is greater.

This is a virtual function so that subclasses can set the input pointers for child operators. The arguments to inputNumber() are also provided to assist with this. Make sure that any derived classes still call the parent class version though.

Reimplemented in DD::Image::NukeWrapper.

References DD::Image::OpTreeHandler::addOpToTrees(), input(), and DD::Image::OpTreeHandler::removeOpFromTrees().

Referenced by DD::Image::Write::execute(), inputs(), DD::Image::NukeWrapper::set_input(), and set_input().

void DD::Image::Op::set_input0 ( Op i)

Fast inline method of setting input(0).

void Op::set_input ( int  input,
int  offset,
Op op 

Same as set_input(inputNumber(n, offset), op, n, offset);

References inputNumber(), and set_input().

void Op::setOutputContext ( const OutputContext c)

Change what is in outputContext(). Nuke calls this for you. Subclasses can override this, but they must call the base class with exactly the same context. This method is a convenient place to do calculations that are needed before any of the following methods work:

Reimplemented in DD::Image::NukeWrapper.

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

void Op::append ( Hash hash)

Calculate a value for the hash(). The incoming variable is a suggested value for the hash, calculated by Nuke. This is a hash of all the uses_input() Op hash values and all the knobs() that don't have the NO_RERENDER flag set. A subclass can override this to modify the hash, such as to append the frame number in cases where the output image changes depending on the frame even if no controls are animated:

void MyOp::append(Hash& hash) {
this->actual_frame = clamp(int(outputContext.frame()), first, last);

The default version does nothing.

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

float Op::uses_input ( int  ) const

Return non-zero to indicate that this operator actually uses the data on the given input arrow. If this returns false then Nuke will not highlight the input arrow, and may not even construct the operator on this input (so the pointer may be null or garbage or an out-of-date version of the operator.

The value may be used to control how bright the arrow is, 1.0 indicates full use, 0.0 indicates none. This allows a cross-dissolve operator to fade the arrows on/off. In addition, values <= .01 will appear off to the user but will still construct inputs, this is useful for operators that want to peek at the frame ranges or formats but appear to the user as though the input is unused.

The default version returns 1.0.

Reimplemented in DD::Image::NukeWrapper.

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

int Op::split_input ( int  n) const

If this returns a number m greater or equal to zero, then the user-visible input n is split into m separate inputs (i.e. the number of inputs will be increased by m-1, and the next user-visible input will be at input n+m).

This is used to look at the input at several different frames.

If you override this you must also override inputContext() to return different values for each of these or they will all end up hooked to the same Op.

Returning -1 acts like 1 but leaves the input connected to an arbitrary frame (same as what node_input(n, ANY_CONTEXT) returns). You are expected to use an Execute object to switch this input to specific frames.

The default version returns 1.

Reimplemented in DD::Image::NukeWrapper, DD::Image::Write, DD::Image::RenderScene, and DD::Image::WriteGeo.

Referenced by inputNumber(), and DD::Image::NukeWrapper::split_input().

const OutputContext & Op::inputContext ( int  n,
int  offset,
OutputContext scratch 
) const

Return the context to use for the input connected to input(n, offset). The most common thing to do is to change the frame number.

The default version returns outputContext().

You can use scratch as a space to construct the context and return it.

This cannot look at input n or above, as they have not been created yet. Often though it is useful to look at these inputs, for instance to get the frame range to make a time-reversing operator. If you want to do this you use node_input() to generate a "likely" op. You can examine any data in it that you know will not depend on the frame number.

Reimplemented in DD::Image::NukeWrapper, DD::Image::Write, and DD::Image::RenderScene.

Referenced by DD::Image::Render::_validate(), and DD::Image::NukeWrapper::inputContext().

const OutputContext * Op::inputUIContext ( int  n,
OutputContext scratch 
) const

Return the context to show the user for the input connected to user input n. This is used if the frame number, view, etc that you want the user to see is different than the first one you actually want. For instance a time-blending operation may want the times frame-.5 and frame+.5, but wants the user to see the frame number unchanged.

Typical implementation is to not mess with the frame number:

const OutputContext* MyOp::inputUIContext(int n, OutputContext&) const {
return &outputContext();

The default version returns null, which is for back compatibility. If null is returned, inputContext(n,0) is used.

Op * Op::default_input ( int  n) const

Return the Op to connect to this input if the arrow is disconnected in Nuke, or if the Op Nuke tries fails the test_input() test. Making this method return a default instance of the desired Op type will avoid having to put many checks for null inputs in your code. This can assume outputContext() is already set.

The default version returns NULL, so disconnected arrows get NULL in their inputs.

If you implement split_input() n is the user-visible input number, but set_input() will be called with the split input number.

Reimplemented in DD::Image::Iop, DD::Image::NukeWrapper, DD::Image::GeoOp, DD::Image::IllumShader, and DD::Image::TransformGeo.

const Hash & DD::Image::Op::hash ( ) const

A value which will change as the output of the operator changes. Nuke calculates this as a side-effect of constructing the tree. See append(Hash&) for how this is calculated.

Referenced by DD::Image::NukeWrapper::_invalidate(), DD::Image::RenderScene::build_handles(), DD::Image::ParticleBehaviour::conditionsApply(), copyState(), DD::Image::DeepOp::deepRequest(), fetchMetaData(), DD::Image::SourceGeo::get_geometry_hash(), invalidate(), and DD::Image::Transform::motionBlurSample().

virtual bool DD::Image::Op::frameTransformImplemented ( ) const

Override frameTransformImplemented() to return true if the Op implements frameTransformDownstream and frameTransformUpstream. These are used to transform the times on keyframes used for such panels as the Dope Sheet and the Curve Editor, as well as the keyframes on the Viewer timeline.

For example, if this node is a simple retime with a constant factor, then frameTransformDownstream should be overridden to set outFrame to the frame /produced/ given an input frame; and frameTransformUpstream should be overriden to set inFrame to the frame /required/ given an output frame.

For time operators that use multiple frames the 'centre' one should be preferred: this is the same one which will be return by inputUIContext (or if that isn't implemented by the Op, then inputContext. The OutputContext is passed in so that the view and other things on it can be honoured if necessary; ignore that frame on it.

The downstream and upstream methods should match, so taking the result of frameTransformDownstream and feeding it into frameTransformUpstream should produce the same result. However, there are lots of exceptions to this, in particular when there is no downstream mapping the outFrame is allowed to be NAN.

Note that it may be more helpful to provide an extension of the mapping that is is use for the linear part than actually reflecting clipping behaviour at the end. These functions are used for display of keyframes in the user interface and not for actual processing.

Both transform methods also take an input index, which identifies which input is upstream along the path being taken through the DAG. This allows overrides to query upstream nodes for data required for the time transform, e.g. input clip start/length.

frameTransformDownstrean and frameTransformUpstream should return true if the mapping was successful, or false if no mapping was available.

DopeItemFlags::Mask Op::getDopeItemFlags ( ) const

Flags for influencing how the Op should be represented in the dopesheet. Override as appropriate.

virtual bool DD::Image::Op::shouldHideInDopeSheet ( Knob knob) const

Overrides should return true if the specified knob should be omitted in the Dope Sheet. This can be used to hide knobs such as the Read node's 'file' knob.

virtual DD::Image::Knob* DD::Image::Op::getDopeItemKnob ( ) const

Override for an Op to specify a specific knob's keys to appear in its dope item in the DopeSheet. This is intended for use by time nodes, where the bar representing a time clip is driven by animation keys on a knob.

bool DD::Image::Op::requested ( ) const

Returns true if setRequested() has been called since the last time forget_request() was called. This is used by Iop::request() style calls to see if this is the first time they were visited.

Referenced by DD::Image::Iop::_copyState(), forget_request(), forgetRequestShallow(), and DD::Image::Iop::request().

void DD::Image::Op::setRequested ( )

Make requested() return true. This is intended to be called by subclass methods such as Iop::request().

Referenced by DD::Image::Iop::request().

void Op::forgetRequestShallow ( )

Turn off requested() in this Op only

Without this Iop::request() calls will accumulate their results and the Iop::_request() virtual functions will not be called unless the request is for more channels or pixels.

References requested().

void Op::forget_request ( std::set< Op * > &  forgotten)

Recursively turn off requested() in this Op and all the inputs. Without this Iop::request() calls will accumulate their results and the Iop::_request() virtual functions will not be called unless the request is for more channels or pixels.

Also see all_forget_request() which is much faster.

References input(), inputs(), and requested().

void DD::Image::Op::all_forget_request ( )

Acts like forget_request() was called on every Op in existence. This is done by incrementing a static variable and is thus a much faster method.

Referenced by DD::Image::ToBuffer::to_buffer().

const char * Op::node_shape ( ) const

Return what shape Nuke should draw the box in the DAG window. This is a string where the characters approximately show what shapes the ends of the box are. The default return value is "[]" (or "\)" for DeepOps);

Other possible characters are < > ( ) r c p b { } / \ and !

Reimplemented in DD::Image::NukeWrapper, DD::Image::GeoOp, and DD::Image::Material.

References DD::Image::DeepOp::DeepNodeShape().

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

unsigned Op::node_color ( ) const

Return the default color for the Node in the Nuke DAG window. The value is 0xRRGGBBAA. The AA byte is ignored right now. Returning 0 indicates that you want the fall-back color set in the user's preferences to be used. If you really want to return black, return 0xff.

Reimplemented in DD::Image::Transform, DD::Image::NukeWrapper, and DD::Image::Material.

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

const char * Op::node_help ( ) const
pure virtual

Return help information for this node. This information is in the pop-up window that the user gets when they hit the [?] button in the lower-left corner of the control panel.

The first character should not be a punctuation mark, they are all reserved for future use.

Implemented in DD::Image::NukeWrapper, and DD::Image::LightOp.

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

const char * Op::input_label ( int  i,
char *  buffer 
) const

Return the text Nuke should draw on the arrow head for input i in the DAG window. This should be a very short string, one letter ideally. If you want you can print into the passed buffer and return a pointer to that, the buffer is very short (20 characters). Return null or an empty string to not label the arrow.

The default version checks maximum_inputs(). It leaves 1-input nodes blank. 2-input nodes are labeled B and A. Higher numbers of inputs get their index number + 1 as a label.

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

References maximum_inputs().

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

std::string Op::input_longlabel ( int  i) const

Return a longer string describing an input. This is used when there is more room to format the string into, such as a tooltip. If an empty string is returned then input_label() is used.

void DD::Image::Op::node_redraw ( )

An operator should call this if it does anything to change it's color(), shape(), or label(), this tells Nuke to update the DAG display. If this operator has a parent() this does nothing.

void DD::Image::Op::print_name ( std::ostream &  o) const
Op::NodeContext Op::nodeContext ( ) const
std::string Op::node_name ( ) const

Returns the same string as printed by print_name(ostream).

References print_name().

void Op::invalidateSameHash ( )

Make sure the next call to validate() calls _validate(), by turning off the valid() flag, and calling _invalidate().

This is a very fast function if valid() is false so you can call it many times.

References _invalidate().

Referenced by DD::Image::NukeWrapper::_invalidate(), and invalidate().

bool Op::invalidate ( )

If valid(), change the hash() to a random number and call invalidateSameHash(). Since the hash is different, output operators that check it to see if the image has changed will think it has changed. Returns true if it was valid().

Don't use this on Op instances produced by Nuke as it will mess up the hash() value which Nuke relies on not changing. Plugins can use this on internal Op instances, and other programs using DDImage can use this.

If you just want to force _validate() to get called, use invalidateSameHash().

References invalidateSameHash().

Referenced by DD::Image::NukeWrapper::_invalidate(), DD::Image::NukeWrapper::_validate(), copyState(), DD::Image::Scene::evaluate_lights(), DD::Image::GeoOp::knob_changed(), and DD::Image::InternalOCIOOp::validate().

bool Op::invalidate ( const Hash hash)

Checks if the hash is different, in which case it changes hash() to this new value, and calls invalidateSameHash(). Returns true if the hash is different.

References _haveHash, hash(), and invalidateSameHash().

bool Op::update ( const Box box = nullptr)

Obsolete function, calls asapUpdate(*box) or asapUpdate() if box is NULL, returns true.

void Op::asapUpdate ( )

Indicate that the output of this Op has changed. This may be called by a parallel thread, such as a socket listener, or other connection to an outside image source. The Nuke viewer will redraw with the new image.

Currently you must also implement append(Hash&) and make it modify the hash. The easiest way is to increment a counter when you call this and add call hash.append(counter) in that function. The viewer will not update if the hash does not change.

This disables disk caching by the viewer, on the assumption that the resulting image will only be seen once.

Return value from Nuke is currently always true.

void Op::asapUpdate ( const Box box,
int  direction = 0 

Same as asapUpdate() but the box indicates an area that you want the viewer to draw first. This area must be in viewer coordinates (including the current proxy settings). This is used by paint strokes.

The optional direction indicates which direction to draw the box. Positive draws from bottom to top, negative from top to bottom. Zero indicates you don't care.

void Op::validate ( bool  for_real = true)

Turns on valid(), and if for_real is true, turns on real_valid(). This returns immediately if these flags are already on.

When this returns, info() has been filled in with information about the output image. If for_real is false this is a quick "simulation" used by Nuke. If for_real is true this is a more accurate version that incorporates the actual information that is read from input files, and can take considerably longer.

If this has ever called error() since the last time invalidate() was called, this will immediately report the same error message, turn on abort(), and return. You must test for this after calling open() (this need for a test will go away when we fix it to use exceptions).

References force_validate().

Referenced by DD::Image::UpRez::_validate(), DD::Image::AxisOp::_validate(), DD::Image::TransformGeo::_validate(), DD::Image::IllumShader::_validate(), DD::Image::DrawIop::_validate(), DD::Image::Transform::_validate(), DD::Image::ReadGeo::_validate(), DD::Image::Write::_validate(), DD::Image::NukeWrapper::_validate(), DD::Image::Render::_validate(), _validate(), DD::Image::Transform::append(), DD::Image::TransformGeo::build_handles(), DD::Image::Transform::build_handles(), DD::Image::AxisOp::build_handles(), DD::Image::Render::build_handles(), DD::Image::GeoOp::build_matrix_handles(), DD::Image::Iop::copy_info(), copyState(), DD::Image::Scene::evaluate_lights(), DD::Image::Write::execute(), DD::Image::GeoOp::get_geometry_hash(), DD::Image::Transform::matrixAt(), DD::Image::Iop::merge_info(), open(), DD::Image::RenderScene::render_camera(), DD::Image::Iop::request(), tryValidate(), DD::Image::InternalOCIOOp::validate(), and DD::Image::Scene::validate().

void Op::force_validate ( bool  for_real = true)

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

Reimplemented in DD::Image::Iop, and DD::Image::MultiTileIop.

References _validate(), and DD::Image::OpMessageHandler::markMessagesAsOld().

Referenced by DD::Image::Iop::force_validate(), and validate().

bool DD::Image::Op::valid ( ) const

Returns true if it has been validated - including if there was an error.

Returns true after validate(false) or validate(true) has been called. You should not use the data in info() for anything if this is false. Instead call valid() first.

Referenced by DD::Image::Iop::_close(), copyState(), and DD::Image::Write::execute().

bool DD::Image::Op::real_valid ( ) const

Returns true if it has been real-validated - including if there was an error.

Returns true after validate(true) has been called. This means the data in info() is truly correct and tested against slow things like opening files. This is used by Nuke, normal programs that never call validate(false) will not need to use this and can use valid().

Referenced by DD::Image::Iop::copy_info(), copyState(), DD::Image::Iop::merge_info(), and DD::Image::Iop::request().

bool DD::Image::Op::opened ( ) const

Returns true after open() has been called. Returns false after invalidate() or close() has been called. This indicates that the operator is ready to have data extracted from it (by the engine() call in the case of an Iop). Normally this is turned on by operators calling open() on themselves on the first call to get data.

void Op::open ( )

Gets the operator ready for producing data. Normally this is called by operator implementations on the first call to get some data from it. The main thing this does is call _open() if it has not been called since the last invalidate().

If this has ever called error() since the last time invalidate() was called, this will immediately report the same error message, turn on abort(), and return. You must test for this after calling open() (this need for a test will go away when we fix it to use exceptions).

References _open(), abort(), aborted(), and validate().

Referenced by DD::Image::NukeWrapper::_open(), DD::Image::DeepOp::deepEngine(), and DD::Image::Iop::fetchPlane().

bool DD::Image::Op::running ( ) const

Returns true if engine() is currently executing. This is used to highlight the busy operators in Nuke. It is not very accurate (because multiple threads may turn it off) so don't use this for anything other than user feedback.

void DD::Image::Op::running ( bool  v)

Turn the running highlight in the Nuke display on/off. You should do this around any code that extracts data. This is very fast (much faster than calling node_redraw()), it just sets/clears a local flag. Nuke works by running a parallel thread that wakes several times a second to see if the highlight changed and redraw the DAG display with the current highlighting.

bool DD::Image::Op::not_closed ( ) const

Returns true after open() has been called. Returns false after close() has been called. invalidate() does not turn this off, this is an indicator that the Op may have resources allocated that could be freed.

void Op::close ( )

Tell the Op to free all recreatable data, on the assumption that this operator will not be used again soon. This calls _close() and also turns off flags so it knows that _open() must be called again.

References _close().

Referenced by DD::Image::NukeWrapper::_close(), and callPendingClose().

void Op::callCloseAfter ( double  seconds)

Indicate that close() (and thus _close()) should be called after the given number of seconds of idle. Passing zero is useful to get close() called as soon as the viewer stops updating.

This is a one-shot timeout, the entry is removed after close() is called. Call this again if you want to be called again. Only the last call is used, it replaces any previous timeout whether larger or smaller, so calling this with INFINITY will disable the callback.

double Op::callPendingClose ( double  seconds)

Call close() on some (currently only zero or one) Ops that asked for it to be called with a time less or equal to seconds. Return with the smallest time of any remaining callCloseAfter calls, or INFINITY if none. You should loop until this returns INFINITY (or perhaps some very large number).

References close().

void Op::clearPendingClose ( )

For use by Nuke, do not use

void Op::copyState ( Op input)

This is called when Nuke inserts no-op operators such as postagestamps. Change the op's valid and request state to match exactly the input, and possibly move the cache from the input to here. The hash is copied because this must be a no-op.

References DD::Image::Iop::_copyState(), hash(), invalidate(), iop(), real_valid(), valid(), and validate().

void DD::Image::Op::cached ( bool  b)

Indicates that caching of the output data is requested, so that asking for it again will be faster. Whether or not this does anything depends on the subclass of Op, but Iop uses this.

virtual Executable* DD::Image::Op::executable ( )

Return pointer to this object as an Executable if you want Nuke to call execute() on this node when the user hits render.

Don't implement this if you just want to have a button the user presses to execute the node. The tcl "execute" command will still work and you can make a script_knob that calls it.

The default version returns nil.

void Op::setKnobsToContext ( const OutputContext context)

Change the knobs to reflect the values at a different frame (or other piece of context information), and call invalidate if they are different. This can be used to determine the Op's animation. Make sure the knobs are set back by calling this with outputContext() when done.

Referenced by DD::Image::Transform::matrixAt().

void Op::gotoContext ( const OutputContext context,
bool  update 

Change Nuke to reflect a different frame number (and perhaps other aspects of the context), and change this op and its entire input tree to reflect this context. If update is true then it will also pause until the entire user interface is updated with the new frame.

You will have to call validate() on the inputs before using them.

This should only be called due to UI actions such as knob_changed().

void Op::progressFraction ( double  fraction,
StatusFlags  flags = StatusNone 

Set the location of the progress bar. fraction should be between 0 and 1. If this is not called the fraction is zero. flags can control the behaviour of progress updates, see StatusFlags enum. Only StatusUseCallback affects progressFraction().

References status_callback.

Referenced by DD::Image::Writer::progressFraction(), and DD::Image::GeoWriter::status().

void Op::progressMessage ( const char *  fmt,

Set a message to display on the progress meter. If this is not called, or if fmt is zero, then the message is the name of the operator. If you already have the message figured out, use a fmt of "%s", this is detected and the next argument is passed directly.

References status_callback, and vsnprintf().

Referenced by DD::Image::Write::execute().

void Op::progressDismiss ( )

Make the progress meter disappear (if it was displaying this op) and reset all the progress stuff to it's default values.

References status_callback.

int DD::Image::Op::slowness ( ) const

0 means no cache is necessary. This is for operators that directly calculate their output (and thus read no inputs), and for operators that internally buffer their output (so any additional caching is useless). Any operator that returns zero will disable any attempt to cache the output.

Non-zero numbers are supposed to indicate the slowness of the calculation. In theory this will be used to intelligently place caches where they do the most good, but the values are currently ignored. A sequence of operators would have the request() counts multiplied by their slowness and these added together to get an idea how expensive a branch is. So this value should be linear with the speed of the operator.

The default value is 10. This value is used by color correctors and similar pixel operators. Almost any other operator will be slower, you should judge how long it takes relative to a color corrector and multiply accordingly.

1 means really fast and should be returned by an operator that does not look at pixels, but simply copies blocks of them from the input to the output. Shuffle and Crop are examples of this.

Referenced by DD::Image::RenderScene::_validate(), DD::Image::Transform::_validate(), DD::Image::NukeWrapper::_validate(), DD::Image::Render::_validate(), DD::Image::Transform::degenerate(), DD::Image::Iop::get(), and DD::Image::Iop::Iop().

bool Op::firstEngineRendersWholeRequest ( ) const

Override this method and return true if the first engine call renders the entire request area and locks all the other render threads.

This may be used to reuse the spare render threads in other parts of the tree and only call this op's engine call from one thread.

It is also useful in Nuke as it will hide the 'white-lines' if this method returns true and the viewer is connected to this op.

Note it is valid to return true or false dynamically from this method between validate passes.

Reimplemented in DD::Image::NukeWrapper.

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

virtual bool DD::Image::Op::updateUI ( const OutputContext context)

can be overriden by ops to update their UI when their control panel is open. if you override it, return true, otherwise it will not be called again.

const Format & Op::input_format ( ) const

Returns the full_size_format() of node_input(0). This is needed to convert uv values to pixels or to look at the pixel aspect ratio. It can also be used to initialize default values of fields in the constructor. If the input is not connected, or not connected to a node producing an Iop, the format of Iop::default_input() is returned.

Note that until validate() is called, this returns only a "guess". Be prepared for the format being different in validate().

References node().

const OutputContext & Op::uiContext ( ) const

Return the "user interface Context" from the node that generated this Op. See Knob::outputContext() for more information. This is most useful for finding out the frame number or view the user is interested in right now. This is not necessarily the same as the Context passed to setOutputContext()!

References node().

Referenced by DD::Image::ReadGeo::_validate(), and DD::Image::RenderScene::build_handles().

void Op::error ( const char *  fmt,

An operator can call this to report an error. This will abort all trees that the op is in - i. e. calling aborted() on this op or any op in one of the trees it's in will subsequently return true.

The fact that this was called is recorded and open() will immediately cause the error again and return unless you call invalidate() on this.

The current version truncates the error message at 2048 characters unless the format is "%s" in which case it knows to use the first argument directly.

References DD::Image::OpMessageHandler::addMessage(), DD::Image::OpTreeHandler::lockTrees(), DD::Image::OpTreeHandler::unlockTrees(), and vsnprintf().

Referenced by DD::Image::DrawIop::_validate(), DD::Image::Write::_validate(), DD::Image::NukeWrapper::_validate(), create(), DD::Image::ReadGeo::internalError(), DD::Image::DeepWriter::openFile(), and DD::Image::Iop::request().

void Op::warning ( const char *  fmt,
void Op::critical ( const char *  fmt,

An operator can call this to report an error. This will abort all trees that the op is in - i. e. calling aborted() on this op or any op in one of the trees it's in will subsequently return true.

The fact that this was called is recorded and open() will immediately cause the error again and return unless you call invalidate() on this.

The current version truncates the error message at 2048 characters unless the format is "%s" in which case it knows to use the first argument directly.

References DD::Image::OpMessageHandler::addMessage(), DD::Image::OpTreeHandler::lockTrees(), DD::Image::OpTreeHandler::unlockTrees(), and vsnprintf().

Referenced by DD::Image::FileWriter::close(), DD::Image::Write::execute(), DD::Image::WriteGeo::internalError(), DD::Image::Write::internalError(), DD::Image::FileWriter::open(), DD::Image::RenameTempToFinal(), DD::Image::FileWriter::seek(), and DD::Image::FileWriter::write().

Op * Op::error_op ( )

Returns an op with an active error (the first one found if any), or NULL if none. Deprecated. Use other error functions such as Op::hasError() or OpTree::getFirstOpWithError() instead.

References DD::Image::OpTree::getFirstOpWithError().

Referenced by error_message().

const char * Op::error_message ( )

Returns the error string from an op with an active error (the return from error_op()), or NULL if none. Deprecated. Use other error functions such as OpMessageHandler::getFirstError() instead.

References error_op().

Referenced by DD::Image::WriteGeo::set_file_type_from_filename().

bool Op::hasError ( ) const

Return true if this op, or any of it's children, is in an error state Not thread safe; only call from the main thread

Referenced by DD::Image::OpTree::addMessageOp(), DD::Image::Write::execute(), and DD::Image::OpTree::removeMessageOp().

bool Op::opOrChildHasError ( ) const

The same as opOrChildHasError, but will return the first Op which is in an error state. Not thread safe; only call from the main thread

bool Op::tryValidate ( bool  for_real = true)

Call validate() and return true if it did not cause error() to be called. During this call calls to error() do not cause abort(), and thus will not kill running parallel threads.

All new code should call this instead of validate() to be compatible with future versions.

Returns false if error was called. More detail can be retrieved from the message in the op's message handler - see getMsgHandler(). Returns true if error() was not called.

References DD::Image::OpTree::hasError(), and validate().

const char * DD::Image::Op::Class ( ) const
pure virtual

Return the command name that will be stored in Nuke scripts. This must be unique for each different function and must be the same string (ie the same pointer) as is in the Op::Description object that constructed this instance.

If you don't plan to make a Nuke operator you can have this return null.

Implemented in DD::Image::NukeWrapper, and DD::Image::Convolve.

Referenced by DD::Image::ParticleOp::appendSimulationCurve(), DD::Image::GeoOp::build_scene(), DD::Image::NukeWrapper::Class(), displayName(), docsPath(), DD::Image::Material::fragment_shader(), DD::Image::Iop::get(), DD::Image::GeoOp::get_geometry(), DD::Image::BufferIop::getName(), DD::Image::GetOpText(), DD::Image::opHints(), DD::Image::GeoOp::print_info(), DD::Image::Material::shade_GL(), DD::Image::GeometryList::synchronize_objects(), and DD::Image::Material::vertex_shader().

const std::string Op::libraryDisplayName ( ) const

Return the library name and version that the Op is using if they have been set, otherwise return an empty string.

References getLibraryName().

const char * Op::displayName ( ) const

Return a name for this class that will be shown to the user. The default implementation returns Class(). You can return a different (ie more user-friendly) name instead here, and there is no need for this to be unique.

Nuke currently will remove any trailing digits and underscores from this and add a new number to make a unique name for the new node.

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

References Class().

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

std::string Op::docsPath ( ) const

Return the default path used to search for online help. Usually the Class() but can be overridden.

Reimplemented in DD::Image::NukeWrapper.

References Class().

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

virtual bool DD::Image::Op::onAction ( const ViewerContext c,
const DD::Image::Flags  f,
void *  d 

A function designed to send keyboard (and other) events to the selected node. Could be used for a variety of event & data.

Op * Op::get ( const Description description)

This is used to insert operators that produce data needed by the user interface, such as TextureMap, Histograms, and PostageStamp. Usually this is called by one of the outputs of this op to insert something that operator needs for the user interface.

Nuke will create the described operator and connect it to the output of this->firstOp(), inserting it between it and whatever was connected to there. The new operator is returned. You can then validate() it and execute() it to get information from it. Or you can rely on side-effects of lines being pulled through the operator, or on execute() being called during idle by Nuke, which will avoid slowing down the main calculation.

If this is called again with the same description the previous created one is returned again. So at most one operator of each type is created for any Node.

const Op::Description * Op::find_description ( const char *  name,
const Op op_ 

Search for an Op::Description that has the given name. Returns the description if found. If it fails, it throws a std::runtime_error which contains the message from plugin_error().

First this searches all the ones that are known about. Then it tries to load a plugin using plugin_load() and sees if that defines the operator.

References DD::Image::plugin_error(), and DD::Image::plugin_load().

Referenced by create().

int Op::message_f ( char  t,
const char *  format,

This function prints a formated message to stdout. If DDImage runs in Nuke in interactive mode, this function will open a modal dialog box instead.

  • t defines the type of dialog that will appear:
    • 'i' will show a message dialog
    • '!' will show an alert dialog
    • '?' will show a question and return 1 if the user click 'yes', and 0 otherwise
int Op::message_vf ( char  t,
const char *  format,
va_list  va 
See also
void Op::add_timeout ( float  t,
TimeoutHandler  toh,
void *  v = nullptr 

Add a one-shot timeout callback.

The function will be called by Nuke at t seconds after this function is called. The optional void* argument is passed to the callback (you may want to pass this).

The timeout will be called even if the Op is destroyed. If you don't want this to happen, make sure you call remove_timeout in the destructor.

void Op::repeat_timeout ( float  t,
TimeoutHandler  toh,
void *  v = nullptr 

Inside a timeout callback you can call this to add another timeout. Rather than the time being measured from "now", it is measured from when the system call elapsed that caused this timeout to be called. This will result in far more accurate spacing of the timeout callbacks, it also has slightly less system call overhead.

It is undefined what this does if called from outside a timeout callback.

bool Op::has_timeout ( TimeoutHandler  toh,
void *  v = nullptr 

Returns true if the timeout exists and has not been called yet.

void Op::remove_timeout ( TimeoutHandler  toh,
void *  v = nullptr 

Removes a timeout callback. It is harmless to remove a timeout callback that no longer exists.

Op::PrevalidateResult Op::doPreValidate ( ViewerContext ctx = nullptr,
PreValidateContext pvc = nullptr 

virtual function that is called by preValidate to do actual work. The base class version calls preValidate() recursively on all inputs. An override of this should either call that and return its return value if non-eFinished, eCancelled if the user actually clicked 'cancel' in a progress bar, or eAbandoned if the tree became obsolete.

Reimplemented in DD::Image::ParticleRender.

References input(), inputs(), and preValidate().

Referenced by preValidate().

Member Data Documentation

void(* Op::node_redraw_cb)(const Op *)=default_redraw

Programs (e.g. Nuke) can set this callback to change what code is called when node_redraw() is called. The default version does nothing.

void(* Op::print_name_cb)(std::ostream &o, const Op *i)=default_print_name

Programs can set this callback so they can use the node() to print the name of the Op. By default this just prints the Class() of this and all parent() operators.

void(* Op::status_callback)(const Op *, float, float, const char *, Op::StatusFlags)

Non-Nuke programs may set this pointer to get called when operators call progressFraction() and progressMessage(). This is mostly useful to get Write operators to print a display.

The Op argument is set to the op that status() was called on.

The fraction is passed unchanged.

Total is unused and should be ignored.

The message is the printed message from progressMessage(). This buffered result will be freed when this returns, so you must copy it if you want to keep it.

Flags indicate whether operating in modal mode, and whether doProgressUpdate should be called.

An implementation should show the message (if any) to the user, and use the fraction to update a percent-done indicator. You should avoid expensive operations if the indicator has not changed. Here is a sample:

void status_callback(const Op*, float fraction, float total, const char* t, StatusFlags flags)
static int previous = 0;
int percent = int(fraction*100+.5);
if (t)
printf("\r%s:\033[K", t);
else if (percent == previous)
previous = percent;
printf("%3d%%\b\b\b\b", percent);
// ...

Referenced by progressDismiss(), progressFraction(), and progressMessage().

©2022 The Foundry Visionmongers, Ltd. All Rights Reserved.