[Bf-blender-cvs] [b716661366e] functions: support for vertex weights in Sample Object Surface node

Jacques Lucke noreply at git.blender.org
Thu Dec 12 18:28:22 CET 2019


Commit: b716661366e536095a54c5f2f6981fbcc6b91ccd
Author: Jacques Lucke
Date:   Thu Dec 12 14:59:39 2019 +0100
Branches: functions
https://developer.blender.org/rBb716661366e536095a54c5f2f6981fbcc6b91ccd

support for vertex weights in Sample Object Surface node

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

M	release/scripts/startup/nodes/function_nodes/object_mesh.py
M	source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
M	source/blender/functions/intern/multi_functions/surface_hook.cc
M	source/blender/functions/intern/multi_functions/surface_hook.h

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

diff --git a/release/scripts/startup/nodes/function_nodes/object_mesh.py b/release/scripts/startup/nodes/function_nodes/object_mesh.py
index 4399378833a..55a7516914d 100644
--- a/release/scripts/startup/nodes/function_nodes/object_mesh.py
+++ b/release/scripts/startup/nodes/function_nodes/object_mesh.py
@@ -89,8 +89,24 @@ class SampleObjectSurfaceNode(bpy.types.Node, FunctionNode):
     bl_idname = "fn_SampleObjectSurfaceNode"
     bl_label = "Sample Object Surface"
 
+    weight_mode: EnumProperty(
+        name="Weight Mode",
+        items=[
+            ("UNIFORM", "Uniform", "", "NONE", 0),
+            ("VERTEX_WEIGHTS", "Vertex Weights", "", "NONE", 1),
+        ],
+        default="UNIFORM",
+        update=FunctionNode.sync_tree,
+    )
+
     def declaration(self, builder: NodeBuilder):
         builder.fixed_input("object", "Object", "Object")
         builder.fixed_input("amount", "Amount", "Integer", default=10)
         builder.fixed_input("seed", "Seed", "Integer")
+        if self.weight_mode == "VERTEX_WEIGHTS":
+            builder.fixed_input("vertex_group_name", "Vertex Group", "Text", default="Group")
+
         builder.fixed_output("surface_hooks", "Surface Hooks", "Surface Hook List")
+
+    def draw(self, layout):
+        layout.prop(self, "weight_mode", text="")
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
index 6b0370d9fb5..ce775083f35 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
@@ -483,7 +483,8 @@ static void INSERT_emitter_time_info(VNodeMFNetworkBuilder &builder)
 
 static void INSERT_sample_object_surface(VNodeMFNetworkBuilder &builder)
 {
-  builder.set_constructed_matching_fn<MF_SampleObjectSurface>();
+  int value = RNA_enum_get(builder.rna(), "weight_mode");
+  builder.set_constructed_matching_fn<MF_SampleObjectSurface>(value == 1);
 }
 
 void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
diff --git a/source/blender/functions/intern/multi_functions/surface_hook.cc b/source/blender/functions/intern/multi_functions/surface_hook.cc
index 623a1df6604..f227c3835cd 100644
--- a/source/blender/functions/intern/multi_functions/surface_hook.cc
+++ b/source/blender/functions/intern/multi_functions/surface_hook.cc
@@ -444,12 +444,16 @@ void MF_GetImageColorOnSurface::call(MFMask mask, MFParams params, MFContext con
       });
 }
 
-MF_SampleObjectSurface::MF_SampleObjectSurface()
+MF_SampleObjectSurface::MF_SampleObjectSurface(bool use_vertex_weights)
+    : m_use_vertex_weights(use_vertex_weights)
 {
   MFSignatureBuilder signature("Sample Object Surface");
   signature.single_input<ObjectIDHandle>("Object");
   signature.single_input<int>("Amount");
   signature.single_input<int>("Seed");
+  if (use_vertex_weights) {
+    signature.single_input<std::string>("Vertex Group Name");
+  }
   signature.vector_output<SurfaceHook>("Surface Hooks");
   this->set_signature(signature);
 }
@@ -493,14 +497,61 @@ static BLI_NOINLINE void compute_random_uniform_bary_coords(
   }
 }
 
+static BLI_NOINLINE bool get_vertex_weights(Object *object,
+                                            StringRefNull group_name,
+                                            MutableArrayRef<float> r_vertex_weights)
+{
+  Mesh *mesh = (Mesh *)object->data;
+  BLI_assert(r_vertex_weights.size() == mesh->totvert);
+
+  MDeformVert *vertices = mesh->dvert;
+  int group_index = defgroup_name_index(object, group_name.data());
+  if (group_index == -1 || vertices == nullptr) {
+    return false;
+  }
+
+  for (uint i : r_vertex_weights.index_iterator()) {
+    r_vertex_weights[i] = defvert_find_weight(vertices + i, group_index);
+  }
+  return true;
+}
+
+static BLI_NOINLINE void vertex_weights_to_triangle_weights(
+    Mesh *mesh,
+    ArrayRef<MLoopTri> triangles,
+    ArrayRef<float> vertex_weights,
+    MutableArrayRef<float> r_triangle_weights)
+{
+  BLI_assert(r_triangle_weights.size() == triangles.size());
+  BLI_assert(mesh->totvert == vertex_weights.size());
+
+  for (uint triangle_index : triangles.index_iterator()) {
+    const MLoopTri &looptri = triangles[triangle_index];
+    float triangle_weight = 0.0f;
+    for (uint i = 0; i < 3; i++) {
+      uint vertex_index = mesh->mloop[looptri.tri[i]].v;
+      float weight = vertex_weights[vertex_index];
+      triangle_weight += weight;
+    }
+
+    r_triangle_weights[triangle_index] = triangle_weight / 3.0f;
+  }
+}
+
 void MF_SampleObjectSurface::call(MFMask mask, MFParams params, MFContext context) const
 {
+  uint param_index = 0;
   VirtualListRef<ObjectIDHandle> object_handles = params.readonly_single_input<ObjectIDHandle>(
-      0, "Object");
-  VirtualListRef<int> amounts = params.readonly_single_input<int>(1, "Amount");
-  VirtualListRef<int> seeds = params.readonly_single_input<int>(2, "Seed");
+      param_index++, "Object");
+  VirtualListRef<int> amounts = params.readonly_single_input<int>(param_index++, "Amount");
+  VirtualListRef<int> seeds = params.readonly_single_input<int>(param_index++, "Seed");
+  VirtualListRef<std::string> vertex_group_names;
+  if (m_use_vertex_weights) {
+    vertex_group_names = params.readonly_single_input<std::string>(param_index++,
+                                                                   "Vertex Group Name");
+  }
   GenericVectorArray::MutableTypedRef<SurfaceHook> r_hooks_per_index =
-      params.vector_output<SurfaceHook>(3, "Surface Hooks");
+      params.vector_output<SurfaceHook>(param_index++, "Surface Hooks");
 
   const IDHandleLookup *id_handle_lookup = context.try_find_global<IDHandleLookup>();
   if (id_handle_lookup == nullptr) {
@@ -531,6 +582,19 @@ void MF_SampleObjectSurface::call(MFMask mask, MFParams params, MFContext contex
     TemporaryArray<float> triangle_weights(triangles.size());
     compute_triangle_areas(mesh, triangles, triangle_weights);
 
+    if (m_use_vertex_weights) {
+      TemporaryArray<float> vertex_weights(mesh->totvert);
+      if (get_vertex_weights(object, vertex_group_names[i], vertex_weights)) {
+        TemporaryArray<float> vertex_weights_for_triangles(triangles.size());
+        vertex_weights_to_triangle_weights(
+            mesh, triangles, vertex_weights, vertex_weights_for_triangles);
+
+        for (uint i : triangle_weights.index_iterator()) {
+          triangle_weights[i] *= vertex_weights_for_triangles[i];
+        }
+      }
+    }
+
     TemporaryArray<float> cumulative_weights(triangle_weights.size() + 1);
     float total_weight = compute_cumulative_distribution(triangle_weights, cumulative_weights);
     if (total_weight <= 0.0f) {
diff --git a/source/blender/functions/intern/multi_functions/surface_hook.h b/source/blender/functions/intern/multi_functions/surface_hook.h
index 9de1e22cfe5..4d33adf951a 100644
--- a/source/blender/functions/intern/multi_functions/surface_hook.h
+++ b/source/blender/functions/intern/multi_functions/surface_hook.h
@@ -35,8 +35,11 @@ class MF_GetImageColorOnSurface final : public MultiFunction {
 };
 
 class MF_SampleObjectSurface final : public MultiFunction {
+ private:
+  bool m_use_vertex_weights;
+
  public:
-  MF_SampleObjectSurface();
+  MF_SampleObjectSurface(bool use_vertex_weights);
   void call(MFMask mask, MFParams params, MFContext context) const override;
 };



More information about the Bf-blender-cvs mailing list