Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Oeser <info@graphics-engineer.com>2021-02-03 16:39:24 +0300
committerPhilipp Oeser <info@graphics-engineer.com>2021-03-02 14:08:44 +0300
commitb279fef85d1a561ceb71e2cdce458bd44b4d853a (patch)
treec62de6e0a676b2413a38b31d4f3c05f900c8a245
parent00f27a85689ba52d77924a7f7741f724caf831de (diff)
Geometry Nodes: show "Show Texture in texture tab" button
This enables the quick access button [to show the relevant Texture in the Properties Editor] for textures used in geometry nodes. This goes in line to what we do for other textures: - modifier textures have this button - particle textures have this button - brush textures will soon have it, too (see D9813) When outside of the Properties Editor, the button will always show (if a texture is actually assigned), but will be inactive if no suiting Properties Editor to show the texture in can be found. Note this also changes the behavior to not show the button if _no_ texture is assigned (as in: we are still showing the "New" button). Previously it was always there (e.g. for modifier textures), even if it would take us to an empty texture tab. (Sure, we could add a texture there then, but imho it makes more sense to just start showing it once a texture is already there) For this to work with geometry nodes, the following chages were done: - implement foreachTexLink for geonode modifiers - new buttons_texture_user_node_property_add() that stores prop as well as node - also use NODE_ACTIVE_TEXTURE flag in geometry nodetrees notes: - this still uses the first suiting (as in: pinning does not interfere) Properties Editor it finds, this should (maybe?) find the _closest_ Property Editor instead (see related feedback in D9813). - this will already show the button for brush textures as well (disabled), but there is another mandatory change in an upcomming commit to make it work there as well (see D9813) ref. T85278 Maniphest Tasks: T85278 Differential Revision: https://developer.blender.org/D10293
-rw-r--r--source/blender/blenkernel/intern/node.cc6
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c251
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc7
3 files changed, 204 insertions, 60 deletions
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 4d52a14b742..55cb0d5cce4 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -3555,7 +3555,8 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
tnode->flag &= ~NODE_ACTIVE_ID;
}
}
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
+ if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
+ (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) {
tnode->flag &= ~NODE_ACTIVE_TEXTURE;
}
}
@@ -3564,7 +3565,8 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
if (node->id) {
node->flag |= NODE_ACTIVE_ID;
}
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
+ if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
+ (node->typeinfo->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE)) {
node->flag |= NODE_ACTIVE_TEXTURE;
}
}
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 4847e8738df..43128ed00fa 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -64,13 +64,42 @@
#include "ED_screen.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "../interface/interface_intern.h"
#include "buttons_intern.h" /* own include */
+static ScrArea *find_area_properties(const bContext *C);
+static SpaceProperties *find_space_properties(const bContext *C);
+
/************************* Texture User **************************/
+static void buttons_texture_user_node_property_add(ListBase *users,
+ ID *id,
+ PointerRNA ptr,
+ PropertyRNA *prop,
+ bNodeTree *ntree,
+ bNode *node,
+ const char *category,
+ int icon,
+ const char *name)
+{
+ ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser");
+
+ user->id = id;
+ user->ptr = ptr;
+ user->prop = prop;
+ user->ntree = ntree;
+ user->node = node;
+ user->category = category;
+ user->icon = icon;
+ user->name = name;
+ user->index = BLI_listbase_count(users);
+
+ BLI_addtail(users, user);
+}
+
static void buttons_texture_user_property_add(ListBase *users,
ID *id,
PointerRNA ptr,
@@ -139,20 +168,66 @@ static void buttons_texture_users_find_nodetree(ListBase *users,
}
}
+static void buttons_texture_modifier_geonodes_users_add(Object *ob,
+ NodesModifierData *nmd,
+ bNodeTree *node_tree,
+ ListBase *users)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
+ if (node->type == NODE_GROUP && node->id) {
+ /* Recurse into the node group */
+ buttons_texture_modifier_geonodes_users_add(ob, nmd, (bNodeTree *)node->id, users);
+ }
+ else if (node->type == GEO_NODE_ATTRIBUTE_SAMPLE_TEXTURE) {
+ RNA_pointer_create(&node_tree->id, &RNA_Node, node, &ptr);
+ prop = RNA_struct_find_property(&ptr, "texture");
+ if (prop == NULL) {
+ continue;
+ }
+
+ PointerRNA texptr = RNA_property_pointer_get(&ptr, prop);
+ Tex *tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? (Tex *)texptr.data : NULL;
+ if (tex != NULL) {
+ buttons_texture_user_node_property_add(users,
+ &ob->id,
+ ptr,
+ prop,
+ node_tree,
+ node,
+ N_("Geometry Nodes"),
+ RNA_struct_ui_icon(ptr.type),
+ nmd->modifier.name);
+ }
+ }
+ }
+}
+
static void buttons_texture_modifier_foreach(void *userData,
Object *ob,
ModifierData *md,
const char *propname)
{
- PointerRNA ptr;
- PropertyRNA *prop;
ListBase *users = userData;
- RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
- prop = RNA_struct_find_property(&ptr, propname);
+ if (md->type == eModifierType_Nodes) {
+ NodesModifierData *nmd = (NodesModifierData *)md;
+ if (nmd->node_group != NULL) {
+ buttons_texture_modifier_geonodes_users_add(ob, nmd, nmd->node_group, users);
+ }
+ }
+ else {
+ PointerRNA ptr;
+ PropertyRNA *prop;
- buttons_texture_user_property_add(
- users, &ob->id, ptr, prop, N_("Modifiers"), RNA_struct_ui_icon(ptr.type), md->name);
+ RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
+ prop = RNA_struct_find_property(&ptr, propname);
+
+ buttons_texture_user_property_add(
+ users, &ob->id, ptr, prop, N_("Modifiers"), RNA_struct_ui_icon(ptr.type), md->name);
+ }
}
static void buttons_texture_modifier_gpencil_foreach(void *userData,
@@ -325,31 +400,32 @@ void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts)
ct->texture = NULL;
if (ct->user) {
+ if (ct->user->node != NULL) {
+ /* Detect change of active texture node in same node tree, in that
+ * case we also automatically switch to the other node. */
+ if ((ct->user->node->flag & NODE_ACTIVE_TEXTURE) == 0) {
+ ButsTextureUser *user;
+ for (user = ct->users.first; user; user = user->next) {
+ if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
+ if (user->node->flag & NODE_ACTIVE_TEXTURE) {
+ ct->user = user;
+ ct->index = BLI_findindex(&ct->users, user);
+ break;
+ }
+ }
+ }
+ }
+ }
if (ct->user->ptr.data) {
PointerRNA texptr;
Tex *tex;
- /* get texture datablock pointer if it's a property */
+ /* Get texture datablock pointer if it's a property. */
texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? texptr.data : NULL;
ct->texture = tex;
}
- else if (ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) {
- ButsTextureUser *user;
-
- /* detect change of active texture node in same node tree, in that
- * case we also automatically switch to the other node */
- for (user = ct->users.first; user; user = user->next) {
- if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
- if (user->node->flag & NODE_ACTIVE_TEXTURE) {
- ct->user = user;
- ct->index = BLI_findindex(&ct->users, user);
- break;
- }
- }
- }
- }
}
}
}
@@ -357,7 +433,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts)
static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg))
{
/* callback when selecting a texture user in the menu */
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
+ SpaceProperties *sbuts = find_space_properties(C);
ButsContextTexture *ct = (sbuts) ? sbuts->texuser : NULL;
ButsTextureUser *user = (ButsTextureUser *)user_p;
PointerRNA texptr;
@@ -371,8 +447,15 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)
if (user->node) {
ED_node_set_active(CTX_data_main(C), user->ntree, user->node, NULL);
ct->texture = NULL;
+
+ /* Not totally sure if we should also change selection? */
+ LISTBASE_FOREACH (bNode *, node, &user->ntree->nodes) {
+ nodeSetSelected(node, false);
+ }
+ nodeSetSelected(user->node, true);
+ WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL);
}
- else {
+ if (user->ptr.data) {
texptr = RNA_property_pointer_get(&user->ptr, user->prop);
tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? texptr.data : NULL;
@@ -511,16 +594,53 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
/************************* Texture Show **************************/
+static ScrArea *find_area_properties(const bContext *C)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ Object *ob = CTX_data_active_object(C);
+
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ if (area->spacetype == SPACE_PROPERTIES) {
+ /* Only if unpinned, or if pinned object matches. */
+ SpaceProperties *sbuts = area->spacedata.first;
+ ID *pinid = sbuts->pinid;
+ if (pinid == NULL || ((GS(pinid->name) == ID_OB) && (Object *)pinid == ob)) {
+ return area;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static SpaceProperties *find_space_properties(const bContext *C)
+{
+ ScrArea *area = find_area_properties(C);
+ if (area != NULL) {
+ return area->spacedata.first;
+ }
+
+ return NULL;
+}
+
static void template_texture_show(bContext *C, void *data_p, void *prop_p)
{
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- ButsContextTexture *ct = (sbuts) ? sbuts->texuser : NULL;
- ButsTextureUser *user;
+ if (data_p == NULL || prop_p == NULL) {
+ return;
+ }
+
+ ScrArea *area = find_area_properties(C);
+ if (area == NULL) {
+ return;
+ }
+ SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
+ ButsContextTexture *ct = (sbuts) ? sbuts->texuser : NULL;
if (!ct) {
return;
}
+ ButsTextureUser *user;
for (user = ct->users.first; user; user = user->next) {
if (user->ptr.data == data_p && user->prop == prop_p) {
break;
@@ -537,48 +657,65 @@ static void template_texture_show(bContext *C, void *data_p, void *prop_p)
sbuts->preview = 1;
/* redraw editor */
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(area);
}
}
+/* Button to quickly show texture in Properties Editor texture tab. */
void uiTemplateTextureShow(uiLayout *layout, const bContext *C, PointerRNA *ptr, PropertyRNA *prop)
{
- /* button to quickly show texture in texture tab */
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
- ButsContextTexture *ct = (sbuts) ? sbuts->texuser : NULL;
- ButsTextureUser *user;
+ /* Only show the button if there is actually a texture assigned. */
+ Tex *texture = RNA_property_pointer_get(ptr, prop).data;
+ if (texture == NULL) {
+ return;
+ }
- /* only show button in other tabs in properties editor */
- if (!ct || sbuts->mainb == BCONTEXT_TEXTURE) {
+ /* Only show the button if we are not in the Properties Editor's texture tab. */
+ SpaceProperties *sbuts_context = CTX_wm_space_properties(C);
+ if (sbuts_context != NULL && sbuts_context->mainb == BCONTEXT_TEXTURE) {
return;
}
+ SpaceProperties *sbuts = find_space_properties(C);
+ ButsContextTexture *ct = (sbuts) ? sbuts->texuser : NULL;
+
/* find corresponding texture user */
- for (user = ct->users.first; user; user = user->next) {
- if (user->ptr.data == ptr->data && user->prop == prop) {
- break;
+ ButsTextureUser *user;
+ bool user_found = false;
+ if (ct != NULL) {
+ for (user = ct->users.first; user; user = user->next) {
+ if (user->ptr.data == ptr->data && user->prop == prop) {
+ user_found = true;
+ break;
+ }
}
}
- /* draw button */
- if (user) {
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but;
-
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_PROPERTIES,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Show texture in texture tab"));
- UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop);
+ /* Draw button (disabled if we cannot find a Properties Editor to display this in). */
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but;
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_PROPERTIES,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Show texture in texture tab"));
+ UI_but_func_set(but,
+ template_texture_show,
+ user_found ? user->ptr.data : NULL,
+ user_found ? user->prop : NULL);
+ if (ct == NULL) {
+ UI_but_disable(but, TIP_("No (unpinned) Properties Editor found to display texture in"));
+ }
+ else if (!user_found) {
+ UI_but_disable(but, TIP_("No texture user found"));
}
}
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index c7731815a2a..b47f5806c9c 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -233,6 +233,11 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u
&settings);
}
+static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void *userData)
+{
+ walk(userData, ob, md, "texture");
+}
+
static bool isDisabled(const struct Scene *UNUSED(scene),
ModifierData *md,
bool UNUSED(useRenderParams))
@@ -1348,7 +1353,7 @@ ModifierTypeInfo modifierType_Nodes = {
/* dependsOnTime */ nullptr,
/* dependsOnNormals */ nullptr,
/* foreachIDLink */ foreachIDLink,
- /* foreachTexLink */ nullptr,
+ /* foreachTexLink */ foreachTexLink,
/* freeRuntimeData */ nullptr,
/* panelRegister */ panelRegister,
/* blendWrite */ blendWrite,