diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2017-04-04 22:39:57 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2017-04-04 22:39:57 +0300 |
commit | 7576ad3d043ac5d15e0c5a68e65339904441b5e7 (patch) | |
tree | bb990cce1eec04d45ab57e8a42af2669f9d7522f /source/blender/depsgraph | |
parent | 10b24eabbab0193f6944cdf3bec7b386c75d5445 (diff) | |
parent | db0f67f46454fd0bfeb886d3e61227b65fbc6ac1 (diff) |
Merge branch 'blender2.8' into transform-manipulatorstransform-manipulators
Conflicts:
intern/gawain/gawain/immediate.h
intern/gawain/src/immediate.c
source/blender/editors/physics/physics_ops.c
source/blender/editors/screen/glutil.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/transform/transform_manipulator.c
Diffstat (limited to 'source/blender/depsgraph')
19 files changed, 566 insertions, 204 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 2d32e85bf64..a266f30fe11 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -43,11 +43,13 @@ set(SRC intern/builder/deg_builder.cc intern/builder/deg_builder_cycle.cc intern/builder/deg_builder_nodes.cc + intern/builder/deg_builder_nodes_layer.cc intern/builder/deg_builder_nodes_rig.cc intern/builder/deg_builder_nodes_scene.cc intern/builder/deg_builder_pchanmap.cc intern/builder/deg_builder_relations.cc intern/builder/deg_builder_relations_keys.cc + intern/builder/deg_builder_relations_layer.cc intern/builder/deg_builder_relations_rig.cc intern/builder/deg_builder_relations_scene.cc intern/builder/deg_builder_transitive.cc diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index cb2f057a090..828da6cb056 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -77,28 +77,8 @@ static bool check_object_needs_evaluation(Object *object) return false; } -void deg_graph_build_finalize(Depsgraph *graph) +void deg_graph_build_flush_layers(Depsgraph *graph) { - /* STEP 1: Make sure new invisible dependencies are ready for use. - * - * TODO(sergey): This might do a bit of extra tagging, but it's kinda nice - * to do it ahead of a time and don't spend time on flushing updates on - * every frame change. - */ - GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash) - { - if (id_node->layers == 0) { - ID *id = id_node->id; - if (GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if (check_object_needs_evaluation(object)) { - id_node->tag_update(graph); - } - } - } - } - GHASH_FOREACH_END(); - /* STEP 2: Flush visibility layers from children to parent. */ std::stack<OperationDepsNode *> stack; foreach (OperationDepsNode *node, graph->operations) { IDDepsNode *id_node = node->owner->owner; @@ -143,6 +123,31 @@ void deg_graph_build_finalize(Depsgraph *graph) } } } +} + +void deg_graph_build_finalize(Depsgraph *graph) +{ + /* STEP 1: Make sure new invisible dependencies are ready for use. + * + * TODO(sergey): This might do a bit of extra tagging, but it's kinda nice + * to do it ahead of a time and don't spend time on flushing updates on + * every frame change. + */ + GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash) + { + if (id_node->layers == 0) { + ID *id = id_node->id; + if (GS(id->name) == ID_OB) { + Object *object = (Object *)id; + if (check_object_needs_evaluation(object)) { + id_node->tag_update(graph); + } + } + } + } + GHASH_FOREACH_END(); + /* STEP 2: Flush visibility layers from children to parent. */ + deg_graph_build_flush_layers(graph); /* STEP 3: Re-tag IDs for update if it was tagged before the relations * update tag. */ @@ -154,7 +159,7 @@ void deg_graph_build_finalize(Depsgraph *graph) } GHASH_FOREACH_END(); - if ((id_node->layers & graph->layers) != 0) { + if ((id_node->layers & graph->layers) != 0 || graph->layers == 0) { ID *id = id_node->id; if ((id->tag & LIB_TAG_ID_RECALC_ALL) && (id->tag & LIB_TAG_DOIT)) diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h index bdc030e3810..3cc51a2d7db 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.h +++ b/source/blender/depsgraph/intern/builder/deg_builder.h @@ -42,5 +42,6 @@ struct Depsgraph; string deg_fcurve_id_name(const FCurve *fcu); void deg_graph_build_finalize(struct Depsgraph *graph); +void deg_graph_build_flush_layers(struct Depsgraph *graph); } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 0f0d16907f4..b6071b10757 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -433,7 +433,7 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob) } /* Object data. */ - if (ob->data) { + if (ob->data != NULL) { /* type-specific data... */ switch (ob->type) { case OB_MESH: /* Geometry */ @@ -491,14 +491,25 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob) build_animdata(&ob->id); /* particle systems */ - if (ob->particlesystem.first) { + if (ob->particlesystem.first != NULL) { build_particles(scene, ob); } - /* grease pencil */ - if (ob->gpd) { + /* Grease pencil. */ + if (ob->gpd != NULL) { build_gpencil(ob->gpd); } + + /* Object that this is a proxy for. */ + if (ob->proxy) { + ob->proxy->proxy_from = ob; + build_object(scene, ob->proxy); + } + + /* Object dupligroup. */ + if (ob->dup_group != NULL) { + build_group(scene, ob->dup_group); + } } void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob) @@ -735,7 +746,8 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) */ /* component for all particle systems */ - ComponentDepsNode *psys_comp = add_component_node(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES); + ComponentDepsNode *psys_comp = + add_component_node(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES); /* particle systems */ LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { @@ -748,11 +760,12 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) /* this particle system */ // TODO: for now, this will just be a placeholder "ubereval" node add_operation_node(psys_comp, - DEPSOP_TYPE_EXEC, function_bind(BKE_particle_system_eval, - _1, - scene, - ob, - psys), + DEPSOP_TYPE_EXEC, + function_bind(BKE_particle_system_eval, + _1, + scene, + ob, + psys), DEG_OPCODE_PSYS_EVAL, psys->name); } @@ -761,6 +774,20 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob) // TODO... } +void DepsgraphNodeBuilder::build_cloth(Scene *scene, Object *object) +{ + ComponentDepsNode *cache_comp = add_component_node(&object->id, + DEPSNODE_TYPE_CACHE); + add_operation_node(cache_comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_object_eval_cloth, + _1, + scene, + object), + DEG_OPCODE_PLACEHOLDER, + "Cloth Modifier"); +} + /* Shapekeys */ void DepsgraphNodeBuilder::build_shapekeys(Key *key) { @@ -822,6 +849,9 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) md), DEG_OPCODE_GEOMETRY_MODIFIER, md->name); + if (md->type == eModifierType_Cloth) { + build_cloth(scene, ob); + } } /* materials */ @@ -835,8 +865,8 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) add_operation_node(&ob->id, DEPSNODE_TYPE_SHADING, DEPSOP_TYPE_EXEC, - function_bind(BKE_object_eval_shading, _1, ob), - DEG_OPCODE_OPERATION, "Material Update"); + NULL, + DEG_OPCODE_PLACEHOLDER, "Material Update"); } /* geometry collision */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 2f3f733b8db..d28aaf6a10a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -41,6 +41,7 @@ struct Image; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Material; struct Mask; @@ -132,6 +133,7 @@ struct DepsgraphNodeBuilder { void build_pose_constraints(Object *ob, bPoseChannel *pchan); void build_rigidbody(Scene *scene); void build_particles(Scene *scene, Object *ob); + void build_cloth(Scene *scene, Object *object); void build_animdata(ID *id); OperationDepsNode *build_driver(ID *id, FCurve *fcurve); void build_ik_pose(Scene *scene, @@ -160,6 +162,17 @@ struct DepsgraphNodeBuilder { void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); + struct LayerCollectionState { + int index; + LayerCollection *parent; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); protected: Main *m_bmain; Depsgraph *m_graph; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc new file mode 100644 index 00000000000..494ae585272 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc @@ -0,0 +1,121 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph's nodes + */ + +#include "intern/builder/deg_builder_nodes.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_utildefines.h" + +#include "BKE_layer.h" + +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" +#include "intern/depsgraph_types.h" +#include "intern/depsgraph_intern.h" +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphNodeBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + /* TODO(sergey): This will attempt to create component for each collection. + * Harmless but could be optimized. + */ + ComponentDepsNode *comp = add_component_node(&scene->id, DEPSNODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection, + _1, + scene, + layer_collection, + state->parent), + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + ++state->index; + + /* Recurs into nested layer collections. */ + LayerCollection *parent = state->parent; + state->parent = layer_collection; + build_layer_collections(scene, &layer_collection->layer_collections, state); + state->parent = parent; +} + +void DepsgraphNodeBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + ComponentDepsNode *comp = add_component_node(&scene->id, DEPSNODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection_pre, _1, scene, scene_layer), + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + add_operation_node(comp, + DEPSOP_TYPE_EXEC, + function_bind(BKE_layer_eval_layer_collection_post, _1, scene_layer), + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.parent = NULL; + build_layer_collections(scene, &scene_layer->layer_collections, &state); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index c7e8edb122e..3f9febc1228 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -80,23 +80,10 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) } /* scene objects */ - Object *ob; FOREACH_SCENE_OBJECT(scene, ob) { /* object itself */ build_object(scene, ob); - - /* object that this is a proxy for */ - // XXX: the way that proxies work needs to be completely reviewed! - if (ob->proxy) { - ob->proxy->proxy_from = ob; - build_object(scene, ob->proxy); - } - - /* Object dupligroup. */ - if (ob->dup_group) { - build_group(scene, ob->dup_group); - } } FOREACH_SCENE_OBJECT_END @@ -142,6 +129,9 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) LINKLIST_FOREACH (MovieClip *, clip, &bmain->movieclip) { build_movieclip(clip); } + + /* Collections. */ + build_scene_layer_collections(scene); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 6d4597fed9d..da788297a2f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -396,30 +396,52 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o OperationKey ob_ubereval_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL); /* parenting */ - if (ob->parent) { + if (ob->parent != NULL) { /* parent relationship */ build_object_parent(ob); /* local -> parent */ - add_relation(local_transform_key, parent_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "[ObLocal -> ObParent]"); + add_relation(local_transform_key, + parent_transform_key, + DEPSREL_TYPE_COMPONENT_ORDER, + "[ObLocal -> ObParent]"); } /* object constraints */ - if (ob->constraints.first) { - OperationKey constraint_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_CONSTRAINTS); + if (ob->constraints.first != NULL) { + OperationKey constraint_key(&ob->id, + DEPSNODE_TYPE_TRANSFORM, + DEG_OPCODE_TRANSFORM_CONSTRAINTS); /* constraint relations */ // TODO: provide base op // XXX: this is broken - build_constraints(scene, &ob->id, DEPSNODE_TYPE_TRANSFORM, "", &ob->constraints, NULL); + build_constraints(scene, + &ob->id, + DEPSNODE_TYPE_TRANSFORM, + "", + &ob->constraints, + NULL); /* operation order */ - add_relation(base_op_key, constraint_key, DEPSREL_TYPE_COMPONENT_ORDER, "[ObBase-> Constraint Stack]"); - add_relation(constraint_key, final_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "[ObConstraints -> Done]"); + add_relation(base_op_key, + constraint_key, + DEPSREL_TYPE_COMPONENT_ORDER, + "[ObBase-> Constraint Stack]"); + add_relation(constraint_key, + final_transform_key, + DEPSREL_TYPE_COMPONENT_ORDER, + "[ObConstraints -> Done]"); // XXX - add_relation(constraint_key, ob_ubereval_key, DEPSREL_TYPE_COMPONENT_ORDER, "Temp Ubereval"); - add_relation(ob_ubereval_key, final_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "Temp Ubereval"); + add_relation(constraint_key, + ob_ubereval_key, + DEPSREL_TYPE_COMPONENT_ORDER, + "Temp Ubereval"); + add_relation(ob_ubereval_key, + final_transform_key, + DEPSREL_TYPE_COMPONENT_ORDER, + "Temp Ubereval"); } else { /* NOTE: Keep an eye here, we skip some relations here to "streamline" @@ -448,7 +470,10 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o // XXX: This should be hooked up by the build_animdata code if (needs_animdata_node(&ob->id)) { ComponentKey adt_key(&ob->id, DEPSNODE_TYPE_ANIMATION); - add_relation(adt_key, local_transform_key, DEPSREL_TYPE_OPERATION, "Object Animation"); + add_relation(adt_key, + local_transform_key, + DEPSREL_TYPE_OPERATION, + "Object Animation"); } @@ -494,25 +519,48 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o if (key != NULL) { ComponentKey geometry_key((ID *)ob->data, DEPSNODE_TYPE_GEOMETRY); ComponentKey key_key(&key->id, DEPSNODE_TYPE_GEOMETRY); - add_relation(key_key, geometry_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Shapekeys"); + add_relation(key_key, + geometry_key, + DEPSREL_TYPE_GEOMETRY_EVAL, + "Shapekeys"); } } - /* particle systems */ - if (ob->particlesystem.first) { + /* Particle systems. */ + if (ob->particlesystem.first != NULL) { build_particles(scene, ob); } - /* grease pencil */ - if (ob->gpd) { + /* Grease pencil. */ + if (ob->gpd != NULL) { build_gpencil(ob->gpd); } + + /* Object that this is a proxy for. */ + if (ob->proxy != NULL) { + ob->proxy->proxy_from = ob; + build_object(bmain, scene, ob->proxy); + /* TODO(sergey): This is an inverted relation, matches old depsgraph + * behavior and need to be investigated if it still need to be inverted. + */ + ComponentKey ob_pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); + ComponentKey proxy_pose_key(&ob->proxy->id, DEPSNODE_TYPE_EVAL_POSE); + add_relation(ob_pose_key, proxy_pose_key, DEPSREL_TYPE_TRANSFORM, "Proxy"); + } + + /* Object dupligroup. */ + if (ob->dup_group != NULL) { + build_group(bmain, scene, ob, ob->dup_group); + } } void DepsgraphRelationBuilder::build_object_parent(Object *ob) { - /* XXX: for now, need to use the component key (not just direct to the parent op), or else the matrix doesn't get reset */ - // XXX: @sergey - it would be good if we got that backwards flushing working when tagging for updates + /* XXX: for now, need to use the component key (not just direct to the parent op), + * or else the matrix doesn't get reset/ + */ + // XXX: @sergey - it would be good if we got that backwards flushing working + // when tagging for updates. //OperationKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT); ComponentKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); @@ -1312,6 +1360,25 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) // TODO... } +void DepsgraphRelationBuilder::build_cloth(Scene * /*scene*/, + Object *object, + ModifierData *md) +{ + OperationKey cache_key(&object->id, + DEPSNODE_TYPE_CACHE, + DEG_OPCODE_PLACEHOLDER, + "Cloth Modifier"); + /* Cache component affects on modifier. */ + OperationKey modifier_key(&object->id, + DEPSNODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_MODIFIER, + md->name); + add_relation(cache_key, + modifier_key, + DEPSREL_TYPE_TIME, + "Cloth Cache -> Cloth"); +} + /* Shapekeys */ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key) { @@ -1413,6 +1480,10 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje } } + if (md->type == eModifierType_Cloth) { + build_cloth(scene, ob, md); + } + prev_mod_key = mod_key; } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 2e6fa7b5801..557f2dd36b8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -54,10 +54,12 @@ struct ID; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Mask; struct Material; struct MTex; +struct ModifierData; struct MovieClip; struct bNodeTree; struct Object; @@ -205,6 +207,7 @@ struct DepsgraphRelationBuilder void build_world(World *world); void build_rigidbody(Scene *scene); void build_particles(Scene *scene, Object *ob); + void build_cloth(Scene *scene, Object *object, ModifierData *md); void build_ik_pose(Object *ob, bPoseChannel *pchan, bConstraint *con, @@ -232,6 +235,20 @@ struct DepsgraphRelationBuilder void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name); void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name); + struct LayerCollectionState { + int index; + OperationKey init_key; + OperationKey done_key; + OperationKey prev_key; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); + template <typename KeyType> OperationDepsNode *find_operation_node(const KeyType &key); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc new file mode 100644 index 00000000000..46bef7a0131 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc @@ -0,0 +1,134 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph + */ + +#include "intern/builder/deg_builder_relations.h" + +#include <stdio.h> +#include <stdlib.h> +#include <cstring> /* required for STREQ later on. */ + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/builder/deg_builder_pchanmap.h" + +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" + +#include "intern/depsgraph_intern.h" +#include "intern/depsgraph_types.h" + +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphRelationBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + OperationKey layer_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + add_relation(state->prev_key, + layer_key, + DEPSREL_TYPE_OPERATION, + "Layer collection order"); + + ++state->index; + state->prev_key = layer_key; + + /* Recurs into nested layer collections. */ + build_layer_collections(scene, + &layer_collection->layer_collections, + state); +} + +void DepsgraphRelationBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + /* Recurs into the layer. */ + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphRelationBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + OperationKey init_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + OperationKey done_key(&scene->id, + DEPSNODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.init_key = init_key; + state.done_key = done_key; + state.prev_key = init_key; + + build_layer_collections(scene, + &scene_layer->layer_collections, + &state); + + + add_relation(state.prev_key, + done_key, + DEPSREL_TYPE_OPERATION, + "Layer collection order"); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index 2f49d5b1645..3a007c4153a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -75,28 +75,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) } /* scene objects */ - Object *ob; FOREACH_SCENE_OBJECT(scene, ob) { - /* object itself */ build_object(bmain, scene, ob); - - /* object that this is a proxy for */ - if (ob->proxy) { - ob->proxy->proxy_from = ob; - build_object(bmain, scene, ob->proxy); - /* TODO(sergey): This is an inverted relation, matches old depsgraph - * behavior and need to be investigated if it still need to be inverted. - */ - ComponentKey ob_pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE); - ComponentKey proxy_pose_key(&ob->proxy->id, DEPSNODE_TYPE_EVAL_POSE); - add_relation(ob_pose_key, proxy_pose_key, DEPSREL_TYPE_TRANSFORM, "Proxy"); - } - - /* Object dupligroup. */ - if (ob->dup_group) { - build_group(bmain, scene, ob, ob->dup_group); - } } FOREACH_SCENE_OBJECT_END @@ -135,6 +116,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) build_movieclip(clip); } + /* Collections. */ + build_scene_layer_collections(scene); + for (Depsgraph::OperationNodes::const_iterator it_op = m_graph->operations.begin(); it_op != m_graph->operations.end(); ++it_op) diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 0d56ce71c7d..d49d5e1b000 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -83,15 +83,16 @@ static const int deg_debug_node_type_color_map[][2] = { {DEPSNODE_TYPE_SUBGRAPH, 3}, /* Outer Types */ - {DEPSNODE_TYPE_PARAMETERS, 4}, - {DEPSNODE_TYPE_PROXY, 5}, - {DEPSNODE_TYPE_ANIMATION, 6}, - {DEPSNODE_TYPE_TRANSFORM, 7}, - {DEPSNODE_TYPE_GEOMETRY, 8}, - {DEPSNODE_TYPE_SEQUENCER, 9}, - {DEPSNODE_TYPE_SHADING, 10}, - {DEPSNODE_TYPE_CACHE, 11}, - {-1, 0} + {DEPSNODE_TYPE_PARAMETERS, 4}, + {DEPSNODE_TYPE_PROXY, 5}, + {DEPSNODE_TYPE_ANIMATION, 6}, + {DEPSNODE_TYPE_TRANSFORM, 7}, + {DEPSNODE_TYPE_GEOMETRY, 8}, + {DEPSNODE_TYPE_SEQUENCER, 9}, + {DEPSNODE_TYPE_SHADING, 10}, + {DEPSNODE_TYPE_CACHE, 11}, + {DEPSNODE_TYPE_LAYER_COLLECTIONS, 12}, + {-1, 0} }; #endif @@ -403,6 +404,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, case DEPSNODE_TYPE_BONE: case DEPSNODE_TYPE_SHADING: case DEPSNODE_TYPE_CACHE: + case DEPSNODE_TYPE_LAYER_COLLECTIONS: case DEPSNODE_TYPE_EVAL_PARTICLES: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index a9df68beb36..8e7f8e01a59 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -56,8 +56,8 @@ extern "C" { #include "DEG_depsgraph.h" } /* extern "C" */ +#include "intern/builder/deg_builder.h" #include "intern/eval/deg_eval_flush.h" - #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_component.h" #include "intern/nodes/deg_node_operation.h" @@ -348,6 +348,27 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene) GHASH_FOREACH_END(); } scene->lay_updated |= graph->layers; + /* Special trick to get local view to work. */ + LINKLIST_FOREACH (Base *, base, &scene->base) { + Object *object = base->object; + DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); + id_node->layers = 0; + } + LINKLIST_FOREACH (Base *, base, &scene->base) { + Object *object = base->object; + DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); + id_node->layers |= base->lay; + } + DEG::deg_graph_build_flush_layers(graph); + LINKLIST_FOREACH (Base *, base, &scene->base) { + Object *object = base->object; + DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); + GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp, id_node->components) + { + id_node->layers |= comp->layers; + } + GHASH_FOREACH_END(); + } } void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time)) diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 39c189629f2..6c3e3805169 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -130,6 +130,10 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(BONE_DONE); STRINGIFY_OPCODE(PSYS_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_INIT); + STRINGIFY_OPCODE(SCENE_LAYER_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_DONE); + case DEG_NUM_OPCODES: return "SpecialCase"; #undef STRINGIFY_OPCODE } diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index effd34a0eb9..6b9a6e0191e 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -44,9 +44,6 @@ #include <string> #include <vector> -using std::string; -using std::vector; - struct bAction; struct ChannelDriver; struct ModifierData; @@ -56,6 +53,9 @@ struct FCurve; namespace DEG { +using std::string; +using std::vector; + /* Evaluation Operation for atomic operation */ // XXX: move this to another header that can be exposed? typedef function<void(struct EvaluationContext *)> DepsEvalOperationCb; @@ -89,52 +89,54 @@ typedef enum eDepsNode_Type { /* **** Generic Types **** */ /* "Current Scene" - basically whatever kicks off the evaluation process. */ - DEPSNODE_TYPE_ROOT = 1, + DEPSNODE_TYPE_ROOT, /* Time-Source */ - DEPSNODE_TYPE_TIMESOURCE = 2, + DEPSNODE_TYPE_TIMESOURCE, /* ID-Block reference - used as landmarks/collection point for components, * but not usually part of main graph. */ - DEPSNODE_TYPE_ID_REF = 3, + DEPSNODE_TYPE_ID_REF, /* Isolated sub-graph - used for keeping instanced data separate from * instances using them. */ - DEPSNODE_TYPE_SUBGRAPH = 4, + DEPSNODE_TYPE_SUBGRAPH, /* **** Outer Types **** */ /* Parameters Component - Default when nothing else fits * (i.e. just SDNA property setting). */ - DEPSNODE_TYPE_PARAMETERS = 11, + DEPSNODE_TYPE_PARAMETERS, /* Generic "Proxy-Inherit" Component * XXX: Also for instancing of subgraphs? */ - DEPSNODE_TYPE_PROXY = 12, + DEPSNODE_TYPE_PROXY, /* Animation Component * * XXX: merge in with parameters? */ - DEPSNODE_TYPE_ANIMATION = 13, + DEPSNODE_TYPE_ANIMATION, /* Transform Component (Parenting/Constraints) */ - DEPSNODE_TYPE_TRANSFORM = 14, + DEPSNODE_TYPE_TRANSFORM, /* Geometry Component (DerivedMesh/Displist) */ - DEPSNODE_TYPE_GEOMETRY = 15, + DEPSNODE_TYPE_GEOMETRY, /* Sequencer Component (Scene Only) */ - DEPSNODE_TYPE_SEQUENCER = 16, + DEPSNODE_TYPE_SEQUENCER, /* **** Evaluation-Related Outer Types (with Subdata) **** */ /* Pose Component - Owner/Container of Bones Eval */ - DEPSNODE_TYPE_EVAL_POSE = 21, + DEPSNODE_TYPE_EVAL_POSE, /* Bone Component - Child/Subcomponent of Pose */ - DEPSNODE_TYPE_BONE = 22, + DEPSNODE_TYPE_BONE, /* Particle Systems Component */ - DEPSNODE_TYPE_EVAL_PARTICLES = 23, + DEPSNODE_TYPE_EVAL_PARTICLES, /* Material Shading Component */ - DEPSNODE_TYPE_SHADING = 24, + DEPSNODE_TYPE_SHADING, /* Cache Component */ - DEPSNODE_TYPE_CACHE = 25, + DEPSNODE_TYPE_CACHE, + /* Component which contains all operations needed for layer collections evaluation. */ + DEPSNODE_TYPE_LAYER_COLLECTIONS, } eDepsNode_Type; /* Identifiers for common operations (as an enum). */ @@ -243,6 +245,11 @@ typedef enum eDepsOperation_Code { /* XXX: placeholder - Particle System eval */ DEG_OPCODE_PSYS_EVAL, + /* Collections ------------------------------------- */ + DEG_OPCODE_SCENE_LAYER_INIT, + DEG_OPCODE_SCENE_LAYER_EVAL, + DEG_OPCODE_SCENE_LAYER_DONE, + DEG_NUM_OPCODES, } eDepsOperation_Code; diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 3a042535d26..e739bc9dbb5 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -95,105 +95,38 @@ static void deg_task_run_func(TaskPool *pool, /* Should only be the case for NOOPs, which never get to this point. */ BLI_assert(node->evaluate); - while (true) { - /* Get context. */ - /* TODO: Who initialises this? "Init" operations aren't able to - * initialise it!!! - */ - /* TODO(sergey): We don't use component contexts at this moment. */ - /* ComponentDepsNode *comp = node->owner; */ - BLI_assert(node->owner != NULL); - - /* Since we're not leaving the thread for until the graph branches it is - * possible to have NO-OP on the way. for which evaluate() will be NULL. - * but that's all fine, we'll just scheduler it's children. - */ - if (node->evaluate) { + /* Get context. */ + /* TODO: Who initialises this? "Init" operations aren't able to + * initialise it!!! + */ + /* TODO(sergey): We don't use component contexts at this moment. */ + /* ComponentDepsNode *comp = node->owner; */ + BLI_assert(node->owner != NULL); + + /* Since we're not leaving the thread for until the graph branches it is + * possible to have NO-OP on the way. for which evaluate() will be NULL. + * but that's all fine, we'll just scheduler it's children. + */ + if (node->evaluate) { /* Take note of current time. */ #ifdef USE_DEBUGGER - double start_time = PIL_check_seconds_timer(); - DepsgraphDebug::task_started(state->graph, node); + double start_time = PIL_check_seconds_timer(); + DepsgraphDebug::task_started(state->graph, node); #endif - /* Perform operation. */ - node->evaluate(state->eval_ctx); + /* Perform operation. */ + node->evaluate(state->eval_ctx); /* Note how long this took. */ #ifdef USE_DEBUGGER - double end_time = PIL_check_seconds_timer(); - DepsgraphDebug::task_completed(state->graph, - node, - end_time - start_time); + double end_time = PIL_check_seconds_timer(); + DepsgraphDebug::task_completed(state->graph, + node, + end_time - start_time); #endif - } - - /* If there's only one outgoing link we try to immediately switch to - * that node evaluation, without leaving the thread. - * - * It's only doable if the child don't have extra relations or all they - * are satisfied. - * - * TODO(sergey): Checks here can be de-duplicated with the ones from - * schedule_node(), however, how to do it nicely? - */ - if (node->outlinks.size() == 1) { - DepsRelation *rel = node->outlinks[0]; - OperationDepsNode *child = (OperationDepsNode *)rel->to; - BLI_assert(child->type == DEPSNODE_TYPE_OPERATION); - if (!child->scheduled) { - unsigned int id_layers = child->owner->owner->layers; - if (!((child->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 && - (id_layers & state->layers) != 0)) - { - /* Node does not need an update, so can;t continue with the - * chain and need to switch to another one by leaving the - * thread. - */ - break; - } - if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { - BLI_assert(child->num_links_pending > 0); - atomic_sub_and_fetch_uint32(&child->num_links_pending, 1); - } - if (child->num_links_pending == 0) { - bool is_scheduled = atomic_fetch_and_or_uint8( - (uint8_t *)&child->scheduled, (uint8_t)true); - if (!is_scheduled) { - /* Node was not scheduled, switch to it! */ - node = child; - } - else { - /* Someone else scheduled the node, leaving us - * unemployed in this thread, we're leaving. - */ - break; - } - } - else { - /* There are other dependencies on the child, can't do - * anything in the current thread. - */ - break; - } - } - else { - /* Happens when having cyclic dependencies. - * - * Nothing to do here, single child was already scheduled, we - * can leave the thread now. - */ - break; - } - } - else { - /* TODO(sergey): It's possible to use one of the outgoing relations - * as a chain which we'll try to keep alive, but it's a bit more - * involved change. - */ - schedule_children(pool, state->graph, node, state->layers, thread_id); - break; - } } + + schedule_children(pool, state->graph, node, state->layers, thread_id); } typedef struct CalculatePengindData { @@ -378,12 +311,19 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, state.graph = graph; state.layers = layers; - TaskScheduler *task_scheduler = BLI_task_scheduler_get(); - TaskPool *task_pool = BLI_task_pool_create(task_scheduler, &state); + TaskScheduler *task_scheduler; + bool need_free_scheduler; if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) { - BLI_pool_set_num_threads(task_pool, 1); + task_scheduler = BLI_task_scheduler_create(1); + need_free_scheduler = true; } + else { + task_scheduler = BLI_task_scheduler_get(); + need_free_scheduler = false; + } + + TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); calculate_pending_parents(graph, layers); @@ -410,6 +350,10 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, /* Clear any uncleared tags - just in case. */ deg_graph_clear_tags(graph); + + if (need_free_scheduler) { + BLI_task_scheduler_free(task_scheduler); + } } } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 7c6c25bef0d..e10f86f6e95 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -180,6 +180,11 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) comp_node->done = 1; /* Flush to nodes along links... */ + /* TODO(sergey): This is mainly giving speedup due ot less queue pushes, which + * reduces number of memory allocations. + * + * We should try solve the allocation issue instead of doing crazy things here. + */ if (node->outlinks.size() == 1) { OperationDepsNode *to_node = (OperationDepsNode *)node->outlinks[0]->to; if (to_node->scheduled == false) { diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 06f91ac7fdc..9549cbcfeef 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -406,6 +406,11 @@ static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING; DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEPSNODE_TYPE_CACHE, "Cache Component"); static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE; +/* Layer COllections Defines ============================ */ + +DEG_DEPSNODE_DEFINE(LayerCollectionsDepsNode, DEPSNODE_TYPE_LAYER_COLLECTIONS, "Layer Collections Component"); +static DepsNodeFactoryImpl<LayerCollectionsDepsNode> DNTI_LAYER_COLLECTIONS; + /* Node Types Register =================================== */ @@ -425,6 +430,8 @@ void deg_register_component_depsnodes() deg_register_node_typeinfo(&DNTI_SHADING); deg_register_node_typeinfo(&DNTI_CACHE); + + deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 969771a29c9..bb94401562d 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -201,6 +201,10 @@ struct CacheComponentDepsNode : public ComponentDepsNode { DEG_DEPSNODE_DECLARE; }; +struct LayerCollectionsDepsNode : public ComponentDepsNode { + DEG_DEPSNODE_DECLARE; +}; + void deg_register_component_depsnodes(); |