Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/intern/node_tree_ref.cc
| Show All 9 Lines | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
| * along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
| */ | */ | ||||
| #include <mutex> | #include <mutex> | ||||
| #include <queue> | |||||
| #include "NOD_node_tree_ref.hh" | #include "NOD_node_tree_ref.hh" | ||||
| #include "BLI_dot_export.hh" | #include "BLI_dot_export.hh" | ||||
| namespace blender::nodes { | namespace blender::nodes { | ||||
| NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree) | NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree) | ||||
| ▲ Show 20 Lines • Show All 442 Lines • ▼ Show 20 Lines | bool NodeTreeRef::has_undefined_nodes_or_sockets() const | ||||
| for (const SocketRef *socket : sockets_by_id_) { | for (const SocketRef *socket : sockets_by_id_) { | ||||
| if (socket->is_undefined()) { | if (socket->is_undefined()) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool NodeRef::any_input_is_directly_linked() const | |||||
| { | |||||
| for (const SocketRef *socket : inputs_) { | |||||
| if (!socket->directly_linked_sockets().is_empty()) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool NodeRef::any_output_is_directly_linked() const | |||||
| { | |||||
| for (const SocketRef *socket : outputs_) { | |||||
| if (!socket->directly_linked_sockets().is_empty()) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool NodeRef::any_socket_is_directly_linked(eNodeSocketInOut in_out) const | |||||
| { | |||||
| if (in_out == SOCK_IN) { | |||||
| return this->any_input_is_directly_linked(); | |||||
| } | |||||
| return this->any_output_is_directly_linked(); | |||||
| } | |||||
| /** | |||||
| * Sort nodes topologically from left to right or right to left. | |||||
| * In the future the result if this could be cached on #NodeTreeRef. | |||||
| */ | |||||
| Vector<const NodeRef *> NodeTreeRef::toposort(const ToposortDirection direction) const | |||||
| { | |||||
| Vector<const NodeRef *> toposort; | |||||
| toposort.reserve(nodes_by_id_.size()); | |||||
| Array<bool> node_is_pushed_by_id(nodes_by_id_.size(), false); | |||||
| std::queue<const NodeRef *> nodes_to_check; | |||||
| for (const NodeRef *node : nodes_by_id_) { | |||||
| if (!node->any_socket_is_directly_linked( | |||||
| direction == ToposortDirection::LeftToRight ? SOCK_OUT : SOCK_IN)) { | |||||
| node_is_pushed_by_id[node->id()] = true; | |||||
| nodes_to_check.push(node); | |||||
| } | |||||
| } | |||||
| while (!nodes_to_check.empty()) { | |||||
| const NodeRef *node = nodes_to_check.front(); | |||||
| nodes_to_check.pop(); | |||||
| toposort.append(node); | |||||
| for (const SocketRef *socket : | |||||
| node->sockets(direction == ToposortDirection::LeftToRight ? SOCK_IN : SOCK_OUT)) { | |||||
| for (const SocketRef *linked_socket : socket->directly_linked_sockets()) { | |||||
| const NodeRef &linked_node = linked_socket->node(); | |||||
| const int linked_node_id = linked_node.id(); | |||||
| if (!node_is_pushed_by_id[linked_node_id]) { | |||||
| node_is_pushed_by_id[linked_node_id] = true; | |||||
| nodes_to_check.push(&linked_node); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| toposort.as_mutable_span().reverse(); | |||||
| return toposort; | |||||
| } | |||||
| std::string NodeTreeRef::to_dot() const | std::string NodeTreeRef::to_dot() const | ||||
| { | { | ||||
| dot::DirectedGraph digraph; | dot::DirectedGraph digraph; | ||||
| digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); | digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); | ||||
| Map<const NodeRef *, dot::NodeWithSocketsRef> dot_nodes; | Map<const NodeRef *, dot::NodeWithSocketsRef> dot_nodes; | ||||
| for (const NodeRef *node : nodes_by_id_) { | for (const NodeRef *node : nodes_by_id_) { | ||||
| Show All 36 Lines | |||||