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:
-rw-r--r--release/scripts/startup/nodeitems_builtins.py1
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/blenlib/BLI_math_vector.hh5
-rw-r--r--source/blender/makesdna/DNA_node_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c27
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_arc.cc392
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);
+}