Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2018-12-07 13:17:25 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-12-07 13:22:31 +0300
commit989fbff16f49204ca31a67f56f87c2221e0246f4 (patch)
treeee4109fb816cd7d23a3dd8900d6482166b485b81 /source/blender/editors
parent41e4059f3c41234016dfabf6b3ae9e40c735483e (diff)
Cleanup/refactor binding code for MeshDeform modifier.
We had two different ways of doing it, SurfaceDeform and LaplacianDeform would do it through a special modifier stack evaluation triggered from binding operator, while MeshDeform would do it through a regular depsgraph update/eval (also triggered from its binding op). This enforces the later to search back for orig modifier data inside modifier code (to apply binding on that one, and not on useless CoW one). Besides the question of safety about modifying orig data from threaded despgraph (that was *probably* OK, but think it's bad idea in general), it's much better to have a common way of doing that kind of things. For now it remains rather dodgy, but at least it's reasonably consistent and safe now. This commit also fixes a potential memleak from binding process of MeshDeform, and does some general cleanup a bit.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/armature/meshlaplacian.c6
-rw-r--r--source/blender/editors/include/ED_armature.h1
-rw-r--r--source/blender/editors/object/object_modifier.c49
3 files changed, 22 insertions, 34 deletions
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 001c8ce215f..96799304845 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1427,7 +1427,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
EIG_linear_solver_delete(context);
}
-static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierData *mmd, MeshDeformBind *mdb)
+static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBind *mdb)
{
MDefBindInfluence *inf;
MDefInfluence *mdinf;
@@ -1578,7 +1578,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa
}
void ED_mesh_deform_bind_callback(
- Scene *scene, MeshDeformModifierData *mmd, Mesh *cagemesh,
+ MeshDeformModifierData *mmd, Mesh *cagemesh,
float *vertexcos, int totvert, float cagemat[4][4])
{
MeshDeformBind mdb;
@@ -1606,7 +1606,7 @@ void ED_mesh_deform_bind_callback(
mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3);
/* solve */
- harmonic_coordinates_bind(scene, mmd, &mdb);
+ harmonic_coordinates_bind(mmd, &mdb);
/* assign bind variables */
mmd->bindcagecos = (float *)mdb.cagecos;
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index d5698ecadf7..3131e5221d8 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -238,7 +238,6 @@ struct Object *ED_pose_object_from_context(struct bContext *C);
/* meshlaplacian.c */
void ED_mesh_deform_bind_callback(
- struct Scene *scene,
struct MeshDeformModifierData *mmd,
struct Mesh *cagemesh,
float *vertexcos, int totvert, float cagemat[4][4]);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 7b4fba23551..200ff1ab0d6 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -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;
}