Depsgraph: support depending on collection geometry
This fixes T87666 and T83252. The boolean modifier and geometry nodes can depend on the geometry of an entire collection. Before, the modifiers had to manually create relations to all the objects in the collection. This worked for the most part, but was cumbersome and did not solve all issues. For example, the modifiers were not properly updated when objects were added/removed from the referenced collection. This commit introduces the concept of "collection geometry" in the depsgraph. The geometry of a collection depends on the transforms and geometry of all the objects in it. The boolean modifier and geometry nodes can now just depend on the collection geometry instead of creating all the dependencies themselves. Differential Revision: https://developer.blender.org/D11053
This commit is contained in:
@@ -40,6 +40,7 @@ struct Object;
|
||||
struct Scene;
|
||||
struct Simulation;
|
||||
struct bNodeTree;
|
||||
struct Collection;
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
@@ -137,6 +138,12 @@ void DEG_add_object_relation(struct DepsNodeHandle *node_handle,
|
||||
struct Object *object,
|
||||
eDepsObjectComponentType component,
|
||||
const char *description);
|
||||
void DEG_add_collection_geometry_relation(struct DepsNodeHandle *node_handle,
|
||||
struct Collection *collection,
|
||||
const char *description);
|
||||
void DEG_add_collection_geometry_customdata_mask(struct DepsNodeHandle *node_handle,
|
||||
struct Collection *collection,
|
||||
const struct CustomData_MeshMasks *masks);
|
||||
void DEG_add_simulation_relation(struct DepsNodeHandle *node_handle,
|
||||
struct Simulation *simulation,
|
||||
const char *description);
|
||||
|
@@ -554,6 +554,7 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
|
||||
id_node->is_directly_visible = is_collection_visible;
|
||||
|
||||
build_idproperties(collection->id.properties);
|
||||
add_operation_node(&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE);
|
||||
}
|
||||
if (from_layer_collection != nullptr) {
|
||||
/* If we came from layer collection we don't go deeper, view layer
|
||||
|
@@ -635,11 +635,38 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
|
||||
ComponentKey duplicator_key(object != nullptr ? &object->id : nullptr, NodeType::DUPLI);
|
||||
if (!group_done) {
|
||||
build_idproperties(collection->id.properties);
|
||||
OperationKey collection_geometry_key{
|
||||
&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE};
|
||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||
build_object(cob->ob);
|
||||
|
||||
/* The geometry of a collection depends on the positions of the elements in it. */
|
||||
OperationKey object_transform_key{
|
||||
&cob->ob->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL};
|
||||
add_relation(object_transform_key, collection_geometry_key, "Collection Geometry");
|
||||
|
||||
/* Only create geometry relations to child objects, if they have a geometry component. */
|
||||
OperationKey object_geometry_key{
|
||||
&cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL};
|
||||
if (find_node(object_geometry_key) != nullptr) {
|
||||
add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry");
|
||||
}
|
||||
|
||||
/* An instance is part of the geometry of the collection. */
|
||||
if (cob->ob->type == OB_EMPTY) {
|
||||
Collection *collection_instance = object->instance_collection;
|
||||
if (collection_instance != nullptr) {
|
||||
OperationKey collection_instance_key{
|
||||
&collection_instance->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE};
|
||||
add_relation(collection_instance_key, collection_geometry_key, "Collection Geometry");
|
||||
}
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
build_collection(nullptr, nullptr, child->collection);
|
||||
OperationKey child_collection_geometry_key{
|
||||
&child->collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE};
|
||||
add_relation(child_collection_geometry_key, collection_geometry_key, "Collection Geometry");
|
||||
}
|
||||
}
|
||||
if (object != nullptr) {
|
||||
|
@@ -32,11 +32,13 @@
|
||||
#include "PIL_time_utildefines.h"
|
||||
|
||||
#include "DNA_cachefile_types.h"
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_simulation_types.h"
|
||||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
@@ -107,6 +109,29 @@ void DEG_add_object_relation(DepsNodeHandle *node_handle,
|
||||
deg_node_handle->builder->add_node_handle_relation(comp_key, deg_node_handle, description);
|
||||
}
|
||||
|
||||
void DEG_add_collection_geometry_relation(DepsNodeHandle *node_handle,
|
||||
Collection *collection,
|
||||
const char *description)
|
||||
{
|
||||
deg::OperationKey operation_key{
|
||||
&collection->id, deg::NodeType::GEOMETRY, deg::OperationCode::GEOMETRY_EVAL_DONE};
|
||||
deg::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle);
|
||||
deg_node_handle->builder->add_node_handle_relation(operation_key, deg_node_handle, description);
|
||||
}
|
||||
|
||||
void DEG_add_collection_geometry_customdata_mask(DepsNodeHandle *node_handle,
|
||||
Collection *collection,
|
||||
const CustomData_MeshMasks *masks)
|
||||
{
|
||||
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, ob) {
|
||||
DEG_add_customdata_mask(node_handle, ob, masks);
|
||||
if (ob->type == OB_EMPTY && ob->instance_collection != nullptr) {
|
||||
DEG_add_collection_geometry_customdata_mask(node_handle, ob->instance_collection, masks);
|
||||
}
|
||||
}
|
||||
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
|
||||
void DEG_add_simulation_relation(DepsNodeHandle *node_handle,
|
||||
Simulation *simulation,
|
||||
const char *description)
|
||||
|
@@ -594,6 +594,7 @@ NodeType geometry_tag_to_component(const ID *id)
|
||||
case ID_HA:
|
||||
case ID_PT:
|
||||
case ID_VO:
|
||||
case ID_GR:
|
||||
return NodeType::GEOMETRY;
|
||||
case ID_PA: /* Particles */
|
||||
return NodeType::UNDEFINED;
|
||||
|
Reference in New Issue
Block a user