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:
parent
43d22d80e7
commit
ed3d693cb1
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue