diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-24 13:15:13 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-24 13:15:13 +0300 |
commit | b53c46d760568f02cd8be45547a4ffacad3c7b47 (patch) | |
tree | 51abc55d4735fedefbfccca6d4e13b074f75f88b /source/blender/simulation | |
parent | 141deeefff5f68a3fd629f91ddda22ba49f9a4e0 (diff) |
BLI: add MultiValueMap
This is a convenience wrapper for `Map<Key, Vector<Value>>`.
It does not provide any performance benefits (yet). I need this
kind of map in a couple of places and before I was duplicating
the lookup logic in many places.
Diffstat (limited to 'source/blender/simulation')
3 files changed, 20 insertions, 36 deletions
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc index eebfe8b864e..7554f61404a 100644 --- a/source/blender/simulation/intern/simulation_collect_influences.cc +++ b/source/blender/simulation/intern/simulation_collect_influences.cc @@ -122,13 +122,12 @@ static void find_and_deduplicate_particle_attribute_nodes(nodes::MFNetworkTreeMa return; } - Map<std::pair<std::string, fn::MFDataType>, Vector<fn::MFNode *>> + MultiValueMap<std::pair<std::string, fn::MFDataType>, fn::MFNode *> attribute_nodes_by_name_and_type; for (int i : attribute_names->index_range()) { - attribute_nodes_by_name_and_type - .lookup_or_add_default( - {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()}) - .append(&name_sockets[i]->node()); + attribute_nodes_by_name_and_type.add( + {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()}, + &name_sockets[i]->node()); } Map<const fn::MFOutputSocket *, std::string> attribute_inputs; @@ -237,11 +236,11 @@ class ParticleFunctionForce : public ParticleForce { } }; -static Vector<const ParticleForce *> create_forces_for_particle_simulation( - const nodes::DNode &simulation_node, - nodes::MFNetworkTreeMap &network_map, - ResourceCollector &resources, - DummyDataSources &data_sources) +static void create_forces_for_particle_simulation(const nodes::DNode &simulation_node, + nodes::MFNetworkTreeMap &network_map, + ResourceCollector &resources, + DummyDataSources &data_sources, + SimulationInfluences &r_influences) { Vector<const ParticleForce *> forces; for (const nodes::DOutputSocket *origin_socket : @@ -264,7 +263,9 @@ static Vector<const ParticleForce *> create_forces_for_particle_simulation( const ParticleForce &force = resources.construct<ParticleFunctionForce>(AT, *particle_fn); forces.append(&force); } - return forces; + + std::string particle_name = dnode_to_path(simulation_node); + r_influences.particle_forces.add_multiple(std::move(particle_name), forces); } static void collect_forces(nodes::MFNetworkTreeMap &network_map, @@ -273,10 +274,8 @@ static void collect_forces(nodes::MFNetworkTreeMap &network_map, SimulationInfluences &r_influences) { for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) { - std::string name = dnode_to_path(*dnode); - Vector<const ParticleForce *> forces = create_forces_for_particle_simulation( - *dnode, network_map, resources, data_sources); - r_influences.particle_forces.add_new(std::move(name), std::move(forces)); + create_forces_for_particle_simulation( + *dnode, network_map, resources, data_sources, r_influences); } } diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc index 1ed60022e2d..5ab706dbb4b 100644 --- a/source/blender/simulation/intern/simulation_solver.cc +++ b/source/blender/simulation/intern/simulation_solver.cc @@ -137,7 +137,7 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_c { int particle_amount = attributes.size(); Array<float3> force_vectors{particle_amount, {0, 0, 0}}; - Span<const ParticleForce *> forces = solve_context.influences().get_particle_forces( + Span<const ParticleForce *> forces = solve_context.influences().particle_forces.lookup_as( state.head.name); ParticleChunkContext particle_chunk_context{IndexMask(particle_amount), attributes}; diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh index 0eb4dfbaf69..95e6463e60d 100644 --- a/source/blender/simulation/intern/simulation_solver_influences.hh +++ b/source/blender/simulation/intern/simulation_solver_influences.hh @@ -18,6 +18,7 @@ #define __SIM_SIMULATION_SOLVER_INFLUENCES_HH__ #include "BLI_float3.hh" +#include "BLI_multi_value_map.hh" #include "BLI_span.hh" #include "DNA_simulation_types.h" @@ -48,31 +49,21 @@ class ParticleForce { }; struct SimulationInfluences { - /* TODO: Use a special type for a map that contains vectors. */ - Map<std::string, Vector<const ParticleForce *>> particle_forces; + MultiValueMap<std::string, const ParticleForce *> particle_forces; Map<std::string, fn::AttributesInfoBuilder *> particle_attributes_builder; Vector<const ParticleEmitter *> particle_emitters; - - Span<const ParticleForce *> get_particle_forces(StringRef particle_name) const - { - const Vector<const ParticleForce *> *forces = particle_forces.lookup_ptr(particle_name); - if (forces == nullptr) { - return {}; - } - return *forces; - } }; class SimulationStateMap { private: Map<StringRefNull, SimulationState *> states_by_name_; - Map<StringRefNull, Vector<SimulationState *>> states_by_type_; + MultiValueMap<StringRefNull, SimulationState *> states_by_type_; public: void add(SimulationState *state) { states_by_name_.add_new(state->name, state); - states_by_type_.lookup_or_add_default(state->type).append(state); + states_by_type_.add(state->type, state); } template<typename StateType> StateType *lookup(StringRef name) const @@ -101,13 +92,7 @@ class SimulationStateMap { Span<SimulationState *> lookup_type(StringRef type) const { - const Vector<SimulationState *> *states = states_by_type_.lookup_ptr_as(type); - if (states == nullptr) { - return {}; - } - else { - return states->as_span(); - } + return states_by_type_.lookup_as(type); } }; |