[Bf-blender-cvs] [e64fa963ded] functions: initial particle group implementation

Jacques Lucke noreply at git.blender.org
Sun Sep 22 15:05:54 CEST 2019


Commit: e64fa963deddda12193e47107ae5f53de8219b9c
Author: Jacques Lucke
Date:   Sun Sep 22 15:05:45 2019 +0200
Branches: functions
https://developer.blender.org/rBe64fa963deddda12193e47107ae5f53de8219b9c

initial particle group implementation

===================================================================

A	release/scripts/startup/nodes/bparticle_nodes/groups.py
M	release/scripts/startup/nodes/bparticle_nodes/mockups.py
M	source/blender/functions/backends/cpp/cpp_type_info.hpp
M	source/blender/simulations/bparticles/actions.cpp
M	source/blender/simulations/bparticles/actions.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp
M	source/blender/simulations/bparticles/particle_function_builder.cpp
M	source/blender/simulations/bparticles/particle_function_input_providers.cpp
M	source/blender/simulations/bparticles/particle_function_input_providers.hpp

===================================================================

diff --git a/release/scripts/startup/nodes/bparticle_nodes/groups.py b/release/scripts/startup/nodes/bparticle_nodes/groups.py
new file mode 100644
index 00000000000..429b6c67554
--- /dev/null
+++ b/release/scripts/startup/nodes/bparticle_nodes/groups.py
@@ -0,0 +1,31 @@
+import bpy
+from bpy.props import *
+from .. base import BParticlesNode
+from .. node_builder import NodeBuilder
+
+
+class AddToGroupNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_AddToGroupNode"
+    bl_label = "Add to Group"
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("group_name", "Group", "Text")
+        builder.execute_output("execute", "Execute")
+
+
+class RemoveFromGroupNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_RemoveFromGroupNode"
+    bl_label = "Remove from Group"
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("group_name", "Group", "Text")
+        builder.execute_output("execute", "Execute")
+
+
+class IsInGroupNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_IsInGroupNode"
+    bl_label = "Is in Group"
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_input("group_name", "Group", "Text")
+        builder.fixed_output("is_in_group", "Is in Group", "Boolean")
diff --git a/release/scripts/startup/nodes/bparticle_nodes/mockups.py b/release/scripts/startup/nodes/bparticle_nodes/mockups.py
index e168f2edfb4..6b6081e2528 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/mockups.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/mockups.py
@@ -14,33 +14,6 @@ class ParticleMeshDistanceNode(bpy.types.Node, BParticlesNode):
         builder.fixed_output("is_inside", "Is Inside", "Boolean")
 
 
-class AddToGroupNode(bpy.types.Node, BParticlesNode):
-    bl_idname = "bp_AddToGroupNode"
-    bl_label = "Mockup - Add to Group"
-
-    def declaration(self, builder: NodeBuilder):
-        builder.fixed_input("group_name", "Group", "Text")
-        builder.execute_output("execute", "Execute")
-
-
-class RemoveFromGroupNode(bpy.types.Node, BParticlesNode):
-    bl_idname = "bp_RemoveFromGroupNode"
-    bl_label = "Mockup - Remove from Group"
-
-    def declaration(self, builder: NodeBuilder):
-        builder.fixed_input("group_name", "Group", "Text")
-        builder.execute_output("execute", "Execute")
-
-
-class IsInGroupNode(bpy.types.Node, BParticlesNode):
-    bl_idname = "bp_IsInGroupNode"
-    bl_label = "Mockup - Is in Group"
-
-    def declaration(self, builder: NodeBuilder):
-        builder.fixed_input("group_name", "Group", "Text")
-        builder.fixed_output("is_in_group", "Is in Group", "Boolean")
-
-
 class DerivedAttributeNode(bpy.types.Node, BParticlesNode):
     bl_idname = "bp_DerivedAttributeNode"
     bl_label = "Mockup - Derived Attribute"
diff --git a/source/blender/functions/backends/cpp/cpp_type_info.hpp b/source/blender/functions/backends/cpp/cpp_type_info.hpp
index 74d76f20f12..2919fb75dfd 100644
--- a/source/blender/functions/backends/cpp/cpp_type_info.hpp
+++ b/source/blender/functions/backends/cpp/cpp_type_info.hpp
@@ -300,8 +300,15 @@ template<typename T> class UniquePointerWrapper {
 
   T *operator->()
   {
+    BLI_assert(m_ptr != nullptr);
     return m_ptr;
   }
+
+  T &operator*()
+  {
+    BLI_assert(m_ptr != nullptr);
+    return *m_ptr;
+  }
 };
 
 /**
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index 35cf68a1a6a..f9f7aec9046 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -177,4 +177,25 @@ void ConditionAction::execute(ActionInterface &interface)
   m_false_action.execute_for_subset(false_pindices, interface);
 }
 
+void AddToGroupAction::execute(ActionInterface &interface)
+{
+  auto is_in_group = interface.attributes().get<uint8_t>(m_group_name);
+  for (uint pindex : interface.pindices()) {
+    is_in_group[pindex] = true;
+  }
+}
+
+void RemoveFromGroupAction::execute(ActionInterface &interface)
+{
+  auto is_in_group_optional = interface.attributes().try_get<uint8_t>(m_group_name);
+  if (!is_in_group_optional.has_value()) {
+    return;
+  }
+
+  MutableArrayRef<uint8_t> is_in_group = *is_in_group_optional;
+  for (uint pindex : interface.pindices()) {
+    is_in_group[pindex] = false;
+  }
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/actions.hpp b/source/blender/simulations/bparticles/actions.hpp
index 53afbd00b62..e63cbf6fd80 100644
--- a/source/blender/simulations/bparticles/actions.hpp
+++ b/source/blender/simulations/bparticles/actions.hpp
@@ -119,4 +119,28 @@ class ConditionAction : public Action {
   void execute(ActionInterface &interface) override;
 };
 
+class AddToGroupAction : public Action {
+ private:
+  std::string m_group_name;
+
+ public:
+  AddToGroupAction(std::string group_name) : m_group_name(std::move(group_name))
+  {
+  }
+
+  void execute(ActionInterface &interface) override;
+};
+
+class RemoveFromGroupAction : public Action {
+ private:
+  std::string m_group_name;
+
+ public:
+  RemoveFromGroupAction(std::string group_name) : m_group_name(std::move(group_name))
+  {
+  }
+
+  void execute(ActionInterface &interface) override;
+};
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index 3bdbb54fc0e..7abaa22bf2e 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -354,6 +354,41 @@ static std::unique_ptr<Action> ACTION_change_position(InfluencesCollector &UNUSE
   return std::unique_ptr<Action>(action);
 }
 
+static std::unique_ptr<Action> ACTION_add_to_group(InfluencesCollector &collector,
+                                                   VTreeData &vtree_data,
+                                                   VirtualSocket *execute_vsocket)
+{
+  VirtualNode *vnode = execute_vsocket->vnode();
+  auto inputs = vtree_data.compute_all_data_inputs(vnode);
+  if (!inputs.has_value()) {
+    return {};
+  }
+
+  StringW group_name = inputs->relocate_out<StringW>(0, "Group");
+
+  /* Add group to all particle systems for now. */
+  collector.m_attributes.foreach_value(
+      [&](AttributesDeclaration &attributes) { attributes.add<uint8_t>(*group_name, 0); });
+
+  Action *action = new AddToGroupAction(*group_name);
+  return std::unique_ptr<Action>(action);
+}
+
+static std::unique_ptr<Action> ACTION_remove_from_group(InfluencesCollector &UNUSED(collector),
+                                                        VTreeData &vtree_data,
+                                                        VirtualSocket *execute_vsocket)
+{
+  VirtualNode *vnode = execute_vsocket->vnode();
+  auto inputs = vtree_data.compute_all_data_inputs(vnode);
+  if (!inputs.has_value()) {
+    return {};
+  }
+
+  StringW group_name = inputs->relocate_out<StringW>(0, "Group");
+  Action *action = new RemoveFromGroupAction(*group_name);
+  return std::unique_ptr<Action>(action);
+}
+
 BLI_LAZY_INIT(StringMap<ActionParserCallback>, get_action_parsers)
 {
   StringMap<ActionParserCallback> map;
@@ -364,6 +399,8 @@ BLI_LAZY_INIT(StringMap<ActionParserCallback>, get_action_parsers)
   map.add_new("bp_ChangeParticleColorNode", ACTION_change_color);
   map.add_new("bp_ChangeParticleSizeNode", ACTION_change_size);
   map.add_new("bp_ChangeParticlePositionNode", ACTION_change_position);
+  map.add_new("bp_AddToGroupNode", ACTION_add_to_group);
+  map.add_new("bp_RemoveFromGroupNode", ACTION_remove_from_group);
   return map;
 }
 
diff --git a/source/blender/simulations/bparticles/particle_function_builder.cpp b/source/blender/simulations/bparticles/particle_function_builder.cpp
index 263351c0a27..af248eb146c 100644
--- a/source/blender/simulations/bparticles/particle_function_builder.cpp
+++ b/source/blender/simulations/bparticles/particle_function_builder.cpp
@@ -142,6 +142,22 @@ static ParticleFunctionInputProvider *INPUT_randomness_input(
   return new RandomFloatInputProvider(seed);
 }
 
+static ParticleFunctionInputProvider *INPUT_is_in_group(VTreeDataGraph &vtree_data_graph,
+                                                        VirtualSocket *vsocket)
+{
+  FunctionGraph fgraph(
+      vtree_data_graph.graph(), {}, {vtree_data_graph.lookup_socket(vsocket->vnode()->input(0))});
+  FN::SharedFunction fn = fgraph.new_function(vsocket->vnode()->name());
+  FN::fgraph_add_TupleCallBody(fn, fgraph);
+
+  FN::TupleCallBody &body = fn->body<TupleCallBody>();
+  FN_TUPLE_CALL_ALLOC_TUPLES(body, fn_in, fn_out);
+  body.call__setup_execution_context(fn_in, fn_out);
+  StringW group_name = fn_out.relocate_out<StringW>(0);
+
+  return new IsInGroupInputProvider(*group_name);
+}
+
 BLI_LAZY_INIT_STATIC(StringMap<BuildInputProvider>, get_input_providers_map)
 {
   StringMap<BuildInputProvider> map;
@@ -150,6 +166,7 @@ BLI_LAZY_INIT_STATIC(StringMap<BuildInputProvider>, get_input_providers_map)
   map.add_new("bp_SurfaceImageNode", INPUT_surface_image);
   map.add_new("bp_SurfaceWeightNode", INPUT_surface_weight);
   map.add_new("bp_ParticleRandomnessInputNode", INPUT_randomness_input);
+  map.add_new("bp_IsInGroupNode", INPUT_is_in_group);
   return map;
 }
 
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.cpp b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
index 8ad4026a5a9..fdf459242f2 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.cpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
@@ -245,4 +245,24 @@ Optional<ParticleFunctionInputArray> RandomFloatInputProvider::get(
   return ParticleFunctionInputArray(random_values.as_ref(), true);
 }
 
+Optional<ParticleFunctionInputArray> IsInGroupInputProvider::get(InputProviderInterface &interface)
+{
+  auto is_in_group_output = BLI::temporary_allocate_array<uint8_t>(interface.attributes().size());
+
+  auto is_in_group_optional = interface.attributes().try_get<uint8_t>(m_group_name);
+  if (is_in_group_optional.has_value()) {
+    ArrayRef<uint8_t> is_in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list