Dev:Source/Modifiers/Stack/API Reference

提供: wiki
< Dev:Source‎ | Modifiers‎ | Stack
2017年4月14日 (金) 11:59時点におけるwiki>Jaggzによる版 (Adding a modifier type)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

Overview

ModifierTypeInfo

The modifier stack accesses modifiers through a standard interface. The interface for each modifier is stored as a set of callback function pointers in a ModifierTypeInfo structure (defined in BKE_modifier.h). There is a static array of these structures (one for each modifier type) accessible through the modifierType_getInfo function defined in modifier.c.

ModifierData

The data for a specific instance of a certain modifier type is stored in a <type>ModifierData structure (e.g. MirrorModifierData for the Mirror modifier), defined in DNA_modifier_types.h. Each <type>ModifierData structure must include, as its first field, a ModifierData structure which contains a type identifier. This type identifier is passed to the modifierType_getInfo function to retrieve a ModifierTypeInfo structure describing the modifier type. Since the ModifierData structure is the first field, any <type>ModifierData pointer can be cast to a ModifierData pointer and used to directly retrieve the type identifier.

Required vs. Optional functions

Some callback functions in ModifierTypeInfo are required, others are optional (these should be set to NULL if not implemented). Additionally, modifiers can be classified as either deforming or non-deforming, which affects which callback functions they are required to implement.

Adding a modifier type

To add a modifier type, the following things must be done (where <type> is the one-word name of the modifier):

  • Add an eModifierType_<type> entry at the end of the ModifierType enum in DNA_modifier_types.h (just before NUM_MODIFIER_TYPES - the position is important to make sure all the other type values stay the same)
  • Add a <type>ModifierData structure definition to DNA_modifier_types.h (following the example of the existing structures and the guidelines in BlenderDev/DNAStructs)
  • Add function definitions to modifier.c. The current convention is to name them <type>Modifier_<functionName>, where <type> is spelt starting with a lowercase letter (e.g. curveModifier_deformVerts).
  • Add a section to the modifierType_getInfo function in modifier.c initialising the ModifierTypeInfo structure for the new modifier (using the INIT_TYPE macro and following the example of the existing sections)
  • RNA wrap the modifier in rna_modifier.c, by adding a function static void rna_def_modifier_<type>(BlenderRNA *brna) similar to other modifiers.
  • Add def <type>(self, layout, ob, md, wide_ui): sections to the DATA_PT_modifiers class in properties_data_modifier.py, following the example of the existing sections.

Required functions

All Modifiers

copyData

 void copyData(ModifierData *''md'', ModifierData *''target'')
Copy instance data for this modifier type. Should copy all user level settings to the target modifier.

Deforming modifiers

deformVerts

 void deformVerts(ModifierData *''md'', struct Object *''ob'',
                  struct DerivedMesh *''derivedData'', float (*''vertexCos'')[3],
                  int ''numVerts'')
Should apply the deformation to the given vertex array.
  • If the deformer requires information from the object it can obtain it from the derivedData argument if non-NULL, and otherwise the ob argument. The derivedData argument should not be changed.

deformVertsEM

 void deformVertsEM(ModifierData *''md'', struct Object *''ob'',
                    struct EditMesh *''editData'', struct DerivedMesh *''derivedData'',
                    float (*''vertexCos'')[3], int ''numVerts'')
Like deformVerts but called during editmode (for modifiers which support editmode).

Non-deforming modifiers

applyModifier

 DerivedMesh *applyModifier(ModifierData *''md'', struct Object *''ob'',
                            struct DerivedMesh *''derivedData'',
                            int ''useRenderParams'', int ''isFinalCalc'')
Should apply the modifier and return a DerivedMesh object (type is dependent on object type).
  • The derivedData argument will always be non-NULL; the modifier should read the mesh data from derivedData instead of the actual object data.
  • The useRenderParams argument indicates if the modifier is being applied in the service of the renderer (which may alter quality settings).
  • The isFinalCalc parameter indicates if the modifier is being calculated for a final result or for something temporary (like orcos). This is a hack at the moment, it is meant so subsurf can know if it is safe to reuse its internal cache.
  • The modifier may reuse the derivedData argument (i.e. return it in modified form), but must not release it.

applyModifierEM

 DerivedMesh *applyModifierEM(ModifierData *''md'', struct Object *''ob'',
                              struct EditMesh *''editData'', struct DerivedMesh *''derivedData'')
Like applyModifier but called during editmode (for modifiers which support editmode).
  • The DerivedMesh that is returned must support the operations that are expected from editmode objects. The same qualifications regarding derivedData apply as for applyModifier.

Optional functions

All Modifiers

initData

 void initData(ModifierData *''md'')
Initialize new instance data for this modifier type. This function should set modifier variables to their default values.

freeData

 void freeData(ModifierData *''md'')
Should free internal modifier data variables. This function should not free the md variable itself.

requiredDataMask

 CustomDataMask requiredDataMask(struct ModifierData *''md'')
Should return a CustomDataMask indicating what data this modifier needs. If (mask & (1 << (layer type))) != 0, this modifier needs that custom data layer. This function's return value can change depending on the modifier's settings.
  • Note that this means extra data (e.g. vertex groups) - it is assumed that all modifiers need mesh data and deform modifiers need vertex coordinates.
  • If this function is not present or it returns 0, it is assumed that no extra data is needed.

isDisabled

 int isDisabled(ModifierData *''md'')
Should return a boolean value indicating if this modifier is able to be calculated based on the modifier data. This is *not* regarding md->flag (that is tested by the system); this just tests if the data validates (for example, a lattice will return false if the lattice object is not defined). If this function is not present, the modifier is assumed to never be disabled.

updateDepgraph

 void updateDepgraph(ModifierData *''md'', struct DagForest *''forest'',
                     struct Object *''ob'', struct DagNode *''obNode'')
Should add the appropriate relations to the dependancy graph depending on the modifier data. These relations are used by Blender to determine when the modifier stack needs to be re-evaluated.

dependsOnTime

 int dependsOnTime(ModifierData *''md'')
Should return true if the modifier needs to be recalculated on time changes. This function is assumed to return false if not present.

foreachObjectLink

 void foreachObjectLink(ModifierData *''md'', struct Object *''ob'',
                        ObjectWalkFunc ''walk'', void *''userData'')
Should call the given walk function with a pointer to each Object pointer that the modifier data stores. This is used for unlinking objects or forwarding object references, and for linking on file load if foreachIDLink is not present.
  • If a modifier stores Object pointers, it should probably implement this function.

foreachIDLink

 void foreachIDLink(ModifierData *''md'', struct Object *''ob'',
                    IDWalkFunc ''walk'', void *''userData'')
Should call the given walk function with a pointer to each ID pointer (i.e. each datablock pointer) that the modifier data stores. This is used for linking on file load and for unlinking datablocks or forwarding datablock references.
  • If this function is not present and foreachObjectLink is, foreachObjectLink will be used.
  • If a modifier stores datablock pointers (including Object pointers), it should probably implement this function.

Enumerations

ModifierTypeType

eModifierTypeType_None

Should not be used, only for None modifier type

eModifierTypeType_OnlyDeform

Modifier only does deformation, implies that modifier type should have a valid deformVerts function. OnlyDeform style modifiers implicitly accept either mesh or CV input but should still declare flags appropriately.

eModifierTypeType_Constructive

eModifierTypeType_Nonconstructive

ModifierTypeFlag

eModifierTypeFlag_AcceptsMesh

eModifierTypeFlag_AcceptsCVs

eModifierTypeFlag_SupportsMapping

eModifierTypeFlag_SupportsEditmode

eModifierTypeFlag_EnableInEditmode

For modifiers that support editmode this determines if the modifier should be enabled by default in editmode. This should only be used by modifiers that are relatively speedy and also generally used in editmode, otherwise let the user enable it by hand.

eModifierTypeFlag_RequiresOriginalData

For modifiers that require original data and so cannot be placed after any non-deformative modifier.


Data types

ObjectWalkFunc

 typedef void (*ObjectWalkFunc)(void *userData, Object *ob, Object **obpoin)
A pointer to a function to be called on each object pointer in the modifier data; passed to forEachObjectLink

IDWalkFunc

 typedef void (*IDWalkFunc)(void *userData, Object *ob, ID **idpoin)
A pointer to a function to be called on each ID pointer in the modifier data; passed to forEachIDLink