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:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user