diff options
-rw-r--r-- | release/scripts/startup/nodeitems_builtins.py | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 1 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.hh | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 27 | ||||
-rw-r--r-- | source/blender/nodes/NOD_geometry.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_static_types.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc | 392 |
10 files changed, 440 insertions, 0 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 7d8179265da..6bcc263be19 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -704,6 +704,7 @@ geometry_node_categories = [ NodeItem("GeometryNodeCurvePrimitiveCircle"), NodeItem("GeometryNodeCurveStar"), NodeItem("GeometryNodeCurveSpiral"), + NodeItem("GeometryNodeCurveArc"), NodeItem("GeometryNodeCurveQuadraticBezier"), NodeItem("GeometryNodeCurvePrimitiveQuadrilateral"), NodeItem("GeometryNodeCurvePrimitiveBezierSegment"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 8f408ecd675..1ee8c91ff3e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1629,6 +1629,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_ACCUMULATE_FIELD 1146 #define GEO_NODE_INPUT_MESH_EDGE_ANGLE 1147 #define GEO_NODE_FIELD_AT_INDEX 1148 +#define GEO_NODE_CURVE_PRIMITIVE_ARC 1149 /** \} */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index b3bf80cd448..4bac8c150df 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4746,6 +4746,7 @@ static void registerGeometryNodes() register_node_type_geo_curve_fillet(); register_node_type_geo_curve_handle_type_selection(); register_node_type_geo_curve_length(); + register_node_type_geo_curve_primitive_arc(); register_node_type_geo_curve_primitive_bezier_segment(); register_node_type_geo_curve_primitive_circle(); register_node_type_geo_curve_primitive_line(); diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index e7d765df842..1d60447445e 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -365,6 +365,11 @@ template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T interpolate(const T &a, return a * (1 - t) + b * t; } +template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T midpoint(const T &a, const T &b) +{ + return (a + b) * 0.5; +} + template<typename T, BLI_ENABLE_IF_FLT_VEC(T)> inline T faceforward(const T &vector, const T &incident, const T &reference) { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 114e350b582..a23e45f8b74 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1503,6 +1503,11 @@ typedef struct NodeGeometryCurveSelectHandles { uint8_t mode; } NodeGeometryCurveSelectHandles; +typedef struct NodeGeometryCurvePrimitiveArc { + /* GeometryNodeCurvePrimitiveArcMode. */ + uint8_t mode; +} NodeGeometryCurvePrimitiveArc; + typedef struct NodeGeometryCurvePrimitiveLine { /* GeometryNodeCurvePrimitiveLineMode. */ uint8_t mode; @@ -2237,6 +2242,11 @@ typedef enum GeometryNodeMeshLineCountMode { GEO_NODE_MESH_LINE_COUNT_RESOLUTION = 1, } GeometryNodeMeshLineCountMode; +typedef enum GeometryNodeCurvePrimitiveArcMode { + GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS = 0, + GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS = 1, +} GeometryNodeCurvePrimitiveArcMode; + typedef enum GeometryNodeCurvePrimitiveLineMode { GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_POINTS = 0, GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_DIRECTION = 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 775c7a68f65..adb6b1e4e34 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -10139,6 +10139,33 @@ static void def_geo_curve_primitive_circle(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); } +static void def_geo_curve_primitive_arc(StructRNA *srna) +{ + static const EnumPropertyItem mode_items[] = { + + {GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS, + "POINTS", + ICON_NONE, + "Points", + "Define arc by 3 points on circle. Arc is calculated between start and end points"}, + {GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS, + "RADIUS", + ICON_NONE, + "Radius", + "Define radius with a float"}, + {0, NULL, 0, NULL, NULL}, + }; + + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeGeometryCurvePrimitiveArc", "storage"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, mode_items); + RNA_def_property_ui_text(prop, "Mode", "Method used to determine radius and placement"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); +} + static void def_geo_curve_primitive_line(StructRNA *srna) { static const EnumPropertyItem mode_items[] = { diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index 3b9dd5a1f7c..1548ba32abc 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -77,6 +77,7 @@ void register_node_type_geo_curve_fill(void); void register_node_type_geo_curve_fillet(void); void register_node_type_geo_curve_handle_type_selection(void); void register_node_type_geo_curve_length(void); +void register_node_type_geo_curve_primitive_arc(void); void register_node_type_geo_curve_primitive_bezier_segment(void); void register_node_type_geo_curve_primitive_circle(void); void register_node_type_geo_curve_primitive_line(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 7434e0071ee..1657a924ddb 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -335,6 +335,7 @@ DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Conve DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINT_SELECTION, 0, "CURVE_ENDPOINT_SELECTION", CurveEndpointSelection, "Endpoint Selection", "") DefNode(GeometryNode, GEO_NODE_CURVE_HANDLE_TYPE_SELECTION, def_geo_curve_handle_type_selection, "CURVE_HANDLE_TYPE_SELECTION", CurveHandleTypeSelection, "Handle Type Selection", "") DefNode(GeometryNode, GEO_NODE_CURVE_LENGTH, 0, "CURVE_LENGTH", CurveLength, "Curve Length", "") +DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_ARC, def_geo_curve_primitive_arc, "CURVE_PRIMITIVE_ARC", CurveArc, "Arc", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, def_geo_curve_primitive_bezier_segment, "CURVE_PRIMITIVE_BEZIER_SEGMENT", CurvePrimitiveBezierSegment, "Bezier Segment", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, def_geo_curve_primitive_circle, "CURVE_PRIMITIVE_CIRCLE", CurvePrimitiveCircle, "Curve Circle", "") DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_LINE, def_geo_curve_primitive_line, "CURVE_PRIMITIVE_LINE", CurvePrimitiveLine, "Curve Line", "") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index b9e762a341a..7ce8988a075 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -95,6 +95,7 @@ set(SRC nodes/node_geo_curve_fillet.cc nodes/node_geo_curve_handle_type_selection.cc nodes/node_geo_curve_length.cc + nodes/node_geo_curve_primitive_arc.cc nodes/node_geo_curve_primitive_bezier_segment.cc nodes/node_geo_curve_primitive_circle.cc nodes/node_geo_curve_primitive_line.cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc new file mode 100644 index 00000000000..5131cb965aa --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc @@ -0,0 +1,392 @@ +/* + * 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 "BLI_math_base_safe.h" +#include "UI_interface.h" +#include "UI_resources.h" +#include "node_geometry_util.hh" +#include <numeric> + +namespace blender::nodes::node_geo_curve_primitive_arc_cc { + +NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveArc) + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input<decl::Int>(N_("Resolution")) + .default_value(16) + .min(2) + .max(256) + .subtype(PROP_UNSIGNED) + .description(N_("The number of points on the arc")); + b.add_input<decl::Vector>(N_("Start")) + .default_value({-1.0f, 0.0f, 0.0f}) + .subtype(PROP_TRANSLATION) + .description(N_("Position of the first control point")); + b.add_input<decl::Vector>(N_("Middle")) + .default_value({0.0f, 2.0f, 0.0f}) + .subtype(PROP_TRANSLATION) + .description(N_("Position of the middle control point")); + b.add_input<decl::Vector>(N_("End")) + .default_value({1.0f, 0.0f, 0.0f}) + .subtype(PROP_TRANSLATION) + .description(N_("Position of the last control point")); + b.add_input<decl::Float>(N_("Radius")) + .default_value(1.0f) + .min(0.0f) + .subtype(PROP_DISTANCE) + .description(N_("Distance of the points from the origin")); + b.add_input<decl::Float>(N_("Start Angle")) + .default_value(0.0f) + .subtype(PROP_ANGLE) + .description(N_("Starting angle of the arc")); + b.add_input<decl::Float>(N_("Sweep Angle")) + .default_value(1.75f * M_PI) + .min(-2 * M_PI) + .max(2 * M_PI) + .subtype(PROP_ANGLE) + .description(N_("Length of the arc")); + b.add_input<decl::Float>(N_("Offset Angle")) + .default_value(0.0f) + .subtype(PROP_ANGLE) + .description(N_("Offset angle of the arc")); + b.add_input<decl::Bool>(N_("Connect Center")) + .default_value(false) + .description(N_("Connect the arc at the center")); + b.add_input<decl::Bool>(N_("Invert Arc")) + .default_value(false) + .description(N_("Invert and draw opposite arc")); + + b.add_output<decl::Geometry>(N_("Curve")); + b.add_output<decl::Vector>(N_("Center")) + .description(N_("The center of the circle described by the three points")) + .make_available( + [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; }); + b.add_output<decl::Vector>(N_("Normal")) + .description(N_("The normal direction of the plane described by the three points, pointing " + "towards the positive Z axis")) + .make_available( + [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; }); + b.add_output<decl::Float>(N_("Radius")) + .description(N_("The radius of the circle described by the three points")) + .make_available( + [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS; }); +} + +static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); +} + +static void node_init(bNodeTree *UNUSED(tree), bNode *node) +{ + NodeGeometryCurvePrimitiveArc *data = MEM_cnew<NodeGeometryCurvePrimitiveArc>(__func__); + + data->mode = GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS; + node->storage = data; +} + +static void node_update(bNodeTree *ntree, bNode *node) +{ + const NodeGeometryCurvePrimitiveArc &storage = node_storage(*node); + const GeometryNodeCurvePrimitiveArcMode mode = (GeometryNodeCurvePrimitiveArcMode)storage.mode; + + bNodeSocket *start_socket = ((bNodeSocket *)node->inputs.first)->next; + bNodeSocket *middle_socket = start_socket->next; + bNodeSocket *end_socket = middle_socket->next; + + bNodeSocket *radius_socket = end_socket->next; + bNodeSocket *start_angle_socket = radius_socket->next; + bNodeSocket *sweep_angle_socket = start_angle_socket->next; + + bNodeSocket *offset_angle_socket = sweep_angle_socket->next; + + bNodeSocket *center_out_socket = ((bNodeSocket *)node->outputs.first)->next; + bNodeSocket *normal_out_socket = center_out_socket->next; + bNodeSocket *radius_out_socket = normal_out_socket->next; + + const bool radius_mode = (mode == GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS); + const bool points_mode = (mode == GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS); + + nodeSetSocketAvailability(ntree, start_socket, points_mode); + nodeSetSocketAvailability(ntree, middle_socket, points_mode); + nodeSetSocketAvailability(ntree, end_socket, points_mode); + + nodeSetSocketAvailability(ntree, radius_socket, radius_mode); + nodeSetSocketAvailability(ntree, start_angle_socket, radius_mode); + nodeSetSocketAvailability(ntree, sweep_angle_socket, radius_mode); + + nodeSetSocketAvailability(ntree, offset_angle_socket, points_mode); + + nodeSetSocketAvailability(ntree, center_out_socket, points_mode); + nodeSetSocketAvailability(ntree, normal_out_socket, points_mode); + nodeSetSocketAvailability(ntree, radius_out_socket, points_mode); +} + +static float3 rotate_vector_around_axis(const float3 vector, const float3 axis, const float angle) +{ + float3 result = vector; + float mat[3][3]; + axis_angle_to_mat3(mat, axis, angle); + mul_m3_v3(mat, result); + return result; +} + +static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3) +{ + const float3 a = math::normalize(p2 - p1); + const float3 b = math::normalize(p3 - p1); + return (ELEM(a, b, b * -1.0f)); +} + +static std::unique_ptr<CurveEval> create_arc_curve_from_points(const int resolution, + const float3 a, + const float3 b, + const float3 c, + float angle_offset, + const bool connect_center, + const bool invert_arc, + float3 &r_center, + float3 &r_normal, + float &r_radius) +{ + std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>(); + std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>(); + + if (connect_center) { + spline->resize(resolution + 1); + } + else { + spline->resize(resolution); + } + + const int stepcount = resolution - 1; + const int centerpoint = resolution; + MutableSpan<float3> positions = spline->positions(); + spline->radii().fill(1.0f); + spline->tilts().fill(0.0f); + + const bool is_colinear = colinear_f3_f3_f3(a, b, c); + + float3 center; + float3 normal; + float radius; + const float3 mid_ac = math::midpoint(a, c); + normal_tri_v3(normal, a, c, b); + + if (is_colinear || a == c || a == b || b == c || resolution == 2) { + /* If colinear, generate a point line between points. */ + float3 p1, p2; + + /* Find the two points that are furthest away from each other. */ + const float ab = math::distance_squared(a, b); + const float ac = math::distance_squared(a, c); + const float bc = math::distance_squared(b, c); + if (ab > ac && ab > bc) { + p1 = a; + p2 = b; + } + else if (bc > ab && bc > ac) { + p1 = b; + p2 = c; + } + else { + p1 = a; + p2 = c; + } + + const float step = 1.0f / stepcount; + for (const int i : IndexRange(resolution)) { + const float factor = step * i; + positions[i] = math::interpolate(p1, p2, factor); + } + center = mid_ac; + radius = 0.0f; + } + else { + /* Midpoints of `A->B` and `B->C`. */ + const float3 mid_ab = math::midpoint(a, b); + const float3 mid_bc = math::midpoint(c, b); + + /* Normalized vectors of `A->B` and `B->C`. */ + const float3 nba = math::normalize(b - a); + const float3 ncb = math::normalize(c - b); + + /* Normal of plane of main 2 segments A->B and `B->C`. */ + const float3 nabc = math::normalize(math::cross(nba, ncb)); + + /* Determine center point from the intersection of 3 planes. */ + float plane_1[4], plane_2[4], plane_3[4]; + plane_from_point_normal_v3(plane_1, mid_ab, nabc); + plane_from_point_normal_v3(plane_2, mid_ab, nba); + plane_from_point_normal_v3(plane_3, mid_bc, ncb); + + /* If the 3 planes do not intersect at one point, just return empty geometry. */ + if (!isect_plane_plane_plane_v3(plane_1, plane_2, plane_3, center)) { + r_center = mid_ac; + r_normal = normal; + r_radius = 0.0f; + return nullptr; + } + + /* Radial vectors. */ + const float3 rad_a = math::normalize(a - center); + const float3 rad_b = math::normalize(b - center); + const float3 rad_c = math::normalize(c - center); + + /* Calculate angles. */ + radius = math::distance(center, b); + float angle_ab = angle_signed_on_axis_v3v3_v3(rad_a, rad_b, normal) + 2.0f * M_PI; + float angle_ac = angle_signed_on_axis_v3v3_v3(rad_a, rad_c, normal) + 2.0f * M_PI; + float angle = (angle_ac > angle_ab) ? angle_ac : angle_ab; + angle -= 2.0f * M_PI; + if (invert_arc) { + angle = -(2.0f * M_PI - angle); + } + + /* Create arc. */ + const float step = angle / stepcount; + for (const int i : IndexRange(resolution)) { + const float factor = step * i + angle_offset; + float3 out = rotate_vector_around_axis(rad_a, -normal, factor); + positions[i] = out * radius + center; + } + } + + if (connect_center) { + spline->set_cyclic(true); + positions[centerpoint] = center; + } + + /* Ensure normal is relative to Z-up. */ + if (math::dot(float3(0, 0, 1), normal) < 0) { + normal = -normal; + } + + curve->add_spline(std::move(spline)); + curve->attributes.reallocate(curve->splines().size()); + r_center = center; + r_radius = radius; + r_normal = normal; + return curve; +} + +std::unique_ptr<CurveEval> create_arc_curve_from_radius(const int resolution, + const float radius, + const float start_angle, + const float sweep_angle, + const bool connect_center, + const bool invert_arc) +{ + std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>(); + std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>(); + + if (connect_center) { + spline->resize(resolution + 1); + } + else { + spline->resize(resolution); + } + + const int stepcount = resolution - 1; + const int centerpoint = resolution; + MutableSpan<float3> positions = spline->positions(); + spline->radii().fill(1.0f); + spline->tilts().fill(0.0f); + + const float sweep = (invert_arc) ? -(2.0f * M_PI - sweep_angle) : sweep_angle; + + const float theta_step = sweep / float(stepcount); + for (const int i : IndexRange(resolution)) { + const float theta = theta_step * i + start_angle; + const float x = radius * cos(theta); + const float y = radius * sin(theta); + positions[i] = float3(x, y, 0.0f); + } + + if (connect_center) { + spline->set_cyclic(true); + positions[centerpoint] = float3(0.0f, 0.0f, 0.0f); + } + + curve->add_spline(std::move(spline)); + curve->attributes.reallocate(curve->splines().size()); + return curve; +} + +static void node_geo_exec(GeoNodeExecParams params) +{ + const NodeGeometryCurvePrimitiveArc &storage = node_storage(params.node()); + + const GeometryNodeCurvePrimitiveArcMode mode = (GeometryNodeCurvePrimitiveArcMode)storage.mode; + + switch (mode) { + case GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_POINTS: { + std::unique_ptr<CurveEval> curve; + float3 r_center, r_normal; + float r_radius; + curve = create_arc_curve_from_points(std::max(params.extract_input<int>("Resolution"), 2), + params.extract_input<float3>("Start"), + params.extract_input<float3>("Middle"), + params.extract_input<float3>("End"), + params.extract_input<float>("Offset Angle"), + params.extract_input<bool>("Connect Center"), + params.extract_input<bool>("Invert Arc"), + r_center, + r_normal, + r_radius); + params.set_output("Curve", GeometrySet::create_with_curve(curve.release())); + params.set_output("Center", r_center); + params.set_output("Normal", r_normal); + params.set_output("Radius", r_radius); + break; + } + case GEO_NODE_CURVE_PRIMITIVE_ARC_TYPE_RADIUS: { + std::unique_ptr<CurveEval> curve; + const bool use_circle = false; + curve = create_arc_curve_from_radius(std::max(params.extract_input<int>("Resolution"), 2), + params.extract_input<float>("Radius"), + params.extract_input<float>("Start Angle"), + params.extract_input<float>("Sweep Angle"), + params.extract_input<bool>("Connect Center"), + params.extract_input<bool>("Invert Arc")); + + params.set_output("Curve", GeometrySet::create_with_curve(curve.release())); + break; + } + } +} + +} // namespace blender::nodes::node_geo_curve_primitive_arc_cc + +void register_node_type_geo_curve_primitive_arc() +{ + namespace file_ns = blender::nodes::node_geo_curve_primitive_arc_cc; + + static bNodeType ntype; + geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_ARC, "Arc", NODE_CLASS_GEOMETRY); + node_type_init(&ntype, file_ns::node_init); + node_type_update(&ntype, file_ns::node_update); + node_type_storage(&ntype, + "NodeGeometryCurvePrimitiveArc", + node_free_standard_storage, + node_copy_standard_storage); + ntype.declare = file_ns::node_declare; + ntype.geometry_node_execute = file_ns::node_geo_exec; + ntype.draw_buttons = file_ns::node_layout; + nodeRegisterType(&ntype); +} |