Roto serialisation format — NDK Developers Guide

### Navigation

- index
- next |
- previous |
- NDK Dev Guide »
- Advanced »

# Roto serialisation format

Roto serialisation format has changed for NUKE 7.0. The new format is not backwards compatible but NUKE 7 will read older scripts.

See also Curve serialisation format

## Curve tree

The curve tree consists of a hierarchy of one or more layers, each containing zero or more curvegroups. Here we give a general description of the format, using AUgmented Backhaus Naur Form.

It disregards some fine lexer details, and is not necessarily suitable for turning directly into a parser. In particular, it has not been checked for ambiguity in the definition, and begin and end can be followed and preceded by whitespace.

    begin                          = "{"

    end                            = "}"

    float                          = "0x" 8HEXDIG
    float                          =/ ["-"] (1*DIGIT "." 1*DIGIT) / 1*DIGIT

      ; Floating point numbers can, in addition to being written out as normal
      ; decimals literals, be written out as hexadecimal literals (represented
      ; under IEEE 754).  For endianness considerations, see serialisation code
      ; further down.

    int                            = ["-"] 1*DIGIT

    unquoted-char                  = "!" / %x23-26 / %x28-5B / %x5D-7B / %x7C / %x7E

      ; everything ASCII except space, " ' \ { }

    escaped-char                   = %x7D DQUOTE   ; "
    escaped-char                   =/ %x7D %x27    ; '
    escaped-char                   =/ %x7D %x5C    ; \
    escaped-char                   =/ %x7D %x7B    ; {
    escaped-char                   =/ %x7D %x7D    ; }

    printable-char                 = unquoted-char / escaped-char

    string                         = 1*unquoted-char
    string                         =/ DQUOTE 0*printable-char DQUOTE

      ; the effect of this is that a string with space, " ' \ { } within it must be
      ; quoted

    flag                           = int

      ; Flags are a bitmask.  See below for the significance of the bits.

    wsp                            = 1*SP

    view-name                      = string

    attribute-name                 = string

      ; the view name "-" means the default view.

    anim-curve-key-time            = float

    anim-curve-key-value           = float

    anim-curve-key-left-tangent    = wsp float wsp float

    anim-curve-key-right-tangent   = wsp float wsp float

    anim-curve-key-interpolation   = wsp int

      ; This is a bitmask.  The interpolation type can be found when masked
      ; with 255; the extrapolation can be found when shifted right 8 bits and
      ; masked with 255.
      ;
      ; The defined interpolation types are:
      ;   0 - step
      ;   1 - linear
      ;   2 - cubic
      ;
      ; The default value for this is "256" - i.e. linear extrapolation
      ; and step interpolation.

    anim-curve-key-extra           = wsp "-"
    anim-curve-key-extra           =/ anim-curve-key-left-tangent [anim-curve-key-right-tangent [anim-curve-key-interpolation]]

    anim-curve-key                 = begin anim-curve-key-time wsp anim-curve-key-value [anim-curve-key-extra] end
    anim-curve-key                 =/ begin anim-curve-key-time end

      ; Together these mean that a basic anim curve key consists of a group with
      ; time and value, separated by spaces, and then a list of optional
      ; elements that are in order the left tangents (2 floats), the right
      ; tangents (2 floats) and then the the interpolation type (which is a
      ; bitmask)
      ;
      ; If any of these are not provided the tangents default to 0 and the
      ; interpolation defaults to 256.  Instead of the optional elements, the
      ; literal "-" can be provided, which defaults both tangents to (0, 1) and
      ; the interpolation to 256.
      ;
      ; If this consists of only one element, then this represents the time
      ; alone, and can only appear as a medial or final element in the key-list.
      ; The other fields are copied from the immediately previous curve key.

    anim-curve-expression          = "=" string
    anim-curve-key-list            = anim-curve-key 0*(wsp anim-curve-key)

    anim-curve-constant-value      = float

    anim-curve-rle-key-count       = int

    anim-curve-rle-key-entry       = begin anim-curve-key anim-curve-rle-key-count end

      ; The anim-curve-key is repeated anim-curve-key-count numbers of times,
      ; with each key's time being incremented by one from the base.

    anim-curve-rle-key-list        = anim-curve-rle-key-entry 0*(wsp anim-curve-rle-key-entry)

    anim-curve-data                = anim-curve-constant-value
    anim-curve-data                =/ begin anim-curve-key-list end
    anim-curve-data                =/ begin "r" begin anim-curve-rle-key-list end end

    anim-curve-flag-entry          = begin "f" wsp flag end

      ; Flag entry consists of a group with "f" followed by the actual flag value
      ;
      ; There are no interesting flags on curves.  Ignore this.  Do not write it
      ; out.

    anim-curve                     = anim-curve-data
    anim-curve                     =/ begin [anim-curve-expression wsp] [anim-curve-flag-entry wsp] anim-curve-data end

      ; If there is no animation, an anim-curve can be represented as a single
      ; value, with no futher grouping at this level.
      ;
      ; Alternatively, it will be represented as a keylist, or possibly as an
      ; RLE keylist.
      ;
      ; If these is a flag and/or an expression then this will itself be wrapped
      ; in a group, with the expression or flag.

    anim-curve-timeless-key        = anim-curve-key-value / ( begin anim-curve-key-value anim-curve-key-extra end )

      ; Similar to anim-curve-key but without time, which is fed in at a higher
      ; level and shared between multiple curves.  As an additional compaction
      ; step, if the tangents and interpolation are default values (i.e. 0 and
      ; 56), then it will be a single value outside a group, without the braces.

    anim-curve-timeless-data-count = int

    anim-curve-timeless-data-entry = anim-curve-timeless-key
    anim-curve-timeless-data-entry =/ begin "x" wsp anim-curve-timeless-data-count wsp anim-curve-timeless end

    anim-curve-timeless-data       = anim-curve-timeless-data-entry [wsp anim-curve-timeless-data-entry]

      ; Keylists for timeless data consists of elements which are either a
      ; timeless key in themselves (which might be a float literal if the
      ; tangents and interpolation is to be copied from the previous key), or a
      ; group which contains "x", a count, and then the actual key, for repeats
      ; of the same values.
      ;
      ; The time is fed in from outside

    anim-curve-timeless            = anim-curve-key-value
    anim-curve-timeless            =/ anim-curve-timeless-data
    anim-curve-timeless            =/ begin [anim-curve-expression wsp] [anim-curve-flag-entry wsp] anim-curve-timeless-data end

    anim-curve-views-entry         = view-name wsp anim-curve

    anim-curve-views-list          = anim-curve-views-entry [wsp anim-curve-views-entry]

      ; This consists of the view as a string followed by the anim-curve.

    anim-curve-views               = anim-curve
    anim-curve-views               =/ begin "v" anim-curve-views-list end

      ; An anim-curve-views can be a regular anim-curve.  If so, then this is
      ; the "default" curve, and no others are split.  If it is split then it
      ; will be a group with "v" as its first element, followed by a number of
      ; view-curve entries (not themselves groups).

    anim-attribute-entry           = attribute-name wsp anim-curve-views

    anim-attribute-list            = anim-attribute-entry 0*(wsp anim-attribute-entry)

    anim-attributes                = begin "a" anim-attribute-list end

      ; An AnimAttributes block is made up of a group containing "a", to
      ; indicate a set of attributes, then the name and curve for each
      ; attribute in turn.  Omitted attributes are set to the default,
      ; which will depend upon the type of object these attributes
      ; are for.
      ;
      ; Shape points have 2 dimensions.  Strokes have a third dimension,
      ; used for storing pressure.

    anim-control-point             = begin [anim-attributes] 1*4(wsp anim-curve) end

      ; An AnimControlPoint consists of a group containing optionally, a list
      ; of attributes, and then up to four AnimCurves, one for each
      ; dimension.

    anim-control-point-timeless    = begin [anim-attributes] 1*4(wsp anim-curve-timeless) end

      ; The timeless version of an AnimControlPoint uses anim-curve-timeless
      ; objects instead of AnimCurves.

    anim-cubic-curve-flag-entry    = begin "f" wsp flag end

    anim-cubic-curve-tension       = float

    anim-cubic-curve-tension-entry = begin "tens" wsp anim-cubic-curve-tension end

    key-times-list                 = begin float 1*(wsp float) end

    anim-cubic-curve-points-list   = begin "p" wsp anim-control-point 0*(wsp anim-control-point) end
    anim-cubic-curve-points-list   =/ begin "px" wsp key-times-list wsp anim-control-point-timeless 0*(wsp anim-control-point-timeless) end

      ; There are two versions of the cubic curve points list.  If all
      ; the AnimCurves within it use the same keyframes, then these are
      ; extracted outwards and a "px" group is made, with that keylist as
      ; the next element in the group - this is then followed by all the
      ; control point data.  This means it doesn't need to keep repeating
      ; common keyframes.
      ;
      ; However, it is not structurally built into the cubic curve that
      ; all control points or dimensions within must be keyed on the
      ; same sets of frames, they may be individually controled.  So a
      ; simpler format exists, which will write out all the control points
      ; in full.
      ;
      ; Note that the attributes are independent of this.

    anim-cubic-curve               = begin "cc" wsp anim-cubic-curve-flag-entry [wsp anim-cubic-curve-tension-entry] wsp anim-cubic-curve-points-list end

      ; A cubic curve is a group containing the declaration "cc", the
      ; flags for the curve, an optional tension entry if the tension is
      ; non-default (the default being 0.5) followed by a point-list
      ; in either full or compact format.

    anim-curve-group               = begin anim-cubic-curve wsp "idem" end
    anim-curve-group               = begin anim-cubic-curve wsp anim-cubic-curve end

      ; An AnimCurveGroup is a group containing exactly two cubic curves.
      ; The first of these is always specified in full, and is the main
      ; curve.  The second of these is the feather, which is specified as
      ; an offset to the main curve (or rather, the 'absolute' points on the main
      ; become offsets to the corresponding ones, whereas the tangents,
      ; which were offsets from those absolute points on the main curve, become
      ; offsets from the absolute points on the feather.
      ;
      ; The feather curve can be replaced simply with "idem", which means
      ; that the feather is identical to the main curve: all the absolute offsets
      ; are zero, and the tangents are the same.

    anim-curve-group-views-entry   = view-name wsp anim-curve-group

    anim-curve-group-views         = anim-curve-group
    anim-curve-group-views         =/ begin "v" anim-curve-group-views-entry 0*(wsp anim-curve-group-views-entry) end

    anim-node-curve-type           = "bezier" / "bspline" / "catmullrom"

    anim-node-name                 = string

    anim-node-flag                 = int

    anim-transform                 = begin "t" wsp anim-curve-views 1*(wsp anim-curve-views) end
    anim-transform                 =/ begin "tx" wsp key-times-list anim-curve-timeless 1*(wsp anim-curve-timeless) end

     ; An AnimTransform consists of a bunch of animations for each transform curve
     ; these are in order - the pivot point (xyz), the translation (xyz), the scale (xyz),
     ; the rotation (xyz), the skew (xyz), the extra translation (xyz), the skew order;
     ; and then a 4x4 extra matrix.  These default to 0, except for the scale, which
     ; defaults to (1, 1, 1), and the matrix, which defaults to the identity matrix.
     ; any fields not present are the default.
     ;
     ; Transform and rotation orders are fixed, as there is no way of adjusting them
     ; in the UI, and therefore do not appear in the file format.  skew order is
     ; 0 = xy, 1 = yx

    anim-curve-group-node          = begin "curvegroup" wsp anim-node-name wsp anim-node-flag wsp anim-node-curve-type wsp anim-curve-group-views wsp anim-transform wsp anim-attributes end

      ; An AnimCurveGroupNode is a group containing a declaration of its
      ; type, a node name, a flag, a curve type, a curve groups list (which
      ; might contain one curve group or one for several diffferent view),
      ; and then a transform and an attributes.
      ;
      ; The default attributes are as follows
      ;    0   : ro go bo ao bm inv mbo mbsot mbso fx fy ft src stx sy str sr sskx
      ;          ssky sso stot sto sv sb ltt tt pt
      ;    1   : vis r g b a opc mb fo ff ssx ssy sf nv view1 ltn ltm
      ;    0.5 : mbs
      ;    240 : spy
      ;    320 : spx

    anim-curve-node                = begin "cubiccurve" wsp anim-node-name wsp anim-node-flag wsp anim-node-curve-type wsp anim-cubic-curve wsp anim-transform wsp anim-attributes end

      ; An AnimCurveNode is similar to the AnimCurveGroupNode, except that it only
      ; contains one curve, and that this cannot be split. (the attributes and transforms
      ; can be split)
      ;
      ; The default attributes are as follows
      ;    0    : bu bm ds dh bt inv src stx sty str sr sskx ssky sso sb
      ;           stot sto sv ltt tt ws ep1 ep2 ep3 nv1 view1
      ;    0.05 : bsp
      ;    0.2  : h
      ;    1    : vis r g b a ro go bo ao opc dt ssx ssy sf ltn ltm we
      ;           cookie hard_boundary boundary ab
      ;    25   : bs
      ;    240  : spy
      ;    320  : spx

    anim-node                      = anim-curve-group-node / anim-curve-node / anim-layer-node

      ; An AnimNode can be either a CurveGroup, a CubicCurve or a Layer.
      ;
      ; Which is distinguished by the first keyword inside the group.

    anim-node-list                 = [anim-node 1*(wsp anim-node)]

    anim-layer-node                = begin "layer" wsp anim-node-name wsp begin "f" wsp anim-node-flag end wsp anim-transform wsp anim-node-list end

      ; A Layer node.  This contains a name, some flags, a transform, and then some more nodes.
      ;
      ; The default attributes are as follows
      ;   0     : fx fy pt
      ;   0.5   : mbs
      ;   1     : vis opc mbo mb fo ff warp

    anim-tree-version              = float

    anim-tree-version-entry        = begin "v" wsp anim-tree-version end

    anim-tree-flag-entry           = begin "f" wsp flag end

    anim-tree-root-entry           = begin "n" anim-layer-node end

    anim-tree                      = begin anim-tree-version-entry wsp anim-tree-flag-entry wsp anim-tree-root-entry end

## Floating point format

Floating point values are stored in binary encoded format (‘x01234567’), you can use the following code to convert between the two:

Values of 0.0f and 1.0f (zero and one) are special cased and stored just as ‘0’ or ‘1’.

From floating point to binary encoded:

    std::string toString(float fltValue)
    {
      static const char* hexDigits = "0123456789abcdef";

      unsigned int value = *reinterpret_cast<unsigned int*>(&fltValue);

      char buf[10];

      buf[9] = '\0';
      buf[8] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[7] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[6] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[5] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[4] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[3] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[2] = hexDigits[(value & 0xf)];
      value >>= 4;
      buf[1] = hexDigits[(value & 0xf)];
      buf[0] = 'x';

      return std::string(buf);
    }

From binary encoding to floating point:

    float toFloat(const char* str) {
      int value = 0;
      sscanf(str, "x%x", &value);
      return *reinterpret_cast<float*>(&value);
    }

## Layers

Layers can contain other layers or curve groups

## Curve Groups

Curve groups specify the actual curve data for both Bezier and B-Spline curves.

There’s normally two curves in a curve group; the main curve and a feather curve (which can be the same as the main curve, unless the feather has been dragged out.)

SplineWarp curves only contain a main curve.

## Keyframes and Animation

Keyframes are defined within a curvegroup in a {px ...} block

    {px {key0_time key1_time ...}
      {
        {a attribute_name {attribute_value_at_key0}}
        {control_point_position_at_key0}
      }
      {
        {a attribute_name {attribute_value_at_key1}}
        {control_point_positions_at_key1}
      }

      #...
    }

## Flags

Flag | Binary | Bit shift
--- | --- | ---
eBreakFlag | 000000000000000000000001 | (1<<0)
eTangentLengthLockFlag | 000000000000000000000010 | (1<<1)
eKeySelectedFlag | 000000000000000000000100 | (1<<2)
eLeftTangentSelectedFlag | 000000000000000000001000 | (1<<3)
eRightTangentSelectedFlag | 000000000000000000010000 | (1<<4)
eOpenFlag | 000000000000000000100000 | (1<<5)
eSelectedFlag | 000000000000000001000000 | (1<<6)
eActiveFlag | 000000000000000010000000 | (1<<7)
eVisibleFlag | 000000000000000100000000 | (1<<8)
eRenderableFlag | 000000000000001000000000 | (1<<9)
eLockedFlag | 000000000000010000000000 | (1<<10)
ePressureInZFlag | 000000000000100000000000 | (1<<11)
eNukeAnimCurveEvalFlag | 000000000001000000000000 | (1<<12)
eRelativeTangentFlag | 000000000010000000000000 | (1<<13)

## Attribute Names

Attribute name | script key | Notes
--- | --- | ---
kRedAttribute | r | Colour
kGreenAttribute | g |
kBlueAttribute | b |
kAlphaAttribute | a |
kFeatherOnAttribute | fo | Feather on/off
kFeatherXAttribute | fx | Relative X coordinate
kFeatherYAttribute | fy | Relative Y coordinate
kFeatherFallOffAttribute | ff |
kFeatherTypeAttribute | ft |
kBrushSizeAttribute | bs | RotoPaint: Brush size
kBrushSpacingAttribute | bsp | RotoPaint: Brush spacing
kOpacityAttribute | opc | Opacity
kHardnessAttribute | h |
kSourceAttribute | src |
kBlendingModeAttribute | bm |
kBrushTypeAttribute | bt | RotoPaint: Brush type
kBuildUpAttribute | bu | RotoPaint
kDynamicTransparencyAttribute | dt |
kDynamicSizeAttribute | ds |
kDynamicHardnessAttribute | dh |
kViewAttribute | view |
kNumberOfViewsAttribute | nv |
kInvertedAttribute | inv |
kMotionBlurOnAttribute | mbo | Motion blur
kMotionBlurAttribute | mb |
kMotionBlurShutterAttribute | mbs |
kMotionBlurShutterOffsetTypeAttribute | mbsot |
kMotionBlurShutterOffsetAttribute | mbso |
kSourceTranslateXAttribute | stx |
kSourceTranslateYAttribute | sty |
kSourceTranslateRoundAttribute | str |
kSourceRotateAttribute | sr |
kSourceScaleXAttribute | ssx |
kSourceScaleYAttribute | ssy |
kSourceSkewXAttribute | sskx |
kSourceSkewYAttribute | ssky |
kSourceSkewOrderAttribute | sso |
kSourcePivotPointXAttribute | spx |
kSourcePivotPointYAttribute | spy |
kSourceTimeOffsetTypeAttribute | stot |
kSourceTimeOffsetAttribute | sto |
kSourceFilterAttribute | sf |
kSourceBlackOutsideAttribute | sb |
kSourceViewAttribute | sv |
kLifeTimeNAttribute | ltn | Life time start
kLifeTimeMAttribute | ltm | Life time end
kLifeTimeTypeAttribute | ltt |
kWriteOnStartAttribute | ws |
kWriteOnEndAttribute | we |
kRedOverlayAttribute | ro |
kGreenOverlayAttribute | go |
kBlueOverlayAttribute | bo |
kAlphaOverlayAttribute | ao |
kEffectParameter1Attribute | ep1 |
kEffectParameter2Attribute | ep2 |
kEffectParameter3Attribute | ep3 |
kToolTypeAttribute | tt |
kPlanarTrackLayerAttribute | pt |
kVisibleAttribute | vis |
kTensionAttribute | t |
kRepeatAttribute | rp |
kTensionExponentAttribute | te |
kCutoutAttribute | hard_boundary | SplineWarp only
kBoundaryAttribute | boundary | SplineWarp only
kWarpAttribute | warp | SplineWarp only
kMixAttribute | mix | SplineWarp only
kABAttribute | ab | SplineWarp only - whether the curve is in A or B
kCookieCutAttribute | cookie | SplineWarp only
kAnimCurveKeyframeRLE | r | Run-length encoding for key frames (as value, length pairs)

### Navigation

- index
- next |
- previous |
- NDK Dev Guide »
- Advanced »