[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 ¤t_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 ¤t_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