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:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-02-25 13:44:39 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-02-25 13:52:56 +0400
commitf2309ba57943eb7e5a06119b6d45d9ba3b664c8b (patch)
tree44e32047cd67f914ee5d848dd85fba08d54a1d8a
parent3ae641eb020ea61a595840eee8cbcc9f7ee36043 (diff)
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.
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h1
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c54
-rw-r--r--source/blender/blenkernel/intern/scene.c7
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c3
6 files changed, 37 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 8a0f9f3fa67..05bb01a4490 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 52042649dc4..a10a3f3f59f 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 31e388e6b6b..167baec3d9f 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 ee7c62fc9a6..af321302984 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 09bfdbb2d95..da2eda0fbee 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 a4f1f84f94d..c51ee901370 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;