[Bf-blender-cvs] [f2309ba] master: Fix T38824: curve which is constrained on a hidden layer causes cycles crash

Sergey Sharybin noreply at git.blender.org
Tue Feb 25 10:53:08 CET 2014


Commit: f2309ba57943eb7e5a06119b6d45d9ba3b664c8b
Author: Sergey Sharybin
Date:   Tue Feb 25 15:44:39 2014 +0600
https://developer.blender.org/rBf2309ba57943eb7e5a06119b6d45d9ba3b664c8b

Fix T38824: curve which is constrained on a hidden layer causes cycles crash

Issue was caused by cycles setting scene frame which will update scene for
all the layers (not just visible ones) which confuses depsgraph making
objects which are needed as dependency are not really evaluated.

Made it so setting frame via scene.frame_set() which check whether update
need to be flushed to an invisible objects and do this if so.

Not ideal solution but seems to be safest at this point.

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

M	source/blender/blenkernel/BKE_depsgraph.h
M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/anim.c
M	source/blender/blenkernel/intern/depsgraph.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/makesrna/intern/rna_scene_api.c

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

diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 8a0f9f3..05bb01a 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -106,7 +106,7 @@ void DAG_scene_free(struct Scene *sce);
  * not cause any updates but is used by external render engines to detect if for
  * example a datablock was removed. */
 
-void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const bool do_time);
+void DAG_scene_update_flags(struct Main *bmain, struct Scene *sce, unsigned int lay, const bool do_time, const bool do_invisible_flush);
 void DAG_on_visible_update(struct Main *bmain, const bool do_time);
 
 void DAG_id_tag_update(struct ID *id, short flag);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 5204264..a10a3f3 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -117,6 +117,7 @@ void  BKE_scene_frame_set(struct Scene *scene, double cfra);
 /* **  Scene evaluation ** */
 void BKE_scene_update_tagged(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce);
 void BKE_scene_update_for_newframe(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay);
+void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, unsigned int lay, bool do_invisible_flush);
 
 struct SceneRenderLayer *BKE_scene_add_render_layer(struct Scene *sce, const char *name);
 bool BKE_scene_remove_render_layer(struct Main *main, struct Scene *scene, struct SceneRenderLayer *srl);
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 31e388e..167baec 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -315,7 +315,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
 		Base *base, *last = NULL;
 		
 		/* only stuff that moves or needs display still */
-		DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
+		DAG_scene_update_flags(G.main, scene, scene->lay, true, false);
 		
 		/* find the last object with the tag 
 		 * - all those afterwards are assumed to not be relevant for our calculations
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index ee7c62f..af32130 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1377,9 +1377,9 @@ static void dag_scene_free(Scene *sce)
  * Other objects or objects which are tagged for data update are
  * not considered to be in need of evaluation.
  */
-static bool check_object_data_needs_evaluation(Object *object)
+static bool check_object_needs_evaluation(Object *object)
 {
-	if (object->recalc & OB_RECALC_DATA) {
+	if (object->recalc & OB_RECALC_ALL) {
 		/* Object is tagged for update anyway, no need to re-tag it. */
 		return false;
 	}
@@ -1395,9 +1395,9 @@ static bool check_object_data_needs_evaluation(Object *object)
 }
 
 /* Check whether object data is tagged for update. */
-static bool check_object_data_tagged_for_update(Object *object)
+static bool check_object_tagged_for_update(Object *object)
 {
-	if (object->recalc & OB_RECALC_DATA) {
+	if (object->recalc & OB_RECALC_ALL) {
 		return true;
 	}
 
@@ -1454,12 +1454,12 @@ static void dag_invisible_dependencies_flush(Scene *scene)
 
 					if (current_node->type == ID_OB) {
 						Object *current_object = current_node->ob;
-						if (check_object_data_needs_evaluation(current_object)) {
+						if (check_object_needs_evaluation(current_object)) {
 							for (itA = current_node->child; itA; itA = itA->next) {
 								if (itA->node->type == ID_OB) {
 									Object *object = itA->node->ob;
-									if (check_object_data_tagged_for_update(object)) {
-										current_object->recalc |= OB_RECALC_DATA;
+									if (check_object_tagged_for_update(object)) {
+										current_object->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
 									}
 								}
 							}
@@ -1474,6 +1474,18 @@ static void dag_invisible_dependencies_flush(Scene *scene)
 	queue_delete(queue);
 }
 
+static void dag_invisible_dependencies_check_flush(Main *bmain, Scene *scene)
+{
+	if (DAG_id_type_tagged(bmain, ID_OB) ||
+	    DAG_id_type_tagged(bmain, ID_ME) ||  /* Mesh */
+	    DAG_id_type_tagged(bmain, ID_CU) ||  /* Curve */
+	    DAG_id_type_tagged(bmain, ID_MB) ||  /* MetaBall */
+	    DAG_id_type_tagged(bmain, ID_LT))    /* Lattice */
+	{
+		dag_invisible_dependencies_flush(scene);
+	}
+}
+
 /* sort the base list on dependency order */
 static void dag_scene_build(Main *bmain, Scene *sce)
 {
@@ -1572,14 +1584,7 @@ static void dag_scene_build(Main *bmain, Scene *sce)
 	 * are tagged for update (if they're needed for objects which were
 	 * tagged for update).
 	 */
-	if (DAG_id_type_tagged(bmain, ID_OB) ||
-	    DAG_id_type_tagged(bmain, ID_ME)  ||  /* Mesh */
-	    DAG_id_type_tagged(bmain, ID_CU)  ||  /* Curve */
-	    DAG_id_type_tagged(bmain, ID_MB)  ||  /* MetaBall */
-	    DAG_id_type_tagged(bmain, ID_LT))     /* Lattice */
-	{
-		dag_invisible_dependencies_flush(sce);
-	}
+	dag_invisible_dependencies_check_flush(bmain, sce);
 }
 
 /* clear all dependency graphs */
@@ -2126,7 +2131,7 @@ static void dag_group_update_flags(Main *bmain, Scene *scene, Group *group, cons
 
 /* flag all objects that need recalc, for changes in time for example */
 /* do_time: make this optional because undo resets objects to their animated locations without this */
-void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const bool do_time)
+void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const bool do_time, const bool do_invisible_flush)
 {
 	Base *base;
 	Object *ob;
@@ -2181,7 +2186,10 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const b
 			group->id.flag &= ~LIB_DOIT;
 		}
 	}
-	
+
+	if (do_invisible_flush) {
+		dag_invisible_dependencies_check_flush(bmain, scene);
+	}
 }
 
 /* struct returned by DagSceneLayer */
@@ -2296,7 +2304,6 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
 		Object *ob;
 		DagNode *node;
 		unsigned int lay = dsl->layer, oblay;
-		bool have_updated_objects = false;
 
 		/* derivedmeshes and displists are not saved to file so need to be
 		 * remade, tag them so they get remade in the scene update loop,
@@ -2313,8 +2320,6 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
 			oblay = (node) ? node->lay : ob->lay;
 
 			if ((oblay & lay) & ~scene->lay_updated) {
-				have_updated_objects = true;
-
 				if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) {
 					ob->recalc |= OB_RECALC_DATA;
 					lib_id_recalc_tag(bmain, &ob->id);
@@ -2328,17 +2333,10 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
 			}
 		}
 
-		/* Make sure that object which needs for tagged ones and which are not
-		 * in the current scene are also tagged for update.
-		 */
-		if (have_updated_objects) {
-			dag_invisible_dependencies_flush(scene);
-		}
-
 		BKE_main_id_tag_idcode(bmain, ID_GR, false);
 
 		/* now tag update flags, to ensure deformers get calculated on redraw */
-		DAG_scene_update_flags(bmain, scene, lay, do_time);
+		DAG_scene_update_flags(bmain, scene, lay, do_time, true);
 		scene->lay_updated |= lay;
 	}
 	
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 09bfdbb..da2eda0 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1613,6 +1613,11 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
 /* applies changes right away, does all sets too */
 void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay)
 {
+	BKE_scene_update_for_newframe_ex(eval_ctx, bmain, sce, lay, false);
+}
+
+void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay, bool do_invisible_flush)
+{
 	float ctime = BKE_scene_frame_get(sce);
 	Scene *sce_iter;
 #ifdef DETAILED_ANALYSIS_OUTPUT
@@ -1648,7 +1653,7 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
 
 	/* Following 2 functions are recursive
 	 * so don't call within 'scene_update_tagged_recursive' */
-	DAG_scene_update_flags(bmain, sce, lay, TRUE);   // only stuff that moves or needs display still
+	DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush);   // only stuff that moves or needs display still
 
 	BKE_mask_evaluate_all_masks(bmain, ctime, true);
 
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a4f1f84..c51ee90 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -69,7 +69,8 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
 	BPy_BEGIN_ALLOW_THREADS;
 #endif
 
-	BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, (1 << 20) - 1);
+	/* It's possible that here we're including layers which were never visible before. */
+	BKE_scene_update_for_newframe_ex(G.main->eval_ctx, G.main, scene, (1 << 20) - 1, true);
 
 #ifdef WITH_PYTHON
 	BPy_END_ALLOW_THREADS;




More information about the Bf-blender-cvs mailing list