This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/nodes/NOD_derived_node_tree.hh

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

563 lines
13 KiB
C++
Raw Normal View History

/*
* 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.
*/
#pragma once
/** \file
* \ingroup nodes
*
* DerivedNodeTree provides a flattened view on a bNodeTree, i.e. node groups are inlined. It
* builds on top of NodeTreeRef and supports similar queries efficiently.
*
* Every inlined node remembers its path to the parent ("call stack").
*
* Unlinked group node inputs are handled separately from other sockets.
*
* There is a dot graph exporter for debugging purposes.
*/
#include "NOD_node_tree_ref.hh"
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
#include "BLI_vector_set.hh"
namespace blender::nodes {
class DSocket;
class DInputSocket;
class DOutputSocket;
class DNode;
class DParentNode;
class DGroupInput;
class DerivedNodeTree;
class DSocket : NonCopyable, NonMovable {
protected:
DNode *node_;
const SocketRef *socket_ref_;
int id_;
friend DerivedNodeTree;
public:
const DNode &node() const;
int id() const;
int 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;
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
StringRefNull identifier() const;
bNodeSocketType *typeinfo() const;
const SocketRef &socket_ref() const;
bNodeSocket *bsocket() const;
bool is_available() const;
};
class DInputSocket : public DSocket {
private:
Vector<DOutputSocket *> linked_sockets_;
Vector<DGroupInput *> linked_group_inputs_;
friend DerivedNodeTree;
public:
const InputSocketRef &socket_ref() const;
Span<const DOutputSocket *> linked_sockets() const;
Span<const DGroupInput *> linked_group_inputs() const;
bool is_linked() const;
};
class DOutputSocket : public DSocket {
private:
Vector<DInputSocket *> linked_sockets_;
friend DerivedNodeTree;
public:
const OutputSocketRef &socket_ref() const;
Span<const DInputSocket *> linked_sockets() const;
};
class DGroupInput : NonCopyable, NonMovable {
private:
const InputSocketRef *socket_ref_;
DParentNode *parent_;
Vector<DInputSocket *> linked_sockets_;
int id_;
friend DerivedNodeTree;
public:
const InputSocketRef &socket_ref() const;
bNodeSocket *bsocket() const;
const DParentNode *parent() const;
Span<const DInputSocket *> linked_sockets() const;
int id() const;
StringRefNull name() const;
};
class DNode : NonCopyable, NonMovable {
private:
const NodeRef *node_ref_;
DParentNode *parent_;
Span<DInputSocket *> inputs_;
Span<DOutputSocket *> outputs_;
int id_;
friend DerivedNodeTree;
public:
const NodeRef &node_ref() const;
const DParentNode *parent() const;
Span<const DInputSocket *> inputs() const;
Span<const DOutputSocket *> outputs() const;
const DInputSocket &input(int index) const;
const DOutputSocket &output(int index) const;
const DInputSocket &input(int index, StringRef expected_name) const;
const DOutputSocket &output(int index, StringRef expected_name) const;
int id() const;
PointerRNA *rna() const;
StringRefNull idname() const;
StringRefNull name() const;
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
bNode *bnode() const;
bNodeType *typeinfo() const;
private:
void destruct_with_sockets();
};
class DParentNode : NonCopyable, NonMovable {
private:
const NodeRef *node_ref_;
DParentNode *parent_;
int id_;
friend DerivedNodeTree;
public:
const DParentNode *parent() const;
const NodeRef &node_ref() const;
int id() const;
};
using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
class DerivedNodeTree : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
Vector<DNode *> nodes_by_id_;
Vector<DGroupInput *> group_inputs_;
Vector<DParentNode *> parent_nodes_;
Vector<DSocket *> sockets_by_id_;
Vector<DInputSocket *> input_sockets_;
Vector<DOutputSocket *> output_sockets_;
MultiValueMap<const bNodeType *, DNode *> nodes_by_type_;
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
VectorSet<const NodeTreeRef *> used_node_tree_refs_;
bNodeTree *btree_;
public:
DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs);
~DerivedNodeTree();
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
bNodeTree *btree() const;
Span<const DNode *> nodes() const;
Span<const DNode *> nodes_by_type(StringRefNull idname) const;
Span<const DNode *> nodes_by_type(const bNodeType *nodetype) const;
Span<const DSocket *> sockets() const;
Span<const DInputSocket *> input_sockets() const;
Span<const DOutputSocket *> output_sockets() const;
Span<const DGroupInput *> group_inputs() const;
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
Span<const NodeTreeRef *> used_node_tree_refs() const;
bool has_link_cycles() const;
std::string to_dot() const;
private:
/* Utility functions used during construction. */
void insert_nodes_and_links_in_id_order(const NodeTreeRef &tree_ref,
DParentNode *parent,
Vector<DNode *> &all_nodes);
DNode &create_node(const NodeRef &node_ref,
DParentNode *parent,
MutableSpan<DSocket *> r_sockets_map);
void expand_groups(Vector<DNode *> &all_nodes,
Vector<DGroupInput *> &all_group_inputs,
Vector<DParentNode *> &all_parent_nodes,
NodeTreeRefMap &node_tree_refs);
void expand_group_node(DNode &group_node,
Vector<DNode *> &all_nodes,
Vector<DGroupInput *> &all_group_inputs,
Vector<DParentNode *> &all_parent_nodes,
NodeTreeRefMap &node_tree_refs);
void create_group_inputs_for_unlinked_inputs(DNode &node,
Vector<DGroupInput *> &all_group_inputs);
void relink_group_inputs(const NodeTreeRef &group_ref,
Span<DNode *> nodes_by_id,
DNode &group_node);
void relink_group_outputs(const NodeTreeRef &group_ref,
Span<DNode *> nodes_by_id,
DNode &group_node);
void remove_expanded_group_interfaces(Vector<DNode *> &all_nodes);
void remove_unused_group_inputs(Vector<DGroupInput *> &all_group_inputs);
void relink_and_remove_muted_nodes(Vector<DNode *> &all_nodes);
void relink_muted_node(DNode &muted_node);
void store_in_this_and_init_ids(Vector<DNode *> &&all_nodes,
Vector<DGroupInput *> &&all_group_inputs,
Vector<DParentNode *> &&all_parent_nodes);
};
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
namespace derived_node_tree_types {
using nodes::DerivedNodeTree;
using nodes::DGroupInput;
using nodes::DInputSocket;
using nodes::DNode;
using nodes::DOutputSocket;
using nodes::DParentNode;
}; // namespace derived_node_tree_types
/* --------------------------------------------------------------------
* DSocket inline methods.
*/
inline const DNode &DSocket::node() const
{
return *node_;
}
inline int DSocket::id() const
{
return id_;
}
inline int DSocket::index() const
{
return socket_ref_->index();
}
inline bool DSocket::is_input() const
{
return socket_ref_->is_input();
}
inline bool DSocket::is_output() const
{
return socket_ref_->is_output();
}
inline const DSocket &DSocket::as_base() const
{
return *this;
}
inline const DInputSocket &DSocket::as_input() const
{
return static_cast<const DInputSocket &>(*this);
}
inline const DOutputSocket &DSocket::as_output() const
{
return static_cast<const DOutputSocket &>(*this);
}
inline PointerRNA *DSocket::rna() const
{
return socket_ref_->rna();
}
inline StringRefNull DSocket::idname() const
{
return socket_ref_->idname();
}
inline StringRefNull DSocket::name() const
{
return socket_ref_->name();
}
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
inline StringRefNull DSocket::identifier() const
{
return socket_ref_->identifier();
}
inline bNodeSocketType *DSocket::typeinfo() const
{
return socket_ref_->bsocket()->typeinfo;
}
inline const SocketRef &DSocket::socket_ref() const
{
return *socket_ref_;
}
inline bNodeSocket *DSocket::bsocket() const
{
return socket_ref_->bsocket();
}
inline bool DSocket::is_available() const
{
return (socket_ref_->bsocket()->flag & SOCK_UNAVAIL) == 0;
}
/* --------------------------------------------------------------------
* DInputSocket inline methods.
*/
inline const InputSocketRef &DInputSocket::socket_ref() const
{
return socket_ref_->as_input();
}
inline Span<const DOutputSocket *> DInputSocket::linked_sockets() const
{
return linked_sockets_;
}
inline Span<const DGroupInput *> DInputSocket::linked_group_inputs() const
{
return linked_group_inputs_;
}
inline bool DInputSocket::is_linked() const
{
return linked_sockets_.size() > 0 || linked_group_inputs_.size() > 0;
}
/* --------------------------------------------------------------------
* DOutputSocket inline methods.
*/
inline const OutputSocketRef &DOutputSocket::socket_ref() const
{
return socket_ref_->as_output();
}
inline Span<const DInputSocket *> DOutputSocket::linked_sockets() const
{
return linked_sockets_;
}
/* --------------------------------------------------------------------
* DGroupInput inline methods.
*/
inline const InputSocketRef &DGroupInput::socket_ref() const
{
return *socket_ref_;
}
inline bNodeSocket *DGroupInput::bsocket() const
{
return socket_ref_->bsocket();
}
inline const DParentNode *DGroupInput::parent() const
{
return parent_;
}
inline Span<const DInputSocket *> DGroupInput::linked_sockets() const
{
return linked_sockets_;
}
inline int DGroupInput::id() const
{
return id_;
}
inline StringRefNull DGroupInput::name() const
{
return socket_ref_->name();
}
/* --------------------------------------------------------------------
* DNode inline methods.
*/
inline const NodeRef &DNode::node_ref() const
{
return *node_ref_;
}
inline const DParentNode *DNode::parent() const
{
return parent_;
}
inline Span<const DInputSocket *> DNode::inputs() const
{
return inputs_;
}
inline Span<const DOutputSocket *> DNode::outputs() const
{
return outputs_;
}
inline const DInputSocket &DNode::input(int index) const
{
return *inputs_[index];
}
inline const DOutputSocket &DNode::output(int index) const
{
return *outputs_[index];
}
inline const DInputSocket &DNode::input(int index, StringRef expected_name) const
{
const DInputSocket &socket = *inputs_[index];
BLI_assert(socket.name() == expected_name);
UNUSED_VARS_NDEBUG(expected_name);
return socket;
}
inline const DOutputSocket &DNode::output(int index, StringRef expected_name) const
{
const DOutputSocket &socket = *outputs_[index];
BLI_assert(socket.name() == expected_name);
UNUSED_VARS_NDEBUG(expected_name);
return socket;
}
inline int DNode::id() const
{
return id_;
}
inline PointerRNA *DNode::rna() const
{
return node_ref_->rna();
}
inline StringRefNull DNode::idname() const
{
return node_ref_->idname();
}
inline StringRefNull DNode::name() const
{
return node_ref_->name();
}
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
inline bNode *DNode::bnode() const
{
return node_ref_->bnode();
}
inline bNodeType *DNode::typeinfo() const
{
return node_ref_->bnode()->typeinfo;
}
/* --------------------------------------------------------------------
* DParentNode inline methods.
*/
inline const DParentNode *DParentNode::parent() const
{
return parent_;
}
inline const NodeRef &DParentNode::node_ref() const
{
return *node_ref_;
}
inline int DParentNode::id() const
{
return id_;
}
/* --------------------------------------------------------------------
* DerivedNodeTree inline methods.
*/
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
inline bNodeTree *DerivedNodeTree::btree() const
{
return btree_;
}
inline Span<const DNode *> DerivedNodeTree::nodes() const
{
return nodes_by_id_;
}
inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname) const
{
const bNodeType *nodetype = nodeTypeFind(idname.c_str());
return this->nodes_by_type(nodetype);
}
inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const
{
return nodes_by_type_.lookup(nodetype);
}
inline Span<const DSocket *> DerivedNodeTree::sockets() const
{
return sockets_by_id_;
}
inline Span<const DInputSocket *> DerivedNodeTree::input_sockets() const
{
return input_sockets_;
}
inline Span<const DOutputSocket *> DerivedNodeTree::output_sockets() const
{
return output_sockets_;
}
inline Span<const DGroupInput *> DerivedNodeTree::group_inputs() const
{
return group_inputs_;
}
Geometry Nodes: initial scattering and geometry nodes This is the initial merge from the geometry-nodes branch. Nodes: * Attribute Math * Boolean * Edge Split * Float Compare * Object Info * Point Distribute * Point Instance * Random Attribute * Random Float * Subdivision Surface * Transform * Triangulate It includes the initial evaluation of geometry node groups in the Geometry Nodes modifier. Notes on the Generic attribute access API The API adds an indirection for attribute access. That has the following benefits: * Most code does not have to care about how an attribute is stored internally. This is mainly necessary, because we have to deal with "legacy" attributes such as vertex weights and attributes that are embedded into other structs such as vertex positions. * When reading from an attribute, we generally don't care what domain the attribute is stored on. So we want to abstract away the interpolation that that adapts attributes from one domain to another domain (this is not actually implemented yet). Other possible improvements for later iterations include: * Actually implement interpolation between domains. * Don't use inheritance for the different attribute types. A single class for read access and one for write access might be enough, because we know all the ways in which attributes are stored internally. We don't want more different internal structures in the future. On the contrary, ideally we can consolidate the different storage formats in the future to reduce the need for this indirection. * Remove the need for heap allocations when creating attribute accessors. It includes commits from: * Dalai Felinto * Hans Goudey * Jacques Lucke * Léo Depoix
2020-12-02 13:25:25 +01:00
inline Span<const NodeTreeRef *> DerivedNodeTree::used_node_tree_refs() const
{
return used_node_tree_refs_;
}
} // namespace blender::nodes