diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-15 18:14:48 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-15 18:15:42 +0300 |
commit | ed3d693cb181c21c8d00b6d2aa734e25c2d65cda (patch) | |
tree | e44c3ea635efd5ee6c3b694bd856eb8f7d5de7a3 /source/blender/depsgraph | |
parent | 43d22d80e72d1a1bf49d33fc4f8bd1a031e3358b (diff) |
Dependency graph fixes for RigidBodyWorld
- rbw->group added to the depsgraph.
- Mesh evaluation added when necessary.
- Prevent of double-free by freeing the scene before objects.
Diffstat (limited to 'source/blender/depsgraph')
5 files changed, 39 insertions, 18 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index ba34d24d9d5..d4a115cfb8b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -897,6 +897,8 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene) /* objects - simulation participants */ if (rbw->group) { + build_collection(DEG_COLLECTION_OWNER_OBJECT, rbw->group); + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object) { if (object->type != OB_MESH) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 5312c7adac8..bc8528f6738 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1426,6 +1426,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) /* objects - simulation participants */ if (rbw->group) { + build_collection(DEG_COLLECTION_OWNER_OBJECT, NULL, rbw->group); + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object) { if (object->type != OB_MESH) { @@ -1447,6 +1449,13 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) add_relation(sim_key, rbo_key, "Rigidbody Sim Eval -> RBO Sync"); + /* Geometry must be known to create the rigid body. RBO_MESH_BASE uses the non-evaluated + * mesh, so then the evaluation is unnecessary. */ + if (object->rigidbody_object->mesh_source != RBO_MESH_BASE) { + ComponentKey geom_key(&object->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(geom_key, init_key, "Object Geom Eval -> Rigidbody Rebuild"); + } + /* if constraints exist, those depend on the result of the rigidbody sim * - This allows constraints to modify the result of the sim (i.e. clamping) * while still allowing the sim to depend on some changes to the objects. diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 26a23cff372..16427d3eb59 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -327,27 +327,33 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint) return id_node; } -void Depsgraph::clear_id_nodes() +void Depsgraph::clear_id_nodes_conditional(const std::function <bool (ID_Type id_type)>& filter) { - /* Free memory used by ID nodes. */ - { - /* Stupid workaround to ensure we free IDs in a proper order. */ - foreach (IDDepsNode *id_node, id_nodes) { - if (id_node->id_cow == NULL) { - /* This means builder "stole" ownership of the copy-on-written - * datablock for her own dirty needs. - */ - continue; - } - if (!deg_copy_on_write_is_expanded(id_node->id_cow)) { - continue; - } - const ID_Type id_type = GS(id_node->id_cow->name); - if (id_type != ID_PA) { - id_node->destroy(); - } + foreach (IDDepsNode *id_node, id_nodes) { + if (id_node->id_cow == NULL) { + /* This means builder "stole" ownership of the copy-on-written + * datablock for her own dirty needs. + */ + continue; + } + if (!deg_copy_on_write_is_expanded(id_node->id_cow)) { + continue; + } + const ID_Type id_type = GS(id_node->id_cow->name); + if (filter(id_type)) { + id_node->destroy(); } } +} + +void Depsgraph::clear_id_nodes() +{ + /* Free memory used by ID nodes. */ + + /* Stupid workaround to ensure we free IDs in a proper order. */ + clear_id_nodes_conditional([](ID_Type id_type) { return id_type == ID_SCE; }); + clear_id_nodes_conditional([](ID_Type id_type) { return id_type != ID_PA; }); + foreach (IDDepsNode *id_node, id_nodes) { OBJECT_GUARDED_DELETE(id_node, IDDepsNode); } diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 3c1233cd5bb..a69be39c50b 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -38,6 +38,8 @@ #include <stdlib.h> +#include "DNA_ID.h" /* for ID_Type */ + #include "BKE_library.h" /* for MAX_LIBARRAY */ #include "BLI_threads.h" /* for SpinLock */ @@ -128,6 +130,7 @@ struct Depsgraph { IDDepsNode *find_id_node(const ID *id) const; IDDepsNode *add_id_node(ID *id, ID *id_cow_hint = NULL); void clear_id_nodes(); + void clear_id_nodes_conditional(const std::function <bool (ID_Type id_type)>& filter); /* Add new relationship between two nodes. */ DepsRelation *add_new_relation(OperationDepsNode *from, diff --git a/source/blender/depsgraph/intern/nodes/deg_node_id.cc b/source/blender/depsgraph/intern/nodes/deg_node_id.cc index 956c23978ab..3a164a50692 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_id.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_id.cc @@ -156,6 +156,7 @@ void IDDepsNode::destroy() if (id_cow != id_orig && id_cow != NULL) { deg_free_copy_on_write_datablock(id_cow); MEM_freeN(id_cow); + id_cow = NULL; DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow); } |