[Bf-blender-cvs] [59f6371a858] master: Fix T63252: Bind in Mesh Deform Modifier fails

Sergey Sharybin noreply at git.blender.org
Thu Apr 4 15:57:32 CEST 2019


Commit: 59f6371a85824b4785db8e2b526c1101a5e30ca7
Author: Sergey Sharybin
Date:   Thu Apr 4 14:42:33 2019 +0200
Branches: master
https://developer.blender.org/rB59f6371a85824b4785db8e2b526c1101a5e30ca7

Fix T63252: Bind in Mesh Deform Modifier fails

A regression since 64c8d72ef1ad.

The solution is to force modifier evaluation for an evaluated
object, and let it to copy binding data back to original when
is being evaluated for binding.

Reviewers: brecht

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D4642

===================================================================

M	source/blender/blenkernel/BKE_modifier.h
M	source/blender/blenkernel/intern/modifier.c
M	source/blender/editors/armature/meshlaplacian.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/modifiers/intern/MOD_correctivesmooth.c
M	source/blender/modifiers/intern/MOD_meshdeform.c
M	source/blender/modifiers/intern/MOD_surfacedeform.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index a375ed3044c..9f522c11733 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -403,6 +403,16 @@ void        modifier_path_init(char *path, int path_maxlen, const char *name);
 const char *modifier_path_relbase(struct Main *bmain, struct Object *ob);
 const char *modifier_path_relbase_from_global(struct Object *ob);
 
+/* Accessors of original/evaluated modifiers. */
+
+/* For a given modifier data, get corresponding original one.
+ * If the modifier data is already original, return it as-is. */
+struct ModifierData *modifier_get_original(struct ModifierData *md);
+struct ModifierData *modifier_get_evaluated(
+        struct Depsgraph* depsgraph,
+        struct Object *object,
+        struct ModifierData *md);
+
 /* wrappers for modifier callbacks that ensure valid normals */
 
 struct Mesh *modwrap_applyModifier(
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index fe955ced5f5..8f52e579a91 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -885,3 +885,23 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval, con
 
 	return me;
 }
+
+ModifierData *modifier_get_original(ModifierData *md)
+{
+	if (md->orig_modifier_data == NULL) {
+		return md;
+	}
+	return md->orig_modifier_data;
+}
+
+struct ModifierData *modifier_get_evaluated(
+        Depsgraph* depsgraph,
+        Object *object,
+        ModifierData *md)
+{
+	Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
+	if (object_eval == object) {
+		return md;
+	}
+	return modifiers_findByName(object_eval, md->name);
+}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 34fea2e0996..66bd7a8db80 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1577,6 +1577,8 @@ void ED_mesh_deform_bind_callback(
         MeshDeformModifierData *mmd, Mesh *cagemesh,
         float *vertexcos, int totvert, float cagemat[4][4])
 {
+	MeshDeformModifierData *mmd_orig =
+	        (MeshDeformModifierData *)modifier_get_original(&mmd->modifier);
 	MeshDeformBind mdb;
 	MVert *mvert;
 	int a;
@@ -1602,23 +1604,23 @@ void ED_mesh_deform_bind_callback(
 		mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3);
 
 	/* solve */
-	harmonic_coordinates_bind(mmd, &mdb);
+	harmonic_coordinates_bind(mmd_orig, &mdb);
 
 	/* assign bind variables */
-	mmd->bindcagecos = (float *)mdb.cagecos;
-	mmd->totvert = mdb.totvert;
-	mmd->totcagevert = mdb.totcagevert;
-	copy_m4_m4(mmd->bindmat, mmd->object->obmat);
+	mmd_orig->bindcagecos = (float *)mdb.cagecos;
+	mmd_orig->totvert = mdb.totvert;
+	mmd_orig->totcagevert = mdb.totcagevert;
+	copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->obmat);
 
 	/* transform bindcagecos to world space */
 	for (a = 0; a < mdb.totcagevert; a++)
-		mul_m4_v3(mmd->object->obmat, mmd->bindcagecos + a * 3);
+		mul_m4_v3(mmd_orig->object->obmat, mmd_orig->bindcagecos + a * 3);
 
 	/* free */
 	MEM_freeN(mdb.vertexcos);
 
 	/* compact weights */
-	modifier_mdef_compact_influences((ModifierData *)mmd);
+	modifier_mdef_compact_influences((ModifierData *)mmd_orig);
 
 	end_progress_bar();
 	waitcursor(0);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index c3a562df037..1944d2989ac 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -93,23 +93,38 @@ static void modifier_skin_customdata_delete(struct Object *ob);
 
 /******************************** API ****************************/
 
-static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Scene *scene, Object *ob)
+static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob)
 {
+	Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+	Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+	BKE_object_eval_reset(ob_eval);
 	if (ob->type == OB_MESH) {
-		Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene, ob, &CD_MASK_BAREMESH);
+		Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
 		BKE_id_free(NULL, me_eval);
 	}
 	else if (ob->type == OB_LATTICE) {
-		BKE_lattice_modifiers_calc(depsgraph, scene, ob);
+		BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
 	}
 	else if (ob->type == OB_MBALL) {
-		BKE_displist_make_mball(depsgraph, scene, ob);
+		BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
 	}
 	else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
-		BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL);
+		BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false, NULL);
 	}
 }
 
+static void object_force_modifier_bind_simple_options(
+        Depsgraph *depsgraph,
+        Object *object,
+        ModifierData *md)
+{
+	ModifierData *md_eval = (ModifierData *)modifier_get_evaluated(depsgraph, object, md);
+	const int mode = md_eval->mode;
+	md_eval->mode |= eModifierMode_Realtime;
+	object_force_modifier_update_for_bind(depsgraph, object);
+	md_eval->mode = mode;
+}
+
 ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
 {
 	ModifierData *md = NULL, *new_md = NULL;
@@ -1926,19 +1941,17 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
 		csmd->bind_coords_num = 0;
 	}
 	else {
-		/* signal to modifier to recalculate */
-		csmd->bind_coords_num = (unsigned int)-1;
+		/* Signal to modifier to recalculate. */
+		CorrectiveSmoothModifierData *csmd_eval =
+		        (CorrectiveSmoothModifierData *)modifier_get_evaluated(depsgraph, ob, &csmd->modifier);
+		csmd_eval->bind_coords_num = (unsigned int)-1;
 
 		/* Force modifier to run, it will call binding routine
 		 * (this has to happen outside of depsgraph evaluation). */
-		const int mode = csmd->modifier.mode;
-		csmd->modifier.mode |= eModifierMode_Realtime;
-		object_force_modifier_update_for_bind(depsgraph, scene, ob);
-		csmd->modifier.mode = mode;
+		object_force_modifier_bind_simple_options(depsgraph, ob, &csmd->modifier);
 	}
 
-	/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
-	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
 	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
 
 	return OPERATOR_FINISHED;
@@ -1979,7 +1992,6 @@ static bool meshdeform_poll(bContext *C)
 static int meshdeform_bind_exec(bContext *C, wmOperator *op)
 {
 	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);
 
@@ -2002,16 +2014,14 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
 	}
 	else {
 		/* 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;
-		mmd->bindfunc = ED_mesh_deform_bind_callback;
-		object_force_modifier_update_for_bind(depsgraph, scene, ob);
-		mmd->modifier.mode = mode;
-		mmd->bindfunc = NULL;
+		MeshDeformModifierData *mmd_eval =
+		        (MeshDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &mmd->modifier);
+		mmd_eval->bindfunc = ED_mesh_deform_bind_callback;
+		object_force_modifier_bind_simple_options(depsgraph, ob, &mmd->modifier);
+		mmd_eval->bindfunc = NULL;
 	}
 
-	/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
-	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
 	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
 	return OPERATOR_FINISHED;
 }
@@ -2188,7 +2198,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
 
 	if (free) {
 		BKE_ocean_free_modifier_cache(omd);
-		DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+		DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
 		WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
 		return OPERATOR_FINISHED;
 	}
@@ -2288,7 +2298,6 @@ static bool laplaciandeform_poll(bContext *C)
 
 static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
 {
-	Scene *scene = CTX_data_scene(C);
 	Object *ob = ED_object_active_context(C);
 	Depsgraph *depsgraph = CTX_data_depsgraph(C);
 	LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform);
@@ -2304,15 +2313,25 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
 		lmd->flag |= MOD_LAPLACIANDEFORM_BIND;
 	}
 
+	LaplacianDeformModifierData *lmd_eval =
+	        (LaplacianDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &lmd->modifier);
+	lmd_eval->flag = lmd->flag;
+
 	/* Force modifier to run, it will call binding routine
 	 * (this has to happen outside of depsgraph evaluation). */
-	const int mode = lmd->modifier.mode;
-	lmd->modifier.mode |= eModifierMode_Realtime;
-	object_force_modifier_update_for_bind(depsgraph, scene, ob);
-	lmd->modifier.mode = mode;
+	object_force_modifier_bind_simple_options(depsgraph, ob, &lmd->modifier);
 
-	/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
-	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+	/* This is hard to know from the modifier itself whether the evaluation is
+	 * happening for binding or not. So we copy all the required data here. */
+	lmd->total_verts = lmd_eval->total_verts;
+	if (lmd_eval->vertexco == NULL) {
+		MEM_SAFE_FREE(lmd->vertexco);
+	}
+	else {
+		lmd->vertexco = MEM_dupallocN(lmd_eval->vertexco);
+	}
+
+	DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
 	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFI

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list