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:
authorJohnny Matthews <guitargeek>2021-10-11 19:03:57 +0300
committerHans Goudey <h.goudey@me.com>2021-10-11 19:03:57 +0300
commitc1b4abf527f102ca20114e8179eca511d90784b3 (patch)
treeef5c074ada59fc25acf11034cd9e3d5daf1ae4e6 /source/blender/nodes
parent83f87d9f21fada613a70e7296120752e1e876dc3 (diff)
Geometry Nodes: Add Nodes to Get/Set Built-in Attributes
This commit implements T91780, adding nodes to get and set builtin attributes. Individual set nodes are used so that the values can be exposed for direct editing, which is useful for attributes like shade smooth and spline resolution. Individual input nodes are used to allow reusing nodes for multiple components, and to allow grouping multiple outputs conceptually in the same node in the future. Input Nodes - Radius - Curve Tilt - Curve Handle Positions - Is Shade Smooth - Spline Resolution - Is Spline Cyclic 'Set' Nodes - Curve Radius - Point Radius - Curve Tilt - Curve Handle Positions - Is Shade Smooth - Spline Resolution - Is Spline Cyclic Using hardcoded categories is necessary to add separators to the node menu. Differential Revision: https://developer.blender.org/D12687
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/CMakeLists.txt13
-rw-r--r--source/blender/nodes/NOD_geometry.h13
-rw-r--r--source/blender/nodes/NOD_static_types.h15
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc46
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_radius.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc43
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc43
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc164
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc79
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc78
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc80
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc78
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc79
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc95
16 files changed, 951 insertions, 1 deletions
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index b29568a5c9f..a4e8df3164c 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -219,11 +219,17 @@ set(SRC
geometry/nodes/node_geo_curve_trim.cc
geometry/nodes/node_geo_delete_geometry.cc
geometry/nodes/node_geo_distribute_points_on_faces.cc
+ geometry/nodes/node_geo_input_curve_handles.cc
+ geometry/nodes/node_geo_input_curve_tilt.cc
geometry/nodes/node_geo_input_index.cc
geometry/nodes/node_geo_input_material.cc
geometry/nodes/node_geo_input_normal.cc
geometry/nodes/node_geo_input_position.cc
+ geometry/nodes/node_geo_input_radius.cc
+ geometry/nodes/node_geo_input_shade_smooth.cc
+ geometry/nodes/node_geo_input_spline_cyclic.cc
geometry/nodes/node_geo_input_spline_length.cc
+ geometry/nodes/node_geo_input_spline_resolution.cc
geometry/nodes/node_geo_input_tangent.cc
geometry/nodes/node_geo_instance_on_points.cc
geometry/nodes/node_geo_is_viewport.cc
@@ -248,7 +254,14 @@ set(SRC
geometry/nodes/node_geo_realize_instances.cc
geometry/nodes/node_geo_separate_components.cc
geometry/nodes/node_geo_separate_geometry.cc
+ geometry/nodes/node_geo_set_curve_handles.cc
+ geometry/nodes/node_geo_set_curve_radius.cc
+ geometry/nodes/node_geo_set_curve_tilt.cc
+ geometry/nodes/node_geo_set_point_radius.cc
geometry/nodes/node_geo_set_position.cc
+ geometry/nodes/node_geo_set_shade_smooth.cc
+ geometry/nodes/node_geo_set_spline_cyclic.cc
+ geometry/nodes/node_geo_set_spline_resolution.cc
geometry/nodes/node_geo_string_join.cc
geometry/nodes/node_geo_string_to_curves.cc
geometry/nodes/node_geo_switch.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index baa841460e9..2d409d6d80b 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -88,11 +88,17 @@ void register_node_type_geo_curve_trim(void);
void register_node_type_geo_delete_geometry(void);
void register_node_type_geo_distribute_points_on_faces(void);
void register_node_type_geo_edge_split(void);
+void register_node_type_geo_input_curve_handles(void);
+void register_node_type_geo_input_curve_tilt(void);
void register_node_type_geo_input_index(void);
void register_node_type_geo_input_material(void);
void register_node_type_geo_input_normal(void);
void register_node_type_geo_input_position(void);
+void register_node_type_geo_input_radius(void);
+void register_node_type_geo_input_shade_smooth(void);
+void register_node_type_geo_input_spline_cyclic(void);
void register_node_type_geo_input_spline_length(void);
+void register_node_type_geo_input_spline_resolution(void);
void register_node_type_geo_input_tangent(void);
void register_node_type_geo_instance_on_points(void);
void register_node_type_geo_is_viewport(void);
@@ -127,7 +133,14 @@ void register_node_type_geo_sample_texture(void);
void register_node_type_geo_select_by_handle_type(void);
void register_node_type_geo_separate_components(void);
void register_node_type_geo_separate_geometry(void);
+void register_node_type_geo_set_curve_handles(void);
+void register_node_type_geo_set_curve_radius(void);
+void register_node_type_geo_set_curve_tilt(void);
+void register_node_type_geo_set_point_radius(void);
void register_node_type_geo_set_position(void);
+void register_node_type_geo_set_shade_smooth(void);
+void register_node_type_geo_set_spline_cyclic(void);
+void register_node_type_geo_set_spline_resolution(void);
void register_node_type_geo_string_join(void);
void register_node_type_geo_string_to_curves(void);
void register_node_type_geo_subdivision_surface(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 1acd082377f..e43f471d1e3 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -338,20 +338,26 @@ DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, def_geo_curve_prim
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL, 0, "CURVE_PRIMITIVE_SPIRAL", CurveSpiral, "Curve Spiral", "")
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "")
DefNode(GeometryNode, GEO_NODE_CURVE_RESAMPLE, def_geo_curve_resample, "CURVE_RESAMPLE", CurveResample, "Resample Curve", "")
-DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type, "CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "")
DefNode(GeometryNode, GEO_NODE_CURVE_REVERSE, 0, "CURVE_REVERSE", CurveReverse, "Reverse Curve", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SAMPLE, def_geo_curve_sample, "CURVE_SAMPLE", CurveSample, "Sample Curve", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SET_HANDLES, def_geo_curve_set_handles, "CURVE_SET_HANDLES", CurveSetHandles, "Set Handle Type", "")
+DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type, "CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "")
DefNode(GeometryNode, GEO_NODE_CURVE_SUBDIVIDE, 0, "CURVE_SUBDIVIDE", CurveSubdivide, "Subdivide Curve", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "")
DefNode(GeometryNode, GEO_NODE_CURVE_TRIM, def_geo_curve_trim, "CURVE_TRIM", CurveTrim, "Trim Curve", "")
DefNode(GeometryNode, GEO_NODE_DELETE_GEOMETRY, def_geo_delete_geometry, "DELETE_GEOMETRY", DeleteGeometry, "Delete Geometry", "")
DefNode(GeometryNode, GEO_NODE_DISTRIBUTE_POINTS_ON_FACES, def_geo_distribute_points_on_faces, "DISTRIBUTE_POINTS_ON_FACES", DistributePointsOnFaces, "Distribute Points on Faces", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions, "Curve Handle Positions", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "")
DefNode(GeometryNode, GEO_NODE_INPUT_INDEX, 0, "INDEX", InputIndex, "Index", "")
DefNode(GeometryNode, GEO_NODE_INPUT_MATERIAL, def_geo_input_material, "INPUT_MATERIAL", InputMaterial, "Material", "")
DefNode(GeometryNode, GEO_NODE_INPUT_NORMAL, 0, "INPUT_NORMAL", InputNormal, "Normal", "")
DefNode(GeometryNode, GEO_NODE_INPUT_POSITION, 0, "POSITION", InputPosition, "Position", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_RADIUS, 0, "INPUT_RADIUS", InputRadius, "Radius", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_SHADE_SMOOTH, 0, "INPUT_SHADE_SMOOTH", InputShadeSmooth, "Is Shade Smooth", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_CYCLIC, 0, "INPUT_SPLINE_CYCLIC", InputSplineCyclic, "Is Spline Cyclic", "")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLength, "Spline Length", "")
+DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUTION", InputSplineResolution, "Spline Resolution", "")
DefNode(GeometryNode, GEO_NODE_INPUT_TANGENT, 0, "INPUT_TANGENT", InputTangent, "Curve Tangent", "")
DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, 0, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "")
DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "")
@@ -376,7 +382,14 @@ DefNode(GeometryNode, GEO_NODE_PROXIMITY, def_geo_proximity, "PROXIMITY", Proxim
DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, 0, "REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "")
DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry, "SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "")
+DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "")
+DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "")
+DefNode(GeometryNode, GEO_NODE_SET_CURVE_TILT, 0, "SET_CURVE_TILT", SetCurveTilt, "Set Curve Tilt", "")
+DefNode(GeometryNode, GEO_NODE_SET_POINT_RADIUS, 0, "SET_POINT_RADIUS", SetPointRadius, "Set Point Radius", "")
DefNode(GeometryNode, GEO_NODE_SET_POSITION, 0, "SET_POSITION", SetPosition, "Set Position", "")
+DefNode(GeometryNode, GEO_NODE_SET_SHADE_SMOOTH, 0, "SET_SHADE_SMOOTH", SetShadeSmooth, "Set Shade Smooth", "")
+DefNode(GeometryNode, GEO_NODE_SET_SPLINE_CYCLIC, 0, "SET_SPLINE_CYCLIC", SetSplineCyclic, "Set Spline Cyclic", "")
+DefNode(GeometryNode, GEO_NODE_SET_SPLINE_RESOLUTION, 0, "SET_SPLINE_RESOLUTION", SetSplineResolution, "Set Spline Resolution", "")
DefNode(GeometryNode, GEO_NODE_STRING_JOIN, 0, "STRING_JOIN", StringJoin, "Join Strings", "")
DefNode(GeometryNode, GEO_NODE_STRING_TO_CURVES, def_geo_string_to_curves, "STRING_TO_CURVES", StringToCurves, "String to Curves", "")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
new file mode 100644
index 00000000000..604b181918d
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
@@ -0,0 +1,46 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_curve_handles_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Vector>("Left").field_source();
+ b.add_output<decl::Vector>("Right").field_source();
+}
+
+static void geo_node_input_curve_handles_exec(GeoNodeExecParams params)
+{
+ Field<float3> left_field = AttributeFieldInput::Create<float3>("handle_left");
+ Field<float3> right_field = AttributeFieldInput::Create<float3>("handle_right");
+ params.set_output("Left", std::move(left_field));
+ params.set_output("Right", std::move(right_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_curve_handles()
+{
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_CURVE_HANDLES, "Curve Handle Positions", NODE_CLASS_INPUT, 0);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_curve_handles_exec;
+ ntype.declare = blender::nodes::geo_node_input_curve_handles_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc
new file mode 100644
index 00000000000..5a24b7f3f07
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc
@@ -0,0 +1,42 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_curve_tilt_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>("Tilt").field_source();
+}
+
+static void geo_node_input_curve_tilt_exec(GeoNodeExecParams params)
+{
+ Field<float> tilt_field = AttributeFieldInput::Create<float>("tilt");
+ params.set_output("Tilt", std::move(tilt_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_curve_tilt()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_CURVE_TILT, "Curve Tilt", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_curve_tilt_exec;
+ ntype.declare = blender::nodes::geo_node_input_curve_tilt_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc
new file mode 100644
index 00000000000..586005511ad
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc
@@ -0,0 +1,42 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_radius_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>("Radius").default_value(1.0f).min(0.0f).field_source();
+}
+
+static void geo_node_input_radius_exec(GeoNodeExecParams params)
+{
+ Field<float> radius_field = AttributeFieldInput::Create<float>("radius");
+ params.set_output("Radius", std::move(radius_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_radius()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_RADIUS, "Radius", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_radius_exec;
+ ntype.declare = blender::nodes::geo_node_input_radius_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc
new file mode 100644
index 00000000000..de520787e78
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc
@@ -0,0 +1,42 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_shade_smooth_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Bool>("Smooth").field_source();
+}
+
+static void geo_node_input_shade_smooth_exec(GeoNodeExecParams params)
+{
+ Field<bool> shade_smooth_field = AttributeFieldInput::Create<bool>("shade_smooth");
+ params.set_output("Smooth", std::move(shade_smooth_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_shade_smooth()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_SHADE_SMOOTH, "Is Shade Smooth", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_shade_smooth_exec;
+ ntype.declare = blender::nodes::geo_node_input_shade_smooth_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc
new file mode 100644
index 00000000000..44a1bb62de8
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc
@@ -0,0 +1,43 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_spline_cyclic_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Bool>("Cyclic").field_source();
+}
+
+static void geo_node_input_spline_cyclic_exec(GeoNodeExecParams params)
+{
+ Field<bool> cyclic_field = AttributeFieldInput::Create<bool>("cyclic");
+ params.set_output("Cyclic", std::move(cyclic_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_spline_cyclic()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_SPLINE_CYCLIC, "Is Spline Cyclic", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_spline_cyclic_exec;
+ ntype.declare = blender::nodes::geo_node_input_spline_cyclic_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc
new file mode 100644
index 00000000000..eab95ebc46e
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc
@@ -0,0 +1,43 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_input_spline_resolution_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>("Resolution").field_source();
+}
+
+static void geo_node_input_spline_resolution_exec(GeoNodeExecParams params)
+{
+ Field<int> resolution_field = AttributeFieldInput::Create<int>("resolution");
+ params.set_output("Resolution", std::move(resolution_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_input_spline_resolution()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_SPLINE_RESOLUTION, "Spline Resolution", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_input_spline_resolution_exec;
+ ntype.declare = blender::nodes::geo_node_input_spline_resolution_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
new file mode 100644
index 00000000000..3e106a92b14
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
@@ -0,0 +1,164 @@
+/*
+ * 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 "BKE_spline.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+static void geo_node_set_curve_handles_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Vector>("Position").implicit_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void geo_node_set_curve_handles_layout(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+}
+
+static void geo_node_set_curve_handles_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeGeometrySetCurveHandlePositions *data = (NodeGeometrySetCurveHandlePositions *)MEM_callocN(
+ sizeof(NodeGeometrySetCurveHandlePositions), __func__);
+
+ data->mode = GEO_NODE_CURVE_HANDLE_LEFT;
+ node->storage = data;
+}
+
+static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
+ GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<float3> &position_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ CurveComponent *curve_component = static_cast<CurveComponent *>(&component);
+ CurveEval *curve = curve_component->get_for_write();
+
+ StringRef side = mode & GEO_NODE_CURVE_HANDLE_LEFT ? "handle_left" : "handle_right";
+
+ int current_point = 0;
+ int current_mask = 0;
+
+ for (const SplinePtr &spline : curve->splines()) {
+ if (spline->type() == Spline::Type::Bezier) {
+ BezierSpline &bezier = static_cast<BezierSpline &>(*spline);
+ for (int i : bezier.positions().index_range()) {
+ if (selection[current_mask] == current_point) {
+ if (mode & GEO_NODE_CURVE_HANDLE_LEFT) {
+ if (bezier.handle_types_left()[i] == BezierSpline::HandleType::Vector) {
+ bezier.handle_types_left()[i] = BezierSpline::HandleType::Free;
+ }
+ else if (bezier.handle_types_left()[i] == BezierSpline::HandleType::Auto) {
+ bezier.handle_types_left()[i] = BezierSpline::HandleType::Align;
+ }
+ }
+ else {
+ if (bezier.handle_types_right()[i] == BezierSpline::HandleType::Vector) {
+ bezier.handle_types_right()[i] = BezierSpline::HandleType::Free;
+ }
+ else if (bezier.handle_types_right()[i] == BezierSpline::HandleType::Auto) {
+ bezier.handle_types_right()[i] = BezierSpline::HandleType::Align;
+ }
+ }
+ current_mask++;
+ }
+ current_point++;
+ }
+ }
+ else {
+ for (int UNUSED(i) : spline->positions().index_range()) {
+ if (selection[current_mask] == current_point) {
+ current_mask++;
+ }
+ current_point++;
+ }
+ }
+ }
+
+ OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output_only<float3>(
+ side, ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator position_evaluator{field_context, &selection};
+ position_evaluator.add_with_destination(position_field, positions.varray());
+ position_evaluator.evaluate();
+ positions.save();
+}
+
+static void geo_node_set_curve_handles_exec(GeoNodeExecParams params)
+{
+ const NodeGeometrySetCurveHandlePositions *node_storage =
+ (NodeGeometrySetCurveHandlePositions *)params.node().storage;
+ const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)node_storage->mode;
+
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<float3> position_field = params.extract_input<Field<float3>>("Position");
+
+ bool has_bezier = false;
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_curve() &&
+ geometry_set.get_curve_for_read()->has_spline_with_type(Spline::Type::Bezier)) {
+ has_bezier = true;
+ set_position_in_component(mode,
+ geometry_set.get_component_for_write<CurveComponent>(),
+ selection_field,
+ position_field);
+ }
+ });
+ if (!has_bezier) {
+ params.error_message_add(NodeWarningType::Info,
+ TIP_("The input geometry does not contain a Bezier spline"));
+ }
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_curve_handles()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_CURVE_HANDLES, "Set Handle Positions", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_handles_exec;
+ ntype.declare = blender::nodes::geo_node_set_curve_handles_declare;
+ ntype.minwidth = 100.0f;
+ node_type_init(&ntype, blender::nodes::geo_node_set_curve_handles_init);
+ node_type_storage(&ntype,
+ "NodeGeometrySetCurveHandlePositions",
+ node_free_standard_storage,
+ node_copy_standard_storage);
+ ntype.draw_buttons = blender::nodes::geo_node_set_curve_handles_layout;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
new file mode 100644
index 00000000000..446e63d0471
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
@@ -0,0 +1,79 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_set_curve_radius_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Float>("Radius").min(0.0f).default_value(1.0f).supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_radius_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<float> &radius_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
+ "radius", ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator radii_evaluator{field_context, &selection};
+ radii_evaluator.add_with_destination(radius_field, radii.varray());
+ radii_evaluator.evaluate();
+ radii.save();
+}
+
+static void geo_node_set_curve_radius_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<float> radii_field = params.extract_input<Field<float>>("Radius");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_curve()) {
+ set_radius_in_component(
+ geometry_set.get_component_for_write<CurveComponent>(), selection_field, radii_field);
+ }
+ });
+
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_curve_radius()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_CURVE_RADIUS, "Set Curve Radius", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_radius_exec;
+ ntype.declare = blender::nodes::geo_node_set_curve_radius_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
new file mode 100644
index 00000000000..ee88b24fb04
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
@@ -0,0 +1,78 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_set_curve_tilt_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Float>("Tilt").subtype(PROP_ANGLE).supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_tilt_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<float> &tilt_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<float> tilts = component.attribute_try_get_for_output_only<float>(
+ "tilt", ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator tilt_evaluator{field_context, &selection};
+ tilt_evaluator.add_with_destination(tilt_field, tilts.varray());
+ tilt_evaluator.evaluate();
+ tilts.save();
+}
+
+static void geo_node_set_curve_tilt_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<float> tilt_field = params.extract_input<Field<float>>("Tilt");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_curve()) {
+ set_tilt_in_component(
+ geometry_set.get_component_for_write<CurveComponent>(), selection_field, tilt_field);
+ }
+ });
+
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_curve_tilt()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(&ntype, GEO_NODE_SET_CURVE_TILT, "Set Tilt", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_tilt_exec;
+ ntype.declare = blender::nodes::geo_node_set_curve_tilt_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
new file mode 100644
index 00000000000..18646c789b4
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
@@ -0,0 +1,80 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_set_point_radius_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Float>("Radius").default_value(0.05f).min(0.0f).supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_radius_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<float> &radius_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
+ "radius", ATTR_DOMAIN_POINT);
+ fn::FieldEvaluator radii_evaluator{field_context, &selection};
+ radii_evaluator.add_with_destination(radius_field, radii.varray());
+ radii_evaluator.evaluate();
+ radii.save();
+}
+
+static void geo_node_set_point_radius_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<float> radii_field = params.extract_input<Field<float>>("Radius");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_pointcloud()) {
+ set_radius_in_component(geometry_set.get_component_for_write<PointCloudComponent>(),
+ selection_field,
+ radii_field);
+ }
+ });
+
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_point_radius()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_POINT_RADIUS, "Set Point Radius", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_point_radius_exec;
+ ntype.declare = blender::nodes::geo_node_set_point_radius_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
new file mode 100644
index 00000000000..1d7bab4a6bb
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
@@ -0,0 +1,78 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_set_shade_smooth_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Bool>("Shade Smooth").supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_smooth_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<bool> &shade_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_FACE};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_FACE);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<bool> shades = component.attribute_try_get_for_output_only<bool>(
+ "shade_smooth", ATTR_DOMAIN_FACE);
+ fn::FieldEvaluator shade_evaluator{field_context, &selection};
+ shade_evaluator.add_with_destination(shade_field, shades.varray());
+ shade_evaluator.evaluate();
+ shades.save();
+}
+
+static void geo_node_set_shade_smooth_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<bool> shade_field = params.extract_input<Field<bool>>("Shade Smooth");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_mesh()) {
+ set_smooth_in_component(
+ geometry_set.get_component_for_write<MeshComponent>(), selection_field, shade_field);
+ }
+ });
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_shade_smooth()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_SHADE_SMOOTH, "Set Shade Smooth", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_shade_smooth_exec;
+ ntype.declare = blender::nodes::geo_node_set_shade_smooth_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
new file mode 100644
index 00000000000..c013e6f0ba4
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
@@ -0,0 +1,79 @@
+/*
+ * 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"
+
+namespace blender::nodes {
+
+static void geo_node_set_spline_cyclic_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Bool>("Cyclic").supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_cyclic_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<bool> &cyclic_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<bool> cyclics = component.attribute_try_get_for_output_only<bool>(
+ "cyclic", ATTR_DOMAIN_CURVE);
+ fn::FieldEvaluator cyclic_evaluator{field_context, &selection};
+ cyclic_evaluator.add_with_destination(cyclic_field, cyclics.varray());
+ cyclic_evaluator.evaluate();
+ cyclics.save();
+}
+
+static void geo_node_set_spline_cyclic_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<bool> cyclic_field = params.extract_input<Field<bool>>("Cyclic");
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_curve()) {
+ set_cyclic_in_component(
+ geometry_set.get_component_for_write<CurveComponent>(), selection_field, cyclic_field);
+ }
+ });
+
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_spline_cyclic()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_SPLINE_CYCLIC, "Set Spline Cyclic", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_spline_cyclic_exec;
+ ntype.declare = blender::nodes::geo_node_set_spline_cyclic_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
new file mode 100644
index 00000000000..fc8706f3223
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
@@ -0,0 +1,95 @@
+/*
+ * 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 "BKE_spline.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+static void geo_node_set_spline_resolution_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Int>("Resolution").default_value(12).supports_field();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void set_resolution_in_component(GeometryComponent &component,
+ const Field<bool> &selection_field,
+ const Field<int> &resolution_field)
+{
+ GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_CURVE};
+ const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_CURVE);
+ if (domain_size == 0) {
+ return;
+ }
+
+ fn::FieldEvaluator selection_evaluator{field_context, domain_size};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ OutputAttribute_Typed<int> resolutions = component.attribute_try_get_for_output_only<int>(
+ "resolution", ATTR_DOMAIN_CURVE);
+ fn::FieldEvaluator resolution_evaluator{field_context, &selection};
+ resolution_evaluator.add_with_destination(resolution_field, resolutions.varray());
+ resolution_evaluator.evaluate();
+ resolutions.save();
+}
+
+static void geo_node_set_spline_resolution_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ Field<int> resolution_field = params.extract_input<Field<int>>("Resolution");
+
+ bool only_poly = true;
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_curve()) {
+ if (!only_poly) {
+ for (const SplinePtr &spline : geometry_set.get_curve_for_read()->splines()) {
+ if (ELEM(spline->type(), Spline::Type::Bezier, Spline::Type::NURBS)) {
+ only_poly = false;
+ break;
+ }
+ }
+ }
+ set_resolution_in_component(geometry_set.get_component_for_write<CurveComponent>(),
+ selection_field,
+ resolution_field);
+ }
+ });
+
+ if (only_poly) {
+ params.error_message_add(NodeWarningType::Warning,
+ TIP_("Input geometry does not contain a Bezier or NURB spline"));
+ }
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_set_spline_resolution()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_SET_SPLINE_RESOLUTION, "Set Spline Resolution", NODE_CLASS_GEOMETRY, 0);
+ ntype.geometry_node_execute = blender::nodes::geo_node_set_spline_resolution_exec;
+ ntype.declare = blender::nodes::geo_node_set_spline_resolution_declare;
+ nodeRegisterType(&ntype);
+}