diff options
Diffstat (limited to 'source/blender/blenkernel/intern/modifier.c')
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 365 |
1 files changed, 346 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index ce04f3c31e2..6722ed2aab1 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -46,6 +46,7 @@ #include "MEM_guardedalloc.h" #include "DNA_armature_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "BLI_utildefines.h" @@ -58,9 +59,11 @@ #include "BLT_translation.h" #include "BKE_appdir.h" +#include "BKE_cdderivedmesh.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_library_query.h" +#include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_DerivedMesh.h" @@ -69,6 +72,8 @@ #include "BKE_main.h" /* end */ +#include "DEG_depsgraph.h" + #include "MOD_modifiertypes.h" static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL}; @@ -679,7 +684,7 @@ bool modifiers_usesArmature(Object *ob, bArmature *arm) bool modifier_isCorrectableDeformed(ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); - return (mti->deformMatricesEM != NULL); + return (mti->deformMatricesEM != NULL) || (mti->deformMatricesEM_DM != NULL); } bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob) @@ -688,9 +693,9 @@ bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); int required_mode = eModifierMode_Realtime; - if (ob->mode == OB_MODE_EDIT) + if (ob->mode == OB_MODE_EDIT) { required_mode |= eModifierMode_Editmode; - + } for (; md; md = md->next) { if (!modifier_isEnabled(scene, md, required_mode)) { /* pass */ @@ -784,9 +789,8 @@ void modifier_path_init(char *path, int path_maxlen, const char *name) /* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */ struct DerivedMesh *modwrap_applyModifier( - ModifierData *md, Object *ob, - struct DerivedMesh *dm, - ModifierApplyFlag flag) + ModifierData *md, const ModifierEvalContext *ctx, + struct DerivedMesh *dm) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); @@ -794,14 +798,12 @@ struct DerivedMesh *modwrap_applyModifier( if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - return mti->applyModifier(md, ob, dm, flag); + return modifier_applyModifier_DM_deprecated(md, ctx, dm); } struct DerivedMesh *modwrap_applyModifierEM( - ModifierData *md, Object *ob, - struct BMEditMesh *em, - DerivedMesh *dm, - ModifierApplyFlag flag) + ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *em, DerivedMesh *dm) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); @@ -809,14 +811,12 @@ struct DerivedMesh *modwrap_applyModifierEM( if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - return mti->applyModifierEM(md, ob, em, dm, flag); + return modifier_applyModifierEM_DM_deprecated(md, ctx, em, dm); } void modwrap_deformVerts( - ModifierData *md, Object *ob, - DerivedMesh *dm, - float (*vertexCos)[3], int numVerts, - ModifierApplyFlag flag) + ModifierData *md, const ModifierEvalContext *ctx, + DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); @@ -824,11 +824,11 @@ void modwrap_deformVerts( if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag); + modifier_deformVerts_DM_deprecated(md, ctx, dm, vertexCos, numVerts); } void modwrap_deformVertsEM( - ModifierData *md, Object *ob, + ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { @@ -838,6 +838,333 @@ void modwrap_deformVertsEM( if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } - mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts); + modifier_deformVertsEM_DM_deprecated(md, ctx, em, dm, vertexCos, numVerts); } /* end modifier callback wrappers */ + + +/* wrappers for modifier callbacks that accept Mesh and select the proper implementation + * depending on if the modifier has been ported to Mesh or is still using DerivedMesh + */ + +void modifier_deformVerts(struct ModifierData *md, const ModifierEvalContext *ctx, + struct Mesh *mesh, + float (*vertexCos)[3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformVerts) { + mti->deformVerts(md, ctx, mesh, vertexCos, numVerts); + } + else { + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } + + mti->deformVerts_DM(md, ctx, dm, vertexCos, numVerts); + + if (dm) { + dm->release(dm); + } + } +} + +void modifier_deformMatrices(struct ModifierData *md, const ModifierEvalContext *ctx, + struct Mesh *mesh, + float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformMatrices) { + mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts); + } + else { + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } + + mti->deformMatrices_DM(md, ctx, dm, vertexCos, defMats, numVerts); + + if (dm) { + dm->release(dm); + } + } +} + +void modifier_deformVertsEM(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, struct Mesh *mesh, + float (*vertexCos)[3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformVertsEM) { + mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts); + } + else { + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } + + mti->deformVertsEM_DM(md, ctx, editData, dm, vertexCos, numVerts); + + if (dm) { + dm->release(dm); + } + } +} + +void modifier_deformMatricesEM(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, struct Mesh *mesh, + float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformMatricesEM) { + mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts); + } + else { + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } + + mti->deformMatricesEM_DM(md, ctx, editData, dm, vertexCos, defMats, numVerts); + + if (dm) { + dm->release(dm); + } + } +} + +struct Mesh *modifier_applyModifier(struct ModifierData *md, const ModifierEvalContext *ctx, + struct Mesh *mesh) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->applyModifier) { + return mti->applyModifier(md, ctx, mesh); + } + else { + DerivedMesh *dm = CDDM_from_mesh(mesh); + + DerivedMesh *ndm = mti->applyModifier_DM(md, ctx, dm); + + if(ndm != dm) { + dm->release(dm); + } + + DM_to_mesh(ndm, mesh, ctx->object, CD_MASK_EVERYTHING, true); + + return mesh; + } +} + +struct Mesh *modifier_applyModifierEM(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, + struct Mesh *mesh) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->applyModifierEM) { + return mti->applyModifierEM(md, ctx, editData, mesh); + } + else { + DerivedMesh *dm = CDDM_from_mesh(mesh); + + DerivedMesh *ndm = mti->applyModifierEM_DM(md, ctx, editData, dm); + + if(ndm != dm) { + dm->release(dm); + } + + DM_to_mesh(ndm, mesh, ctx->object, CD_MASK_EVERYTHING, true); + + return mesh; + } +} + +/* depricated variants of above that accept DerivedMesh */ + +void modifier_deformVerts_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformVerts_DM) { + mti->deformVerts_DM(md, ctx, dm, vertexCos, numVerts); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + mti->deformVerts(md, ctx, mesh, vertexCos, numVerts); + + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + } +} + +void modifier_deformMatrices_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct DerivedMesh *dm, + float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) +{ + + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformMatrices_DM) { + mti->deformMatrices_DM(md, ctx, dm, vertexCos, defMats, numVerts); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts); + + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + } +} + +void modifier_deformVertsEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, struct DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformVertsEM_DM) { + mti->deformVertsEM_DM(md, ctx, editData, dm, vertexCos, numVerts); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts); + + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + } +} + +void modifier_deformMatricesEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, struct DerivedMesh *dm, + float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->deformMatricesEM_DM) { + mti->deformMatricesEM_DM(md, ctx, editData, dm, vertexCos, defMats, numVerts); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts); + + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + } +} + +struct DerivedMesh *modifier_applyModifier_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct DerivedMesh *dm) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->applyModifier_DM) { + return mti->applyModifier_DM(md, ctx, dm); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + struct Mesh *new_mesh = mti->applyModifier(md, ctx, mesh); + + /* Make a DM that doesn't reference new_mesh so we can free the latter. */ + DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE); + + if(new_mesh != mesh) { + BKE_mesh_free(new_mesh); + MEM_freeN(new_mesh); + } + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + + return ndm; + } +} + +struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx, + struct BMEditMesh *editData, + struct DerivedMesh *dm) +{ + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (mti->applyModifierEM_DM) { + return mti->applyModifierEM_DM(md, ctx, editData, dm); + } + else { + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false); + } + + struct Mesh *new_mesh = mti->applyModifierEM(md, ctx, editData, mesh); + + /* Make a DM that doesn't reference new_mesh so we can free the latter. */ + DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE); + + if(new_mesh != mesh) { + BKE_mesh_free(new_mesh); + MEM_freeN(new_mesh); + } + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } + + return ndm; + } +} + |