[Bf-blender-cvs] [afe4577256e] functions: initial InlinedNodeTree structure

Jacques Lucke noreply at git.blender.org
Sat Nov 23 18:05:15 CET 2019


Commit: afe4577256ef5368842060115ed08dde22d518c8
Author: Jacques Lucke
Date:   Sat Nov 23 18:04:56 2019 +0100
Branches: functions
https://developer.blender.org/rBafe4577256ef5368842060115ed08dde22d518c8

initial InlinedNodeTree structure

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

A	source/blender/blenkernel/BKE_inlined_node_tree.h
M	source/blender/blenkernel/BKE_virtual_node_tree.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/inlined_node_tree.cc

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

diff --git a/source/blender/blenkernel/BKE_inlined_node_tree.h b/source/blender/blenkernel/BKE_inlined_node_tree.h
new file mode 100644
index 00000000000..1f4eab8151d
--- /dev/null
+++ b/source/blender/blenkernel/BKE_inlined_node_tree.h
@@ -0,0 +1,114 @@
+#ifndef __BKE_INLINED_NODE_TREE_H__
+#define __BKE_INLINED_NODE_TREE_H__
+
+#include "BKE_virtual_node_tree.h"
+
+#include "BLI_map.h"
+#include "BLI_multi_map.h"
+
+namespace BKE {
+
+using BLI::Map;
+using BLI::MultiMap;
+
+class XNode;
+class XParentNode;
+class XSocket;
+class XInputSocket;
+class XOutputSocket;
+class XGroupInput;
+class InlinedNodeTree;
+
+class XSocket : BLI::NonCopyable, BLI::NonMovable {
+ protected:
+  XNode *m_node;
+  uint m_id;
+
+  friend InlinedNodeTree;
+
+ public:
+  const XNode &node() const;
+};
+
+class XInputSocket : public XSocket {
+ private:
+  const VInputSocket *m_vsocket;
+  Vector<XOutputSocket *> m_linked_sockets;
+  Vector<XGroupInput *> m_linked_group_inputs;
+
+  friend InlinedNodeTree;
+};
+
+class XOutputSocket : public XSocket {
+ private:
+  const VOutputSocket *m_vsocket;
+  Vector<XInputSocket *> m_linked_sockets;
+
+  friend InlinedNodeTree;
+};
+
+class XGroupInput : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  const VInputSocket *m_vsocket;
+  XParentNode *m_parent;
+  Vector<XInputSocket *> m_linked_sockets;
+
+  friend InlinedNodeTree;
+};
+
+class XNode : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  const VNode *m_vnode;
+  XParentNode *m_parent;
+  uint m_id;
+  Vector<XInputSocket *> m_inputs;
+  Vector<XOutputSocket *> m_outputs;
+
+  friend InlinedNodeTree;
+};
+
+class XParentNode : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  const VNode *m_vnode;
+  XParentNode *m_parent;
+
+  friend InlinedNodeTree;
+};
+
+using BTreeVTreeMap = Map<bNodeTree *, std::unique_ptr<const VirtualNodeTree>>;
+
+class InlinedNodeTree : BLI::NonCopyable, BLI::NonMovable {
+ private:
+  BLI::MonotonicAllocator<> m_allocator;
+  bNodeTree *m_btree;
+  Vector<XNode *> m_node_by_id;
+  Vector<XSocket *> m_sockets_by_id;
+  Vector<XInputSocket *> m_input_sockets;
+  Vector<XOutputSocket *> m_output_sockets;
+  Vector<XParentNode *> m_parent_nodes;
+
+ public:
+  InlinedNodeTree(bNodeTree *btree, BTreeVTreeMap &vtrees);
+
+  std::string to_dot() const;
+  void to_dot__clipboard() const;
+
+ private:
+  void expand_group_node(XNode &group_node, Vector<XNode *> &nodes, BTreeVTreeMap &vtrees);
+  XNode &create_node(const VNode &vnode,
+                     XParentNode *parent,
+                     Map<const VInputSocket *, XInputSocket *> &inputs_map,
+                     Map<const VOutputSocket *, XOutputSocket *> &outputs_map);
+};
+
+/* Inline functions
+ ********************************************/
+
+const XNode &XSocket::node() const
+{
+  return *m_node;
+}
+
+}  // namespace BKE
+
+#endif /* __BKE_INLINED_NODE_TREE_H__ */
diff --git a/source/blender/blenkernel/BKE_virtual_node_tree.h b/source/blender/blenkernel/BKE_virtual_node_tree.h
index fd511ea4aba..b7462e5545d 100644
--- a/source/blender/blenkernel/BKE_virtual_node_tree.h
+++ b/source/blender/blenkernel/BKE_virtual_node_tree.h
@@ -52,6 +52,8 @@ class VSocket : BLI::NonCopyable, BLI::NonMovable {
   const VirtualNodeTree &tree() const;
   uint id() const;
 
+  uint index() const;
+
   bool is_input() const;
   bool is_output() const;
 
@@ -170,6 +172,11 @@ inline uint VSocket::id() const
   return m_id;
 }
 
+inline uint VSocket::index() const
+{
+  return m_index;
+}
+
 inline bool VSocket::is_input() const
 {
   return m_is_input;
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 13a9b45df28..3f72567ef8f 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -128,6 +128,7 @@ set(SRC
   intern/image.c
   intern/image_gen.c
   intern/image_save.c
+  intern/inlined_node_tree.cc
   intern/ipo.c
   intern/key.c
   intern/keyconfig.c
@@ -292,6 +293,7 @@ set(SRC
   BKE_idprop.h
   BKE_image.h
   BKE_image_save.h
+  BKE_inlined_node_tree.h
   BKE_ipo.h
   BKE_key.h
   BKE_keyconfig.h
diff --git a/source/blender/blenkernel/intern/inlined_node_tree.cc b/source/blender/blenkernel/intern/inlined_node_tree.cc
new file mode 100644
index 00000000000..a9b278503a1
--- /dev/null
+++ b/source/blender/blenkernel/intern/inlined_node_tree.cc
@@ -0,0 +1,270 @@
+#include "BKE_inlined_node_tree.h"
+
+#include "BLI_string.h"
+
+extern "C" {
+void WM_clipboard_text_set(const char *buf, bool selection);
+}
+
+namespace BKE {
+
+static const VirtualNodeTree &get_vtree(BTreeVTreeMap &vtrees, bNodeTree *btree)
+{
+  return *vtrees.lookup_or_add(btree,
+                               [btree]() { return BLI::make_unique<VirtualNodeTree>(btree); });
+}
+
+static bool cmp_group_interface_nodes(const VNode *a, const VNode *b)
+{
+  int a_index = RNA_int_get(a->rna(), "sort_index");
+  int b_index = RNA_int_get(b->rna(), "sort_index");
+  if (a_index < b_index) {
+    return true;
+  }
+
+  /* TODO: Match sorting with Python. */
+  return BLI_strcasecmp(a->name().data(), b->name().data()) == -1;
+}
+
+static Vector<const VOutputSocket *> get_group_inputs(const VirtualNodeTree &vtree)
+{
+  Vector<const VNode *> input_vnodes = vtree.nodes_with_idname("fn_GroupDataInputNode");
+  std::sort(input_vnodes.begin(), input_vnodes.end(), cmp_group_interface_nodes);
+
+  Vector<const VOutputSocket *> input_vsockets;
+  for (const VNode *vnode : input_vnodes) {
+    input_vsockets.append(&vnode->output(0));
+  }
+
+  return input_vsockets;
+}
+
+static Vector<const VInputSocket *> get_group_outputs(const VirtualNodeTree &vtree)
+{
+  Vector<const VNode *> output_vnodes = vtree.nodes_with_idname("fn_GroupDataOutputNode");
+  std::sort(output_vnodes.begin(), output_vnodes.end(), cmp_group_interface_nodes);
+
+  Vector<const VInputSocket *> output_vsockets;
+  for (const VNode *vnode : output_vnodes) {
+    output_vsockets.append(&vnode->input(0));
+  }
+
+  return output_vsockets;
+}
+
+static bool is_input_interface_vnode(const VNode &vnode)
+{
+  return vnode.idname() == "fn_GroupDataInputNode";
+}
+
+static bool is_output_interface_vnode(const VNode &vnode)
+{
+  return vnode.idname() == "fn_GroupDataOutputNode";
+}
+
+static bool is_interface_node(const VNode &vnode)
+{
+  return is_input_interface_vnode(vnode) || is_output_interface_vnode(vnode);
+}
+
+static bool is_group_node(const VNode &vnode)
+{
+  return vnode.idname() == "fn_GroupNode";
+}
+
+InlinedNodeTree::InlinedNodeTree(bNodeTree *btree, BTreeVTreeMap &vtrees) : m_btree(btree)
+{
+  const VirtualNodeTree &main_vtree = get_vtree(vtrees, btree);
+
+  Vector<XNode *> nodes;
+
+  Map<const VInputSocket *, XInputSocket *> inputs_map;
+  Map<const VOutputSocket *, XOutputSocket *> outputs_map;
+
+  /* Insert main nodes. */
+  for (const VNode *vnode : main_vtree.nodes()) {
+    XNode &node = this->create_node(*vnode, nullptr, inputs_map, outputs_map);
+    nodes.append(&node);
+  }
+
+  /* Insert main links. */
+  for (const VNode *vnode : main_vtree.nodes()) {
+    for (const VInputSocket *to_vsocket : vnode->inputs()) {
+      XInputSocket *to_socket = inputs_map.lookup(to_vsocket);
+      for (const VOutputSocket *from_vsocket : to_vsocket->linked_sockets()) {
+        XOutputSocket *from_socket = outputs_map.lookup(from_vsocket);
+        to_socket->m_linked_sockets.append(from_socket);
+        from_socket->m_linked_sockets.append(to_socket);
+      }
+    }
+  }
+
+  /* Expand node groups one after another. */
+  for (uint i = 0; i < nodes.size(); i++) {
+    XNode &current_node = *nodes[i];
+    if (is_group_node(*current_node.m_vnode)) {
+      this->expand_group_node(current_node, nodes, vtrees);
+    }
+  }
+
+  /* Remove unused nodes. */
+  for (int i = 0; i < nodes.size(); i++) {
+    XNode &current_node = *nodes[i];
+    if (is_group_node(*current_node.m_vnode)) {
+      nodes.remove_and_reorder(i);
+      i--;
+    }
+    else if (is_interface_node(*current_node.m_vnode) && current_node.m_parent != nullptr) {
+      nodes.remove_and_reorder(i);
+      i--;
+    }
+  }
+
+  m_node_by_id = nodes;
+}
+
+void InlinedNodeTree::expand_group_node(XNode &group_node,
+                                        Vector<XNode *> &nodes,
+                                        BTreeVTreeMap &vtrees)
+{
+  BLI_assert(is_group_node(*group_node.m_vnode));
+  const VNode &group_vnode = *group_node.m_vnode;
+  bNodeTree *btree = (bNodeTree *)RNA_pointer_get(group_vnode.rna(), "node_group").data;
+  if (btree == nullptr) {
+    return;
+  }
+
+  const VirtualNodeTree &vtree = get_vtree(vtrees, btree);
+
+  XParentNode &sub_parent = *m_allocator.construct<XParentNode>().release();
+  sub_parent.m_parent = group_node.m_parent;
+  sub_parent.m_vnode = &group_vnode;
+
+  Map<const VInputSocket *, XInputSocket *> inputs_map;
+  Map<const VOutputSocket *, XOutputSocket *> outputs_map;
+
+  /* Insert nodes of group. */
+  for (const VNode *vnode : vtree.nodes()) {
+    XNode &node = this->create_node(*vnode, &sub_parent, inputs_map, outputs_map);
+    nodes.append(&node);
+  }
+
+  /* Insert links of group. */
+  for (const VNode *vnode : vtree.nodes()) {
+    for (const VInputSocket *to_vsocket : vnode->inputs()) {
+      XInputSocket *to_socket = inputs_map.lookup(to_vsocket);
+      for (const VOutputSocket *from_vsocket : to_vsocket->linked_sockets()) {
+        XOutputSocket *from_socket = outputs_map.lookup(from_vsocket);
+        to_socket->m_linked_sockets.append(from_socket);
+        from_socket->m_linked_sockets.append(to_socket);
+      }
+    }
+  }
+
+  Vector<const VOutputSocket *> group_inputs = get_group_inputs(vtree);
+  Vector<const VInputSocket *> group_outputs = get_group_outputs(vtree);
+
+  /* Relink links to group inputs. */
+  for (const VOutputSocket *from_vsocket : group_inputs) {
+    XOutputSocket &from_socket = *outputs_map.lookup(from_vsocket);
+
+    /* If the group input has no origin, insert a dummy group input. */
+    XInputSocket &outside_group_input = *group_node.m_inputs[from_vsocket->index()];
+    if (outside_group_input.m_linked_sockets.size() == 0 &&
+        outside_group_input.m_linked_group_inputs.size() == 0) {
+      XGroupInput &gro

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list