diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index eb1c99e9d6a..a77174ec36d 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -35,6 +35,7 @@ extern "C" { #include "BLI_compiler_attrs.h" +struct Base; struct EvaluationContext; struct Scene; struct ViewLayer; @@ -209,6 +210,9 @@ void BKE_object_eval_update_shading(const struct EvaluationContext *eval_ctx, void BKE_object_data_select_update(const struct EvaluationContext *eval_ctx, struct ID *object_data); +void BKE_object_eval_flush_base_flags(const struct EvaluationContext *eval_ctx, + struct Object *object, struct Base *base); + void BKE_object_handle_data_update( const struct EvaluationContext *eval_ctx, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 8da3e8136b3..85f207509c2 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -383,13 +383,16 @@ void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx, ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME); } -void BKE_object_eval_cloth(const EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *object) +void BKE_object_eval_cloth(const EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *object) { DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object); BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH); } -void BKE_object_eval_update_shading(const EvaluationContext *UNUSED(eval_ctx), Object *object) +void BKE_object_eval_update_shading(const EvaluationContext *UNUSED(eval_ctx), + Object *object) { DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object); if (object->type == OB_MESH) { @@ -418,3 +421,15 @@ void BKE_object_data_select_update(const EvaluationContext *UNUSED(eval_ctx), break; } } + +void BKE_object_eval_flush_base_flags(const EvaluationContext *UNUSED(eval_ctx), + Object *object, Base *base) +{ + /* Make sure we have the base collection settings is already populated. + * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet + * Which usually means a missing call to DEG_id_tag_update(). */ + BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group)); + /* Copy flags and settings from base. */ + object->base_flag = base->flag; + object->base_collection_properties = base->collection_properties; +} diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 3442f040bba..221fcea5498 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -404,10 +404,15 @@ void DepsgraphNodeBuilder::build_object(Base *base, Object *object, eDepsNode_LinkedState_Type linked_state) { - (void)base; /* Skip rest of components if the ID node was already there. */ if (object->id.tag & LIB_TAG_DOIT) { IDDepsNode *id_node = find_id_node(&object->id); + /* We need to build some extra stuff if object becomes linked + * directly. + */ + if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) { + build_object_flags(base, object); + } id_node->linked_state = max(id_node->linked_state, linked_state); return; } @@ -416,6 +421,8 @@ void DepsgraphNodeBuilder::build_object(Base *base, IDDepsNode *id_node = add_id_node(&object->id); id_node->linked_state = linked_state; object->customdata_mask = 0; + /* Various flags, flushing from bases/collections. */ + build_object_flags(base, object); /* Transform. */ build_object_transform(object); /* Parent. */ @@ -462,6 +469,20 @@ void DepsgraphNodeBuilder::build_object(Base *base, } } +void DepsgraphNodeBuilder::build_object_flags(Base *base, Object *object) +{ + if (base == NULL) { + return; + } + /* TODO(sergey): Is this really best component to be used? */ + Object *object_cow = get_cow_datablock(object); + add_operation_node(&object->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + function_bind(BKE_object_eval_flush_base_flags, + _1, object_cow, base), + DEG_OPCODE_OBJECT_BASE_FLAGS); +} + void DepsgraphNodeBuilder::build_object_data(Object *object) { if (object->data == NULL) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 853a6b7f15d..a68f756f6ca 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -165,6 +165,7 @@ struct DepsgraphNodeBuilder { void build_object(Base *base, Object *object, eDepsNode_LinkedState_Type linked_state); + void build_object_flags(Base *base, Object *object); void build_object_data(Object *object); void build_object_transform(Object *object); void build_object_constraints(Object *object); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 26eaea9a18c..dd499a01425 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -455,6 +455,8 @@ void DepsgraphRelationBuilder::build_object(Object *object) OperationKey ob_ubereval_key(&object->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); + /* Various flags, flushing from bases/collections. */ + build_object_flags(object); /* Parenting. */ if (object->parent != NULL) { /* Parent relationship. */ @@ -541,6 +543,17 @@ void DepsgraphRelationBuilder::build_object(Object *object) } } +void DepsgraphRelationBuilder::build_object_flags(Object *object) +{ + OperationKey view_layer_done_key(&scene_->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_VIEW_LAYER_DONE); + OperationKey object_flags_key(&object->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_OBJECT_BASE_FLAGS); + add_relation(view_layer_done_key, object_flags_key, "Base flags flush"); +} + void DepsgraphRelationBuilder::build_object_data(Object *object) { if (object->data == NULL) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 57c9c762d9b..ef4b9c87c25 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -190,6 +190,7 @@ struct DepsgraphRelationBuilder void build_group(Object *object, Group *group); void build_object(Object *object); void build_object_data(Object *object); + void build_object_flags(Object *object); void build_object_parent(Object *object); void build_constraints(ID *id, eDepsNode_Type component_type, diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 6ffdfeac644..f2288e93beb 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -124,57 +124,6 @@ ID *DEG_get_evaluated_id(struct Depsgraph *depsgraph, ID *id) /* ************************ DEG ITERATORS ********************* */ -/** - * XXX (dfelinto/sergey) big hack, waiting for: - * "Reshuffle collections base flags evaluation, make it so object is gathering its base flags from collections." - * - * Returns false if object shouldn't be found (which should never happen in the final implementation - * and instead we should have a tag to the objects that were not directly part of the depsgraph). - * - * That means that the object is not in a collection but it's part of depsgraph, or the object is simply - * not in the current ViewLayer - Depsgraph at the moment includes all the ViewLayer in the Scene. - */ -static bool deg_flush_base_flags_and_settings( - DEGObjectsIteratorData *data, Object *ob_dst, Object *ob_src, const bool is_dupli) -{ - Base *base; - Depsgraph *graph = data->graph; - ViewLayer *view_layer = data->eval_ctx.view_layer; - int flag = is_dupli ? BASE_FROMDUPLI : 0; - - /* First attempt, see if object is in the current ViewLayer. */ - base = (Base *)BLI_findptr(&view_layer->object_bases, ob_src, offsetof(Base, object)); - - /* Next attempt, see if object is in one of the sets. */ - if (base == NULL) { - Scene *scene_iter, *scene = DEG_get_evaluated_scene(graph); - scene_iter = scene; - - while ((scene_iter = (scene_iter)->set)) { - ViewLayer *view_layer_set = BKE_view_layer_from_scene_get(scene_iter); - base = (Base *)BLI_findptr(&view_layer_set->object_bases, ob_src, offsetof(Base, object)); - if (base != NULL) { - flag |= BASE_FROM_SET; - flag &= ~(BASE_SELECTED | BASE_SELECTABLED); - break; - } - } - } - - if (base == NULL) { - return false; - } - - /* Make sure we have the base collection settings is already populated. - * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet - * Which usually means a missing call to DEG_id_tag_update(). */ - BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group)); - - ob_dst->base_flag = base->flag | flag; - ob_dst->base_collection_properties = base->collection_properties; - return true; -} - static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) { DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; @@ -198,16 +147,19 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) data->dupli_object_current = dob; /* Temporary object to evaluate. */ - data->temp_dupli_object = *dob->ob; - data->temp_dupli_object.select_color = data->dupli_parent->select_color; + Object *dupli_parent = data->dupli_parent; + Object *temp_dupli_object = &data->temp_dupli_object; + *temp_dupli_object = *dob->ob; + temp_dupli_object->select_color = dupli_parent->select_color; + temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI; + temp_dupli_object->base_collection_properties = + dupli_parent->base_collection_properties; copy_m4_m4(data->temp_dupli_object.obmat, dob->mat); - deg_flush_base_flags_and_settings(data, - &data->temp_dupli_object, - data->dupli_parent, - true); iter->current = &data->temp_dupli_object; - BLI_assert(DEG::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id)); + BLI_assert( + DEG::deg_validate_copy_on_write_datablock( + &data->temp_dupli_object.id)); return true; } @@ -245,11 +197,6 @@ static void deg_objects_iterator_step(BLI_Iterator *iter, DEG::IDDepsNode *id_no Object *object = (Object *)id_node->id_cow; BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id)); - if (deg_flush_base_flags_and_settings(data, object, object, false) == false) { - iter->skip = true; - return; - } - if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) { data->dupli_parent = object; data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 0dffab3511e..12d0ed4501b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -860,7 +860,7 @@ static void view3d_main_region_listener( break; case ND_OB_ACTIVE: case ND_OB_SELECT: - DEG_id_tag_update((ID *)&scene->id, DEG_TAG_COPY_ON_WRITE); + DEG_id_tag_update((ID *)&scene->id, DEG_TAG_SELECT_UPDATE); ATTR_FALLTHROUGH; case ND_FRAME: case ND_TRANSFORM: