Cleanup: Nodes: reduce coupling between socket shape and field state

Previously, the inferencing result was only stored in the socket shape.
However, that was conflicting with experiments where the socket shape and
the field state was not related.
This commit is contained in:
Jacques Lucke
2024-08-20 16:15:52 +02:00
parent 7f1812e335
commit 24f7b7a8fb
5 changed files with 48 additions and 21 deletions

View File

@@ -196,6 +196,12 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
Vector<bNode *> root_frames;
};
enum class FieldSocketState {
RequiresSingle,
CanBeField,
IsField,
};
/**
* Run-time data for every socket. This should only contain data that is somewhat persistent (i.e.
* data that lives longer than a single depsgraph evaluation + redraw). Data that's only used in
@@ -226,6 +232,11 @@ class bNodeSocketRuntime : NonCopyable, NonMovable {
*/
float2 location;
/**
* This is computed during field inferencing and influences the socket shape in geometry nodes.
*/
std::optional<FieldSocketState> field_state;
/** Only valid when #topology_cache_is_dirty is false. */
Vector<bNodeLink *> directly_linked_links;
Vector<bNodeSocket *> directly_linked_sockets;

View File

@@ -24,7 +24,7 @@ using nodes::NodeDeclaration;
static bool socket_is_field(const bNodeSocket &socket)
{
return socket.display_shape == SOCK_DISPLAY_SHAPE_DIAMOND;
return socket.runtime->field_state == FieldSocketState::IsField;
}
static const aal::RelationsInNode &get_relations_in_node(const bNode &node, ResourceScope &scope)

View File

@@ -671,33 +671,25 @@ static void determine_group_output_states(
}
}
static void update_socket_shapes(const bNodeTree &tree,
static void update_socket_states(const bNodeTree &tree,
const Span<SocketFieldState> field_state_by_socket_id)
{
const eNodeSocketDisplayShape requires_data_shape = SOCK_DISPLAY_SHAPE_CIRCLE;
const eNodeSocketDisplayShape data_but_can_be_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND_DOT;
const eNodeSocketDisplayShape is_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND;
auto get_shape_for_state = [&](const SocketFieldState &state) {
auto get_state_to_store = [&](const SocketFieldState &state) {
if (state.is_always_single) {
return requires_data_shape;
return FieldSocketState::RequiresSingle;
}
if (!state.is_single) {
return is_field_shape;
return FieldSocketState::IsField;
}
if (state.requires_single) {
return requires_data_shape;
return FieldSocketState::RequiresSingle;
}
return data_but_can_be_field_shape;
return FieldSocketState::CanBeField;
};
for (const bNodeSocket *socket : tree.all_input_sockets()) {
const SocketFieldState &state = field_state_by_socket_id[socket->index_in_tree()];
const_cast<bNodeSocket *>(socket)->display_shape = get_shape_for_state(state);
}
for (const bNodeSocket *socket : tree.all_sockets()) {
const SocketFieldState &state = field_state_by_socket_id[socket->index_in_tree()];
const_cast<bNodeSocket *>(socket)->display_shape = get_shape_for_state(state);
const_cast<bNodeSocket *>(socket)->runtime->field_state = get_state_to_store(state);
}
}
@@ -739,7 +731,7 @@ bool update_field_inferencing(const bNodeTree &tree)
propagate_field_status_from_left_to_right(tree, interface_by_node, field_state_by_socket_id);
determine_group_output_states(
tree, *new_inferencing_interface, interface_by_node, field_state_by_socket_id);
update_socket_shapes(tree, field_state_by_socket_id);
update_socket_states(tree, field_state_by_socket_id);
/* Update the previous group interface. */
const bool group_interface_changed = !tree.runtime->field_inferencing_interface ||

View File

@@ -514,6 +514,7 @@ class NodeTreeMainUpdater {
if (nodes::gizmos::update_tree_gizmo_propagation(ntree)) {
result.interface_changed = true;
}
this->update_socket_shapes(ntree);
}
result.output_changed = this->check_if_output_changed(ntree);
@@ -840,13 +841,36 @@ class NodeTreeMainUpdater {
for (const int i : IndexRange(storage.items_num)) {
const bNodeSocket &socket = node->input_socket(i);
NodeGeometryBakeItem &item = storage.items[i];
if (socket.display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) {
if (socket.runtime->field_state == FieldSocketState::IsField) {
item.flag |= GEO_NODE_BAKE_ITEM_IS_ATTRIBUTE;
}
}
}
}
void update_socket_shapes(bNodeTree &ntree)
{
ntree.ensure_topology_cache();
for (bNodeSocket *socket : ntree.all_sockets()) {
socket->display_shape = this->get_socket_shape(*socket);
}
}
int get_socket_shape(const bNodeSocket &socket)
{
if (socket.runtime->field_state) {
switch (*socket.runtime->field_state) {
case bke::FieldSocketState::RequiresSingle:
return SOCK_DISPLAY_SHAPE_CIRCLE;
case bke::FieldSocketState::CanBeField:
return SOCK_DISPLAY_SHAPE_DIAMOND_DOT;
case bke::FieldSocketState::IsField:
return SOCK_DISPLAY_SHAPE_DIAMOND;
}
}
return socket.display_shape;
}
bool propagate_enum_definitions(bNodeTree &ntree)
{
ntree.ensure_interface_cache();
@@ -1131,8 +1155,8 @@ class NodeTreeMainUpdater {
continue;
}
if (ntree.type == NTREE_GEOMETRY) {
if (link->fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND &&
link->tosock->display_shape != SOCK_DISPLAY_SHAPE_DIAMOND)
if (link->fromsock->runtime->field_state == FieldSocketState::IsField &&
link->tosock->runtime->field_state != FieldSocketState::IsField)
{
link->flag &= ~NODE_LINK_VALID;
ntree.runtime->link_errors_by_target_node.add(

View File

@@ -2215,7 +2215,7 @@ static bool node_link_is_field_link(const SpaceNode &snode, const bNodeLink &lin
if (snode.edittree->type != NTREE_GEOMETRY) {
return false;
}
if (link.fromsock && link.fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) {
if (link.fromsock && link.fromsock->runtime->field_state == bke::FieldSocketState::IsField) {
return true;
}
return false;