[Bf-blender-cvs] [1130c53] master: Fix T38755: Crash when having cyclic dependency and curve deform

Sergey Sharybin noreply at git.blender.org
Mon Feb 24 14:15:59 CET 2014


Commit: 1130c53cdb24b68d1871a03bad59fad9e6418f29
Author: Sergey Sharybin
Date:   Mon Feb 24 19:12:40 2014 +0600
https://developer.blender.org/rB1130c53cdb24b68d1871a03bad59fad9e6418f29

Fix T38755: Crash when having cyclic dependency and curve deform

Issue was caused by undefined object update order and in some
cases NULL pointer will be de-referenced.

Added on-demand curve path calculation, just the same creepy call
of BKE_displist_make_curveTypes(). This violates DAG and might
end up in a difficult to troubleshoot race condition if there'll
be some issues with how dependencies are calculated in DAG, but
this is the easiest and safest way to solve the bug at this stage,

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

M	source/blender/blenkernel/BKE_lattice.h
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/blenkernel/intern/lattice.c
M	source/blender/modifiers/intern/MOD_array.c
M	source/blender/modifiers/intern/MOD_curve.c

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

diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 29d3673..fc84ef1 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -59,10 +59,10 @@ void end_latt_deform(struct LatticeDeformData *lattice_deform_data);
 bool object_deform_mball(struct Object *ob, struct ListBase *dispbase);
 void outside_lattice(struct Lattice *lt);
 
-void curve_deform_verts(struct Object *cuOb, struct Object *target,
+void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target,
                         struct DerivedMesh *dm, float (*vertexCos)[3],
                         int numVerts, const char *vgroup, short defaxis);
-void curve_deform_vector(struct Object *cuOb, struct Object *target,
+void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target,
                          float orco[3], float vec[3], float mat[3][3], int no_rot_axis);
 
 void lattice_deform_verts(struct Object *laOb, struct Object *target,
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index caec93a..29d322e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2306,7 +2306,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
 							if (strcmp(pchan->name, amod->channel) == 0) {
 								float mat4[4][4], mat3[3][3];
 
-								curve_deform_vector(amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
+								curve_deform_vector(scene, amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
 								copy_m4_m4(mat4, pchan->pose_mat);
 								mul_m4_m3m4(pchan->pose_mat, mat3, mat4);
 
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 1397a7d..30e0c31 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -89,6 +89,11 @@
 #  include "BPY_extern.h"
 #endif
 
+/* Workaround for cyclic depenndnecy with curves.
+ * In such case curve_cache might not be ready yet,
+ */
+#define CYCLIC_DEPENDENCY_WORKAROUND
+
 /* ************************ Constraints - General Utilities *************************** */
 /* These functions here don't act on any specific constraints, and are therefore should/will
  * not require any of the special function-pointers afforded by the relevant constraint 
@@ -1146,7 +1151,7 @@ static void followpath_flush_tars(bConstraint *con, ListBase *list, short nocopy
 	}
 }
 
-static void followpath_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
 	bFollowPathConstraint *data = con->data;
 	
@@ -1162,6 +1167,12 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob),
 		 *		currently for paths to work it needs to go through the bevlist/displist system (ton) 
 		 */
 
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+		if (ct->tar->curve_cache == NULL) {
+			BKE_displist_make_curveTypes(cob->scene, ct->tar, FALSE);
+		}
+#endif
+
 		if (ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) {
 			float quat[4];
 			if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
@@ -1920,13 +1931,22 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
 }
 
 /* Whether this approach is maintained remains to be seen (aligorith) */
-static void pycon_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
 #ifdef WITH_PYTHON
 	bPythonConstraint *data = con->data;
 #endif
 
 	if (VALID_CONS_TARGET(ct)) {
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+		/* special exception for curves - depsgraph issues */
+		if (ct->tar->type == OB_CURVE) {
+			if (ct->tar->curve_cache == NULL) {
+				BKE_displist_make_curveTypes(cob->scene, ct->tar, FALSE);
+			}
+		}
+#endif
+
 		/* firstly calculate the matrix the normal way, then let the py-function override
 		 * this matrix if it needs to do so
 		 */
@@ -2993,8 +3013,16 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, short nocopy)
 	}
 }
 
-static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+	if (VALID_CONS_TARGET(ct)) {
+		if (ct->tar->curve_cache == NULL) {
+			BKE_displist_make_curveTypes(cob->scene, ct->tar, FALSE);
+		}
+	}
+#endif
+
 	/* technically, this isn't really needed for evaluation, but we don't know what else
 	 * might end up calling this...
 	 */
@@ -3648,8 +3676,16 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, short nocopy)
 	}
 }
 
-static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+	if (VALID_CONS_TARGET(ct)) {
+		if (ct->tar->curve_cache == NULL) {
+			BKE_displist_make_curveTypes(cob->scene, ct->tar, FALSE);
+		}
+	}
+#endif
+
 	/* technically, this isn't really needed for evaluation, but we don't know what else
 	 * might end up calling this...
 	 */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index f7d3945..8330fef 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -64,6 +64,11 @@
 
 #include "BKE_deform.h"
 
+/* Workaround for cyclic depenndnecy with curves.
+ * In such case curve_cache might not be ready yet,
+ */
+#define CYCLIC_DEPENDENCY_WORKAROUND
+
 int BKE_lattice_index_from_uvw(Lattice *lt,
                                const int u, const int v, const int w)
 {
@@ -614,7 +619,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
 /* co: local coord, result local too */
 /* returns quaternion for rotation, using cd->no_rot_axis */
 /* axis is using another define!!! */
-static bool calc_curve_deform(Object *par, float co[3],
+static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
                               const short axis, CurveDeform *cd, float quat_r[4])
 {
 	Curve *cu = par->data;
@@ -624,7 +629,12 @@ static bool calc_curve_deform(Object *par, float co[3],
 
 	/* to be sure, mostly after file load */
 	if (ELEM(NULL, par->curve_cache, par->curve_cache->path)) {
-		return 0;  // happens on append and cyclic dependencies...
+#ifdef CYCLIC_DEPENDENCY_WORKAROUND
+		BKE_displist_make_curveTypes(scene, par, FALSE);
+#endif
+		if (par->curve_cache->path == NULL) {
+			return 0;  // happens on append and cyclic dependencies...
+		}
 	}
 	
 	/* options */
@@ -704,7 +714,7 @@ static bool calc_curve_deform(Object *par, float co[3],
 	return 0;
 }
 
-void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
+void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
                         int numVerts, const char *vgroup, short defaxis)
 {
 	Curve *cu;
@@ -768,7 +778,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 					if (weight > 0.0f) {
 						mul_m4_v3(cd.curvespace, vertexCos[a]);
 						copy_v3_v3(vec, vertexCos[a]);
-						calc_curve_deform(cuOb, vec, defaxis, &cd, NULL);
+						calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
 						interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
 						mul_m4_v3(cd.objectspace, vertexCos[a]);
 					}
@@ -796,7 +806,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 					if (weight > 0.0f) {
 						/* already in 'cd.curvespace', prev for loop */
 						copy_v3_v3(vec, vertexCos[a]);
-						calc_curve_deform(cuOb, vec, defaxis, &cd, NULL);
+						calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
 						interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
 						mul_m4_v3(cd.objectspace, vertexCos[a]);
 					}
@@ -808,7 +818,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 		if (cu->flag & CU_DEFORM_BOUNDS_OFF) {
 			for (a = 0; a < numVerts; a++) {
 				mul_m4_v3(cd.curvespace, vertexCos[a]);
-				calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd, NULL);
+				calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
 				mul_m4_v3(cd.objectspace, vertexCos[a]);
 			}
 		}
@@ -823,7 +833,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 	
 			for (a = 0; a < numVerts; a++) {
 				/* already in 'cd.curvespace', prev for loop */
-				calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd, NULL);
+				calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
 				mul_m4_v3(cd.objectspace, vertexCos[a]);
 			}
 		}
@@ -833,7 +843,7 @@ void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*v
 /* input vec and orco = local coord in armature space */
 /* orco is original not-animated or deformed reference point */
 /* result written in vec and mat */
-void curve_deform_vector(Object *cuOb, Object *target,
+void curve_deform_vector(Scene *scene, Object *cuOb, Object *target,
                          float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
 {
 	CurveDeform cd;
@@ -852,7 +862,7 @@ void curve_deform_vector(Object *cuOb, Object *target,
 
 	mul_m4_v3(cd.curvespace, vec);
 	
-	if (calc_curve_deform(cuOb, vec, target->trackflag, &cd, quat)) {
+	if (calc_curve_deform(scene, cuOb, vec, target->trackflag, &cd, quat)) {
 		float qmat[3][3];
 		
 		quat_to_mat3(qmat, quat);
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index d2c44cd

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list