diff options
author | Jacques Lucke <mail@jlucke.com> | 2019-09-12 16:45:55 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2019-09-12 16:45:55 +0300 |
commit | 592470b07b405547f7a8065ff5330f9f0a882b95 (patch) | |
tree | 4257694854993528118c9708ec3c416de002488f | |
parent | 971ad95f2bac3f2d141693bfcc7c6b190db43344 (diff) |
simplify code by changing ownership of particle functions
10 files changed, 273 insertions, 248 deletions
diff --git a/source/blender/functions/frontends/data_flow_nodes/vtree_data_graph.hpp b/source/blender/functions/frontends/data_flow_nodes/vtree_data_graph.hpp index 695f21f24e9..cfcbda6c69f 100644 --- a/source/blender/functions/frontends/data_flow_nodes/vtree_data_graph.hpp +++ b/source/blender/functions/frontends/data_flow_nodes/vtree_data_graph.hpp @@ -23,6 +23,11 @@ class VTreeDataGraph { public: VTreeDataGraph(VirtualNodeTree &vtree, SharedDataGraph graph, Array<DataSocket> mapping); + VirtualNodeTree &vtree() + { + return m_vtree; + } + SharedDataGraph &graph() { return m_graph; diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp index 3f34d29113b..72d751de7e5 100644 --- a/source/blender/simulations/bparticles/actions.cpp +++ b/source/blender/simulations/bparticles/actions.cpp @@ -55,7 +55,7 @@ void SetVelocityAction::execute(ActionInterface &interface) { auto velocities = interface.attributes().get<float3>("Velocity"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float3 velocity = inputs->get<float3>("Velocity", 0, pindex); @@ -69,7 +69,7 @@ void RandomizeVelocityAction::execute(ActionInterface &interface) { auto velocities = interface.attributes().get<float3>("Velocity"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float randomness = inputs->get<float>("Randomness", 0, pindex); @@ -87,7 +87,7 @@ void ChangeColorAction::execute(ActionInterface &interface) { auto colors = interface.attributes().get<rgba_f>("Color"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { rgba_f color = inputs->get<rgba_f>("Color", 0, pindex); colors[pindex] = color; @@ -98,7 +98,7 @@ void ChangeSizeAction::execute(ActionInterface &interface) { auto sizes = interface.attributes().get<float>("Size"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float size = inputs->get<float>("Size", 0, pindex); sizes[pindex] = size; @@ -109,7 +109,7 @@ void ChangePositionAction::execute(ActionInterface &interface) { auto positions = interface.attributes().get<float3>("Position"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float3 position = inputs->get<float3>("Position", 0, pindex); positions[pindex] = position; @@ -130,7 +130,7 @@ void ExplodeAction::execute(ActionInterface &interface) Vector<float> new_birth_times; Vector<uint> source_particles; - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex)); @@ -160,7 +160,7 @@ void ExplodeAction::execute(ActionInterface &interface) void ConditionAction::execute(ActionInterface &interface) { - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); Vector<uint> true_pindices, false_pindices; for (uint pindex : interface.pindices()) { diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp index b1cce7d87be..746c47156b8 100644 --- a/source/blender/simulations/bparticles/actions.hpp +++ b/source/blender/simulations/bparticles/actions.hpp @@ -27,11 +27,10 @@ class KillAction : public Action { class SetVelocityAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - SetVelocityAction(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + SetVelocityAction(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } @@ -40,11 +39,10 @@ class SetVelocityAction : public Action { class RandomizeVelocityAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - RandomizeVelocityAction(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + RandomizeVelocityAction(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } @@ -53,11 +51,10 @@ class RandomizeVelocityAction : public Action { class ChangeColorAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - ChangeColorAction(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + ChangeColorAction(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } @@ -66,11 +63,10 @@ class ChangeColorAction : public Action { class ChangeSizeAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - ChangeSizeAction(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + ChangeSizeAction(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } @@ -79,11 +75,10 @@ class ChangeSizeAction : public Action { class ChangePositionAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - ChangePositionAction(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + ChangePositionAction(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } @@ -93,15 +88,15 @@ class ChangePositionAction : public Action { class ExplodeAction : public Action { private: Vector<std::string> m_types_to_emit; - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Action> m_on_birth_action; public: ExplodeAction(Vector<std::string> types_to_emit, - std::unique_ptr<ParticleFunction> compute_inputs, + ParticleFunction *inputs_fn, std::unique_ptr<Action> on_birth_action) : m_types_to_emit(std::move(types_to_emit)), - m_compute_inputs(std::move(compute_inputs)), + m_inputs_fn(inputs_fn), m_on_birth_action(std::move(on_birth_action)) { } @@ -111,14 +106,14 @@ class ExplodeAction : public Action { class ConditionAction : public Action { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Action> m_true_action, m_false_action; public: - ConditionAction(std::unique_ptr<ParticleFunction> compute_inputs, + ConditionAction(ParticleFunction *inputs_fn, std::unique_ptr<Action> true_action, std::unique_ptr<Action> false_action) - : m_compute_inputs(std::move(compute_inputs)), + : m_inputs_fn(inputs_fn), m_true_action(std::move(true_action)), m_false_action(std::move(false_action)) { diff --git a/source/blender/simulations/bparticles/events.cpp b/source/blender/simulations/bparticles/events.cpp index 8a6e44592b0..116e5e8d380 100644 --- a/source/blender/simulations/bparticles/events.cpp +++ b/source/blender/simulations/bparticles/events.cpp @@ -19,7 +19,7 @@ void AgeReachedEvent::filter(EventFilterInterface &interface) AttributesRef attributes = interface.attributes(); auto ids = attributes.get<int32_t>("ID"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); TemporaryArray<float> trigger_ages(attributes.size()); for (uint pindex : interface.pindices()) { @@ -90,7 +90,7 @@ void CustomEvent::filter(EventFilterInterface &interface) } } - auto inputs = m_compute_inputs->compute( + auto inputs = m_inputs_fn->compute( pindices_to_check, interface.attributes(), ParticleTimes::FromDurationsAndEnd(interface.remaining_durations(), diff --git a/source/blender/simulations/bparticles/events.hpp b/source/blender/simulations/bparticles/events.hpp index d3de7da5516..9d05605423d 100644 --- a/source/blender/simulations/bparticles/events.hpp +++ b/source/blender/simulations/bparticles/events.hpp @@ -19,16 +19,14 @@ using BLI::float4x4; class AgeReachedEvent : public Event { private: std::string m_identifier; - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Action> m_action; public: AgeReachedEvent(StringRef identifier, - std::unique_ptr<ParticleFunction> compute_inputs, + ParticleFunction *inputs_fn, std::unique_ptr<Action> action) - : m_identifier(identifier), - m_compute_inputs(std::move(compute_inputs)), - m_action(std::move(action)) + : m_identifier(identifier), m_inputs_fn(inputs_fn), m_action(std::move(action)) { } @@ -40,16 +38,12 @@ class AgeReachedEvent : public Event { class CustomEvent : public Event { private: std::string m_identifier; - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Action> m_action; public: - CustomEvent(StringRef identifier, - std::unique_ptr<ParticleFunction> compute_inputs, - std::unique_ptr<Action> action) - : m_identifier(identifier), - m_compute_inputs(std::move(compute_inputs)), - m_action(std::move(action)) + CustomEvent(StringRef identifier, ParticleFunction *inputs_fn, std::unique_ptr<Action> action) + : m_identifier(identifier), m_inputs_fn(inputs_fn), m_action(std::move(action)) { } diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp index 5ee4ee6044c..ffd16aca14c 100644 --- a/source/blender/simulations/bparticles/forces.cpp +++ b/source/blender/simulations/bparticles/forces.cpp @@ -12,7 +12,7 @@ void GravityForce::add_force(ForceInterface &interface) { MutableArrayRef<float3> destination = interface.combined_destination(); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); TemporaryArray<float> weights(destination.size()); m_falloff->compute(interface.attributes(), interface.pindices(), weights); @@ -29,7 +29,7 @@ void TurbulenceForce::add_force(ForceInterface &interface) MutableArrayRef<float3> destination = interface.combined_destination(); auto positions = interface.attributes().get<float3>("Position"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); TemporaryArray<float> weights(destination.size()); m_falloff->compute(interface.attributes(), interface.pindices(), weights); @@ -50,7 +50,7 @@ void DragForce::add_force(ForceInterface &interface) MutableArrayRef<float3> destination = interface.combined_destination(); auto velocities = interface.attributes().get<float3>("Velocity"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); TemporaryArray<float> weights(destination.size()); m_falloff->compute(interface.attributes(), interface.pindices(), weights); @@ -68,7 +68,7 @@ void MeshForce::add_force(ForceInterface &interface) MutableArrayRef<float3> destination = interface.combined_destination(); auto positions = interface.attributes().get<float3>("Position"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float3 position = positions[pindex]; diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp index 7b41909edc8..250a40a0df3 100644 --- a/source/blender/simulations/bparticles/forces.hpp +++ b/source/blender/simulations/bparticles/forces.hpp @@ -24,12 +24,12 @@ class Force { class GravityForce : public Force { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Falloff> m_falloff; public: - GravityForce(std::unique_ptr<ParticleFunction> compute_inputs, std::unique_ptr<Falloff> falloff) - : m_compute_inputs(std::move(compute_inputs)), m_falloff(std::move(falloff)) + GravityForce(ParticleFunction *inputs_fn, std::unique_ptr<Falloff> falloff) + : m_inputs_fn(inputs_fn), m_falloff(std::move(falloff)) { } @@ -38,13 +38,12 @@ class GravityForce : public Force { class TurbulenceForce : public Force { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Falloff> m_falloff; public: - TurbulenceForce(std::unique_ptr<ParticleFunction> compute_inputs, - std::unique_ptr<Falloff> falloff) - : m_compute_inputs(std::move(compute_inputs)), m_falloff(std::move(falloff)) + TurbulenceForce(ParticleFunction *inputs_fn, std::unique_ptr<Falloff> falloff) + : m_inputs_fn(inputs_fn), m_falloff(std::move(falloff)) { } @@ -53,12 +52,12 @@ class TurbulenceForce : public Force { class DragForce : public Force { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Falloff> m_falloff; public: - DragForce(std::unique_ptr<ParticleFunction> compute_inputs, std::unique_ptr<Falloff> falloff) - : m_compute_inputs(std::move(compute_inputs)), m_falloff(std::move(falloff)) + DragForce(ParticleFunction *inputs_fn, std::unique_ptr<Falloff> falloff) + : m_inputs_fn(inputs_fn), m_falloff(std::move(falloff)) { } @@ -67,15 +66,14 @@ class DragForce : public Force { class MeshForce : public Force { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; Object *m_object; BVHTreeFromMesh m_bvhtree_data; float4x4 m_local_to_world; float4x4 m_world_to_local; public: - MeshForce(std::unique_ptr<ParticleFunction> compute_inputs, Object *object) - : m_compute_inputs(std::move(compute_inputs)), m_object(object) + MeshForce(ParticleFunction *inputs_fn, Object *object) : m_inputs_fn(inputs_fn), m_object(object) { BLI_assert(object->type == OB_MESH); m_local_to_world = m_object->obmat; diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp index 807d43540b2..852bb3f7697 100644 --- a/source/blender/simulations/bparticles/node_frontend.cpp +++ b/source/blender/simulations/bparticles/node_frontend.cpp @@ -38,10 +38,80 @@ class BehaviorCollector { MultiMap<std::string, OffsetHandler *> &m_offset_handlers; }; +class VTreeData { + private: + VTreeDataGraph &m_vtree_data_graph; + Vector<std::unique_ptr<ParticleFunction>> m_particle_functions; + Vector<SharedFunction> m_functions; + + public: + VTreeData(VTreeDataGraph &vtree_data) : m_vtree_data_graph(vtree_data) + { + } + + VirtualNodeTree &vtree() + { + return m_vtree_data_graph.vtree(); + } + + SharedDataGraph &data_graph() + { + return m_vtree_data_graph.graph(); + } + + VTreeDataGraph &vtree_data_graph() + { + return m_vtree_data_graph; + } + + ParticleFunction *particle_function_for_all_inputs(VirtualNode *vnode) + { + auto fn_or_error = create_particle_function(vnode, m_vtree_data_graph); + if (fn_or_error.is_error()) { + return {}; + } + std::unique_ptr<ParticleFunction> fn = fn_or_error.extract_value(); + ParticleFunction *fn_ptr = fn.get(); + BLI_assert(fn_ptr != nullptr); + m_particle_functions.append(std::move(fn)); + return fn_ptr; + } + + TupleCallBody &function_body_for_inputs(VirtualNode *vnode, ArrayRef<uint> input_indices) + { + SetVector<DataSocket> sockets_to_compute; + for (uint index : input_indices) { + sockets_to_compute.add_new(m_vtree_data_graph.lookup_socket(vnode->input(index))); + } + + FunctionGraph fgraph(m_vtree_data_graph.graph(), {}, sockets_to_compute); + auto fn = fgraph.new_function(vnode->name()); + FN::fgraph_add_TupleCallBody(fn, fgraph); + m_functions.append(fn); + return fn->body<TupleCallBody>(); + } + + TupleCallBody &function_body_for_all_inputs(VirtualNode *vnode) + { + SetVector<DataSocket> sockets_to_compute; + for (VirtualSocket *vsocket : vnode->inputs()) { + if (m_vtree_data_graph.uses_socket(vsocket)) { + sockets_to_compute.add_new(m_vtree_data_graph.lookup_socket(vsocket)); + } + } + + FunctionGraph fgraph(m_vtree_data_graph.graph(), {}, sockets_to_compute); + auto fn = fgraph.new_function(vnode->name()); + FN::fgraph_add_TupleCallBody(fn, fgraph); + m_functions.append(fn); + return fn->body<TupleCallBody>(); + } +}; + static StringRef particle_type_idname = "bp_ParticleTypeNode"; static StringRef combine_behaviors_idname = "bp_CombineBehaviorsNode"; -static std::unique_ptr<Action> build_action_list(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> build_action_list(VTreeData &vtree_data, VirtualNode *start_vnode, StringRef name); @@ -96,121 +166,113 @@ static Vector<VirtualSocket *> find_execute_sockets(VirtualNode *vnode, StringRe return execute_sockets; } -using ActionParserCallback = std::function<std::unique_ptr<Action>( - VTreeDataGraph &vtree_data_graph, VirtualSocket *execute_vsocket)>; +using ActionParserCallback = + std::function<std::unique_ptr<Action>(VTreeData &vtree_data, VirtualSocket *execute_vsocket)>; -static std::unique_ptr<Action> ACTION_kill(VTreeDataGraph &UNUSED(vtree_data_graph), +static std::unique_ptr<Action> ACTION_kill(VTreeData &UNUSED(vtree_data), VirtualSocket *UNUSED(execute_vsocket)) { return std::unique_ptr<Action>(new KillAction()); } -static std::unique_ptr<Action> ACTION_change_velocity(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_change_velocity(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); PointerRNA rna = vnode->rna(); int mode = RNA_enum_get(&rna, "mode"); Action *action = nullptr; if (mode == 0) { - action = new SetVelocityAction(std::move(compute_inputs_fn)); + action = new SetVelocityAction(inputs_fn); } else if (mode == 1) { - action = new RandomizeVelocityAction(std::move(compute_inputs_fn)); + action = new RandomizeVelocityAction(inputs_fn); } return std::unique_ptr<Action>(action); } -static std::unique_ptr<Action> ACTION_explode(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_explode(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); std::unique_ptr<Action> on_birth_action = build_action_list( - vtree_data_graph, vnode, "Execute on Birth"); + vtree_data, vnode, "Execute on Birth"); Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(1, "Type")); - Action *action = new ExplodeAction( - type_names, std::move(compute_inputs_fn), std::move(on_birth_action)); + Action *action = new ExplodeAction(type_names, inputs_fn, std::move(on_birth_action)); return std::unique_ptr<Action>(action); } -static std::unique_ptr<Action> ACTION_condition(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_condition(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); - auto action_true = build_action_list(vtree_data_graph, vnode, "Execute If True"); - auto action_false = build_action_list(vtree_data_graph, vnode, "Execute If False"); + auto action_true = build_action_list(vtree_data, vnode, "Execute If True"); + auto action_false = build_action_list(vtree_data, vnode, "Execute If False"); - Action *action = new ConditionAction( - std::move(compute_inputs_fn), std::move(action_true), std::move(action_false)); + Action *action = new ConditionAction(inputs_fn, std::move(action_true), std::move(action_false)); return std::unique_ptr<Action>(action); } -static std::unique_ptr<Action> ACTION_change_color(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_change_color(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); - Action *action = new ChangeColorAction(std::move(compute_inputs_fn)); + Action *action = new ChangeColorAction(inputs_fn); return std::unique_ptr<Action>(action); } -static std::unique_ptr<Action> ACTION_change_size(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_change_size(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); - Action *action = new ChangeSizeAction(std::move(compute_inputs_fn)); + Action *action = new ChangeSizeAction(inputs_fn); return std::unique_ptr<Action>(action); } -static std::unique_ptr<Action> ACTION_change_position(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> ACTION_change_position(VTreeData &vtree_data, VirtualSocket *execute_vsocket) { VirtualNode *vnode = execute_vsocket->vnode(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { + if (inputs_fn == nullptr) { return {}; } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); - Action *action = new ChangePositionAction(std::move(compute_inputs_fn)); + Action *action = new ChangePositionAction(inputs_fn); return std::unique_ptr<Action>(action); } @@ -227,7 +289,7 @@ BLI_LAZY_INIT_STATIC(StringMap<ActionParserCallback>, get_action_parsers) return map; } -static std::unique_ptr<Action> build_action(VTreeDataGraph &vtree_data_graph, VirtualSocket *start) +static std::unique_ptr<Action> build_action(VTreeData &vtree_data, VirtualSocket *start) { BLI_assert(start->is_input()); if (start->links().size() != 1) { @@ -241,40 +303,39 @@ static std::unique_ptr<Action> build_action(VTreeDataGraph &vtree_data_graph, Vi StringMap<ActionParserCallback> &parsers = get_action_parsers(); ActionParserCallback &parser = parsers.lookup(execute_socket->vnode()->idname()); - std::unique_ptr<Action> action = parser(vtree_data_graph, execute_socket); + std::unique_ptr<Action> action = parser(vtree_data, execute_socket); if (action.get() == nullptr) { return std::unique_ptr<Action>(new NoneAction()); } return action; } -static std::unique_ptr<Action> build_action_list(VTreeDataGraph &vtree_data_graph, +static std::unique_ptr<Action> build_action_list(VTreeData &vtree_data, VirtualNode *start_vnode, StringRef name) { Vector<VirtualSocket *> execute_sockets = find_execute_sockets(start_vnode, name); Vector<std::unique_ptr<Action>> actions; for (VirtualSocket *socket : execute_sockets) { - actions.append(build_action(vtree_data_graph, socket)); + actions.append(build_action(vtree_data, socket)); } Action *sequence = new ActionSequence(std::move(actions)); return std::unique_ptr<Action>(sequence); } using ParseNodeCallback = std::function<void(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &world_transition, VirtualNode *vnode)>; -static SharedFunction get_compute_data_inputs_function(VTreeDataGraph &vtree_data_graph, - VirtualNode *vnode) +static SharedFunction get_compute_data_inputs_function(VTreeData &vtree_data, VirtualNode *vnode) { - SharedDataGraph &data_graph = vtree_data_graph.graph(); + SharedDataGraph &data_graph = vtree_data.data_graph(); SetVector<DataSocket> function_outputs; for (VirtualSocket *vsocket : vnode->inputs()) { - if (vtree_data_graph.uses_socket(vsocket)) { - DataSocket socket = vtree_data_graph.lookup_socket(vsocket); + if (vtree_data.vtree_data_graph().uses_socket(vsocket)) { + DataSocket socket = vtree_data.vtree_data_graph().lookup_socket(vsocket); function_outputs.add(socket); } } @@ -287,11 +348,11 @@ static SharedFunction get_compute_data_inputs_function(VTreeDataGraph &vtree_dat } static void PARSE_point_emitter(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &world_transition, VirtualNode *vnode) { - SharedFunction inputs_fn = get_compute_data_inputs_function(vtree_data_graph, vnode); + SharedFunction inputs_fn = get_compute_data_inputs_function(vtree_data, vnode); Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Emitter")); std::string name = vnode->name(); @@ -362,18 +423,18 @@ static Vector<float> compute_emitter_vertex_weights(VirtualNode *vnode, } static void PARSE_mesh_emitter(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &world_transition, VirtualNode *vnode) { - SharedFunction compute_inputs_fn = get_compute_data_inputs_function(vtree_data_graph, vnode); - TupleCallBody &body = compute_inputs_fn->body<TupleCallBody>(); + SharedFunction inputs_fn = get_compute_data_inputs_function(vtree_data, vnode); + TupleCallBody &body = inputs_fn->body<TupleCallBody>(); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); std::unique_ptr<Action> on_birth_action = build_action_list( - vtree_data_graph, vnode, "Execute on Birth"); + vtree_data, vnode, "Execute on Birth"); Object *object = fn_out.relocate_out<ObjectW>(0).ptr(); if (object == nullptr || object->type != OB_MESH) { @@ -395,56 +456,49 @@ static void PARSE_mesh_emitter(BehaviorCollector &collector, } static void PARSE_gravity_force(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - FunctionGraph fgraph( - vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vnode->input(1, "Falloff"))}); - auto fn = fgraph.new_function("Compute Falloff"); - FN::fgraph_add_TupleCallBody(fn, fgraph); - FN::TupleCallBody &body = fn->body<TupleCallBody>(); - + FN::TupleCallBody &body = vtree_data.function_body_for_inputs(vnode, {1}); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); auto falloff = fn_out.relocate_out<FN::Types::FalloffW>(0); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Force")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - - GravityForce *force = new GravityForce(std::move(compute_inputs), falloff.get_unique_copy()); + GravityForce *force = new GravityForce(inputs_fn, falloff.get_unique_copy()); collector.m_forces.add(type_name, force); } } static void PARSE_age_reached_event(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Event")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - auto action = build_action_list(vtree_data_graph, vnode, "Execute on Event"); + auto action = build_action_list(vtree_data, vnode, "Execute on Event"); - Event *event = new AgeReachedEvent( - vnode->name(), std::move(compute_inputs), std::move(action)); + Event *event = new AgeReachedEvent(vnode->name(), inputs_fn, std::move(action)); collector.m_events.add(type_name, event); } } static void PARSE_trails(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { @@ -453,28 +507,26 @@ static void PARSE_trails(BehaviorCollector &collector, Vector<std::string> trail_type_names = find_connected_particle_type_names( vnode->output(1, "Trail Type")); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + for (std::string &main_type : main_type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - auto action = build_action_list(vtree_data_graph, vnode, "Execute on Birth"); + auto action = build_action_list(vtree_data, vnode, "Execute on Birth"); OffsetHandler *offset_handler = new CreateTrailHandler( - trail_type_names, std::move(compute_inputs), std::move(action)); + trail_type_names, inputs_fn, std::move(action)); collector.m_offset_handlers.add(main_type, offset_handler); } } static void PARSE_initial_grid_emitter(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - SharedFunction compute_inputs_fn = get_compute_data_inputs_function(vtree_data_graph, vnode); - TupleCallBody &body = compute_inputs_fn->body<TupleCallBody>(); - + TupleCallBody &body = vtree_data.function_body_for_all_inputs(vnode); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); @@ -490,126 +542,108 @@ static void PARSE_initial_grid_emitter(BehaviorCollector &collector, } static void PARSE_turbulence_force(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - FunctionGraph fgraph( - vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vnode->input(1, "Falloff"))}); - auto fn = fgraph.new_function("Compute Falloff"); - FN::fgraph_add_TupleCallBody(fn, fgraph); - FN::TupleCallBody &body = fn->body<TupleCallBody>(); - + FN::TupleCallBody &body = vtree_data.function_body_for_inputs(vnode, {1}); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); auto falloff = fn_out.relocate_out<FN::Types::FalloffW>(0); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Force")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - Force *force = new TurbulenceForce(std::move(compute_inputs), falloff.get_unique_copy()); + Force *force = new TurbulenceForce(inputs_fn, falloff.get_unique_copy()); collector.m_forces.add(type_name, force); } } static void PARSE_drag_force(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - FunctionGraph fgraph( - vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vnode->input(1, "Falloff"))}); - auto fn = fgraph.new_function("Compute Falloff"); - FN::fgraph_add_TupleCallBody(fn, fgraph); - FN::TupleCallBody &body = fn->body<TupleCallBody>(); - + FN::TupleCallBody &body = vtree_data.function_body_for_inputs(vnode, {1}); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); auto falloff = fn_out.relocate_out<FN::Types::FalloffW>(0); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Force")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - Force *force = new DragForce(std::move(compute_inputs), falloff.get_unique_copy()); + Force *force = new DragForce(inputs_fn, falloff.get_unique_copy()); collector.m_forces.add(type_name, force); } } static void PARSE_mesh_collision(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Event")); - for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs_fn = fn_or_error.extract_value(); + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } - if (compute_inputs_fn->parameter_depends_on_particle("Object", 0)) { - continue; - } + if (inputs_fn->parameter_depends_on_particle("Object", 0)) { + return; + } - SharedFunction &fn = compute_inputs_fn->function_no_deps(); - TupleCallBody &body = fn->body<TupleCallBody>(); - FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); - body.call__setup_execution_context(fn_in, fn_out); + SharedFunction &fn = inputs_fn->function_no_deps(); + TupleCallBody &body = fn->body<TupleCallBody>(); + FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); + body.call__setup_execution_context(fn_in, fn_out); - Object *object = fn_out.relocate_out<ObjectW>(0).ptr(); - if (object == nullptr || object->type != OB_MESH) { - return; - } + Object *object = fn_out.relocate_out<ObjectW>(0).ptr(); + if (object == nullptr || object->type != OB_MESH) { + return; + } - auto action = build_action_list(vtree_data_graph, vnode, "Execute on Event"); + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Event")); + for (std::string &type_name : type_names) { + auto action = build_action_list(vtree_data, vnode, "Execute on Event"); Event *event = new MeshCollisionEvent(vnode->name(), object, std::move(action)); collector.m_events.add(type_name, event); } } static void PARSE_size_over_time(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Type")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - - OffsetHandler *handler = new SizeOverTimeHandler(std::move(compute_inputs)); + OffsetHandler *handler = new SizeOverTimeHandler(inputs_fn); collector.m_offset_handlers.add(type_name, handler); } } static void PARSE_mesh_force(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { - - FunctionGraph fgraph( - vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vnode->input(0, "Object"))}); - auto fn = fgraph.new_function("Find Object"); - FN::fgraph_add_TupleCallBody(fn, fgraph); - FN::TupleCallBody &body = fn->body<TupleCallBody>(); - + FN::TupleCallBody &body = vtree_data.function_body_for_inputs(vnode, {0}); FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out); body.call__setup_execution_context(fn_in, fn_out); @@ -618,46 +652,45 @@ static void PARSE_mesh_force(BehaviorCollector &collector, return; } + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Force")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - - Force *force = new MeshForce(std::move(compute_inputs), object); + Force *force = new MeshForce(inputs_fn, object); collector.m_forces.add(type_name, force); } } static void PARSE_custom_event(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { + ParticleFunction *inputs_fn = vtree_data.particle_function_for_all_inputs(vnode); + if (inputs_fn == nullptr) { + return; + } + Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Event")); for (std::string &type_name : type_names) { - auto fn_or_error = create_particle_function(vnode, vtree_data_graph); - if (fn_or_error.is_error()) { - continue; - } - std::unique_ptr<ParticleFunction> compute_inputs = fn_or_error.extract_value(); - auto action = build_action_list(vtree_data_graph, vnode, "Execute on Event"); + auto action = build_action_list(vtree_data, vnode, "Execute on Event"); - Event *event = new CustomEvent(vnode->name(), std::move(compute_inputs), std::move(action)); + Event *event = new CustomEvent(vnode->name(), inputs_fn, std::move(action)); collector.m_events.add(type_name, event); } } static void PARSE_always_execute(BehaviorCollector &collector, - VTreeDataGraph &vtree_data_graph, + VTreeData &vtree_data, WorldTransition &UNUSED(world_transition), VirtualNode *vnode) { Vector<std::string> type_names = find_connected_particle_type_names(vnode->output(0, "Type")); for (std::string &type_name : type_names) { - auto action = build_action_list(vtree_data_graph, vnode, "Execute"); + auto action = build_action_list(vtree_data, vnode, "Execute"); OffsetHandler *handler = new AlwaysExecuteHandler(std::move(action)); collector.m_offset_handlers.add(type_name, handler); @@ -684,7 +717,7 @@ BLI_LAZY_INIT_STATIC(StringMap<ParseNodeCallback>, get_node_parsers) } static void collect_particle_behaviors( - VirtualNodeTree &vtree, + VTreeData &vtree_data, WorldTransition &world_transition, Vector<std::string> &r_type_names, Vector<Emitter *> &r_emitters, @@ -695,12 +728,6 @@ static void collect_particle_behaviors( { SCOPED_TIMER(__func__); - auto data_graph_or_error = FN::DataFlowNodes::generate_graph(vtree); - if (data_graph_or_error.is_error()) { - return; - } - std::unique_ptr<VTreeDataGraph> vtree_data_graph = data_graph_or_error.extract_value(); - StringMap<ParseNodeCallback> &parsers = get_node_parsers(); MultiMap<std::string, Force *> forces; @@ -711,15 +738,15 @@ static void collect_particle_behaviors( r_offset_handler_per_type, }; - for (VirtualNode *vnode : vtree.nodes()) { + for (VirtualNode *vnode : vtree_data.vtree().nodes()) { StringRef idname = vnode->idname(); ParseNodeCallback *callback = parsers.lookup_ptr(idname); if (callback != nullptr) { - (*callback)(collector, *vtree_data_graph, world_transition, vnode); + (*callback)(collector, vtree_data, world_transition, vnode); } } - for (VirtualNode *vnode : vtree.nodes_with_idname("bp_ParticleTypeNode")) { + for (VirtualNode *vnode : vtree_data.vtree().nodes_with_idname("bp_ParticleTypeNode")) { StringRef name = vnode->name(); r_type_names.append(name); } @@ -764,7 +791,14 @@ class NodeTreeStepSimulator : public StepSimulator { StringMap<AttributesDeclaration> attributes; StringMap<Integrator *> integrators; - collect_particle_behaviors(m_vtree, + auto data_graph_or_error = FN::DataFlowNodes::generate_graph(m_vtree); + if (data_graph_or_error.is_error()) { + return; + } + std::unique_ptr<VTreeDataGraph> vtree_data_graph = data_graph_or_error.extract_value(); + VTreeData vtree_data(*vtree_data_graph); + + collect_particle_behaviors(vtree_data, world_transition, type_names, emitters, diff --git a/source/blender/simulations/bparticles/offset_handlers.cpp b/source/blender/simulations/bparticles/offset_handlers.cpp index 20958c8dc73..13621fad6f6 100644 --- a/source/blender/simulations/bparticles/offset_handlers.cpp +++ b/source/blender/simulations/bparticles/offset_handlers.cpp @@ -7,7 +7,7 @@ void CreateTrailHandler::execute(OffsetHandlerInterface &interface) auto positions = interface.attributes().get<float3>("Position"); auto position_offsets = interface.attribute_offsets().get<float3>("Position"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); Vector<float3> new_positions; Vector<float> new_birth_times; @@ -44,7 +44,7 @@ void SizeOverTimeHandler::execute(OffsetHandlerInterface &interface) auto birth_times = interface.attributes().get<float>("Birth Time"); auto sizes = interface.attributes().get<float>("Size"); - auto inputs = m_compute_inputs->compute(interface); + auto inputs = m_inputs_fn->compute(interface); for (uint pindex : interface.pindices()) { float final_size = inputs->get<float>("Final Size", 0, pindex); diff --git a/source/blender/simulations/bparticles/offset_handlers.hpp b/source/blender/simulations/bparticles/offset_handlers.hpp index 2a35eaf6fa6..24b5999a9ee 100644 --- a/source/blender/simulations/bparticles/offset_handlers.hpp +++ b/source/blender/simulations/bparticles/offset_handlers.hpp @@ -8,15 +8,15 @@ namespace BParticles { class CreateTrailHandler : public OffsetHandler { private: Vector<std::string> m_types_to_emit; - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; std::unique_ptr<Action> m_on_birth_action; public: CreateTrailHandler(Vector<std::string> types_to_emit, - std::unique_ptr<ParticleFunction> compute_inputs, + ParticleFunction *inputs_fn, std::unique_ptr<Action> on_birth_action) : m_types_to_emit(std::move(types_to_emit)), - m_compute_inputs(std::move(compute_inputs)), + m_inputs_fn(inputs_fn), m_on_birth_action(std::move(on_birth_action)) { } @@ -26,11 +26,10 @@ class CreateTrailHandler : public OffsetHandler { class SizeOverTimeHandler : public OffsetHandler { private: - std::unique_ptr<ParticleFunction> m_compute_inputs; + ParticleFunction *m_inputs_fn; public: - SizeOverTimeHandler(std::unique_ptr<ParticleFunction> compute_inputs) - : m_compute_inputs(std::move(compute_inputs)) + SizeOverTimeHandler(ParticleFunction *inputs_fn) : m_inputs_fn(inputs_fn) { } |