blender/release/scripts/startup/bl_operators/node.py

287 lines
9.6 KiB
Python
Raw Normal View History

# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8-80 compliant>
import bpy
Replacing the node Add menu and making the toolbar useful As some people have already noticed, the "Add" menu for nodes is a bit messy since pynodes merge. The reason for this is that the order of nodes in submenus (categories) was previously defined by the order in which all nodes are registered (at the bottom of blenkernel/intern/node.c). For the dynamic registration of node types now possible this system of defining node order along with registration is no longer viable: while it would still sort of work for C nodes, it is completely meaningless for dynamic (python) nodes, which are basically registered automatically in whatever order modules and addons are loaded, with the added complexity of unloading and reloading. To fix this problem and add a bunch of desirable features this commit replaces the C menu with a python implementation. The new menu does not rely on any particular order of types in the node registry, but instead uses a simple explicit list of all the available nodes, grouped by categories (in scripts/nodeitems_builtins.py). There are a number of additional features that become possible with this implementation: 1) Node Toolbar can be populated! The list of nodes is used to create 2 UI items for each node: 1 entry in a submenu of "Add" menu and 1 item in a node toolbar panel with basically the same functionality. Clicking a button in the toolbar will add a new node of this type, just like selecting an item in the menu. The toolbar has the advantage of having collapsible panels for each category, so users can decide if they don't need certain nodes categories and have the rest more easily accessible. 2) Each node item is a true operator call. The old Add menu is a pretty old piece of C code which doesn't even use proper operator buttons. Now there is a generic node_add operator which can be used very flexibly for adding any of the available nodes. 3) Node Items support additional settings. Each "NodeItem" consists of the basic node type plus an optional list of initial settings that shall be applied to a new instance. This gives additional flexibility for creating variants of the same node or for defining preferred initial settings. E.g. it has been requested to disable previews for all nodes except inputs, this would be simple change in the py code and much less intrusive than in C. 4) Node items can be generated with a function. A callback can be used in any category instead of the fixed list, which generates a set of items based on the context (much like dynamic enum items in bpy.props). Originally this was implemented for group nodes, because these nodes only make sense when linked to a node tree from the library data. This principle could come in handy for a number of other nodes, e.g. Image nodes could provide a similar list of node variants based on images in the library - no need to first add node, then select an image. WARNING: pynodes scripters will have to rework their "draw_add_menu" callback in node tree types, this has been removed now! It was already pretty redundant, since one can add draw functions to the Add menu just like for any other menu. In the future i'd like to improve the categories system further so scripters can use it for custom node systems too, for now just make a draw callback and attach it to the Add menu.
2013-04-13 15:38:02 +00:00
from bpy.types import Operator, PropertyGroup
from bpy.props import BoolProperty, CollectionProperty, EnumProperty, IntProperty, StringProperty
2013-01-15 23:15:32 +00:00
class NodeSetting(PropertyGroup):
value = StringProperty(
name="Value",
description="Python expression to be evaluated as the initial node setting",
default="",
)
# Base class for node 'Add' operators
class NodeAddOperator():
type = StringProperty(
name="Node Type",
description="Node type",
)
use_transform = BoolProperty(
name="Use Transform",
description="Start transform operator after inserting the node",
default=False,
)
settings = CollectionProperty(
name="Settings",
description="Settings to be applied on the newly created node",
type=NodeSetting,
options={'SKIP_SAVE'},
)
@staticmethod
def store_mouse_cursor(context, event):
space = context.space_data
v2d = context.region.view2d
tree = space.edit_tree
# convert mouse position to the View2D for later node placement
if context.region.type == 'WINDOW':
space.cursor_location = v2d.region_to_view(event.mouse_region_x,
event.mouse_region_y)
else:
space.cursor_location = tree.view_center
def create_node(self, context):
space = context.space_data
tree = space.edit_tree
# select only the new node
for n in tree.nodes:
n.select = False
node = tree.nodes.new(type=self.type)
for setting in self.settings:
# XXX catch exceptions here?
value = eval(setting.value)
try:
setattr(node, setting.name, value)
except AttributeError as e:
self.report({'ERROR_INVALID_INPUT'}, "Node has no attribute "+setting.name)
print (str(e))
# Continue despite invalid attribute
if space.use_hidden_preview:
node.show_preview = False
node.select = True
tree.nodes.active = node
node.location = space.cursor_location
return node
@classmethod
def poll(cls, context):
space = context.space_data
# needs active node editor and a tree to add nodes to
return (space.type == 'NODE_EDITOR' and space.edit_tree)
# Default execute simply adds a node
def execute(self, context):
self.create_node(context)
return {'FINISHED'}
# Default invoke stores the mouse position to place the node correctly
# and optionally invokes the transform operator
def invoke(self, context, event):
self.store_mouse_cursor(context, event)
result = self.execute(context)
if self.use_transform and ('FINISHED' in result):
bpy.ops.transform.translate('INVOKE_DEFAULT')
return result
Replacing the node Add menu and making the toolbar useful As some people have already noticed, the "Add" menu for nodes is a bit messy since pynodes merge. The reason for this is that the order of nodes in submenus (categories) was previously defined by the order in which all nodes are registered (at the bottom of blenkernel/intern/node.c). For the dynamic registration of node types now possible this system of defining node order along with registration is no longer viable: while it would still sort of work for C nodes, it is completely meaningless for dynamic (python) nodes, which are basically registered automatically in whatever order modules and addons are loaded, with the added complexity of unloading and reloading. To fix this problem and add a bunch of desirable features this commit replaces the C menu with a python implementation. The new menu does not rely on any particular order of types in the node registry, but instead uses a simple explicit list of all the available nodes, grouped by categories (in scripts/nodeitems_builtins.py). There are a number of additional features that become possible with this implementation: 1) Node Toolbar can be populated! The list of nodes is used to create 2 UI items for each node: 1 entry in a submenu of "Add" menu and 1 item in a node toolbar panel with basically the same functionality. Clicking a button in the toolbar will add a new node of this type, just like selecting an item in the menu. The toolbar has the advantage of having collapsible panels for each category, so users can decide if they don't need certain nodes categories and have the rest more easily accessible. 2) Each node item is a true operator call. The old Add menu is a pretty old piece of C code which doesn't even use proper operator buttons. Now there is a generic node_add operator which can be used very flexibly for adding any of the available nodes. 3) Node Items support additional settings. Each "NodeItem" consists of the basic node type plus an optional list of initial settings that shall be applied to a new instance. This gives additional flexibility for creating variants of the same node or for defining preferred initial settings. E.g. it has been requested to disable previews for all nodes except inputs, this would be simple change in the py code and much less intrusive than in C. 4) Node items can be generated with a function. A callback can be used in any category instead of the fixed list, which generates a set of items based on the context (much like dynamic enum items in bpy.props). Originally this was implemented for group nodes, because these nodes only make sense when linked to a node tree from the library data. This principle could come in handy for a number of other nodes, e.g. Image nodes could provide a similar list of node variants based on images in the library - no need to first add node, then select an image. WARNING: pynodes scripters will have to rework their "draw_add_menu" callback in node tree types, this has been removed now! It was already pretty redundant, since one can add draw functions to the Add menu just like for any other menu. In the future i'd like to improve the categories system further so scripters can use it for custom node systems too, for now just make a draw callback and attach it to the Add menu.
2013-04-13 15:38:02 +00:00
# Simple basic operator for adding a node
class NODE_OT_add_node(NodeAddOperator, Operator):
'''Add a node to the active tree'''
bl_idname = "node.add_node"
bl_label = "Add Node"
# Add a node and link it to an existing socket
class NODE_OT_add_and_link_node(NodeAddOperator, Operator):
'''Add a node to the active tree and link to an existing socket'''
bl_idname = "node.add_and_link_node"
bl_label = "Add and Link Node"
link_socket_index = IntProperty(
name="Link Socket Index",
description="Index of the socket to link",
Replacing the node Add menu and making the toolbar useful As some people have already noticed, the "Add" menu for nodes is a bit messy since pynodes merge. The reason for this is that the order of nodes in submenus (categories) was previously defined by the order in which all nodes are registered (at the bottom of blenkernel/intern/node.c). For the dynamic registration of node types now possible this system of defining node order along with registration is no longer viable: while it would still sort of work for C nodes, it is completely meaningless for dynamic (python) nodes, which are basically registered automatically in whatever order modules and addons are loaded, with the added complexity of unloading and reloading. To fix this problem and add a bunch of desirable features this commit replaces the C menu with a python implementation. The new menu does not rely on any particular order of types in the node registry, but instead uses a simple explicit list of all the available nodes, grouped by categories (in scripts/nodeitems_builtins.py). There are a number of additional features that become possible with this implementation: 1) Node Toolbar can be populated! The list of nodes is used to create 2 UI items for each node: 1 entry in a submenu of "Add" menu and 1 item in a node toolbar panel with basically the same functionality. Clicking a button in the toolbar will add a new node of this type, just like selecting an item in the menu. The toolbar has the advantage of having collapsible panels for each category, so users can decide if they don't need certain nodes categories and have the rest more easily accessible. 2) Each node item is a true operator call. The old Add menu is a pretty old piece of C code which doesn't even use proper operator buttons. Now there is a generic node_add operator which can be used very flexibly for adding any of the available nodes. 3) Node Items support additional settings. Each "NodeItem" consists of the basic node type plus an optional list of initial settings that shall be applied to a new instance. This gives additional flexibility for creating variants of the same node or for defining preferred initial settings. E.g. it has been requested to disable previews for all nodes except inputs, this would be simple change in the py code and much less intrusive than in C. 4) Node items can be generated with a function. A callback can be used in any category instead of the fixed list, which generates a set of items based on the context (much like dynamic enum items in bpy.props). Originally this was implemented for group nodes, because these nodes only make sense when linked to a node tree from the library data. This principle could come in handy for a number of other nodes, e.g. Image nodes could provide a similar list of node variants based on images in the library - no need to first add node, then select an image. WARNING: pynodes scripters will have to rework their "draw_add_menu" callback in node tree types, this has been removed now! It was already pretty redundant, since one can add draw functions to the Add menu just like for any other menu. In the future i'd like to improve the categories system further so scripters can use it for custom node systems too, for now just make a draw callback and attach it to the Add menu.
2013-04-13 15:38:02 +00:00
)
2013-01-15 23:15:32 +00:00
def execute(self, context):
space = context.space_data
ntree = space.edit_tree
node = self.create_node(context)
if not node:
return {'CANCELLED'}
to_socket = getattr(context, "link_to_socket", None)
if to_socket:
ntree.links.new(node.outputs[self.link_socket_index], to_socket)
Replacing the node Add menu and making the toolbar useful As some people have already noticed, the "Add" menu for nodes is a bit messy since pynodes merge. The reason for this is that the order of nodes in submenus (categories) was previously defined by the order in which all nodes are registered (at the bottom of blenkernel/intern/node.c). For the dynamic registration of node types now possible this system of defining node order along with registration is no longer viable: while it would still sort of work for C nodes, it is completely meaningless for dynamic (python) nodes, which are basically registered automatically in whatever order modules and addons are loaded, with the added complexity of unloading and reloading. To fix this problem and add a bunch of desirable features this commit replaces the C menu with a python implementation. The new menu does not rely on any particular order of types in the node registry, but instead uses a simple explicit list of all the available nodes, grouped by categories (in scripts/nodeitems_builtins.py). There are a number of additional features that become possible with this implementation: 1) Node Toolbar can be populated! The list of nodes is used to create 2 UI items for each node: 1 entry in a submenu of "Add" menu and 1 item in a node toolbar panel with basically the same functionality. Clicking a button in the toolbar will add a new node of this type, just like selecting an item in the menu. The toolbar has the advantage of having collapsible panels for each category, so users can decide if they don't need certain nodes categories and have the rest more easily accessible. 2) Each node item is a true operator call. The old Add menu is a pretty old piece of C code which doesn't even use proper operator buttons. Now there is a generic node_add operator which can be used very flexibly for adding any of the available nodes. 3) Node Items support additional settings. Each "NodeItem" consists of the basic node type plus an optional list of initial settings that shall be applied to a new instance. This gives additional flexibility for creating variants of the same node or for defining preferred initial settings. E.g. it has been requested to disable previews for all nodes except inputs, this would be simple change in the py code and much less intrusive than in C. 4) Node items can be generated with a function. A callback can be used in any category instead of the fixed list, which generates a set of items based on the context (much like dynamic enum items in bpy.props). Originally this was implemented for group nodes, because these nodes only make sense when linked to a node tree from the library data. This principle could come in handy for a number of other nodes, e.g. Image nodes could provide a similar list of node variants based on images in the library - no need to first add node, then select an image. WARNING: pynodes scripters will have to rework their "draw_add_menu" callback in node tree types, this has been removed now! It was already pretty redundant, since one can add draw functions to the Add menu just like for any other menu. In the future i'd like to improve the categories system further so scripters can use it for custom node systems too, for now just make a draw callback and attach it to the Add menu.
2013-04-13 15:38:02 +00:00
from_socket = getattr(context, "link_from_socket", None)
if from_socket:
ntree.links.new(from_socket, node.inputs[self.link_socket_index])
Replacing the node Add menu and making the toolbar useful As some people have already noticed, the "Add" menu for nodes is a bit messy since pynodes merge. The reason for this is that the order of nodes in submenus (categories) was previously defined by the order in which all nodes are registered (at the bottom of blenkernel/intern/node.c). For the dynamic registration of node types now possible this system of defining node order along with registration is no longer viable: while it would still sort of work for C nodes, it is completely meaningless for dynamic (python) nodes, which are basically registered automatically in whatever order modules and addons are loaded, with the added complexity of unloading and reloading. To fix this problem and add a bunch of desirable features this commit replaces the C menu with a python implementation. The new menu does not rely on any particular order of types in the node registry, but instead uses a simple explicit list of all the available nodes, grouped by categories (in scripts/nodeitems_builtins.py). There are a number of additional features that become possible with this implementation: 1) Node Toolbar can be populated! The list of nodes is used to create 2 UI items for each node: 1 entry in a submenu of "Add" menu and 1 item in a node toolbar panel with basically the same functionality. Clicking a button in the toolbar will add a new node of this type, just like selecting an item in the menu. The toolbar has the advantage of having collapsible panels for each category, so users can decide if they don't need certain nodes categories and have the rest more easily accessible. 2) Each node item is a true operator call. The old Add menu is a pretty old piece of C code which doesn't even use proper operator buttons. Now there is a generic node_add operator which can be used very flexibly for adding any of the available nodes. 3) Node Items support additional settings. Each "NodeItem" consists of the basic node type plus an optional list of initial settings that shall be applied to a new instance. This gives additional flexibility for creating variants of the same node or for defining preferred initial settings. E.g. it has been requested to disable previews for all nodes except inputs, this would be simple change in the py code and much less intrusive than in C. 4) Node items can be generated with a function. A callback can be used in any category instead of the fixed list, which generates a set of items based on the context (much like dynamic enum items in bpy.props). Originally this was implemented for group nodes, because these nodes only make sense when linked to a node tree from the library data. This principle could come in handy for a number of other nodes, e.g. Image nodes could provide a similar list of node variants based on images in the library - no need to first add node, then select an image. WARNING: pynodes scripters will have to rework their "draw_add_menu" callback in node tree types, this has been removed now! It was already pretty redundant, since one can add draw functions to the Add menu just like for any other menu. In the future i'd like to improve the categories system further so scripters can use it for custom node systems too, for now just make a draw callback and attach it to the Add menu.
2013-04-13 15:38:02 +00:00
return {'FINISHED'}
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
def node_classes_iter(base=bpy.types.Node):
"""
Yields all true node classes by checking for the is_registered_node_type classmethod.
Node types can use specialized subtypes of bpy.types.Node, which are not usable
nodes themselves (e.g. CompositorNode).
"""
if base.is_registered_node_type():
yield base
for subclass in base.__subclasses__():
for node_class in node_classes_iter(subclass):
yield node_class
def node_class_items_iter(node_class, context):
identifier = node_class.bl_rna.identifier
# XXX Checking for explicit group node types is stupid.
# This should be replaced by a generic system of generating
# node items via callback.
# Group node_tree pointer should also use a poll function to filter the library list,
# but cannot do that without a node instance here. A node callback could just use the internal poll function.
if identifier in {'ShaderNodeGroup', 'CompositorNodeGroup', 'TextureNodeGroup'}:
tree_idname = context.space_data.edit_tree.bl_idname
for group in bpy.data.node_groups:
if group.bl_idname == tree_idname:
# XXX empty string should be replaced by description from tree
yield (group.name, "", {"node_tree": group})
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
else:
yield (node_class.bl_rna.name, node_class.bl_rna.description, {})
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
def node_items_iter(context):
snode = context.space_data
if not snode:
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
return
tree = snode.edit_tree
if not tree:
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
return
for node_class in node_classes_iter():
if node_class.poll(tree):
for item in node_class_items_iter(node_class, context):
yield (node_class,) + item
# Create an enum list from node class items
def node_type_items_cb(self, context):
# XXX Python has to keep a ref to those strings, else they may be freed :(
NODE_OT_add_search._enum_str_store = [(str(index), item[1], item[2])
for index, item in enumerate(node_items_iter(context))]
return NODE_OT_add_search._enum_str_store
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
class NODE_OT_add_search(NodeAddOperator, Operator):
'''Add a node to the active tree'''
bl_idname = "node.add_search"
bl_label = "Search and Add Node"
bl_options = {'REGISTER', 'UNDO'}
# XXX Python has to keep a ref to the data (strings) generated by enum's callback, else they may be freed :(
_enum_str_store = []
2012-09-26 21:19:51 +00:00
# XXX this should be called 'node_type' but the operator search
# property is hardcoded to 'type' by a hack in bpy_operator_wrap.c ...
type = EnumProperty(
name="Node Type",
description="Node type",
items=node_type_items_cb,
)
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
def execute(self, context):
for index, item in enumerate(node_items_iter(context)):
if str(index) == self.type:
node = self.create_node(context, item[0].bl_rna.identifier)
for prop, value in item[3].items():
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
setattr(node, prop, value)
break
return {'FINISHED'}
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
def invoke(self, context, event):
self.store_mouse_cursor(context, event)
# Delayed execution in the search popup
context.window_manager.invoke_search_popup(self)
return {'CANCELLED'}
class NODE_OT_collapse_hide_unused_toggle(Operator):
'''Toggle collapsed nodes and hide unused sockets'''
bl_idname = "node.collapse_hide_unused_toggle"
bl_label = "Collapse and Hide Unused Sockets"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
space = context.space_data
# needs active node editor and a tree
return (space.type == 'NODE_EDITOR' and space.edit_tree)
def execute(self, context):
space = context.space_data
tree = space.edit_tree
for node in tree.nodes:
if node.select:
hide = (not node.hide)
node.hide = hide
# Note: connected sockets are ignored internally
for socket in node.inputs:
socket.hide = hide
for socket in node.outputs:
socket.hide = hide
return {'FINISHED'}
Merge of the PyNodes branch (aka "custom nodes") into trunk. PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements. === Dynamic node type registration === Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes. Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2]. === Node group improvements === Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3]. The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there. [1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes [2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender [3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
2013-03-18 16:34:57 +00:00
class NODE_OT_tree_path_parent(Operator):
'''Go to parent node tree'''
bl_idname = "node.tree_path_parent"
bl_label = "Parent Node Tree"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
space = context.space_data
# needs active node editor and a tree
return (space.type == 'NODE_EDITOR' and len(space.path) > 1)
def execute(self, context):
space = context.space_data
space.path.pop()
return {'FINISHED'}