Compare commits
9 Commits
xr-world-n
...
node-tree-
Author | SHA1 | Date | |
---|---|---|---|
925166bed6 | |||
dd1a90353b | |||
04c05a028c | |||
22d68d0f26 | |||
220bcdaa15 | |||
a9051f4106 | |||
a600e76a58 | |||
723b12bbca | |||
7ca85442ad |
381
source/blender/blenkernel/BKE_derived_node_tree.hh
Normal file
381
source/blender/blenkernel/BKE_derived_node_tree.hh
Normal file
@@ -0,0 +1,381 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BKE_DERIVED_NODE_TREE_HH__
|
||||||
|
#define __BKE_DERIVED_NODE_TREE_HH__
|
||||||
|
|
||||||
|
#include "BKE_node_tree_ref.hh"
|
||||||
|
|
||||||
|
namespace BKE {
|
||||||
|
|
||||||
|
class DSocket;
|
||||||
|
class DInputSocket;
|
||||||
|
class DOutputSocket;
|
||||||
|
class DNode;
|
||||||
|
class DParentNode;
|
||||||
|
class DGroupInput;
|
||||||
|
class DerivedNodeTree;
|
||||||
|
|
||||||
|
class DSocket : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
protected:
|
||||||
|
DNode *m_node;
|
||||||
|
const SocketRef *m_socket_ref;
|
||||||
|
uint m_id;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const DNode &node() const;
|
||||||
|
|
||||||
|
uint id() const;
|
||||||
|
uint index() const;
|
||||||
|
|
||||||
|
bool is_input() const;
|
||||||
|
bool is_output() const;
|
||||||
|
|
||||||
|
const DSocket &as_base() const;
|
||||||
|
const DInputSocket &as_input() const;
|
||||||
|
const DOutputSocket &as_output() const;
|
||||||
|
|
||||||
|
PointerRNA *rna() const;
|
||||||
|
StringRefNull idname() const;
|
||||||
|
StringRefNull name() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DInputSocket : public DSocket {
|
||||||
|
private:
|
||||||
|
Vector<DOutputSocket *> m_linked_sockets;
|
||||||
|
Vector<DGroupInput *> m_linked_group_inputs;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const InputSocketRef &socket_ref() const;
|
||||||
|
|
||||||
|
ArrayRef<const DOutputSocket *> linked_sockets() const;
|
||||||
|
ArrayRef<const DGroupInput *> linked_group_inputs() const;
|
||||||
|
|
||||||
|
bool is_linked() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOutputSocket : public DSocket {
|
||||||
|
private:
|
||||||
|
Vector<DInputSocket *> m_linked_sockets;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const OutputSocketRef &socket_ref() const;
|
||||||
|
ArrayRef<const DInputSocket *> linked_sockets() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DGroupInput : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
const InputSocketRef *m_socket_ref;
|
||||||
|
DParentNode *m_parent;
|
||||||
|
Vector<DInputSocket *> m_linked_sockets;
|
||||||
|
uint m_id;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const InputSocketRef &socket_ref() const;
|
||||||
|
const DParentNode *parent() const;
|
||||||
|
ArrayRef<const DInputSocket *> linked_sockets() const;
|
||||||
|
uint id() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DNode : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
const NodeRef *m_node_ref;
|
||||||
|
DParentNode *m_parent;
|
||||||
|
|
||||||
|
MutableArrayRef<DInputSocket *> m_inputs;
|
||||||
|
MutableArrayRef<DOutputSocket *> m_outputs;
|
||||||
|
|
||||||
|
uint m_id;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const NodeRef &node_ref() const;
|
||||||
|
const DParentNode *parent() const;
|
||||||
|
|
||||||
|
ArrayRef<const DInputSocket *> inputs() const;
|
||||||
|
ArrayRef<const DOutputSocket *> outputs() const;
|
||||||
|
|
||||||
|
const DInputSocket &input(uint index) const;
|
||||||
|
const DOutputSocket &output(uint index) const;
|
||||||
|
|
||||||
|
uint id() const;
|
||||||
|
|
||||||
|
PointerRNA *rna() const;
|
||||||
|
StringRefNull idname() const;
|
||||||
|
StringRefNull name() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DParentNode : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
const NodeRef *m_node_ref;
|
||||||
|
DParentNode *m_parent;
|
||||||
|
uint m_id;
|
||||||
|
|
||||||
|
friend DerivedNodeTree;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const DParentNode *parent() const;
|
||||||
|
const NodeRef &node_ref() const;
|
||||||
|
uint id() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
|
||||||
|
|
||||||
|
class DerivedNodeTree : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
LinearAllocator<> m_allocator;
|
||||||
|
bNodeTree *m_btree;
|
||||||
|
Vector<DNode *> m_nodes_by_id;
|
||||||
|
Vector<DGroupInput *> m_group_inputs;
|
||||||
|
Vector<DParentNode *> m_parent_nodes;
|
||||||
|
|
||||||
|
Vector<DSocket *> m_sockets_by_id;
|
||||||
|
Vector<DInputSocket *> m_input_sockets;
|
||||||
|
Vector<DOutputSocket *> m_output_sockets;
|
||||||
|
|
||||||
|
StringMap<Vector<DNode *>> m_nodes_by_idname;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs);
|
||||||
|
~DerivedNodeTree();
|
||||||
|
|
||||||
|
ArrayRef<const DNode *> all_nodes() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Utility functions used during construction. */
|
||||||
|
void insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
|
||||||
|
DParentNode *parent,
|
||||||
|
Vector<DNode *> &r_nodes);
|
||||||
|
DNode &create_node(const NodeRef &node_ref,
|
||||||
|
DParentNode *parent,
|
||||||
|
MutableArrayRef<DSocket *> r_sockets_map);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DSocket inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const DNode &DSocket::node() const
|
||||||
|
{
|
||||||
|
return *m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint DSocket::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint DSocket::index() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->index();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool DSocket::is_input() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->is_input();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool DSocket::is_output() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->is_output();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DSocket &DSocket::as_base() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DInputSocket &DSocket::as_input() const
|
||||||
|
{
|
||||||
|
return *(DInputSocket *)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DOutputSocket &DSocket::as_output() const
|
||||||
|
{
|
||||||
|
return *(DOutputSocket *)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PointerRNA *DSocket::rna() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->rna();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull DSocket::idname() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->idname();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull DSocket::name() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DInputSocket inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const InputSocketRef &DInputSocket::socket_ref() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->as_input();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DOutputSocket *> DInputSocket::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DGroupInput *> DInputSocket::linked_group_inputs() const
|
||||||
|
{
|
||||||
|
return m_linked_group_inputs.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool DInputSocket::is_linked() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.size() > 0 || m_linked_group_inputs.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DOutputSocket inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const OutputSocketRef &DOutputSocket::socket_ref() const
|
||||||
|
{
|
||||||
|
return m_socket_ref->as_output();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DInputSocket *> DOutputSocket::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DGroupInput inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const InputSocketRef &DGroupInput::socket_ref() const
|
||||||
|
{
|
||||||
|
return *m_socket_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DParentNode *DGroupInput::parent() const
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DInputSocket *> DGroupInput::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint DGroupInput::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DNode inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const NodeRef &DNode::node_ref() const
|
||||||
|
{
|
||||||
|
return *m_node_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DParentNode *DNode::parent() const
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DInputSocket *> DNode::inputs() const
|
||||||
|
{
|
||||||
|
return m_inputs.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const DOutputSocket *> DNode::outputs() const
|
||||||
|
{
|
||||||
|
return m_outputs.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DInputSocket &DNode::input(uint index) const
|
||||||
|
{
|
||||||
|
return *m_inputs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DOutputSocket &DNode::output(uint index) const
|
||||||
|
{
|
||||||
|
return *m_outputs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint DNode::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PointerRNA *DNode::rna() const
|
||||||
|
{
|
||||||
|
return m_node_ref->rna();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull DNode::idname() const
|
||||||
|
{
|
||||||
|
return m_node_ref->idname();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull DNode::name() const
|
||||||
|
{
|
||||||
|
return m_node_ref->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DParentNode inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const DParentNode *DParentNode::parent() const
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const NodeRef &DParentNode::node_ref() const
|
||||||
|
{
|
||||||
|
return *m_node_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint DParentNode::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* DerivedNodeTree inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ArrayRef<const DNode *> DerivedNodeTree::all_nodes() const
|
||||||
|
{
|
||||||
|
return m_nodes_by_id.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BKE
|
||||||
|
|
||||||
|
#endif /* __BKE_DERIVED_NODE_TREE_HH__ */
|
409
source/blender/blenkernel/BKE_node_tree_ref.hh
Normal file
409
source/blender/blenkernel/BKE_node_tree_ref.hh
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BKE_NODE_TREE_REF_HH__
|
||||||
|
#define __BKE_NODE_TREE_REF_HH__
|
||||||
|
|
||||||
|
#include "BLI_array.hh"
|
||||||
|
#include "BLI_linear_allocator.hh"
|
||||||
|
#include "BLI_map.hh"
|
||||||
|
#include "BLI_string_map.hh"
|
||||||
|
#include "BLI_string_ref.hh"
|
||||||
|
#include "BLI_utility_mixins.hh"
|
||||||
|
#include "BLI_vector.hh"
|
||||||
|
|
||||||
|
#include "BKE_node.h"
|
||||||
|
|
||||||
|
#include "DNA_node_types.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
|
namespace BKE {
|
||||||
|
|
||||||
|
using BLI::Array;
|
||||||
|
using BLI::ArrayRef;
|
||||||
|
using BLI::LinearAllocator;
|
||||||
|
using BLI::Map;
|
||||||
|
using BLI::MutableArrayRef;
|
||||||
|
using BLI::StringMap;
|
||||||
|
using BLI::StringRef;
|
||||||
|
using BLI::StringRefNull;
|
||||||
|
using BLI::Vector;
|
||||||
|
|
||||||
|
class SocketRef;
|
||||||
|
class InputSocketRef;
|
||||||
|
class OutputSocketRef;
|
||||||
|
class NodeRef;
|
||||||
|
class NodeTreeRef;
|
||||||
|
|
||||||
|
class SocketRef : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
protected:
|
||||||
|
NodeRef *m_node;
|
||||||
|
bNodeSocket *m_bsocket;
|
||||||
|
bool m_is_input;
|
||||||
|
uint m_id;
|
||||||
|
uint m_index;
|
||||||
|
PointerRNA m_rna;
|
||||||
|
Vector<SocketRef *> m_linked_sockets;
|
||||||
|
Vector<SocketRef *> m_directly_linked_sockets;
|
||||||
|
|
||||||
|
friend NodeTreeRef;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ArrayRef<const SocketRef *> linked_sockets() const;
|
||||||
|
ArrayRef<const SocketRef *> directly_linked_sockets() const;
|
||||||
|
bool is_linked() const;
|
||||||
|
|
||||||
|
const NodeRef &node() const;
|
||||||
|
const NodeTreeRef &tree() const;
|
||||||
|
|
||||||
|
uint id() const;
|
||||||
|
uint index() const;
|
||||||
|
|
||||||
|
bool is_input() const;
|
||||||
|
bool is_output() const;
|
||||||
|
|
||||||
|
const SocketRef &as_base() const;
|
||||||
|
const InputSocketRef &as_input() const;
|
||||||
|
const OutputSocketRef &as_output() const;
|
||||||
|
|
||||||
|
PointerRNA *rna() const;
|
||||||
|
|
||||||
|
StringRefNull idname() const;
|
||||||
|
StringRefNull name() const;
|
||||||
|
|
||||||
|
bNodeSocket *bsocket() const;
|
||||||
|
bNode *bnode() const;
|
||||||
|
bNodeTree *btree() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputSocketRef final : public SocketRef {
|
||||||
|
public:
|
||||||
|
ArrayRef<const OutputSocketRef *> linked_sockets() const;
|
||||||
|
ArrayRef<const OutputSocketRef *> directly_linked_sockets() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OutputSocketRef final : public SocketRef {
|
||||||
|
public:
|
||||||
|
ArrayRef<const InputSocketRef *> linked_sockets() const;
|
||||||
|
ArrayRef<const InputSocketRef *> directly_linked_sockets() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeRef : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
NodeTreeRef *m_tree;
|
||||||
|
bNode *m_bnode;
|
||||||
|
PointerRNA m_rna;
|
||||||
|
uint m_id;
|
||||||
|
Vector<InputSocketRef *> m_inputs;
|
||||||
|
Vector<OutputSocketRef *> m_outputs;
|
||||||
|
|
||||||
|
friend NodeTreeRef;
|
||||||
|
|
||||||
|
public:
|
||||||
|
const NodeTreeRef &tree() const;
|
||||||
|
|
||||||
|
ArrayRef<const InputSocketRef *> inputs() const;
|
||||||
|
ArrayRef<const OutputSocketRef *> outputs() const;
|
||||||
|
|
||||||
|
const InputSocketRef &input(uint index) const;
|
||||||
|
const OutputSocketRef &output(uint index) const;
|
||||||
|
|
||||||
|
bNode *bnode() const;
|
||||||
|
bNodeTree *btree() const;
|
||||||
|
|
||||||
|
PointerRNA *rna() const;
|
||||||
|
StringRefNull idname() const;
|
||||||
|
StringRefNull name() const;
|
||||||
|
|
||||||
|
uint id() const;
|
||||||
|
|
||||||
|
bool is_reroute_node() const;
|
||||||
|
bool is_group_node() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeTreeRef : BLI::NonCopyable, BLI::NonMovable {
|
||||||
|
private:
|
||||||
|
LinearAllocator<> m_allocator;
|
||||||
|
bNodeTree *m_btree;
|
||||||
|
Vector<NodeRef *> m_nodes_by_id;
|
||||||
|
Vector<SocketRef *> m_sockets_by_id;
|
||||||
|
Vector<InputSocketRef *> m_input_sockets;
|
||||||
|
Vector<OutputSocketRef *> m_output_sockets;
|
||||||
|
StringMap<Vector<NodeRef *>> m_nodes_by_idname;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeTreeRef(bNodeTree *btree);
|
||||||
|
~NodeTreeRef();
|
||||||
|
|
||||||
|
ArrayRef<const NodeRef *> nodes() const;
|
||||||
|
ArrayRef<const NodeRef *> nodes_with_idname(StringRef idname) const;
|
||||||
|
|
||||||
|
ArrayRef<const SocketRef *> sockets() const;
|
||||||
|
ArrayRef<const InputSocketRef *> input_sockets() const;
|
||||||
|
ArrayRef<const OutputSocketRef *> output_sockets() const;
|
||||||
|
|
||||||
|
bNodeTree *btree() const;
|
||||||
|
|
||||||
|
std::string to_dot() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Utility functions used during construction. */
|
||||||
|
InputSocketRef &find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
|
||||||
|
bNode *bnode,
|
||||||
|
bNodeSocket *bsocket);
|
||||||
|
OutputSocketRef &find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
|
||||||
|
bNode *bnode,
|
||||||
|
bNodeSocket *bsocket);
|
||||||
|
void find_targets_skipping_reroutes(OutputSocketRef &socket_ref, Vector<SocketRef *> &r_targets);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* SocketRef inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ArrayRef<const SocketRef *> SocketRef::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const SocketRef *> SocketRef::directly_linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_directly_linked_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SocketRef::is_linked() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const NodeRef &SocketRef::node() const
|
||||||
|
{
|
||||||
|
return *m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const NodeTreeRef &SocketRef::tree() const
|
||||||
|
{
|
||||||
|
return m_node->tree();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint SocketRef::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint SocketRef::index() const
|
||||||
|
{
|
||||||
|
return m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SocketRef::is_input() const
|
||||||
|
{
|
||||||
|
return m_is_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SocketRef::is_output() const
|
||||||
|
{
|
||||||
|
return !m_is_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const SocketRef &SocketRef::as_base() const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const InputSocketRef &SocketRef::as_input() const
|
||||||
|
{
|
||||||
|
BLI_assert(this->is_input());
|
||||||
|
return *(const InputSocketRef *)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const OutputSocketRef &SocketRef::as_output() const
|
||||||
|
{
|
||||||
|
BLI_assert(this->is_output());
|
||||||
|
return *(const OutputSocketRef *)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PointerRNA *SocketRef::rna() const
|
||||||
|
{
|
||||||
|
return const_cast<PointerRNA *>(&m_rna);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull SocketRef::idname() const
|
||||||
|
{
|
||||||
|
return m_bsocket->idname;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull SocketRef::name() const
|
||||||
|
{
|
||||||
|
return m_bsocket->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNodeSocket *SocketRef::bsocket() const
|
||||||
|
{
|
||||||
|
return m_bsocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNode *SocketRef::bnode() const
|
||||||
|
{
|
||||||
|
return m_node->bnode();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNodeTree *SocketRef::btree() const
|
||||||
|
{
|
||||||
|
return m_node->btree();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* InputSocketRef inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ArrayRef<const OutputSocketRef *> InputSocketRef::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref().cast<const OutputSocketRef *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const OutputSocketRef *> InputSocketRef::directly_linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_directly_linked_sockets.as_ref().cast<const OutputSocketRef *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* OutputSocketRef inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ArrayRef<const InputSocketRef *> OutputSocketRef::linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_linked_sockets.as_ref().cast<const InputSocketRef *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const InputSocketRef *> OutputSocketRef::directly_linked_sockets() const
|
||||||
|
{
|
||||||
|
return m_directly_linked_sockets.as_ref().cast<const InputSocketRef *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* NodeRef inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline const NodeTreeRef &NodeRef::tree() const
|
||||||
|
{
|
||||||
|
return *m_tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const InputSocketRef *> NodeRef::inputs() const
|
||||||
|
{
|
||||||
|
return m_inputs.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const OutputSocketRef *> NodeRef::outputs() const
|
||||||
|
{
|
||||||
|
return m_outputs.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const InputSocketRef &NodeRef::input(uint index) const
|
||||||
|
{
|
||||||
|
return *m_inputs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const OutputSocketRef &NodeRef::output(uint index) const
|
||||||
|
{
|
||||||
|
return *m_outputs[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNode *NodeRef::bnode() const
|
||||||
|
{
|
||||||
|
return m_bnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNodeTree *NodeRef::btree() const
|
||||||
|
{
|
||||||
|
return m_tree->btree();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PointerRNA *NodeRef::rna() const
|
||||||
|
{
|
||||||
|
return const_cast<PointerRNA *>(&m_rna);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull NodeRef::idname() const
|
||||||
|
{
|
||||||
|
return m_bnode->idname;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StringRefNull NodeRef::name() const
|
||||||
|
{
|
||||||
|
return m_bnode->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint NodeRef::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NodeRef::is_reroute_node() const
|
||||||
|
{
|
||||||
|
return m_bnode->type == NODE_REROUTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NodeRef::is_group_node() const
|
||||||
|
{
|
||||||
|
return m_bnode->type == NODE_GROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------
|
||||||
|
* NodeRef inline methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline ArrayRef<const NodeRef *> NodeTreeRef::nodes() const
|
||||||
|
{
|
||||||
|
return m_nodes_by_id.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const NodeRef *> NodeTreeRef::nodes_with_idname(StringRef idname) const
|
||||||
|
{
|
||||||
|
const Vector<NodeRef *> *nodes = m_nodes_by_idname.lookup_ptr(idname);
|
||||||
|
if (nodes == nullptr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return nodes->as_ref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const SocketRef *> NodeTreeRef::sockets() const
|
||||||
|
{
|
||||||
|
return m_sockets_by_id.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const InputSocketRef *> NodeTreeRef::input_sockets() const
|
||||||
|
{
|
||||||
|
return m_input_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ArrayRef<const OutputSocketRef *> NodeTreeRef::output_sockets() const
|
||||||
|
{
|
||||||
|
return m_output_sockets.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bNodeTree *NodeTreeRef::btree() const
|
||||||
|
{
|
||||||
|
return m_btree;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BKE
|
||||||
|
|
||||||
|
#endif /* __BKE_NODE_TREE_REF_HH__ */
|
@@ -106,6 +106,7 @@ set(SRC
|
|||||||
intern/customdata_file.c
|
intern/customdata_file.c
|
||||||
intern/data_transfer.c
|
intern/data_transfer.c
|
||||||
intern/deform.c
|
intern/deform.c
|
||||||
|
intern/derived_node_tree.cc
|
||||||
intern/displist.c
|
intern/displist.c
|
||||||
intern/displist_tangent.c
|
intern/displist_tangent.c
|
||||||
intern/dynamicpaint.c
|
intern/dynamicpaint.c
|
||||||
@@ -183,6 +184,7 @@ set(SRC
|
|||||||
intern/multires_unsubdivide.c
|
intern/multires_unsubdivide.c
|
||||||
intern/nla.c
|
intern/nla.c
|
||||||
intern/node.c
|
intern/node.c
|
||||||
|
intern/node_tree_ref.cc
|
||||||
intern/object.c
|
intern/object.c
|
||||||
intern/object_deform.c
|
intern/object_deform.c
|
||||||
intern/object_dupli.c
|
intern/object_dupli.c
|
||||||
@@ -291,6 +293,7 @@ set(SRC
|
|||||||
BKE_customdata_file.h
|
BKE_customdata_file.h
|
||||||
BKE_data_transfer.h
|
BKE_data_transfer.h
|
||||||
BKE_deform.h
|
BKE_deform.h
|
||||||
|
BKE_derived_node_tree.hh
|
||||||
BKE_displist.h
|
BKE_displist.h
|
||||||
BKE_displist_tangent.h
|
BKE_displist_tangent.h
|
||||||
BKE_duplilist.h
|
BKE_duplilist.h
|
||||||
@@ -348,6 +351,7 @@ set(SRC
|
|||||||
BKE_multires.h
|
BKE_multires.h
|
||||||
BKE_nla.h
|
BKE_nla.h
|
||||||
BKE_node.h
|
BKE_node.h
|
||||||
|
BKE_node_tree_ref.hh
|
||||||
BKE_object.h
|
BKE_object.h
|
||||||
BKE_object_deform.h
|
BKE_object_deform.h
|
||||||
BKE_object_facemap.h
|
BKE_object_facemap.h
|
||||||
|
106
source/blender/blenkernel/intern/derived_node_tree.cc
Normal file
106
source/blender/blenkernel/intern/derived_node_tree.cc
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BKE_derived_node_tree.hh"
|
||||||
|
|
||||||
|
#define UNINITIALIZED_ID UINT32_MAX
|
||||||
|
|
||||||
|
namespace BKE {
|
||||||
|
|
||||||
|
static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree *btree)
|
||||||
|
{
|
||||||
|
return *node_tree_refs.lookup_or_add(btree,
|
||||||
|
[&]() { return BLI::make_unique<NodeTreeRef>(btree); });
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs)
|
||||||
|
{
|
||||||
|
const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree);
|
||||||
|
|
||||||
|
Vector<DNode *> all_nodes;
|
||||||
|
|
||||||
|
this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DerivedNodeTree::insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
|
||||||
|
DParentNode *parent,
|
||||||
|
Vector<DNode *> &r_nodes)
|
||||||
|
{
|
||||||
|
Array<DSocket *, 64> sockets_map(tree_ref.sockets().size());
|
||||||
|
|
||||||
|
/* Insert nodes. */
|
||||||
|
for (const NodeRef *node_ref : tree_ref.nodes()) {
|
||||||
|
DNode &node = this->create_node(*node_ref, parent, sockets_map);
|
||||||
|
r_nodes.append(&node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert links. */
|
||||||
|
for (const NodeRef *node_ref : tree_ref.nodes()) {
|
||||||
|
for (const InputSocketRef *to_socket_ref : node_ref->inputs()) {
|
||||||
|
DInputSocket *to_socket = (DInputSocket *)sockets_map[to_socket_ref->id()];
|
||||||
|
for (const OutputSocketRef *from_socket_ref : to_socket_ref->linked_sockets()) {
|
||||||
|
DOutputSocket *from_socket = (DOutputSocket *)sockets_map[from_socket_ref->id()];
|
||||||
|
to_socket->m_linked_sockets.append(from_socket);
|
||||||
|
from_socket->m_linked_sockets.append(to_socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
|
||||||
|
DParentNode *parent,
|
||||||
|
MutableArrayRef<DSocket *> r_sockets_map)
|
||||||
|
{
|
||||||
|
DNode &node = *m_allocator.construct<DNode>();
|
||||||
|
node.m_node_ref = &node_ref;
|
||||||
|
node.m_parent = parent;
|
||||||
|
node.m_id = UNINITIALIZED_ID;
|
||||||
|
|
||||||
|
node.m_inputs = m_allocator.construct_elements_and_pointer_array<DInputSocket>(
|
||||||
|
node_ref.inputs().size());
|
||||||
|
node.m_outputs = m_allocator.construct_elements_and_pointer_array<DOutputSocket>(
|
||||||
|
node_ref.outputs().size());
|
||||||
|
|
||||||
|
for (uint i : node.m_inputs.index_range()) {
|
||||||
|
const InputSocketRef &socket_ref = node_ref.input(i);
|
||||||
|
DInputSocket &socket = *node.m_inputs[i];
|
||||||
|
|
||||||
|
socket.m_id = UNINITIALIZED_ID;
|
||||||
|
socket.m_node = &node;
|
||||||
|
socket.m_socket_ref = &socket_ref;
|
||||||
|
|
||||||
|
r_sockets_map[socket_ref.id()] = &socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i : node.m_outputs.index_range()) {
|
||||||
|
const OutputSocketRef &socket_ref = node_ref.output(i);
|
||||||
|
DOutputSocket &socket = *node.m_outputs[i];
|
||||||
|
|
||||||
|
socket.m_id = UNINITIALIZED_ID;
|
||||||
|
socket.m_node = &node;
|
||||||
|
socket.m_socket_ref = &socket_ref;
|
||||||
|
|
||||||
|
r_sockets_map[socket_ref.id()] = &socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
DerivedNodeTree::~DerivedNodeTree()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BKE
|
178
source/blender/blenkernel/intern/node_tree_ref.cc
Normal file
178
source/blender/blenkernel/intern/node_tree_ref.cc
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BKE_node_tree_ref.hh"
|
||||||
|
|
||||||
|
#include "BLI_dot_export.hh"
|
||||||
|
|
||||||
|
namespace BKE {
|
||||||
|
|
||||||
|
NodeTreeRef::NodeTreeRef(bNodeTree *btree)
|
||||||
|
{
|
||||||
|
Map<bNode *, NodeRef *> node_mapping;
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bNode *, bnode, &btree->nodes) {
|
||||||
|
NodeRef &node = *m_allocator.construct<NodeRef>();
|
||||||
|
|
||||||
|
node.m_tree = this;
|
||||||
|
node.m_bnode = bnode;
|
||||||
|
node.m_id = m_nodes_by_id.append_and_get_index(&node);
|
||||||
|
RNA_pointer_create(&btree->id, &RNA_Node, bnode, &node.m_rna);
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->inputs) {
|
||||||
|
InputSocketRef &socket = *m_allocator.construct<InputSocketRef>();
|
||||||
|
socket.m_node = &node;
|
||||||
|
socket.m_index = node.m_inputs.append_and_get_index(&socket);
|
||||||
|
socket.m_is_input = true;
|
||||||
|
socket.m_bsocket = bsocket;
|
||||||
|
socket.m_id = m_sockets_by_id.append_and_get_index(&socket);
|
||||||
|
RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.m_rna);
|
||||||
|
}
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bNodeSocket *, bsocket, &bnode->outputs) {
|
||||||
|
OutputSocketRef &socket = *m_allocator.construct<OutputSocketRef>();
|
||||||
|
socket.m_node = &node;
|
||||||
|
socket.m_index = node.m_outputs.append_and_get_index(&socket);
|
||||||
|
socket.m_is_input = false;
|
||||||
|
socket.m_bsocket = bsocket;
|
||||||
|
socket.m_id = m_sockets_by_id.append_and_get_index(&socket);
|
||||||
|
RNA_pointer_create(&btree->id, &RNA_NodeSocket, bsocket, &socket.m_rna);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_input_sockets.extend(node.m_inputs);
|
||||||
|
m_output_sockets.extend(node.m_outputs);
|
||||||
|
|
||||||
|
node_mapping.add_new(bnode, &node);
|
||||||
|
}
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (bNodeLink *, blink, &btree->links) {
|
||||||
|
OutputSocketRef &from_socket = this->find_output_socket(
|
||||||
|
node_mapping, blink->fromnode, blink->fromsock);
|
||||||
|
InputSocketRef &to_socket = this->find_input_socket(
|
||||||
|
node_mapping, blink->tonode, blink->tosock);
|
||||||
|
|
||||||
|
from_socket.m_directly_linked_sockets.append(&to_socket);
|
||||||
|
to_socket.m_directly_linked_sockets.append(&from_socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (OutputSocketRef *socket : m_output_sockets) {
|
||||||
|
if (!socket->m_node->is_reroute_node()) {
|
||||||
|
this->find_targets_skipping_reroutes(*socket, socket->m_linked_sockets);
|
||||||
|
for (SocketRef *target : socket->m_linked_sockets) {
|
||||||
|
target->m_linked_sockets.append(socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NodeRef *node : m_nodes_by_id) {
|
||||||
|
m_nodes_by_idname.lookup_or_add_default(node->idname()).append(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeTreeRef::~NodeTreeRef()
|
||||||
|
{
|
||||||
|
for (NodeRef *node : m_nodes_by_id) {
|
||||||
|
node->~NodeRef();
|
||||||
|
}
|
||||||
|
for (InputSocketRef *socket : m_input_sockets) {
|
||||||
|
socket->~InputSocketRef();
|
||||||
|
}
|
||||||
|
for (OutputSocketRef *socket : m_output_sockets) {
|
||||||
|
socket->~OutputSocketRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InputSocketRef &NodeTreeRef::find_input_socket(Map<bNode *, NodeRef *> &node_mapping,
|
||||||
|
bNode *bnode,
|
||||||
|
bNodeSocket *bsocket)
|
||||||
|
{
|
||||||
|
NodeRef *node = node_mapping.lookup(bnode);
|
||||||
|
for (SocketRef *socket : node->m_inputs) {
|
||||||
|
if (socket->m_bsocket == bsocket) {
|
||||||
|
return *(InputSocketRef *)socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_assert(false);
|
||||||
|
return *node->m_inputs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputSocketRef &NodeTreeRef::find_output_socket(Map<bNode *, NodeRef *> &node_mapping,
|
||||||
|
bNode *bnode,
|
||||||
|
bNodeSocket *bsocket)
|
||||||
|
{
|
||||||
|
NodeRef *node = node_mapping.lookup(bnode);
|
||||||
|
for (SocketRef *socket : node->m_outputs) {
|
||||||
|
if (socket->m_bsocket == bsocket) {
|
||||||
|
return *(OutputSocketRef *)socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BLI_assert(false);
|
||||||
|
return *node->m_outputs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeTreeRef::find_targets_skipping_reroutes(OutputSocketRef &socket,
|
||||||
|
Vector<SocketRef *> &r_targets)
|
||||||
|
{
|
||||||
|
for (SocketRef *direct_target : socket.m_directly_linked_sockets) {
|
||||||
|
if (direct_target->m_node->is_reroute_node()) {
|
||||||
|
this->find_targets_skipping_reroutes(*direct_target->m_node->m_outputs[0], r_targets);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r_targets.append_non_duplicates(direct_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeTreeRef::to_dot() const
|
||||||
|
{
|
||||||
|
namespace Dot = BLI::DotExport;
|
||||||
|
|
||||||
|
Dot::DirectedGraph digraph;
|
||||||
|
digraph.set_rankdir(Dot::Attr_rankdir::LeftToRight);
|
||||||
|
|
||||||
|
Map<const NodeRef *, Dot::NodeWithSocketsRef> dot_nodes;
|
||||||
|
|
||||||
|
for (const NodeRef *node : m_nodes_by_id) {
|
||||||
|
Dot::Node &dot_node = digraph.new_node("");
|
||||||
|
dot_node.set_background_color("white");
|
||||||
|
|
||||||
|
Vector<std::string> input_names;
|
||||||
|
Vector<std::string> output_names;
|
||||||
|
for (const InputSocketRef *socket : node->inputs()) {
|
||||||
|
input_names.append(socket->name());
|
||||||
|
}
|
||||||
|
for (const OutputSocketRef *socket : node->outputs()) {
|
||||||
|
output_names.append(socket->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_nodes.add_new(node,
|
||||||
|
Dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const OutputSocketRef *from_socket : m_output_sockets) {
|
||||||
|
for (const InputSocketRef *to_socket : from_socket->directly_linked_sockets()) {
|
||||||
|
Dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(&from_socket->node());
|
||||||
|
Dot::NodeWithSocketsRef &to_dot_node = dot_nodes.lookup(&to_socket->node());
|
||||||
|
|
||||||
|
digraph.new_edge(from_dot_node.output(from_socket->index()),
|
||||||
|
to_dot_node.input(to_socket->index()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return digraph.to_dot_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BKE
|
@@ -120,7 +120,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
ArrayRef<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
|
MutableArrayRef<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
|
||||||
{
|
{
|
||||||
void *pointer_buffer = this->allocate(n * sizeof(T *), alignof(T *));
|
void *pointer_buffer = this->allocate(n * sizeof(T *), alignof(T *));
|
||||||
void *element_buffer = this->allocate(n * sizeof(T), alignof(T));
|
void *element_buffer = this->allocate(n * sizeof(T), alignof(T));
|
||||||
|
Reference in New Issue
Block a user