Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 7 May 2018 16:04:16 +0000 (18:04 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 7 May 2018 16:04:16 +0000 (18:04 +0200)
1  2 
source/blender/blenkernel/intern/modifier.c

index 29a4fcbb9c7bf79387566114f90e09bbdd0878b7,19c0a083703e18e7db3d51a661aa28bf7c59b51b..54e5848c2e61d1c297bd655bbdef9c856deb610b
@@@ -46,7 -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"
  #include "BLT_translation.h"
  
  #include "BKE_appdir.h"
 +#include "BKE_cdderivedmesh.h"
 +#include "BKE_idcode.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"
  
@@@ -73,8 -69,6 +73,8 @@@
  #include "BKE_main.h"
  /* end */
  
 +#include "DEG_depsgraph.h"
 +
  #include "MOD_modifiertypes.h"
  
  static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
@@@ -133,7 -127,6 +133,7 @@@ ModifierData *modifier_new(int type
  
        md->type = type;
        md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded;
 +      md->flag = eModifierFlag_StaticOverride_Local;
  
        if (mti->flags & eModifierTypeFlag_EnableInEditmode)
                md->mode |= eModifierMode_Editmode;
@@@ -293,6 -286,13 +293,13 @@@ void modifiers_foreachTexLink(Object *o
  void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
  {
        const ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
+       /* md_dst may have alredy be fully initialized with some extra allocated data,
+        * we need to free it now to avoid memleak. */
+       if (mti->freeData) {
+               mti->freeData(md_dst);
+       }
        const size_t data_size = sizeof(ModifierData);
        const char *md_src_data = ((const char *)md_src) + data_size;
        char       *md_dst_data =       ((char *)md_dst) + data_size;
@@@ -313,7 -313,6 +320,7 @@@ void modifier_copyData_ex(ModifierData 
        const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
  
        target->mode = md->mode;
 +      target->flag = md->flag;
  
        if (mti->copyData) {
                mti->copyData(md, target);
@@@ -687,7 -686,7 +694,7 @@@ bool modifiers_usesArmature(Object *ob
  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)
        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 */
@@@ -792,8 -791,9 +799,8 @@@ void modifier_path_init(char *path, in
  /* 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);
        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);
        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);
        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)
  {
        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_id_new_nomain(ID_ME, NULL);
 +                      DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
 +              }
 +
 +              mti->deformVerts(md, ctx, mesh, vertexCos, numVerts);
 +
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, 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_id_new_nomain(ID_ME, NULL);
 +                      DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
 +              }
 +
 +              mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts);
 +
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, 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_id_new_nomain(ID_ME, NULL);
 +                      DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
 +              }
 +
 +              mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts);
 +
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, 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_id_new_nomain(ID_ME, NULL);
 +                      DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
 +              }
 +
 +              mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts);
 +
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, 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_id_new_nomain(ID_ME, NULL);
 +                      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_id_free(NULL, new_mesh);
 +              }
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, 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_id_new_nomain(ID_ME, NULL);
 +                      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_id_free(NULL, new_mesh);
 +              }
 +              if (mesh != NULL) {
 +                      BKE_id_free(NULL, mesh);
 +              }
 +
 +              return ndm;
 +      }
 +}
 +