[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