Skip to content

Architecture

This document outlines the architecture of Grease Pencil.

Warning

This explains the Grease Pencil v3 architecture. At the time of writing, Grease Pencil v3 is still experimental, but will replace the legacy Grease Pencil eventually. All developments on the legacy Grease Pencil have been stopped.

Grease Pencil ID Data Block

The GreasePencil ID data-block stores the following data fields:

Developers should only rarely have to manipulate these fields directly. Most of the time, it's better to use the Grease Pencil API.

API

The GreasePencil ID data-block offers an API for developers to easily add layers, insert keyframes, create drawings, read/write custom data, etc.

For more details you can check out the functions in struct GreasePencil in DNA_grease_pencil_types.h.

Drawings

A drawing is a static set of strokes (with no layers). You can think of it as a vector image. Drawings are referenced by the keyframes of a layer (see layer animation data).

Internally, drawings are represented as CurvesGeometry. All of the data is stored as attributes.

Internal Attributes

Here are attributes that are used by Grease Pencil.

Name Domain Optional Description
position POINT The positions of the curve points.
radius POINT The radii of the points (in meters). The default radius is 1 cm.
opacity POINT The opacities of the points (0 to 1). The default opacity is 1.
vertex_color POINT The color of the points. This is mixed on top of the base material color based on the alpha. By default, the alpha is 0.
.selection POINT The selection state of the point. True if the point is selected, false otherwise.
cyclic CURVE True for curves that are cyclic and false otherwise. Default is false.
material_index CURVE A material index for this curve. Defaults to the default material.
start_cap CURVE A cap type for the start of the curve. 0 = ROUND, 1 = FLAT. Default is ROUND.
end_cap CURVE A cap type for the end of the curve. 0 = ROUND, 1 = FLAT. Default is ROUND.

Drawing References

Drawing references are drawings that don't contain the actual drawing data, but reference the data from the drawings of another Grease Pencil object.

Layers

In Grease Pencil, a layer allows users to organize their drawings as well as their animation workflow.

For example, one might want to animate a character using multiple layers: one layer is just used to draw the torso, another for the drawings of the head and finally a layer that has all the drawings for the hair. These drawings are referenced by keyframes on the timeline. They form the animation.

Each layer has a separate timeline for its keyframes.

Animation Data

Layers store a mapping that decides what drawing to show starting at which frame and for how long that drawing should be held (keyframes can also be implicitly held). This is the animation data of the layer.

More specifcally, this mapping maps a keyframe to a scene frame. And the keyframe references a drawing by index (see drawings).

TODO

Add diagram for the layer frames mapping (ideally not as an image).

Attributes

Layers can also store custom data. This data is availible on the Grease Pencil data-block using the attribute API. The element index of a layer in an attribute is the bottom-up index in the layer stack (see layer stack ordering).

Layer Tree

Inside the Grease Pencil data-block layers are structured in a tree called the layer tree.

The layer tree is made up of tree nodes. A tree node is either a layer or a layer group.

classDiagram
  class TreeNode {
    +String name
    ...
  }
  class LayerGroup {
    +List~TreeNode~ children
    ...
  }
  class Layer {
    ...
  }
  TreeNode <|-- Layer
  TreeNode <|-- LayerGroup

Only layer groups can contain other nodes. Therefore, layers are always leaf nodes.

Here is an example of what a layer tree might look like:

graph TD
  root --> Layer1
  root --> LayerGroup1
  LayerGroup1 --> Layer2
  LayerGroup1 --> Layer3
  root --> Layer4

In the Grease Pencil data-block there is always a root layer group. This group can be empty.

Layer Stack Ordering

The order of layers is bottom-up, meaning that the first layer is the bottom most layer in the layer stack. In the example above, this would be the layer stack.

graph BT
  Layer1 --> Layer2
  Layer2 --> Layer3
  Layer3 --> Layer4