diff options
Diffstat (limited to 'source/blender/nodes')
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); +} |