WIP: Closures and deferred evaluation for geometry nodes #107842
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "FN_closure.hh"
|
||||
#include "FN_init.h"
|
||||
|
||||
struct Tex;
|
||||
|
@ -30,6 +31,8 @@ BLI_CPP_TYPE_MAKE(MStringProperty, CPPTypeFlags::None);
|
|||
|
||||
BLI_CPP_TYPE_MAKE(blender::bke::AnonymousAttributeSet, CPPTypeFlags::None);
|
||||
|
||||
BLI_CPP_TYPE_MAKE(blender::fn::Closure, CPPTypeFlags::None);
|
||||
|
||||
void BKE_cpp_types_init()
|
||||
{
|
||||
blender::register_cpp_types();
|
||||
|
@ -49,4 +52,6 @@ void BKE_cpp_types_init()
|
|||
BLI_CPP_TYPE_REGISTER(MStringProperty);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(blender::bke::AnonymousAttributeSet);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(blender::fn::Closure);
|
||||
}
|
||||
|
|
|
@ -321,6 +321,7 @@ static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket
|
|||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -466,6 +467,7 @@ static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *so
|
|||
case __SOCK_MESH:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
|
@ -886,6 +888,7 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock
|
|||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -981,6 +984,7 @@ static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
|
|||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1627,6 +1631,7 @@ static void socket_id_user_increment(bNodeSocket *sock)
|
|||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1673,6 +1678,7 @@ static bool socket_id_user_decrement(bNodeSocket *sock)
|
|||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_GEOMETRY:
|
||||
case SOCK_FUNCTION:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
@ -1855,6 +1861,8 @@ const char *nodeStaticSocketType(const int type, const int subtype)
|
|||
return "NodeSocketTexture";
|
||||
case SOCK_MATERIAL:
|
||||
return "NodeSocketMaterial";
|
||||
case SOCK_FUNCTION:
|
||||
return "NodeSocketFunction";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1934,6 +1942,8 @@ const char *nodeStaticSocketInterfaceType(const int type, const int subtype)
|
|||
return "NodeSocketInterfaceTexture";
|
||||
case SOCK_MATERIAL:
|
||||
return "NodeSocketInterfaceMaterial";
|
||||
case SOCK_FUNCTION:
|
||||
return "NodeSocketInterfaceFunction";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1969,6 +1979,8 @@ const char *nodeStaticSocketLabel(const int type, const int /*subtype*/)
|
|||
return "Texture";
|
||||
case SOCK_MATERIAL:
|
||||
return "Material";
|
||||
case SOCK_FUNCTION:
|
||||
return "Function";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1198,6 +1198,7 @@ static const float std_node_socket_colors[][4] = {
|
|||
{0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */
|
||||
{0.62, 0.31, 0.64, 1.0}, /* SOCK_TEXTURE */
|
||||
{0.92, 0.46, 0.51, 1.0}, /* SOCK_MATERIAL */
|
||||
{0.65, 0.05, 0.64, 1.0}, /* SOCK_FUNCTION */
|
||||
};
|
||||
|
||||
/* common color callbacks for standard types */
|
||||
|
|
|
@ -2241,6 +2241,7 @@ static int get_main_socket_priority(const bNodeSocket *socket)
|
|||
case SOCK_COLLECTION:
|
||||
case SOCK_TEXTURE:
|
||||
case SOCK_MATERIAL:
|
||||
case SOCK_FUNCTION:
|
||||
return 6;
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -405,6 +405,9 @@ static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
|
|||
else if (dynamic_cast<const decl::Object *>(&socket_decl)) {
|
||||
item.socket_type = SOCK_OBJECT;
|
||||
}
|
||||
else if (dynamic_cast<const decl::Function *>(&socket_decl)) {
|
||||
item.socket_type = SOCK_FUNCTION;
|
||||
}
|
||||
else {
|
||||
item.socket_type = SOCK_CUSTOM;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ set(INC_SYS
|
|||
)
|
||||
|
||||
set(SRC
|
||||
intern/closure.cc
|
||||
intern/cpp_types.cc
|
||||
intern/field.cc
|
||||
intern/field_cpp_type.cc
|
||||
|
@ -26,6 +27,7 @@ set(SRC
|
|||
intern/multi_function_procedure_executor.cc
|
||||
intern/multi_function_procedure_optimization.cc
|
||||
|
||||
FN_closure.hh
|
||||
FN_field.hh
|
||||
FN_field_cpp_type.hh
|
||||
FN_field_cpp_type_make.hh
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup fn
|
||||
*/
|
||||
|
||||
#include "BLI_cpp_type.hh"
|
||||
|
||||
#include "FN_lazy_function.hh"
|
||||
#include "FN_lazy_function_graph_executor.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
class Closure {
|
||||
private:
|
||||
std::shared_ptr<lf::GraphExecutor> function_;
|
||||
|
||||
public:
|
||||
Closure() = default;
|
||||
Closure(const Closure &other) = default;
|
||||
explicit Closure(const lf::GraphExecutor &function);
|
||||
~Closure() = default;
|
||||
|
||||
Closure &operator=(const Closure &other) = default;
|
||||
};
|
||||
|
||||
|
||||
} // namespace blender::fn
|
|
@ -0,0 +1,16 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup fn
|
||||
*/
|
||||
|
||||
#include "FN_closure.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
Closure::Closure(const lf::GraphExecutor &function)
|
||||
: function_(std::make_shared<lf::GraphExecutor>(function))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blender::fn
|
|
@ -236,6 +236,7 @@ typedef enum eNodeSocketDatatype {
|
|||
SOCK_COLLECTION = 11,
|
||||
SOCK_TEXTURE = 12,
|
||||
SOCK_MATERIAL = 13,
|
||||
SOCK_FUNCTION = 14,
|
||||
} eNodeSocketDatatype;
|
||||
|
||||
/** Socket shape. */
|
||||
|
|
|
@ -72,6 +72,7 @@ static const EnumPropertyItem node_socket_data_type_items[] = {
|
|||
{SOCK_COLLECTION, "COLLECTION", 0, "Collection", ""},
|
||||
{SOCK_TEXTURE, "TEXTURE", 0, "Texture", ""},
|
||||
{SOCK_MATERIAL, "MATERIAL", 0, "Material", ""},
|
||||
{SOCK_FUNCTION, "FUNCTION", 0, "Function", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -100,6 +101,7 @@ static const EnumPropertyItem node_socket_type_items[] = {
|
|||
{SOCK_COLLECTION, "COLLECTION", 0, "Collection", ""},
|
||||
{SOCK_TEXTURE, "TEXTURE", 0, "Texture", ""},
|
||||
{SOCK_MATERIAL, "MATERIAL", 0, "Material", ""},
|
||||
{SOCK_FUNCTION, "FUNCTION", 0, "Function", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -2077,7 +2079,8 @@ static bool switch_type_supported(const EnumPropertyItem *item)
|
|||
SOCK_COLLECTION,
|
||||
SOCK_TEXTURE,
|
||||
SOCK_MATERIAL,
|
||||
SOCK_IMAGE);
|
||||
SOCK_IMAGE,
|
||||
SOCK_FUNCTION);
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_GeometryNodeSwitch_type_itemf(bContext *UNUSED(C),
|
||||
|
@ -11932,6 +11935,21 @@ static void rna_def_node_socket_material(BlenderRNA *brna,
|
|||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
}
|
||||
|
||||
static void rna_def_node_socket_function(BlenderRNA *brna,
|
||||
const char *identifier,
|
||||
const char *interface_idname)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
|
||||
RNA_def_struct_ui_text(srna, "Function Node Socket", "Function socket of a node");
|
||||
RNA_def_struct_sdna(srna, "bNodeSocket");
|
||||
|
||||
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
|
||||
RNA_def_struct_ui_text(srna, "Function Node Socket Interface", "Function socket of a node");
|
||||
RNA_def_struct_sdna(srna, "bNodeSocket");
|
||||
}
|
||||
|
||||
static void rna_def_node_socket_standard_types(BlenderRNA *brna)
|
||||
{
|
||||
/* XXX Workaround: Registered functions are not exposed in python by bpy,
|
||||
|
@ -12084,6 +12102,8 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
|
|||
rna_def_node_socket_texture(brna, "NodeSocketTexture", "NodeSocketInterfaceTexture");
|
||||
|
||||
rna_def_node_socket_material(brna, "NodeSocketMaterial", "NodeSocketInterfaceMaterial");
|
||||
|
||||
rna_def_node_socket_function(brna, "NodeSocketFunction", "NodeSocketInterfaceFunction");
|
||||
}
|
||||
|
||||
static void rna_def_internal_node(BlenderRNA *brna)
|
||||
|
|
|
@ -225,6 +225,13 @@ class Shader : public SocketDeclaration {
|
|||
class ShaderBuilder : public SocketDeclarationBuilder<Shader> {
|
||||
};
|
||||
|
||||
class Function : public IDSocketDeclaration {
|
||||
public:
|
||||
using Builder = SocketDeclarationBuilder<Function>;
|
||||
|
||||
Function();
|
||||
};
|
||||
|
||||
class ExtendBuilder;
|
||||
|
||||
class Extend : public SocketDeclaration {
|
||||
|
@ -401,6 +408,10 @@ inline Texture::Texture() : IDSocketDeclaration("NodeSocketTexture") {}
|
|||
|
||||
inline Image::Image() : IDSocketDeclaration("NodeSocketImage") {}
|
||||
|
||||
inline Function::Function() : IDSocketDeclaration("NodeSocketFunction")
|
||||
{
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
SocketDeclarationPtr create_extend_declaration(const eNodeSocketInOut in_out);
|
||||
|
|
|
@ -102,7 +102,8 @@ static bool geometry_node_tree_socket_type_valid(bNodeTreeType * /*treetype*/,
|
|||
SOCK_COLLECTION,
|
||||
SOCK_TEXTURE,
|
||||
SOCK_IMAGE,
|
||||
SOCK_MATERIAL);
|
||||
SOCK_MATERIAL,
|
||||
SOCK_FUNCTION);
|
||||
}
|
||||
|
||||
void register_node_tree_type_geo()
|
||||
|
|
|
@ -251,6 +251,9 @@ static SocketDeclarationPtr declaration_for_interface_socket(const bNodeTree &nt
|
|||
dst = std::move(value);
|
||||
break;
|
||||
}
|
||||
case SOCK_FUNCTION:
|
||||
dst = std::make_unique<decl::Function>();
|
||||
break;
|
||||
case SOCK_CUSTOM:
|
||||
std::unique_ptr<decl::Custom> decl = std::make_unique<decl::Custom>();
|
||||
decl->idname_ = io_socket.idname;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "NOD_node_declaration.hh"
|
||||
#include "NOD_socket.h"
|
||||
|
||||
#include "FN_closure.hh"
|
||||
#include "FN_field.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
@ -778,6 +779,18 @@ static bNodeSocketType *make_socket_type_material()
|
|||
return socktype;
|
||||
}
|
||||
|
||||
static bNodeSocketType *make_socket_type_function()
|
||||
{
|
||||
bNodeSocketType *socktype = make_standard_socket_type(SOCK_FUNCTION, PROP_NONE);
|
||||
socktype->base_cpp_type = &blender::CPPType::get<fn::Closure>();
|
||||
socktype->get_base_cpp_value = [](const bNodeSocket &/*socket*/, void *r_value) {
|
||||
new (r_value) fn::Closure();
|
||||
};
|
||||
socktype->geometry_nodes_cpp_type = socktype->base_cpp_type;
|
||||
socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
|
||||
return socktype;
|
||||
}
|
||||
|
||||
void register_standard_node_socket_types()
|
||||
{
|
||||
/* Draw callbacks are set in `drawnode.c` to avoid bad-level calls. */
|
||||
|
@ -824,5 +837,7 @@ void register_standard_node_socket_types()
|
|||
|
||||
nodeRegisterSocketType(make_socket_type_material());
|
||||
|
||||
nodeRegisterSocketType(make_socket_type_function());
|
||||
|
||||
nodeRegisterSocketType(make_socket_type_virtual());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue