How can I recognize node/tree/group created by addon?

My add-on creates a shader node tree and encloses it in node group.
I want to have some side panel tools to add some tweaks, rearrange links, etc.
For this to work I need to make Panel.poll operator to check if the active nodetree has been created by the add-on.

Using names doesn’t seem right, because user can naturally rename the node group.
Analysing tree structure to search for particular nodes is very heavy operation for poll, which is called on every click.

Is there any other way?

P.S.
Also, cannot find a way to determine an ‘active_nodetree’, when a node group is opened.
An active_node doesn’t seem to have any references to nodetree it belongs.

Nodes have a draw call specific for the Tools panel, which is draw_buttons_ext(self, context, layout).

However, you shouldn’t enclose your nodetree into a Nodegroup node, but in a bpy.types.ShaderNodeCustomGroup class.

It’s part of the Editor, as each editor can have it’s own set of node_trees:
bpy.context.window.screen.areas[idx].spaces[0].path.items()[-1][1].node_tree

Oh! Thanks.

Using the ShaderNodeCustomGroup seems to solve a lot of issues.

It’s its purpose! :slight_smile:
Not only it can do much more than nodegroups, it also has a better UI.
I have some examples here.

2 Likes

Nice! I’ve just implemented exactly like that ShaderNodeBase :slight_smile:

BTW, You use an undocumented property NodeTree.is_hidden.
What is it?

oh… that’s an old thing that I forgot to remove, as it’s part of the 2.7x version of the addon.

Prior to 2.80, all node_trees were listed in the Add menu… The only way I figured to change that (because there’s no need to have private node_trees visible), was to replace the function for drawing the menu and to add an is_hidden property to node_trees…

However that has changed, and now we only need to add a ‘.’ to the beggining of the node_tree’s name.
So if a node_tree’s name is like ".my_custom_nodetree", it won’t show in the add menu, neither in the dropdown from the GroupNode.

I’m planning to turn most of the functions in ShaderNodeBase into a function library… The plan is for the users to inherit directly from XxxxNodeCustomGroup, and just import the library if they need it. Also, this is planned to be integrated directly in the Preferences Editor, so each individual node will be treated as an addon.

That’s a nice hack to know!

My add-on also tends to be a library, but a library of tricky nodes.

Construction of fabric texture cannot fit into single node with simple parameters, but it needs a bunch of nodes with links and tweaks between them.

It seems like the best way is to provide main components as custom nodes available from dedicated ‘add’ submenu. And a separate blend-library of samples as a material templates.

Well… It’s really something that was done for this purpose. Though it’s not documented.

BrickTricks addon works in a similar way. You might also want to have a look on those. :wink:

Speaking of utility library, I found it’s more convenient to use procedural approach with references to nodes, instead of name paths.

Like this:

    xyz = self.add_node(
        'ShaderNodeSeparateXYZ',
        inputs={0: ('input', 'vector')})

    weft = self.add_node(
        PFcosine,
        inputs={
            't': self.add_math('ADD', (xyz, 'X'), self.add_math('FLOOR', (xyz, 'Y'))),
            'period': 2.0,
            'shift': -0.25,
        })
    warp = self.add_node(
        PFcosine,
        inputs={
            't': self.add_math('ADD', (xyz, 'Y'), self.add_math('FLOOR', (xyz, 'X'))),
            'period': 2.0,
            'shift': +0.25,
        })

    out = self.add_rgb(weft, warp)

    self.add_link(out, ('output', 'waves'))