[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