Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/node.cc
| Show First 20 Lines • Show All 4,589 Lines • ▼ Show 20 Lines | static FieldInferencingInterface get_node_field_inferencing_interface(const NodeRef &node) | ||||
| return inferencing_interface; | return inferencing_interface; | ||||
| } | } | ||||
| /** | /** | ||||
| * This struct contains information for every socket. The values are propagated through the | * This struct contains information for every socket. The values are propagated through the | ||||
| * network. | * network. | ||||
| */ | */ | ||||
| struct SocketFieldState { | struct SocketFieldState { | ||||
| /* This socket starts a new field. */ | |||||
| bool is_field_source = false; | |||||
| /* This socket can never become a field, because the node itself does not support it. */ | |||||
| bool is_always_single = false; | |||||
| /* This socket is currently a single value. It could become a field though. */ | /* This socket is currently a single value. It could become a field though. */ | ||||
| bool is_single = true; | bool is_single = true; | ||||
| /* This socket is required to be a single value. It must not be a field. */ | /* This socket is required to be a single value. This can be because the node itself only | ||||
| * supports this socket to be a single value, or because a node afterwards requires this to be a | |||||
| * single value. */ | |||||
| bool requires_single = false; | bool requires_single = false; | ||||
| /* This socket starts a new field. */ | |||||
| bool is_field_source = false; | |||||
| }; | }; | ||||
| static Vector<const InputSocketRef *> gather_input_socket_dependencies( | static Vector<const InputSocketRef *> gather_input_socket_dependencies( | ||||
| const OutputFieldDependency &field_dependency, const NodeRef &node) | const OutputFieldDependency &field_dependency, const NodeRef &node) | ||||
| { | { | ||||
| const OutputSocketFieldType type = field_dependency.field_type(); | const OutputSocketFieldType type = field_dependency.field_type(); | ||||
| Vector<const InputSocketRef *> input_sockets; | Vector<const InputSocketRef *> input_sockets; | ||||
| switch (type) { | switch (type) { | ||||
| ▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | for (const OutputSocketRef *output_socket : node->outputs()) { | ||||
| const OutputFieldDependency &field_dependency = | const OutputFieldDependency &field_dependency = | ||||
| inferencing_interface.outputs[output_socket->index()]; | inferencing_interface.outputs[output_socket->index()]; | ||||
| if (field_dependency.field_type() == OutputSocketFieldType::FieldSource) { | if (field_dependency.field_type() == OutputSocketFieldType::FieldSource) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (field_dependency.field_type() == OutputSocketFieldType::None) { | if (field_dependency.field_type() == OutputSocketFieldType::None) { | ||||
| state.requires_single = true; | state.requires_single = true; | ||||
| state.is_always_single = true; | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* The output is required to be a single value when it is connected to any input that does | /* The output is required to be a single value when it is connected to any input that does | ||||
| * not support fields. */ | * not support fields. */ | ||||
| for (const InputSocketRef *target_socket : output_socket->directly_linked_sockets()) { | for (const InputSocketRef *target_socket : output_socket->directly_linked_sockets()) { | ||||
| state.requires_single |= field_state_by_socket_id[target_socket->id()].requires_single; | state.requires_single |= field_state_by_socket_id[target_socket->id()].requires_single; | ||||
| } | } | ||||
| Show All 25 Lines | for (const OutputSocketRef *output_socket : node->outputs()) { | ||||
| } | } | ||||
| } | } | ||||
| /* Some inputs do not require fields independent of what the outputs are connected to. */ | /* Some inputs do not require fields independent of what the outputs are connected to. */ | ||||
| for (const InputSocketRef *input_socket : node->inputs()) { | for (const InputSocketRef *input_socket : node->inputs()) { | ||||
| SocketFieldState &state = field_state_by_socket_id[input_socket->id()]; | SocketFieldState &state = field_state_by_socket_id[input_socket->id()]; | ||||
| if (inferencing_interface.inputs[input_socket->index()] == InputSocketFieldType::None) { | if (inferencing_interface.inputs[input_socket->index()] == InputSocketFieldType::None) { | ||||
| state.requires_single = true; | state.requires_single = true; | ||||
| state.is_always_single = true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void determine_group_input_states( | static void determine_group_input_states( | ||||
| const NodeTreeRef &tree, | const NodeTreeRef &tree, | ||||
| FieldInferencingInterface &new_inferencing_interface, | FieldInferencingInterface &new_inferencing_interface, | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | for (const NodeRef *node : sorted_nodes) { | ||||
| } | } | ||||
| const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface( | const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface( | ||||
| *node); | *node); | ||||
| /* Update field state of input sockets, also taking into account linked origin sockets. */ | /* Update field state of input sockets, also taking into account linked origin sockets. */ | ||||
| for (const InputSocketRef *input_socket : node->inputs()) { | for (const InputSocketRef *input_socket : node->inputs()) { | ||||
| SocketFieldState &state = field_state_by_socket_id[input_socket->id()]; | SocketFieldState &state = field_state_by_socket_id[input_socket->id()]; | ||||
| if (state.requires_single) { | if (state.is_always_single) { | ||||
| state.is_single = true; | state.is_single = true; | ||||
| continue; | continue; | ||||
| } | } | ||||
| state.is_single = true; | state.is_single = true; | ||||
| if (input_socket->logically_linked_sockets().is_empty()) { | if (input_socket->logically_linked_sockets().is_empty()) { | ||||
| if (inferencing_interface.inputs[input_socket->index()] == | if (inferencing_interface.inputs[input_socket->index()] == | ||||
| InputSocketFieldType::Implicit) { | InputSocketFieldType::Implicit) { | ||||
| state.is_single = false; | state.is_single = false; | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
| static void update_socket_shapes(const NodeTreeRef &tree, | static void update_socket_shapes(const NodeTreeRef &tree, | ||||
| const Span<SocketFieldState> field_state_by_socket_id) | const Span<SocketFieldState> field_state_by_socket_id) | ||||
| { | { | ||||
| const eNodeSocketDisplayShape requires_data_shape = SOCK_DISPLAY_SHAPE_CIRCLE; | const eNodeSocketDisplayShape requires_data_shape = SOCK_DISPLAY_SHAPE_CIRCLE; | ||||
| const eNodeSocketDisplayShape data_but_can_be_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND_DOT; | const eNodeSocketDisplayShape data_but_can_be_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND_DOT; | ||||
| const eNodeSocketDisplayShape is_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND; | const eNodeSocketDisplayShape is_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND; | ||||
| for (const InputSocketRef *socket : tree.input_sockets()) { | auto get_shape_for_state = [&](const SocketFieldState &state) { | ||||
| bNodeSocket *bsocket = socket->bsocket(); | if (state.is_always_single) { | ||||
| const SocketFieldState &state = field_state_by_socket_id[socket->id()]; | return requires_data_shape; | ||||
| if (state.requires_single) { | |||||
| bsocket->display_shape = requires_data_shape; | |||||
| } | } | ||||
| else if (state.is_single) { | if (!state.is_single) { | ||||
| bsocket->display_shape = data_but_can_be_field_shape; | return is_field_shape; | ||||
| } | } | ||||
| else { | if (state.requires_single) { | ||||
| bsocket->display_shape = is_field_shape; | return requires_data_shape; | ||||
| } | } | ||||
| return data_but_can_be_field_shape; | |||||
| }; | |||||
| for (const InputSocketRef *socket : tree.input_sockets()) { | |||||
| bNodeSocket *bsocket = socket->bsocket(); | |||||
| const SocketFieldState &state = field_state_by_socket_id[socket->id()]; | |||||
| bsocket->display_shape = get_shape_for_state(state); | |||||
| } | } | ||||
| for (const OutputSocketRef *socket : tree.output_sockets()) { | for (const OutputSocketRef *socket : tree.output_sockets()) { | ||||
| bNodeSocket *bsocket = socket->bsocket(); | bNodeSocket *bsocket = socket->bsocket(); | ||||
| const SocketFieldState &state = field_state_by_socket_id[socket->id()]; | const SocketFieldState &state = field_state_by_socket_id[socket->id()]; | ||||
| if (state.requires_single) { | bsocket->display_shape = get_shape_for_state(state); | ||||
| bsocket->display_shape = requires_data_shape; | |||||
| } | |||||
| else if (state.is_single) { | |||||
| bsocket->display_shape = data_but_can_be_field_shape; | |||||
| } | |||||
| else { | |||||
| bsocket->display_shape = is_field_shape; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static bool update_field_inferencing(bNodeTree &btree) | static bool update_field_inferencing(bNodeTree &btree) | ||||
| { | { | ||||
| using namespace blender::nodes; | using namespace blender::nodes; | ||||
| if (btree.type != NTREE_GEOMETRY) { | if (btree.type != NTREE_GEOMETRY) { | ||||
| return false; | return false; | ||||
| ▲ Show 20 Lines • Show All 1,077 Lines • Show Last 20 Lines | |||||