Depsgrapg: Add per-modifier graph nodes

No functional changes expected.
This commit is contained in:
Sergey Sharybin 2022-08-04 11:52:42 +02:00
parent fad112be1c
commit cfbe11563a
Notes: blender-bot 2023-02-14 04:10:15 +01:00
Referenced by issue #103685, Regression: Animation on objects that are disabled from render is ignored while Render Animation
Referenced by issue #100653, Reported object statistics are very wrong (under reported).
Referenced by issue #100656, Rigid body/cloth simulation not occurring.
6 changed files with 80 additions and 33 deletions

View File

@ -769,11 +769,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
build_object(-1, object->parent, DEG_ID_LINKED_INDIRECTLY, is_visible);
}
/* Modifiers. */
if (object->modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
build_object_modifiers(object);
/* Grease Pencil Modifiers. */
if (object->greasepencil_modifiers.first != nullptr) {
BuilderWalkUserData data;
@ -877,6 +873,22 @@ void DepsgraphNodeBuilder::build_object_instance_collection(Object *object, bool
is_parent_collection_visible_ = is_current_parent_collection_visible;
}
void DepsgraphNodeBuilder::build_object_modifiers(Object *object)
{
if (BLI_listbase_is_empty(&object->modifiers)) {
return;
}
LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
add_operation_node(
&object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, nullptr, modifier->name);
}
BuilderWalkUserData data;
data.builder = this;
BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
void DepsgraphNodeBuilder::build_object_data(Object *object)
{
if (object->data == nullptr) {

View File

@ -174,6 +174,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_object_flags(int base_index,
Object *object,
eDepsNode_LinkedState_Type linked_state);
virtual void build_object_modifiers(Object *object);
virtual void build_object_data(Object *object);
virtual void build_object_data_camera(Object *object);
virtual void build_object_data_geometry(Object *object);

View File

@ -298,7 +298,8 @@ void DepsgraphRelationBuilder::add_depends_on_transform_relation(const DepsNodeH
{
IDNode *id_node = handle->node->owner->owner;
ID *id = id_node->id_orig;
ComponentKey geometry_key(id, NodeType::GEOMETRY);
const OperationKey geometry_key(
id, NodeType::GEOMETRY, OperationCode::MODIFIER, handle->node->name.c_str());
/* Wire up the actual relation. */
add_depends_on_transform_relation(id, geometry_key, description);
}
@ -718,11 +719,7 @@ void DepsgraphRelationBuilder::build_object(Object *object)
}
/* Modifiers. */
if (object->modifiers.first != nullptr) {
BuilderWalkUserData data;
data.builder = this;
BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
build_object_modifiers(object);
/* Grease Pencil Modifiers. */
if (object->greasepencil_modifiers.first != nullptr) {
@ -870,6 +867,53 @@ void DepsgraphRelationBuilder::build_object_layer_component_relations(Object *ob
add_relation(object_from_layer_exit_key, synchronize_key, "Synchronize to Original");
}
void DepsgraphRelationBuilder::build_object_modifiers(Object *object)
{
if (BLI_listbase_is_empty(&object->modifiers)) {
return;
}
const OperationKey eval_init_key(
&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
const OperationKey eval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
OperationKey previous_key = eval_init_key;
LISTBASE_FOREACH (ModifierData *, modifier, &object->modifiers) {
const OperationKey modifier_key(
&object->id, NodeType::GEOMETRY, OperationCode::MODIFIER, modifier->name);
/* Relation for the modifier stack chain. */
add_relation(previous_key, modifier_key, "Modifier");
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)modifier->type);
if (mti->updateDepsgraph) {
const BuilderStack::ScopedEntry stack_entry = stack_.trace(*modifier);
DepsNodeHandle handle = create_node_handle(modifier_key);
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(modifier, &ctx);
}
/* Time dependency. */
if (BKE_modifier_depends_ontime(scene_, modifier)) {
const TimeSourceKey time_src_key;
add_relation(time_src_key, modifier_key, "Time Source -> Modifier");
}
previous_key = modifier_key;
}
add_relation(previous_key, eval_key, "modifier stack order");
/* Build IDs referenced by the modifiers. */
BuilderWalkUserData data;
data.builder = this;
BKE_modifiers_foreach_ID_link(object, modifier_walk, &data);
}
void DepsgraphRelationBuilder::build_object_data(Object *object)
{
if (object->data == nullptr) {
@ -2193,26 +2237,6 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
* evaluated prior to Scene's CoW is ready. */
OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
add_relation(scene_key, obdata_ubereval_key, "CoW Relation", RELATION_FLAG_NO_FLUSH);
/* Modifiers */
if (object->modifiers.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
ctx.scene = scene_;
ctx.object = object;
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
if (mti->updateDepsgraph) {
const BuilderStack::ScopedEntry stack_entry = stack_.trace(*md);
DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(md, &ctx);
}
if (BKE_modifier_depends_ontime(scene_, md)) {
TimeSourceKey time_src_key;
add_relation(time_src_key, obdata_ubereval_key, "Time Source -> Modifier");
}
}
}
/* Grease Pencil Modifiers. */
if (object->greasepencil_modifiers.first != nullptr) {
ModifierUpdateDepsgraphContext ctx = {};
@ -2256,8 +2280,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
if (ELEM(object->type, OB_MESH, OB_CURVES_LEGACY, OB_LATTICE)) {
// add geometry collider relations
}
/* Make sure uber update is the last in the dependencies. */
add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval");
/* Make sure uber update is the last in the dependencies.
* Only do it here unless there are modifiers. This avoids transitive relations. */
if (BLI_listbase_is_empty(&object->modifiers)) {
OperationKey obdata_ubereval_key(
&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval");
}
if (object->type == OB_MBALL) {
Object *mom = BKE_mball_basis_find(scene_, object);
ComponentKey mom_geom_key(&mom->id, NodeType::GEOMETRY);

View File

@ -265,6 +265,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_object(Object *object);
virtual void build_object_from_view_layer_base(Object *object);
virtual void build_object_layer_component_relations(Object *object);
virtual void build_object_modifiers(Object *object);
virtual void build_object_data(Object *object);
virtual void build_object_data_camera(Object *object);
virtual void build_object_data_geometry(Object *object);

View File

@ -84,6 +84,8 @@ const char *operationCodeAsString(OperationCode opcode)
/* Geometry. */
case OperationCode::GEOMETRY_EVAL_INIT:
return "GEOMETRY_EVAL_INIT";
case OperationCode::MODIFIER:
return "MODIFIER";
case OperationCode::GEOMETRY_EVAL:
return "GEOMETRY_EVAL";
case OperationCode::GEOMETRY_EVAL_DONE:

View File

@ -84,6 +84,8 @@ enum class OperationCode {
/* Initialize evaluation of the geometry. Is an entry operation of geometry
* component. */
GEOMETRY_EVAL_INIT,
/* Modifier. */
MODIFIER,
/* Evaluate the whole geometry, including modifiers. */
GEOMETRY_EVAL,
/* Evaluation of geometry is completely done. */