Blender V5.0
node_geo_mesh_primitive_cylinder.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_material.hh"
6
7#include "NOD_rna_define.hh"
8
10
12#include "UI_resources.hh"
13
14#include "node_geometry_util.hh"
15
16#include "RNA_enum_types.hh"
17
19
21
23{
24 b.add_input<decl::Int>("Vertices")
25 .default_value(32)
26 .min(3)
27 .max(512)
28 .description("The number of vertices on the top and bottom circles");
29 b.add_input<decl::Int>("Side Segments")
31 .min(1)
32 .max(512)
33 .description("The number of rectangular segments along each side");
34 auto &fill = b.add_input<decl::Int>("Fill Segments")
36 .min(1)
37 .max(512)
38 .description("The number of concentric rings used to fill the round faces");
39 b.add_input<decl::Float>("Radius")
40 .default_value(1.0f)
41 .min(0.0f)
42 .subtype(PROP_DISTANCE)
43 .description("The radius of the cylinder");
44 b.add_input<decl::Float>("Depth")
45 .default_value(2.0f)
46 .min(0.0f)
47 .subtype(PROP_DISTANCE)
48 .description("The height of the cylinder");
49 b.add_output<decl::Geometry>("Mesh");
50 b.add_output<decl::Bool>("Top").field_on_all().translation_context(BLT_I18NCONTEXT_ID_NODETREE);
51 b.add_output<decl::Bool>("Side").field_on_all();
52 b.add_output<decl::Bool>("Bottom").field_on_all().translation_context(
54 b.add_output<decl::Vector>("UV Map").field_on_all();
55
56 const bNode *node = b.node_or_null();
57 if (node != nullptr) {
58 const NodeGeometryMeshCylinder &storage = node_storage(*node);
60 storage.fill_type);
61 fill.available(fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE);
62 }
63}
64
65static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
66{
67 layout->use_property_split_set(true);
68 layout->use_property_decorate_set(false);
69 layout->prop(ptr, "fill_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
70}
71
72static void node_init(bNodeTree * /*tree*/, bNode *node)
73{
75
77
78 node->storage = node_storage;
79}
80
82{
83 const NodeGeometryMeshCylinder &storage = node_storage(params.node());
85
86 const float radius = params.extract_input<float>("Radius");
87 const float depth = params.extract_input<float>("Depth");
88 const int circle_segments = params.extract_input<int>("Vertices");
89 if (circle_segments < 3) {
90 params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3"));
91 params.set_default_remaining_outputs();
92 return;
93 }
94
95 const int side_segments = params.extract_input<int>("Side Segments");
96 if (side_segments < 1) {
97 params.error_message_add(NodeWarningType::Info, TIP_("Side Segments must be at least 1"));
98 params.set_default_remaining_outputs();
99 return;
100 }
101
102 const bool no_fill = fill == GEO_NODE_MESH_CIRCLE_FILL_NONE;
103 const int fill_segments = no_fill ? 1 : params.extract_input<int>("Fill Segments");
104 if (fill_segments < 1) {
105 params.error_message_add(NodeWarningType::Info, TIP_("Fill Segments must be at least 1"));
106 params.set_default_remaining_outputs();
107 return;
108 }
109
110 geometry::ConeAttributeOutputs attribute_outputs;
111 attribute_outputs.top_id = params.get_output_anonymous_attribute_id_if_needed("Top");
112 attribute_outputs.bottom_id = params.get_output_anonymous_attribute_id_if_needed("Bottom");
113 attribute_outputs.side_id = params.get_output_anonymous_attribute_id_if_needed("Side");
114 attribute_outputs.uv_map_id = params.get_output_anonymous_attribute_id_if_needed("UV Map");
115
116 /* The cylinder is a special case of the cone mesh where the top and bottom radius are equal. */
118 radius,
119 depth,
120 circle_segments,
121 side_segments,
122 fill_segments,
124 attribute_outputs);
125 BKE_id_material_eval_ensure_default_slot(reinterpret_cast<ID *>(mesh));
126
127 params.set_output("Mesh", GeometrySet::from_mesh(mesh));
128}
129
130static void node_rna(StructRNA *srna)
131{
133 "fill_type",
134 "Fill Type",
135 "",
139 nullptr,
140 true);
141}
142
143static void node_register()
144{
145 static blender::bke::bNodeType ntype;
146 geo_node_type_base(&ntype, "GeometryNodeMeshCylinder", GEO_NODE_MESH_PRIMITIVE_CYLINDER);
147 ntype.ui_name = "Cylinder";
148 ntype.ui_description = "Generate a cylinder mesh";
149 ntype.enum_name_legacy = "MESH_PRIMITIVE_CYLINDER";
151 ntype.initfunc = node_init;
153 ntype, "NodeGeometryMeshCylinder", node_free_standard_storage, node_copy_standard_storage);
154 ntype.declare = node_declare;
158
159 node_rna(ntype.rna_ext.srna);
160}
162
163} // namespace blender::nodes::node_geo_mesh_primitive_cylinder_cc
General operations, lookup, etc. for materials.
void BKE_id_material_eval_ensure_default_slot(ID *id)
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_MESH_PRIMITIVE_CYLINDER
#define BLT_I18NCONTEXT_ID_NODETREE
#define TIP_(msgid)
GeometryNodeMeshCircleFillType
@ GEO_NODE_MESH_CIRCLE_FILL_NGON
@ GEO_NODE_MESH_CIRCLE_FILL_NONE
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_storage_enum_accessors(member)
@ PROP_DISTANCE
Definition RNA_types.hh:256
#define UI_ITEM_NONE
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
Mesh * create_cylinder_or_cone_mesh(float radius_top, float radius_bottom, float depth, int circle_segments, int side_segments, int fill_segments, ConeFillType fill_type, ConeAttributeOutputs &attribute_outputs)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
const EnumPropertyItem rna_enum_node_geometry_mesh_circle_fill_type_items[]
#define min(a, b)
Definition sort.cc:36
StructRNA * srna
Definition DNA_ID.h:414
void * storage
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:259
NodeDeclareFunction declare
Definition BKE_node.hh:362
static GeometrySet from_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void use_property_decorate_set(bool is_sep)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4238