Depsgraph: Flush flags from base to object as an evaluation step
Previously it was done during depsgraph iteration, which is not good at all, since after evaluation nobody should really modify how object was evaluated.
This commit is contained in:
parent
93f6a9d652
commit
87c821ff26
|
@ -35,6 +35,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "BLI_compiler_attrs.h"
|
#include "BLI_compiler_attrs.h"
|
||||||
|
|
||||||
|
struct Base;
|
||||||
struct EvaluationContext;
|
struct EvaluationContext;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
struct ViewLayer;
|
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,
|
void BKE_object_data_select_update(const struct EvaluationContext *eval_ctx,
|
||||||
struct ID *object_data);
|
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(
|
void BKE_object_handle_data_update(
|
||||||
const struct EvaluationContext *eval_ctx,
|
const struct EvaluationContext *eval_ctx,
|
||||||
struct Scene *scene,
|
struct Scene *scene,
|
||||||
|
|
|
@ -383,13 +383,16 @@ void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx,
|
||||||
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
|
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);
|
DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object);
|
||||||
BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH);
|
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);
|
DEBUG_PRINT("%s on %s (%p)\n", __func__, object->id.name, object);
|
||||||
if (object->type == OB_MESH) {
|
if (object->type == OB_MESH) {
|
||||||
|
@ -418,3 +421,15 @@ void BKE_object_data_select_update(const EvaluationContext *UNUSED(eval_ctx),
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -404,10 +404,15 @@ void DepsgraphNodeBuilder::build_object(Base *base,
|
||||||
Object *object,
|
Object *object,
|
||||||
eDepsNode_LinkedState_Type linked_state)
|
eDepsNode_LinkedState_Type linked_state)
|
||||||
{
|
{
|
||||||
(void)base;
|
|
||||||
/* Skip rest of components if the ID node was already there. */
|
/* Skip rest of components if the ID node was already there. */
|
||||||
if (object->id.tag & LIB_TAG_DOIT) {
|
if (object->id.tag & LIB_TAG_DOIT) {
|
||||||
IDDepsNode *id_node = find_id_node(&object->id);
|
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);
|
id_node->linked_state = max(id_node->linked_state, linked_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -416,6 +421,8 @@ void DepsgraphNodeBuilder::build_object(Base *base,
|
||||||
IDDepsNode *id_node = add_id_node(&object->id);
|
IDDepsNode *id_node = add_id_node(&object->id);
|
||||||
id_node->linked_state = linked_state;
|
id_node->linked_state = linked_state;
|
||||||
object->customdata_mask = 0;
|
object->customdata_mask = 0;
|
||||||
|
/* Various flags, flushing from bases/collections. */
|
||||||
|
build_object_flags(base, object);
|
||||||
/* Transform. */
|
/* Transform. */
|
||||||
build_object_transform(object);
|
build_object_transform(object);
|
||||||
/* Parent. */
|
/* 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)
|
void DepsgraphNodeBuilder::build_object_data(Object *object)
|
||||||
{
|
{
|
||||||
if (object->data == NULL) {
|
if (object->data == NULL) {
|
||||||
|
|
|
@ -165,6 +165,7 @@ struct DepsgraphNodeBuilder {
|
||||||
void build_object(Base *base,
|
void build_object(Base *base,
|
||||||
Object *object,
|
Object *object,
|
||||||
eDepsNode_LinkedState_Type linked_state);
|
eDepsNode_LinkedState_Type linked_state);
|
||||||
|
void build_object_flags(Base *base, Object *object);
|
||||||
void build_object_data(Object *object);
|
void build_object_data(Object *object);
|
||||||
void build_object_transform(Object *object);
|
void build_object_transform(Object *object);
|
||||||
void build_object_constraints(Object *object);
|
void build_object_constraints(Object *object);
|
||||||
|
|
|
@ -455,6 +455,8 @@ void DepsgraphRelationBuilder::build_object(Object *object)
|
||||||
OperationKey ob_ubereval_key(&object->id,
|
OperationKey ob_ubereval_key(&object->id,
|
||||||
DEG_NODE_TYPE_TRANSFORM,
|
DEG_NODE_TYPE_TRANSFORM,
|
||||||
DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL);
|
DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL);
|
||||||
|
/* Various flags, flushing from bases/collections. */
|
||||||
|
build_object_flags(object);
|
||||||
/* Parenting. */
|
/* Parenting. */
|
||||||
if (object->parent != NULL) {
|
if (object->parent != NULL) {
|
||||||
/* Parent relationship. */
|
/* 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)
|
void DepsgraphRelationBuilder::build_object_data(Object *object)
|
||||||
{
|
{
|
||||||
if (object->data == NULL) {
|
if (object->data == NULL) {
|
||||||
|
|
|
@ -190,6 +190,7 @@ struct DepsgraphRelationBuilder
|
||||||
void build_group(Object *object, Group *group);
|
void build_group(Object *object, Group *group);
|
||||||
void build_object(Object *object);
|
void build_object(Object *object);
|
||||||
void build_object_data(Object *object);
|
void build_object_data(Object *object);
|
||||||
|
void build_object_flags(Object *object);
|
||||||
void build_object_parent(Object *object);
|
void build_object_parent(Object *object);
|
||||||
void build_constraints(ID *id,
|
void build_constraints(ID *id,
|
||||||
eDepsNode_Type component_type,
|
eDepsNode_Type component_type,
|
||||||
|
|
|
@ -124,57 +124,6 @@ ID *DEG_get_evaluated_id(struct Depsgraph *depsgraph, ID *id)
|
||||||
|
|
||||||
/* ************************ DEG ITERATORS ********************* */
|
/* ************************ 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)
|
static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
|
||||||
{
|
{
|
||||||
DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
|
DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
|
||||||
|
@ -198,16 +147,19 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
|
||||||
data->dupli_object_current = dob;
|
data->dupli_object_current = dob;
|
||||||
|
|
||||||
/* Temporary object to evaluate. */
|
/* Temporary object to evaluate. */
|
||||||
data->temp_dupli_object = *dob->ob;
|
Object *dupli_parent = data->dupli_parent;
|
||||||
data->temp_dupli_object.select_color = data->dupli_parent->select_color;
|
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);
|
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;
|
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;
|
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;
|
Object *object = (Object *)id_node->id_cow;
|
||||||
BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
|
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)) {
|
if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) {
|
||||||
data->dupli_parent = object;
|
data->dupli_parent = object;
|
||||||
data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
|
data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
|
||||||
|
|
|
@ -860,7 +860,7 @@ static void view3d_main_region_listener(
|
||||||
break;
|
break;
|
||||||
case ND_OB_ACTIVE:
|
case ND_OB_ACTIVE:
|
||||||
case ND_OB_SELECT:
|
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;
|
ATTR_FALLTHROUGH;
|
||||||
case ND_FRAME:
|
case ND_FRAME:
|
||||||
case ND_TRANSFORM:
|
case ND_TRANSFORM:
|
||||||
|
|
Loading…
Reference in New Issue