diff options
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_query_filter.cc')
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_query_filter.cc | 292 |
1 files changed, 145 insertions, 147 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_query_filter.cc b/source/blender/depsgraph/intern/depsgraph_query_filter.cc index dbfc488d44e..987e9330d35 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_filter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_filter.cc @@ -26,7 +26,7 @@ #include "MEM_guardedalloc.h" extern "C" { -#include <string.h> // XXX: memcpy +#include <string.h> // XXX: memcpy #include "BLI_utildefines.h" #include "BKE_idcode.h" @@ -34,7 +34,7 @@ extern "C" { #include "BLI_listbase.h" #include "BLI_ghash.h" -#include "BKE_action.h" // XXX: BKE_pose_channel_from_name +#include "BKE_action.h" // XXX: BKE_pose_channel_from_name } /* extern "C" */ #include "DNA_object_types.h" @@ -56,7 +56,6 @@ extern "C" { #include "intern/node/deg_node_id.h" #include "intern/node/deg_node_operation.h" - /* *************************************************** */ /* Graph Filtering Internals */ @@ -64,8 +63,8 @@ namespace DEG { /* UserData for deg_add_retained_id_cb */ struct RetainedIdUserData { - DEG_FilterQuery *query; - GSet *set; + DEG_FilterQuery *query; + GSet *set; }; /* Helper for DEG_foreach_ancestor_id() @@ -73,8 +72,8 @@ struct RetainedIdUserData { */ static void deg_add_retained_id_cb(ID *id, void *user_data) { - RetainedIdUserData *data = (RetainedIdUserData *)user_data; - BLI_gset_add(data->set, (void *)id); + RetainedIdUserData *data = (RetainedIdUserData *)user_data; + BLI_gset_add(data->set, (void *)id); } /* ------------------------------------------- */ @@ -83,92 +82,87 @@ static void deg_add_retained_id_cb(ID *id, void *user_data) /* TODO: Make this part of OperationNode? */ static void deg_unlink_opnode(Depsgraph *graph, OperationNode *op_node) { - vector<Relation *> all_links; - - /* Collect all inlinks to this operation */ - for (Relation *rel : op_node->inlinks) { - all_links.push_back(rel); - } - /* Collect all outlinks from this operation */ - for (Relation *rel : op_node->outlinks) { - all_links.push_back(rel); - } - - /* Delete all collected relations */ - for (Relation *rel : all_links) { - rel->unlink(); - OBJECT_GUARDED_DELETE(rel, Relation); - } - - /* Remove from entry tags */ - if (BLI_gset_haskey(graph->entry_tags, op_node)) { - BLI_gset_remove(graph->entry_tags, op_node, NULL); - } + vector<Relation *> all_links; + + /* Collect all inlinks to this operation */ + for (Relation *rel : op_node->inlinks) { + all_links.push_back(rel); + } + /* Collect all outlinks from this operation */ + for (Relation *rel : op_node->outlinks) { + all_links.push_back(rel); + } + + /* Delete all collected relations */ + for (Relation *rel : all_links) { + rel->unlink(); + OBJECT_GUARDED_DELETE(rel, Relation); + } + + /* Remove from entry tags */ + if (BLI_gset_haskey(graph->entry_tags, op_node)) { + BLI_gset_remove(graph->entry_tags, op_node, NULL); + } } /* Remove every ID Node (and its associated subnodes, COW data) */ static void deg_filter_remove_unwanted_ids(Depsgraph *graph, GSet *retained_ids) { - /* 1) First pass over ID nodes + their operations - * - Identify and tag ID's (via "custom_flags = 1") to be removed - * - Remove all links to/from operations that will be removed. */ - for (IDNode *id_node : graph->id_nodes) { - id_node->custom_flags = !BLI_gset_haskey(retained_ids, (void *)id_node->id_orig); - if (id_node->custom_flags) { - GHASH_FOREACH_BEGIN(ComponentNode *, comp_node, id_node->components) - { - for (OperationNode *op_node : comp_node->operations) { - deg_unlink_opnode(graph, op_node); - } - } - GHASH_FOREACH_END(); - } - } - - /* 2) Remove unwanted operations from graph->operations */ - for (Depsgraph::OperationNodes::iterator it_opnode = graph->operations.begin(); - it_opnode != graph->operations.end(); - ) - { - OperationNode *op_node = *it_opnode; - IDNode *id_node = op_node->owner->owner; - if (id_node->custom_flags) { - it_opnode = graph->operations.erase(it_opnode); - } - else { - ++it_opnode; - } - } - - /* Free ID nodes that are no longer wanted - * - * This is loosely based on Depsgraph::clear_id_nodes(). - * However, we don't worry about the conditional freeing for physics - * stuff, since it's rarely needed currently. */ - for (Depsgraph::IDDepsNodes::iterator it_id = graph->id_nodes.begin(); - it_id != graph->id_nodes.end(); - ) - { - IDNode *id_node = *it_id; - ID *id = id_node->id_orig; - - if (id_node->custom_flags) { - /* Destroy node data, then remove from collections, and free */ - id_node->destroy(); - - BLI_ghash_remove(graph->id_hash, id, NULL, NULL); - it_id = graph->id_nodes.erase(it_id); - - OBJECT_GUARDED_DELETE(id_node, IDNode); - } - else { - /* This node has not been marked for deletion. Increment iterator */ - ++it_id; - } - } + /* 1) First pass over ID nodes + their operations + * - Identify and tag ID's (via "custom_flags = 1") to be removed + * - Remove all links to/from operations that will be removed. */ + for (IDNode *id_node : graph->id_nodes) { + id_node->custom_flags = !BLI_gset_haskey(retained_ids, (void *)id_node->id_orig); + if (id_node->custom_flags) { + GHASH_FOREACH_BEGIN (ComponentNode *, comp_node, id_node->components) { + for (OperationNode *op_node : comp_node->operations) { + deg_unlink_opnode(graph, op_node); + } + } + GHASH_FOREACH_END(); + } + } + + /* 2) Remove unwanted operations from graph->operations */ + for (Depsgraph::OperationNodes::iterator it_opnode = graph->operations.begin(); + it_opnode != graph->operations.end();) { + OperationNode *op_node = *it_opnode; + IDNode *id_node = op_node->owner->owner; + if (id_node->custom_flags) { + it_opnode = graph->operations.erase(it_opnode); + } + else { + ++it_opnode; + } + } + + /* Free ID nodes that are no longer wanted + * + * This is loosely based on Depsgraph::clear_id_nodes(). + * However, we don't worry about the conditional freeing for physics + * stuff, since it's rarely needed currently. */ + for (Depsgraph::IDDepsNodes::iterator it_id = graph->id_nodes.begin(); + it_id != graph->id_nodes.end();) { + IDNode *id_node = *it_id; + ID *id = id_node->id_orig; + + if (id_node->custom_flags) { + /* Destroy node data, then remove from collections, and free */ + id_node->destroy(); + + BLI_ghash_remove(graph->id_hash, id, NULL, NULL); + it_id = graph->id_nodes.erase(it_id); + + OBJECT_GUARDED_DELETE(id_node, IDNode); + } + else { + /* This node has not been marked for deletion. Increment iterator */ + ++it_id; + } + } } -} //namespace DEG +} //namespace DEG /* *************************************************** */ /* Graph Filtering API */ @@ -179,67 +173,71 @@ static void deg_filter_remove_unwanted_ids(Depsgraph *graph, GSet *retained_ids) */ Depsgraph *DEG_graph_filter(const Depsgraph *graph_src, Main *bmain, DEG_FilterQuery *query) { - const DEG::Depsgraph *deg_graph_src = reinterpret_cast<const DEG::Depsgraph *>(graph_src); - if (deg_graph_src == NULL) { - return NULL; - } - - /* Construct a full new depsgraph based on the one we got */ - /* TODO: Improve the builders to not add any ID nodes we don't need later (e.g. ProxyBuilder?) */ - Depsgraph *graph_new = DEG_graph_new(deg_graph_src->scene, - deg_graph_src->view_layer, - deg_graph_src->mode); - DEG_graph_build_from_view_layer(graph_new, - bmain, - deg_graph_src->scene, - deg_graph_src->view_layer); - - /* Build a set of all the id's we want to keep */ - GSet *retained_ids = BLI_gset_ptr_new(__func__); - DEG::RetainedIdUserData retained_id_data = {query, retained_ids}; - - LISTBASE_FOREACH (DEG_FilterTarget *, target, &query->targets) { - /* Target Itself */ - BLI_gset_add(retained_ids, (void *)target->id); - - /* Target's Ancestors (i.e. things it depends on) */ - DEG_foreach_ancestor_ID(graph_new, - target->id, - DEG::deg_add_retained_id_cb, - &retained_id_data); - } - - /* Remove everything we don't want to keep around anymore */ - DEG::Depsgraph *deg_graph_new = reinterpret_cast<DEG::Depsgraph *>(graph_new); - if (BLI_gset_len(retained_ids) > 0) { - DEG::deg_filter_remove_unwanted_ids(deg_graph_new, retained_ids); - } - // TODO: query->LOD filters - - /* Free temp data */ - BLI_gset_free(retained_ids, NULL); - retained_ids = NULL; - - /* Print Stats */ - // XXX: Hide behind debug flags - size_t s_outer, s_operations, s_relations; - size_t s_ids = deg_graph_src->id_nodes.size(); - unsigned int s_idh = BLI_ghash_len(deg_graph_src->id_hash); - - size_t n_outer, n_operations, n_relations; - size_t n_ids = deg_graph_new->id_nodes.size(); - unsigned int n_idh = BLI_ghash_len(deg_graph_new->id_hash); - - DEG_stats_simple(graph_src, &s_outer, &s_operations, &s_relations); - DEG_stats_simple(graph_new, &n_outer, &n_operations, &n_relations); - - printf("%s: src = (ID's: %zu (%u), Out: %zu, Op: %zu, Rel: %zu)\n", - __func__, s_ids, s_idh, s_outer, s_operations, s_relations); - printf("%s: new = (ID's: %zu (%u), Out: %zu, Op: %zu, Rel: %zu)\n", - __func__, n_ids, n_idh, n_outer, n_operations, n_relations); - - /* Return this new graph instance */ - return graph_new; + const DEG::Depsgraph *deg_graph_src = reinterpret_cast<const DEG::Depsgraph *>(graph_src); + if (deg_graph_src == NULL) { + return NULL; + } + + /* Construct a full new depsgraph based on the one we got */ + /* TODO: Improve the builders to not add any ID nodes we don't need later (e.g. ProxyBuilder?) */ + Depsgraph *graph_new = DEG_graph_new( + deg_graph_src->scene, deg_graph_src->view_layer, deg_graph_src->mode); + DEG_graph_build_from_view_layer( + graph_new, bmain, deg_graph_src->scene, deg_graph_src->view_layer); + + /* Build a set of all the id's we want to keep */ + GSet *retained_ids = BLI_gset_ptr_new(__func__); + DEG::RetainedIdUserData retained_id_data = {query, retained_ids}; + + LISTBASE_FOREACH (DEG_FilterTarget *, target, &query->targets) { + /* Target Itself */ + BLI_gset_add(retained_ids, (void *)target->id); + + /* Target's Ancestors (i.e. things it depends on) */ + DEG_foreach_ancestor_ID(graph_new, target->id, DEG::deg_add_retained_id_cb, &retained_id_data); + } + + /* Remove everything we don't want to keep around anymore */ + DEG::Depsgraph *deg_graph_new = reinterpret_cast<DEG::Depsgraph *>(graph_new); + if (BLI_gset_len(retained_ids) > 0) { + DEG::deg_filter_remove_unwanted_ids(deg_graph_new, retained_ids); + } + // TODO: query->LOD filters + + /* Free temp data */ + BLI_gset_free(retained_ids, NULL); + retained_ids = NULL; + + /* Print Stats */ + // XXX: Hide behind debug flags + size_t s_outer, s_operations, s_relations; + size_t s_ids = deg_graph_src->id_nodes.size(); + unsigned int s_idh = BLI_ghash_len(deg_graph_src->id_hash); + + size_t n_outer, n_operations, n_relations; + size_t n_ids = deg_graph_new->id_nodes.size(); + unsigned int n_idh = BLI_ghash_len(deg_graph_new->id_hash); + + DEG_stats_simple(graph_src, &s_outer, &s_operations, &s_relations); + DEG_stats_simple(graph_new, &n_outer, &n_operations, &n_relations); + + printf("%s: src = (ID's: %zu (%u), Out: %zu, Op: %zu, Rel: %zu)\n", + __func__, + s_ids, + s_idh, + s_outer, + s_operations, + s_relations); + printf("%s: new = (ID's: %zu (%u), Out: %zu, Op: %zu, Rel: %zu)\n", + __func__, + n_ids, + n_idh, + n_outer, + n_operations, + n_relations); + + /* Return this new graph instance */ + return graph_new; } /* *************************************************** */ |