[Bf-blender-cvs] [5982a57] alembic: Alembic: Limit frame update to only group which we're interested in

Sergey Sharybin noreply at git.blender.org
Thu Apr 23 14:08:50 CEST 2015


Commit: 5982a57f02cb2122bb509e858624f358f6433fab
Author: Sergey Sharybin
Date:   Thu Apr 23 17:04:21 2015 +0500
Branches: alembic
https://developer.blender.org/rB5982a57f02cb2122bb509e858624f358f6433fab

Alembic: Limit frame update to only group which we're interested in

The idea is simple: make it so scene_update_for_newframe is only doing updates
of the stuff which is really needed for the currently baking group.

Implementation is a bit tricky since we don't have parent relations after the
DAG is built, so doing some graph traversal there.

This code is also now using simplified version of scene_update_for_newframe()
which means in theory we can try de-duplicating some pieces of code, but that
can be done later.

Additionally, the same approach can be used to optimize motion path calculation.

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

M	source/blender/blenkernel/BKE_depsgraph.h
M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/depsgraph.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/editors/io/io_cache_library.c

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

diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 1887a89..f38800c 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -44,6 +44,7 @@
 extern "C" {
 #endif
 
+struct Group;
 struct ID;
 struct Main;
 struct Object;
@@ -111,6 +112,7 @@ void DAG_scene_free(struct Scene *sce);
  * example a datablock was removed. */
 
 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_scene_update_group_flags(struct Main *bmain, struct Scene *scene, struct Group *group, 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 79778d5..d9c2ee9 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -40,6 +40,7 @@ extern "C" {
 struct AviCodecData;
 struct Base;
 struct EvaluationContext;
+struct Group;
 struct Main;
 struct Object;
 struct QuicktimeCodecData;
@@ -119,6 +120,11 @@ void  BKE_scene_frame_set(struct Scene *scene, double cfra);
 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);
+void BKE_scene_update_group_for_newframe(struct EvaluationContext *eval_ctx,
+                                         struct Main *bmain,
+                                         struct Scene *scene,
+                                         struct Group *group,
+                                         unsigned int lay);
 
 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/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 9cd978c..5a1e11b 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2248,6 +2248,90 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const b
 	}
 }
 
+void DAG_scene_update_group_flags(Main *bmain,
+                                  Scene *scene,
+                                  Group *group,
+                                  unsigned int lay,
+                                  const bool do_time,
+                                  const bool do_invisible_flush)
+{
+	DagNode *root_node = scene->theDag->DagNode.first, *node;
+	GroupObject *go;
+	DagNodeQueue *queue;
+
+	/* Tag all possible objects for update. */
+	DAG_scene_update_flags(bmain, scene, lay, do_time, do_invisible_flush);
+
+	/* Initialize colors of nodes. */
+	for (node = root_node; node != NULL; node = node->next) {
+		node->color = DAG_WHITE;
+		node->scheduled = false;
+	}
+
+	/* Tag nodes which corresponds to objects which are to be updated. */
+	for (go = group->gobject.first; go != NULL; go = go->next) {
+		if (go->ob != NULL) {
+			node = dag_find_node(scene->theDag, go->ob);
+			if (node != NULL) {
+				node->scheduled = true;
+			}
+		}
+	}
+
+	/* Flush schedule flags to parent. */
+	queue = queue_create(DAGQUEUEALLOC);
+	for (node = root_node; node != NULL; node = node->next) {
+		if (node->color == DAG_WHITE) {
+			push_stack(queue, node);
+			node->color = DAG_GRAY;
+			while (queue->count) {
+				DagNode *current_node = get_top_node_queue(queue);
+				DagAdjList *itA;
+				bool skip = false;
+				/* Check if all child nodes were scheduled. */
+				for (itA = current_node->child; itA; itA = itA->next) {
+					if (itA->node->color == DAG_WHITE) {
+						itA->node->color = DAG_GRAY;
+						push_stack(queue, itA->node);
+						skip = true;
+						break;
+					}
+				}
+				/* Check if there are scheduled children and if so schedule
+				 * current node as well since it's needed for chidlren.
+				 */
+				if (!skip) {
+					current_node = pop_queue(queue);
+					if (current_node->type == ID_OB) {
+						for (itA = current_node->child; itA; itA = itA->next) {
+							if (itA->node->scheduled) {
+								current_node->scheduled = true;
+								break;
+							}
+						}
+					}
+					node->color = DAG_BLACK;
+				}
+			}
+		}
+	}
+	queue_delete(queue);
+
+	/* Clear recalc flags from objects which corresponds to nodes which are
+	 * not needed for the interesting group update.
+	 */
+	for (node = root_node; node != NULL; node = node->next) {
+		if (node->type == ID_OB) {
+			Object *object = node->ob;
+			if (!node->scheduled) {
+				object->recalc &= ~OB_RECALC_ALL;
+			}
+		}
+		node->color = DAG_WHITE;
+		node->scheduled = false;
+	}
+}
+
 /* struct returned by DagSceneLayer */
 typedef struct DagSceneLayer {
 	struct DagSceneLayer *next, *prev;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index ab18d4d..4965126 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1874,6 +1874,45 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
 #endif
 }
 
+void BKE_scene_update_group_for_newframe(EvaluationContext *eval_ctx,
+                                         Main *bmain,
+                                         Scene *scene,
+                                         Group *group,
+                                         unsigned int lay)
+{
+	float ctime = BKE_scene_frame_get(scene);
+	Scene *sce_iter;
+
+	/* Step 1: Preparation, same as in regular frame update. */
+	BKE_image_update_frame(bmain, scene->r.cfra);
+	scene_rebuild_rbw_recursive(scene, ctime);
+	BKE_cache_library_dag_recalc_tag(eval_ctx, bmain);
+	for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) {
+		DAG_scene_relations_update(bmain, sce_iter);
+	}
+
+	/* Step 2: Tag objects which we need to update. */
+	DAG_ids_flush_tagged(bmain);
+	DAG_scene_update_group_flags(bmain, scene, group, lay, true, false);
+
+	/* Step 3: Update animation. */
+#ifdef POSE_ANIMATION_WORKAROUND
+	scene_armature_depsgraph_workaround(bmain);
+#endif
+	BKE_animsys_evaluate_all_animation(bmain, scene, ctime);
+
+	/* Step 4: Actual evaluation. */
+	BKE_main_id_tag_idcode(bmain, ID_MA, false);
+	BKE_main_id_tag_idcode(bmain, ID_LA, false);
+	scene_do_rb_simulation_recursive(scene, ctime);
+	scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
+	scene_depsgraph_hack(eval_ctx, scene, scene);
+
+	/* Step 5: Cleanup after evaluaiton. */
+	DAG_ids_check_recalc(bmain, scene, true);
+	DAG_ids_clear_recalc(bmain);
+}
+
 /* return default layer, also used to patch old files */
 SceneRenderLayer *BKE_scene_add_render_layer(Scene *sce, const char *name)
 {
diff --git a/source/blender/editors/io/io_cache_library.c b/source/blender/editors/io/io_cache_library.c
index 89a6f69..d8a6ed3 100644
--- a/source/blender/editors/io/io_cache_library.c
+++ b/source/blender/editors/io/io_cache_library.c
@@ -76,7 +76,7 @@
 
 #include "PTC_api.h"
 
-static int ED_cache_library_active_object_poll(bContext *C)
+#static int ED_cache_library_active_object_poll(bContext *C)
 {
 	Object *ob = CTX_data_active_object(C);
 	if (!(ob && (ob->transflag & OB_DUPLIGROUP) && ob->dup_group && ob->cache_library))
@@ -300,7 +300,7 @@ static void cache_library_bake_do(CacheLibraryBakeJob *data)
 		cache_library_bake_set_particle_baking(data->bmain, !init_strands);
 		
 		scene->r.cfra = frame;
-		BKE_scene_update_for_newframe(&data->eval_ctx, data->bmain, scene, scene->lay);
+		BKE_scene_update_group_for_newframe(&data->eval_ctx, data->bmain, scene, data->group, scene->lay);
 		
 		switch (data->cachelib->source_mode) {
 			case CACHE_LIBRARY_SOURCE_SCENE:




More information about the Bf-blender-cvs mailing list