Introduction
When grease pencil was first introduced to Blender back in 2008(?) by Joshua Leung it was designed around drawing annotations into the viewport. Over a decade later, the community has built a feature-rich 2D animation tool out of the initial draft of grease pencil. Today, there are some challenges and limitations that we face with how grease pencil is structured. I’d like to summarize the issues and propose a way forward.
Current Code Related Problems
- Inefficient data structures
- Layers, Frames and Strokes are stored in linked-lists making them very slow to search and iterate through.
- Large tree-like hierarchy: GPdata → Layers → Frames → Strokes → Point
- E.g. to access a point, one needs to search through all the levels above to get to it.
- Grease Pencil is separated from the rest of Blender. Integration with other modules is hard.
- Some examples are:
- Grease Pencil modifiers
- Grease Pencil materials (will change with upcoming EEVEE rewrite)
- Grease Pencil dopesheet
- More internal examples:
- Grease Pencil modes
- Grease Pencil brush settings (might be necessary)
- Some examples are:
- A large portion of the grease pencil code base is very old and also very verbose (not an issue exclusive to grease pencil in Blender of course).
- It gets harder and harder to make bigger changes
- New developers have a hard time contributing
Proposal
For the last couple of weeks I have been working together with the Grease Pencil module (Antonio, Daniel, Matias) as well as Hans (Geometry Nodes developer) and Amélie (Developer at Les Fées Spéciales) to work on a new proposal for grease pencil.
The main goals of this proposal are to solve the issues mentioned above and also open the door for features that are currently very hard to implement.
Here is a quick summary:
- Move to C++ and a RAII idiom.
- Use two separate arrays to store layers and frames.
- Use
CurvesGeometry
to store the strokes in a frame. - Make use of attributes to store radius, opacity, vertex color, etc.
(For more details, take a look at the demo/test implementation.)
Some of the new possibilities with this proposal:
- Overall improved performance (e.g. copy-on-write).
- Grease Pencil fills with holes.
- Idea would be to use an attribute on strokes to group them and then pass the whole group to the triangulation algorithm.
- This could enable: boolean operation on fills, boolean eraser, etc.
- Layer groups.
- Stroke types (default: poly, but could also use e.g. bézier type).
- Easier integration into Geometry Nodes (because the core structure would be based around the same as e.g. Curves).
- More readable and concise code.
Test Implementation
To better understand how the new grease pencil structures could look like, how we would work with them, and how they could perform I created a branch gpencil-new-data-proposal
that implements a test file with the new proposed structures. They are:
-
blender/source/blender/blenkernel/intern/gpencil_new_proposal_test.cc
and blender/source/blender/blenkernel/intern/gpencil_new_proposal.hh
Feedback on the code would be greatly appreciated!
Here are some first performance numbers that came out of this test:
Duplicate GP data-block
Layers: 10, Frames: 5K, Strokes: 500K, Points: 50M
New structure: 205ms
Old structure: 1410ms
Note: Since the new structure is still missing parts of the old structure, take these numbers with a grain of salt.
Discussion
This proposal would be a major rewrite of course. There is a good chance it will break python compatibility, etc. We would like to get opinions/suggestions/concerns from other developers on this.
Note: This thread is not meant for user feedback. Only for development related discussions on the proposal!