Cleanup/refactor binding code for MeshDeform modifier.
[blender.git] / source / blender / editors / object / object_modifier.c
index 7b4fba235518cfda75fd240649fbe553f4b802b3..200ff1ab0d66653ac88fefee7820c51d99b11224 100644 (file)
@@ -1944,52 +1944,41 @@ static bool meshdeform_poll(bContext *C)
 
 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
+       Scene *scene = CTX_data_scene(C);
        Object *ob = ED_object_active_context(C);
        MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform);
 
-       if (!mmd)
+       if (mmd == NULL) {
                return OPERATOR_CANCELLED;
+       }
 
-       if (mmd->bindcagecos) {
-               MEM_freeN(mmd->bindcagecos);
-               if (mmd->dyngrid) MEM_freeN(mmd->dyngrid);
-               if (mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
-               if (mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
-               if (mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
-               if (mmd->dynverts) MEM_freeN(mmd->dynverts);
-               if (mmd->bindweights) MEM_freeN(mmd->bindweights);  /* deprecated */
-               if (mmd->bindcos) MEM_freeN(mmd->bindcos);  /* deprecated */
-
-               mmd->bindcagecos = NULL;
-               mmd->dyngrid = NULL;
-               mmd->dyninfluences = NULL;
-               mmd->bindinfluences = NULL;
-               mmd->bindoffsets = NULL;
-               mmd->dynverts = NULL;
-               mmd->bindweights = NULL; /* deprecated */
-               mmd->bindcos = NULL; /* deprecated */
+       if (mmd->bindcagecos != NULL) {
+               MEM_SAFE_FREE(mmd->bindcagecos);
+               MEM_SAFE_FREE(mmd->dyngrid);
+               MEM_SAFE_FREE(mmd->dyninfluences);
+               MEM_SAFE_FREE(mmd->bindinfluences);
+               MEM_SAFE_FREE(mmd->bindoffsets);
+               MEM_SAFE_FREE(mmd->dynverts);
+               MEM_SAFE_FREE(mmd->bindweights);  /* Deprecated */
+               MEM_SAFE_FREE(mmd->bindcos);  /* Deprecated */
                mmd->totvert = 0;
                mmd->totcagevert = 0;
                mmd->totinfluence = 0;
        }
        else {
-               int mode = mmd->modifier.mode;
-               mmd->bindfunc = ED_mesh_deform_bind_callback;
+               /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */
+               const int mode = mmd->modifier.mode;
                mmd->modifier.mode |= eModifierMode_Realtime;
-
-               /* Force depsgraph update, this will do binding. */
-               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
-               BKE_scene_graph_update_tagged(depsgraph, bmain);
-
-               mmd->bindfunc = NULL;
+               mmd->bindfunc = ED_mesh_deform_bind_callback;
+               object_force_modifier_update_for_bind(depsgraph, scene, ob);
                mmd->modifier.mode = mode;
+               mmd->bindfunc = NULL;
        }
 
-       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       /* We need DEG_TAG_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
+       DEG_id_tag_update(&ob->id, DEG_TAG_GEOMETRY | DEG_TAG_COPY_ON_WRITE);
        WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
-
        return OPERATOR_FINISHED;
 }