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>2019-09-20 18:37:14 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-09-25 15:40:06 +0300
commiteb2ed0ea7a2c4090b8e2f239a40da03d6ee29900 (patch)
tree26a8034d942e688ff7bc4007612cf1c0cffaff36 /source/blender/depsgraph/intern/depsgraph_build.cc
parent6aadfa243de3736d48400ceb8eae81febeffd987 (diff)
Depsgraph: Implement builder from given set of IDs
The title explains it all actually: this commit introduces special dependency graph builder API which builds graph which is sufficient to evaluate given set of IDs.
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_build.cc')
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc141
1 files changed, 141 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index e34c8af0cf3..f67ab381c79 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -324,6 +324,147 @@ void DEG_graph_build_for_compositor_preview(
}
}
+/* Optimized builders for dependency graph built from a given set of IDs.
+ *
+ * General notes:
+ *
+ * - We pull in all bases if their objects are in the set of IDs. This allows to have proper
+ * visibility and other flags assigned to the objects.
+ * All other bases (the ones which points to object which is outside of the set of IDs) are
+ * completely ignored.
+ *
+ * - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
+ * This way we avoid high-poly character body pulled into the dependency graph when it's coming
+ * from a library into an animation file and the dependency graph constructed for a proxy rig. */
+
+namespace DEG {
+namespace {
+
+class DepsgraphFromIDsFilter {
+ public:
+ DepsgraphFromIDsFilter(ID **ids, const int num_ids)
+ {
+ for (int i = 0; i < num_ids; ++i) {
+ ids_.insert(ids[0]);
+ }
+ }
+
+ bool contains(ID *id)
+ {
+ return ids_.find(id) != ids_.end();
+ }
+
+ protected:
+ set<ID *> ids_;
+};
+
+class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
+ public:
+ DepsgraphFromIDsNodeBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object, bool is_visible) override
+ {
+ if (object->proxy_group == NULL) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
+ public:
+ DepsgraphFromIDsRelationBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object) override
+ {
+ if (object->proxy_group == NULL) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphRelationBuilder::build_object_proxy_group(object);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+} // namespace
+} // namespace DEG
+
+void DEG_graph_build_from_ids(Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ID **ids,
+ const int num_ids)
+{
+ double start_time = 0.0;
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ start_time = PIL_check_seconds_timer();
+ }
+ DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+ /* Perform sanity checks. */
+ BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
+ BLI_assert(deg_graph->scene == scene);
+ BLI_assert(deg_graph->view_layer == view_layer);
+ DEG::DepsgraphBuilderCache builder_cache;
+ /* Generate all the nodes in the graph first */
+ DEG::DepsgraphFromIDsNodeBuilder node_builder(bmain, deg_graph, &builder_cache, ids, num_ids);
+ node_builder.begin_build();
+ node_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids; ++i) {
+ node_builder.build_id(ids[i]);
+ }
+ node_builder.end_build();
+ /* Hook up relationships between operations - to determine evaluation order. */
+ DEG::DepsgraphFromIDsRelationBuilder relation_builder(
+ bmain, deg_graph, &builder_cache, ids, num_ids);
+ relation_builder.begin_build();
+ relation_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids; ++i) {
+ relation_builder.build_id(ids[i]);
+ }
+ relation_builder.build_copy_on_write_relations();
+ /* Finalize building. */
+ graph_build_finalize_common(deg_graph, bmain);
+ /* Finish statistics. */
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
+ }
+}
+
/* Tag graph relations for update. */
void DEG_graph_tag_relations_update(Depsgraph *graph)
{