Dev:Source/Modifiers/Stack/Implementation
Overview
This page documents the implementation of Blender's modifier stack. See also this page about the modifier stack upgrade undertaken as part of Google's Summer of Code 2006.
Basic Operation
The modifier stack is called by Blender whenever an object's final mesh is needed (for drawing in the user interface, rendering, exporting, etc.). The main functions which take care of evaluating the modifier stack are mesh_calc_modifiers (called when in object mode) and editmesh_calc_modifiers (called when in edit mode). The modifier stack is stored in the Object structure as a linked list of ModifierData structures.
These functions follow a simple procedure to evaluate the modifier stack:
- Create a DerivedMesh from the base mesh
- Call each modifier in turn, passing it the current DerivedMesh (which will be the result of the previous modifier)
The DerivedMesh structure is used to pass mesh data from one modifier to the next, as well as to cache results at certain points along the stack. This procedure is illustrated in (Modifier Stack Procedure). Modifiers which only deform the mesh without changing its topology are only passed the vertex coordinates from the mesh, but the principle is the same.
DerivedMesh
The DerivedMesh structure used to pass data between modifiers is documented at BlenderDev/BlenderArchitecture/DerivedMesh.
Modifier API
The modifier stack API is documented at BlenderDev/ModifierStack/API_Reference.
Entry Points
The API functions which do the main work of each modifier are the deformVerts(), deformVertsEM(), applyModifier() and applyModiferEM() functions. These functions are called from the following places:
- source/blender/blenkernel/intern/DerivedMesh.c
-
- mesh_calc_modifiers() (calls deformVerts(), applyModifier())
- mesh_create_derived_for_modifier() (calls deformVerts(), applyModifier())
- editmesh_calc_modifiers() (calls deformVertsEM(), applyModifierEM())
- source/blender/blenkernel/intern/displist.c
-
- curve_calc_modifiers_pre() (calls deformVerts())
- curve_calc_modifiers_post() (calls deformVerts())
- source/blender/blenkernel/intern/lattice.c
-
- lattice_calc_modifiers() (calls deformVerts())
- source/blender/src/buttons_editing.c
-
- modifiers_applyModifier() (calls deformVerts())
These relationships are illustrated in (Modifier API):
mesh_calc_modifiers()
mesh_calc_modifiers() does the following:
- Performs some special-case handling (e.g. for fluidsim objects).
- Applies all the deform-only modifiers at the start of the modifier list (i.e. up to the first non-deform modifier) and caches the result if desired. This step passes data between modifiers as an array of vertex coordinates.
- Applies the remaining modifiers and returns the result as a DerivedMesh structure. This step passes data between modifiers as either an array of vertex coordinates (for deform-only modifiers) or a DerivedMesh structure (for all other modifier types).
The mesh_calc_modifiers() function is called from several places, all in DerivedMesh.c:
- mesh_build_data(), which in turn is called from DerivedMesh.c:mesh_get_derived_deform() and DerivedMesh.c:mesh_get_derived_final() (used by many parts of Blender to retrieve post-modifier mesh data as a DerivedMesh structure).
- mesh_create_derived_render(). This function returns the final mesh for use by the renderer (meaning that modifiers use render settings), and is called by source/blender/render/intern/source/convertblender.c:init_render_mesh(). It is also used by the Python API (source/blender/python/api2_2x/Mesh.c:Mesh_getFromObject()) and fluid simulation code (DerivedMesh.c:initElbeemMesh() and DerivedMesh.c:writeBobjgz()).
- mesh_create_derived_no_deform(). This function creates a DerivedMesh with all non-deform modifiers applied.
- mesh_create_derived_no_deform_render() This function creates a DerivedMesh with all non-deform modifiers applied, using render settings for the modifiers which are applied.
mesh_create_derived_for_modifier()
This function is used by the modifiers_applyModifier() function. It returns a DerivedMesh containing the result of applying the given modifier to the given mesh.
editmesh_calc_modifiers()
This function is used by the editmesh_build_data() function. It performs the same function as mesh_calc_modifiers for editmesh data.
curve_calc_modifiers_pre()
This function calculates the result of applying all modifiers up to and including the last softbody or hook modifier to a given curve object. It is used by the makeDispListSurf() and makeDispListCurveTypes() functions in source/blender/blenkernel/intern/displist.c.
curve_calc_modifiers_post()
This function calculates the result of applying all modifiers after the last softbody or hook modifier to a given curve object. It is used by the makeDispListSurf() and makeDispListCurveTypes() functions in source/blender/blenkernel/intern/displist.c.
lattice_calc_modifiers()
This function calculates the result of applying all modifiers to the given Lattice object. It is used by the object_handle_update() function in source/blender/blenkernel/intern/object.c.
modifiers_applyModifier()
This function applies a modifier to an object permanently. It is called when a modifier's "Apply" button is pressed in the modifier panel.