Simulation: cleanup dna data

This commit is contained in:
2020-07-25 11:54:06 +02:00
parent ddd4fec386
commit eeaa4379aa
6 changed files with 69 additions and 69 deletions

View File

@@ -112,9 +112,8 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
BKE_simulation_state_copy_data(state_src, state_dst);
}
BLI_listbase_clear(&simulation_dst->persistent_data_handles);
BLI_duplicatelist(&simulation_dst->persistent_data_handles,
&simulation_src->persistent_data_handles);
BLI_listbase_clear(&simulation_dst->dependencies);
BLI_duplicatelist(&simulation_dst->dependencies, &simulation_src->dependencies);
}
static void simulation_free_data(ID *id)
@@ -131,7 +130,7 @@ static void simulation_free_data(ID *id)
BKE_simulation_state_remove_all(simulation);
BLI_freelistN(&simulation->persistent_data_handles);
BLI_freelistN(&simulation->dependencies);
}
static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -141,9 +140,8 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
}
LISTBASE_FOREACH (
PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
BKE_LIB_FOREACHID_PROCESS_ID(data, handle_item->id, IDWALK_CB_USER);
LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
BKE_LIB_FOREACHID_PROCESS_ID(data, dependency->id, IDWALK_CB_USER);
}
}

View File

@@ -8677,9 +8677,8 @@ static void direct_link_volume(BlendDataReader *reader, Volume *volume)
static void lib_link_simulation(BlendLibReader *reader, Simulation *simulation)
{
LISTBASE_FOREACH (
PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
BLO_read_id_address(reader, simulation->id.lib, &handle_item->id);
LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
BLO_read_id_address(reader, simulation->id.lib, &dependency->id);
}
}
@@ -8698,7 +8697,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
}
}
BLO_read_list(reader, &simulation->persistent_data_handles);
BLO_read_list(reader, &simulation->dependencies);
}
/** \} */
@@ -11107,9 +11106,8 @@ static void expand_simulation(BlendExpander *expander, Simulation *simulation)
if (simulation->adt) {
expand_animdata(expander, simulation->adt);
}
LISTBASE_FOREACH (
PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
BLO_expand(expander, handle_item->id);
LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
BLO_expand(expander, dependency->id);
}
}

View File

@@ -3862,7 +3862,7 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
}
}
BLO_write_struct_list(writer, PersistentDataHandleItem, &simulation->persistent_data_handles);
BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies);
}
}

View File

@@ -2636,19 +2636,18 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
&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) {
LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
if (dependency->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) {
build_id(dependency->id);
if (GS(dependency->id->name) == ID_OB) {
Object *object = (Object *)dependency->id;
if (dependency->flag & SIM_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) {
if (dependency->flag & SIM_DEPENDS_ON_GEOMETRY) {
ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
add_relation(object_geometry_key, simulation_eval_key, "Object Geometry -> Simulation");
}

View File

@@ -30,16 +30,21 @@ typedef struct Simulation {
struct bNodeTree *nodetree;
int flag;
uint32_t flag;
/** This is the frame in scene time, that the states correspond to. */
float current_frame;
/** Time since the start of the simulation in simulation time (which might differ from scene
* time). */
float current_simulation_time;
char _pad[4];
/** List containing SimulationState objects. */
struct ListBase states;
/** List containing PersistentDataHandleItem objects. */
struct ListBase persistent_data_handles;
/** List containing SimulationDependency objects. */
struct ListBase dependencies;
} Simulation;
typedef struct SimulationState {
@@ -54,8 +59,8 @@ typedef struct ParticleSimulationState {
SimulationState head;
/** Contains the state of the particles at time Simulation->current_frame. */
int tot_particles;
int next_particle_id;
int32_t tot_particles;
int32_t next_particle_id;
struct CustomData attributes;
} ParticleSimulationState;
@@ -66,24 +71,25 @@ typedef struct ParticleMeshEmitterSimulationState {
char _pad[4];
} ParticleMeshEmitterSimulationState;
/** Stores a mapping between an integer handle and a corresponding ID data block. */
typedef struct PersistentDataHandleItem {
struct PersistentDataHandleItem *next;
struct PersistentDataHandleItem *prev;
/** Stores a reference to data that the simulation depends on. This is partially derived from the
* simulation node tree. */
typedef struct SimulationDependency {
struct SimulationDependency *next;
struct SimulationDependency *prev;
struct ID *id;
int handle;
int flag;
} PersistentDataHandleItem;
int32_t handle;
uint32_t flag;
} SimulationDependency;
/* Simulation.flag */
enum {
SIM_DS_EXPAND = (1 << 0),
};
/* PersistentDataHandleItem.flag */
/* SimulationDependency.flag */
enum {
SIM_HANDLE_DEPENDS_ON_TRANSFORM = (1 << 0),
SIM_HANDLE_DEPENDS_ON_GEOMETRY = (1 << 1),
SIM_DEPENDS_ON_TRANSFORM = (1 << 0),
SIM_DEPENDS_ON_GEOMETRY = (1 << 1),
};
#define SIM_TYPE_NAME_PARTICLE_SIMULATION "Particle Simulation"

View File

@@ -115,10 +115,9 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
collect_simulation_influences(*simulation_cow, resources, influences, required_states);
bke::PersistentDataHandleMap handle_map;
LISTBASE_FOREACH (
PersistentDataHandleItem *, handle_item, &simulation_orig->persistent_data_handles) {
ID *id_cow = DEG_get_evaluated_id(depsgraph, handle_item->id);
handle_map.add(handle_item->handle, *id_cow);
LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation_orig->dependencies) {
ID *id_cow = DEG_get_evaluated_id(depsgraph, dependency->id);
handle_map.add(dependency->handle, *id_cow);
}
if (current_frame == 1) {
@@ -146,28 +145,28 @@ bool update_simulation_dependencies(Simulation *simulation)
nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies(
*simulation->nodetree);
ListBase *handle_list = &simulation->persistent_data_handles;
ListBase *dependency_list = &simulation->dependencies;
bool dependencies_changed = false;
Map<ID *, PersistentDataHandleItem *> handle_item_by_id;
Map<PersistentDataHandleItem *, int> old_flag_by_handle_item;
Map<ID *, SimulationDependency *> dependency_by_id;
Map<SimulationDependency *, int> old_flag_by_dependency;
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);
LISTBASE_FOREACH_MUTABLE (SimulationDependency *, dependency, dependency_list) {
if (dependencies.depends_on(dependency->id)) {
dependency_by_id.add_new(dependency->id, dependency);
used_handles.add_new(dependency->handle);
old_flag_by_dependency.add_new(dependency, dependency->flag);
dependency->flag &= ~(SIM_DEPENDS_ON_TRANSFORM | SIM_DEPENDS_ON_GEOMETRY);
}
else {
if (handle_item->id != nullptr) {
id_us_min(handle_item->id);
if (dependency->id != nullptr) {
id_us_min(dependency->id);
}
BLI_remlink(handle_list, handle_item);
MEM_freeN(handle_item);
BLI_remlink(dependency_list, dependency);
MEM_freeN(dependency);
dependencies_changed = true;
}
}
@@ -175,38 +174,38 @@ bool update_simulation_dependencies(Simulation *simulation)
/* 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, [&]() {
dependency_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);
SimulationDependency *dependency = (SimulationDependency *)MEM_callocN(sizeof(*dependency),
AT);
id_us_plus(id);
handle_item->id = id;
handle_item->handle = next_handle;
BLI_addtail(handle_list, handle_item);
dependency->id = id;
dependency->handle = next_handle;
BLI_addtail(dependency_list, dependency);
return handle_item;
return dependency;
});
}
/* 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;
SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
dependency->flag |= SIM_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;
SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
dependency->flag |= SIM_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;
LISTBASE_FOREACH (SimulationDependency *, dependency, dependency_list) {
uint32_t old_flag = old_flag_by_dependency.lookup_default(dependency, 0);
uint32_t new_flag = dependency->flag;
if (old_flag != new_flag) {
dependencies_changed = true;
break;