Tutorial: Vector Model Description

Vector Model Description

This tutorial explains how the drawings are structured within Harmony.

Arts

A vector drawing has four layers named arts. In the user interface, we refer to them as Underlay, Colour, Line and Overlay Arts. They each have a numeric index.

 0: Underlay
 1: Colour
 2: Line
 3: Overlay

These arts are rendered in this order when compositing which means the Underlay is under everything and the Overlay is on top.

Layers

Each of the art layer can have any number of drawing layers. Please note that the layers of the Harmony drawings are planar which means that each of their strokes cannot have intersections with itself or any other stroke in the layer.

Here is an example of a planar layer.

Here is an example of a non-planar layer. This can never happen in Harmony.

Do not worry, the scripting API users do not have to make sure that what is created is not self intersecting. If you were to issue a command to create a layer with the strokes of the image above, the system would split the strokes to make them planar.

Colours and contours

Since the drawing layers are planar, the contours can be derived from the strokes and are not really part of the drawing format. So, internally, each stroke has 3 properties:

  • Line style
  • Left colour
  • Right colour

The line style property tells is a stroke is a pencil line with a thickness and a colour or if it is simply a separation between 2 coloured regions or both. Please note, the Left and the Right side of a stroke are the left and the right when looking from the last vertex of the stroke to the first vertex of the stroke.

Let's consider the simple following drawing which consists of a single layer with a rectangle a pencil line and two coloured regions that have been flattened using the Drawing -> Flatten function of Harmony.

The layer of this drawing now has 6 strokes. The strokes are connected to each other using joints. Here is a representation of these joints and strokes. Each vertex of the strokes are represented using a blue dots. Joints are the vertices with an orange contour around them. Strokes are oriented using the arrows. So, their first vertex is at the start of the arrow and the last vertex is at the tip of the arrow.

If we use the Drawing.query.getStrokes() function on the drawing, using the following example script, we could have access to all this stroke information.

var settings = Tools.getToolSettings();
if (settings.currentDrawing) {
  var drawing =  settings.currentDrawing;
  var data = Drawing.query.getStrokes( {
   drawing : drawing,
   art: 2  // The drawing was in the line art
   });
   // data now contains all the drawing strokes and joint information
}

Let's take a look at the content of the data object above.

{
  "layers": [
    {
      "index": 0,
      "shaders": [
         // These are the inside colour if the two coloured contours
         // each coloured contour can have a shaderLeft or shaderRight
         // member set to an index in this list. If shaderLeft or shaderRight
         // is undefined, this means that the stroke has no colour on this side
         // e.g. exterior strokes or unpainted zones.
         // Here, the colorId is the colorId in the palette files.
        { "colorId": "086b2442f4ea2b68" },
        { "colorId": "086b2442f4ea2b66" }
      ],
      // List of joints. Joints have positions and a list of strokes
      // that are ordered counter-clockwise. For example, joint index 2
      // has strokes 5, 1, 4 0 and if you look at the picture above,
      // you see that if you turn around joint J2, you will encounter
      // the strokes in the order above. 
      "joints": [
        {
          "x": -1333.515625,
          "y": 619.421875,
          "strokes": [
            {
              "strokeIndex": 0,
              "vertex": 0
            },
            {
              "strokeIndex": 2,
              "vertex": 1
            }
          ]
        },
        {
          "x": -712.8125,
          "y": -885,
          "strokes": [
            {
              "strokeIndex": 5,
              "vertex": 1
            }
          ]
        },
        {
          "x": -640.671875,
          "y": -337.9375,
          "strokes": [
            {
              "strokeIndex": 5,
              "vertex": 0
            },
            {
              "strokeIndex": 1,
              "vertex": 0
            },
            {
              "strokeIndex": 4,
              "vertex": 1
            },
            {
              "strokeIndex": 0,
              "vertex": 2
            }
          ]
        },
        {
          "x": -514.421875,
          "y": 619.421875,
          "strokes": [
            {
              "strokeIndex": 4,
              "vertex": 0
            },
            {
              "strokeIndex": 1,
              "vertex": 3
            },
            {
              "strokeIndex": 3,
              "vertex": 1
            },
            {
              "strokeIndex": 2,
              "vertex": 0
            }
          ]
        },
        {
          "x": -460.3125,
          "y": 1029.71875,
          "strokes": [
            {
              "strokeIndex": 3,
              "vertex": 0
            }
          ]
        }
      ],
      // Pencil lines are attached to thickness paths
      "thicknessPaths": [
        {
          "minThickness": 7.100006103515625,
          "maxThickness": 7.100006103515625,
          "keys": [
            {
              "t": 0,
              "leftThickness": 7.100006103515625,
              "rightThickness": 7.100006103515625
            },
            {
              "t": 1,
              "leftThickness": 7.100006103515625,
              "rightThickness": 7.100006103515625
            }
          ]
        },
        {
          "minThickness": 7.100006103515625,
          "maxThickness": 7.100006103515625,
          "keys": [
            {
              "t": 0,
              "leftThickness": 7.100006103515625,
              "rightThickness": 7.100006103515625
            },
            {
              "t": 1,
              "leftThickness": 7.100006103515625,
              "rightThickness": 7.100006103515625
            }
          ]
        }
      ],
      // The list of strokes.
      // Note that the strokes have a fromJoint and a toJoin
      // to know the direction to traverse them
      // The right and the left of the stroke is the right
      // and the left when looking from the end of the stroke
      // to the begining of the stroke.
      "strokes": [
        {
          "fromJoint": 0,
          "toJoint": 2,
          "path": [
            {
              "x": -1333.515625,
              "y": 619.421875,
              "onCurve": true
            },
            {
              "x": -1333.515625,
              "y": -337.9375,
              "onCurve": true
            },
            {
              "x": -640.671875,
              "y": -337.9375,
              "onCurve": true
            }
          ],
          "numBeziers": 2,
          "closed": false,
          "shaderRight": 0,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 0
          }
        },
        {
          "fromJoint": 2,
          "toJoint": 3,
          "path": [
            {
              "x": -640.671875,
              "y": -337.9375,
              "onCurve": true
            },
            {
              "x": 223.515625,
              "y": -337.9375,
              "onCurve": true
            },
            {
              "x": 223.515625,
              "y": 619.421875,
              "onCurve": true
            },
            {
              "x": -514.421875,
              "y": 619.421875,
              "onCurve": true
            }
          ],
          "numBeziers": 3,
          "closed": false,
          "shaderRight": 1,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 0
          }
        },
        {
          "fromJoint": 3,
          "toJoint": 0,
          "path": [
            {
              "x": -514.421875,
              "y": 619.421875,
              "onCurve": true
            },
            {
              "x": -1333.515625,
              "y": 619.421875,
              "onCurve": true
            }
          ],
          "numBeziers": 1,
          "closed": false,
          "shaderRight": 0,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 0
          }
        },
        {
          "fromJoint": 4,
          "toJoint": 3,
          "path": [
            {
              "x": -460.3125,
              "y": 1029.71875,
              "onCurve": true
            },
            {
              "x": -514.421875,
              "y": 619.421875,
              "onCurve": true
            }
          ],
          "numBeziers": 1,
          "closed": false,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 1
          }
        },
        {
          "fromJoint": 3,
          "toJoint": 2,
          "path": [
            {
              "x": -514.421875,
              "y": 619.421875,
              "onCurve": true
            },
            {
              "x": -640.671875,
              "y": -337.9375,
              "onCurve": true
            }
          ],
          "numBeziers": 1,
          "closed": false,
          "shaderLeft": 0,
          "shaderRight": 1,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 1
          }
        },
        {
          "fromJoint": 2,
          "toJoint": 1,
          "path": [
            {
              "x": -640.671875,
              "y": -337.9375,
              "onCurve": true
            },
            {
              "x": -712.8125,
              "y": -885,
              "onCurve": true
            }
          ],
          "numBeziers": 1,
          "closed": false,
          "pencilColorId": "086b2442f4ea2b62",
          "thickness": {
            "minThickness": 7.100006103515625,
            "maxThickness": 7.100006103515625,
            "thicknessPath": 1
          }
        }
      ]
    }
  ],
  "drawing": {
    "drawingId": "36",
    "elementId": 2,
    "projectId": "08e1332e957cbf88",
    "isValid": true
  },
  "art": 2
}