[Bf-blender-cvs] [6c241b2dd7f] geometry-nodes: Geometry Nodes: Node editor header interaction with active modifier

Hans Goudey noreply at git.blender.org
Wed Nov 25 21:34:37 CET 2020


Commit: 6c241b2dd7fc48e8981335e7750dd378b5e4f02b
Author: Hans Goudey
Date:   Wed Nov 25 15:34:29 2020 -0500
Branches: geometry-nodes
https://developer.blender.org/rB6c241b2dd7fc48e8981335e7750dd378b5e4f02b

Geometry Nodes: Node editor header interaction with active modifier

This commit makes the way the selector in the middle of the node editor
header interacts with the active modifier much more intuitive.

 - With no active modifier, or when the active modifier is a non-node
   modifier, the "new" operator adds a new nodes modifier.
 - With an active node modifier, the drop-down affects the modifier's
   selected node group.
 - With no active object, there is no drop-down in the header.
 - The node editor's node group always updates, even when there is no
   active modifier.
 - Pinning disables the drop-down and keeps the same node group
   selected, regardless of the context.

This is designed to work similarly to materials and material slots,
which should be familiar to any Blender user. One workflow not allowed
by this design is editing any geometry node group, regardless of the
context, but if that turns out to be an issue it should be solved in a
similar way for all node editors.

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

M	release/scripts/startup/bl_operators/geometry_nodes.py
M	release/scripts/startup/bl_ui/space_node.py
M	source/blender/nodes/geometry/node_geometry_tree.cc

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

diff --git a/release/scripts/startup/bl_operators/geometry_nodes.py b/release/scripts/startup/bl_operators/geometry_nodes.py
index 0b8c7814808..0d4eb89494f 100644
--- a/release/scripts/startup/bl_operators/geometry_nodes.py
+++ b/release/scripts/startup/bl_operators/geometry_nodes.py
@@ -18,35 +18,82 @@
 
 import bpy
 
+def geometry_node_group_empty_new(context):
+    group = bpy.data.node_groups.new("Geometry Nodes", 'GeometryNodeTree')
+    group.inputs.new('NodeSocketGeometry', "Geometry")
+    group.outputs.new('NodeSocketGeometry', "Geometry")
+    input_node = group.nodes.new('NodeGroupInput')
+    output_node = group.nodes.new('NodeGroupOutput')
+    output_node.is_active_output = True
 
-class NewGeometryNodeTree(bpy.types.Operator):
-    """Create a new geometry node tree"""
+    input_node.location.x = -200 - input_node.width
+    output_node.location.x = 200
 
-    bl_idname = "node.new_geometry_node_tree"
-    bl_label = "New Geometry Node Tree"
+    group.links.new(output_node.inputs[0], input_node.outputs[0])
+
+    return group
+
+def node_editor_geometry_modifier_poll(context) -> bool:
+    if not (context.area.type == 'NODE_EDITOR' and context.space_data.tree_type == 'GeometryNodeTree'):
+        return False
+
+    ob = context.object
+
+    # Test object support for geometry node modifier (No volume or hair object support yet)
+    if not ob or ob.type not in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'POINTCLOUD'}:
+        return False
+
+    return True
+
+class NewGeometryNodeModifier(bpy.types.Operator):
+    """Create a new modifier with a new geometry node group"""
+
+    bl_idname = "node.new_geometry_node_modifier"
+    bl_label = "New Geometry Node Modifier"
     bl_options = {'REGISTER', 'UNDO'}
 
     @classmethod
     def poll(cls, context):
-        return context.area.type == 'NODE_EDITOR' and context.space_data.tree_type == 'GeometryNodeTree'
+        return node_editor_geometry_modifier_poll(context)
 
     def execute(self, context):
-        group = bpy.data.node_groups.new("Geometry Nodes", 'GeometryNodeTree')
-        group.inputs.new('NodeSocketGeometry', "Geometry")
-        group.outputs.new('NodeSocketGeometry', "Geometry")
-        input_node = group.nodes.new('NodeGroupInput')
-        output_node = group.nodes.new('NodeGroupOutput')
-        output_node.is_active_output = True
+        modifier = context.object.modifiers.new("Empty", "NODES")
 
-        input_node.location.x = -200 - input_node.width
-        output_node.location.x = 200
+        if not modifier:
+            return {'CANCELLED'}
 
-        group.links.new(output_node.inputs[0], input_node.outputs[0])
+        group = geometry_node_group_empty_new(context)
+        modifier.node_group = group
 
         context.space_data.node_tree = group
         return {'FINISHED'}
 
 
+class NewGeometryNodeTreeAssign(bpy.types.Operator):
+    """Create a new geometry node group and assign it the the active modifier"""
+
+    bl_idname = "node.new_geometry_node_group_assign"
+    bl_label = "Assign New Geometry Node Group"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    @classmethod
+    def poll(cls, context):
+        return node_editor_geometry_modifier_poll(context)
+
+    def execute(self, context):
+        modifier = context.object.modifiers.active
+
+        if not modifier:
+            return {'CANCELLED'}
+
+        group = geometry_node_group_empty_new(context)
+        modifier.node_group = group
+        context.space_data.node_tree = group
+
+        return {'FINISHED'}
+
+
 classes = (
-    NewGeometryNodeTree,
+    NewGeometryNodeModifier,
+    NewGeometryNodeTreeAssign,
 )
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 4cd38831cdf..9ad454d49e1 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -154,7 +154,20 @@ class NODE_HT_header(Header):
         elif snode.tree_type == 'GeometryNodeTree':
             NODE_MT_editor_menus.draw_collapsible(context, layout)
             layout.separator_spacer()
-            layout.template_ID(snode, "node_tree", new="node.new_geometry_node_tree")
+
+            ob = context.object
+
+            row = layout.row()
+            if snode.pin:
+                row.enabled = False
+                row.template_ID(snode, "node_tree", new="node.new_geometry_node_group_assign")
+            elif ob:
+                active_modifier = ob.modifiers.active
+                if active_modifier and active_modifier.type == "NODES":                     
+                    row.template_ID(active_modifier, "node_group", new="node.new_geometry_node_group_assign")
+                else:
+                    row.template_ID(snode, "node_tree", new="node.new_geometry_node_modifier")
+            
 
         else:
             # Custom node tree is edited as independent ID block
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index ed1ede50ee8..69f9f7fb4ed 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -49,14 +49,7 @@ static void geometry_node_tree_get_from_context(const bContext *C,
 
   const ModifierData *md = BKE_object_active_modifier(ob);
 
-  SpaceNode *snode = CTX_wm_space_node(C);
-  BLI_assert(snode != nullptr);
-
-  /* Don't change the node tree if there is no active modifier. */
   if (md == nullptr) {
-    *r_ntree = snode->nodetree;
-    *r_from = snode->id;
-    *r_id = snode->from;
     return;
   }



More information about the Bf-blender-cvs mailing list