Compare commits
4 Commits
temp-compo
...
temp-runti
Author | SHA1 | Date | |
---|---|---|---|
7ff375b212 | |||
df05fae126 | |||
4793154d0d | |||
4af555a031 |
@@ -560,6 +560,7 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeMeshCone"),
|
||||
NodeItem("GeometryNodeMeshCube"),
|
||||
NodeItem("GeometryNodeMeshCylinder"),
|
||||
NodeItem("GeometryNodeMeshEllipse"),
|
||||
NodeItem("GeometryNodeMeshGrid"),
|
||||
NodeItem("GeometryNodeMeshIcoSphere"),
|
||||
NodeItem("GeometryNodeMeshLine"),
|
||||
|
@@ -5165,6 +5165,7 @@ static void registerGeometryNodes()
|
||||
register_node_type_geo_mesh_primitive_cone();
|
||||
register_node_type_geo_mesh_primitive_cube();
|
||||
register_node_type_geo_mesh_primitive_cylinder();
|
||||
register_node_type_geo_mesh_primitive_ellipse();
|
||||
register_node_type_geo_mesh_primitive_grid();
|
||||
register_node_type_geo_mesh_primitive_ico_sphere();
|
||||
register_node_type_geo_mesh_primitive_line();
|
||||
|
@@ -193,6 +193,7 @@ set(SRC
|
||||
geometry/nodes/node_geo_mesh_primitive_cone.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_cube.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_cylinder.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_ellipse.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_grid.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
|
||||
geometry/nodes/node_geo_mesh_primitive_line.cc
|
||||
@@ -346,6 +347,7 @@ set(SRC
|
||||
intern/node_exec.cc
|
||||
intern/node_geometry_exec.cc
|
||||
intern/node_multi_function.cc
|
||||
intern/node_runtime_types.cc
|
||||
intern/node_socket.cc
|
||||
intern/node_tree_ref.cc
|
||||
intern/node_util.c
|
||||
@@ -367,6 +369,7 @@ set(SRC
|
||||
NOD_math_functions.hh
|
||||
NOD_multi_function.hh
|
||||
NOD_node_tree_ref.hh
|
||||
NOD_runtime_types.hh
|
||||
NOD_shader.h
|
||||
NOD_socket.h
|
||||
NOD_static_types.h
|
||||
|
@@ -79,6 +79,7 @@ void register_node_type_geo_mesh_primitive_circle(void);
|
||||
void register_node_type_geo_mesh_primitive_cone(void);
|
||||
void register_node_type_geo_mesh_primitive_cube(void);
|
||||
void register_node_type_geo_mesh_primitive_cylinder(void);
|
||||
void register_node_type_geo_mesh_primitive_ellipse(void);
|
||||
void register_node_type_geo_mesh_primitive_grid(void);
|
||||
void register_node_type_geo_mesh_primitive_ico_sphere(void);
|
||||
void register_node_type_geo_mesh_primitive_line(void);
|
||||
|
@@ -239,6 +239,14 @@ class GeoNodeExecParams {
|
||||
return *provider_->dnode->bnode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node tree containing the executed node.
|
||||
*/
|
||||
const bNodeTree &node_tree() const
|
||||
{
|
||||
return *provider_->dnode->btree();
|
||||
}
|
||||
|
||||
const Object *self_object() const
|
||||
{
|
||||
return provider_->self_object;
|
||||
|
70
source/blender/nodes/NOD_runtime_types.hh
Normal file
70
source/blender/nodes/NOD_runtime_types.hh
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup nodes
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "BKE_node.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
/** \file
|
||||
* \ingroup fn
|
||||
*
|
||||
* Utility functions for registering node types at runtime.
|
||||
*
|
||||
* Defining nodes here does not require compile-time DNA (makesdna) or RNA (makesrna).
|
||||
* Nodes can use ID properties and runtime RNA definition.
|
||||
*
|
||||
* Node types can be registered using a C++ class with static fields and functions.
|
||||
* Functions are plain C callbacks, not actual class methods.
|
||||
* The register function detects missing optional fields and falls back on default values.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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(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.
|
||||
* The node type is not unregistered here.
|
||||
*/
|
||||
void node_free_runtime_type(struct bNodeType *ntype);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -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.
|
||||
|
@@ -31,6 +31,9 @@
|
||||
|
||||
#include "NOD_geometry.h"
|
||||
#include "NOD_geometry_exec.hh"
|
||||
#include "NOD_runtime_types.hh"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "node_util.h"
|
||||
|
||||
@@ -41,6 +44,15 @@ bool geo_node_poll_default(struct bNodeType *ntype,
|
||||
const char **r_disabled_hint);
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
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,
|
||||
const GeometryNodeAttributeInputMode mode,
|
||||
|
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "NOD_runtime_types.hh"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
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);
|
||||
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
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_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 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);
|
||||
}
|
||||
|
||||
/* Create outer edges. */
|
||||
for (const int i : IndexRange(verts_num)) {
|
||||
MEdge &edge = edges[i];
|
||||
edge.v1 = i;
|
||||
edge.v2 = (i + 1) % verts_num;
|
||||
}
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
Mesh *mesh = create_ellipse_mesh(radius_a, radius_b, verts_num, fill_type);
|
||||
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
87
source/blender/nodes/intern/node_runtime_types.cc
Normal file
87
source/blender/nodes/intern/node_runtime_types.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup nodes
|
||||
*/
|
||||
|
||||
#include "NOD_runtime_types.hh"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "ED_node.h"
|
||||
|
||||
#include "node_util.h"
|
||||
|
||||
static bool custom_node_poll_default(bNodeType *UNUSED(ntype),
|
||||
bNodeTree *UNUSED(ntree),
|
||||
const char **UNUSED(disabled_hint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool custom_node_poll_instance(bNode *node,
|
||||
bNodeTree *nodetree,
|
||||
const char **r_disabled_hint)
|
||||
{
|
||||
return node->typeinfo->poll(node->typeinfo, nodetree, r_disabled_hint);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Basic type setup. */
|
||||
node_type_base_custom(ntype, idname, ui_name, node_class, node_flags);
|
||||
BLI_strncpy(ntype->ui_description, ui_description, sizeof(ntype->ui_description));
|
||||
ntype->ui_icon = ui_icon;
|
||||
|
||||
/* RNA runtime type declaration. */
|
||||
ntype->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, idname, (StructRNA *)rna_base);
|
||||
RNA_struct_blender_type_set(ntype->rna_ext.srna, 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void node_free_runtime_type(bNodeType *ntype)
|
||||
{
|
||||
if (!ntype) {
|
||||
return;
|
||||
}
|
||||
|
||||
RNA_struct_free_extension(ntype->rna_ext.srna, &ntype->rna_ext);
|
||||
RNA_struct_free(&BLENDER_RNA, ntype->rna_ext.srna);
|
||||
}
|
Reference in New Issue
Block a user