diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/nodes/NOD_runtime_types.hh | 214 | ||||
-rw-r--r-- | source/blender/nodes/geometry/node_geometry_util.cc | 14 | ||||
-rw-r--r-- | source/blender/nodes/geometry/node_geometry_util.hh | 36 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc | 422 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_runtime_types.cc | 57 |
5 files changed, 259 insertions, 484 deletions
diff --git a/source/blender/nodes/NOD_runtime_types.hh b/source/blender/nodes/NOD_runtime_types.hh index 88764dbd171..6970906b7f9 100644 --- a/source/blender/nodes/NOD_runtime_types.hh +++ b/source/blender/nodes/NOD_runtime_types.hh @@ -47,79 +47,17 @@ extern "C" { #endif /** - * Can this node type be added to a node tree? - * \param r_disabled_hint: Optional hint to display in the UI when the poll fails. - * The callback can set this to a static string without having to - * null-check it (or without setting it to null if it's not used). - * The caller must pass a valid `const char **` and null-initialize it - * when it's not just a dummy, that is, if it actually wants to access - * the returned disabled-hint (null-check needed!). - */ -typedef bool (*NodePollCb)(bNodeType *ntype, bNodeTree *ntree, const char **r_disabled_hint); -/** Can this node be added to a node tree? - * \param r_disabled_hint: See `poll()`. - */ -typedef bool (*NodeInstancePollCb)(bNode *node, bNodeTree *ntree, const char **r_disabled_hint); -/** Initialize a new node instance of this type after creation. */ -typedef void (*NodeInitCb)(struct bNodeTree *ntree, struct bNode *node); -/** Free the node instance. */ -typedef void (*NodeFreeCb)(struct bNode *node); -/** Make a copy of the node instance. */ -typedef void (*NodeCopyCb)(struct bNodeTree *dest_ntree, - struct bNode *dest_node, - const struct bNode *src_node); -/* Called after a node socket has been linked. */ -typedef void (*NodeInsertLinkCb)(struct bNodeTree *ntree, - struct bNode *node, - struct bNodeLink *link); -/* Update the internal links list, for muting and disconnect operators. */ -typedef void (*NodeUpdateInternalLinksCb)(struct bNodeTree *, struct bNode *node); -/* Called when the node is updated in the editor. */ -typedef void (*NodeUpdateCb)(struct bNodeTree *ntree, struct bNode *node); -/* Check and update if internal ID data has changed. */ -typedef void (*NodeGroupUpdateCb)(struct bNodeTree *ntree, struct bNode *node); -/** - * Optional custom label function for the node header. - * \note Used as a fallback when #bNode.label isn't set. - */ -typedef void (*NodeLabelCb)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen); -/* Draw the option buttons on the node */ -typedef void (*NodeDrawButtonsCb)(struct uiLayout *layout, - struct bContext *C, - struct PointerRNA *ptr); -/* Additional parameters in the side panel */ -typedef void (*NodeDrawButtonsExCb)(struct uiLayout *layout, - struct bContext *C, - struct PointerRNA *ptr); -/* Additional drawing on backdrop */ -typedef void (*NodeDrawBackdropCb)( - struct SpaceNode *snode, struct ImBuf *backdrop, struct bNode *node, int x, int y); - -/** - * Define a full node type with all possible callbacks. + * Define a basic runtime node type. + * A custom RNA struct is declared for the type. * The node type is not registered here. */ -void node_make_runtime_type_ex(struct bNodeType *ntype, - const char *idname, - const char *ui_name, - const char *ui_description, - int ui_icon, - short node_class, - const StructRNA *rna_base, - NodePollCb poll_cb, - NodeInstancePollCb instance_poll_cb, - NodeInitCb init_cb, - NodeFreeCb free_cb, - NodeCopyCb copy_cb, - NodeInsertLinkCb insert_link_cb, - NodeUpdateInternalLinksCb update_internal_links_cb, - NodeUpdateCb update_cb, - NodeGroupUpdateCb group_update_cb, - NodeLabelCb label_cb, - NodeDrawButtonsCb draw_buttons_cb, - NodeDrawButtonsExCb draw_buttons_ex_cb, - NodeDrawBackdropCb draw_backdrop_cb, - eNodeSizePreset size_preset); +void node_make_runtime_type(struct bNodeType *ntype, + const char *idname, + const char *ui_name, + const char *ui_description, + int ui_icon, + short node_class, + const StructRNA *rna_base); /** * Free runtime type information of the node type. @@ -130,137 +68,3 @@ void node_free_runtime_type(struct bNodeType *ntype); #ifdef __cplusplus } #endif - -namespace blender::nodes { - -namespace detail { - -/** Utility macro expanding to a field of the node class. - * Used for consistency with more complex optional field macros below. - */ -#define DECL_NODE_FIELD_REQUIRED(FIELD_NAME) \ - template<typename T> static constexpr auto node_type_get__##FIELD_NAME() \ - { \ - return T::FIELD_NAME; \ - } -#define DECL_NODE_FUNC_REQUIRED(FUNC_NAME) \ - template<typename T> static constexpr auto node_type_get__##FUNC_NAME() \ - { \ - return &T::FUNC_NAME; \ - } - -/** - * Utility macro for selecting a static field from the node class, - * or a default value if the field is not defined. - * - * The int/long argument is used to prioritize the T::FIELD_NAME implementation - * if the field is defined: the 0 literal is preferably interpreted as int. - * Only if the field does not exist, i.e. decltype(T::FIELD_NAME) is invalid, - * will the default value implementation be used (SFINAE). - * - * TODO C++20 introduces "concepts" and the "requires" keyword, - * which are more elegant ways to handle missing fields on template arguments. - */ -#define DECL_NODE_FIELD_OPTIONAL(FIELD_NAME, DEFAULT_VALUE) \ - template<typename T> \ - static constexpr auto node_type_impl__##FIELD_NAME(int)->decltype(T::FIELD_NAME) \ - { \ - return T::FIELD_NAME; \ - } \ - template<typename T> \ - static constexpr auto node_type_impl__##FIELD_NAME(long)->decltype(DEFAULT_VALUE) \ - { \ - return DEFAULT_VALUE; \ - } \ - template<typename T> static constexpr auto node_type_get__##FIELD_NAME() \ - { \ - return node_type_impl__##FIELD_NAME<T>(0); \ - } -#define DECL_NODE_FUNC_OPTIONAL(FUNC_NAME) \ - template<typename T> \ - static constexpr auto node_type_impl__##FUNC_NAME(int)->decltype(&T::FUNC_NAME) \ - { \ - return &T::FUNC_NAME; \ - } \ - template<typename T> static constexpr auto node_type_impl__##FUNC_NAME(long)->decltype(nullptr) \ - { \ - return nullptr; \ - } \ - template<typename T> static constexpr auto node_type_get__##FUNC_NAME() \ - { \ - return node_type_impl__##FUNC_NAME<T>(0); \ - } - -/* Required and optional fields and callbacks expected in node type classes. */ -DECL_NODE_FIELD_REQUIRED(idname) -DECL_NODE_FIELD_REQUIRED(ui_name) -DECL_NODE_FIELD_OPTIONAL(ui_description, "") -DECL_NODE_FIELD_OPTIONAL(ui_icon, ICON_NONE) -DECL_NODE_FIELD_REQUIRED(node_class) -DECL_NODE_FIELD_OPTIONAL(rna_base, &RNA_Node) -DECL_NODE_FUNC_OPTIONAL(poll) -DECL_NODE_FUNC_OPTIONAL(instance_poll) -DECL_NODE_FUNC_OPTIONAL(init) -DECL_NODE_FUNC_OPTIONAL(free) -DECL_NODE_FUNC_OPTIONAL(copy) -DECL_NODE_FUNC_OPTIONAL(insert_link) -DECL_NODE_FUNC_OPTIONAL(update_internal_links) -DECL_NODE_FUNC_OPTIONAL(update) -DECL_NODE_FUNC_OPTIONAL(group_update) -DECL_NODE_FUNC_OPTIONAL(label) -DECL_NODE_FUNC_OPTIONAL(draw_buttons) -DECL_NODE_FUNC_OPTIONAL(draw_buttons_ex) -DECL_NODE_FUNC_OPTIONAL(draw_backdrop) -DECL_NODE_FIELD_OPTIONAL(size_preset, NODE_SIZE_DEFAULT) - -DECL_NODE_FUNC_OPTIONAL(define_rna) - -} // namespace detail - -/* Template for runtime node definition. */ -template<typename T> struct NodeDefinition { - inline static bNodeType typeinfo_; - - /* Registers a node type using static fields and callbacks of the template argument. */ - static void register_type() - { - ::node_make_runtime_type_ex(&typeinfo_, - detail::node_type_get__idname<T>(), - detail::node_type_get__ui_name<T>(), - detail::node_type_get__ui_description<T>(), - detail::node_type_get__ui_icon<T>(), - detail::node_type_get__node_class<T>(), - detail::node_type_get__rna_base<T>(), - detail::node_type_get__poll<T>(), - detail::node_type_get__instance_poll<T>(), - detail::node_type_get__init<T>(), - detail::node_type_get__free<T>(), - detail::node_type_get__copy<T>(), - detail::node_type_get__insert_link<T>(), - detail::node_type_get__update_internal_links<T>(), - detail::node_type_get__update<T>(), - detail::node_type_get__group_update<T>(), - detail::node_type_get__label<T>(), - detail::node_type_get__draw_buttons<T>(), - detail::node_type_get__draw_buttons_ex<T>(), - detail::node_type_get__draw_backdrop<T>(), - detail::node_type_get__size_preset<T>()); - - /* Call optional RNA setup function for the type. */ - if (void (*define_rna_cb)(struct StructRNA *) = detail::node_type_get__define_rna<T>()) { - define_rna_cb(typeinfo_.rna_ext.srna); - } - - nodeRegisterType(&typeinfo_); - } - - static void unregister_type() - { - ::node_free_runtime_type(&typeinfo_); - - nodeUnregisterType(&typeinfo_); - }; - -}; - -} // namespace blender::nodes diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc index 46e9d36c09c..81946a93fda 100644 --- a/source/blender/nodes/geometry/node_geometry_util.cc +++ b/source/blender/nodes/geometry/node_geometry_util.cc @@ -28,6 +28,20 @@ namespace blender::nodes { using bke::GeometryInstanceGroup; +void geometry_node_make_runtime_type(bNodeType *ntype, + const char *idname, + const char *ui_name, + const char *ui_description, + int ui_icon, + short node_class, + const StructRNA *rna_base) +{ + node_make_runtime_type(ntype, idname, ui_name, ui_description, ui_icon, node_class, rna_base); + + /* Default poll function for geometry nodes. */ + ntype->poll = geo_node_poll_default; +} + /** * Update the availability of a group of input sockets with the same name, * used for switching between attribute inputs or single values. diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index e7d9d9639bd..85716fb0c4f 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -45,35 +45,13 @@ bool geo_node_poll_default(struct bNodeType *ntype, namespace blender::nodes { -namespace detail { -DECL_NODE_FUNC_OPTIONAL(build_multi_function) -DECL_NODE_FUNC_OPTIONAL(geometry_node_execute) -DECL_NODE_FIELD_OPTIONAL(geometry_node_execute_supports_laziness, false); -} // namespace detail - -template<typename T> struct GeometryNodeDefinition : public NodeDefinition<T> { - static const int ui_icon = ICON_NONE; - static const short node_class = NODE_CLASS_GEOMETRY; - inline static const StructRNA *rna_base = &RNA_GeometryNode; - - static bool poll(bNodeType *ntype, bNodeTree *ntree, const char **r_disabled_hint) - { - return geo_node_poll_default(ntype, ntree, r_disabled_hint); - } - - /* Registers a node type using static fields and callbacks of the template argument. */ - static void register_type() - { - NodeDefinition<T>::typeinfo_.build_multi_function = - detail::node_type_get__build_multi_function<T>(); - NodeDefinition<T>::typeinfo_.geometry_node_execute = - detail::node_type_get__geometry_node_execute<T>(); - NodeDefinition<T>::typeinfo_.geometry_node_execute_supports_laziness = - detail::node_type_get__geometry_node_execute_supports_laziness<T>(); - - NodeDefinition<T>::register_type(); - } -}; +void geometry_node_make_runtime_type(struct bNodeType *ntype, + const char *idname, + const char *ui_name, + const char *ui_description, + int ui_icon, + short node_class, + const StructRNA *rna_base); void update_attribute_input_socket_availabilities(bNode &node, const StringRef name, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc index 1d69b92a220..c685a039d7a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc @@ -31,248 +31,256 @@ namespace blender::nodes { -struct GeometryNodeMeshEllipse : public GeometryNodeDefinition<GeometryNodeMeshEllipse> { - inline static const char *idname = "GeometryNodeMeshEllipse"; - inline static const char *ui_name = "Mesh Ellipse"; - inline static const char *ui_description = "Create an elliptical shape"; - - enum FillType { - FILL_NONE = 0, - FILL_NGON = 1, - FILL_TRIANGLE_FAN = 2, - }; +enum FillType { + FILL_NONE = 0, + FILL_NGON = 1, + FILL_TRIANGLE_FAN = 2, +}; + +static void node_init(bNodeTree *ntree, bNode *node) +{ + PointerRNA ptr; + RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + + RNA_enum_set(&ptr, "fill_type", FILL_NONE); - static void define_rna(StructRNA *srna) { - static EnumPropertyItem fill_type_items[] = { - {FILL_NONE, "NONE", 0, "None", ""}, - {FILL_NGON, "NGON", 0, "N-Gon", ""}, - {FILL_TRIANGLE_FAN, "TRIANGLE_FAN", 0, "Triangles", ""}, - {0, NULL, 0, NULL, NULL}, - }; - - RNA_def_enum(srna, "fill_type", fill_type_items, FILL_NONE, "Fill Type", ""); + bNodeSocketValueInt *dval = (bNodeSocketValueInt *)nodeAddSocket( + ntree, node, SOCK_IN, "NodeSocketInt", "Vertices", "Vertices") + ->default_value; + dval->value = 32; + dval->min = 3; + dval->max = 4096; } - - static void init(bNodeTree *ntree, bNode *node) { - PointerRNA ptr; - RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); - - RNA_enum_set(&ptr, "fill_type", FILL_NONE); - - { - bNodeSocketValueInt *dval = - (bNodeSocketValueInt *)nodeAddSocket( - ntree, node, SOCK_IN, "NodeSocketInt", "Vertices", "Vertices") - ->default_value; - dval->value = 32; - dval->min = 3; - dval->max = 4096; - } - { - bNodeSocketValueFloat *dval = - (bNodeSocketValueFloat *)nodeAddSocket( - ntree, node, SOCK_IN, "NodeSocketFloat", "Radius A", "Radius A") - ->default_value; - dval->value = 1.0f; - dval->min = 0.0f; - dval->max = FLT_MAX; - dval->subtype = PROP_DISTANCE; - } - { - bNodeSocketValueFloat *dval = - (bNodeSocketValueFloat *)nodeAddSocket( - ntree, node, SOCK_IN, "NodeSocketFloat", "Radius B", "Radius B") - ->default_value; - dval->value = 1.0f; - dval->min = 0.0f; - dval->max = FLT_MAX; - dval->subtype = PROP_DISTANCE; - } - - nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketGeometry", "Geometry", "Geometry"); + bNodeSocketValueFloat *dval = + (bNodeSocketValueFloat *)nodeAddSocket( + ntree, node, SOCK_IN, "NodeSocketFloat", "Radius A", "Radius A") + ->default_value; + dval->value = 1.0f; + dval->min = 0.0f; + dval->max = FLT_MAX; + dval->subtype = PROP_DISTANCE; } - - static void draw_buttons(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { - uiLayoutSetPropSep(layout, true); - uiLayoutSetPropDecorate(layout, false); - uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE); + bNodeSocketValueFloat *dval = + (bNodeSocketValueFloat *)nodeAddSocket( + ntree, node, SOCK_IN, "NodeSocketFloat", "Radius B", "Radius B") + ->default_value; + dval->value = 1.0f; + dval->min = 0.0f; + dval->max = FLT_MAX; + dval->subtype = PROP_DISTANCE; } - static int circle_vert_total(const FillType fill_type, const int verts_num) - { - switch (fill_type) { - case GEO_NODE_MESH_CIRCLE_FILL_NONE: - case GEO_NODE_MESH_CIRCLE_FILL_NGON: - return verts_num; - case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: - return verts_num + 1; - } - BLI_assert_unreachable(); - return 0; + nodeAddSocket(ntree, node, SOCK_OUT, "NodeSocketGeometry", "Geometry", "Geometry"); +} + +static void node_draw_buttons(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE); +} + +static int circle_vert_total(const FillType fill_type, const int verts_num) +{ + switch (fill_type) { + case GEO_NODE_MESH_CIRCLE_FILL_NONE: + case GEO_NODE_MESH_CIRCLE_FILL_NGON: + return verts_num; + case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: + return verts_num + 1; } + BLI_assert_unreachable(); + return 0; +} - static int circle_edge_total(const FillType fill_type, const int verts_num) - { - switch (fill_type) { - case GEO_NODE_MESH_CIRCLE_FILL_NONE: - case GEO_NODE_MESH_CIRCLE_FILL_NGON: - return verts_num; - case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: - return verts_num * 2; - } - BLI_assert_unreachable(); - return 0; +static int circle_edge_total(const FillType fill_type, const int verts_num) +{ + switch (fill_type) { + case GEO_NODE_MESH_CIRCLE_FILL_NONE: + case GEO_NODE_MESH_CIRCLE_FILL_NGON: + return verts_num; + case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: + return verts_num * 2; } + BLI_assert_unreachable(); + return 0; +} - static int circle_corner_total(const FillType fill_type, const int verts_num) - { - switch (fill_type) { - case GEO_NODE_MESH_CIRCLE_FILL_NONE: - return 0; - case GEO_NODE_MESH_CIRCLE_FILL_NGON: - return verts_num; - case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: - return verts_num * 3; - } - BLI_assert_unreachable(); - return 0; +static int circle_corner_total(const FillType fill_type, const int verts_num) +{ + switch (fill_type) { + case GEO_NODE_MESH_CIRCLE_FILL_NONE: + return 0; + case GEO_NODE_MESH_CIRCLE_FILL_NGON: + return verts_num; + case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: + return verts_num * 3; } + BLI_assert_unreachable(); + return 0; +} - static int circle_face_total(const FillType fill_type, const int verts_num) - { - switch (fill_type) { - case GEO_NODE_MESH_CIRCLE_FILL_NONE: - return 0; - case GEO_NODE_MESH_CIRCLE_FILL_NGON: - return 1; - case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: - return verts_num; - } - BLI_assert_unreachable(); - return 0; +static int circle_face_total(const FillType fill_type, const int verts_num) +{ + switch (fill_type) { + case GEO_NODE_MESH_CIRCLE_FILL_NONE: + return 0; + case GEO_NODE_MESH_CIRCLE_FILL_NGON: + return 1; + case GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN: + return verts_num; } + BLI_assert_unreachable(); + return 0; +} - static Mesh *create_ellipse_mesh(const float radius_a, - const float radius_b, - const int verts_num, - const FillType fill_type) - { - Mesh *mesh = BKE_mesh_new_nomain(circle_vert_total(fill_type, verts_num), - circle_edge_total(fill_type, verts_num), - 0, - circle_corner_total(fill_type, verts_num), - circle_face_total(fill_type, verts_num)); - BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; - - /* Assign vertex coordinates. */ - const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num)); - for (const int i : IndexRange(verts_num)) { - const float angle = i * angle_delta; - copy_v3_v3(verts[i].co, - float3(std::cos(angle) * radius_a, std::sin(angle) * radius_b, 0.0f)); - } - if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { - copy_v3_v3(verts.last().co, float3(0)); - } +static Mesh *create_ellipse_mesh(const float radius_a, + const float radius_b, + const int verts_num, + const FillType fill_type) +{ + Mesh *mesh = BKE_mesh_new_nomain(circle_vert_total(fill_type, verts_num), + circle_edge_total(fill_type, verts_num), + 0, + circle_corner_total(fill_type, verts_num), + circle_face_total(fill_type, verts_num)); + BKE_id_material_eval_ensure_default_slot(&mesh->id); + MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; + MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; + MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; + MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + + /* Assign vertex coordinates. */ + const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num)); + for (const int i : IndexRange(verts_num)) { + const float angle = i * angle_delta; + copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius_a, std::sin(angle) * radius_b, 0.0f)); + } + if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { + copy_v3_v3(verts.last().co, float3(0)); + } - /* Point all vertex normals in the up direction. */ - const short up_normal[3] = {0, 0, SHRT_MAX}; - for (MVert &vert : verts) { - copy_v3_v3_short(vert.no, up_normal); - } + /* Point all vertex normals in the up direction. */ + const short up_normal[3] = {0, 0, SHRT_MAX}; + for (MVert &vert : verts) { + copy_v3_v3_short(vert.no, up_normal); + } + + /* Create outer edges. */ + for (const int i : IndexRange(verts_num)) { + MEdge &edge = edges[i]; + edge.v1 = i; + edge.v2 = (i + 1) % verts_num; + } - /* Create outer edges. */ + /* Set loose edge flags. */ + if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) { for (const int i : IndexRange(verts_num)) { MEdge &edge = edges[i]; - edge.v1 = i; - edge.v2 = (i + 1) % verts_num; + edge.flag |= ME_LOOSEEDGE; } + } - /* Set loose edge flags. */ - if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) { - for (const int i : IndexRange(verts_num)) { - MEdge &edge = edges[i]; - edge.flag |= ME_LOOSEEDGE; - } + /* Create triangle fan edges. */ + if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { + for (const int i : IndexRange(verts_num)) { + MEdge &edge = edges[verts_num + i]; + edge.v1 = verts_num; + edge.v2 = i; + edge.flag = ME_EDGEDRAW | ME_EDGERENDER; } + } - /* Create triangle fan edges. */ - if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { - for (const int i : IndexRange(verts_num)) { - MEdge &edge = edges[verts_num + i]; - edge.v1 = verts_num; - edge.v2 = i; - edge.flag = ME_EDGEDRAW | ME_EDGERENDER; - } - } + /* Create corners and faces. */ + if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { + MPoly &poly = polys[0]; + poly.loopstart = 0; + poly.totloop = loops.size(); - /* Create corners and faces. */ - if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) { - MPoly &poly = polys[0]; - poly.loopstart = 0; - poly.totloop = loops.size(); - - for (const int i : IndexRange(verts_num)) { - MLoop &loop = loops[i]; - loop.e = i; - loop.v = i; - } + for (const int i : IndexRange(verts_num)) { + MLoop &loop = loops[i]; + loop.e = i; + loop.v = i; } - else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { - for (const int i : IndexRange(verts_num)) { - MPoly &poly = polys[i]; - poly.loopstart = 3 * i; - poly.totloop = 3; - - MLoop &loop_a = loops[3 * i]; - loop_a.e = i; - loop_a.v = i; - MLoop &loop_b = loops[3 * i + 1]; - loop_b.e = verts_num + ((i + 1) % verts_num); - loop_b.v = (i + 1) % verts_num; - MLoop &loop_c = loops[3 * i + 2]; - loop_c.e = verts_num + i; - loop_c.v = verts_num; - } + } + else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { + for (const int i : IndexRange(verts_num)) { + MPoly &poly = polys[i]; + poly.loopstart = 3 * i; + poly.totloop = 3; + + MLoop &loop_a = loops[3 * i]; + loop_a.e = i; + loop_a.v = i; + MLoop &loop_b = loops[3 * i + 1]; + loop_b.e = verts_num + ((i + 1) % verts_num); + loop_b.v = (i + 1) % verts_num; + MLoop &loop_c = loops[3 * i + 2]; + loop_c.e = verts_num + i; + loop_c.v = verts_num; } - - return mesh; } - static void geometry_node_execute(GeoNodeExecParams params) - { - PointerRNA ptr; - RNA_pointer_create((ID *)¶ms.node_tree(), &RNA_Node, (void *)¶ms.node(), &ptr); - - const FillType fill_type = (FillType)RNA_enum_get(&ptr, "fill_type"); - - const float radius_a = params.extract_input<float>("Radius A"); - const float radius_b = params.extract_input<float>("Radius B"); - const int verts_num = params.extract_input<int>("Vertices"); - if (verts_num < 3) { - params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3")); - params.set_output("Geometry", GeometrySet()); - return; - } + return mesh; +} - Mesh *mesh = create_ellipse_mesh(radius_a, radius_b, verts_num, fill_type); +static void geometry_node_execute(GeoNodeExecParams params) +{ + PointerRNA ptr; + RNA_pointer_create((ID *)¶ms.node_tree(), &RNA_Node, (void *)¶ms.node(), &ptr); + + const FillType fill_type = (FillType)RNA_enum_get(&ptr, "fill_type"); + + const float radius_a = params.extract_input<float>("Radius A"); + const float radius_b = params.extract_input<float>("Radius B"); + const int verts_num = params.extract_input<int>("Vertices"); + if (verts_num < 3) { + params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3")); + params.set_output("Geometry", GeometrySet()); + return; + } - BLI_assert(BKE_mesh_is_valid(mesh)); + Mesh *mesh = create_ellipse_mesh(radius_a, radius_b, verts_num, fill_type); - params.set_output("Geometry", GeometrySet::create_with_mesh(mesh)); - } -}; + BLI_assert(BKE_mesh_is_valid(mesh)); + + params.set_output("Geometry", GeometrySet::create_with_mesh(mesh)); +} } // namespace blender::nodes void register_node_type_geo_mesh_primitive_ellipse() { - blender::nodes::GeometryNodeMeshEllipse::register_type(); + static bNodeType ntype; + + node_make_runtime_type(&ntype, + "GeometryNodeMeshEllipse", + "Mesh Ellipse", + "Create an elliptical shape", + ICON_NONE, + NODE_CLASS_GEOMETRY, + &RNA_GeometryNode); + node_type_init(&ntype, blender::nodes::node_init); + ntype.geometry_node_execute = blender::nodes::geometry_node_execute; + ntype.draw_buttons = blender::nodes::node_draw_buttons; + + static EnumPropertyItem fill_type_items[] = { + {blender::nodes::FILL_NONE, "NONE", 0, "None", ""}, + {blender::nodes::FILL_NGON, "NGON", 0, "N-Gon", ""}, + {blender::nodes::FILL_TRIANGLE_FAN, "TRIANGLE_FAN", 0, "Triangles", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + StructRNA *srna = ntype.rna_ext.srna; + RNA_def_enum(srna, + "fill_type", + fill_type_items, + blender::nodes::FILL_NONE, + "Fill Type", + ""); + + nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/intern/node_runtime_types.cc b/source/blender/nodes/intern/node_runtime_types.cc index aca94221573..f90f3ed9cdc 100644 --- a/source/blender/nodes/intern/node_runtime_types.cc +++ b/source/blender/nodes/intern/node_runtime_types.cc @@ -44,27 +44,13 @@ static bool custom_node_poll_instance(bNode *node, return node->typeinfo->poll(node->typeinfo, nodetree, r_disabled_hint); } -void node_make_runtime_type_ex(bNodeType *ntype, - const char *idname, - const char *ui_name, - const char *ui_description, - int ui_icon, - short node_class, - const StructRNA *rna_base, - NodePollCb poll_cb, - NodeInstancePollCb instance_poll_cb, - NodeInitCb init_cb, - NodeFreeCb free_cb, - NodeCopyCb copy_cb, - NodeInsertLinkCb insert_link_cb, - NodeUpdateInternalLinksCb update_internal_links_cb, - NodeUpdateCb update_cb, - NodeGroupUpdateCb group_update_cb, - NodeLabelCb label_cb, - NodeDrawButtonsCb draw_buttons_cb, - NodeDrawButtonsExCb draw_buttons_ex_cb, - NodeDrawBackdropCb draw_backdrop_cb, - eNodeSizePreset size_preset) +void node_make_runtime_type(bNodeType *ntype, + const char *idname, + const char *ui_name, + const char *ui_description, + int ui_icon, + short node_class, + const StructRNA *rna_base) { const short node_flags = 0; @@ -80,25 +66,14 @@ void node_make_runtime_type_ex(bNodeType *ntype, RNA_def_struct_ui_text(ntype->rna_ext.srna, ntype->ui_name, ntype->ui_description); RNA_def_struct_ui_icon(ntype->rna_ext.srna, ntype->ui_icon); - /* BKE callbacks. */ - ntype->poll = poll_cb ? poll_cb : custom_node_poll_default; - ntype->poll_instance = instance_poll_cb ? instance_poll_cb : custom_node_poll_instance; - ntype->initfunc = init_cb ? init_cb : nullptr; - ntype->copyfunc = copy_cb ? copy_cb : nullptr; - ntype->freefunc = free_cb ? free_cb : nullptr; - ntype->insert_link = insert_link_cb ? insert_link_cb : node_insert_link_default; - ntype->update_internal_links = update_internal_links_cb ? update_internal_links_cb : - node_update_internal_links_default; - ntype->updatefunc = update_cb ? update_cb : nullptr; - ntype->group_update_func = group_update_cb ? group_update_cb : nullptr; - - /* UI callbacks. */ + /* Default BKE callbacks. */ + ntype->poll = custom_node_poll_default; + ntype->poll_instance = custom_node_poll_instance; + ntype->insert_link = node_insert_link_default; + ntype->update_internal_links = node_update_internal_links_default; + + /* Default UI callbacks. */ ED_init_custom_node_type(ntype); - ntype->labelfunc = label_cb ? label_cb : nullptr; - ntype->draw_buttons = draw_buttons_cb ? draw_buttons_cb : nullptr; - ntype->draw_buttons_ex = draw_buttons_ex_cb ? draw_buttons_ex_cb : nullptr; - ntype->draw_backdrop = draw_backdrop_cb ? draw_backdrop_cb : nullptr; - node_type_size_preset(ntype, size_preset); } void node_free_runtime_type(bNodeType *ntype) @@ -110,7 +85,3 @@ void node_free_runtime_type(bNodeType *ntype) RNA_struct_free_extension(ntype->rna_ext.srna, &ntype->rna_ext); RNA_struct_free(&BLENDER_RNA, ntype->rna_ext.srna); } - -namespace blender::nodes { - -} // namespace blender::nodes |