0e3b594edb
Part of modernizing scripts in Blender, where the previous convention was to use percentage formatting which has become the "old" way to format strings in Python. See proposal for details #120453. Ref !120552
106 lines
2.8 KiB
Python
106 lines
2.8 KiB
Python
# SPDX-FileCopyrightText: 2013-2023 Blender Authors
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import bpy
|
|
from nodeitems_utils import (
|
|
NodeCategory,
|
|
NodeItem,
|
|
NodeItemCustom,
|
|
)
|
|
|
|
|
|
# Subclasses for standard node types
|
|
|
|
class SortedNodeCategory(NodeCategory):
|
|
def __init__(self, identifier, name, description="", items=None):
|
|
# for builtin nodes the convention is to sort by name
|
|
if isinstance(items, list):
|
|
items = sorted(items, key=lambda item: item.label.lower())
|
|
|
|
super().__init__(identifier, name, description=description, items=items)
|
|
|
|
|
|
class CompositorNodeCategory(SortedNodeCategory):
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return (context.space_data.type == 'NODE_EDITOR' and
|
|
context.space_data.tree_type == 'CompositorNodeTree')
|
|
|
|
|
|
class ShaderNodeCategory(SortedNodeCategory):
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return (context.space_data.type == 'NODE_EDITOR' and
|
|
context.space_data.tree_type == 'ShaderNodeTree')
|
|
|
|
|
|
# Menu entry for node group tools.
|
|
def group_tools_draw(_self, layout, _context):
|
|
layout.operator("node.group_make")
|
|
layout.operator("node.group_ungroup")
|
|
layout.separator()
|
|
|
|
|
|
# Maps node tree type to group node type.
|
|
node_tree_group_type = {
|
|
'CompositorNodeTree': 'CompositorNodeGroup',
|
|
'ShaderNodeTree': 'ShaderNodeGroup',
|
|
'TextureNodeTree': 'TextureNodeGroup',
|
|
'GeometryNodeTree': 'GeometryNodeGroup',
|
|
}
|
|
|
|
|
|
# Generic node group items generator for shader, compositor, geometry and texture node groups.
|
|
def node_group_items(context):
|
|
if context is None:
|
|
return
|
|
space = context.space_data
|
|
if not space:
|
|
return
|
|
|
|
yield NodeItemCustom(draw=group_tools_draw)
|
|
|
|
if group_input_output_item_poll(context):
|
|
yield NodeItem("NodeGroupInput")
|
|
yield NodeItem("NodeGroupOutput")
|
|
|
|
ntree = space.edit_tree
|
|
if not ntree:
|
|
return
|
|
|
|
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
|
|
|
|
for group in context.blend_data.node_groups:
|
|
if group.bl_idname != ntree.bl_idname:
|
|
continue
|
|
# Filter out recursive groups.
|
|
if group.contains_tree(ntree):
|
|
continue
|
|
# Filter out hidden node-trees.
|
|
if group.name.startswith('.'):
|
|
continue
|
|
yield NodeItem(node_tree_group_type[group.bl_idname],
|
|
label=group.name,
|
|
settings={"node_tree": "bpy.data.node_groups[{!r}]".format(group.name)})
|
|
|
|
|
|
# only show input/output nodes inside node groups
|
|
def group_input_output_item_poll(context):
|
|
space = context.space_data
|
|
if space.edit_tree in bpy.data.node_groups.values():
|
|
return True
|
|
return False
|
|
|
|
|
|
def register():
|
|
pass
|
|
|
|
|
|
def unregister():
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
register()
|