[Bf-blender-cvs] [710c3b8312a] functions: new Get Weight on Surface node

Jacques Lucke noreply at git.blender.org
Sat Nov 30 16:40:19 CET 2019


Commit: 710c3b8312adefe15485187393867257bb2f6fc4
Author: Jacques Lucke
Date:   Sat Nov 30 14:36:19 2019 +0100
Branches: functions
https://developer.blender.org/rB710c3b8312adefe15485187393867257bb2f6fc4

new Get Weight on Surface node

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

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

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

diff --git a/release/scripts/startup/nodes/function_nodes/object_mesh.py b/release/scripts/startup/nodes/function_nodes/object_mesh.py
index c4400022b04..514348fcc60 100644
--- a/release/scripts/startup/nodes/function_nodes/object_mesh.py
+++ b/release/scripts/startup/nodes/function_nodes/object_mesh.py
@@ -35,4 +35,21 @@ class GetPositionOnSurfaceNode(bpy.types.Node, FunctionNode):
 
     def declaration(self, builder):
         builder.fixed_input("location", "Location", "Surface Location")
-        builder.fixed_output("position", "Position", "Vector")
\ No newline at end of file
+        builder.fixed_output("position", "Position", "Vector")
+
+
+class GetWeightOnSurfaceNode(bpy.types.Node, FunctionNode):
+    bl_idname = "fn_GetWeightOnSurfaceNode"
+    bl_label = "Get Weight on Surface"
+
+    vertex_group_name: StringProperty(
+        name="Vertex Group Name",
+        default="Group",
+    )
+
+    def declaration(self, builder):
+        builder.fixed_input("location", "Location", "Surface Location")
+        builder.fixed_output("weight", "Weight", "Float")
+    
+    def draw(self, layout):
+        layout.prop(self, "vertex_group_name", text="", icon="GROUP_VERTEX")
\ No newline at end of file
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/builder.h b/source/blender/functions/intern/inlined_tree_multi_function_network/builder.h
index 350822b1431..57b7ee842fe 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/builder.h
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/builder.h
@@ -344,6 +344,14 @@ class VNodeMFNetworkBuilder {
     return m_network_builder.data_type_from_property(m_xnode, prop_name);
   }
 
+  std::string string_from_property(StringRefNull prop_name)
+  {
+    char *str_ptr = RNA_string_get_alloc(m_xnode.rna(), prop_name.data(), nullptr, 0);
+    std::string str = str_ptr;
+    MEM_freeN(str_ptr);
+    return str;
+  }
+
   Vector<bool> get_list_base_variadic_states(StringRefNull prop_name);
 
   template<typename T, typename... Args> T &construct_fn(Args &&... args)
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 2ff7be8787a..70eb3bc109b 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
@@ -65,6 +65,12 @@ static void INSERT_get_position_on_surface(VNodeMFNetworkBuilder &builder)
   builder.set_constructed_matching_fn<MF_GetPositionOnSurface>();
 }
 
+static void INSERT_get_weight_on_surface(VNodeMFNetworkBuilder &builder)
+{
+  std::string group_name = builder.string_from_property("vertex_group_name");
+  builder.set_constructed_matching_fn<MF_GetWeightOnSurface>(std::move(group_name));
+}
+
 static void INSERT_switch(VNodeMFNetworkBuilder &builder)
 {
   MFDataType type = builder.data_type_from_property("data_type");
@@ -353,6 +359,7 @@ void add_inlined_tree_node_mapping_info(VTreeMultiFunctionMappings &mappings)
   mappings.xnode_inserters.add_new("fn_ObjectTransformsNode", INSERT_object_location);
   mappings.xnode_inserters.add_new("fn_ObjectMeshNode", INSERT_object_mesh_info);
   mappings.xnode_inserters.add_new("fn_GetPositionOnSurfaceNode", INSERT_get_position_on_surface);
+  mappings.xnode_inserters.add_new("fn_GetWeightOnSurfaceNode", INSERT_get_weight_on_surface);
   mappings.xnode_inserters.add_new("fn_TextLengthNode", INSERT_text_length);
   mappings.xnode_inserters.add_new("fn_VertexInfoNode", INSERT_vertex_info);
   mappings.xnode_inserters.add_new("fn_FloatRangeNode", INSERT_float_range);
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index b2d41d92311..4094fc8234a 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -17,6 +17,7 @@
 
 #include "BKE_surface_location.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_deform.h"
 
 namespace FN {
 
@@ -324,6 +325,70 @@ void MF_GetPositionOnSurface::call(MFMask mask, MFParams params, MFContext conte
   }
 }
 
+MF_GetWeightOnSurface::MF_GetWeightOnSurface(std::string vertex_group_name)
+    : m_vertex_group_name(std::move(vertex_group_name))
+{
+  MFSignatureBuilder signature("Get Weight on Surface");
+  signature.single_input<SurfaceLocation>("Surface Location");
+  signature.single_output<float>("Weight");
+  this->set_signature(signature);
+}
+
+void MF_GetWeightOnSurface::call(MFMask mask, MFParams params, MFContext context) const
+{
+  VirtualListRef<SurfaceLocation> locations = params.readonly_single_input<SurfaceLocation>(
+      0, "Surface Location");
+  MutableArrayRef<float> r_weights = params.uninitialized_single_output<float>(1, "Weight");
+
+  auto persistent_surfaces_opt =
+      context.element_contexts().find_first<PersistentSurfacesLookupContext>();
+  if (!persistent_surfaces_opt.has_value()) {
+    r_weights.fill_indices(mask.indices(), 0.0f);
+    return;
+  }
+
+  for (uint i : mask.indices()) {
+    SurfaceLocation location = locations[i];
+    if (!location.is_valid()) {
+      r_weights[i] = 0.0f;
+      continue;
+    }
+
+    Object *object = persistent_surfaces_opt->data->lookup((uint32_t)location.surface_id());
+    if (object == nullptr) {
+      r_weights[i] = 0.0f;
+      continue;
+    }
+
+    Mesh *mesh = (Mesh *)object->data;
+    const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
+    int triangle_amount = BKE_mesh_runtime_looptri_len(mesh);
+
+    if (location.triangle_index() >= triangle_amount) {
+      r_weights[i] = 0.0f;
+      continue;
+    }
+
+    const MLoopTri &triangle = triangles[location.triangle_index()];
+    uint v1 = mesh->mloop[triangle.tri[0]].v;
+    uint v2 = mesh->mloop[triangle.tri[1]].v;
+    uint v3 = mesh->mloop[triangle.tri[2]].v;
+
+    MDeformVert *vertex_weights = mesh->dvert;
+    int group_index = defgroup_name_index(object, m_vertex_group_name.data());
+    if (group_index == -1 || vertex_weights == nullptr) {
+      r_weights[i] = 0.0f;
+    }
+
+    float3 corner_weights{defvert_find_weight(vertex_weights + v1, group_index),
+                          defvert_find_weight(vertex_weights + v2, group_index),
+                          defvert_find_weight(vertex_weights + v3, group_index)};
+
+    float weight = float3::dot(location.bary_coords(), corner_weights);
+    r_weights[i] = weight;
+  }
+}
+
 MF_ObjectWorldLocation::MF_ObjectWorldLocation()
 {
   MFSignatureBuilder signature("Object Location");
@@ -724,8 +789,11 @@ void MF_ClosestLocationOnObject::call(MFMask mask, MFParams params, MFContext co
     const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
     int32_t object_surface_id = SurfaceLocation::ComputeObjectSurfaceID(object);
 
+    float4x4 global_to_local = float4x4(object->obmat).inverted__LocRotScale();
+
     for (uint i : mask.indices()) {
-      BVHTreeNearest nearest = get_nearest_point(bvhtree, positions[i]);
+      float3 local_position = global_to_local.transform_position(positions[i]);
+      BVHTreeNearest nearest = get_nearest_point(bvhtree, local_position);
       if (nearest.index == -1) {
         r_surface_locations[i] = {};
         continue;
@@ -753,7 +821,10 @@ void MF_ClosestLocationOnObject::call(MFMask mask, MFParams params, MFContext co
       const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
       int32_t object_surface_id = SurfaceLocation::ComputeObjectSurfaceID(object);
 
-      BVHTreeNearest nearest = get_nearest_point(bvhtree, positions[i]);
+      float4x4 global_to_local = float4x4(object->obmat).inverted__LocRotScale();
+      float3 local_position = global_to_local.transform_position(positions[i]);
+
+      BVHTreeNearest nearest = get_nearest_point(bvhtree, local_position);
       if (nearest.index == -1) {
         r_surface_locations[i] = {};
         continue;
diff --git a/source/blender/functions/intern/multi_functions/mixed.h b/source/blender/functions/intern/multi_functions/mixed.h
index 1d525e6648c..d010c4009ef 100644
--- a/source/blender/functions/intern/multi_functions/mixed.h
+++ b/source/blender/functions/intern/multi_functions/mixed.h
@@ -83,6 +83,15 @@ class MF_GetPositionOnSurface final : public MultiFunction {
   void call(MFMask mask, MFParams params, MFContext context) const override;
 };
 
+class MF_GetWeightOnSurface final : public MultiFunction {
+ private:
+  std::string m_vertex_group_name;
+
+ public:
+  MF_GetWeightOnSurface(std::string vertex_group_name);
+  void call(MFMask mask, MFParams params, MFContext context) const override;
+};
+
 class MF_TextLength final : public MultiFunction {
  public:
   MF_TextLength();



More information about the Bf-blender-cvs mailing list