[Bf-blender-cvs] [d68c47ff347] master: Geometry Nodes: new Blur Attribute node

Iliya Katueshenock noreply at git.blender.org
Wed Dec 7 18:29:01 CET 2022


Commit: d68c47ff347bbb3824c27387f3387bd0583158a2
Author: Iliya Katueshenock
Date:   Wed Dec 7 18:22:44 2022 +0100
Branches: master
https://developer.blender.org/rBd68c47ff347bbb3824c27387f3387bd0583158a2

Geometry Nodes: new Blur Attribute node

The Blur Attribute node mixes values of neighboring elements in meshes and curves.

Currently it supports points, edges and faces on meshes and points on curves.
In theory, support for face corners could be added, but useful semantics are not
obvious yet.

The node calculates a weighted average of each element with its neighbors (based
on curve/mesh topology). The weight of the element itself is always 1, and the weight
of the neighbor elements is controlled by the weight input socket. In the future,
more options for how different elements are weight can be added (e.g. smoothing
groups and selection).

The node can perform multiple blurring iterations to achieve a blurrier result.
Generally, it is better to do multiple iterations in one node instead of using
multiple blur nodes because it has better performance in the current implementation.

We use the term "Blur" (instead of "Smooth") because smoothing is generally more
related to removing roughness from surfaces. When viewing the result of the
Blur Attribute node in the viewport, it looks like an image is blurred. While the
node can also be used to smooth surfaces, other/better algorithms exists for that
purpose (which e.g. don't reduce the volume of the mesh to zero with too many
iterations).

Differential Revision: https://developer.blender.org/D13952

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

M	release/scripts/startup/bl_ui/node_add_menu_geometry.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/CMakeLists.txt
M	source/blender/nodes/geometry/node_geometry_register.cc
M	source/blender/nodes/geometry/node_geometry_register.hh
A	source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc

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

diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
index 83448f8e32a..d75d617c3ac 100644
--- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py
+++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py
@@ -12,6 +12,7 @@ class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu):
     def draw(self, _context):
         layout = self.layout
         node_add_menu.add_node_type(layout, "GeometryNodeAttributeStatistic")
+        node_add_menu.add_node_type(layout, "GeometryNodeBlurAttribute")
         node_add_menu.add_node_type(layout, "GeometryNodeCaptureAttribute")
         node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize")
         node_add_menu.add_node_type(layout, "GeometryNodeRemoveAttribute")
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index e50d895d203..88f9c801aa8 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1541,6 +1541,7 @@ struct TexResult;
 #define GEO_NODE_SAMPLE_UV_SURFACE 1187
 #define GEO_NODE_SET_CURVE_NORMAL 1188
 #define GEO_NODE_IMAGE_INFO 1189
+#define GEO_NODE_BLUR_ATTRIBUTE 1190
 
 /** \} */
 
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 4a0094831b9..3e0ca04a0b2 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2202,6 +2202,19 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_with_socket_it
                               generic_attribute_type_supported_with_socket);
 }
 
+static bool rna_GeometryNodeBlurAttribute_data_type_supported(const EnumPropertyItem *item)
+{
+  return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_INT32);
+}
+
+static const EnumPropertyItem *rna_GeometryNodeBlurAttribute_data_type_itemf(
+    bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+  *r_free = true;
+  return itemf_function_check(rna_enum_attribute_type_items,
+                              rna_GeometryNodeBlurAttribute_data_type_supported);
+}
+
 static bool attribute_statistic_type_supported(const EnumPropertyItem *item)
 {
   return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3);
@@ -9521,6 +9534,19 @@ static void def_geo_accumulate_field(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
+static void def_geo_blur_attribute(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "custom1");
+  RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
+  RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeBlurAttribute_data_type_itemf");
+  RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
+  RNA_def_property_ui_text(prop, "Data Type", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
+}
+
 static void def_fn_random_value(StructRNA *srna)
 {
   PropertyRNA *prop;
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 03cab5a778a..6b892dfc5cf 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -283,6 +283,7 @@ DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToStri
 DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")
 DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")
 DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic","Calculate statistics about a data set from a field evaluated on a geometry")
+DefNode(GeometryNode, GEO_NODE_BLUR_ATTRIBUTE, def_geo_blur_attribute, "BLUR_ATTRIBUTE", BlurAttribute, "Blur Attribute", "Mix attribute values of neighboring elements")
 DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "Calculate the limits of a geometry's positions and generate a box mesh with those dimensions")
 DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture,"CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation")
 DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "Retrieve geometry from a collection")
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 2118ba778be..840be95ce1a 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -29,6 +29,7 @@ set(SRC
   nodes/node_geo_attribute_capture.cc
   nodes/node_geo_attribute_domain_size.cc
   nodes/node_geo_attribute_statistic.cc
+  nodes/node_geo_blur_attribute.cc
   nodes/node_geo_boolean.cc
   nodes/node_geo_bounding_box.cc
   nodes/node_geo_collection_info.cc
diff --git a/source/blender/nodes/geometry/node_geometry_register.cc b/source/blender/nodes/geometry/node_geometry_register.cc
index 8b011547fe2..da3f0966eee 100644
--- a/source/blender/nodes/geometry/node_geometry_register.cc
+++ b/source/blender/nodes/geometry/node_geometry_register.cc
@@ -14,6 +14,7 @@ void register_geometry_nodes()
   register_node_type_geo_attribute_capture();
   register_node_type_geo_attribute_domain_size();
   register_node_type_geo_attribute_statistic();
+  register_node_type_geo_blur_attribute();
   register_node_type_geo_boolean();
   register_node_type_geo_bounding_box();
   register_node_type_geo_collection_info();
diff --git a/source/blender/nodes/geometry/node_geometry_register.hh b/source/blender/nodes/geometry/node_geometry_register.hh
index 2c94e60a2ec..b7cca9e1903 100644
--- a/source/blender/nodes/geometry/node_geometry_register.hh
+++ b/source/blender/nodes/geometry/node_geometry_register.hh
@@ -11,6 +11,7 @@ void register_node_type_geo_attribute_capture();
 void register_node_type_geo_attribute_domain_size();
 void register_node_type_geo_attribute_separate_xyz();
 void register_node_type_geo_attribute_statistic();
+void register_node_type_geo_blur_attribute();
 void register_node_type_geo_boolean();
 void register_node_type_geo_bounding_box();
 void register_node_type_geo_collection_info();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc
new file mode 100644
index 00000000000..f53364aebdb
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc
@@ -0,0 +1,497 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_array.hh"
+#include "BLI_generic_array.hh"
+#include "BLI_index_mask.hh"
+#include "BLI_index_range.hh"
+#include "BLI_span.hh"
+#include "BLI_task.hh"
+#include "BLI_vector.hh"
+#include "BLI_virtual_array.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_curves.hh"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "NOD_socket_search_link.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_blur_attribute_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+  b.add_input<decl::Float>(N_("Value"), "Value_Float")
+      .supports_field()
+      .hide_value()
+      .is_default_link_socket();
+  b.add_input<decl::Int>(N_("Value"), "Value_Int")
+      .supports_field()
+      .hide_value()
+      .is_default_link_socket();
+  b.add_input<decl::Vector>(N_("Value"), "Value_Vector")
+      .supports_field()
+      .hide_value()
+      .is_default_link_socket();
+  b.add_input<decl::Color>(N_("Value"), "Value_Color")
+      .supports_field()
+      .hide_value()
+      .is_default_link_socket();
+
+  b.add_input<decl::Int>("Iterations")
+      .default_value(1)
+      .min(0)
+      .description(N_("How many times to blur the values for all elements"));
+  b.add_input<decl::Float>("Weight")
+      .default_value(1.0f)
+      .subtype(PROP_FACTOR)
+      .min(0.0f)
+      .max(1.0f)
+      .supports_field()
+      .description(N_("Relative mix weight of neighboring elements"));
+
+  b.add_output<decl::Float>(N_("Value"), "Value_Float").field_source().dependent_field();
+  b.add_output<decl::Int>(N_("Value"), "Value_Int").field_source().dependent_field();
+  b.add_output<decl::Vector>(N_("Value"), "Value_Vector").field_source().dependent_field();
+  b.add_output<decl::Color>(N_("Value"), "Value_Color").field_source().dependent_field();
+}
+
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+  node->custom1 = CD_PROP_FLOAT;
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+  const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+  search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
+
+  const bNodeType &node_type = params.node_type();
+  const std::optional<eCustomDataType> type = node_data_type_to_custom_data_type(
+      (eNodeSocketDatatype)params.other_socket().type);
+  if (type && *type != CD_PROP_STRING) {
+    params.add_item(IFACE_("Value"), [node_type, type](LinkSearchOpParams &params) {
+      bNode &node = params.add_node(node_type);
+      node.custom1 = *type;
+      params.update_and_connect_available_socket(node, "Value");
+    });
+  }
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+  const eCustomDataType data_type = static_cast

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list