Depsgraph: Add explicit object collection hierarchy tracking
The practical problem this change addresses is ability to have base flag dependent functionality in Cycles without re-setting the render on selection. This problem initially arose during the Cycles light linking project. The original review happened there: blender/blender#105837 Pull Request: blender/blender#108182
This commit is contained in:
@@ -1402,7 +1402,7 @@ bool BKE_collection_object_add_notest(Main *bmain, Collection *collection, Objec
|
||||
BKE_main_collection_sync(bmain);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&collection->id, ID_RECALC_GEOMETRY);
|
||||
DEG_id_tag_update(&collection->id, ID_RECALC_GEOMETRY | ID_RECALC_HIERARCHY);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1470,7 +1470,7 @@ bool BKE_collection_object_remove(Main *bmain,
|
||||
BKE_main_collection_sync(bmain);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&collection->id, ID_RECALC_GEOMETRY);
|
||||
DEG_id_tag_update(&collection->id, ID_RECALC_GEOMETRY | ID_RECALC_HIERARCHY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -323,6 +323,13 @@ bool DepsgraphNodeBuilder::has_operation_node(ID *id,
|
||||
return find_operation_node(id, comp_type, comp_name, opcode, name, name_tag) != nullptr;
|
||||
}
|
||||
|
||||
bool DepsgraphNodeBuilder::has_operation_node(ID *id,
|
||||
const NodeType comp_type,
|
||||
const OperationCode opcode)
|
||||
{
|
||||
return find_operation_node(id, comp_type, opcode) != nullptr;
|
||||
}
|
||||
|
||||
OperationNode *DepsgraphNodeBuilder::find_operation_node(const ID *id,
|
||||
NodeType comp_type,
|
||||
const char *comp_name,
|
||||
@@ -701,7 +708,10 @@ void DepsgraphNodeBuilder::build_collection(LayerCollection *from_layer_collecti
|
||||
id_node = add_id_node(&collection->id);
|
||||
id_node->is_visible_on_build = is_collection_visible;
|
||||
|
||||
add_operation_node(&collection->id, NodeType::HIERARCHY, OperationCode::HIERARCHY);
|
||||
|
||||
build_idproperties(collection->id.properties);
|
||||
build_parameters(&collection->id);
|
||||
add_operation_node(&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE);
|
||||
}
|
||||
if (from_layer_collection != nullptr) {
|
||||
@@ -768,6 +778,9 @@ void DepsgraphNodeBuilder::build_object(int base_index,
|
||||
id_node->is_visible_on_build = is_visible;
|
||||
}
|
||||
id_node->has_base |= (base_index != -1);
|
||||
|
||||
add_operation_node(&object->id, NodeType::HIERARCHY, OperationCode::HIERARCHY);
|
||||
|
||||
/* Various flags, flushing from bases/collections. */
|
||||
build_object_from_layer(base_index, object, linked_state);
|
||||
/* Transform. */
|
||||
@@ -818,6 +831,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
|
||||
{
|
||||
build_texture(object->pd->tex);
|
||||
}
|
||||
|
||||
/* Object dupligroup. */
|
||||
if (object->instance_collection != nullptr) {
|
||||
build_object_instance_collection(object, is_visible);
|
||||
@@ -825,6 +839,7 @@ void DepsgraphNodeBuilder::build_object(int base_index,
|
||||
&object->id, NodeType::DUPLI, OperationCode::DUPLI);
|
||||
op_node->flag |= OperationFlag::DEPSOP_FLAG_PINNED;
|
||||
}
|
||||
|
||||
/* Synchronization back to original object. */
|
||||
add_operation_node(&object->id,
|
||||
NodeType::SYNCHRONIZATION,
|
||||
|
@@ -139,6 +139,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
|
||||
OperationCode opcode,
|
||||
const char *name = "",
|
||||
int name_tag = -1);
|
||||
bool has_operation_node(ID *id, NodeType comp_type, OperationCode opcode);
|
||||
|
||||
OperationNode *find_operation_node(const ID *id,
|
||||
NodeType comp_type,
|
||||
@@ -193,6 +194,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
|
||||
virtual void build_object_transform(Object *object);
|
||||
virtual void build_object_constraints(Object *object);
|
||||
virtual void build_object_pointcache(Object *object);
|
||||
|
||||
virtual void build_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index);
|
||||
virtual void build_rigidbody(Scene *scene);
|
||||
virtual void build_particle_systems(Object *object, bool is_object_visible);
|
||||
|
@@ -78,6 +78,9 @@ void DepsgraphNodeBuilder::build_view_layer(Scene *scene,
|
||||
/* Scene ID block. */
|
||||
IDNode *id_node = add_id_node(&scene->id);
|
||||
id_node->linked_state = linked_state;
|
||||
|
||||
add_operation_node(&scene->id, NodeType::HIERARCHY, OperationCode::HIERARCHY);
|
||||
|
||||
/* Time source. */
|
||||
add_time_source();
|
||||
/* Setup currently building context. */
|
||||
|
@@ -282,6 +282,15 @@ Node *DepsgraphRelationBuilder::get_node(const RNAPathKey &key)
|
||||
return rna_node_query_.find_node(&key.ptr, key.prop, key.source);
|
||||
}
|
||||
|
||||
ComponentNode *DepsgraphRelationBuilder::find_node(const ComponentKey &key) const
|
||||
{
|
||||
IDNode *id_node = graph_->find_id_node(key.id);
|
||||
if (!id_node) {
|
||||
return nullptr;
|
||||
}
|
||||
return id_node->find_component(key.type, key.name);
|
||||
}
|
||||
|
||||
OperationNode *DepsgraphRelationBuilder::find_node(const OperationKey &key) const
|
||||
{
|
||||
IDNode *id_node = graph_->find_id_node(key.id);
|
||||
@@ -300,6 +309,11 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const
|
||||
return find_node(key) != nullptr;
|
||||
}
|
||||
|
||||
bool DepsgraphRelationBuilder::has_node(const ComponentKey &key) const
|
||||
{
|
||||
return find_node(key) != nullptr;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_depends_on_transform_relation(const DepsNodeHandle *handle,
|
||||
const char *description)
|
||||
{
|
||||
@@ -617,6 +631,8 @@ void DepsgraphRelationBuilder::build_idproperties(IDProperty *id_property)
|
||||
void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_collection,
|
||||
Collection *collection)
|
||||
{
|
||||
const ComponentKey collection_hierarchy_key{&collection->id, NodeType::HIERARCHY};
|
||||
|
||||
if (from_layer_collection != nullptr) {
|
||||
/* If we came from layer collection we don't go deeper, view layer builder takes care of going
|
||||
* deeper.
|
||||
@@ -624,6 +640,23 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
|
||||
* NOTE: Do early output before tagging build as done, so possible subsequent builds from
|
||||
* outside of the layer collection properly recurses into all the nested objects and
|
||||
* collections. */
|
||||
|
||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||
Object *object = cob->ob;
|
||||
|
||||
/* Ensure that the hierarchy relations always exists, even for the layer collection.
|
||||
*
|
||||
* Note that the view layer builder can skip bases if they are constantly excluded from the
|
||||
* collections. In order to avoid noisy output check that the target node exists before
|
||||
* adding the relation. */
|
||||
const ComponentKey object_hierarchy_key{&object->id, NodeType::HIERARCHY};
|
||||
if (has_node(object_hierarchy_key)) {
|
||||
add_relation(collection_hierarchy_key,
|
||||
object_hierarchy_key,
|
||||
"Collection -> Object hierarchy",
|
||||
RELATION_CHECK_BEFORE_ADD);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -632,6 +665,7 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
|
||||
}
|
||||
|
||||
build_idproperties(collection->id.properties);
|
||||
build_parameters(&collection->id);
|
||||
|
||||
const BuilderStack::ScopedEntry stack_entry = stack_.trace(collection->id);
|
||||
|
||||
@@ -639,22 +673,27 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
|
||||
&collection->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE};
|
||||
|
||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||
build_object(cob->ob);
|
||||
Object *object = cob->ob;
|
||||
|
||||
build_object(object);
|
||||
|
||||
const ComponentKey object_hierarchy_key{&object->id, NodeType::HIERARCHY};
|
||||
add_relation(collection_hierarchy_key, object_hierarchy_key, "Collection -> Object hierarchy");
|
||||
|
||||
/* The geometry of a collection depends on the positions of the elements in it. */
|
||||
const OperationKey object_transform_key{
|
||||
&cob->ob->id, NodeType::TRANSFORM, OperationCode::TRANSFORM_FINAL};
|
||||
&object->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. */
|
||||
const OperationKey object_geometry_key{
|
||||
&cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL};
|
||||
&object->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) {
|
||||
if (object->type == OB_EMPTY) {
|
||||
Collection *collection_instance = cob->ob->instance_collection;
|
||||
if (collection_instance != nullptr) {
|
||||
const OperationKey collection_instance_key{
|
||||
@@ -3256,6 +3295,11 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
|
||||
if (ELEM(comp_node->type, NodeType::PARAMETERS, NodeType::LAYER_COLLECTIONS)) {
|
||||
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
|
||||
}
|
||||
/* Compatibility with the legacy tagging: groups are only tagged for Copy-on-Write when their
|
||||
* hierarchy changes, and it needs to be flushed downstream. */
|
||||
if (id_type == ID_GR && comp_node->type == NodeType::HIERARCHY) {
|
||||
rel_flag &= ~RELATION_FLAG_NO_FLUSH;
|
||||
}
|
||||
/* All entry operations of each component should wait for a proper
|
||||
* copy of ID. */
|
||||
OperationNode *op_entry = comp_node->get_entry_operation();
|
||||
|
@@ -129,7 +129,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
|
||||
virtual void build_scene_parameters(Scene *scene);
|
||||
virtual void build_scene_compositor(Scene *scene);
|
||||
|
||||
virtual void build_layer_collections(ListBase *lb);
|
||||
virtual bool build_layer_collection(LayerCollection *layer_collection);
|
||||
virtual void build_view_layer_collections(ViewLayer *view_layer);
|
||||
|
||||
virtual void build_view_layer(Scene *scene,
|
||||
ViewLayer *view_layer,
|
||||
eDepsNode_LinkedState_Type linked_state);
|
||||
@@ -148,6 +150,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
|
||||
virtual void build_object_parent(Object *object);
|
||||
virtual void build_object_pointcache(Object *object);
|
||||
virtual void build_object_instance_collection(Object *object);
|
||||
|
||||
virtual void build_constraints(ID *id,
|
||||
NodeType component_type,
|
||||
const char *component_subdata,
|
||||
@@ -262,6 +265,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
|
||||
Node *get_node(const RNAPathKey &key);
|
||||
|
||||
OperationNode *find_node(const OperationKey &key) const;
|
||||
ComponentNode *find_node(const ComponentKey &key) const;
|
||||
bool has_node(const ComponentKey &key) const;
|
||||
bool has_node(const OperationKey &key) const;
|
||||
|
||||
Relation *add_time_relation(TimeSourceNode *timesrc,
|
||||
|
@@ -43,19 +43,48 @@
|
||||
|
||||
namespace blender::deg {
|
||||
|
||||
void DepsgraphRelationBuilder::build_layer_collections(ListBase *lb)
|
||||
bool DepsgraphRelationBuilder::build_layer_collection(LayerCollection *layer_collection)
|
||||
{
|
||||
const int visibility_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_HIDE_VIEWPORT :
|
||||
COLLECTION_HIDE_RENDER;
|
||||
const int hide_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? COLLECTION_HIDE_VIEWPORT :
|
||||
COLLECTION_HIDE_RENDER;
|
||||
|
||||
for (LayerCollection *lc = (LayerCollection *)lb->first; lc; lc = lc->next) {
|
||||
if (lc->collection->flag & visibility_flag) {
|
||||
continue;
|
||||
Collection *collection = layer_collection->collection;
|
||||
|
||||
const bool is_collection_hidden = collection->flag & hide_flag;
|
||||
const bool is_layer_collection_excluded = layer_collection->flag & LAYER_COLLECTION_EXCLUDE;
|
||||
|
||||
if (is_collection_hidden || is_layer_collection_excluded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
build_collection(layer_collection, collection);
|
||||
|
||||
const ComponentKey collection_hierarchy_key{&collection->id, NodeType::HIERARCHY};
|
||||
|
||||
LISTBASE_FOREACH (
|
||||
LayerCollection *, child_layer_collection, &layer_collection->layer_collections) {
|
||||
if (build_layer_collection(child_layer_collection)) {
|
||||
Collection *child_collection = child_layer_collection->collection;
|
||||
const ComponentKey child_collection_hierarchy_key{&child_collection->id,
|
||||
NodeType::HIERARCHY};
|
||||
add_relation(
|
||||
collection_hierarchy_key, child_collection_hierarchy_key, "Collection hierarchy");
|
||||
}
|
||||
if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
|
||||
build_collection(lc, lc->collection);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_view_layer_collections(ViewLayer *view_layer)
|
||||
{
|
||||
const ComponentKey scene_hierarchy_key{&scene_->id, NodeType::HIERARCHY};
|
||||
|
||||
LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
|
||||
if (build_layer_collection(layer_collection)) {
|
||||
Collection *collection = layer_collection->collection;
|
||||
const ComponentKey collection_hierarchy_key{&collection->id, NodeType::HIERARCHY};
|
||||
add_relation(scene_hierarchy_key, collection_hierarchy_key, "Scene -> Collection hierarchy");
|
||||
}
|
||||
build_layer_collections(&lc->layer_collections);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +115,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene,
|
||||
}
|
||||
}
|
||||
|
||||
build_layer_collections(&view_layer->layer_collections);
|
||||
build_view_layer_collections(view_layer);
|
||||
|
||||
if (scene->camera != nullptr) {
|
||||
build_object(scene->camera);
|
||||
|
@@ -400,6 +400,7 @@ static void deg_debug_graphviz_node(DotExportContext &ctx,
|
||||
case NodeType::PARTICLE_SETTINGS:
|
||||
case NodeType::COPY_ON_WRITE:
|
||||
case NodeType::OBJECT_FROM_LAYER:
|
||||
case NodeType::HIERARCHY:
|
||||
case NodeType::BATCH_CACHE:
|
||||
case NodeType::DUPLI:
|
||||
case NodeType::SYNCHRONIZATION:
|
||||
|
@@ -217,7 +217,11 @@ void depsgraph_tag_to_component_opcode(const ID *id,
|
||||
*operation_code = OperationCode::NTREE_OUTPUT;
|
||||
break;
|
||||
|
||||
case ID_RECALC_PROVISION_26:
|
||||
case ID_RECALC_HIERARCHY:
|
||||
*component_type = NodeType::HIERARCHY;
|
||||
*operation_code = OperationCode::HIERARCHY;
|
||||
break;
|
||||
|
||||
case ID_RECALC_PROVISION_27:
|
||||
case ID_RECALC_PROVISION_28:
|
||||
case ID_RECALC_PROVISION_29:
|
||||
@@ -749,7 +753,9 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
|
||||
case ID_RECALC_NTREE_OUTPUT:
|
||||
return "ID_RECALC_NTREE_OUTPUT";
|
||||
|
||||
case ID_RECALC_PROVISION_26:
|
||||
case ID_RECALC_HIERARCHY:
|
||||
return "ID_RECALC_HIERARCHY";
|
||||
|
||||
case ID_RECALC_PROVISION_27:
|
||||
case ID_RECALC_PROVISION_28:
|
||||
case ID_RECALC_PROVISION_29:
|
||||
|
@@ -124,6 +124,7 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
|
||||
|
||||
object->base_flag = base_flag;
|
||||
object->base_local_view_bits = base_local_view_bits;
|
||||
|
||||
/* Restore modifier's runtime data.
|
||||
* NOTE: Data of unused modifiers will be freed there. */
|
||||
restore_modifier_runtime_data(object);
|
||||
|
@@ -65,6 +65,8 @@ const char *nodeTypeAsString(NodeType type)
|
||||
return "COPY_ON_WRITE";
|
||||
case NodeType::OBJECT_FROM_LAYER:
|
||||
return "OBJECT_FROM_LAYER";
|
||||
case NodeType::HIERARCHY:
|
||||
return "HIERARCHY";
|
||||
/* **** Evaluation-Related Outer Types (with Subdata) **** */
|
||||
case NodeType::EVAL_POSE:
|
||||
return "EVAL_POSE";
|
||||
@@ -140,6 +142,7 @@ eDepsSceneComponentType nodeTypeToSceneComponent(NodeType type)
|
||||
case NodeType::LAYER_COLLECTIONS:
|
||||
case NodeType::COPY_ON_WRITE:
|
||||
case NodeType::OBJECT_FROM_LAYER:
|
||||
case NodeType::HIERARCHY:
|
||||
case NodeType::AUDIO:
|
||||
case NodeType::ARMATURE:
|
||||
case NodeType::GENERIC_DATABLOCK:
|
||||
@@ -223,6 +226,7 @@ eDepsObjectComponentType nodeTypeToObjectComponent(NodeType type)
|
||||
case NodeType::LAYER_COLLECTIONS:
|
||||
case NodeType::COPY_ON_WRITE:
|
||||
case NodeType::OBJECT_FROM_LAYER:
|
||||
case NodeType::HIERARCHY:
|
||||
case NodeType::AUDIO:
|
||||
case NodeType::ARMATURE:
|
||||
case NodeType::GENERIC_DATABLOCK:
|
||||
|
@@ -77,6 +77,8 @@ enum class NodeType {
|
||||
/* Used by all operations which are updating object when something is
|
||||
* changed in view layer. */
|
||||
OBJECT_FROM_LAYER,
|
||||
/* Hierarchy of objects and collections */
|
||||
HIERARCHY,
|
||||
/* Audio-related evaluation. */
|
||||
AUDIO,
|
||||
ARMATURE,
|
||||
|
@@ -331,6 +331,7 @@ DEG_COMPONENT_NODE_DEFINE(Sequencer, SEQUENCER, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Shading, SHADING, ID_RECALC_SHADING);
|
||||
DEG_COMPONENT_NODE_DEFINE(Transform, TRANSFORM, ID_RECALC_TRANSFORM);
|
||||
DEG_COMPONENT_NODE_DEFINE(ObjectFromLayer, OBJECT_FROM_LAYER, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Hierarchy, HIERARCHY, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Dupli, DUPLI, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Synchronization, SYNCHRONIZATION, 0);
|
||||
DEG_COMPONENT_NODE_DEFINE(Audio, AUDIO, 0);
|
||||
@@ -366,6 +367,7 @@ void deg_register_component_depsnodes()
|
||||
register_node_typeinfo(&DNTI_SHADING);
|
||||
register_node_typeinfo(&DNTI_TRANSFORM);
|
||||
register_node_typeinfo(&DNTI_OBJECT_FROM_LAYER);
|
||||
register_node_typeinfo(&DNTI_HIERARCHY);
|
||||
register_node_typeinfo(&DNTI_DUPLI);
|
||||
register_node_typeinfo(&DNTI_SYNCHRONIZATION);
|
||||
register_node_typeinfo(&DNTI_AUDIO);
|
||||
|
@@ -200,6 +200,7 @@ DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Shading);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(ShadingParameters);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Transform);
|
||||
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(ObjectFromLayer);
|
||||
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Hierarchy);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Dupli);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio);
|
||||
|
@@ -152,6 +152,7 @@ ComponentNode *IDNode::add_component(NodeType type, const char *name)
|
||||
ComponentNode *comp_node = find_component(type, name);
|
||||
if (!comp_node) {
|
||||
DepsNodeFactory *factory = type_get_factory(type);
|
||||
BLI_assert(factory);
|
||||
comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
|
||||
|
||||
/* Register. */
|
||||
|
@@ -34,6 +34,9 @@ const char *operationCodeAsString(OperationCode opcode)
|
||||
return "PARAMETERS_EXIT";
|
||||
case OperationCode::VISIBILITY:
|
||||
return "VISIBILITY";
|
||||
/* Hierarchy. */
|
||||
case OperationCode::HIERARCHY:
|
||||
return "HIERARCHY";
|
||||
/* Animation, Drivers, etc. */
|
||||
case OperationCode::ANIMATION_ENTRY:
|
||||
return "ANIMATION_ENTRY";
|
||||
|
@@ -28,13 +28,16 @@ enum class OperationCode {
|
||||
/* Placeholder for operations which don't need special mention */
|
||||
OPERATION = 0,
|
||||
|
||||
/* Generic parameters evaluation. */
|
||||
/* Generic parameters evaluation. --------------------------------------- */
|
||||
ID_PROPERTY,
|
||||
PARAMETERS_ENTRY,
|
||||
PARAMETERS_EVAL,
|
||||
PARAMETERS_EXIT,
|
||||
VISIBILITY,
|
||||
|
||||
/* Hierarchy. ----------------------------------------------------------- */
|
||||
HIERARCHY,
|
||||
|
||||
/* Animation, Drivers, etc. --------------------------------------------- */
|
||||
/* NLA + Action */
|
||||
ANIMATION_ENTRY,
|
||||
|
@@ -395,14 +395,14 @@ static void unlink_collection_fn(bContext *C,
|
||||
if (GS(tsep->id->name) == ID_OB) {
|
||||
Object *ob = (Object *)tsep->id;
|
||||
ob->instance_collection = nullptr;
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
else if (GS(tsep->id->name) == ID_GR) {
|
||||
Collection *parent = (Collection *)tsep->id;
|
||||
id_fake_user_set(&collection->id);
|
||||
BKE_collection_child_remove(bmain, parent, collection);
|
||||
DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
else if (GS(tsep->id->name) == ID_SCE) {
|
||||
@@ -410,7 +410,7 @@ static void unlink_collection_fn(bContext *C,
|
||||
Collection *parent = scene->master_collection;
|
||||
id_fake_user_set(&collection->id);
|
||||
BKE_collection_child_remove(bmain, parent, collection);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
}
|
||||
@@ -457,14 +457,15 @@ static void unlink_object_fn(bContext *C,
|
||||
if (GS(tsep->id->name) == ID_GR) {
|
||||
Collection *parent = (Collection *)tsep->id;
|
||||
BKE_collection_object_remove(bmain, parent, ob, true);
|
||||
DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&parent->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_HIERARCHY);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
else if (GS(tsep->id->name) == ID_SCE) {
|
||||
Scene *scene = (Scene *)tsep->id;
|
||||
Collection *parent = scene->master_collection;
|
||||
BKE_collection_object_remove(bmain, parent, ob, true);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
}
|
||||
@@ -2557,7 +2558,7 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
|
||||
* cleanup tree here to prevent such cases. */
|
||||
outliner_cleanup_tree(space_outliner);
|
||||
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_HIERARCHY);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
|
@@ -1071,11 +1071,13 @@ typedef enum IDRecalcFlag {
|
||||
/* The node tree has changed in a way that affects its output nodes. */
|
||||
ID_RECALC_NTREE_OUTPUT = (1 << 25),
|
||||
|
||||
/* Hierarchy of collection and object within collection changed. */
|
||||
ID_RECALC_HIERARCHY = (1 << 26),
|
||||
|
||||
/* Provisioned flags.
|
||||
*
|
||||
* Not for actual use. The idea of them is to have all bits of the `IDRecalcFlag` defined to a
|
||||
* known value, silencing sanitizer warnings when checking bits of the ID_RECALC_ALL. */
|
||||
ID_RECALC_PROVISION_26 = (1 << 26),
|
||||
ID_RECALC_PROVISION_27 = (1 << 27),
|
||||
ID_RECALC_PROVISION_28 = (1 << 28),
|
||||
ID_RECALC_PROVISION_29 = (1 << 29),
|
||||
|
Reference in New Issue
Block a user