[Bf-blender-cvs] [ea068aeb227] functions: start implementing vertex group support in emitter

Jacques Lucke noreply at git.blender.org
Wed Aug 28 18:01:22 CEST 2019


Commit: ea068aeb2279e0681fd1ab45618273604915a629
Author: Jacques Lucke
Date:   Wed Aug 28 14:23:38 2019 +0200
Branches: functions
https://developer.blender.org/rBea068aeb2279e0681fd1ab45618273604915a629

start implementing vertex group support in emitter

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

M	release/scripts/startup/nodes/bparticle_nodes/mesh_emitter.py
M	source/blender/blenkernel/BKE_deform.h
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/emitters.hpp
M	source/blender/simulations/bparticles/node_frontend.cpp

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

diff --git a/release/scripts/startup/nodes/bparticle_nodes/mesh_emitter.py b/release/scripts/startup/nodes/bparticle_nodes/mesh_emitter.py
index 6014a2d9bf7..37f24856997 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/mesh_emitter.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/mesh_emitter.py
@@ -15,5 +15,6 @@ class MeshEmitterNode(bpy.types.Node, BParticlesNode):
         builder.fixed_input("normal_velocity", "Normal Velocity", "Float", default=1)
         builder.fixed_input("emitter_velocity", "Emitter Velocity", "Float", default=0)
         builder.fixed_input("size", "Size", "Float", default=0.05)
+        builder.fixed_input("density_vertex_group", "Density Group", "Text")
         builder.execute_input("execute_on_birth", "Execute on Birth", "execute_on_birth__prop")
         builder.particle_effector_output("emitter", "Emitter")
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index fd7fa632999..056b2caa3d8 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -25,6 +25,10 @@
  * \brief support for deformation groups and hooks.
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct ListBase;
 struct MDeformVert;
 struct MEdge;
@@ -142,4 +146,8 @@ void BKE_defvert_extract_vgroup_to_polyweights(struct MDeformVert *dvert,
 
 void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __BKE_DEFORM_H__ */
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index caf435eea15..24185d299b0 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -5,8 +5,10 @@
 
 #include "BKE_curve.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_deform.h"
 
 #include "BLI_math_geom.h"
+#include "BLI_vector_adaptor.hpp"
 
 #include "FN_types.hpp"
 
@@ -14,6 +16,7 @@
 
 namespace BParticles {
 
+using BLI::VectorAdaptor;
 using FN::SharedList;
 using namespace FN::Types;
 
@@ -61,6 +64,75 @@ static float3 random_point_in_triangle(float3 a, float3 b, float3 c)
   return a + dir1 * rand1 + dir2 * rand2;
 }
 
+static BLI_NOINLINE void get_all_vertex_weights(Object *ob,
+                                                Mesh *mesh,
+                                                StringRefNull group_name,
+                                                MutableArrayRef<float> r_vertex_weights)
+{
+  int group_index = defgroup_name_index(ob, group_name.data());
+  if (group_index == -1) {
+    r_vertex_weights.fill(0);
+    return;
+  }
+
+  MDeformVert *vertices = mesh->dvert;
+  for (uint i = 0; i < mesh->totvert; i++) {
+    r_vertex_weights[i] = defvert_find_weight(vertices + i, group_index);
+  }
+}
+
+static BLI_NOINLINE float get_average_poly_weights(const Mesh *mesh,
+                                                   ArrayRef<float> vertex_weights,
+                                                   TemporaryVector<float> &r_poly_weights,
+                                                   TemporaryVector<uint> &r_polys_with_weight)
+{
+  float weight_sum = 0.0f;
+
+  for (uint poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
+    const MPoly &poly = mesh->mpoly[poly_index];
+    float poly_weight = 0.0f;
+    for (const MLoop &loop : BLI::ref_c_array(mesh->mloop + poly.loopstart, poly.totloop)) {
+      poly_weight += vertex_weights[loop.v];
+    }
+    if (poly_weight > 0) {
+      poly_weight /= poly.totloop;
+      r_polys_with_weight.append(poly_index);
+      r_poly_weights.append(poly_weight);
+      weight_sum += poly_weight;
+    }
+  }
+
+  return weight_sum;
+}
+
+static BLI_NOINLINE void sample_weighted_slots(uint amount,
+                                               ArrayRef<float> weights,
+                                               float total_weight,
+                                               MutableArrayRef<uint> r_sampled_indices)
+{
+  BLI_assert(amount == r_sampled_indices.size());
+
+  float remaining_weight = total_weight;
+  uint remaining_amount = amount;
+  VectorAdaptor<uint> all_samples(r_sampled_indices.begin(), amount);
+
+  for (uint i = 0; i < weights.size(); i++) {
+    float weight = weights[i];
+    float factor = weight / remaining_weight;
+    float samples_of_index = factor * remaining_amount;
+    float frac = samples_of_index - floorf(samples_of_index);
+    if (random_float() < frac) {
+      samples_of_index += 1;
+    }
+    uint int_samples_of_index = (uint)samples_of_index;
+    all_samples.append_n_times(i, int_samples_of_index);
+
+    remaining_weight -= weight;
+    remaining_amount -= int_samples_of_index;
+  }
+  BLI_assert(all_samples.is_full());
+}
+
 void SurfaceEmitter::emit(EmitterInterface &interface)
 {
   if (m_object == nullptr) {
@@ -87,12 +159,27 @@ void SurfaceEmitter::emit(EmitterInterface &interface)
     return;
   }
 
+  // TemporaryArray<float> vertex_weights(mesh->totvert);
+  // TemporaryVector<float> poly_weights;
+  // TemporaryVector<uint> poly_indices_with_weight;
+  // get_all_vertex_weights(m_object, mesh, m_density_group, vertex_weights);
+  // float weight_sum = get_average_poly_weights(
+  //     mesh, vertex_weights, poly_weights, poly_indices_with_weight);
+
+  // TemporaryArray<uint> sampled_weighted_indices(particles_to_emit);
+  // sample_weighted_slots(particles_to_emit, poly_weights, weight_sum, sampled_weighted_indices);
+
   Vector<float3> positions;
   Vector<float3> velocities;
   Vector<float> sizes;
   Vector<float> birth_times;
 
   for (uint i = 0; i < particles_to_emit; i++) {
+    // uint poly_index = poly_indices_with_weight[sampled_weighted_indices[i]];
+    // MPoly &poly = mesh->mpoly[poly_index];
+    // uint triangle_start_index = poly_to_tri_count(poly_index, poly.loopstart);
+    // uint triangle_index = triangle_start_index + (rand() % (poly.totloop - 2));
+    // MLoopTri triangle = triangles[triangle_index];
     MLoopTri triangle = triangles[rand() % triangle_amount];
     float birth_moment = random_float();
 
diff --git a/source/blender/simulations/bparticles/emitters.hpp b/source/blender/simulations/bparticles/emitters.hpp
index 4eed3bb5236..a86561d7808 100644
--- a/source/blender/simulations/bparticles/emitters.hpp
+++ b/source/blender/simulations/bparticles/emitters.hpp
@@ -22,6 +22,7 @@ class SurfaceEmitter : public Emitter {
   float m_normal_velocity;
   float m_emitter_velocity;
   float m_size;
+  std::string m_density_group;
 
  public:
   SurfaceEmitter(Vector<std::string> types_to_emit,
@@ -31,7 +32,8 @@ class SurfaceEmitter : public Emitter {
                  float rate,
                  float normal_velocity,
                  float emitter_velocity,
-                 float size)
+                 float size,
+                 StringRef density_group)
       : m_types_to_emit(std::move(types_to_emit)),
         m_on_birth_action(std::move(on_birth_action)),
         m_object(object),
@@ -39,7 +41,8 @@ class SurfaceEmitter : public Emitter {
         m_rate(rate),
         m_normal_velocity(normal_velocity),
         m_emitter_velocity(emitter_velocity),
-        m_size(size)
+        m_size(size),
+        m_density_group(density_group)
   {
   }
 
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index f7134ecd09c..c95ca097c19 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -280,7 +280,8 @@ static void PARSE_mesh_emitter(BehaviorCollector &collector,
                                         body.get_output<float>(fn_out, 1, "Rate"),
                                         body.get_output<float>(fn_out, 2, "Normal Velocity"),
                                         body.get_output<float>(fn_out, 3, "Emitter Velocity"),
-                                        body.get_output<float>(fn_out, 4, "Size"));
+                                        body.get_output<float>(fn_out, 4, "Size"),
+                                        StringRef(fn_out.relocate_out<FN::Types::MyString>(5)));
   collector.m_emitters.append(emitter);
 }



More information about the Bf-blender-cvs mailing list