[Bf-blender-cvs] [9a7f0b7fec3] temp-node-tree-pages-prototype: implement copy paste of portals

Jacques Lucke noreply at git.blender.org
Thu Mar 18 13:51:19 CET 2021


Commit: 9a7f0b7fec322aa62bf69d0e27dd609861fe4305
Author: Jacques Lucke
Date:   Thu Mar 18 13:51:08 2021 +0100
Branches: temp-node-tree-pages-prototype
https://developer.blender.org/rB9a7f0b7fec322aa62bf69d0e27dd609861fe4305

implement copy paste of portals

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

M	release/scripts/startup/bl_operators/node.py
M	release/scripts/startup/bl_ui/space_node.py
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/geometry/nodes/node_geo_portals.cc

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

diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 86cc9c96034..86bf48ec135 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -323,7 +323,7 @@ class NODE_OT_follow_portal(Operator):
 
         portal_id = old_active_node.portal_id
         if old_active_node.bl_idname == 'NodePortalIn':
-            out_nodes = [n for n in ntree.nodes if n.bl_idname == 'NodePortalOut']
+            out_nodes = [n for n in ntree.nodes if n.bl_idname == 'NodePortalOut' and n.portal_id == portal_id]
             if len(out_nodes) != 1:
                 return {'CANCELLED'}
             out_node = out_nodes[0]
@@ -332,7 +332,7 @@ class NODE_OT_follow_portal(Operator):
             out_node.select = True
             ntree.nodes.active = out_node
         if old_active_node.bl_idname == 'NodePortalOut':
-            in_nodes = [n for n in ntree.nodes if n.bl_idname == 'NodePortalIn']
+            in_nodes = [n for n in ntree.nodes if n.bl_idname == 'NodePortalIn' and n.portal_id == portal_id]
             if len(in_nodes) != 1:
                 return {'CANCELLED'}
             in_node = in_nodes[0]
@@ -398,6 +398,62 @@ class NODE_OT_goto_page(Operator):
         return {'FINISHED'}
 
 
+copied_portal = None
+
+def get_nodes_with_portal_id(ntree, portal_id):
+    return [n for n in ntree.nodes if getattr(n, "portal_id", None) == portal_id]
+
+class NODE_OT_copy_portal(Operator):
+    '''Copy portal'''
+    bl_idname = "node.copy_portal"
+    bl_label = "Copy Portal"
+
+    @classmethod
+    def poll(cls, context):
+        try:
+            context.space_data.node_tree.nodes.active.portal_id
+            return True
+        except:
+            return False
+
+    def execute(self, context):
+        global copied_portal
+        node = context.space_data.node_tree.nodes.active
+        copied_portal = (node.bl_idname, node.portal_id)
+        return {'FINISHED'}
+
+class NODE_OT_paste_portal(Operator):
+    '''Paste portal'''
+    bl_idname = "node.paste_portal"
+    bl_label = "Paste Portal"
+
+    @classmethod
+    def poll(cls, context):
+        if context.space_data.type != 'NODE_EDITOR':
+            return False
+        ntree = context.space_data.node_tree
+        if ntree is None:
+            return False
+        if copied_portal is None:
+            return False
+        return len(get_nodes_with_portal_id(ntree, copied_portal[1])) == 1
+
+    def invoke(self, context, event):
+        global copied_portal
+
+        ntree = context.space_data.node_tree
+        new_idname = "NodePortalIn" if copied_portal[0] == "NodePortalOut" else "NodePortalOut"
+
+        bpy.ops.node.add_and_link_node(type=new_idname)
+        new_node = ntree.nodes[-1]
+
+        new_node.portal_id = copied_portal[1]
+
+        bpy.ops.node.translate_attach("INVOKE_DEFAULT")
+
+        copied_portal = None
+        return {'FINISHED'}
+
 classes = (
     NodeSetting,
 
@@ -408,4 +464,6 @@ classes = (
     NODE_OT_tree_path_parent,
     NODE_OT_follow_portal,
     NODE_OT_goto_page,
+    NODE_OT_copy_portal,
+    NODE_OT_paste_portal,
 )
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 706a9fe4585..d6a904968f4 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -173,6 +173,11 @@ class NODE_HT_header(Header):
                 props = row.operator("node.goto_page", text=str(page))
                 props.page = page
 
+            row = layout.row(align=True)
+            row.label(text="Portal")
+            row.operator("node.copy_portal", text="Copy")
+            row.operator("node.paste_portal", text="Paste")
+
         else:
             # Custom node tree is edited as independent ID block
             NODE_MT_editor_menus.draw_collapsible(context, layout)
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index e3dcb66e10d..7bc01cc13e1 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -38,6 +38,7 @@ set(INC
   ../makesdna
   ../makesrna
   ../render
+  ../windowmanager
   ../../../intern/glew-mx
   ../../../intern/guardedalloc
   ../../../intern/sky/include
diff --git a/source/blender/nodes/geometry/nodes/node_geo_portals.cc b/source/blender/nodes/geometry/nodes/node_geo_portals.cc
index b0796147a90..7a99c53b16b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_portals.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_portals.cc
@@ -19,6 +19,10 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "WM_types.h"
+
+#include "RNA_access.h"
+
 static bNodeSocketTemplate node_portal_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
     {-1, ""},
@@ -29,16 +33,54 @@ static bNodeSocketTemplate node_portal_out[] = {
     {-1, ""},
 };
 
+// static bool output_with_id_exists(const bNodeTree &ntree, const int portal_id)
+// {
+//   LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+//     if (node->type == NODE_PORTAL_OUT) {
+//       if (((NodePortalOut *)node->storage)->portal_id == portal_id) {
+//         return true;
+//       }
+//     }
+//   }
+//   return false;
+// }
+
 static void node_portal_in_layout(uiLayout *UNUSED(layout),
                                   bContext *UNUSED(C),
                                   PointerRNA *UNUSED(ptr))
 {
+  // uiItemR(layout, ptr, "portal_id", 0, IFACE_("Portal ID"), ICON_NONE);
+
+  // bNodeTree &ntree = *(bNodeTree *)ptr->owner_id;
+  // bNode *node = (bNode *)ptr->data;
+  // int portal_id = RNA_int_get(ptr, "portal_id");
+
+  // if (!output_with_id_exists(ntree, portal_id)) {
+  //   PointerRNA op_ptr;
+  //   uiItemFullO(layout,
+  //               "node.add_node",
+  //               "Add Endpoint",
+  //               ICON_NONE,
+  //               nullptr,
+  //               WM_OP_INVOKE_DEFAULT,
+  //               0,
+  //               &op_ptr);
+  //   RNA_string_set(&op_ptr, "type", "NodePortalOut");
+  //   RNA_boolean_set(&op_ptr, "use_transform", true);
+  //   PropertyRNA *settings_prop = RNA_struct_find_property(&op_ptr, "settings");
+  //   PointerRNA item_ptr;
+  //   RNA_property_collection_add(&op_ptr, settings_prop, &item_ptr);
+  //   RNA_string_set(&item_ptr, "name", "portal_id");
+  //   std::string portal_id_str = std::to_string(RNA_int_get(ptr, "portal_id"));
+  //   RNA_string_set(&item_ptr, "value", portal_id_str.c_str());
+  // }
 }
 
 static void node_portal_out_layout(uiLayout *UNUSED(layout),
                                    bContext *UNUSED(C),
                                    PointerRNA *UNUSED(ptr))
 {
+  // uiItemR(layout, ptr, "portal_id", 0, IFACE_("Portal ID"), ICON_NONE);
 }
 
 namespace blender::nodes {
@@ -46,6 +88,7 @@ namespace blender::nodes {
 static void node_portal_in_init(bNodeTree *UNUSED(tree), bNode *node)
 {
   NodePortalIn *data = (NodePortalIn *)MEM_callocN(sizeof(NodePortalIn), __func__);
+  data->portal_id = rand();
   node->storage = data;
 }



More information about the Bf-blender-cvs mailing list