Blender  V3.3
node_geo_curve_primitive_circle.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "BKE_curves.hh"
4 
5 #include "UI_interface.h"
6 #include "UI_resources.h"
7 
8 #include "node_geometry_util.hh"
9 
11 
13 
15 {
16  auto endable_points = [](bNode &node) {
18  };
19  auto enable_radius = [](bNode &node) {
21  };
22 
23  b.add_input<decl::Int>(N_("Resolution"))
24  .default_value(32)
25  .min(3)
26  .max(512)
27  .description(N_("Number of points on the circle"));
28  b.add_input<decl::Vector>(N_("Point 1"))
29  .default_value({-1.0f, 0.0f, 0.0f})
30  .subtype(PROP_TRANSLATION)
31  .description(
32  N_("One of the three points on the circle. The point order determines the circle's "
33  "direction"))
34  .make_available(endable_points);
35  b.add_input<decl::Vector>(N_("Point 2"))
36  .default_value({0.0f, 1.0f, 0.0f})
37  .subtype(PROP_TRANSLATION)
38  .description(
39  N_("One of the three points on the circle. The point order determines the circle's "
40  "direction"))
41  .make_available(endable_points);
42  b.add_input<decl::Vector>(N_("Point 3"))
43  .default_value({1.0f, 0.0f, 0.0f})
44  .subtype(PROP_TRANSLATION)
45  .description(
46  N_("One of the three points on the circle. The point order determines the circle's "
47  "direction"))
48  .make_available(endable_points);
49  b.add_input<decl::Float>(N_("Radius"))
50  .default_value(1.0f)
51  .min(0.0f)
52  .subtype(PROP_DISTANCE)
53  .description(N_("Distance of the points from the origin"))
54  .make_available(enable_radius);
55  b.add_output<decl::Geometry>(N_("Curve"));
56  b.add_output<decl::Vector>(N_("Center")).make_available(endable_points);
57 }
58 
59 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
60 {
61  uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
62 }
63 
65 {
66  NodeGeometryCurvePrimitiveCircle *data = MEM_cnew<NodeGeometryCurvePrimitiveCircle>(__func__);
67 
69  node->storage = data;
70 }
71 
73 {
74  const NodeGeometryCurvePrimitiveCircle &storage = node_storage(*node);
76  storage.mode;
77 
78  bNodeSocket *start_socket = ((bNodeSocket *)node->inputs.first)->next;
79  bNodeSocket *middle_socket = start_socket->next;
80  bNodeSocket *end_socket = middle_socket->next;
81  bNodeSocket *radius_socket = end_socket->next;
82 
83  bNodeSocket *center_socket = ((bNodeSocket *)node->outputs.first)->next;
84 
86  ntree, start_socket, mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS);
88  ntree, middle_socket, mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS);
92  ntree, center_socket, mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS);
94  ntree, radius_socket, mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_RADIUS);
95 }
96 
97 static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3)
98 {
99  const float3 a = math::normalize(p2 - p1);
100  const float3 b = math::normalize(p3 - p1);
101  return (ELEM(a, b, b * -1.0f));
102 }
103 
105  const float3 p1, const float3 p2, const float3 p3, const int resolution, float3 &r_center)
106 {
107  if (colinear_f3_f3_f3(p1, p2, p3)) {
108  r_center = float3(0);
109  return nullptr;
110  }
111 
112  Curves *curves_id = bke::curves_new_nomain_single(resolution, CURVE_TYPE_POLY);
114  curves.cyclic_for_write().first() = true;
115 
116  MutableSpan<float3> positions = curves.positions_for_write();
117 
118  float3 center;
119  /* Midpoints of `P1->P2` and `P2->P3`. */
120  const float3 q1 = math::interpolate(p1, p2, 0.5f);
121  const float3 q2 = math::interpolate(p2, p3, 0.5f);
122 
123  /* Normal Vectors of `P1->P2` and `P2->P3` */
124  const float3 v1 = math::normalize(p2 - p1);
125  const float3 v2 = math::normalize(p3 - p2);
126 
127  /* Normal of plane of main 2 segments P1->P2 and `P2->P3`. */
128  const float3 v3 = math::normalize(math::cross(v1, v2));
129 
130  /* Normal of plane of first perpendicular bisector and `P1->P2`. */
131  const float3 v4 = math::normalize(math::cross(v3, v1));
132 
133  /* Determine Center-point from the intersection of 3 planes. */
134  float plane_1[4], plane_2[4], plane_3[4];
135  plane_from_point_normal_v3(plane_1, q1, v3);
136  plane_from_point_normal_v3(plane_2, q1, v1);
137  plane_from_point_normal_v3(plane_3, q2, v2);
138 
139  /* If the 3 planes do not intersect at one point, just return empty geometry. */
140  if (!isect_plane_plane_plane_v3(plane_1, plane_2, plane_3, center)) {
141  r_center = float3(0);
142  return nullptr;
143  }
144 
145  /* Get the radius from the center-point to p1. */
146  const float r = math::distance(p1, center);
147  const float theta_step = ((2 * M_PI) / (float)resolution);
148  for (const int i : IndexRange(resolution)) {
149 
150  /* Formula for a circle around a point and 2 unit vectors perpendicular
151  * to each other and the axis of the circle from:
152  * https://math.stackexchange.com/questions/73237/parametric-equation-of-a-circle-in-3d-space
153  */
154 
155  const float theta = theta_step * i;
156  positions[i] = center + r * sin(theta) * v1 + r * cos(theta) * v4;
157  }
158 
159  r_center = center;
160  return curves_id;
161 }
162 
163 static Curves *create_radius_circle_curve(const int resolution, const float radius)
164 {
165  Curves *curves_id = bke::curves_new_nomain_single(resolution, CURVE_TYPE_POLY);
167  curves.cyclic_for_write().first() = true;
168 
169  MutableSpan<float3> positions = curves.positions_for_write();
170 
171  const float theta_step = (2.0f * M_PI) / float(resolution);
172  for (int i : IndexRange(resolution)) {
173  const float theta = theta_step * i;
174  const float x = radius * cos(theta);
175  const float y = radius * sin(theta);
176  positions[i] = float3(x, y, 0.0f);
177  }
178 
179  return curves_id;
180 }
181 
183 {
184  const NodeGeometryCurvePrimitiveCircle &storage = node_storage(params.node());
186  storage.mode;
187 
188  Curves *curves = nullptr;
190  float3 center_point;
191  curves = create_point_circle_curve(params.extract_input<float3>("Point 1"),
192  params.extract_input<float3>("Point 2"),
193  params.extract_input<float3>("Point 3"),
194  std::max(params.extract_input<int>("Resolution"), 3),
195  center_point);
196  params.set_output("Center", center_point);
197  }
199  curves = create_radius_circle_curve(std::max(params.extract_input<int>("Resolution"), 3),
200  params.extract_input<float>("Radius"));
201  }
202 
203  if (curves) {
204  params.set_output("Curve", GeometrySet::create_with_curves(curves));
205  }
206  else {
207  params.set_default_remaining_outputs();
208  }
209 }
210 
211 } // namespace blender::nodes::node_geo_curve_primitive_circle_cc
212 
214 {
216 
217  static bNodeType ntype;
219 
222  node_type_storage(&ntype,
223  "NodeGeometryCurvePrimitiveCircle",
229  nodeRegisterType(&ntype);
230 }
Low-level operations for curves.
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
#define GEO_NODE_CURVE_PRIMITIVE_CIRCLE
Definition: BKE_node.h:1412
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
#define NODE_CLASS_GEOMETRY
Definition: BKE_node.h:359
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define M_PI
Definition: BLI_math_base.h:20
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
bool isect_plane_plane_plane_v3(const float plane_a[4], const float plane_b[4], const float plane_c[4], float r_isect_co[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_geom.c:2101
#define UNUSED(x)
#define ELEM(...)
@ CURVE_TYPE_POLY
GeometryNodeCurvePrimitiveCircleMode
@ GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_RADIUS
@ GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
@ PROP_DISTANCE
Definition: RNA_types.h:149
@ PROP_TRANSLATION
Definition: RNA_types.h:154
@ UI_ITEM_R_EXPAND
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static CurvesGeometry & wrap(::CurvesGeometry &dna_struct)
Definition: BKE_curves.hh:138
OperationNode * node
void * tree
bNodeTree * ntree
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static ulong * next
static unsigned a[3]
Definition: RandGen.cpp:78
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
Curves * curves_new_nomain_single(int points_num, CurveType type)
Definition: curves.cc:375
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
T distance(const T &a, const T &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
T interpolate(const T &a, const T &b, const FactorT &t)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static Curves * create_point_circle_curve(const float3 p1, const float3 p2, const float3 p3, const int resolution, float3 &r_center)
static void node_init(bNodeTree *UNUSED(tree), bNode *node)
static Curves * create_radius_circle_curve(const int resolution, const float radius)
static bool colinear_f3_f3_f3(const float3 p1, const float3 p2, const float3 p3)
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
Definition: node.cc:1082
void register_node_type_geo_curve_primitive_circle()
MutableSpan< float3 > positions
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
CurvesGeometry geometry
static GeometrySet create_with_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
struct bNodeSocket * next
Defines a node type.
Definition: BKE_node.h:226
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:316
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
float max
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480