/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __BKE_MODIFIER_H__ #define __BKE_MODIFIER_H__ /** \file * \ingroup bke */ #include "BKE_customdata.h" #include "BLI_compiler_attrs.h" #include "DNA_modifier_types.h" /* needed for all enum typdefs */ #ifdef __cplusplus extern "C" { #endif struct BMEditMesh; struct CustomData_MeshMasks; struct DepsNodeHandle; struct Depsgraph; struct ID; struct ListBase; struct Main; struct Mesh; struct ModifierData; struct Object; struct Scene; struct bArmature; typedef enum { /* Should not be used, only for None modifier type */ eModifierTypeType_None, /* 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_OnlyDeform, /* Modifier adds geometry. */ eModifierTypeType_Constructive, /* Modifier can add and remove geometry. */ eModifierTypeType_Nonconstructive, /* both deformVerts & applyModifier are valid calls * used for particles modifier that doesn't actually modify the object * unless it's a mesh and can be exploded -> curve can also emit particles */ eModifierTypeType_DeformOrConstruct, /* Like eModifierTypeType_Nonconstructive, but does not affect the geometry * of the object, rather some of its CustomData layers. * E.g. UVProject and WeightVG modifiers. */ eModifierTypeType_NonGeometrical, } ModifierTypeType; typedef enum { eModifierTypeFlag_AcceptsMesh = (1 << 0), eModifierTypeFlag_AcceptsCVs = (1 << 1), eModifierTypeFlag_SupportsMapping = (1 << 2), eModifierTypeFlag_SupportsEditmode = (1 << 3), /* 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_EnableInEditmode = (1 << 4), /* For modifiers that require original data and so cannot * be placed after any non-deformative modifier. */ eModifierTypeFlag_RequiresOriginalData = (1 << 5), /* For modifiers that support pointcache, * so we can check to see if it has files we need to deal with. */ eModifierTypeFlag_UsesPointCache = (1 << 6), /* For physics modifiers, max one per type */ eModifierTypeFlag_Single = (1 << 7), /* Some modifier can't be added manually by user */ eModifierTypeFlag_NoUserAdd = (1 << 8), /* For modifiers that use CD_PREVIEW_MCOL for preview. */ eModifierTypeFlag_UsesPreview = (1 << 9), eModifierTypeFlag_AcceptsLattice = (1 << 10), } ModifierTypeFlag; /* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */ typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag); typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag); typedef void (*TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname); typedef enum ModifierApplyFlag { /** Render time. */ MOD_APPLY_RENDER = 1 << 0, /** Result of evaluation will be cached, so modifier might * want to cache data for quick updates (used by subsurf) */ MOD_APPLY_USECACHE = 1 << 1, /** Modifier evaluated for undeformed texture coordinates */ MOD_APPLY_ORCO = 1 << 2, /** Ignore scene simplification flag and use subdivisions * level set in multires modifier. */ MOD_APPLY_IGNORE_SIMPLIFY = 1 << 3, /** The effect of this modifier will be applied to the base mesh * The modifier itself will be removed from the modifier stack. * This flag can be checked to ignore rendering display data to the mesh. * See `OBJECT_OT_modifier_apply` operator. */ MOD_APPLY_TO_BASE_MESH = 1 << 4, } ModifierApplyFlag; typedef struct ModifierUpdateDepsgraphContext { struct Scene *scene; struct Object *object; struct DepsNodeHandle *node; } ModifierUpdateDepsgraphContext; /* Contains the information for deformXXX and applyXXX functions below that * doesn't change between consecutive modifiers. */ typedef struct ModifierEvalContext { struct Depsgraph *depsgraph; struct Object *object; ModifierApplyFlag flag; } ModifierEvalContext; typedef struct ModifierTypeInfo { /* The user visible name for this modifier */ char name[32]; /* The DNA struct name for the modifier data type, used to * write the DNA data out. */ char structName[32]; /* The size of the modifier data type, used by allocation. */ int structSize; ModifierTypeType type; ModifierTypeFlag flags; /********************* Non-optional functions *********************/ /* Copy instance data for this modifier type. Should copy all user * level settings to the target modifier. * * \param flag: Copying options (see BKE_lib_id.h's LIB_ID_COPY_... flags for more). */ void (*copyData)(const struct ModifierData *md, struct ModifierData *target, const int flag); /********************* Deform modifier functions *********************/ /* Only for deform types, should apply the deformation * to the given vertex array. If the deformer requires information from * the object it can obtain it from the mesh argument if non-NULL, * and otherwise the ob argument. */ void (*deformVerts)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], int numVerts); /* Like deformMatricesEM but called from object mode (for supporting modifiers in sculpt mode) */ void (*deformMatrices)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts); /* Like deformVerts but called during editmode (for supporting modifiers) */ void (*deformVertsEM)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh, float (*vertexCos)[3], int numVerts); /* Set deform matrix per vertex for crazyspace correction */ void (*deformMatricesEM)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts); /********************* Non-deform modifier functions *********************/ /* For non-deform types: apply the modifier and return a mesh object. * * The mesh argument should always be non-NULL; the modifier * should read the object data from the mesh object instead of the * actual object data. * * The modifier may reuse the mesh argument (i.e. return it in * modified form), but must not release it. */ struct Mesh *(*applyModifier)(struct ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *mesh); /********************* Optional functions *********************/ /* Initialize new instance data for this modifier type, this function * should set modifier variables to their default values. * * This function is optional. */ void (*initData)(struct ModifierData *md); /* Should add to passed \a r_cddata_masks the data types that this * modifier needs. If (mask & (1 << (layer type))) != 0, this modifier * needs that custom data layer. It can change required layers * 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, it is assumed that no extra data is needed. * * This function is optional. */ void (*requiredDataMask)(struct Object *ob, struct ModifierData *md, struct CustomData_MeshMasks *r_cddata_masks); /* Free internal modifier data variables, this function should * not free the md variable itself. * * This function is responsible for freeing the runtime data as well. * * This function is optional. */ void (*freeData)(struct ModifierData *md); /* Return a boolean value indicating if this modifier is able to be * calculated based on the modifier data. This is *not* regarding the * md->flag, that is tested by the system, this is just if the data * validates (for example, a lattice will return false if the lattice * object is not defined). * * This function is optional (assumes never disabled if not present). */ bool (*isDisabled)(const struct Scene *scene, struct ModifierData *md, bool userRenderParams); /* Add the appropriate relations to the dependency graph. * * This function is optional. */ void (*updateDepsgraph)(struct ModifierData *md, const ModifierUpdateDepsgraphContext *ctx); /* Should return true if the modifier needs to be recalculated on time * changes. * * This function is optional (assumes false if not present). */ bool (*dependsOnTime)(struct ModifierData *md); /* True when a deform modifier uses normals, the requiredDataMask * cant be used here because that refers to a normal layer whereas * in this case we need to know if the deform modifier uses normals. * * this is needed because applying 2 deform modifiers will give the * second modifier bogus normals. * */ bool (*dependsOnNormals)(struct ModifierData *md); /* Should call the given walk function on with a pointer to each Object * pointer that the modifier data stores. This is used for linking on file * load and for unlinking objects or forwarding object references. * * This function is optional. */ void (*foreachObjectLink)(struct ModifierData *md, struct Object *ob, ObjectWalkFunc walk, void *userData); /* Should call the given walk function with a pointer to each ID * pointer (i.e. each data-block pointer) that the modifier data * stores. This is used for linking on file load and for * unlinking data-blocks or forwarding data-block references. * * This function is optional. If it is not present, foreachObjectLink * will be used. */ void (*foreachIDLink)(struct ModifierData *md, struct Object *ob, IDWalkFunc walk, void *userData); /* Should call the given walk function for each texture that the * modifier data stores. This is used for finding all textures in * the context for the UI. * * This function is optional. If it is not present, it will be * assumed the modifier has no textures. */ void (*foreachTexLink)(struct ModifierData *md, struct Object *ob, TexWalkFunc walk, void *userData); /* Free given run-time data. * * This data is coming from a modifier of the corresponding type, but actual * modifier data is not known here. * * Notes: * - The data itself is to be de-allocated as well. * - This callback is allowed to receive NULL pointer as a data, so it's * more like "ensure the data is freed". */ void (*freeRuntimeData)(void *runtime_data); } ModifierTypeInfo; /* Initialize modifier's global data (type info and some common global storages). */ void BKE_modifier_init(void); const ModifierTypeInfo *modifierType_getInfo(ModifierType type); /* Modifier utility calls, do call through type pointer and return * default values if pointer is optional. */ struct ModifierData *modifier_new(int type); void modifier_free_ex(struct ModifierData *md, const int flag); void modifier_free(struct ModifierData *md); bool modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md); void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target, const int flag); void modifier_copyData(struct ModifierData *md, struct ModifierData *target); void modifier_copyData_ex(struct ModifierData *md, struct ModifierData *target, const int flag); bool modifier_dependsOnTime(struct ModifierData *md); bool modifier_supportsMapping(struct ModifierData *md); bool modifier_supportsCage(struct Scene *scene, struct ModifierData *md); bool modifier_couldBeCage(struct Scene *scene, struct ModifierData *md); bool modifier_isCorrectableDeformed(struct ModifierData *md); bool modifier_isSameTopology(ModifierData *md); bool modifier_isNonGeometrical(ModifierData *md); bool modifier_isEnabled(const struct Scene *scene, struct ModifierData *md, int required_mode); void modifier_setError(struct ModifierData *md, const char *format, ...) ATTR_PRINTF_FORMAT(2, 3); bool modifier_isPreview(struct ModifierData *md); void modifiers_foreachObjectLink(struct Object *ob, ObjectWalkFunc walk, void *userData); void modifiers_foreachIDLink(struct Object *ob, IDWalkFunc walk, void *userData); void modifiers_foreachTexLink(struct Object *ob, TexWalkFunc walk, void *userData); struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type); struct ModifierData *modifiers_findByName(struct Object *ob, const char *name); void modifiers_clearErrors(struct Object *ob); int modifiers_getCageIndex(struct Scene *scene, struct Object *ob, int *r_lastPossibleCageIndex, bool is_virtual); bool modifiers_isModifierEnabled(struct Object *ob, int modifierType); bool modifiers_isSoftbodyEnabled(struct Object *ob); bool modifiers_isClothEnabled(struct Object *ob); bool modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByMeshDeform(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); struct Object *modifiers_isDeformedByCurve(struct Object *ob); bool modifiers_usesMultires(struct Object *ob); bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm); bool modifiers_usesSubsurfFacedots(struct Scene *scene, struct Object *ob); bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); bool modifiers_isPreview(struct Object *ob); typedef struct CDMaskLink { struct CDMaskLink *next; struct CustomData_MeshMasks mask; } CDMaskLink; /* Calculates and returns a linked list of CustomData_MeshMasks and modified * final datamask, indicating the data required by each modifier in the stack * pointed to by md for correct evaluation, assuming the data indicated by * final_datamask is required at the end of the stack. */ struct CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, struct Object *ob, struct ModifierData *md, struct CustomData_MeshMasks *final_datamask, int required_mode, ModifierData *previewmd, const struct CustomData_MeshMasks *previewmask); struct ModifierData *modifiers_getLastPreview(struct Scene *scene, struct ModifierData *md, int required_mode); typedef struct VirtualModifierData { ArmatureModifierData amd; CurveModifierData cmd; LatticeModifierData lmd; ShapeKeyModifierData smd; } VirtualModifierData; struct ModifierData *modifiers_getVirtualModifierList(const struct Object *ob, struct VirtualModifierData *data); /* ensure modifier correctness when changing ob->data */ void test_object_modifiers(struct Object *ob); /* here for do_versions */ void modifier_mdef_compact_influences(struct ModifierData *md); void modifier_path_init(char *path, int path_maxlen, const char *name); const char *modifier_path_relbase(struct Main *bmain, struct Object *ob); const char *modifier_path_relbase_from_global(struct Object *ob); /* Accessors of original/evaluated modifiers. */ /* For a given modifier data, get corresponding original one. * If the modifier data is already original, return it as-is. */ struct ModifierData *modifier_get_original(struct ModifierData *md); struct ModifierData *modifier_get_evaluated(struct Depsgraph *depsgraph, struct Object *object, struct ModifierData *md); /* wrappers for modifier callbacks that ensure valid normals */ struct Mesh *modwrap_applyModifier(ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *me); void modwrap_deformVerts(ModifierData *md, const struct ModifierEvalContext *ctx, struct Mesh *me, float (*vertexCos)[3], int numVerts); void modwrap_deformVertsEM(ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *em, struct Mesh *me, float (*vertexCos)[3], int numVerts); struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval, const bool get_cage_mesh); #ifdef __cplusplus } #endif #endif