Nodes: unify static and dynamic declarations #113742
|
@ -362,17 +362,22 @@ typedef struct bNodeType {
|
|||
/* Execute a geometry node. */
|
||||
NodeGeometryExecFunction geometry_node_execute;
|
||||
|
||||
/* Declares which sockets the node has. */
|
||||
NodeDeclareFunction declare;
|
||||
/**
|
||||
* Declare which sockets the node has for declarations that aren't static per node type.
|
||||
* In other words, defining this callback means that different nodes of this type can have
|
||||
* different declarations and different sockets.
|
||||
* Declares which sockets and panels the node has. It has to be able to generate a declaration
|
||||
* with and without a specific node context. If the declaration depends on the node, but the node
|
||||
* is not provided, then the declaration should be generated as much as possible and everything
|
||||
* that depends on the node context should be skipped.
|
||||
*/
|
||||
NodeDeclareDynamicFunction declare_dynamic;
|
||||
NodeDeclareFunction declare;
|
||||
|
||||
/* Declaration to be used when it is not dynamic. */
|
||||
NodeDeclarationHandle *fixed_declaration;
|
||||
/**
|
||||
* Declaration of the node outside of any context. If the node declaration is never dependent on
|
||||
* the node context, this declaration is also shared with the corresponding node instances.
|
||||
* Otherwise, it mainly allows checking what sockets a node will have, without having to create
|
||||
* the node. In this case, the static declaration is mostly just a hint, and does not have to
|
||||
* match with the final node.
|
||||
*/
|
||||
NodeDeclarationHandle *static_declaration;
|
||||
|
||||
/**
|
||||
* Add to the list of search names and operations gathered by node link drag searching.
|
||||
|
|
|
@ -1153,7 +1153,7 @@ namespace blender::bke {
|
|||
|
||||
static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype)
|
||||
{
|
||||
if (ntype->declare || ntype->declare_dynamic) {
|
||||
if (ntype->declare) {
|
||||
node_verify_sockets(ntree, node, true);
|
||||
return;
|
||||
}
|
||||
|
@ -1455,8 +1455,8 @@ static void node_free_type(void *nodetype_v)
|
|||
* or we'd want to update *all* active Mains, which we cannot do anyway currently. */
|
||||
blender::bke::update_typeinfo(G_MAIN, nullptr, nullptr, nodetype, nullptr, true);
|
||||
|
||||
delete nodetype->fixed_declaration;
|
||||
nodetype->fixed_declaration = nullptr;
|
||||
delete nodetype->static_declaration;
|
||||
nodetype->static_declaration = nullptr;
|
||||
|
||||
/* Can be null when the type is not dynamically allocated. */
|
||||
if (nodetype->free_self) {
|
||||
|
@ -1470,11 +1470,9 @@ void nodeRegisterType(bNodeType *nt)
|
|||
BLI_assert(nt->idname[0] != '\0');
|
||||
BLI_assert(nt->poll != nullptr);
|
||||
|
||||
if (nt->declare && !nt->declare_dynamic) {
|
||||
if (nt->fixed_declaration == nullptr) {
|
||||
nt->fixed_declaration = new blender::nodes::NodeDeclaration();
|
||||
blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration);
|
||||
}
|
||||
if (nt->declare) {
|
||||
nt->static_declaration = new blender::nodes::NodeDeclaration();
|
||||
blender::nodes::build_node_declaration(*nt, *nt->static_declaration, nullptr, nullptr);
|
||||
}
|
||||
|
||||
BLI_ghash_insert(blender::bke::nodetypes_hash, nt->idname, nt);
|
||||
|
@ -3268,8 +3266,12 @@ void node_free_node(bNodeTree *ntree, bNode *node)
|
|||
MEM_freeN(node->prop);
|
||||
}
|
||||
|
||||
if (node->typeinfo->declare_dynamic) {
|
||||
delete node->runtime->declaration;
|
||||
if (node->runtime->declaration) {
|
||||
/* Only free if this declaration is not shared with the node type, which can happen if it does
|
||||
* not depend on any context. */
|
||||
if (node->runtime->declaration != node->typeinfo->static_declaration) {
|
||||
delete node->runtime->declaration;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_delete(node->runtime);
|
||||
|
@ -3734,18 +3736,20 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
|
|||
if (node->runtime->declaration != nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (node->typeinfo->declare_dynamic) {
|
||||
if (node->typeinfo->declare) {
|
||||
if (node->typeinfo->static_declaration) {
|
||||
if (!node->typeinfo->static_declaration->is_context_dependent) {
|
||||
node->runtime->declaration = node->typeinfo->static_declaration;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node->typeinfo->declare) {
|
||||
BLI_assert(ntree != nullptr);
|
||||
BLI_assert(node != nullptr);
|
||||
blender::nodes::update_node_declaration_and_sockets(*ntree, *node);
|
||||
return true;
|
||||
}
|
||||
if (node->typeinfo->declare) {
|
||||
/* Declaration should have been created in #nodeRegisterType. */
|
||||
BLI_assert(node->typeinfo->fixed_declaration != nullptr);
|
||||
node->runtime->declaration = node->typeinfo->fixed_declaration;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -563,8 +563,12 @@ class NodeTreeMainUpdater {
|
|||
if (ntype.updatefunc) {
|
||||
ntype.updatefunc(&ntree, node);
|
||||
}
|
||||
if (ntype.declare_dynamic) {
|
||||
nodes::update_node_declaration_and_sockets(ntree, *node);
|
||||
if (ntype.declare) {
|
||||
/* Should have been created when the node was registered. */
|
||||
BLI_assert(ntype.static_declaration != nullptr);
|
||||
if (ntype.static_declaration->is_context_dependent) {
|
||||
nodes::update_node_declaration_and_sockets(ntree, *node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -364,7 +364,7 @@ static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
|
|||
using namespace blender::nodes;
|
||||
|
||||
r_node_decl.emplace(NodeDeclaration());
|
||||
blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl);
|
||||
blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl, nullptr, nullptr);
|
||||
Span<SocketDeclaration *> socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs :
|
||||
r_node_decl->outputs;
|
||||
int index = 0;
|
||||
|
|
|
@ -30,9 +30,7 @@ struct bNodeSocket *node_group_output_find_socket(struct bNode *node, const char
|
|||
|
||||
namespace blender::nodes {
|
||||
|
||||
void node_group_declare_dynamic(const bNodeTree &node_tree,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b);
|
||||
void node_group_declare(NodeDeclarationBuilder &b);
|
||||
|
||||
} // namespace blender::nodes
|
||||
|
||||
|
|
|
@ -469,6 +469,11 @@ class NodeDeclaration {
|
|||
* outputs | buttons | inputs order. Panels are only supported when using custom socket order. */
|
||||
bool use_custom_socket_order = false;
|
||||
|
||||
/**
|
||||
* True if any context was used to build this declaration.
|
||||
*/
|
||||
bool is_context_dependent = false;
|
||||
|
||||
friend NodeDeclarationBuilder;
|
||||
|
||||
/** Returns true if the declaration is considered valid. */
|
||||
|
@ -488,6 +493,8 @@ class NodeDeclaration {
|
|||
class NodeDeclarationBuilder {
|
||||
private:
|
||||
NodeDeclaration &declaration_;
|
||||
const bNodeTree *ntree_ = nullptr;
|
||||
const bNode *node_ = nullptr;
|
||||
Vector<std::unique_ptr<BaseSocketDeclarationBuilder>> socket_builders_;
|
||||
Vector<std::unique_ptr<PanelDeclarationBuilder>> panel_builders_;
|
||||
bool is_function_node_ = false;
|
||||
|
@ -496,7 +503,21 @@ class NodeDeclarationBuilder {
|
|||
friend PanelDeclarationBuilder;
|
||||
|
||||
public:
|
||||
NodeDeclarationBuilder(NodeDeclaration &declaration);
|
||||
NodeDeclarationBuilder(NodeDeclaration &declaration,
|
||||
const bNodeTree *ntree = nullptr,
|
||||
const bNode *node = nullptr);
|
||||
|
||||
const bNode *node_or_null() const
|
||||
{
|
||||
declaration_.is_context_dependent = true;
|
||||
return node_;
|
||||
}
|
||||
|
||||
const bNodeTree *tree_or_null() const
|
||||
{
|
||||
declaration_.is_context_dependent = true;
|
||||
return ntree_;
|
||||
}
|
||||
|
||||
/**
|
||||
* All inputs support fields, and all outputs are fields if any of the inputs is a field.
|
||||
|
@ -558,10 +579,10 @@ void index(const bNode &node, void *r_value);
|
|||
void id_or_index(const bNode &node, void *r_value);
|
||||
} // namespace implicit_field_inputs
|
||||
|
||||
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration);
|
||||
void build_node_declaration_dynamic(const bNodeTree &node_tree,
|
||||
const bNode &node,
|
||||
NodeDeclaration &r_declaration);
|
||||
void build_node_declaration(const bNodeType &typeinfo,
|
||||
NodeDeclaration &r_declaration,
|
||||
const bNodeTree *ntree,
|
||||
const bNode *node);
|
||||
|
||||
std::unique_ptr<SocketDeclaration> make_declaration_for_socket_type(
|
||||
eNodeSocketDatatype socket_type);
|
||||
|
|
|
@ -33,7 +33,7 @@ void register_node_type_cmp_group()
|
|||
|
||||
blender::bke::node_type_size(&ntype, 140, 60, 400);
|
||||
ntype.labelfunc = node_group_label;
|
||||
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype.declare = blender::nodes::node_group_declare;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -47,5 +47,5 @@ void register_node_type_cmp_custom_group(bNodeType *ntype)
|
|||
if (ntype->insert_link == nullptr) {
|
||||
ntype->insert_link = node_insert_link_default;
|
||||
}
|
||||
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype->declare = blender::nodes::node_group_declare;
|
||||
}
|
||||
|
|
|
@ -20,13 +20,17 @@
|
|||
|
||||
namespace blender::nodes::node_composite_switchview_cc {
|
||||
|
||||
static void node_declare_dynamic(const bNodeTree & /*ntree*/,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
Scene *scene = reinterpret_cast<Scene *>(node.id);
|
||||
b.add_output<decl::Color>(N_("Image"));
|
||||
|
||||
const bNode *node = b.node_or_null();
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Scene *scene = reinterpret_cast<Scene *>(node->id);
|
||||
|
||||
if (scene != nullptr) {
|
||||
/* add the new views */
|
||||
LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) {
|
||||
|
@ -98,7 +102,7 @@ void register_node_type_cmp_switch_view()
|
|||
static bNodeType ntype;
|
||||
|
||||
cmp_node_type_base(&ntype, CMP_NODE_SWITCH_VIEW, "Switch View", NODE_CLASS_CONVERTER);
|
||||
ntype.declare_dynamic = file_ns::node_declare_dynamic;
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.draw_buttons_ex = file_ns::node_composit_buts_switch_view_ex;
|
||||
ntype.initfunc_api = file_ns::init_switch_view;
|
||||
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
||||
|
|
|
@ -107,7 +107,7 @@ static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSoc
|
|||
|
||||
static void node_gather_link_search_ops(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
|
||||
if (!type) {
|
||||
return;
|
||||
|
|
|
@ -93,7 +93,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ static std::optional<eCustomDataType> node_type_from_other_socket(const bNodeSoc
|
|||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const bNodeType &node_type = params.node_type();
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
|
||||
|
||||
const std::optional<eCustomDataType> type = node_type_from_other_socket(params.other_socket());
|
||||
|
|
|
@ -86,7 +86,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
|
|||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const bNodeType &node_type = params.node_type();
|
||||
const NodeDeclaration &declaration = *node_type.fixed_declaration;
|
||||
const NodeDeclaration &declaration = *node_type.static_declaration;
|
||||
|
||||
/* Weight and Iterations inputs don't change based on the data type. */
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
|
||||
|
|
|
@ -52,7 +52,7 @@ static void node_group_declare(const bNodeTree &node_tree,
|
|||
if (!group) {
|
||||
return;
|
||||
}
|
||||
node_group_declare_dynamic(node_tree, node, b);
|
||||
node_group_declare(node_tree, node, b);
|
||||
if (!node.id) {
|
||||
return;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ static void register_node_type_geo_group()
|
|||
|
||||
blender::bke::node_type_size(&ntype, 140, 60, 400);
|
||||
ntype.labelfunc = node_group_label;
|
||||
ntype.declare_dynamic = node_group_declare;
|
||||
ntype.declare = node_group_declare;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@ -106,5 +106,5 @@ void register_node_type_geo_custom_group(bNodeType *ntype)
|
|||
if (ntype->insert_link == nullptr) {
|
||||
ntype->insert_link = node_insert_link_default;
|
||||
}
|
||||
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype->declare = blender::nodes::node_group_declare;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ class SocketSearchOp {
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
if (params.in_out() == SOCK_OUT) {
|
||||
search_link_ops_for_declarations(params, declaration.outputs);
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(4));
|
||||
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(3));
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ class SocketSearchOp {
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
|
||||
search_link_ops_for_declarations(params, declaration.outputs);
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
|
|
|
@ -65,7 +65,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs);
|
||||
|
||||
const bNodeType &node_type = params.node_type();
|
||||
|
|
|
@ -90,7 +90,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
if (params.in_out() == SOCK_OUT) {
|
||||
search_link_ops_for_declarations(params, declaration.outputs);
|
||||
return;
|
||||
|
|
|
@ -108,7 +108,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3));
|
||||
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(4));
|
||||
|
|
|
@ -20,14 +20,18 @@ namespace blender::nodes::node_geo_repeat_input_cc {
|
|||
|
||||
NODE_STORAGE_FUNCS(NodeGeometryRepeatInput);
|
||||
|
||||
static void node_declare_dynamic(const bNodeTree &tree,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Int>("Iterations").min(0).default_value(1);
|
||||
|
||||
const NodeGeometryRepeatInput &storage = node_storage(node);
|
||||
const bNode *output_node = tree.node_by_id(storage.output_node_id);
|
||||
const bNode *node = b.node_or_null();
|
||||
const bNodeTree *tree = b.tree_or_null();
|
||||
if (ELEM(nullptr, node, tree)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const NodeGeometryRepeatInput &storage = node_storage(*node);
|
||||
const bNode *output_node = tree->node_by_id(storage.output_node_id);
|
||||
if (output_node == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -72,7 +76,7 @@ static void node_register()
|
|||
static bNodeType ntype;
|
||||
geo_node_type_base(&ntype, GEO_NODE_REPEAT_INPUT, "Repeat Input", NODE_CLASS_INTERFACE);
|
||||
ntype.initfunc = node_init;
|
||||
ntype.declare_dynamic = node_declare_dynamic;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gather_link_search_ops = nullptr;
|
||||
ntype.insert_link = node_insert_link;
|
||||
node_type_storage(
|
||||
|
|
|
@ -24,11 +24,13 @@ namespace blender::nodes::node_geo_repeat_output_cc {
|
|||
|
||||
NODE_STORAGE_FUNCS(NodeGeometryRepeatOutput);
|
||||
|
||||
static void node_declare_dynamic(const bNodeTree & /*node_tree*/,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const NodeGeometryRepeatOutput &storage = node_storage(node);
|
||||
const bNode *node = b.node_or_null();
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
const NodeGeometryRepeatOutput &storage = node_storage(*node);
|
||||
for (const int i : IndexRange(storage.items_num)) {
|
||||
const NodeRepeatItem &item = storage.items[i];
|
||||
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
|
||||
|
@ -86,7 +88,7 @@ static void node_register()
|
|||
static bNodeType ntype;
|
||||
geo_node_type_base(&ntype, GEO_NODE_REPEAT_OUTPUT, "Repeat Output", NODE_CLASS_INTERFACE);
|
||||
ntype.initfunc = node_init;
|
||||
ntype.declare_dynamic = node_declare_dynamic;
|
||||
ntype.declare = node_declare;
|
||||
ntype.insert_link = node_insert_link;
|
||||
node_type_storage(&ntype, "NodeGeometryRepeatOutput", node_free_storage, node_copy_storage);
|
||||
nodeRegisterType(&ntype);
|
||||
|
|
|
@ -129,7 +129,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1));
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2));
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_back(1));
|
||||
|
|
|
@ -85,7 +85,7 @@ static void search_link_ops(GatherLinkSearchOpParams ¶ms)
|
|||
if (!U.experimental.use_new_volume_nodes) {
|
||||
return;
|
||||
}
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1));
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1));
|
||||
|
||||
|
|
|
@ -182,19 +182,23 @@ std::unique_ptr<LazyFunction> get_simulation_input_lazy_function(
|
|||
|
||||
namespace blender::nodes::node_geo_simulation_input_cc {
|
||||
|
||||
static void node_declare_dynamic(const bNodeTree &node_tree,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const bNode *output_node = node_tree.node_by_id(node_storage(node).output_node_id);
|
||||
b.add_output<decl::Float>("Delta Time");
|
||||
|
||||
const bNode *node = b.node_or_null();
|
||||
const bNodeTree *node_tree = b.tree_or_null();
|
||||
if (ELEM(nullptr, node, node_tree)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bNode *output_node = node_tree->node_by_id(node_storage(*node).output_node_id);
|
||||
if (!output_node) {
|
||||
return;
|
||||
}
|
||||
const auto &output_storage = *static_cast<const NodeGeometrySimulationOutput *>(
|
||||
output_node->storage);
|
||||
|
||||
b.add_output<decl::Float>("Delta Time");
|
||||
|
||||
for (const int i : IndexRange(output_storage.items_num)) {
|
||||
const NodeSimulationItem &item = output_storage.items[i];
|
||||
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
|
||||
|
@ -234,7 +238,7 @@ static void node_register()
|
|||
static bNodeType ntype;
|
||||
geo_node_type_base(&ntype, GEO_NODE_SIMULATION_INPUT, "Simulation Input", NODE_CLASS_INTERFACE);
|
||||
ntype.initfunc = node_init;
|
||||
ntype.declare_dynamic = node_declare_dynamic;
|
||||
ntype.declare = node_declare;
|
||||
ntype.insert_link = node_insert_link;
|
||||
ntype.gather_link_search_ops = nullptr;
|
||||
node_type_storage(&ntype,
|
||||
|
|
|
@ -672,16 +672,19 @@ std::unique_ptr<LazyFunction> get_simulation_output_lazy_function(
|
|||
|
||||
namespace blender::nodes::node_geo_simulation_output_cc {
|
||||
|
||||
static void node_declare_dynamic(const bNodeTree & /*node_tree*/,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const NodeGeometrySimulationOutput &storage = node_storage(node);
|
||||
|
||||
b.add_input<decl::Bool>("Skip").description(
|
||||
"Forward the output of the simulation input node directly to the output node and ignore "
|
||||
"the nodes in the simulation zone");
|
||||
|
||||
const bNode *node = b.node_or_null();
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const NodeGeometrySimulationOutput &storage = node_storage(*node);
|
||||
|
||||
for (const int i : IndexRange(storage.items_num)) {
|
||||
const NodeSimulationItem &item = storage.items[i];
|
||||
const eNodeSocketDatatype socket_type = eNodeSocketDatatype(item.socket_type);
|
||||
|
@ -877,7 +880,7 @@ static void node_register()
|
|||
geo_node_type_base(
|
||||
&ntype, GEO_NODE_SIMULATION_OUTPUT, "Simulation Output", NODE_CLASS_INTERFACE);
|
||||
ntype.initfunc = node_init;
|
||||
ntype.declare_dynamic = node_declare_dynamic;
|
||||
ntype.declare = node_declare;
|
||||
ntype.gather_link_search_ops = nullptr;
|
||||
ntype.insert_link = node_insert_link;
|
||||
ntype.draw_buttons_ex = node_layout_ex;
|
||||
|
|
|
@ -82,7 +82,7 @@ static void node_update(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2));
|
||||
search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1));
|
||||
|
||||
|
|
|
@ -357,12 +357,14 @@ static PanelDeclarationPtr declaration_for_interface_panel(const bNodeTree & /*n
|
|||
return dst;
|
||||
}
|
||||
|
||||
void node_group_declare_dynamic(const bNodeTree & /*node_tree*/,
|
||||
const bNode &node,
|
||||
NodeDeclarationBuilder &b)
|
||||
void node_group_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const bNode *node = b.node_or_null();
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
NodeDeclaration &r_declaration = b.declaration();
|
||||
const bNodeTree *group = reinterpret_cast<const bNodeTree *>(node.id);
|
||||
const bNodeTree *group = reinterpret_cast<const bNodeTree *>(node->id);
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
|
@ -606,19 +608,21 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier)
|
|||
|
||||
namespace blender::nodes {
|
||||
|
||||
static void group_input_declare_dynamic(const bNodeTree &node_tree,
|
||||
const bNode & /*node*/,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void group_input_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const bNodeTree *node_tree = b.tree_or_null();
|
||||
if (node_tree == nullptr) {
|
||||
return;
|
||||
}
|
||||
NodeDeclaration &r_declaration = b.declaration();
|
||||
node_tree.tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
|
||||
node_tree->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
|
||||
switch (item.item_type) {
|
||||
case NODE_INTERFACE_SOCKET: {
|
||||
const bNodeTreeInterfaceSocket &socket =
|
||||
node_interface::get_item_as<bNodeTreeInterfaceSocket>(item);
|
||||
if (socket.flag & NODE_INTERFACE_SOCKET_INPUT) {
|
||||
SocketDeclarationPtr socket_decl = declaration_for_interface_socket(
|
||||
node_tree, socket, SOCK_OUT);
|
||||
*node_tree, socket, SOCK_OUT);
|
||||
r_declaration.outputs.append(socket_decl.get());
|
||||
r_declaration.items.append(std::move(socket_decl));
|
||||
}
|
||||
|
@ -632,19 +636,21 @@ static void group_input_declare_dynamic(const bNodeTree &node_tree,
|
|||
r_declaration.items.append(std::move(extend_decl));
|
||||
}
|
||||
|
||||
static void group_output_declare_dynamic(const bNodeTree &node_tree,
|
||||
const bNode & /*node*/,
|
||||
NodeDeclarationBuilder &b)
|
||||
static void group_output_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
const bNodeTree *node_tree = b.tree_or_null();
|
||||
if (node_tree == nullptr) {
|
||||
return;
|
||||
}
|
||||
NodeDeclaration &r_declaration = b.declaration();
|
||||
node_tree.tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
|
||||
node_tree->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) {
|
||||
switch (item.item_type) {
|
||||
case NODE_INTERFACE_SOCKET: {
|
||||
const bNodeTreeInterfaceSocket &socket =
|
||||
node_interface::get_item_as<bNodeTreeInterfaceSocket>(item);
|
||||
if (socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) {
|
||||
SocketDeclarationPtr socket_decl = declaration_for_interface_socket(
|
||||
node_tree, socket, SOCK_IN);
|
||||
*node_tree, socket, SOCK_IN);
|
||||
r_declaration.inputs.append(socket_decl.get());
|
||||
r_declaration.items.append(std::move(socket_decl));
|
||||
}
|
||||
|
@ -710,7 +716,7 @@ void register_node_type_group_input()
|
|||
|
||||
blender::bke::node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE);
|
||||
blender::bke::node_type_size(ntype, 140, 80, 400);
|
||||
ntype->declare_dynamic = blender::nodes::group_input_declare_dynamic;
|
||||
ntype->declare = blender::nodes::group_input_declare;
|
||||
ntype->insert_link = blender::nodes::group_input_insert_link;
|
||||
|
||||
nodeRegisterType(ntype);
|
||||
|
@ -734,7 +740,7 @@ void register_node_type_group_output()
|
|||
|
||||
blender::bke::node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE);
|
||||
blender::bke::node_type_size(ntype, 140, 80, 400);
|
||||
ntype->declare_dynamic = blender::nodes::group_output_declare_dynamic;
|
||||
ntype->declare = blender::nodes::group_output_declare;
|
||||
ntype->insert_link = blender::nodes::group_output_insert_link;
|
||||
|
||||
ntype->no_muting = true;
|
||||
|
|
|
@ -21,24 +21,17 @@ static void reset_declaration(NodeDeclaration &declaration)
|
|||
new (&declaration) NodeDeclaration();
|
||||
}
|
||||
|
||||
void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration)
|
||||
void build_node_declaration(const bNodeType &typeinfo,
|
||||
NodeDeclaration &r_declaration,
|
||||
const bNodeTree *ntree,
|
||||
const bNode *node)
|
||||
{
|
||||
reset_declaration(r_declaration);
|
||||
NodeDeclarationBuilder node_decl_builder{r_declaration};
|
||||
NodeDeclarationBuilder node_decl_builder{r_declaration, ntree, node};
|
||||
typeinfo.declare(node_decl_builder);
|
||||
node_decl_builder.finalize();
|
||||
}
|
||||
|
||||
void build_node_declaration_dynamic(const bNodeTree &node_tree,
|
||||
const bNode &node,
|
||||
NodeDeclaration &r_declaration)
|
||||
{
|
||||
reset_declaration(r_declaration);
|
||||
NodeDeclarationBuilder node_decl_builder{r_declaration};
|
||||
node.typeinfo->declare_dynamic(node_tree, node, node_decl_builder);
|
||||
node_decl_builder.finalize();
|
||||
}
|
||||
|
||||
void NodeDeclarationBuilder::finalize()
|
||||
{
|
||||
if (is_function_node_) {
|
||||
|
@ -117,8 +110,10 @@ void NodeDeclarationBuilder::finalize()
|
|||
BLI_assert(declaration_.is_valid());
|
||||
}
|
||||
|
||||
NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration)
|
||||
: declaration_(declaration)
|
||||
NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration,
|
||||
const bNodeTree *ntree,
|
||||
const bNode *node)
|
||||
: declaration_(declaration), ntree_(ntree), node_(node)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -578,11 +578,13 @@ static void refresh_node(bNodeTree &ntree,
|
|||
|
||||
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
|
||||
{
|
||||
if (node.typeinfo->declare_dynamic) {
|
||||
if (!node.runtime->declaration) {
|
||||
node.runtime->declaration = new NodeDeclaration();
|
||||
if (node.typeinfo->declare) {
|
||||
if (node.typeinfo->static_declaration->is_context_dependent) {
|
||||
if (!node.runtime->declaration) {
|
||||
node.runtime->declaration = new NodeDeclaration();
|
||||
}
|
||||
build_node_declaration(*node.typeinfo, *node.runtime->declaration, &ntree, &node);
|
||||
}
|
||||
build_node_declaration_dynamic(ntree, node, *node.runtime->declaration);
|
||||
}
|
||||
refresh_node(ntree, node, *node.runtime->declaration, true);
|
||||
}
|
||||
|
@ -601,7 +603,7 @@ void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user)
|
|||
if (ntype == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (ntype->declare || ntype->declare_dynamic) {
|
||||
if (ntype->declare) {
|
||||
blender::bke::nodeDeclarationEnsureOnOutdatedNode(ntree, node);
|
||||
refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user);
|
||||
return;
|
||||
|
|
|
@ -141,18 +141,10 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms,
|
|||
void search_link_ops_for_basic_node(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const bNodeType &node_type = params.node_type();
|
||||
if (!node_type.declare) {
|
||||
if (!node_type.static_declaration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node_type.declare_dynamic) {
|
||||
/* Dynamic declarations aren't supported here, but avoid crashing in release builds. */
|
||||
BLI_assert_unreachable();
|
||||
return;
|
||||
}
|
||||
|
||||
const NodeDeclaration &declaration = *node_type.fixed_declaration;
|
||||
|
||||
const NodeDeclaration &declaration = *node_type.static_declaration;
|
||||
search_link_ops_for_declarations(params, declaration.sockets(params.in_out()));
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ void register_node_type_sh_group()
|
|||
|
||||
blender::bke::node_type_size(&ntype, 140, 60, 400);
|
||||
ntype.labelfunc = node_group_label;
|
||||
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype.declare = blender::nodes::node_group_declare;
|
||||
ntype.gpu_fn = gpu_group_execute;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
|
@ -112,6 +112,6 @@ void register_node_type_sh_custom_group(bNodeType *ntype)
|
|||
if (ntype->insert_link == nullptr) {
|
||||
ntype->insert_link = node_insert_link_default;
|
||||
}
|
||||
ntype->declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype->declare = blender::nodes::node_group_declare;
|
||||
ntype->gpu_fn = gpu_group_execute;
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ static void node_shader_update_sky(bNodeTree *ntree, bNode *node)
|
|||
|
||||
static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
||||
{
|
||||
const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
|
||||
const NodeDeclaration &declaration = *params.node_type().static_declaration;
|
||||
if (params.in_out() == SOCK_OUT) {
|
||||
search_link_ops_for_declarations(params, declaration.outputs);
|
||||
return;
|
||||
|
|
|
@ -156,7 +156,7 @@ void register_node_type_tex_group()
|
|||
|
||||
blender::bke::node_type_size(&ntype, 140, 60, 400);
|
||||
ntype.labelfunc = node_group_label;
|
||||
ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic;
|
||||
ntype.declare = blender::nodes::node_group_declare;
|
||||
ntype.init_exec_fn = group_initexec;
|
||||
ntype.free_exec_fn = group_freeexec;
|
||||
ntype.exec_fn = group_execute;
|
||||
|
|
Loading…
Reference in New Issue