[Bf-blender-cvs] [898d2ac] object_nodes: List existing node groups in 'Group' categories for easy instancing.

Lukas Tönne noreply at git.blender.org
Sun Dec 27 10:31:19 CET 2015


Commit: 898d2ac36c1cbd2a8e62bf57a30a6acf1f0a63fd
Author: Lukas Tönne
Date:   Sun Dec 27 10:29:30 2015 +0100
Branches: object_nodes
https://developer.blender.org/rB898d2ac36c1cbd2a8e62bf57a30a6acf1f0a63fd

List existing node groups in 'Group' categories for easy instancing.

This includes polling by type and recursion level to ensure groups
are only added in appropriate tree types, and don't create cyclic
dependencies.

===================================================================

M	release/scripts/nodes/geometry_nodes.py
M	release/scripts/nodes/group_nodes.py
M	release/scripts/nodes/instancing_nodes.py

===================================================================

diff --git a/release/scripts/nodes/geometry_nodes.py b/release/scripts/nodes/geometry_nodes.py
index 32fd9e9..359b54f 100644
--- a/release/scripts/nodes/geometry_nodes.py
+++ b/release/scripts/nodes/geometry_nodes.py
@@ -421,9 +421,7 @@ def register():
         GeometryNodeCategory("GEO_CURVE", "Curve", items=[
             NodeItem("CurvePathNode"),
             ]),
-        GeometryNodeCategory("GEO_GROUP", "Group", items=[
-            NodeItem(gnode.bl_idname),
-            ]),
+        group_nodes.GroupNodeCategory("GEO", gnode),
         ]
     nodeitems_utils.register_node_categories("GEOMETRY_NODES", node_categories)
 
diff --git a/release/scripts/nodes/group_nodes.py b/release/scripts/nodes/group_nodes.py
index 6f4c1b6..df06e35 100644
--- a/release/scripts/nodes/group_nodes.py
+++ b/release/scripts/nodes/group_nodes.py
@@ -23,6 +23,7 @@ import nodeitems_utils
 from bpy.types import Operator, Panel, UIList, NodeTree, Node, NodeSocket, ObjectNode, PropertyGroup, BVMTypeDesc
 from bpy.props import *
 from socket_types import socket_type_items, socket_type_to_rna, socket_type_to_bvm_type
+from nodeitems_utils import NodeCategory as NodeCategoryBase, NodeItem, NodeItemCustom
 
 ###############################################################################
 # Group Interface
@@ -179,6 +180,55 @@ def make_node_group_interface(prefix, treetype, tree_items_update):
 
 ###############################################################################
 
+# common identifying class to find group nodes
+class GroupNodeBase():
+    pass
+
+def internal_group_trees(ntree, visited=None):
+    if ntree is None:
+        return
+    if visited is None:
+        visited = set()
+    elif ntree in visited:
+        return
+    visited.add(ntree)
+
+    yield ntree
+
+    for node in ntree.nodes:
+        if not isinstance(node, GroupNodeBase):
+            continue
+        for itree in internal_group_trees(node.id, visited):
+            yield itree
+
+def ancestor_trees(root_tree, all_trees):
+    ancestors = set()
+    if root_tree is None:
+        return ancestors
+
+    visited = set()
+    def visit(ntree):
+        global indent
+        if ntree is None:
+            return False
+        if ntree in visited:
+            return ntree in ancestors
+        visited.add(ntree)
+
+        for node in ntree.nodes:
+            if not isinstance(node, GroupNodeBase):
+                continue
+            elif node.id == root_tree or visit(node.id):
+                ancestors.add(ntree)
+                return True
+        return False
+
+    for ntree in all_trees:
+        visit(ntree)
+
+    return ancestors
+
+
 def make_node_group_types(prefix, treetype, node_base):
     ntree_idname = treetype.bl_idname
     groupnode_idname = '%sGroupNode' % prefix
@@ -270,24 +320,7 @@ def make_node_group_types(prefix, treetype, node_base):
             if index != k:
                 sockets.move(index, k)
 
-    def internal_group_trees(ntree, visited=None):
-        if ntree is None:
-            return
-        if visited is None:
-            visited = set()
-        elif ntree in visited:
-            return
-        visited.add(ntree)
-
-        yield ntree
-
-        for node in ntree.nodes:
-            if not isinstance(node, GroupNode):
-                continue
-            for itree in internal_group_trees(node.id, visited):
-                yield itree
-
-    class GroupNode(node_base, ObjectNode):
+    class GroupNode(node_base, ObjectNode, GroupNodeBase):
         '''Group of nodes that can be used in other trees'''
         bl_idname = groupnode_idname
         bl_label = 'Group'
@@ -386,6 +419,50 @@ def make_node_group_types(prefix, treetype, node_base):
 
 ###############################################################################
 
+def GroupNodeCategory(prefix, gnode):
+    # menu entry for node group tools
+    def group_tools_draw(self, layout, context):
+        # TODO C node operators won't work for our nodes
+        #layout.operator("node.group_make")
+        #layout.operator("node.group_ungroup")
+        layout.separator()
+
+    def node_group_items(context):
+        if context is None:
+            return
+        space = context.space_data
+        if not space:
+            return
+        ntree = space.edit_tree
+        if not ntree:
+            return
+
+        yield NodeItemCustom(draw=group_tools_draw)
+
+        all_trees = context.blend_data.node_groups
+        ancestors = ancestor_trees(ntree, all_trees)
+        free_trees = [t for t in all_trees if (t.bl_idname == gnode.bl_ntree_idname) and (t != ntree) and (t not in ancestors)]
+
+        for ntree in free_trees:
+            yield NodeItem(gnode.bl_idname,
+                           label=ntree.name,
+                           settings={"id": "bpy.data.node_groups[%r]" % ntree.name})
+
+    class NodeCategory(NodeCategoryBase):
+        def __init__(self):
+            super().__init__("%s_GROUPS" % prefix, "Group", items=node_group_items)
+
+        @classmethod
+        def poll(cls, context):
+            ntree = context.space_data.edit_tree
+            if not ntree:
+                return False
+            return gnode.poll(ntree)
+
+    return NodeCategory()
+
+###############################################################################
+
 def register():
     pass
 
diff --git a/release/scripts/nodes/instancing_nodes.py b/release/scripts/nodes/instancing_nodes.py
index 6cf6dc1..db765d3 100644
--- a/release/scripts/nodes/instancing_nodes.py
+++ b/release/scripts/nodes/instancing_nodes.py
@@ -185,7 +185,8 @@ class InstancingNodesNew(Operator):
 ###############################################################################
 
 def register():
-    gnode, ginput, goutput = group_nodes.make_node_group_types("Instancing", InstancingNodeTree, InstancingNodeBase)
+    gnode, ginput, goutput = group_nodes.make_node_group_types(
+        "Instancing", InstancingNodeTree, InstancingNodeBase)
     bpy.utils.register_module(__name__)
 
     node_categories = [
@@ -225,9 +226,7 @@ def register():
             NodeItem("ObjectTextureCloudsNode"),
             NodeItem("ObjectTextureVoronoiNode"),
             ]),
-        InstancingNodeCategory("INS_GROUP", "Group", items=[
-            NodeItem(gnode.bl_idname),
-            ]),
+        group_nodes.GroupNodeCategory("INS", gnode),
         ]
     nodeitems_utils.register_node_categories("INSTANCING_NODES", node_categories)




More information about the Bf-blender-cvs mailing list