[Bf-blender-cvs] [484389cdcd6] blender2.8: Fix T58210, Part II: Surface Deform modifier (un)binding is broken.

Bastien Montagne noreply at git.blender.org
Wed Dec 5 20:54:20 CET 2018


Commit: 484389cdcd6c8cbac9aaaae97bb4c7599a63a793
Author: Bastien Montagne
Date:   Wed Dec 5 18:33:31 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB484389cdcd6c8cbac9aaaae97bb4c7599a63a793

Fix T58210, Part II: Surface Deform modifier (un)binding is broken.

This fixes/clarifies Surface Deform evaluation code that does the
binding, since that part should only be called outside of depsgraph
evaluation, with orig data-blocks and not CoW ones.

Now we have a decent amount of asserts and checks to ensure eveything
works as expected.

Also had to add a special case to get target's mesh in binding case,
since often target's evaluated mesh is not available, in that case (and
in that case only), we can actually compute that mesh (because we are
out of depsgraph evaluation).

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

M	source/blender/modifiers/intern/MOD_surfacedeform.c

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

diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 18bee0d2d59..5a2b54824cc 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -16,6 +16,7 @@
 #include "BKE_modifier.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -1100,7 +1101,7 @@ static void deformVert(
 
 static void surfacedeformModifier_do(
         ModifierData *md,
-        const ModifierEvalContext *UNUSED(ctx),
+        const ModifierEvalContext *ctx,
         float (*vertexCos)[3], unsigned int numverts, Object *ob)
 {
 	SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
@@ -1108,13 +1109,29 @@ static void surfacedeformModifier_do(
 	Mesh *target;
 	unsigned int tnumverts, tnumpoly;
 
-	/* Exit function if bind flag is not set (free bind data if any) */
+	/* Exit function if bind flag is not set (free bind data if any). */
 	if (!(smd->flags & MOD_SDEF_BIND)) {
-		freeData(md);
+		/* Note: with new CoW system, we expect unbinding to be done by a special call from main thread,
+		 * outside of depsgraph evaluation (see object_force_modifier_update_for_bind() in object_modifier.c). */
+		if (smd->verts != NULL) {
+			if (ob != DEG_get_original_object(ob)) {
+				BLI_assert(!"Trying to unbind inside of depsgraph evaluation");
+				modifier_setError(md, "Trying to unbind inside of depsgraph evaluation");
+			}
+			else {
+				freeData(md);
+			}
+		}
 		return;
 	}
 
 	target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(smd->target, &free_target);
+	if (!target && smd->verts == NULL && ob == DEG_get_original_object(ob)) {
+		/* Special case, binding happens outside of depsgraph evaluation, so we can build our own
+		 * target mesh if needed. */
+		target = mesh_create_eval_final_view(ctx->depsgraph, DEG_get_input_scene(ctx->depsgraph), smd->target, 0);
+		free_target = target != NULL;
+	}
 	if (!target) {
 		modifier_setError(md, "No valid target mesh");
 		return;
@@ -1123,8 +1140,15 @@ static void surfacedeformModifier_do(
 	tnumverts = target->totvert;
 	tnumpoly = target->totpoly;
 
-	/* If not bound, execute bind */
-	if (!(smd->verts)) {
+	/* If not bound, execute bind. */
+	/* Note: with new CoW system, we expect binding to be done by a special call from main thread,
+	 * outside of depsgraph evaluation (see object_force_modifier_update_for_bind() in object_modifier.c). */
+	if (smd->verts == NULL) {
+		if (ob != DEG_get_original_object(ob)) {
+			BLI_assert(!"Trying to bind inside of depsgraph evaluation");
+			modifier_setError(md, "Trying to bind inside of depsgraph evaluation");
+			goto finally;
+		}
 		float tmp_mat[4][4];
 
 		invert_m4_m4(tmp_mat, ob->obmat);
@@ -1132,20 +1156,19 @@ static void surfacedeformModifier_do(
 
 		if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
 			smd->flags &= ~MOD_SDEF_BIND;
-			return;
 		}
+		/* Early abort, this is binding 'call', no need to perform whole evaluation. */
+		goto finally;
 	}
 
 	/* 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;
+		goto finally;
 	}
 	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;
+		goto finally;
 	}
 
 	/* Actual vertex location update starts here */
@@ -1173,6 +1196,7 @@ static void surfacedeformModifier_do(
 		MEM_freeN(data.targetCos);
 	}
 
+finally:
 	if (target != NULL && free_target) {
 		BKE_id_free(NULL, target);
 	}



More information about the Bf-blender-cvs mailing list