Node Groups, NodeSocketInterface, and hide_value?


(SynaGl0w) #1

Generating node groups via python and some inputs need to have their value hidden in the UI, but I can’t figure out where this default is for a NodeSocketInterface.

The standard node socket instances have the “hide_value” property, but the inputs/outputs on the node tree don’t appear to have any such property.

Yet, the node tree socket interfaces retain a “hide_value” default somewhere when the node socket interface is added via dragging a link from a socket instance to any group IO node’s virtual socket.

Using the tree_socket_add operator to duplicate the active socket interface however does not copy the hide_value default.

So where is the “hide_value” default for a socket interface on a node tree? It’s obviously in there somewhere.


(Secrop) #2

It’s part of the nodegroup class, that uses socket interfaces (which are the ones that have the ‘hide_value’ parameter.
Also, it’s better to use the nodecustomgroup instead of the nodegroup. :wink:


(SynaGl0w) #3

Not sure what NodeCustomGroup has do with it. This is vanilla blender and a script creating standard node groups with vanilla tree types like: bpy.data.node_groups.new(“example”, “ShaderNodeTree”)

In this case I am referring to the NodeTree inputs and outputs. Not an instance of a NodeGroup node referring to the tree. Sure you can set the hide_value property on the sockets of a ShaderNodeGroup node, but that does not set the default value of it when a user adds a new instance of that group.

This has to do with the node tree inputs/outputs and their defaults, so when a user adds an instance of the group, the hide_value property on the instance is set to the default as specified by the node tree (wherever that is). What I am trying to do is find where this default is stored in the node tree.

For example: bpy.data.node_groups[“example”].inputs[0] does not appear to have any “hide_value” property, but does have a “default_value” property which works as expected.


(Secrop) #4

I can’t write a proper answer right now, but in the meanwhile check my gitbub page… I’ve some examples there.

But in short: nodetrees don’t really have an interface… So hide_value makes little sense there. The sockets interface is created by the nodegroup, that reads the Group_inputs and Group_outputs of the nodetree, and creates an interface automatically. With nodecustomgroups you get far more control in this and other topics around custom nodes for cycles.


(SynaGl0w) #5

Here is a demo file: hide_value.blend (83.5 KB)

It has a node group named “example” with two float inputs. In the node editor add the group from the “add->groups” menu. The second input has it’s value hidden by default, any time it’s added.

It is a vanilla “ShaderNodeTree” and when added uses a vanilla “ShaderNodeGroup” node without any need for python and custom node group classes. So the default state of that socket is stored somewhere associated with the node tree and its interface. Either it’s not in the node tree inputs and somewhere else, or the property is simply not accessible from python.

This default state attaches itself to the input of the group when a user manually links from a socket instance on an actual node (with whatever hide_value setting it has) to the virtual socket of the GroupInputNode to create the input.


(Secrop) #6

I’ll give it a look when at home.


(SynaGl0w) #7

Found it in the actual blend file… LOL


Most significant bit of the marked bytes. Input 0 and Input 1. Set the bit to 1 and hide_value is true by default. I know this is useless, but hey. Confirmation it is stored in the node tree… somewhere.


(Secrop) #8

That’s quite strange… perhaps it’s hidden on purpose… (I took a quick look at the code, but didn’t find nothing relevant to this… perhaps it’s deep in the huge rna_nodetree.c)


(SynaGl0w) #9

Yeah in the blend file its in with the node tree inputs/outputs, yet when loaded in blender the inputs/outputs contain nothing related to a hide_value flag. In the file you do see other components of NodeSocketInferface like the name, identifier, bl_socket_idname, etc.

There is an “interface” property of the NodeGroupInput/Output node. It seems to be a property group type registered the moment an input or output is added(changed?) to a node tree. Not sure what’s in it.

I was browsing rna_nodetree.c as well. I’ll have to eventually load up my debug build to try to figure this out.


(SynaGl0w) #10

void node_socket_copy_default_value(bNodeSocket *to, bNodeSocket *from)
Found that in node_socket.c

At the bottom of the function:
to->flag |= (from->flag & SOCK_HIDE_VALUE);


(SynaGl0w) #11

Finally had some time to sit down and look at this today. Took a look through DNA_node_types.h and bNodeSocket.


Solution:

<b>from ctypes import c_short
</b>
#Hide value true:
<b>c_short.from_address(D.node_groups["test"].inputs[0].as_pointer()+0xAA).value |= 128
</b>
#Hide value false:
<b>c_short.from_address(D.node_groups["test"].inputs[0].as_pointer()+0xAA).value ^= 128</b>

From eNodeSocketFlag:

SOCK_HIDDEN = 2,                    /* hidden is user defined, to hide unused */
SOCK_IN_USE = 4,                    /* for quick check if socket is linked */
SOCK_UNAVAIL = 8,                    /* unavailable is for dynamic sockets */
// SOCK_DYNAMIC = 16,                /* DEPRECATED  dynamic socket (can be modified by user) */
// SOCK_INTERNAL = 32,                /* DEPRECATED  group socket should not be exposed */
SOCK_COLLAPSED = 64,                /* socket collapsed in UI */
SOCK_HIDE_VALUE = 128,                /* hide socket value, if it gets auto default */
SOCK_AUTO_HIDDEN__DEPRECATED = 256,    /* socket hidden automatically, to distinguish from manually hidden */
SOCK_NO_INTERNAL_LINK = 512

(B.Y.O.B.) #12
#Hide value false:
<b>c_short.from_address(D.node_groups["test"].inputs[0].as_pointer()+0xAA).value ^= 128

Technically this does not set the value to false, it toggles the value (so if it’s already false, it will be flipped to true).
To set it to false, negate your bitmask (~) and use the and operator:

#Hide value false:
<b>c_short.from_address(D.node_groups["test"].inputs[0].as_pointer()+0xAA).value &= ~128

(SynaGl0w) #13

Oops! my bad… I copied the line I used on my toggle operator. lol.

I’ll edit that. Thanks.