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.