[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