Cook Interface (OpScript)
=========================

.. lua:module:: Interface

Provides a unified interface for querying and manipulating the scene graph.

Its methods can be broadly divided into two categories:

- Functions that query the incoming, or upstream, scene graph. These functions
  provide *read-only* access to the incoming scene graph.
- Functions that modify the output scene graph, observable after executing this
  Op. This involves creating new scene graph locations, modifying attributes of
  incoming scene graph locations, or deleting locations entirely.

Attributes
----------

Information
~~~~~~~~~~~

.. lua:function:: GetAttr(string attrName, [string inputLocationPath, \
                          int inputIndex])

   Returns the specified attribute on the Op's input. It is often necessary to
   perform some action or compute a value based on the result stored in another
   attribute. The :lua:func:`GetAttr` function allows you to interrogate any
   part of the incoming scene graph by providing the attribute name and a scene
   graph location path (either absolute or relative).

   By default :lua:func:`GetAttr` will return the specified attribute on the
   Op's default input. In most cases where the Op only has one input branch
   this will suffice. If the Op has multiple inputs (e.g. the Merge node) the
   ``inputIndex`` parameter can be used to specify a particular branch. When
   specified, ``inputIndex`` must satisfy ``0 <= inputIndex < GetNumInputs()``.

   .. note:: It is important to remember that :lua:func:`GetAttr` will only
      interrogate the Op's *input* scene graph. Calls made to
      :lua:func:`SetAttr` will not be visible to :lua:func:`GetAttr`. If you
      need to see what attributes have been set during an Op's execution you
      should call :lua:func:`GetOutputAttr`.

   :param attrName: The name of the attribute.
   :param inputLocationPath: The input location path the attribute should be
      retrieved from.
   :param inputIndex: The input index the attribute should be retrieved from.
   :returns: The attribute at the specified location path and input index.

   .. seealso:: :lua:func:`GetNumInputs`, :lua:func:`GetOutputAttr`

.. lua:function:: GetOutputAttr(string attrName)

   Returns the specified attribute on the Op's output for the current location.

   This is useful for inspecting the output attributes set during an
   :lua:func:`ExecOp` that may potentially require further processing after the
   exec'd Op has returned.

   .. note:: This is not recommended for normal usage.

   :param attrName: The name of the attribute to query.
   :returns: The attribute set on the Op's output. If not set ``nil`` will be
      returned.

.. lua:function:: GetGlobalAttr(string name, [string inputLocation, \
                                int inputIndex])

   Returns attribute from the input scene, including inherited attributes.

   :param name: The name of the attribute.
   :param inputLocation: The location at which the attribute should be found.
   :param inputIndex: The input index of which to search for the input scene
      graph location.
   :returns: The specified attribute at the given location including inherited
      attributes.

.. lua:function:: GetBoundAttr([string inputLocationPath, int inputIndex])

   Returns the bound attribute at the specified input scene graph location.

   :param inputLocationPath: The scene graph location to obtain the bound
      attribute from.
   :param inputIndex: The input index on which to find the scene graph
      location.
   :returns: A 6-element DoubleAttribute containing the bound attribute or
      ``nil`` if bounds do not exist at the specified location.

.. lua:function:: GetTransformedBoundAttrPoints(DoubleAttribute boundAttr, \
      number sampleTime, number[16] xform) -> number[8][3]

   Returns the bounding box specified by the bound attribute ``boundAttr``
   after being transformed by the 4x4 transform matrix ``xform``.

   :param boundAttr: A 6-element DoubleAttribute specifying the bounding box to
      be transformed.
   :param sampleTime: The sample time that the bounds attribute ``boundAttr``
      should be sampled at.
   :param xform: A 4x4 transform matrix by which boundAttr will be
      transformed.
   :returns: A table of 8 3-valued tables representing the 8 transformed points
      of the bounding box.

.. lua:function:: GetTransformedBoundAttrMinMax(DoubleAttribute boundAttr, \
      number sampleTime, number[16] xform) -> number[3], number[3]

   Returns the axis-aligned bounding box specified by the bound attribute
   ``boundAttr`` after being transformed by the 4x4 transform matrix
   ``xform``.

   :param boundAttr: A 6-element DoubleAttribute specifying the bounding box to
      be transformed.
   :param sampleTime: The sample time that the bounds attribute ``boundAttr``
      should be sampled at.
   :param xform: A 4x4 transform matrix by which ``boundAttr`` will be
      transformed.
   :returns: Two 3-element tables that contain the transformed (x-min, y-min,
      z-min) and the transformed (x-max, y-max, z-max) values.

.. lua:function:: GetGlobalXFormGroup([string inputLocationPath, \
                                      int inputIndex])

   Returns the global transform as a GroupAttribute, where the immediate
   children represent all the entries from ``/root`` to the leaf which have an
   ``xform`` attribute present.

   .. note:: If a collapsed 4x4 transform matrix is required, pass the result
      of this function to the :lua:func:`XFormUtils.CalcTransformMatrixAtTime`
      function.

   :param inputLocationPath: The input scene graph location to retrieve the
      global transform from.
   :param inputIndex: The input index from which to retrieve the scene graph
      location.
   :returns: The global transform at the specified location.

Manipulation
~~~~~~~~~~~~

.. lua:function:: SetAttr(string attrName, Attribute attrValue, \
      [boolean groupInherit])

   Sets the specified attribute on the Op's output.

   ``attrName`` can be specified in dot-delimited form e.g.
   ``attr1.attr2.attr3``, in which case a new GroupAttribute is created for
   each level required and the value of ``groupInherit`` will determine the
   GroupAttribute's inheritance state.

   .. note:: Calls to :lua:func:`SetAttr` made in the current Op will not be
      reflected in subsequent calls to :lua:func:`GetAttr`. This is because
      functions which mutate the scene graph only affect the output of this Op.
      Methods such as :lua:func:`GetAttr` and :lua:func:`DoesLocationExist`
      query the input to this Op. This is also true for non-local queries i.e.,
      when an Op queries attributes of its parent. In this case it will be
      querying the input at its parent, and thus does see the results of its
      own processing.  If you need to see the attributes set during a cook you
      should use :lua:func:`GetOutputAttr`.

   :param attrName: The name of the attribute to create. This can be specified
      in dot-delimited form.
   :param attrValue: The Attribute instance to be associated with ``attrName``.
   :param groupInherit: The group inheritance state for newly created
      GroupAttributes.

   .. seealso:: :lua:func:`GetOutputAttr`

.. lua:function:: CopyAttr(string dstAttrName, string srcAttrName, \
      [boolean groupInherit=true,  string inputLocationPath, int inputIndex])

   Copies the specified source attribute to the specified destination
   attribute.

   The specified source attribute (determined by ``inputLocationPath`` and
   ``inputIndex``) will be copied to the output of this Op as ``dstAttrName``.
   If the source attribute or location does not exist this call is equivalent
   to calling :lua:func:`DeleteAttr` with the destination attribute.

   :param dstAttrName: The name of the attribute to copy the attribute at
      ``srcAttrName`` to.
   :param srcAttrName: The name of the attribute to copy to ``dstAttrName.``
   :param groupInherit: The group inheritance state of the destination
      attribute.
   :param inputLocationPath: The scene graph location path on this Op's
      input to copy from.
   :param inputIndex: The input index to copy from (where multiple
      branches in the Op tree exist).

.. lua:function:: ReplaceAttrs([string inputLocationPath, int inputIndex])

   Replaces the attributes on this Op's output with those specified by the
   input scene graph location path.

   :param inputLocationPath: The attributes at inputLocationPath will
      replace those on this Op's output.
   :param inputIndex: The input index to use where multiple input
      branches exist for this Op.

.. lua:function:: ExtendAttr(string dstAttrName, Attribute value, \
                             [string srcAttrName='', \
                             boolean groupInherit=true, \
                             string inputLocationPath, int inputIndex])

   Extends the existing input attribute with additional values if the types
   match.

   If no input attribute exists with the specified name then this call is
   equivalent to :lua:func:`SetAttr`.

   Multi-sampling is supported; the new attribute is constructed as the union
   of all incoming and new time samples, leveraging the FnAttribute's existing
   interpolation.

   If there is a type mismatch, it will be reported as a scene graph error. If
   more sophisticated or fine-grained type mismatch handling is required it is
   recommended to instead manually call :lua:func:`GetAttr` /
   :lua:func:`SetAttr`

   Incoming NullAttribute's are equivalent to the attribute not being set in
   the incoming scene.

   :param dstAttrName: The name of the attribute to be extended.
   :param value: The Attributes that will extend the specified attribute.
   :param srcAttrName: The name of the attribute a specified location to
      be extended, if empty string is used this is the equivalent of
      :lua:func:`SetAttr`.
   :param groupInherit: The value of the group inheritance flag.
   :param inputLocationPath: The input location path from which ``srcAttrName``
     should be sourced from.
   :param inputIndex: The input index to search for ``inputLocationPath`` on.

   .. seealso:: :lua:func:`SetAttr`, :lua:func:`GetAttr`

.. lua:function:: DeleteAttr(string attrName)

   Deletes the attribute specified by ``attrName`` so it will no longer on this
   Ops output.

   :param attrName: The name of the attribute to delete from the Op's
      output.

.. lua:function:: DeleteAttrs()

   Deletes all attributes on this Op's output.

Scene graph
-----------

Information
~~~~~~~~~~~

.. lua:function:: AtRoot()

   Returns whether we are at the topmost location this Op has been cooked at.
   This is often, but not always, ``/root``.

   This is equivalent to testing if :lua:func:`GetRootLocationPath` is the same
   as :lua:func:`GetOutputLocationPath`.

.. lua:function:: GetRootLocationPath()

   Returns the scene graph location corresponding to the root of the Op's
   execution.

   This may or may not be ``/root``, specifically in the case where
   :lua:func:`ExecOp` is called beneath ``/root``.

   :returns: The root of the Op's execution.

   .. seealso:: :lua:func:`ExecOp`

.. lua:function:: GetInputLocationType([string inputLocationPath, \
                                       int inputIndex])

   Returns the location type for specified location on the corresponding input.

   :param inputLocationPath: The scene graph location path.
   :param inputIndex: The input index on which to retrieve the specified
      scene graph location path.
   :returns: The location's ``type`` attribute. If type attribute is not
      present, an empty string will be returned, if it is not set then ``group``
      will be returned by default.

.. lua:function:: GetInputName()

   Returns the leaf name for the input location.

   This will typically match :lua:func:`GetOutputName`, but may differ when
   :lua:func:`CopyLocationToChild` is used.

   :returns: The leaf name for the input location.

   .. seealso:: :lua:func:`CopyLocationToChild`

.. lua:function:: GetInputLocationPath()

   Returns the scene graph location path corresponding to the input scene graph
   location that is currently being traversed.

   :returns: The input scene graph location that is currently being
      traversed.

.. lua:function:: GetRelativeInputLocationPath()

   Returns the relative location path corresponding to the input scene graph
   location that is currently being traversed.

   :returns: The relative location path corresponding to the input scene
      graph location that is currently being traversed.

.. lua:function:: GetAbsInputLocationPath(string inputLocationPath)

   Resolves a relative *input* scene graph location path to an absolute path.

   This method cannot be used to query output locations (such as those used
   with methods such as :lua:func:`CreateChild`) but those methods
   that operate on the Op's output such as :lua:func:`GetAttr`. If
   you require the absolute scene graph location path for an output location
   you should use :lua:func:`GetAbsOutputLocationPath`.

   :param inputLocationPath: The relative input scene graph location path.
   :returns: The corresponding absolute location path.

   .. seealso:: :lua:func:`GetAbsOutputLocationPath`

.. lua:function:: GetOutputName()

   Returns the leaf name for the output location.

   Example: ``/root/world/geo`` -> ``geo``

   :returns: The leaf name of the output location.

.. lua:function:: GetOutputLocationPath()

   Returns the output scene graph location path in its absolute form.

   The output scene graph location path is the scene graph location that is
   currently being cooked.

   Example: ``/root/world/geo``

   :returns: The absolute output scene graph location path.

.. lua:function:: GetRelativeOutputLocationPath()

   Returns the location path relative to the root execution location currently
   being traversed.

   For Ops instantiated at document level:

   .. code-block:: none

      "/root" -> ""
      "/root/world" -> "world"
      "/root/world/geo" -> "world/geo"

   For an Op first executed at /root/world/geo (producing "a/b")

   .. code-block:: none

      "/root/world/geo" -> ""
      "/root/world/geo/a" -> "a"
      "/root/world/geo/a/b" -> "a/b"

   :returns: The location path relative to the root execution location
      currently being traversed

.. lua:function:: GetAbsOutputLocationPath(string outputLocationPath)

   Resolves a relative *output* scene graph location path to an absolute path.

   This method cannot be used to query input locations (such as those used with
   methods such as :lua:func:`GetAttr`) but those methods that operate on the
   Op's output such as :lua:func:`CreateChild`. If you require the absolute
   scene graph location path for an input location you should use
   :lua:func:`GetAbsInputLocationPath`.

   :param outputLocationPath: The relative output scene graph location path.
   :returns: The corresponding absolute location path.

   .. seealso:: :lua:func:`GetAbsInputLocationPath`

.. lua:function:: DoesLocationExist([string inputLocationPath, int inputIndex])

   Returns ``true`` if the specified location exists on the Op's input.

   :param inputLocationPath: The scene graph location path.
   :param inputIndex: The input index that should be searched.
   :returns: ``true`` if the location exists at the specified location and
      index otherwise false.

.. lua:function:: GetPotentialChildren([string inputLocationPath, \
                                       int inputIndex])

   Returns a StringAttribute containing list of names of potential children on
   input.

   The ability for Ops, via :lua:func:`DeleteSelf`, to delete themselves gives
   rise to a subtle behavior. When an upstream Op is evaluated and creates
   children, if downstream Ops have the ability to delete them, the upstream Op
   can only go so far as to state that the children it creates may potentially
   exist after a downstream Op has been evaluated at those child locations.
   This is because the Op has no knowledge of what a downstream Op may do when
   evaluated at such a location. To that extent,
   :lua:func:`GetPotentialChildren` returns a list of all the children of a
   given location on the input of an Op.

   :param inputLocationPath: The input location path to obtain the
      potential children for.
   :param inputIndex: The input index to be used.
   :returns: A StringAttribute containing the potential children at the
      specified input location.

Manipulation
~~~~~~~~~~~~

.. lua:function:: ResetRoot()

   Marks this location as the new root location in the Op's traversal.

   Subsequent calls to :lua:func:`GetRelativeOutputLocationPath` at child
   locations will return paths relative to this one.

   .. note:: Calls to :lua:func:`GetRelativeOutputLocationPath` at the current
      location will remain unaffected by this function.

.. lua:function:: CreateChild(string name, [string opType='', \
                              Attribute|nil args, \
                              ResetRootMode resetRoot=ResetRootMode.Auto])

   Creates a new child at the specified location if one didn't already exist.

   If the child already exists in the incoming scene then the Op will be run
   and previously created attribute values and children will be preserved. To
   ensure the child will not have any pre-existing attributes or children it is
   recommended to first call :lua:func:`DeleteChild`, doing so will maintain
   the original child index ordering.

   If the Op type is not specified or is an empty string the calling Op's type
   will be inherited by the child.

   To modify the result of :lua:func:`GetRelativeOutputLocationPath` in calls
   beneath this location the ``resetRoot`` argument can be set. If
   :lua:data:`ResetRootMode.Auto` is specified then the child's root
   location will be reset if and only if the Op's type differs from the
   parent's.

   .. note:: Multiple calls to :lua:func:`CreateChild` for the same named child
      location causes the last specified ``opType`` to be used, that is to
      say, successive calls to :lua:func:`CreateChild` mask prior calls.

   :param name: The name of the child to create.
   :param opType: The type of the Op that will be evaluated at the child
      location. If an empty string or nothing is specified then the current
      Op's type will be used.
   :param args: The Op arguments that will be passed to the Op when run
      at the child location.
   :param resetRoot: Specifies what the root location for Ops run at
      child location should be.

   .. seealso:: :lua:func:`ResetRoot`

.. lua:function:: ReplaceChildren([string inputLocationPath, int inputIndex])

   Replaces the children under the Op's current scene graph location with
   children from an alternate input location and/or input index.

   :param inputLocationPath: The input scene graph location whose
      children will replace this location's children.
   :param inputIndex: The input index on which the where the input
      location path should be retrieved.

.. lua:function:: CopyLocationToChild(string child, \
                                      [string inputLocationPath, \
                                      int inputIndex, string orderBefore])

   Copies the specified location in the input scene, to the specified child
   location.

   The specified ``inputLocationPath`` will not be evaluated until the new child
   location is traversed. At this time, if the input does not exist, neither
   will the new child.

   :lua:func:`CopyLocationToChild` can be used to rename a child location:

   .. code-block:: lua

      CopyLocationToChild(dst, src, InputIndex.Default, src)
      DeleteChild(src)

   The ``inputLocationPath`` always refers to the input name, and child refers
   to output name, so multiple :lua:func:`CopyLocationToChild` calls are
   unambiguous.

   :param child: The name of the child to be copied to the *output* of
      this Op.
   :param inputLocationPath: The input scene graph location path to copy.
   :param inputIndex: The input index to copy the ``inputLocationPath``
      from.
   :param orderBefore: The child that this should be precede in the scene
      graph ordering.

.. lua:function:: RenameChild(string src, string dst)

   Renames the specified child.

   :param src: The name of the child to rename.
   :param dst: The new name of the child.

.. lua:function:: DeleteChild(string name)

   Deletes the specified child location on the Op's output.

   :param name: The name of the child location to delete.

   .. note:: Calling :lua:func:`DeleteChild` is more efficient than allowing
      the child location to delete itself. Where possible you should prefer
      :lua:func:`DeleteChild` over :lua:func:`DeleteSelf`.

.. lua:function:: DeleteChildren()

   Deletes all children on this Op's output, both newly created
   by the current Op and any incoming children.

.. lua:function:: DeleteSelf()

   Deletes the current output location.

   It is common to ``return`` immediately following this call.

   .. note:: Calls to :lua:func:`DeleteSelf` will not remove the location from
      the location's parent :lua:func:`GetPotentialChildren` list. Thus, if
      there is a way to structure code to use :lua:func:`DeleteChild` instead,
      it is generally preferable.

Enumerations
^^^^^^^^^^^^

.. lua:data:: ResetRootMode

   Controls which root scene graph location will be used for Ops when run at
   child locations.

   .. lua:data:: ResetRootMode.Auto

      The root location is reset only if opType is different to the Op calling
      :lua:func:`CreateChild`.

   .. lua:data:: ResetRootMode.True

      The root location of the Op evaluated at the new location is reset to the
      new location path.

   .. lua:data:: ResetRootMode.False

      The root location of the Op evaluated at the new location is inherited
      from the Op that called :lua:func:`CreateChild`.

.. lua:data:: InputIndex

   .. lua:data:: InputIndex.Null

      Special value returned by :lua:func:`GetInputIndex` when the current
      location does not exist in the incoming scene.

   .. lua:data:: InputIndex.Default

      Special value that can be specified to :lua:func:`GetAttr` and many other
      Cook Interface functions. It indicates the operation should apply to the
      "default" index. This is defined as the input index in which the current
      location was created (by :lua:func:`CreateChild()`,
      :lua:func:`CopyLocationToChild()` or :lua:func:`ReplaceChildren()`).


Traversal
~~~~~~~~~

.. lua:function:: ReplaceChildTraversalOp(string opType, GroupAttribute args)

   Replaces the Op type and Op arguments for child locations of this Op.

   Newly created child locations (created with :lua:func:`CreateChild`) only
   have access to the Op arguments and type they were created with originally.
   Conceptually, this is the type and Op arguments used when traversing
   locations in the incoming scene.

   :param opType: The Op type that will be evaluated at child locations.
   :param args: The arguments that will be passed to the Op when run at
      the child locations.

.. lua:function:: StopChildTraversal()

   Stops this Op from running at descendants of the current location.

Graph State
-----------

.. lua:function:: GetCurrentTime()

   Returns the current time from the current Graph State.

   :returns: The current time.

.. lua:function:: GetShutterOpen()

   Returns the shutter open time from the current Graph State.

   :returns: The shutter open time.

.. lua:function:: GetShutterClose()

   Returns the shutter close time from the current Graph State.

   :returns: The shutter close time.

.. lua:function:: GetNumSamples()

   Returns the number of time samples from the current Graph State.

   :returns: The number of time samples.

.. lua:function:: GetGraphStateVariable(string variableName)

   Returns the specified variable from the current Graph State.

   :param variableName: The name of the Graph State Variable.
   :returns: The Graph State Variable specified by ``variableName``.

Error Reporting
---------------

.. lua:function:: ReportError(string message)

   Reports the specified error message to the scene graph at the current scene
   graph location.

   :param message: The error message.

.. lua:function:: ReportWarning(string message)

   Reports the specified warning message to the scene graph at the current
   scene graph location.

   :param message: The warning message.

Miscellaneous
-------------

.. lua:function:: Prefetch([string inputLocationPath, int inputIndex])

   Indicates to the Runtime that the caller depends on the specified location.

   Calling the ``Prefetch()`` function instructs the Runtime that the specified
   location is required for the Op's processing task.

   The ``Prefetch()`` function will return immediately, scheduling the
   computation of the requested location to be cooked concurrently or at some
   point in the future.

   ``Prefetch()`` is recommended if your Op makes multiple scattered queries
   during a cook. Note that it is not necessary to prefetch parent locations of
   your default input.

   The use of a prefetch creates a data flow dependency, so do not prefetch
   locations or inputs you do not need.

   :param inputLocationPath: The scene graph location path to be
       prefetched.
   :param inputIndex: The input index from which to request the specified
      ``inputLocationPath``. In common cases the default input will suffice,
      however if your Op has multiple input branches (like a Merge Op) you will
      need to specify a particular input index.

.. lua:function:: GetOpType()

   Returns the type of this Op.

   :returns: A string containing the Op's type. In OpScript, this returns
      ``OpScript.Lua``.

.. lua:function:: GetOpArg([string argName])

   Returns the specified Op argument or all Op arguments if an empty string is
   provided.

   Op arguments are passed to the Op to configure how it should run. Op
   arguments are stored in a GroupAttribute. This method allows you to query
   the Op arguments available to this Op.

   If you supply an argument name this can be in the dot-delimited form i.e.
   ``a.b.c`` or the single name form.

   :param argName The dot-delimited name of the Op argument.
   :returns: An instance of Attribute containing the Op argument.

.. lua:function:: ExecOp(string opType, GroupAttribute opArgs)

   Runs the specified Op with the provided arguments at the current location.

   Children created as a result of the :lua:func:`ExecOp` call will behave as
   expected in such that they will retain the type and Op arguments of the
   exec'd Op.

   :param opType: The type of Op to be run.
   :param opArgs: A GroupAttribute describing the arguments that will be
      passed to the Op when run.

.. lua:function:: GetNumInputs()

   Returns the number of input branches this Op has.

   An Op can have the output from multiple other Ops as its input. Obvious use
   cases for this are instances where you wish to merge multiple scene graphs
   produced by different OpTrees into a single scene graph, comparing attribute
   values in two scene graph states, or copying one scene graph into another
   one. The :lua:func:`GetNumInputs` function allows you to determine how many
   Ops you have as inputs, which is a precursor to interrogating different
   branches of the OpTree for scene graph data.

   :returns: The number of inputs this Op has.

.. lua:function:: GetInputIndex()

   Returns the input index this scene graph location was created in.

   In most cases :lua:func:`GetInputIndex` will return 0. This reflects the
   fact that most Ops operate on the default input or branch. It can also
   return a special value of :lua:data:`InputIndex.Null` if the current
   location doesn't exist in the incoming scene.

   In specific cases, such as in a Merge Op, :lua:func:`GetInputIndex` may
   return an index > 0. Certain locations may be present only in additional
   input scenes, but not in the first (connected) input scene. Those locations
   are created in the output scene, and are then cooked by subsequent cooks of
   the Merge Op. For those locations, the Runtime keeps track of the index of
   the scene in which they were created. This index is returned by
   :lua:func:`GetInputIndex`. This value allows the Merge Op to know which
   input scene a particular location came from, and is used for performance
   optimizations when certain circumstances apply.

   :returns: The input index this location was created on.

   .. seealso:: :lua:data:`InputIndex`