WIP: Closures and deferred evaluation for geometry nodes #107842

Draft
Lukas Tönne wants to merge 35 commits from LukasTonne/blender:geometry-nodes-closures into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 142 additions and 130 deletions
Showing only changes of commit ae68c6d0e8 - Show all commits

View File

@ -228,38 +228,42 @@ typedef int (*NodeGPUExecFunction)(struct GPUMaterial *mat,
/** \name Node Function Signature
* \{ */
struct bNodeSocket *nodeFunctionSignatureFindSocket(struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const char *identifier);
struct bNodeSocket *nodeFunctionSignatureAddSocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const char *idname,
const char *name);
struct bNodeSocket *nodeFunctionSignatureInsertSocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const char *idname,
struct bNodeSocket *next_sock,
const char *name);
struct bNodeSocket *nodeFunctionSignatureCopySocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
const struct bNode *from_node,
const struct bNodeSocket *from_sock);
struct bNodeSocket *nodeFunctionSignatureCopySocketEx(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
const struct bNode *from_node,
const struct bNodeSocket *from_sock,
const char *idname,
const char *name);
struct bNodeSocket *nodeFunctionSignatureCopyInsertSocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
struct bNodeSocket *next_sock,
const struct bNode *from_node,
const struct bNodeSocket *from_sock);
struct bNodeFunctionParameter *nodeFunctionSignatureFindSocket(struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const char *identifier);
struct bNodeFunctionParameter *nodeFunctionSignatureAddSocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const char *name,
eNodeSocketDatatype socket_type);
struct bNodeFunctionParameter *nodeFunctionSignatureInsertSocket(
struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out,
const struct bNodeFunctionParameter *next_sock,
const char *name,
eNodeSocketDatatype socket_type);
struct bNodeFunctionParameter *nodeFunctionSignatureCopySocket(
struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
const struct bNode *from_node,
const struct bNodeSocket *from_sock);
struct bNodeFunctionParameter *nodeFunctionSignatureCopySocketEx(
struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
const struct bNode *from_node,
const struct bNodeSocket *from_sock,
const char *idname,
const char *name);
struct bNodeFunctionParameter *nodeFunctionSignatureCopyInsertSocket(
struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
struct bNodeSocket *next_sock,
const struct bNode *from_node,
const struct bNodeSocket *from_sock);
void nodeFunctionSignatureRemoveSocket(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
struct bNodeSocket *sock);
struct bNodeFunctionParameter *param);
void nodeFunctionSignatureClear(struct bNodeTree *ntree,
struct bNodeFunctionSignature *sig,
eNodeSocketInOut in_out);

View File

@ -128,64 +128,52 @@ static void node_socket_set_typeinfo(bNodeTree *ntree,
/* ************ NODE FUNCTION SIGNATURE *************** */
static bNodeSocket *make_signature_socket(bNodeTree *ntree,
bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *idname,
const char *name)
static Span<bNodeFunctionParameter> nodeFunctionSignatureGetParams(
const bNodeFunctionSignature *sig, const eNodeSocketInOut in_out)
{
bNodeSocketType *stype = nodeSocketTypeFind(idname);
if (stype == nullptr) {
return nullptr;
}
bNodeSocket *sock = MEM_cnew<bNodeSocket>("socket template");
sock->runtime = MEM_new<bNodeSocketRuntime>(__func__);
BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname));
sock->in_out = in_out;
sock->type = SOCK_CUSTOM; /* int type undefined by default */
node_socket_set_typeinfo(ntree, sock, stype);
/* assign new unique index */
const int own_index = sig->cur_index++;
/* use the own_index as socket identifier */
if (in_out == SOCK_IN) {
BLI_snprintf(sock->identifier, MAX_NAME, "Input_%d", own_index);
return Span<bNodeFunctionParameter>(sig->inputs, sig->inputs_num);
}
else {
BLI_snprintf(sock->identifier, MAX_NAME, "Output_%d", own_index);
return Span<bNodeFunctionParameter>(sig->outputs, sig->outputs_num);
}
sock->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
BLI_strncpy(sock->name, name, NODE_MAXSTR);
sock->storage = nullptr;
sock->flag |= SOCK_COLLAPSED;
return sock;
}
bNodeSocket *nodeFunctionSignatureFindSocket(bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *identifier)
static MutableSpan<bNodeFunctionParameter> nodeFunctionSignatureGetParams(
bNodeFunctionSignature *sig, const eNodeSocketInOut in_out)
{
ListBase *sockets = (in_out == SOCK_IN) ? &sig->inputs : &sig->outputs;
LISTBASE_FOREACH (bNodeSocket *, iosock, sockets) {
if (STREQ(iosock->identifier, identifier)) {
return iosock;
if (in_out == SOCK_IN) {
return MutableSpan<bNodeFunctionParameter>(sig->inputs, sig->inputs_num);
}
else {
return MutableSpan<bNodeFunctionParameter>(sig->outputs, sig->outputs_num);
}
}
bNodeFunctionParameter *nodeFunctionSignatureFindSocket(bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *name)
{
for (bNodeFunctionParameter &param : nodeFunctionSignatureGetParams(sig, in_out)) {
if (STREQ(param.name, name)) {
return &param;
}
}
return nullptr;
}
bNodeSocket *nodeFunctionSignatureAddSocket(bNodeTree *ntree,
bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *idname,
const char *name)
bNodeFunctionParameter *nodeFunctionSignatureAddSocket(bNodeTree *ntree,
bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *name,
eNodeSocketDatatype socket_type)
{
bNodeSocket *iosock = make_signature_socket(ntree, sig, in_out, idname, name);
bNodeFunctionParameter param;
BLI_strncpy(param.name, name, sizeof(param.name));
param.socket_type = socket_type;
if (in_out == SOCK_IN) {
BLI_addtail(&sig->inputs, iosock);
}
else if (in_out == SOCK_OUT) {
@ -195,16 +183,21 @@ bNodeSocket *nodeFunctionSignatureAddSocket(bNodeTree *ntree,
return iosock;
}
bNodeSocket *nodeFunctionSignatureInsertSocket(bNodeTree *ntree,
bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const char *idname,
bNodeSocket *next_sock,
const char *name)
bNodeFunctionParameter *nodeFunctionSignatureInsertSocket(bNodeTree *ntree,
bNodeFunctionSignature *sig,
const eNodeSocketInOut in_out,
const bNodeFunctionParameter *next_sock,
const char *name,
eNodeSocketDatatype socket_type)
{
bNodeSocket *iosock = make_signature_socket(ntree, sig, in_out, idname, name);
bNodeFunctionParameter param;
BLI_strncpy(param.name, name, sizeof(param.name));
param.socket_type = socket_type;
if (in_out == SOCK_IN) {
BLI_insertlinkbefore(&sig->inputs, next_sock, iosock);
bNodeFunctionParameter *old_params = sig->inputs;
sig->inputs = MEM_cnew_array<bNodeFunctionParameter>(sig->inputs_num + 1, __func__);
}
else if (in_out == SOCK_OUT) {
BLI_insertlinkbefore(&sig->outputs, next_sock, iosock);

View File

@ -1629,7 +1629,7 @@ typedef struct NodeShaderMix {
/* Input or output in a bNodeFunctionSignature. */
typedef struct bNodeFunctionParameter {
char name[64]; /* MAX_NAME */
char socket_type[64]; /* MAX_NAME */
int socket_type;
} bNodeFunctionParameter;
typedef struct bNodeFunctionSignature {

View File

@ -3282,48 +3282,6 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C,
/* ******** Node Function Signature ******** */
static int rna_NodeFunctionSignature_active_input_get(PointerRNA *ptr)
{
bNodeFunctionSignature *sig = (bNodeFunctionSignature *)ptr->data;
int index = 0;
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &sig->inputs, index) {
if (socket->flag & SELECT) {
return index;
}
}
return -1;
}
static void rna_NodeFunctionSignature_active_input_set(PointerRNA *ptr, int value)
{
bNodeFunctionSignature *sig = (bNodeFunctionSignature *)ptr->data;
int index = 0;
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &sig->inputs, index) {
SET_FLAG_FROM_TEST(socket->flag, index == value, SELECT);
}
}
static int rna_NodeFunctionSignature_active_output_get(PointerRNA *ptr)
{
bNodeFunctionSignature *sig = (bNodeFunctionSignature *)ptr->data;
int index = 0;
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &sig->outputs, index) {
if (socket->flag & SELECT) {
return index;
}
}
return -1;
}
static void rna_NodeFunctionSignature_active_output_set(PointerRNA *ptr, int value)
{
bNodeFunctionSignature *sig = (bNodeFunctionSignature *)ptr->data;
int index = 0;
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &sig->outputs, index) {
SET_FLAG_FROM_TEST(socket->flag, index == value, SELECT);
}
}
static bNodeSocket *rna_NodeFunctionSignature_inputs_new(ID *id,
bNodeFunctionSignature *sig,
Main *bmain,

View File

@ -625,7 +625,7 @@ static void update_input_properties_from_node_tree(const bNodeTree &tree,
if (new_prop == nullptr) {
/* Out of the set of supported input sockets, only
* geometry sockets aren't added to the modifier. */
BLI_assert(socket.type == SOCK_GEOMETRY);
BLI_assert(ELEM(socket.type, SOCK_GEOMETRY, SOCK_FUNCTION));
continue;
}

View File

@ -291,20 +291,77 @@ void node_group_declare_dynamic(const bNodeTree & /*node_tree*/,
}
}
SocketDeclarationPtr declaration_for_signature_parameter(const bNodeFunctionParameter &param,
eNodeSocketInOut in_out)
{
SocketDeclarationPtr dst;
switch (param.socket_type) {
case SOCK_FLOAT:
dst = std::make_unique<decl::Float>();
break;
case SOCK_VECTOR:
dst = std::make_unique<decl::Vector>();
break;
case SOCK_RGBA:
dst = std::make_unique<decl::Color>();
break;
case SOCK_SHADER:
dst = std::make_unique<decl::Shader>();
break;
case SOCK_BOOLEAN:
dst = std::make_unique<decl::Bool>();
break;
case SOCK_INT:
dst = std::make_unique<decl::Int>();
break;
case SOCK_STRING:
dst = std::make_unique<decl::String>();
break;
case SOCK_OBJECT:
dst = std::make_unique<decl::Object>();
break;
case SOCK_IMAGE:
dst = std::make_unique<decl::Image>();
break;
case SOCK_GEOMETRY:
dst = std::make_unique<decl::Geometry>();
break;
case SOCK_COLLECTION:
dst = std::make_unique<decl::Collection>();
break;
case SOCK_TEXTURE:
dst = std::make_unique<decl::Texture>();
break;
case SOCK_MATERIAL:
dst = std::make_unique<decl::Material>();
break;
case SOCK_FUNCTION:
dst = std::make_unique<decl::Function>();
break;
case SOCK_CUSTOM:
dst = std::make_unique<decl::Custom>();
break;
}
dst->name = param.name;
dst->in_out = in_out;
dst->hide_value = true;
dst->compact = false;
return dst;
}
void node_function_signature_declare(const bNodeFunctionSignature &sig,
const FieldInferencingInterface *field_interface,
NodeDeclaration &r_declaration)
{
int socket_i;
LISTBASE_FOREACH_INDEX (const bNodeSocket *, input, &sig.inputs, socket_i) {
SocketDeclarationPtr decl = declaration_for_interface_socket(*input);
for (const int socket_i : IndexRange(sig.inputs_num)) {
SocketDeclarationPtr decl = declaration_for_signature_parameter(sig.inputs[socket_i], SOCK_IN);
if (field_interface) {
decl->input_field_type = field_interface->inputs[socket_i];
}
r_declaration.inputs.append(std::move(decl));
}
LISTBASE_FOREACH_INDEX (const bNodeSocket *, output, &sig.outputs, socket_i) {
SocketDeclarationPtr decl = declaration_for_interface_socket(*output);
for (const int socket_i : IndexRange(sig.outputs_num)) {
SocketDeclarationPtr decl = declaration_for_signature_parameter(sig.outputs[socket_i], SOCK_OUT);
if (field_interface) {
decl->output_field_dependency = field_interface->outputs[socket_i];
}