In this and following several posts I will write about Blender’s modifier system. I expect following questions to be answered:
- How is modifiers’ source code organized in the source tree?
- How is a modifier registered to Blender system?
- Where and when does a modifier operate?
- How are modifiers combined together?
It seems that the last question is too broad. Let me elaborate to make it more specific.
As you know, Blender organizes all modifiers in a stack. Then multiple modifiers can be combined and chained together. Two adjacent modifiers in the stack must agree in a data format so that the processed data from previous modifier can be handed over to the next one. So what is the protocol of data format which is used among different modifiers?
Now let us get started with above questions in mind.
First we start with the function where a modifier is added to an object.
Hover the cursor on the
Array modifier icon from the
Add Modifier menu in the modifiers panel,
you can see the Python code in the pop-up:
This is an operator named
Search this name in the source code you will find the operator registration function
And then you can locate the actual execution function of this operator:
We add a break point in
modifier_add_exec to trace the construction of a modifier.
Now we try to add an
Array modifier and step into the
Information of a modifier is retrieved by calling function
source/blender/blenkernel/intern/modifier.c) on a given
source/blender/makesdna/DNA_modifier_types.h). This information is stored in
source/blender/blenkernel/BKE_modifier.h). You can register your own modifiers by providing informations for them in this file.
A new modifier is constructed in function
source/blender/blenkernel/intern/modifier.c). In this function, a
source/blender/makesdna/DNA_modifier_types.h) is allocated through
Note that a “derived”
ModifierDatais actually allocated here. The allocator uses a structure size recored in
mtivariable in the code), which usually is different from
Arraymodifier, we can see its derived
ModifierDatais named as
ArrayModifierData, which is defined in the file
After that, the modifier gets initialized through
if (mti->initData) mti->initData(md);.
initDatais a function pointer you could set in the
ModifierTypeInfostructure. By stepping into this function you can reach the definition of
Arraymodifier’s initializer, which resides in the file
source/blender/modifiers/intern/MOD_array.c. During the initialization stage, one modifier’s “derived”
In the file
MOD_array.cthere are also many other functions. These functions could be set to the
ModifierTypeInfostructure when you define the modifier.
Along with the file
MOD_array.cthere are many other files with a prefix of
MOD_. These are the sources of other modifiers. They reside in the folder
Speak in the Object-Oriented glossary,
ModifierTypeInfo is the common interface that modifiers should derive from.
Now the definition and construction of a modifier are finished.
In the next part I will dive into the execution code of the