Blender  V3.3
node_geo_mesh_primitive_circle.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include "DNA_mesh_types.h"
4 #include "DNA_meshdata_types.h"
5 
6 #include "BKE_material.h"
7 #include "BKE_mesh.h"
8 
9 #include "UI_interface.h"
10 #include "UI_resources.h"
11 
12 #include "node_geometry_util.hh"
13 
15 
17 
19 {
20  b.add_input<decl::Int>(N_("Vertices"))
21  .default_value(32)
22  .min(3)
23  .description(N_("Number of vertices on the circle"));
24  b.add_input<decl::Float>(N_("Radius"))
25  .default_value(1.0f)
26  .min(0.0f)
27  .subtype(PROP_DISTANCE)
28  .description(N_("Distance of the vertices from the origin"));
29  b.add_output<decl::Geometry>(N_("Mesh"));
30 }
31 
32 static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
33 {
34  uiLayoutSetPropSep(layout, true);
35  uiLayoutSetPropDecorate(layout, false);
36  uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
37 }
38 
40 {
41  NodeGeometryMeshCircle *node_storage = MEM_cnew<NodeGeometryMeshCircle>(__func__);
42 
44 
45  node->storage = node_storage;
46 }
47 
48 static int circle_vert_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
49 {
50  switch (fill_type) {
53  return verts_num;
55  return verts_num + 1;
56  }
58  return 0;
59 }
60 
61 static int circle_edge_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
62 {
63  switch (fill_type) {
66  return verts_num;
68  return verts_num * 2;
69  }
71  return 0;
72 }
73 
74 static int circle_corner_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
75 {
76  switch (fill_type) {
78  return 0;
80  return verts_num;
82  return verts_num * 3;
83  }
85  return 0;
86 }
87 
88 static int circle_face_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
89 {
90  switch (fill_type) {
92  return 0;
94  return 1;
96  return verts_num;
97  }
99  return 0;
100 }
101 
102 static Mesh *create_circle_mesh(const float radius,
103  const int verts_num,
104  const GeometryNodeMeshCircleFillType fill_type)
105 {
106  Mesh *mesh = BKE_mesh_new_nomain(circle_vert_total(fill_type, verts_num),
107  circle_edge_total(fill_type, verts_num),
108  0,
109  circle_corner_total(fill_type, verts_num),
110  circle_face_total(fill_type, verts_num));
116 
117  /* Assign vertex coordinates. */
118  const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num));
119  for (const int i : IndexRange(verts_num)) {
120  const float angle = i * angle_delta;
121  copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f));
122  }
123  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
124  copy_v3_v3(verts.last().co, float3(0));
125  }
126 
127  /* Create outer edges. */
128  const short edge_flag = (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ?
129  ME_LOOSEEDGE :
130  (ME_EDGEDRAW | ME_EDGERENDER); /* NGON or TRIANGLE_FAN */
131  for (const int i : IndexRange(verts_num)) {
132  MEdge &edge = edges[i];
133  edge.v1 = i;
134  edge.v2 = (i + 1) % verts_num;
135  edge.flag = edge_flag;
136  }
137 
138  /* Create triangle fan edges. */
139  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
140  for (const int i : IndexRange(verts_num)) {
141  MEdge &edge = edges[verts_num + i];
142  edge.v1 = verts_num;
143  edge.v2 = i;
144  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
145  }
146  }
147 
148  /* Create corners and faces. */
149  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
150  MPoly &poly = polys[0];
151  poly.loopstart = 0;
152  poly.totloop = loops.size();
153 
154  for (const int i : IndexRange(verts_num)) {
155  MLoop &loop = loops[i];
156  loop.e = i;
157  loop.v = i;
158  }
159  }
160  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
161  for (const int i : IndexRange(verts_num)) {
162  MPoly &poly = polys[i];
163  poly.loopstart = 3 * i;
164  poly.totloop = 3;
165 
166  MLoop &loop_a = loops[3 * i];
167  loop_a.e = i;
168  loop_a.v = i;
169  MLoop &loop_b = loops[3 * i + 1];
170  loop_b.e = verts_num + ((i + 1) % verts_num);
171  loop_b.v = (i + 1) % verts_num;
172  MLoop &loop_c = loops[3 * i + 2];
173  loop_c.e = verts_num + i;
174  loop_c.v = verts_num;
175  }
176  }
177 
178  return mesh;
179 }
180 
182 {
183  const NodeGeometryMeshCircle &storage = node_storage(params.node());
185 
186  const float radius = params.extract_input<float>("Radius");
187  const int verts_num = params.extract_input<int>("Vertices");
188  if (verts_num < 3) {
189  params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3"));
190  params.set_default_remaining_outputs();
191  return;
192  }
193 
194  Mesh *mesh = create_circle_mesh(radius, verts_num, fill);
195 
196  params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
197 }
198 
199 } // namespace blender::nodes::node_geo_mesh_primitive_circle_cc
200 
202 {
204 
205  static bNodeType ntype;
206 
210  &ntype, "NodeGeometryMeshCircle", node_free_standard_storage, node_copy_standard_storage);
214  nodeRegisterType(&ntype);
215 }
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(struct ID *id)
Definition: material.c:784
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
#define GEO_NODE_MESH_PRIMITIVE_CIRCLE
Definition: BKE_node.h:1392
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
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 BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define M_PI
Definition: BLI_math_base.h:20
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define TIP_(msgid)
@ ME_EDGEDRAW
@ ME_EDGERENDER
@ ME_LOOSEEDGE
GeometryNodeMeshCircleFillType
@ GEO_NODE_MESH_CIRCLE_FILL_NGON
@ GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN
@ GEO_NODE_MESH_CIRCLE_FILL_NONE
in reality light always falls off quadratically Particle Info
@ PROP_DISTANCE
Definition: RNA_types.h:149
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
OperationNode * node
bNodeTree * ntree
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
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
static int circle_edge_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
static int circle_corner_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
static int circle_vert_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
static int circle_face_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num)
static Mesh * create_circle_mesh(const float radius, const int verts_num, const GeometryNodeMeshCircleFillType fill_type)
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
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_mesh_primitive_circle()
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
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
unsigned int e
unsigned int v
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
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
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480