Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2021-08-26 11:59:10 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2021-08-26 11:59:10 +0300
commit7ff375b21277272cc215d488038e7af7c1a70839 (patch)
tree792afd97e9941d211820041f9f2f3b3d59615756
parentdf05fae12695d00a092bdb694786310bface6cbe (diff)
Simplified runtime node type definition.temp-runtime-node-def
-rw-r--r--source/blender/nodes/NOD_runtime_types.hh214
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc14
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ellipse.cc422
-rw-r--r--source/blender/nodes/intern/node_runtime_types.cc57
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 *)&params.node_tree(), &RNA_Node, (void *)&params.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 *)&params.node_tree(), &RNA_Node, (void *)&params.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