/* SPDX-FileCopyrightText: 2013 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup depsgraph * * Public API for Depsgraph * * Dependency Graph * ================ * * The dependency graph tracks relations between various pieces of data in * a Blender file, but mainly just those which make up scene data. It is used * to determine the set of operations need to ensure that all data has been * correctly evaluated in response to changes, based on dependencies and visibility * of affected data. * Evaluation Engine * ================= * * The evaluation takes the operation-nodes the Depsgraph has tagged for updating, * and schedules them up for being evaluated/executed such that the all dependency * relationship constraints are satisfied. */ /* ************************************************* */ /* Forward-defined typedefs for core types * - These are used in all depsgraph code and by all callers of Depsgraph API... */ #pragma once #include "DNA_ID.h" namespace blender { /* Dependency Graph */ struct Depsgraph; /* ------------------------------------------------ */ struct Main; struct Scene; struct ViewLayer; enum eEvaluationMode { DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */ DAG_EVAL_RENDER = 1, /* evaluate for render purposes */ }; /* DagNode->eval_flags */ enum { /* Regardless to curve->path animation flag path is to be evaluated anyway, * to meet dependencies with such a things as curve modifier and other guys * who're using curve deform, where_on_path and so. */ DAG_EVAL_NEED_CURVE_PATH = (1 << 0), /* A shrinkwrap modifier or constraint targeting this mesh needs information * about non-manifold boundary edges for the Target Normal Project mode. */ DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY = (1 << 1), }; /* ************************************************ */ /* Depsgraph API */ /* -------------------------------------------------------------------- */ /** \name CRUD * \{ */ /* Get main depsgraph instance from context! */ /** * Create new Depsgraph instance. * * TODO: what arguments are needed here? What's the building-graph entry point? */ Depsgraph *DEG_graph_new(Main *bmain, Scene *scene, ViewLayer *view_layer, eEvaluationMode mode); /** * Replace the "owner" pointers (currently Main/Scene/ViewLayer) of this depsgraph. * Used for: * - Undo steps when we do want to re-use the old depsgraph data as much as possible. * - Rendering where we want to re-use objects between different view layers. */ void DEG_graph_replace_owners(Depsgraph *depsgraph, Main *bmain, Scene *scene, ViewLayer *view_layer); /** Free graph's contents and graph itself. */ void DEG_graph_free(Depsgraph *graph); /** \} */ /* -------------------------------------------------------------------- */ /** \name Node Types Registry * \{ */ /** Register all node types. */ void DEG_register_node_types(); /** Free node type registry on exit. */ void DEG_free_node_types(); /** \} */ /* -------------------------------------------------------------------- */ /** \name Update Tagging * \{ */ /** Tag dependency graph for updates when visible scenes/layers changes. */ void DEG_graph_tag_on_visible_update(Depsgraph *depsgraph, bool do_time); /** Tag all dependency graphs for update when visible scenes/layers changes. */ void DEG_tag_on_visible_update(Main *bmain, bool do_time); /** * \note Will return NULL if the flag is not known, allowing to gracefully handle situations * when recalc flag has been removed. */ const char *DEG_update_tag_as_string(IDRecalcFlag flag); /** Tag given ID for an update in all the dependency graphs. */ void DEG_id_tag_update(ID *id, unsigned int flags); void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags); void DEG_graph_id_tag_update(Main *bmain, Depsgraph *depsgraph, ID *id, unsigned int flags); /** * Tag the given ID for an update in the given depsgraph even though it evaluated state might not * have changed. This can be used when some data is required that is generated as a side effect of * the evaluation. For example, baking an intermediate geometry in geometry nodes needs this, * because the to-be-baked geometry has to be recomputed even though no input changed and the final * geometry also did not change. */ void DEG_id_tag_update_for_side_effect_request(Depsgraph *depsgraph, ID *id, unsigned int flags); /** Tag all dependency graphs when time has changed. */ void DEG_time_tag_update(Main *bmain); /** Tag a dependency graph when time has changed. */ void DEG_graph_time_tag_update(Depsgraph *depsgraph); /** * Mark a particular data-block type as having changing. * This does not cause any updates but is used by external * render engines to detect if for example a data-block was removed. */ void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type); void DEG_id_type_tag(Main *bmain, short id_type); /** * Set a depsgraph to flush updates to editors. This would be done * for viewport depsgraphs, but not render or export depsgraph for example. */ void DEG_enable_editors_update(Depsgraph *depsgraph); /** Check if something was changed in the database and inform editors about this. */ void DEG_editors_update(Depsgraph *depsgraph, bool time); /** Clear recalc flags after editors or renderers have handled updates. */ void DEG_ids_clear_recalc(Depsgraph *depsgraph, bool backup); /** * Restore recalc flags, backed up by a previous call to #DEG_ids_clear_recalc. * This also clears the backup. */ void DEG_ids_restore_recalc(Depsgraph *depsgraph); /** \} */ /* ************************************************ */ /* Evaluation Engine API */ /* -------------------------------------------------------------------- */ /** \name Graph Evaluation * \{ */ enum DepsgraphEvaluateSyncWriteback { DEG_EVALUATE_SYNC_WRITEBACK_NO, /** * Allow writing back to original data after depsgraph evaluation. The change to original data * may add new ID relations and may tag the depsgraph as changed again. */ DEG_EVALUATE_SYNC_WRITEBACK_YES, }; /** * Frame changed recalculation entry point. * * \note The frame-change happened for root scene that graph belongs to. */ void DEG_evaluate_on_framechange( Depsgraph *graph, float frame, DepsgraphEvaluateSyncWriteback sync_writeback = DEG_EVALUATE_SYNC_WRITEBACK_NO); /** * Data changed recalculation entry point. * Evaluate all nodes tagged for updating. */ void DEG_evaluate_on_refresh( Depsgraph *graph, DepsgraphEvaluateSyncWriteback sync_writeback = DEG_EVALUATE_SYNC_WRITEBACK_NO); /** \} */ /* -------------------------------------------------------------------- */ /** \name Editors Integration * * Mechanism to allow editors to be informed of depsgraph updates, * to do their own updates based on changes. * \{ */ struct DEGEditorUpdateContext { Main *bmain; Depsgraph *depsgraph; Scene *scene; ViewLayer *view_layer; }; using DEG_EditorUpdateIDCb = void (*)(const DEGEditorUpdateContext *update_ctx, ID *id); using DEG_EditorUpdateSceneCb = void (*)(const DEGEditorUpdateContext *update_ctx, bool updated); /** Set callbacks which are being called when depsgraph changes. */ void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func, DEG_EditorUpdateSceneCb scene_func); /** \} */ /* -------------------------------------------------------------------- */ /** \name Evaluation * \{ */ bool DEG_is_evaluating(const Depsgraph *depsgraph); bool DEG_is_active(const Depsgraph *depsgraph); void DEG_make_active(Depsgraph *depsgraph); void DEG_make_inactive(Depsgraph *depsgraph); /* Returns the number of times the graph has been evaluated. */ uint64_t DEG_get_update_count(const Depsgraph *depsgraph); /** * Disable the visibility optimization making it so IDs which affect hidden objects or disabled * modifiers are still evaluated. * * For example, this ensures that an object which is needed by a modifier is ignoring checks about * whether the object is hidden or the modifier is disabled. */ void DEG_disable_visibility_optimization(Depsgraph *depsgraph); /** \} */ /* -------------------------------------------------------------------- */ /** \name Evaluation Debug * \{ */ void DEG_debug_print_begin(Depsgraph *depsgraph); void DEG_debug_print_eval(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address); void DEG_debug_print_eval_subdata(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address); void DEG_debug_print_eval_subdata_index(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address, int subdata_index); void DEG_debug_print_eval_parent_typed(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *parent_comment, const char *parent_name, const void *parent_address); void DEG_debug_print_eval_time(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, float time); /** \} */ } // namespace blender