Geometry Nodes: Expose texture and material inputs to modifier

This allows choosing material and texture sockets for the group input
node in the modifier. Note that currently grease pencil materials are
displayed in the list, even though grease pencil data is not supported
yet by geometry nodes. That is more complicated to fix in this case,
since we use IDProperties to store the dynamic exposed inputs.

Differential Revision: https://developer.blender.org/D11393
This commit is contained in:
Hans Goudey 2021-05-27 11:06:08 -04:00
parent 24b2482ad9
commit 3025c34825
Notes: blender-bot 2023-02-14 02:45:41 +01:00
Referenced by commit ca12d70af0, Cleanup: variable naming for texture/material SocketPropertyType
Referenced by issue #88701, Geometry Nodes: show "Show Texture in texture tab" button in modifier stack
Referenced by issue #88556, Texture input socket support in the modifier stack.
1 changed files with 82 additions and 7 deletions

View File

@ -36,6 +36,7 @@
#include "DNA_collection_types.h"
#include "DNA_defaults.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@ -123,6 +124,18 @@ static void addIdsUsedBySocket(const ListBase *sockets, Set<ID *> &ids)
ids.add(&collection->id);
}
}
else if (socket->type == SOCK_MATERIAL) {
Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value;
if (material != nullptr) {
ids.add(&material->id);
}
}
else if (socket->type == SOCK_TEXTURE) {
Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value;
if (texture != nullptr) {
ids.add(&texture->id);
}
}
}
}
@ -197,13 +210,25 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
find_used_ids_from_settings(nmd->settings, used_ids);
find_used_ids_from_nodes(*nmd->node_group, used_ids);
for (ID *id : used_ids) {
if (GS(id->name) == ID_OB) {
Object *object = reinterpret_cast<Object *>(id);
add_object_relation(ctx, *object);
}
if (GS(id->name) == ID_GR) {
Collection *collection = reinterpret_cast<Collection *>(id);
add_collection_relation(ctx, *collection);
switch ((ID_Type)GS(id->name)) {
case ID_OB: {
Object *object = reinterpret_cast<Object *>(id);
add_object_relation(ctx, *object);
break;
}
case ID_GR: {
Collection *collection = reinterpret_cast<Collection *>(id);
add_collection_relation(ctx, *collection);
break;
}
case ID_TE: {
DEG_add_generic_id_relation(ctx->node, id, "Nodes Modifier");
}
default: {
/* Purposefully don't add relations for materials. While there are material sockets,
* the pointers are only passed around as handles rather than dereferenced. */
break;
}
}
}
}
@ -558,6 +583,48 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
};
return &collection_type;
}
case SOCK_TEXTURE: {
static const SocketPropertyType collection_type = {
[](const bNodeSocket &socket, const char *name) {
bNodeSocketValueTexture *value = (bNodeSocketValueTexture *)socket.default_value;
IDPropertyTemplate idprop = {0};
idprop.id = (ID *)value->value;
return IDP_New(IDP_ID, &idprop, name);
},
nullptr,
nullptr,
nullptr,
nullptr,
[](const IDProperty &property) { return property.type == IDP_ID; },
[](const IDProperty &property, void *r_value) {
ID *id = IDP_Id(&property);
Tex *texture = (id && GS(id->name) == ID_TE) ? (Tex *)id : nullptr;
*(Tex **)r_value = texture;
},
};
return &collection_type;
}
case SOCK_MATERIAL: {
static const SocketPropertyType collection_type = {
[](const bNodeSocket &socket, const char *name) {
bNodeSocketValueMaterial *value = (bNodeSocketValueMaterial *)socket.default_value;
IDPropertyTemplate idprop = {0};
idprop.id = (ID *)value->value;
return IDP_New(IDP_ID, &idprop, name);
},
nullptr,
nullptr,
nullptr,
nullptr,
[](const IDProperty &property) { return property.type == IDP_ID; },
[](const IDProperty &property, void *r_value) {
ID *id = IDP_Id(&property);
Material *material = (id && GS(id->name) == ID_MA) ? (Material *)id : nullptr;
*(Material **)r_value = material;
},
};
return &collection_type;
}
default: {
return nullptr;
}
@ -1085,6 +1152,14 @@ static void draw_property_for_socket(uiLayout *layout,
ICON_OUTLINER_COLLECTION);
break;
}
case SOCK_MATERIAL: {
uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "materials", socket.name, ICON_MATERIAL);
break;
}
case SOCK_TEXTURE: {
uiItemPointerR(layout, md_ptr, rna_path, bmain_ptr, "textures", socket.name, ICON_TEXTURE);
break;
}
default:
uiItemR(layout, md_ptr, rna_path, 0, socket.name, ICON_NONE);
}