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:

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to