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.
This commit is contained in:
Sybren A. Stüvel 2018-06-15 17:14:48 +02:00
parent 43d22d80e7
commit ed3d693cb1
5 changed files with 39 additions and 18 deletions

View File

@ -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)

View File

@ -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.

View File

@ -327,27 +327,33 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
return id_node;
}
void Depsgraph::clear_id_nodes_conditional(const std::function <bool (ID_Type id_type)>& filter)
{
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. */
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();
}
}
}
/* 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);
}

View File

@ -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,

View File

@ -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);
}