[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