[Bf-blender-cvs] [a72bcf11e0b] functions: new Surface Weights input node

Jacques Lucke noreply at git.blender.org
Tue Sep 3 16:23:16 CEST 2019


Commit: a72bcf11e0be7c2d1d7add0657b2120ab6e6edd7
Author: Jacques Lucke
Date:   Tue Sep 3 15:13:27 2019 +0200
Branches: functions
https://developer.blender.org/rBa72bcf11e0be7c2d1d7add0657b2120ab6e6edd7

new Surface Weights input node

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

M	release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
M	source/blender/simulations/bparticles/action_contexts.hpp
M	source/blender/simulations/bparticles/emitters.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/particle_inputs.py b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
index 64b6b9624d3..f403d3166bd 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
@@ -35,3 +35,16 @@ class SurfaceImageNode(bpy.types.Node, BParticlesNode):
 
     def draw(self, layout):
         layout.prop(self, "image", text="")
+
+
+class SurfaceWeightNode(bpy.types.Node, BParticlesNode):
+    bl_idname = "bp_SurfaceWeightNode"
+    bl_label = "Surface Weight"
+
+    group_name: StringProperty()
+
+    def declaration(self, builder: NodeBuilder):
+        builder.fixed_output("weight", "Weight", "Float")
+
+    def draw(self, layout):
+        layout.prop(self, "group_name", text="")
diff --git a/source/blender/simulations/bparticles/action_contexts.hpp b/source/blender/simulations/bparticles/action_contexts.hpp
index f55a1c93d63..229a9493048 100644
--- a/source/blender/simulations/bparticles/action_contexts.hpp
+++ b/source/blender/simulations/bparticles/action_contexts.hpp
@@ -10,7 +10,7 @@ using BLI::float4x4;
 
 class MeshSurfaceActionContext : public ActionContext {
  public:
-  virtual const Object *object() const = 0;
+  virtual Object *object() const = 0;
   virtual ArrayRef<float4x4> world_transforms() const = 0;
   virtual ArrayRef<float3> local_positions() const = 0;
   virtual ArrayRef<float3> local_normals() const = 0;
@@ -58,7 +58,7 @@ class MeshEmitterContext : public MeshSurfaceActionContext, public EmitterAction
     m_looptri_indices = m_all_looptri_indices.slice(slice.start(), slice.size());
   }
 
-  const Object *object() const override
+  Object *object() const override
   {
     return m_object;
   }
@@ -114,7 +114,7 @@ class MeshCollisionContext : public MeshSurfaceActionContext {
   {
   }
 
-  const Object *object() const override
+  Object *object() const override
   {
     return m_object;
   }
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index d6e1fd90810..00466405e10 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -266,8 +266,8 @@ void SurfaceEmitter::emit(EmitterInterface &interface)
 
   Mesh *mesh = (Mesh *)m_object->data;
 
-  ArrayRef<MLoopTri> triangles(BKE_mesh_runtime_looptri_ensure(mesh),
-                               BKE_mesh_runtime_looptri_len(mesh));
+  const MLoopTri *triangles_buffer = BKE_mesh_runtime_looptri_ensure(mesh);
+  ArrayRef<MLoopTri> triangles(triangles_buffer, BKE_mesh_runtime_looptri_len(mesh));
   if (triangles.size() == 0) {
     return;
   }
diff --git a/source/blender/simulations/bparticles/particle_function_builder.cpp b/source/blender/simulations/bparticles/particle_function_builder.cpp
index 24e40914cfa..eeae31356b5 100644
--- a/source/blender/simulations/bparticles/particle_function_builder.cpp
+++ b/source/blender/simulations/bparticles/particle_function_builder.cpp
@@ -98,12 +98,22 @@ static ParticleFunctionInputProvider *INPUT_surface_image(VTreeDataGraph &UNUSED
   return new SurfaceImageInputProvider(image);
 }
 
+static ParticleFunctionInputProvider *INPUT_surface_weight(
+    VTreeDataGraph &UNUSED(vtree_data_graph), VirtualSocket *vsocket)
+{
+  PointerRNA rna = vsocket->vnode()->rna();
+  char group_name[65];
+  RNA_string_get(&rna, "group_name", group_name);
+  return new VertexWeightInputProvider(group_name);
+}
+
 BLI_LAZY_INIT_STATIC(StringMap<BuildInputProvider>, get_input_providers_map)
 {
   StringMap<BuildInputProvider> map;
   map.add_new("bp_ParticleInfoNode", INPUT_particle_info);
   map.add_new("bp_CollisionInfoNode", INPUT_collision_info);
   map.add_new("bp_SurfaceImageNode", INPUT_surface_image);
+  map.add_new("bp_SurfaceWeightNode", INPUT_surface_weight);
   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 d7c73d50629..b518c94c16d 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.cpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.cpp
@@ -4,6 +4,7 @@
 #include "DNA_customdata_types.h"
 #include "BKE_customdata.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_deform.h"
 
 #include "particle_function_input_providers.hpp"
 #include "action_contexts.hpp"
@@ -134,4 +135,59 @@ Optional<ParticleFunctionInputArray> SurfaceImageInputProvider::get(
   return ParticleFunctionInputArray(ArrayRef<rgba_f>(colors), true);
 }
 
+Optional<ParticleFunctionInputArray> VertexWeightInputProvider::get(
+    InputProviderInterface &interface)
+{
+  auto *surface_info = dynamic_cast<MeshSurfaceActionContext *>(interface.action_context());
+  if (surface_info == nullptr) {
+    return {};
+  }
+
+  Object *object = surface_info->object();
+  Mesh *mesh = (Mesh *)object->data;
+
+  MDeformVert *vertex_weights = mesh->dvert;
+  int group_index = defgroup_name_index(object, m_group_name.data());
+  if (group_index == -1 || vertex_weights == nullptr) {
+    return {};
+  }
+
+  ArrayRef<float3> local_positions = surface_info->local_positions();
+  const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
+
+  float *weight_buffer = (float *)BLI_temporary_allocate(sizeof(float) *
+                                                         interface.attributes().size());
+  MutableArrayRef<float> weights(weight_buffer, interface.attributes().size());
+
+  for (uint pindex : interface.pindices()) {
+    float3 local_position = local_positions[pindex];
+    uint triangle_index = surface_info->looptri_indices()[pindex];
+    const MLoopTri &triangle = triangles[triangle_index];
+
+    uint loop1 = triangle.tri[0];
+    uint loop2 = triangle.tri[1];
+    uint loop3 = triangle.tri[2];
+
+    uint vert1 = mesh->mloop[loop1].v;
+    uint vert2 = mesh->mloop[loop2].v;
+    uint vert3 = mesh->mloop[loop3].v;
+
+    float3 v1 = mesh->mvert[vert1].co;
+    float3 v2 = mesh->mvert[vert2].co;
+    float3 v3 = mesh->mvert[vert3].co;
+
+    float3 bary_weights;
+    interp_weights_tri_v3(bary_weights, v1, v2, v3, local_position);
+
+    float3 corner_weights{defvert_find_weight(vertex_weights + vert1, group_index),
+                          defvert_find_weight(vertex_weights + vert2, group_index),
+                          defvert_find_weight(vertex_weights + vert3, group_index)};
+
+    float weight = float3::dot(bary_weights, corner_weights);
+    weights[pindex] = weight;
+  }
+
+  return ParticleFunctionInputArray(ArrayRef<float>(weights), true);
+}
+
 }  // namespace BParticles
diff --git a/source/blender/simulations/bparticles/particle_function_input_providers.hpp b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
index fe3e87f83b5..7c301d085d7 100644
--- a/source/blender/simulations/bparticles/particle_function_input_providers.hpp
+++ b/source/blender/simulations/bparticles/particle_function_input_providers.hpp
@@ -41,4 +41,16 @@ class SurfaceImageInputProvider : public ParticleFunctionInputProvider {
   Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
 };
 
+class VertexWeightInputProvider : public ParticleFunctionInputProvider {
+ private:
+  std::string m_group_name;
+
+ public:
+  VertexWeightInputProvider(StringRef group_name) : m_group_name(group_name)
+  {
+  }
+
+  Optional<ParticleFunctionInputArray> get(InputProviderInterface &interface) override;
+};
+
 }  // namespace BParticles



More information about the Bf-blender-cvs mailing list