Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_query.cc')
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc206
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
+}