Merge branch 'master' into blender2.8
[blender.git] / source / blender / modifiers / intern / MOD_surfacedeform.c
index 95347128ef91dad20f4b2026d2289b987762993b..ab0b31812b2d89556b3d9a36a2f23aa2f8480c37 100644 (file)
@@ -1,3 +1,5 @@
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
@@ -6,12 +8,14 @@
 #include "BLI_math_geom.h"
 #include "BLI_task.h"
 
-#include "BKE_cdderivedmesh.h"
+#include "BKE_bvhutils.h"
+#include "BKE_mesh.h"
 #include "BKE_editmesh.h"
+#include "BKE_library.h"
 #include "BKE_library_query.h"
 #include "BKE_modifier.h"
 
-#include "depsgraph_private.h"
+#include "DEG_depsgraph.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -167,17 +171,6 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
        walk(userData, ob, &smd->target, IDWALK_NOP);
 }
 
-static void updateDepgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
-{
-       SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
-
-       if (smd->target) {
-               DagNode *curNode = dag_get_node(ctx->forest, smd->target);
-
-               dag_add_relation(ctx->forest, curNode, ctx->obNode, DAG_RL_DATA_DATA, "Surface Deform Modifier");
-       }
-}
-
 static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
 {
        SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
@@ -918,14 +911,14 @@ static void bindVert(
 
 static bool surfacedeformBind(
         SurfaceDeformModifierData *smd, float (*vertexCos)[3],
-        unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, DerivedMesh *tdm)
+        unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, Mesh *target)
 {
        BVHTreeFromMesh treeData = {NULL};
-       const MVert *mvert = tdm->getVertArray(tdm);
-       const MPoly *mpoly = tdm->getPolyArray(tdm);
-       const MEdge *medge = tdm->getEdgeArray(tdm);
-       const MLoop *mloop = tdm->getLoopArray(tdm);
-       unsigned int tnumedges = tdm->getNumEdges(tdm);
+       const MVert *mvert = target->mvert;
+       const MPoly *mpoly = target->mpoly;
+       const MEdge *medge = target->medge;
+       const MLoop *mloop = target->mloop;
+       unsigned int tnumedges = target->totedge;
        int adj_result;
        SDefAdjacencyArray *vert_edges;
        SDefAdjacency *adj_array;
@@ -959,7 +952,7 @@ static bool surfacedeformBind(
                return false;
        }
 
-       bvhtree_from_mesh_get(&treeData, tdm, BVHTREE_FROM_LOOPTRI, 2);
+       BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
        if (treeData.tree == NULL) {
                modifier_setError((ModifierData *)smd, "Out of memory");
                freeAdjacencyMap(vert_edges, adj_array, edge_polys);
@@ -988,7 +981,7 @@ static bool surfacedeformBind(
                                     .mpoly = mpoly,
                                     .medge = medge,
                                     .mloop = mloop,
-                                    .looptri = tdm->getLoopTriArray(tdm),
+                                    .looptri = BKE_mesh_runtime_looptri_ensure(target),
                                     .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"),
                                     .bind_verts = smd->verts,
                                     .vertexCos = vertexCos,
@@ -1048,6 +1041,30 @@ static bool surfacedeformBind(
        return data.success == 1;
 }
 
+static Mesh *surfacedeform_get_mesh(SurfaceDeformModifierData *smd, bool *r_needsfree)
+{
+       Mesh *mesh;
+
+       /* Handle target mesh both in and out of edit mode */
+       if (smd->target->mode & OB_MODE_EDIT) {
+               BMEditMesh *em = BKE_editmesh_from_object(smd->target);
+               mesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
+               *r_needsfree = true;
+       }
+       else {
+               mesh = BKE_modifier_get_evaluated_mesh_from_object(
+                          smd->target, smd->modifier.mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
+               *r_needsfree = false;
+       }
+
+       if (!mesh) {
+               mesh = get_mesh(smd->target, NULL, NULL, NULL, false, false);
+               *r_needsfree = true;
+       }
+
+       return mesh;
+}
+
 static void deformVert(
         void *__restrict userdata,
         const int index,
@@ -1105,10 +1122,13 @@ static void deformVert(
        }
 }
 
-static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
+static void surfacedeformModifier_do(
+        ModifierData *md,
+        float (*vertexCos)[3], unsigned int numverts, Object *ob)
 {
        SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
-       DerivedMesh *tdm;
+       bool free_target;
+       Mesh *target;
        unsigned int tnumverts, tnumpoly;
 
        /* Exit function if bind flag is not set (free bind data if any) */
@@ -1117,22 +1137,14 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
                return;
        }
 
-       /* Handle target mesh both in and out of edit mode */
-       if (smd->target == md->scene->obedit) {
-               BMEditMesh *em = BKE_editmesh_from_object(smd->target);
-               tdm = em->derivedFinal;
-       }
-       else {
-               tdm = smd->target->derivedFinal;
-       }
-
-       if (!tdm) {
+       target = surfacedeform_get_mesh(smd, &free_target);
+       if (!target) {
                modifier_setError(md, "No valid target mesh");
                return;
        }
 
-       tnumverts = tdm->getNumVerts(tdm);
-       tnumpoly = tdm->getNumPolys(tdm);
+       tnumverts = target->totvert;
+       tnumpoly = target->totpoly;
 
        /* If not bound, execute bind */
        if (!(smd->verts)) {
@@ -1141,7 +1153,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
                invert_m4_m4(tmp_mat, ob->obmat);
                mul_m4_m4m4(smd->mat, tmp_mat, smd->target->obmat);
 
-               if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, tdm)) {
+               if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
                        smd->flags &= ~MOD_SDEF_BIND;
                        return;
                }
@@ -1150,10 +1162,12 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
        /* Poly count checks */
        if (smd->numverts != numverts) {
                modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts);
+               if (free_target) BKE_id_free(NULL, target);
                return;
        }
        else if (smd->numpoly != tnumpoly) {
                modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+               if (free_target) BKE_id_free(NULL, target);
                return;
        }
 
@@ -1165,8 +1179,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
        };
 
        if (data.targetCos != NULL) {
-               bool tdm_vert_alloc;
-               const MVert * const mvert = DM_get_vert_array(tdm, &tdm_vert_alloc);
+               const MVert * const mvert = target->mvert;
 
                for (int i = 0; i < tnumverts; i++) {
                        mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
@@ -1180,30 +1193,27 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
                                        deformVert,
                                        &settings);
 
-               if (tdm_vert_alloc) {
-                       MEM_freeN((void *)mvert);
-               }
-
                MEM_freeN(data.targetCos);
        }
+
+       if (free_target) BKE_id_free(NULL, target);
 }
 
 static void deformVerts(
-        ModifierData *md, Object *ob,
-        DerivedMesh *UNUSED(derivedData),
-        float (*vertexCos)[3], int numVerts,
-        ModifierApplyFlag UNUSED(flag))
+        ModifierData *md, const ModifierEvalContext *ctx,
+        Mesh *UNUSED(mesh),
+        float (*vertexCos)[3], int numVerts)
 {
-       surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+       surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
 }
 
 static void deformVertsEM(
-        ModifierData *md, Object *ob,
+        ModifierData *md, const ModifierEvalContext *ctx,
         struct BMEditMesh *UNUSED(editData),
-        DerivedMesh *UNUSED(derivedData),
+        Mesh *UNUSED(mesh),
         float (*vertexCos)[3], int numVerts)
 {
-       surfacedeformModifier_do(md, vertexCos, numVerts, ob);
+       surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
 }
 
 static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
@@ -1222,17 +1232,25 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
                                eModifierTypeFlag_SupportsEditmode,
 
        /* copyData */          copyData,
+
+       /* deformVerts_DM */    NULL,
+       /* deformMatrices_DM */ NULL,
+       /* deformVertsEM_DM */  NULL,
+       /* deformMatricesEM_DM*/NULL,
+       /* applyModifier_DM */  NULL,
+       /* applyModifierEM_DM */NULL,
+
        /* deformVerts */       deformVerts,
        /* deformMatrices */    NULL,
        /* deformVertsEM */     deformVertsEM,
        /* deformMatricesEM */  NULL,
        /* applyModifier */     NULL,
        /* applyModifierEM */   NULL,
+
        /* initData */          initData,
        /* requiredDataMask */  NULL,
        /* freeData */          freeData,
        /* isDisabled */        isDisabled,
-       /* updateDepgraph */    updateDepgraph,
        /* updateDepsgraph */   updateDepsgraph,
        /* dependsOnTime */     NULL,
        /* dependsOnNormals */  NULL,