Simulation: add depsgraph relations for ids referenced by node tree
I'll really have to refactor `ntreeUpdateTree` soon to avoid scanning all node trees multiple times.
This commit is contained in:
parent
6596891121
commit
634585aa68
|
@ -32,6 +32,7 @@ void *BKE_simulation_add(struct Main *bmain, const char *name);
|
|||
void BKE_simulation_data_update(struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
struct Simulation *simulation);
|
||||
void BKE_simulation_update_dependencies(struct Simulation *simulation, struct Main *bmain);
|
||||
|
||||
SimulationState *BKE_simulation_state_add(Simulation *simulation,
|
||||
const char *type,
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "BKE_lib_query.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_simulation.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_threads.h"
|
||||
|
@ -3638,6 +3639,16 @@ void ntreeUpdateAllUsers(Main *main, ID *ngroup)
|
|||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
static void ntreeUpdateSimulationDependencies(Main *main, bNodeTree *simulation_ntree)
|
||||
{
|
||||
FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
|
||||
if (GS(owner_id->name) == ID_SIM && ntree == simulation_ntree) {
|
||||
BKE_simulation_update_dependencies((Simulation *)owner_id, main);
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
||||
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
|
||||
{
|
||||
bNode *node;
|
||||
|
@ -3695,6 +3706,11 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
|
|||
ntree_validate_links(ntree);
|
||||
}
|
||||
|
||||
if (bmain != NULL && ntree->typeinfo == ntreeType_Simulation &&
|
||||
(ntree->id.flag & LIB_EMBEDDED_DATA)) {
|
||||
ntreeUpdateSimulationDependencies(bmain, ntree);
|
||||
}
|
||||
|
||||
/* clear update flags */
|
||||
for (node = ntree->nodes.first; node; node = node->next) {
|
||||
node->update = 0;
|
||||
|
|
|
@ -285,6 +285,14 @@ void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *
|
|||
blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation);
|
||||
}
|
||||
|
||||
void BKE_simulation_update_dependencies(Simulation *simulation, Main *bmain)
|
||||
{
|
||||
bool dependencies_changed = blender::sim::update_simulation_dependencies(simulation);
|
||||
if (dependencies_changed) {
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
}
|
||||
|
||||
using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>;
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -2634,6 +2634,25 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
|
|||
OperationKey nodetree_key(
|
||||
&simulation->nodetree->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EXIT);
|
||||
add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0);
|
||||
|
||||
LISTBASE_FOREACH (
|
||||
PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
|
||||
if (handle_item->id == nullptr) {
|
||||
continue;
|
||||
}
|
||||
build_id(handle_item->id);
|
||||
if (GS(handle_item->id->name) == ID_OB) {
|
||||
Object *object = (Object *)handle_item->id;
|
||||
if (handle_item->flag & SIM_HANDLE_DEPENDS_ON_TRANSFORM) {
|
||||
ComponentKey object_transform_key(&object->id, NodeType::TRANSFORM);
|
||||
add_relation(object_transform_key, simulation_eval_key, "Object Transform -> Simulation");
|
||||
}
|
||||
if (handle_item->flag & SIM_HANDLE_DEPENDS_ON_GEOMETRY) {
|
||||
ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
|
||||
add_relation(object_geometry_key, simulation_eval_key, "Object Geometry -> Simulation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef struct PersistentDataHandleItem {
|
|||
struct PersistentDataHandleItem *prev;
|
||||
struct ID *id;
|
||||
int handle;
|
||||
char _pad[4];
|
||||
int flag;
|
||||
} PersistentDataHandleItem;
|
||||
|
||||
/* Simulation.flag */
|
||||
|
@ -80,6 +80,12 @@ enum {
|
|||
SIM_DS_EXPAND = (1 << 0),
|
||||
};
|
||||
|
||||
/* PersistentDataHandleItem.flag */
|
||||
enum {
|
||||
SIM_HANDLE_DEPENDS_ON_TRANSFORM = (1 << 0),
|
||||
SIM_HANDLE_DEPENDS_ON_GEOMETRY = (1 << 1),
|
||||
};
|
||||
|
||||
#define SIM_TYPE_NAME_PARTICLE_SIMULATION "Particle Simulation"
|
||||
#define SIM_TYPE_NAME_PARTICLE_MESH_EMITTER "Particle Mesh Emitter"
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "BKE_animsys.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_simulation.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
@ -2848,6 +2849,14 @@ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
rna_NodeSocketStandard_value_update(C, ptr);
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
}
|
||||
|
||||
/* ******** Node Types ******** */
|
||||
|
||||
static void rna_NodeInternalSocketTemplate_name_get(PointerRNA *ptr, char *value)
|
||||
|
@ -8862,7 +8871,8 @@ static void rna_def_node_socket_object(BlenderRNA *brna,
|
|||
RNA_def_property_pointer_sdna(prop, NULL, "value");
|
||||
RNA_def_property_struct_type(prop, "Object");
|
||||
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
|
||||
RNA_def_property_update(
|
||||
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
|
||||
|
||||
/* socket interface */
|
||||
|
@ -8896,7 +8906,8 @@ static void rna_def_node_socket_image(BlenderRNA *brna,
|
|||
RNA_def_property_pointer_sdna(prop, NULL, "value");
|
||||
RNA_def_property_struct_type(prop, "Image");
|
||||
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
|
||||
RNA_def_property_update(
|
||||
prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
|
||||
|
||||
/* socket interface */
|
||||
|
|
|
@ -278,6 +278,7 @@ set(SRC
|
|||
intern/node_common.c
|
||||
intern/node_exec.c
|
||||
intern/node_socket.cc
|
||||
intern/node_tree_dependencies.cc
|
||||
intern/node_tree_multi_function.cc
|
||||
intern/node_tree_ref.cc
|
||||
intern/node_util.c
|
||||
|
@ -292,6 +293,7 @@ set(SRC
|
|||
NOD_composite.h
|
||||
NOD_derived_node_tree.hh
|
||||
NOD_function.h
|
||||
NOD_node_tree_dependencies.hh
|
||||
NOD_node_tree_multi_function.hh
|
||||
NOD_node_tree_ref.hh
|
||||
NOD_shader.h
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __NOD_NODE_TREE_DEPENDENCIES_H__
|
||||
#define __NOD_NODE_TREE_DEPENDENCIES_H__
|
||||
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
struct bNodeTree;
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
class NodeTreeDependencies {
|
||||
private:
|
||||
VectorSet<Object *> transform_deps_;
|
||||
VectorSet<Object *> geometry_deps_;
|
||||
VectorSet<ID *> id_deps_;
|
||||
|
||||
public:
|
||||
void add_transform_dependency(Object *object)
|
||||
{
|
||||
if (object == nullptr) {
|
||||
return;
|
||||
}
|
||||
transform_deps_.add(object);
|
||||
id_deps_.add(&object->id);
|
||||
}
|
||||
|
||||
void add_geometry_dependency(Object *object)
|
||||
{
|
||||
if (object == nullptr) {
|
||||
return;
|
||||
}
|
||||
geometry_deps_.add(object);
|
||||
id_deps_.add(&object->id);
|
||||
}
|
||||
|
||||
bool depends_on(ID *id) const
|
||||
{
|
||||
return id_deps_.contains(id);
|
||||
}
|
||||
|
||||
Span<Object *> transform_dependencies()
|
||||
{
|
||||
return transform_deps_;
|
||||
}
|
||||
|
||||
Span<Object *> geometry_dependencies()
|
||||
{
|
||||
return geometry_deps_;
|
||||
}
|
||||
|
||||
Span<ID *> id_dependencies()
|
||||
{
|
||||
return id_deps_;
|
||||
}
|
||||
};
|
||||
|
||||
NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree);
|
||||
|
||||
} // namespace blender::nodes
|
||||
|
||||
#endif /* __NOD_NODE_TREE_DEPENDENCIES_H__ */
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "NOD_node_tree_dependencies.hh"
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BKE_node.h"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
static void add_dependencies_of_node_tree(bNodeTree &ntree, NodeTreeDependencies &r_dependencies)
|
||||
{
|
||||
/* TODO: Do a bit more sophisticated parsing to see which dependencies are really required. */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
|
||||
if (socket->type == SOCK_OBJECT) {
|
||||
Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
|
||||
if (object != nullptr) {
|
||||
r_dependencies.add_transform_dependency(object);
|
||||
if (object->type == OB_MESH) {
|
||||
r_dependencies.add_geometry_dependency(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node->type == NODE_GROUP) {
|
||||
bNodeTree *group = (bNodeTree *)node->id;
|
||||
if (group != nullptr) {
|
||||
add_dependencies_of_node_tree(*group, r_dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree)
|
||||
{
|
||||
NodeTreeDependencies dependencies;
|
||||
add_dependencies_of_node_tree(ntree, dependencies);
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
} // namespace blender::nodes
|
|
@ -27,6 +27,8 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
|
|||
Scene *scene_cow,
|
||||
Simulation *simulation_cow);
|
||||
|
||||
}
|
||||
bool update_simulation_dependencies(Simulation *simulation);
|
||||
|
||||
} // namespace blender::sim
|
||||
|
||||
#endif /* __SIM_SIMULATION_UPDATE_HH__ */
|
||||
|
|
|
@ -436,28 +436,10 @@ static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network
|
|||
}
|
||||
}
|
||||
|
||||
static void find_used_persistent_data(const nodes::DerivedNodeTree &tree,
|
||||
UsedPersistentData &r_used_persistent_data)
|
||||
{
|
||||
const bNodeSocketType *socktype = nodeSocketTypeFind("NodeSocketObject");
|
||||
BLI_assert(socktype != nullptr);
|
||||
|
||||
for (const nodes::DInputSocket *dsocket : tree.input_sockets()) {
|
||||
const bNodeSocket *bsocket = dsocket->bsocket();
|
||||
if (bsocket->typeinfo == socktype) {
|
||||
Object *object = ((const bNodeSocketValueObject *)bsocket->default_value)->value;
|
||||
if (object != nullptr) {
|
||||
r_used_persistent_data.add(DEG_get_original_id(&object->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void collect_simulation_influences(Simulation &simulation,
|
||||
ResourceCollector &resources,
|
||||
SimulationInfluences &r_influences,
|
||||
RequiredStates &r_required_states,
|
||||
UsedPersistentData &r_used_persistent_data)
|
||||
RequiredStates &r_required_states)
|
||||
{
|
||||
nodes::NodeTreeRefMap tree_refs;
|
||||
const nodes::DerivedNodeTree tree{simulation.nodetree, tree_refs};
|
||||
|
@ -481,8 +463,6 @@ void collect_simulation_influences(Simulation &simulation,
|
|||
for (const nodes::DNode *dnode : get_particle_simulation_nodes(tree)) {
|
||||
r_required_states.add(dnode_to_path(*dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION);
|
||||
}
|
||||
|
||||
find_used_persistent_data(tree, r_used_persistent_data);
|
||||
}
|
||||
|
||||
} // namespace blender::sim
|
||||
|
|
|
@ -58,29 +58,10 @@ class RequiredStates {
|
|||
}
|
||||
};
|
||||
|
||||
class UsedPersistentData {
|
||||
private:
|
||||
VectorSet<ID *> used_ids_;
|
||||
|
||||
public:
|
||||
void add(ID *id)
|
||||
{
|
||||
BLI_assert(id != nullptr);
|
||||
BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
|
||||
used_ids_.add(id);
|
||||
}
|
||||
|
||||
const VectorSet<ID *> &used_ids() const
|
||||
{
|
||||
return used_ids_;
|
||||
}
|
||||
};
|
||||
|
||||
void collect_simulation_influences(Simulation &simulation,
|
||||
ResourceCollector &resources,
|
||||
SimulationInfluences &r_influences,
|
||||
RequiredStates &r_required_states,
|
||||
UsedPersistentData &r_used_persistent_data);
|
||||
RequiredStates &r_required_states);
|
||||
|
||||
} // namespace blender::sim
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "BLI_set.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "NOD_node_tree_dependencies.hh"
|
||||
|
||||
#include "particle_function.hh"
|
||||
#include "simulation_collect_influences.hh"
|
||||
#include "simulation_solver.hh"
|
||||
|
@ -90,56 +92,6 @@ static void update_simulation_state_list(Simulation *simulation,
|
|||
add_missing_states(simulation, required_states);
|
||||
}
|
||||
|
||||
/* TODO: It might be better to do this as part of ntreeUpdateTree, so that the information
|
||||
* about referenced data blocks is available when building the depsgraph. */
|
||||
static void update_persistent_data_handles(Simulation &simulation_orig,
|
||||
const UsedPersistentData &used_persistent_data)
|
||||
{
|
||||
Set<ID *> contained_ids;
|
||||
Set<int> used_handles;
|
||||
|
||||
/* Remove handles that have been invalidated. */
|
||||
LISTBASE_FOREACH_MUTABLE (
|
||||
PersistentDataHandleItem *, handle_item, &simulation_orig.persistent_data_handles) {
|
||||
if (handle_item->id == nullptr) {
|
||||
BLI_remlink(&simulation_orig.persistent_data_handles, handle_item);
|
||||
MEM_freeN(handle_item);
|
||||
continue;
|
||||
}
|
||||
if (!used_persistent_data.used_ids().contains(handle_item->id)) {
|
||||
id_us_min(handle_item->id);
|
||||
BLI_remlink(&simulation_orig.persistent_data_handles, handle_item);
|
||||
MEM_freeN(handle_item);
|
||||
continue;
|
||||
}
|
||||
contained_ids.add_new(handle_item->id);
|
||||
used_handles.add_new(handle_item->handle);
|
||||
}
|
||||
|
||||
/* Add new handles that are not in the list yet. */
|
||||
int next_handle = 0;
|
||||
for (ID *id : used_persistent_data.used_ids()) {
|
||||
if (contained_ids.contains(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find the next available handle. */
|
||||
while (used_handles.contains(next_handle)) {
|
||||
next_handle++;
|
||||
}
|
||||
used_handles.add_new(next_handle);
|
||||
|
||||
PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN(
|
||||
sizeof(*handle_item), AT);
|
||||
/* Cannot store const pointers in DNA. */
|
||||
id_us_plus(id);
|
||||
handle_item->id = id;
|
||||
handle_item->handle = next_handle;
|
||||
|
||||
BLI_addtail(&simulation_orig.persistent_data_handles, handle_item);
|
||||
}
|
||||
}
|
||||
|
||||
void update_simulation_in_depsgraph(Depsgraph *depsgraph,
|
||||
Scene *scene_cow,
|
||||
Simulation *simulation_cow)
|
||||
|
@ -159,11 +111,8 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
|
|||
ResourceCollector resources;
|
||||
SimulationInfluences influences;
|
||||
RequiredStates required_states;
|
||||
UsedPersistentData used_persistent_data;
|
||||
|
||||
collect_simulation_influences(
|
||||
*simulation_cow, resources, influences, required_states, used_persistent_data);
|
||||
update_persistent_data_handles(*simulation_orig, used_persistent_data);
|
||||
collect_simulation_influences(*simulation_cow, resources, influences, required_states);
|
||||
|
||||
bke::PersistentDataHandleMap handle_map;
|
||||
LISTBASE_FOREACH (
|
||||
|
@ -191,4 +140,81 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
/* Returns true when dependencies have changed. */
|
||||
bool update_simulation_dependencies(Simulation *simulation)
|
||||
{
|
||||
nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies(
|
||||
*simulation->nodetree);
|
||||
|
||||
ListBase *handle_list = &simulation->persistent_data_handles;
|
||||
|
||||
bool dependencies_changed = false;
|
||||
|
||||
Map<ID *, PersistentDataHandleItem *> handle_item_by_id;
|
||||
Map<PersistentDataHandleItem *, int> old_flag_by_handle_item;
|
||||
Set<int> used_handles;
|
||||
|
||||
/* Remove unused handle items and clear flags that are reinitialized later. */
|
||||
LISTBASE_FOREACH_MUTABLE (PersistentDataHandleItem *, handle_item, handle_list) {
|
||||
if (dependencies.depends_on(handle_item->id)) {
|
||||
handle_item_by_id.add_new(handle_item->id, handle_item);
|
||||
used_handles.add_new(handle_item->handle);
|
||||
old_flag_by_handle_item.add_new(handle_item, handle_item->flag);
|
||||
handle_item->flag &= ~(SIM_HANDLE_DEPENDS_ON_TRANSFORM | SIM_HANDLE_DEPENDS_ON_GEOMETRY);
|
||||
}
|
||||
else {
|
||||
if (handle_item->id != nullptr) {
|
||||
id_us_min(handle_item->id);
|
||||
}
|
||||
BLI_remlink(handle_list, handle_item);
|
||||
MEM_freeN(handle_item);
|
||||
dependencies_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add handle items for new id dependencies. */
|
||||
int next_handle = 0;
|
||||
for (ID *id : dependencies.id_dependencies()) {
|
||||
handle_item_by_id.lookup_or_add_cb(id, [&]() {
|
||||
while (used_handles.contains(next_handle)) {
|
||||
next_handle++;
|
||||
}
|
||||
used_handles.add_new(next_handle);
|
||||
|
||||
PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN(
|
||||
sizeof(*handle_item), AT);
|
||||
id_us_plus(id);
|
||||
handle_item->id = id;
|
||||
handle_item->handle = next_handle;
|
||||
BLI_addtail(handle_list, handle_item);
|
||||
|
||||
return handle_item;
|
||||
});
|
||||
}
|
||||
|
||||
/* Set appropriate dependency flags. */
|
||||
for (Object *object : dependencies.transform_dependencies()) {
|
||||
PersistentDataHandleItem *handle_item = handle_item_by_id.lookup(&object->id);
|
||||
handle_item->flag |= SIM_HANDLE_DEPENDS_ON_TRANSFORM;
|
||||
}
|
||||
for (Object *object : dependencies.geometry_dependencies()) {
|
||||
PersistentDataHandleItem *handle_item = handle_item_by_id.lookup(&object->id);
|
||||
handle_item->flag |= SIM_HANDLE_DEPENDS_ON_GEOMETRY;
|
||||
}
|
||||
|
||||
if (!dependencies_changed) {
|
||||
/* Check if any flags have changed. */
|
||||
LISTBASE_FOREACH (PersistentDataHandleItem *, handle_item, handle_list) {
|
||||
int old_flag = old_flag_by_handle_item.lookup_default(handle_item, 0);
|
||||
int new_flag = handle_item->flag;
|
||||
if (old_flag != new_flag) {
|
||||
dependencies_changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dependencies_changed;
|
||||
}
|
||||
|
||||
} // namespace blender::sim
|
||||
|
|
Loading…
Reference in New Issue