Note: Mention that I'll be able to maintain and improve the system further after the SoC period!!
1.0 Name
Joseph Eagar
2.0 Contact Info
joeedh@gmail.com
irc://irc.freenode.net/blendercoder nick joeedh
3.0 Introduction
Blender's mesh system has been in need of a refactor for years. As part of this project, I propose
to rewrite the modifier system to implement a new DerivedMesh system. This new DerivedMesh system
will solve many of the design issues the current DerivedMesh (and in fact the mesh system in
general) suffers from. As an immediate benefit to users, the modifier system will become node-based. This new system will be written in addition to and on top of the old DerivedMesh, reusing as much of the old DerivedMesh as possible.
4.0 Motivations
The modifier stack currently provides very little mesh support for modifiers, most of which are
expected to implement their own set of mesh utility functions. Non-deformation modifiers must also
have separate versions for editmode and object mode, or else use an expensive conversion option.
Most of these issues are a result of the current state of blender's mesh system in general, and
can be solved by creating a new DerivedMesh interface.
Blender's mesh system suffers from a variety of issues. The system has no adjacency support, and
only supports quads/triangles. Triangle support is done via a hack that often causes issues with
per-face-vertex data such as UVs. The memory management is done differently when editing a mesh in
edit mode, which has resulted in a lot of awkwardness in the modifier system.
Since rewriting all of blender's mesh system would be outside the scope of a SoC project, the
refactoring will be limited to reimplementing the modifier system. Modifiers will become
node-based, and have access to many more mesh utility functions (such as remove doubles (split
into two functions, find doubles and weld verts), extrude, etc, all part of the new DerivedMesh
interface.
5.0 Theory
5.1 Rewrite the Modifier Stack
Ultimately the purpose of this project is to advance the mesh refactor while providing immediate
benefits to users. To this end, the project will be limited to rewriting the modifier stack. In
many ways, the modifier stack will become far more advanced then the rest of the mesh code.
5.2 Node-Based Modifiers
Since the modifier system must be redone anyway, the modifier stack will become node-based (this
should only be a little more difficult then simply implementing a new stack-based API). The
existing bNode system will be reused for this purpose.
5.3 A new DerivedMesh
A new DerivedMesh implementation is planned. Several key points of its design has already been
worked out. Specifically:
* The system will be backwards-compatible with the old DerivedMesh, and will reuse as many interfaces as possible.
* This new interface will not make assumptions about how data is stored in the back-end:
o The new DerivedMesh interface will not be limited in the number of verts per faces. So
backends will be allowed to support ngons.
o Some operations will not even assume the backend is a mesh, allowing for e.g. better
integration of curves and surfaces into the modifier stack.
* This new DerivedMesh must require mesh kernels to implement a set of simple operations,
though not as many as typical boundary representations.
* Users of DerivedMesh must be able to query exactly which operations are supported. This is
important, as some DerivedMesh code may even be reusable on non-mesh objects (such as an
array modifier on a curve).
* On a high-level, mesh kernels must implement a specific interface to access mesh data, via
special iterators that also act as containers for data. This will be in addition to whatever
other APIs the mesh kernel may have.
* Reference to mesh elements (e.g. verts, edges, faces, face-vertices) will be done using a
generic intptr_t that the back-ends can use to store either an index (preferred) or a
pointer if they must.
* There will be a system to convert between backends. For example, a loop subsurf modifier
might require a triangle-optimized backend. And some modifiers and tools will require a
BMesh backend.
6.0 Details of the New Node-based Modifier System
6.1 Advantages of the system
Having node-based modifiers would be a new and exciting paradigm for Blender.
Node systems have the advantage of allowing multiple roots in the execution
graph, and for the execution branches to grow back together (unlike a stack
or a tree form).
Practically, this results in a more flexible system. One single mesh input
could drive multiple modifiers. Modifiers could be blended together in
a configurable way with special blend nodes.
The priority for the SoC period is to port all current modifiers to the new
system, as well as implement the nodes listed in 6.2. In addition, the
following nodes will be created if time permits:
* UV Unwrap node
A UV Unwrap node, supporting all UV unwrap modes.
* Spherical effectors (e.g. a "bulge" modifier that bulges meshes at where an object is)
Riggers use these as part of rough muscle simulator setups.
6.2 List of Nodes
The following is a rough list of what would be desired in a complete node
modifier system. The nodes in this list will be completed within the SoC period.
The list will change to take user feedback into account.
The following node socket types will be defined: Color, Value, Vector3, Vector4
and Matrix.
6.2.1 Input nodes
* Mesh input - Inputs: None; Outputs: Mesh
Inputs a mesh into the node tree
* Object input - Inputs: None; Outputs: Mesh, Matrix
Inputs from an object and output a mesh (if needed
by the graph) and a matrix representing the object's
transform.
* Color input
* Vector input - Outputs: Vector
A four-component vector
* Matrix - Inputs: Vector, Vector, Vector, Vector; Outputs: Matrix
A generic matrix input node, that takes either three or four vectors
(depending on whether the user desires a 3x3 or 4x4 matrix) as inputs.
The vectors represent rows in the final matrix.
6.2.2 Math Nodes
* Matrix Math (multiply, invert, transpose) - Inputs: Matrix, Matrix; Outputs: Matrix
* Vector-Matrix Math (multiply, multiply with inverse) - Inputs: Matrix, Vector; Outputs: Vector
* Vector Math (multiply, subtract, add, divide, cross product)
Inputs: Vector, Vector; Outputs: Vector, Value (dot product result)
6.2.3 Transform Nodes
* Matrix Transform - Inputs: Matrix, Mesh; Outputs: Mesh
* Generic Transform (rotate/translate/scale/shear/warp)
Inputs: Vector(rotate), Vector(scale), Vector(translate); Outputs: Mesh
* Mesh Blend node
A simple blending node to blend between two deformed meshes. Note that
both meshes would have to have to have identical vertex ordering, and also
an identical number of verts.
6.2.4 Modifiers
* Triangulation node - Inputs: Mesh; Outputs: Mesh
* Mesh Concatenation - Inputs: Mesh, Matrix, Mesh, Matrix; Outputs: Mesh
This node would concatenate two meshes together. Each mesh would be transformed
by the matrix input following its input.
* All the currently implemented modifiers
6.3 Additional Node Ideas
The following is a list of additional node ideas that would most likely
be impractical to implement during the SoC period, but are nonetheless
usefull.
* Pynodes
Pynodes would be used to implement python-driven modifiers
* Cut
This node would cut a mesh with a plane and remove all geometry on one side
* Boolean
A generic CSG node
* An improved hook modifier with weight control and control
over the falloff curve.
7.0 Deliverables
The main purpose of this project is to refactor DerivedMesh. As this is a large project, it will be
done in an incremental way. As this may be quite time consuming, the main goal is to complete a
basic implementation and refactor the modifier system to use it.
Specifically, the following schedule is proposed:
* (Week 1) Collect design requirements and design the new DerivedMesh system.
* (Weeks 2-3) Write out a basic implementation of the new system, wrapping BMesh, EditMesh and
Mesh.
* (Week 4) Write support for customdata in this system.
* (Weeks 5-6) Write a new infrastructure for the modifier system, and implement the subsurf
modifier.
* (Week 7) Review the code written thus far, and work out any design issues. A maximum of 4
days would be allocated for this.
* (Week 7.4+) Rework the other modifiers to make use of this new system. The rest of the
period would be alotted for this.
8.0 Long- and Short-Term Benefits
The short term benefits would be an increase in the speed of the modifier system, as modifier mesh
data would be cached much more efficiently then is currently done. Modifiers would all support
ngons, allowing (for example) the possibility of finally making use of our subsurf code's internal
ngon support. Interfacing this system with the current fgon implementation will not be difficult.
Node-based modifiers will allow users to create more flexible modifier setups. Users will be able
to animate modifiers via the existing time node. All remaining restrictions as to the order of
modifiers will be removed.
The long-term benefits will greatly affect every aspect of blender's mesh code. Currently,
DerivedMesh is one of the biggest obstacles to completing the planned mesh refactor. The new core
mesh code (BMesh) has already been worked out, yet integrating it with the current DerivedMesh
system has proven to be a great obstacle. Some form of refactoring is needed to allow future
progress of the code. This project will do just that within the scope of the modifier system.
9.0 Bio
I'm a 21 year old student at Northern Arizona University. I previously have done a lot of work on
blender's mesh system, including a half-edge implementation (not used) and helping with Geoffry
Bantle's BMesh project. I initially adapted the current DerivedMesh for BMesh, though later it was
decided to abandon the current DerivedMesh design in favor of a new system.