Geometry Nodes: support muted nodes
The handling of muted nodes is handled at the derived node tree level now. This is also where expanding node groups is handled. Muted nodes are relinked and removed from the derived tree during construction. The geometry node evaluation code does not have to know about muted nodes this way.
This commit is contained in:
parent
ae0aa4b94c
commit
fc4a853846
|
@ -238,6 +238,8 @@ class DerivedNodeTree : NonCopyable, NonMovable {
|
|||
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);
|
||||
|
|
|
@ -153,6 +153,7 @@ class NodeRef : NonCopyable, NonMovable {
|
|||
bool is_group_node() const;
|
||||
bool is_group_input_node() const;
|
||||
bool is_group_output_node() const;
|
||||
bool is_muted() const;
|
||||
};
|
||||
|
||||
class NodeTreeRef : NonCopyable, NonMovable {
|
||||
|
@ -402,6 +403,11 @@ inline bool NodeRef::is_group_output_node() const
|
|||
return bnode_->type == NODE_GROUP_OUTPUT;
|
||||
}
|
||||
|
||||
inline bool NodeRef::is_muted() const
|
||||
{
|
||||
return (bnode_->flag & NODE_MUTED) != 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* NodeRef inline methods.
|
||||
*/
|
||||
|
|
|
@ -27,4 +27,5 @@ void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclas
|
|||
{
|
||||
node_type_base(ntype, type, name, nclass, flag);
|
||||
ntype->poll = fn_node_poll_default;
|
||||
ntype->update_internal_links = node_update_internal_links_default;
|
||||
}
|
||||
|
|
|
@ -26,4 +26,5 @@ void geo_node_type_base(bNodeType *ntype, int type, const char *name, short ncla
|
|||
{
|
||||
node_type_base(ntype, type, name, nclass, flag);
|
||||
ntype->poll = geo_node_poll_default;
|
||||
ntype->update_internal_links = node_update_internal_links_default;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_ref
|
|||
|
||||
this->insert_nodes_and_links_in_id_order(main_tree_ref, nullptr, all_nodes);
|
||||
this->expand_groups(all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
|
||||
this->relink_and_remove_muted_nodes(all_nodes);
|
||||
this->remove_expanded_group_interfaces(all_nodes);
|
||||
this->remove_unused_group_inputs(all_group_inputs);
|
||||
this->store_in_this_and_init_ids(
|
||||
|
@ -120,7 +121,11 @@ BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes,
|
|||
for (int i = 0; i < all_nodes.size(); i++) {
|
||||
DNode &node = *all_nodes[i];
|
||||
if (node.node_ref_->is_group_node()) {
|
||||
this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
|
||||
/* Muted nodes are relinked in a separate step. */
|
||||
if (!node.node_ref_->is_muted()) {
|
||||
this->expand_group_node(
|
||||
node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,6 +306,83 @@ BLI_NOINLINE void DerivedNodeTree::remove_unused_group_inputs(
|
|||
}
|
||||
}
|
||||
|
||||
BLI_NOINLINE void DerivedNodeTree::relink_and_remove_muted_nodes(Vector<DNode *> &all_nodes)
|
||||
{
|
||||
int index = 0;
|
||||
while (index < all_nodes.size()) {
|
||||
DNode &node = *all_nodes[index];
|
||||
const NodeRef &node_ref = *node.node_ref_;
|
||||
if (node_ref.is_muted()) {
|
||||
this->relink_muted_node(node);
|
||||
all_nodes.remove_and_reorder(index);
|
||||
node.destruct_with_sockets();
|
||||
}
|
||||
else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_NOINLINE void DerivedNodeTree::relink_muted_node(DNode &node)
|
||||
{
|
||||
const bNode &bnode = *node.bnode();
|
||||
LISTBASE_FOREACH (const bNodeLink *, internal_link, &bnode.internal_links) {
|
||||
BLI_assert(internal_link->fromnode == &bnode);
|
||||
BLI_assert(internal_link->tonode == &bnode);
|
||||
bNodeSocket *input_bsocket = internal_link->fromsock;
|
||||
bNodeSocket *output_bsocket = internal_link->tosock;
|
||||
|
||||
/* Find internally linked sockets. */
|
||||
DInputSocket *input_socket = nullptr;
|
||||
DOutputSocket *output_socket = nullptr;
|
||||
for (DInputSocket *socket : node.inputs_) {
|
||||
if (socket->bsocket() == input_bsocket) {
|
||||
input_socket = socket;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (DOutputSocket *socket : node.outputs_) {
|
||||
if (socket->bsocket() == output_bsocket) {
|
||||
output_socket = socket;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_assert(input_socket != nullptr);
|
||||
BLI_assert(output_socket != nullptr);
|
||||
|
||||
/* Link sockets connected to the input to sockets that are connected to the internally linked
|
||||
* output. */
|
||||
for (DInputSocket *to_socket : output_socket->linked_sockets_) {
|
||||
for (DOutputSocket *from_socket : input_socket->linked_sockets_) {
|
||||
from_socket->linked_sockets_.append_non_duplicates(to_socket);
|
||||
to_socket->linked_sockets_.append_non_duplicates(from_socket);
|
||||
}
|
||||
for (DGroupInput *group_input : input_socket->linked_group_inputs_) {
|
||||
group_input->linked_sockets_.append_non_duplicates(to_socket);
|
||||
to_socket->linked_group_inputs_.append_non_duplicates(group_input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove remaining links from muted node. */
|
||||
for (DInputSocket *to_socket : node.inputs_) {
|
||||
for (DOutputSocket *from_socket : to_socket->linked_sockets_) {
|
||||
from_socket->linked_sockets_.remove_first_occurrence_and_reorder(to_socket);
|
||||
}
|
||||
for (DGroupInput *from_group_input : to_socket->linked_group_inputs_) {
|
||||
from_group_input->linked_sockets_.remove_first_occurrence_and_reorder(to_socket);
|
||||
}
|
||||
to_socket->linked_sockets_.clear();
|
||||
to_socket->linked_group_inputs_.clear();
|
||||
}
|
||||
for (DOutputSocket *from_socket : node.outputs_) {
|
||||
for (DInputSocket *to_socket : from_socket->linked_sockets_) {
|
||||
to_socket->linked_sockets_.remove_first_occurrence_and_reorder(from_socket);
|
||||
}
|
||||
from_socket->linked_sockets_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void DNode::destruct_with_sockets()
|
||||
{
|
||||
for (DInputSocket *socket : inputs_) {
|
||||
|
|
|
@ -435,6 +435,22 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
|
|||
default:
|
||||
return -1;
|
||||
}
|
||||
case SOCK_OBJECT: {
|
||||
switch (from) {
|
||||
case SOCK_OBJECT:
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
case SOCK_GEOMETRY: {
|
||||
switch (from) {
|
||||
case SOCK_GEOMETRY:
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue