Blender  V2.93
node_geo_mesh_primitive_cone.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include "DNA_mesh_types.h"
18 #include "DNA_meshdata_types.h"
19 
20 #include "BKE_mesh.h"
21 
22 #include "UI_interface.h"
23 #include "UI_resources.h"
24 
25 #include "node_geometry_util.hh"
26 
28  {SOCK_INT, N_("Vertices"), 32, 0.0f, 0.0f, 0.0f, 3, 4096},
29  {SOCK_FLOAT, N_("Radius Top"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE},
30  {SOCK_FLOAT, N_("Radius Bottom"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE},
31  {SOCK_FLOAT, N_("Depth"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX, PROP_DISTANCE},
32  {-1, ""},
33 };
34 
36  {SOCK_GEOMETRY, N_("Geometry")},
37  {-1, ""},
38 };
39 
41  bContext *UNUSED(C),
42  PointerRNA *ptr)
43 {
44  uiLayoutSetPropSep(layout, true);
45  uiLayoutSetPropDecorate(layout, false);
46  uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
47 }
48 
50 {
52  sizeof(NodeGeometryMeshCone), __func__);
53 
55 
56  node->storage = node_storage;
57 }
58 
59 namespace blender::nodes {
60 
61 static int vert_total(const GeometryNodeMeshCircleFillType fill_type,
62  const int verts_num,
63  const bool top_is_point,
64  const bool bottom_is_point)
65 {
66  int vert_total = 0;
67  if (!top_is_point) {
68  vert_total += verts_num;
69  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
70  vert_total++;
71  }
72  }
73  else {
74  vert_total++;
75  }
76  if (!bottom_is_point) {
77  vert_total += verts_num;
78  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
79  vert_total++;
80  }
81  }
82  else {
83  vert_total++;
84  }
85 
86  return vert_total;
87 }
88 
89 static int edge_total(const GeometryNodeMeshCircleFillType fill_type,
90  const int verts_num,
91  const bool top_is_point,
92  const bool bottom_is_point)
93 {
94  if (top_is_point && bottom_is_point) {
95  return 1;
96  }
97 
98  int edge_total = 0;
99  if (!top_is_point) {
100  edge_total += verts_num;
101  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
102  edge_total += verts_num;
103  }
104  }
105 
106  edge_total += verts_num;
107 
108  if (!bottom_is_point) {
109  edge_total += verts_num;
110  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
111  edge_total += verts_num;
112  }
113  }
114 
115  return edge_total;
116 }
117 
118 static int corner_total(const GeometryNodeMeshCircleFillType fill_type,
119  const int verts_num,
120  const bool top_is_point,
121  const bool bottom_is_point)
122 {
123  if (top_is_point && bottom_is_point) {
124  return 0;
125  }
126 
127  int corner_total = 0;
128  if (!top_is_point) {
129  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
130  corner_total += verts_num;
131  }
132  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
133  corner_total += verts_num * 3;
134  }
135  }
136 
137  if (!top_is_point && !bottom_is_point) {
138  corner_total += verts_num * 4;
139  }
140  else {
141  corner_total += verts_num * 3;
142  }
143 
144  if (!bottom_is_point) {
145  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
146  corner_total += verts_num;
147  }
148  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
149  corner_total += verts_num * 3;
150  }
151  }
152 
153  return corner_total;
154 }
155 
156 static int face_total(const GeometryNodeMeshCircleFillType fill_type,
157  const int verts_num,
158  const bool top_is_point,
159  const bool bottom_is_point)
160 {
161  if (top_is_point && bottom_is_point) {
162  return 0;
163  }
164 
165  int face_total = 0;
166  if (!top_is_point) {
167  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
168  face_total++;
169  }
170  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
171  face_total += verts_num;
172  }
173  }
174 
175  face_total += verts_num;
176 
177  if (!bottom_is_point) {
178  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
179  face_total++;
180  }
181  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
182  face_total += verts_num;
183  }
184  }
185 
186  return face_total;
187 }
188 
189 static void calculate_uvs(Mesh *mesh,
190  const bool top_is_point,
191  const bool bottom_is_point,
192  const int verts_num,
193  const GeometryNodeMeshCircleFillType fill_type)
194 {
195  MeshComponent mesh_component;
197  OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
198  "uv_map", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
199  MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
200 
201  Array<float2> circle(verts_num);
202  float angle = 0.0f;
203  const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
204  for (const int i : IndexRange(verts_num)) {
205  circle[i].x = std::cos(angle) * 0.225f + 0.25f;
206  circle[i].y = std::sin(angle) * 0.225f + 0.25f;
207  angle += angle_delta;
208  }
209 
210  int loop_index = 0;
211  if (!top_is_point) {
212  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
213  for (const int i : IndexRange(verts_num)) {
214  uvs[loop_index++] = circle[i];
215  }
216  }
217  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
218  for (const int i : IndexRange(verts_num)) {
219  uvs[loop_index++] = circle[i];
220  uvs[loop_index++] = circle[(i + 1) % verts_num];
221  uvs[loop_index++] = float2(0.25f, 0.25f);
222  }
223  }
224  }
225 
226  /* Create side corners and faces. */
227  if (!top_is_point && !bottom_is_point) {
228  const float bottom = (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ? 0.0f : 0.5f;
229  /* Quads connect the top and bottom. */
230  for (const int i : IndexRange(verts_num)) {
231  const float vert = static_cast<float>(i);
232  uvs[loop_index++] = float2(vert / verts_num, bottom);
233  uvs[loop_index++] = float2(vert / verts_num, 1.0f);
234  uvs[loop_index++] = float2((vert + 1.0f) / verts_num, 1.0f);
235  uvs[loop_index++] = float2((vert + 1.0f) / verts_num, bottom);
236  }
237  }
238  else {
239  /* Triangles connect the top and bottom section. */
240  if (!top_is_point) {
241  for (const int i : IndexRange(verts_num)) {
242  uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
243  uvs[loop_index++] = float2(0.75f, 0.25f);
244  uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
245  }
246  }
247  else {
248  BLI_assert(!bottom_is_point);
249  for (const int i : IndexRange(verts_num)) {
250  uvs[loop_index++] = circle[i];
251  uvs[loop_index++] = circle[(i + 1) % verts_num];
252  uvs[loop_index++] = float2(0.25f, 0.25f);
253  }
254  }
255  }
256 
257  /* Create bottom corners and faces. */
258  if (!bottom_is_point) {
259  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
260  for (const int i : IndexRange(verts_num)) {
261  /* Go backwards because of reversed face normal. */
262  uvs[loop_index++] = circle[verts_num - 1 - i] + float2(0.5f, 0.0f);
263  }
264  }
265  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
266  for (const int i : IndexRange(verts_num)) {
267  uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
268  uvs[loop_index++] = float2(0.75f, 0.25f);
269  uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
270  }
271  }
272  }
273 
274  uv_attribute.apply_span_and_save();
275 }
276 
277 Mesh *create_cylinder_or_cone_mesh(const float radius_top,
278  const float radius_bottom,
279  const float depth,
280  const int verts_num,
281  const GeometryNodeMeshCircleFillType fill_type)
282 {
283  const bool top_is_point = radius_top == 0.0f;
284  const bool bottom_is_point = radius_bottom == 0.0f;
285  const float height = depth * 0.5f;
286  /* Handle the case of a line / single point before everything else to avoid
287  * the need to check for it later. */
288  if (top_is_point && bottom_is_point) {
289  const bool single_vertex = height == 0.0f;
290  Mesh *mesh = BKE_mesh_new_nomain(single_vertex ? 1 : 2, single_vertex ? 0 : 1, 0, 0, 0);
291  copy_v3_v3(mesh->mvert[0].co, float3(0.0f, 0.0f, height));
292  if (single_vertex) {
293  const short up[3] = {0, 0, SHRT_MAX};
294  copy_v3_v3_short(mesh->mvert[0].no, up);
295  return mesh;
296  }
297  copy_v3_v3(mesh->mvert[1].co, float3(0.0f, 0.0f, -height));
298  mesh->medge[0].v1 = 0;
299  mesh->medge[0].v2 = 1;
300  mesh->medge[0].flag |= ME_LOOSEEDGE;
302  return mesh;
303  }
304 
306  vert_total(fill_type, verts_num, top_is_point, bottom_is_point),
307  edge_total(fill_type, verts_num, top_is_point, bottom_is_point),
308  0,
309  corner_total(fill_type, verts_num, top_is_point, bottom_is_point),
310  face_total(fill_type, verts_num, top_is_point, bottom_is_point));
315 
316  /* Calculate vertex positions. */
317  const int top_verts_start = 0;
318  const int bottom_verts_start = top_verts_start + (!top_is_point ? verts_num : 1);
319  float angle = 0.0f;
320  const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
321  for (const int i : IndexRange(verts_num)) {
322  const float x = std::cos(angle);
323  const float y = std::sin(angle);
324  if (!top_is_point) {
325  copy_v3_v3(verts[top_verts_start + i].co, float3(x * radius_top, y * radius_top, height));
326  }
327  if (!bottom_is_point) {
328  copy_v3_v3(verts[bottom_verts_start + i].co,
329  float3(x * radius_bottom, y * radius_bottom, -height));
330  }
331  angle += angle_delta;
332  }
333  if (top_is_point) {
334  copy_v3_v3(verts[top_verts_start].co, float3(0.0f, 0.0f, height));
335  }
336  if (bottom_is_point) {
337  copy_v3_v3(verts[bottom_verts_start].co, float3(0.0f, 0.0f, -height));
338  }
339 
340  /* Add center vertices for the triangle fans at the end. */
341  const int top_center_vert_index = bottom_verts_start + (bottom_is_point ? 1 : verts_num);
342  const int bottom_center_vert_index = top_center_vert_index + (top_is_point ? 0 : 1);
343  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
344  if (!top_is_point) {
345  copy_v3_v3(verts[top_center_vert_index].co, float3(0.0f, 0.0f, height));
346  }
347  if (!bottom_is_point) {
348  copy_v3_v3(verts[bottom_center_vert_index].co, float3(0.0f, 0.0f, -height));
349  }
350  }
351 
352  /* Create top edges. */
353  const int top_edges_start = 0;
354  const int top_fan_edges_start = (!top_is_point &&
356  top_edges_start + verts_num :
357  top_edges_start;
358  if (!top_is_point) {
359  for (const int i : IndexRange(verts_num)) {
360  MEdge &edge = edges[top_edges_start + i];
361  edge.v1 = top_verts_start + i;
362  edge.v2 = top_verts_start + (i + 1) % verts_num;
363  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
364  }
365  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
366  for (const int i : IndexRange(verts_num)) {
367  MEdge &edge = edges[top_fan_edges_start + i];
368  edge.v1 = top_center_vert_index;
369  edge.v2 = top_verts_start + i;
370  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
371  }
372  }
373  }
374 
375  /* Create connecting edges. */
376  const int connecting_edges_start = top_fan_edges_start + (!top_is_point ? verts_num : 0);
377  for (const int i : IndexRange(verts_num)) {
378  MEdge &edge = edges[connecting_edges_start + i];
379  edge.v1 = top_verts_start + (!top_is_point ? i : 0);
380  edge.v2 = bottom_verts_start + (!bottom_is_point ? i : 0);
381  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
382  }
383 
384  /* Create bottom edges. */
385  const int bottom_edges_start = connecting_edges_start + verts_num;
386  const int bottom_fan_edges_start = (!bottom_is_point &&
388  bottom_edges_start + verts_num :
389  bottom_edges_start;
390  if (!bottom_is_point) {
391  for (const int i : IndexRange(verts_num)) {
392  MEdge &edge = edges[bottom_edges_start + i];
393  edge.v1 = bottom_verts_start + i;
394  edge.v2 = bottom_verts_start + (i + 1) % verts_num;
395  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
396  }
397  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
398  for (const int i : IndexRange(verts_num)) {
399  MEdge &edge = edges[bottom_fan_edges_start + i];
400  edge.v1 = bottom_center_vert_index;
401  edge.v2 = bottom_verts_start + i;
402  edge.flag = ME_EDGEDRAW | ME_EDGERENDER;
403  }
404  }
405  }
406 
407  /* Create top corners and faces. */
408  int loop_index = 0;
409  int poly_index = 0;
410  if (!top_is_point) {
411  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
412  MPoly &poly = polys[poly_index++];
413  poly.loopstart = loop_index;
414  poly.totloop = verts_num;
415 
416  for (const int i : IndexRange(verts_num)) {
417  MLoop &loop = loops[loop_index++];
418  loop.v = top_verts_start + i;
419  loop.e = top_edges_start + i;
420  }
421  }
422  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
423  for (const int i : IndexRange(verts_num)) {
424  MPoly &poly = polys[poly_index++];
425  poly.loopstart = loop_index;
426  poly.totloop = 3;
427 
428  MLoop &loop_a = loops[loop_index++];
429  loop_a.v = top_verts_start + i;
430  loop_a.e = top_edges_start + i;
431  MLoop &loop_b = loops[loop_index++];
432  loop_b.v = top_verts_start + (i + 1) % verts_num;
433  loop_b.e = top_fan_edges_start + (i + 1) % verts_num;
434  MLoop &loop_c = loops[loop_index++];
435  loop_c.v = top_center_vert_index;
436  loop_c.e = top_fan_edges_start + i;
437  }
438  }
439  }
440 
441  /* Create side corners and faces. */
442  if (!top_is_point && !bottom_is_point) {
443  /* Quads connect the top and bottom. */
444  for (const int i : IndexRange(verts_num)) {
445  MPoly &poly = polys[poly_index++];
446  poly.loopstart = loop_index;
447  poly.totloop = 4;
448 
449  MLoop &loop_a = loops[loop_index++];
450  loop_a.v = top_verts_start + i;
451  loop_a.e = connecting_edges_start + i;
452  MLoop &loop_b = loops[loop_index++];
453  loop_b.v = bottom_verts_start + i;
454  loop_b.e = bottom_edges_start + i;
455  MLoop &loop_c = loops[loop_index++];
456  loop_c.v = bottom_verts_start + (i + 1) % verts_num;
457  loop_c.e = connecting_edges_start + (i + 1) % verts_num;
458  MLoop &loop_d = loops[loop_index++];
459  loop_d.v = top_verts_start + (i + 1) % verts_num;
460  loop_d.e = top_edges_start + i;
461  }
462  }
463  else {
464  /* Triangles connect the top and bottom section. */
465  if (!top_is_point) {
466  for (const int i : IndexRange(verts_num)) {
467  MPoly &poly = polys[poly_index++];
468  poly.loopstart = loop_index;
469  poly.totloop = 3;
470 
471  MLoop &loop_a = loops[loop_index++];
472  loop_a.v = top_verts_start + i;
473  loop_a.e = connecting_edges_start + i;
474  MLoop &loop_b = loops[loop_index++];
475  loop_b.v = bottom_verts_start;
476  loop_b.e = connecting_edges_start + (i + 1) % verts_num;
477  MLoop &loop_c = loops[loop_index++];
478  loop_c.v = top_verts_start + (i + 1) % verts_num;
479  loop_c.e = top_edges_start + i;
480  }
481  }
482  else {
483  BLI_assert(!bottom_is_point);
484  for (const int i : IndexRange(verts_num)) {
485  MPoly &poly = polys[poly_index++];
486  poly.loopstart = loop_index;
487  poly.totloop = 3;
488 
489  MLoop &loop_a = loops[loop_index++];
490  loop_a.v = bottom_verts_start + i;
491  loop_a.e = bottom_edges_start + i;
492  MLoop &loop_b = loops[loop_index++];
493  loop_b.v = bottom_verts_start + (i + 1) % verts_num;
494  loop_b.e = connecting_edges_start + (i + 1) % verts_num;
495  MLoop &loop_c = loops[loop_index++];
496  loop_c.v = top_verts_start;
497  loop_c.e = connecting_edges_start + i;
498  }
499  }
500  }
501 
502  /* Create bottom corners and faces. */
503  if (!bottom_is_point) {
504  if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
505  MPoly &poly = polys[poly_index++];
506  poly.loopstart = loop_index;
507  poly.totloop = verts_num;
508 
509  for (const int i : IndexRange(verts_num)) {
510  /* Go backwards to reverse surface normal. */
511  MLoop &loop = loops[loop_index++];
512  loop.v = bottom_verts_start + verts_num - 1 - i;
513  loop.e = bottom_edges_start + verts_num - 1 - (i + 1) % verts_num;
514  }
515  }
516  else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
517  for (const int i : IndexRange(verts_num)) {
518  MPoly &poly = polys[poly_index++];
519  poly.loopstart = loop_index;
520  poly.totloop = 3;
521 
522  MLoop &loop_a = loops[loop_index++];
523  loop_a.v = bottom_verts_start + i;
524  loop_a.e = bottom_fan_edges_start + i;
525  MLoop &loop_b = loops[loop_index++];
526  loop_b.v = bottom_center_vert_index;
527  loop_b.e = bottom_fan_edges_start + (i + 1) % verts_num;
528  MLoop &loop_c = loops[loop_index++];
529  loop_c.v = bottom_verts_start + (i + 1) % verts_num;
530  loop_c.e = bottom_edges_start + i;
531  }
532  }
533  }
534 
536 
537  calculate_uvs(mesh, top_is_point, bottom_is_point, verts_num, fill_type);
538 
540 
541  return mesh;
542 }
543 
545 {
546  const bNode &node = params.node();
547  const NodeGeometryMeshCone &storage = *(const NodeGeometryMeshCone *)node.storage;
548 
550  storage.fill_type;
551 
552  const int verts_num = params.extract_input<int>("Vertices");
553  if (verts_num < 3) {
554  params.set_output("Geometry", GeometrySet());
555  return;
556  }
557 
558  const float radius_top = params.extract_input<float>("Radius Top");
559  const float radius_bottom = params.extract_input<float>("Radius Bottom");
560  const float depth = params.extract_input<float>("Depth");
561 
563  radius_top, radius_bottom, depth, verts_num, fill_type);
564 
565  /* Transform the mesh so that the base of the cone is at the origin. */
566  BKE_mesh_translate(mesh, float3(0.0f, 0.0f, depth * 0.5f), false);
567 
568  params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
569 }
570 
571 } // namespace blender::nodes
572 
574 {
575  static bNodeType ntype;
576 
582  &ntype, "NodeGeometryMeshCone", node_free_standard_storage, node_copy_standard_storage);
585  nodeRegisterType(&ntype);
586 }
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:45
bool BKE_mesh_is_valid(struct Mesh *me)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.c:877
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_translate(struct Mesh *me, const float offset[3], const bool do_keys)
Definition: mesh.c:1522
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4559
#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:4599
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define M_PI
Definition: BLI_math_base.h:38
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
#define UNUSED(x)
#define N_(msgid)
@ CD_PROP_FLOAT2
@ 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
@ SOCK_INT
@ SOCK_FLOAT
@ SOCK_GEOMETRY
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 bottom
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random Edge Subdivision Point Object Attribute Attribute Attribute Color Attribute Attribute Vector Point Attribute Sample Collection Attribute Attribute Combine Attribute GEO_NODE_MESH_PRIMITIVE_CONE
@ PROP_DISTANCE
Definition: RNA_types.h:135
#define C
Definition: RandGen.cpp:39
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
OutputAttributePtr attribute_try_get_for_output(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type, const void *default_value=nullptr)
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
fn::GMutableSpan get_span_for_write_only()
OperationNode * node
bNodeTree * ntree
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
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
Mesh * create_cylinder_or_cone_mesh(const float radius_top, const float radius_bottom, const float depth, const int verts_num, const GeometryNodeMeshCircleFillType fill_type)
static int edge_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num, const bool top_is_point, const bool bottom_is_point)
static void calculate_uvs(Mesh *mesh, const bool top_is_point, const bool bottom_is_point, const int verts_num, const GeometryNodeMeshCircleFillType fill_type)
static int corner_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num, const bool top_is_point, const bool bottom_is_point)
static int vert_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num, const bool top_is_point, const bool bottom_is_point)
static int face_total(const GeometryNodeMeshCircleFillType fill_type, const int verts_num, const bool top_is_point, const bool bottom_is_point)
static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
static bNodeSocketTemplate geo_node_mesh_primitive_cone_in[]
static void geo_node_mesh_primitive_cone_init(bNodeTree *UNUSED(ntree), bNode *node)
void register_node_type_geo_mesh_primitive_cone()
static bNodeSocketTemplate geo_node_mesh_primitive_cone_out[]
static void geo_node_mesh_primitive_cone_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:67
void node_free_standard_storage(bNode *node)
Definition: node_util.c:55
static GeometrySet create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
unsigned int v1
unsigned int v2
unsigned int e
unsigned int v
float co[3]
short no[3]
struct MEdge * medge
struct MVert * mvert
int totedge
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
Compact definition of a node socket.
Definition: BKE_node.h:95
Defines a node type.
Definition: BKE_node.h:221
NodeGeometryExecFunction geometry_node_execute
Definition: BKE_node.h:327
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:253
PointerRNA * ptr
Definition: wm_files.c:3157