diff options
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_query.cc')
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_query.cc | 206 |
1 files changed, 204 insertions, 2 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index e58a7a32407..0dd3cfaa783 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -33,17 +33,29 @@ #include "MEM_guardedalloc.h" extern "C" { +#include "BLI_math.h" +#include "BKE_anim.h" #include "BKE_idcode.h" +#include "BKE_layer.h" #include "BKE_main.h" } /* extern "C" */ +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" #include "intern/depsgraph_intern.h" +#include "util/deg_util_foreach.h" + +#ifndef NDEBUG +# include "intern/eval/deg_eval_copy_on_write.h" +#endif -bool DEG_id_type_tagged(Main *bmain, short idtype) +bool DEG_id_type_tagged(Main *bmain, short id_type) { - return bmain->id_tag_update[BKE_idcode_to_index(idtype)] != 0; + return bmain->id_tag_update[BKE_idcode_to_index(id_type)] != 0; } short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id) @@ -68,3 +80,193 @@ short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id) return id_node->eval_flags; } + +Scene *DEG_get_evaluated_scene(Depsgraph *graph) +{ + DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); + Scene *scene_orig = deg_graph->scene; + return reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id)); +} + +SceneLayer *DEG_get_evaluated_scene_layer(Depsgraph *graph) +{ + Scene *scene = DEG_get_evaluated_scene(graph); + if (scene != NULL) { + return BKE_scene_layer_context_active_PLACEHOLDER(scene); + } + return NULL; +} + +Object *DEG_get_evaluated_object(Depsgraph *depsgraph, Object *object) +{ + return (Object *)DEG_get_evaluated_id(depsgraph, &object->id); +} + +ID *DEG_get_evaluated_id(struct Depsgraph *depsgraph, ID *id) +{ + /* TODO(sergey): This is a duplicate of Depsgraph::get_cow_id(), + * but here we never do assert, since we don't know nature of the + * incoming ID datablock. + */ + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph; + DEG::IDDepsNode *id_node = deg_graph->find_id_node(id); + if (id_node == NULL) { + return id; + } + return id_node->id_cow; +} + +/* ************************ DAG ITERATORS ********************* */ + +#define BASE_FLUSH_FLAGS (BASE_FROM_SET | BASE_FROMDUPLI) + +void DEG_objects_iterator_begin(BLI_Iterator *iter, DEGObjectsIteratorData *data) +{ + Depsgraph *graph = data->graph; + SceneLayer *scene_layer = DEG_get_evaluated_scene_layer(graph); + + iter->data = data; + iter->valid = true; + + data->scene = DEG_get_evaluated_scene(graph); + DEG_evaluation_context_init(&data->eval_ctx, DAG_EVAL_RENDER); + + /* TODO(sergey): It's really confusing to store pointer to a local data. */ + Base base = {(Base *)scene_layer->object_bases.first, NULL}; + data->base = &base; + + data->base_flag = ~(BASE_FLUSH_FLAGS); + + data->dupli_parent = NULL; + data->dupli_list = NULL; + data->dupli_object_next = NULL; + data->dupli_object_current = NULL; + + DEG_objects_iterator_next(iter); +} + +/** + * Temporary function to flush depsgraph until we get copy on write (CoW) + */ +static void deg_flush_base_flags_and_settings(Object *ob, Base *base, const int flag) +{ + ob->base_flag = (base->flag | BASE_FLUSH_FLAGS) & flag; + ob->base_collection_properties = base->collection_properties; +} + +static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) +{ + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + while (data->dupli_object_next != NULL) { + DupliObject *dob = data->dupli_object_next; + Object *obd = dob->ob; + + data->dupli_object_next = data->dupli_object_next->next; + + /* Group duplis need to set ob matrices correct, for deform. so no_draw + * is part handled. + */ + if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) { + continue; + } + + if (obd->type == OB_MBALL) { + continue; + } + + 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; + copy_m4_m4(data->temp_dupli_object.obmat, dob->mat); + + deg_flush_base_flags_and_settings(&data->temp_dupli_object, + data->base, + data->base_flag | BASE_FROMDUPLI); + iter->current = &data->temp_dupli_object; + BLI_assert(DEG::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id)); + return true; + } + + return false; +} + +void DEG_objects_iterator_next(BLI_Iterator *iter) +{ + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + Base *base; + + if (data->dupli_list) { + if (deg_objects_dupli_iterator_next(iter)) { + return; + } + else { + free_object_duplilist(data->dupli_list); + data->dupli_parent = NULL; + data->dupli_list = NULL; + data->dupli_object_next = NULL; + data->dupli_object_current = NULL; + } + } + + base = data->base->next; + while (base != NULL) { + if ((base->flag & BASE_VISIBLED) != 0) { + // Object *ob = DEG_get_evaluated_object(data->graph, base->object); + Object *ob = base->object; + iter->current = ob; + data->base = base; + + BLI_assert(DEG::deg_validate_copy_on_write_datablock(&ob->id)); + + /* 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 DAG_id_tag_update(). */ + BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group)); + + /* Flushing depsgraph data. */ + deg_flush_base_flags_and_settings(ob, + base, + data->base_flag); + + if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (ob->transflag & OB_DUPLI)) { + data->dupli_parent = ob; + data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, ob); + data->dupli_object_next = (DupliObject *)data->dupli_list->first; + } + return; + } + base = base->next; + } + + /* Look for an object in the next set. */ + if ((data->flag & DEG_OBJECT_ITER_FLAG_SET) && data->scene->set) { + SceneLayer *scene_layer; + data->scene = data->scene->set; + data->base_flag = ~(BASE_SELECTED | BASE_SELECTABLED); + + /* For the sets we use the layer used for rendering. */ + scene_layer = BKE_scene_layer_from_scene_get(data->scene); + + /* TODO(sergey): It's really confusing to store pointer to a local data. */ + Base base = {(Base *)scene_layer->object_bases.first, NULL}; + data->base = &base; + DEG_objects_iterator_next(iter); + return; + } + + iter->current = NULL; + iter->valid = false; +} + +void DEG_objects_iterator_end(BLI_Iterator *iter) +{ +#ifndef NDEBUG + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + /* Force crash in case the iterator data is referenced and accessed down the line. (T51718) */ + memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object)); +#else + (void) iter; +#endif +} |