Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-12-10 16:58:45 +0300
committerHans Goudey <h.goudey@me.com>2020-12-10 16:58:45 +0300
commit348bd319d5a88f45410a22f8ce2f527d8da48ef0 (patch)
tree0d89f5816c28893582ba1128e26b6574784841ae /source/blender/nodes
parentefb741b280f20cb189e23f2b1335358a95ab609c (diff)
Geometry Nodes: Attribute Fill Node
This commit adds a node that fills every element of an attribute with the same value. Currently it supports float, vector, and color attributes. An immediate use case is for "billboard" scattering. Currently people are using the same input to a Random Attribute node's min and max input to fill every element of a vector with the same value, which is an unintuitive way to accomplish the same thing. Differential Revision: https://developer.blender.org/D9790
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc130
4 files changed, 133 insertions, 0 deletions
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index a367f40dca7..d09b1a8534d 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -138,6 +138,7 @@ set(SRC
function/nodes/node_fn_switch.cc
function/node_function_util.cc
+ geometry/nodes/node_geo_attribute_fill.cc
geometry/nodes/node_geo_attribute_math.cc
geometry/nodes/node_geo_common.cc
geometry/nodes/node_geo_boolean.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 0532547375f..6433841582b 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -26,6 +26,7 @@ void register_node_tree_type_geo(void);
void register_node_type_geo_group(void);
+void register_node_type_geo_attribute_fill(void);
void register_node_type_geo_boolean(void);
void register_node_type_geo_edge_split(void);
void register_node_type_geo_transform(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 09e0908140c..8ca978d1339 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -277,6 +277,7 @@ DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Objec
DefNode(GeometryNode, GEO_NODE_RANDOM_ATTRIBUTE, def_geo_random_attribute, "RANDOM_ATTRIBUTE", RandomAttribute, "Random Attribute", "")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_MATH, def_geo_attribute_math, "ATTRIBUTE_MATH", AttributeMath, "Attribute Math", "")
DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "")
+DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_FILL, def_geo_attribute_fill, "ATTRIBUTE_FILL", AttributeFill, "Attribute Fill", "")
/* undefine macros */
#undef DefNode
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
new file mode 100644
index 00000000000..d3c7e86b708
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
@@ -0,0 +1,130 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "BLI_rand.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_pointcloud_types.h"
+
+static bNodeSocketTemplate geo_node_attribute_fill_in[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {SOCK_STRING, N_("Attribute")},
+ {SOCK_VECTOR, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
+ {SOCK_FLOAT, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
+ {SOCK_RGBA, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate geo_node_attribute_fill_out[] = {
+ {SOCK_GEOMETRY, N_("Geometry")},
+ {-1, ""},
+};
+
+static void geo_node_attribute_fill_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ node->custom1 = CD_PROP_FLOAT;
+}
+
+static void geo_node_attribute_fill_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *socket_value_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
+ bNodeSocket *socket_value_float = socket_value_vector->next;
+ bNodeSocket *socket_value_color4f = socket_value_float->next;
+
+ const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
+
+ nodeSetSocketAvailability(socket_value_vector, data_type == CD_PROP_FLOAT3);
+ nodeSetSocketAvailability(socket_value_float, data_type == CD_PROP_FLOAT);
+ nodeSetSocketAvailability(socket_value_color4f, data_type == CD_PROP_COLOR);
+}
+
+namespace blender::nodes {
+
+static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
+{
+ const bNode &node = params.node();
+ const CustomDataType data_type = static_cast<CustomDataType>(node.custom1);
+ const AttributeDomain domain = static_cast<AttributeDomain>(node.custom2);
+ const std::string attribute_name = params.get_input<std::string>("Attribute");
+ if (attribute_name.empty()) {
+ return;
+ }
+
+ WriteAttributePtr attribute = component.attribute_try_ensure_for_write(
+ attribute_name, domain, data_type);
+ if (!attribute) {
+ return;
+ }
+
+ switch (data_type) {
+ case CD_PROP_FLOAT: {
+ FloatWriteAttribute float_attribute = std::move(attribute);
+ const float value = params.get_input<float>("Value_001");
+ MutableSpan<float> attribute_span = float_attribute.get_span();
+ attribute_span.fill(value);
+ float_attribute.apply_span();
+ break;
+ }
+ case CD_PROP_FLOAT3: {
+ Float3WriteAttribute float3_attribute = std::move(attribute);
+ const float3 value = params.get_input<float3>("Value");
+ MutableSpan<float3> attribute_span = float3_attribute.get_span();
+ attribute_span.fill(value);
+ float3_attribute.apply_span();
+ break;
+ }
+ case CD_PROP_COLOR: {
+ Color4fWriteAttribute color4f_attribute = std::move(attribute);
+ const Color4f value = params.get_input<Color4f>("Value_002");
+ MutableSpan<Color4f> attribute_span = color4f_attribute.get_span();
+ attribute_span.fill(value);
+ color4f_attribute.apply_span();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void geo_node_attribute_fill_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ if (geometry_set.has<MeshComponent>()) {
+ fill_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ fill_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
+ }
+
+ params.set_output("Geometry", geometry_set);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_attribute_fill()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_ATTRIBUTE_FILL, "Attribute Fill", NODE_CLASS_ATTRIBUTE, 0);
+ node_type_socket_templates(&ntype, geo_node_attribute_fill_in, geo_node_attribute_fill_out);
+ node_type_init(&ntype, geo_node_attribute_fill_init);
+ node_type_update(&ntype, geo_node_attribute_fill_update);
+ ntype.geometry_node_execute = blender::nodes::geo_node_attribute_fill_exec;
+ nodeRegisterType(&ntype);
+}