WIP: Closures and deferred evaluation for geometry nodes #107842
|
@ -617,6 +617,16 @@ class NODE_MT_category_GEO_GROUP(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_FUNCTION(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_FUNCTION"
|
||||
bl_label = "Function"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeBind")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeEvaluate")
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_LAYOUT(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_LAYOUT"
|
||||
bl_label = "Layout"
|
||||
|
@ -651,6 +661,7 @@ class NODE_MT_geometry_node_add_all(Menu):
|
|||
layout.menu("NODE_MT_category_GEO_UTILITIES")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_GEO_GROUP")
|
||||
layout.menu("NODE_MT_category_GEO_FUNCTION")
|
||||
layout.menu("NODE_MT_category_GEO_LAYOUT")
|
||||
node_add_menu.draw_root_assets(layout)
|
||||
|
||||
|
@ -696,6 +707,7 @@ classes = (
|
|||
NODE_MT_category_GEO_UTILITIES_MATH,
|
||||
NODE_MT_category_GEO_UTILITIES_ROTATION,
|
||||
NODE_MT_category_GEO_GROUP,
|
||||
NODE_MT_category_GEO_FUNCTION,
|
||||
NODE_MT_category_GEO_LAYOUT,
|
||||
)
|
||||
|
||||
|
|
|
@ -1608,6 +1608,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define FN_NODE_INPUT_INT 1220
|
||||
#define FN_NODE_SEPARATE_COLOR 1221
|
||||
#define FN_NODE_COMBINE_COLOR 1222
|
||||
#define FN_NODE_BIND 1223
|
||||
#define FN_NODE_EVALUATE 1224
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -4544,6 +4544,51 @@ static const EnumPropertyItem *rna_NodeConvertColorSpace_color_space_itemf(
|
|||
return items;
|
||||
}
|
||||
|
||||
static void rna_FunctionNodeBind_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
|
||||
BKE_ntree_update_tag_node_property(ntree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
static void rna_FunctionNodeBind_node_tree_set(PointerRNA *ptr,
|
||||
const PointerRNA value,
|
||||
struct ReportList *UNUSED(reports))
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = ptr->data;
|
||||
bNodeTree *ngroup = value.data;
|
||||
|
||||
const char *disabled_hint = NULL;
|
||||
if (nodeGroupPoll(ntree, ngroup, &disabled_hint)) {
|
||||
if (node->id) {
|
||||
id_us_min(node->id);
|
||||
}
|
||||
if (ngroup) {
|
||||
id_us_plus(&ngroup->id);
|
||||
}
|
||||
|
||||
node->id = &ngroup->id;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rna_FunctionNodeBind_node_tree_poll(PointerRNA *ptr, const PointerRNA value)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNodeTree *ngroup = value.data;
|
||||
|
||||
/* only allow node trees of the same type as the bind node's tree */
|
||||
if (ngroup->type != ntree->type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *disabled_hint = NULL;
|
||||
return nodeGroupPoll(ntree, ngroup, &disabled_hint);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const EnumPropertyItem prop_image_layer_items[] = {
|
||||
|
@ -5200,6 +5245,25 @@ static void def_fn_combsep_color(StructRNA *srna)
|
|||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
|
||||
}
|
||||
|
||||
static void def_fn_bind(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "id");
|
||||
RNA_def_property_struct_type(prop, "NodeTree");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, NULL, "rna_FunctionNodeBind_node_tree_set", NULL, "rna_FunctionNodeBind_node_tree_poll");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Node Tree", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNodeBind_update");
|
||||
}
|
||||
|
||||
static void def_fn_evaluate(StructRNA *srna)
|
||||
{
|
||||
}
|
||||
|
||||
/* -- Shader Nodes ---------------------------------------------------------- */
|
||||
|
||||
static void def_sh_output(StructRNA *srna)
|
||||
|
|
|
@ -279,6 +279,8 @@ DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_CO
|
|||
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "")
|
||||
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
|
||||
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
|
||||
DefNode(FunctionNode, FN_NODE_BIND, def_fn_bind, "BIND", Bind, "Bind", "")
|
||||
DefNode(FunctionNode, FN_NODE_EVALUATE, def_fn_evaluate, "EVALUATE", Evaluate, "Evaluate", "")
|
||||
|
||||
DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")
|
||||
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")
|
||||
|
|
|
@ -21,9 +21,11 @@ set(INC_SYS
|
|||
|
||||
set(SRC
|
||||
nodes/node_fn_align_euler_to_vector.cc
|
||||
nodes/node_fn_bind.cc
|
||||
nodes/node_fn_boolean_math.cc
|
||||
nodes/node_fn_combine_color.cc
|
||||
nodes/node_fn_compare.cc
|
||||
nodes/node_fn_evaluate.cc
|
||||
nodes/node_fn_float_to_int.cc
|
||||
nodes/node_fn_input_bool.cc
|
||||
nodes/node_fn_input_color.cc
|
||||
|
|
|
@ -7,9 +7,11 @@
|
|||
void register_function_nodes()
|
||||
{
|
||||
register_node_type_fn_align_euler_to_vector();
|
||||
register_node_type_fn_bind();
|
||||
register_node_type_fn_boolean_math();
|
||||
register_node_type_fn_combine_color();
|
||||
register_node_type_fn_compare();
|
||||
register_node_type_fn_evaluate();
|
||||
register_node_type_fn_float_to_int();
|
||||
register_node_type_fn_input_bool();
|
||||
register_node_type_fn_input_color();
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
#pragma once
|
||||
|
||||
void register_node_type_fn_align_euler_to_vector();
|
||||
void register_node_type_fn_bind();
|
||||
void register_node_type_fn_boolean_math();
|
||||
void register_node_type_fn_combine_color();
|
||||
void register_node_type_fn_compare();
|
||||
void register_node_type_fn_evaluate();
|
||||
void register_node_type_fn_float_to_int();
|
||||
void register_node_type_fn_input_bool();
|
||||
void register_node_type_fn_input_color();
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_node_runtime.hh"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "NOD_common.h"
|
||||
|
||||
#include "node_common.h"
|
||||
#include "node_function_util.hh"
|
||||
#include "node_function_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_bind_cc {
|
||||
|
||||
static void node_declare(const bNodeTree &node_tree,
|
||||
const bNode &node,
|
||||
NodeDeclaration &r_declaration)
|
||||
{
|
||||
const bNodeTree *group = reinterpret_cast<const bNodeTree *>(node.id);
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
blender::nodes::node_group_declare_dynamic(node_tree, node, r_declaration);
|
||||
if (!node.id) {
|
||||
return;
|
||||
}
|
||||
if (ID_IS_LINKED(&group->id) && (group->id.tag & LIB_TAG_MISSING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const FieldInferencingInterface &field_interface = *group->runtime->field_inferencing_interface;
|
||||
for (const int i : r_declaration.inputs.index_range()) {
|
||||
r_declaration.inputs[i]->input_field_type = field_interface.inputs[i];
|
||||
}
|
||||
for (const int i : r_declaration.outputs.index_range()) {
|
||||
r_declaration.outputs[i]->output_field_dependency = field_interface.outputs[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext *C, PointerRNA *ptr)
|
||||
{
|
||||
uiTemplateIDBrowse(
|
||||
layout, C, ptr, "node_tree", nullptr, nullptr, nullptr, UI_TEMPLATE_ID_FILTER_ALL, nullptr);
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_fn_bind_cc
|
||||
|
||||
void register_node_type_fn_bind()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_fn_bind_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, FN_NODE_BIND, "Bind", NODE_CLASS_GROUP);
|
||||
ntype.poll_instance = node_group_poll_instance;
|
||||
|
||||
node_type_size(&ntype, 140, 60, 400);
|
||||
ntype.declare_dynamic = file_ns::node_declare;
|
||||
ntype.draw_buttons = file_ns::node_layout;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "node_function_util.hh"
|
||||
|
||||
namespace blender::nodes::node_fn_evaluate_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Function>(N_("Function"));
|
||||
}
|
||||
|
||||
static void node_update(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
}
|
||||
|
||||
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::node_fn_evaluate_cc
|
||||
|
||||
void register_node_type_fn_evaluate()
|
||||
{
|
||||
namespace file_ns = blender::nodes::node_fn_evaluate_cc;
|
||||
|
||||
static bNodeType ntype;
|
||||
|
||||
fn_node_type_base(&ntype, FN_NODE_EVALUATE, "Evaluate", NODE_CLASS_GROUP);
|
||||
ntype.declare = file_ns::node_declare;
|
||||
ntype.draw_buttons = file_ns::node_layout;
|
||||
ntype.updatefunc = file_ns::node_update;
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
Loading…
Reference in New Issue