24using nodes::StructureType;
25namespace aal = nodes::anonymous_attribute_lifetime;
36 if (node.is_undefined() || !node.declaration() || node.declaration()->skip_updating_sockets) {
42 if (node.is_reroute()) {
57 if (dependency.
type != StructureType::Dynamic) {
86 for (
const int i :
nodes.index_range()) {
116 switch (requirement) {
118 return StructureType::Dynamic;
120 return StructureType::Field;
122 return StructureType::Single;
124 return StructureType::Grid;
126 return StructureType::List;
128 return StructureType::Dynamic;
131 return StructureType::Dynamic;
138 for (
const int i :
tree.interface_inputs().index_range()) {
143 for (
const bNode *node :
tree.group_input_nodes()) {
145 is_auto_structure_type[socket.index_in_tree()].set();
150 if (
const bNode *group_output_node =
tree.group_output_node()) {
151 is_auto_structure_type.
slice(group_output_node->input_socket_indices_in_tree().drop_back(1))
157 for (
const bNode *closure_input_node :
tree.nodes_by_type(
"NodeClosureInput")) {
159 tree, *closure_input_node);
160 if (!closure_output_node) {
163 const auto &storage = *
static_cast<const NodeClosureOutput *
>(closure_output_node->storage);
164 for (
const int i :
IndexRange(storage.input_items.items_num)) {
167 const bNodeSocket &socket = closure_input_node->output_socket(
i);
168 is_auto_structure_type[socket.index_in_tree()].set();
171 for (
const int i :
IndexRange(storage.output_items.items_num)) {
174 const bNodeSocket &socket = closure_output_node->input_socket(
i);
175 is_auto_structure_type[socket.index_in_tree()].set();
181 for (
const bNode *evaluate_closure_node :
tree.nodes_by_type(
"NodeEvaluateClosure")) {
183 for (
const int i :
IndexRange(storage.input_items.items_num)) {
186 const bNodeSocket &socket = evaluate_closure_node->input_socket(
i + 1);
187 is_auto_structure_type[socket.index_in_tree()].set();
190 for (
const int i :
IndexRange(storage.output_items.items_num)) {
193 const bNodeSocket &socket = evaluate_closure_node->output_socket(
i);
194 is_auto_structure_type[socket.index_in_tree()].set();
200 for (
const bNode *node :
tree.nodes_by_type(
"NodeCombineBundle")) {
202 for (
const int i :
IndexRange(storage.items_num)) {
206 is_auto_structure_type[socket.index_in_tree()].set();
212 for (
const bNode *node :
tree.nodes_by_type(
"NodeSeparateBundle")) {
214 for (
const int i :
IndexRange(storage.items_num)) {
218 is_auto_structure_type[socket.index_in_tree()].set();
228 for (
const bNode *node :
tree.all_nodes()) {
229 for (
const bNodeSocket *socket : node->input_sockets()) {
230 DataRequirement &requirement = input_requirements[socket->index_in_all_inputs()];
231 if (is_auto_structure_type[socket->index_in_tree()]) {
245 case StructureType::Dynamic: {
249 case StructureType::Single: {
253 case StructureType::Grid: {
257 case StructureType::Field: {
261 case StructureType::List: {
274 if (!output_socket.is_available()) {
277 for (
const bNodeSocket *socket : output_socket.directly_linked_sockets()) {
278 if (!socket->is_available()) {
281 requirement =
merge(requirement, input_requirements[socket->index_in_all_inputs()]);
293 for (
const bNode *node :
tree.group_input_nodes()) {
297 interface_requirements[
i] =
merge(
303 for (
const int i :
tree.interface_inputs().index_range()) {
323 if (socket.is_input()) {
326 const bNode &node = socket.owner_node();
327 if (node.is_group_input()) {
346 const bNode &input_node,
347 const bNode &output_node,
351 for (
const int i : output_node.output_sockets().index_range()) {
353 const bNodeSocket &input_of_input_node = input_node.input_socket(
i);
354 const bNodeSocket &output_of_output_node = output_node.output_socket(
i);
355 const bNodeSocket &input_of_output_node = output_node.input_socket(
i + 1);
357 input_requirements[input_of_input_node.index_in_all_inputs()],
359 if (input_requirements[input_of_input_node.index_in_all_inputs()] != new_value) {
360 input_requirements[input_of_input_node.index_in_all_inputs()] = new_value;
363 if (input_requirements[input_of_output_node.index_in_all_inputs()] != new_value) {
364 input_requirements[input_of_output_node.index_in_all_inputs()] = new_value;
372 const bNode &input_node,
373 const bNode &output_node,
377 for (
const int i : output_node.output_sockets().index_range()) {
378 const bNodeSocket &input_of_input_node = input_node.input_socket(
i + 1);
379 const bNodeSocket &output_of_output_node = output_node.output_socket(
i);
380 const bNodeSocket &input_of_output_node = output_node.input_socket(
i);
382 input_requirements[input_of_input_node.index_in_all_inputs()],
384 if (input_requirements[input_of_input_node.index_in_all_inputs()] != new_value) {
385 input_requirements[input_of_input_node.index_in_all_inputs()] = new_value;
388 if (input_requirements[input_of_output_node.index_in_all_inputs()] != new_value) {
389 input_requirements[input_of_output_node.index_in_all_inputs()] = new_value;
404 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
406 node, *output_node, input_requirements);
414 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeSimulationInput")) {
418 *input_node, node, input_requirements);
428 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
430 node, *output_node, input_requirements);
438 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeRepeatInput")) {
442 *input_node, node, input_requirements);
460 bool need_update =
false;
462 for (
const bNode *node :
tree.toposort_right_to_left()) {
470 for (
const bNodeSocket *socket : output_socket.directly_linked_sockets()) {
471 if (!socket->is_available()) {
474 output_requirement =
merge(output_requirement,
475 input_requirements[socket->index_in_all_inputs()]);
478 switch (output_requirement) {
501 if (input_requirements[input_socket.index_in_all_inputs()] ==
507 if (input_socket.is_directly_linked()) {
508 inputs_with_links.
append(input_socket.index_in_all_inputs());
511 if (inputs_with_links.
size() == 1) {
512 input_requirements[inputs_with_links.
first()] = output_requirement;
515 for (
const int input : inputs_with_links) {
541 if (a == StructureType::Dynamic ||
b == StructureType::Dynamic) {
542 return StructureType::Dynamic;
544 if ((a == StructureType::Field &&
b == StructureType::Grid) ||
545 (a == StructureType::Grid &&
b == StructureType::Field))
547 return StructureType::Grid;
549 if ((a == StructureType::Single &&
b == StructureType::Field) ||
550 (a == StructureType::Field &&
b == StructureType::Single))
552 return StructureType::Field;
554 if ((a == StructureType::Single &&
b == StructureType::Grid) ||
555 (a == StructureType::Grid &&
b == StructureType::Single))
557 return StructureType::Grid;
559 if ((a == StructureType::Single &&
b == StructureType::List) ||
560 (a == StructureType::List &&
b == StructureType::Single))
562 return StructureType::List;
564 if ((a == StructureType::Field &&
b == StructureType::List) ||
565 (a == StructureType::List &&
b == StructureType::Field))
567 return StructureType::List;
574 const bNode &output_node,
578 for (
const int i : output_node.output_sockets().index_range()) {
583 structure_types[
output.index_in_tree()]);
584 if (structure_types[
input.index_in_tree()] != new_value) {
585 structure_types[
input.index_in_tree()] = new_value;
588 if (structure_types[
output.index_in_tree()] != new_value) {
589 structure_types[
output.index_in_tree()] = new_value;
597 const bNode &output_node,
601 for (
const int i : output_node.output_sockets().index_range()) {
602 const bNodeSocket &input_of_input_node = input_node.output_socket(
i + 1);
603 const bNodeSocket &output_of_output_node = output_node.output_socket(
i);
605 structure_types[input_of_input_node.index_in_tree()],
606 structure_types[output_of_output_node.index_in_tree()]);
607 if (structure_types[input_of_input_node.index_in_tree()] != new_value) {
608 structure_types[input_of_input_node.index_in_tree()] = new_value;
611 if (structure_types[output_of_output_node.index_in_tree()] != new_value) {
612 structure_types[output_of_output_node.index_in_tree()] = new_value;
627 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
629 node, *output_node, structure_types);
637 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeSimulationInput")) {
641 *input_node, node, structure_types);
651 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
653 node, *output_node, structure_types);
661 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeRepeatInput")) {
665 *input_node, node, structure_types);
682 return StructureType::Field;
684 return StructureType::Single;
694 if (
input->owner_node().is_undefined()) {
697 if (!
input->is_directly_linked()) {
706 for (
const StringRefNull idname : {
"GeometryNodeRepeatInput",
707 "GeometryNodeRepeatOutput",
708 "GeometryNodeSimulationInput",
709 "GeometryNodeSimulationOutput"})
711 for (
const bNode *node :
tree.nodes_by_type(idname)) {
712 for (
const bNodeSocket *socket : node->output_sockets()) {
713 structure_types[socket->index_in_tree()] = StructureType::Single;
719 bool need_update =
false;
720 for (
const bNode *node :
tree.toposort_left_to_right()) {
721 if (node->is_undefined()) {
726 if (node->is_group_input()) {
728 structure_types[output_sockets[
i]->index_in_tree()] = group_input_structure_types[
i];
734 if (!
input->is_available()) {
738 std::optional<StructureType> input_type;
740 if (!link->is_used()) {
743 const StructureType new_type = structure_types[link->fromsock->index_in_tree()];
748 input_type = new_type;
752 structure_types[
input->index_in_tree()] = *input_type;
758 for (
const int output_index :
node_interface.outputs.index_range()) {
760 if (!
output.is_available() || !
output.runtime->declaration) {
763 if (is_auto_structure_type[
output.index_in_tree()]) {
769 std::optional<StructureType> output_type;
770 for (
const int input_index :
node_interface.outputs[output_index].linked_inputs) {
772 if (!
input.is_available()) {
775 const StructureType new_type = structure_types[
input.index_in_tree()];
780 output_type = new_type;
804 handled_sockets.
add(&group_output);
805 sockets_to_check.
push(&group_output);
809 while (!sockets_to_check.
is_empty()) {
811 if (!input_socket->is_directly_linked()) {
815 for (
const bNodeSocket *origin_socket : input_socket->directly_linked_sockets()) {
816 const bNode &origin_node = origin_socket->owner_node();
817 if (origin_node.is_group_input()) {
823 for (
const int input_index :
node_interface.outputs[origin_socket->index()].linked_inputs) {
825 if (!
input.is_available()) {
844 const bNode *group_output_node =
tree.group_output_node();
845 if (!group_output_node) {
847 output.type = StructureType::Dynamic;
856 interface.outputs[
i] = {StructureType(interface_outputs[
i]->structure_type), {}};
860 interface.outputs[
i].type = structure_types[sockets[
i]->index_in_tree()];
861 if (
interface.outputs[
i].type == StructureType::Dynamic) {
876 tree.ensure_topology_cache();
877 tree.ensure_interface_cache();
881 StructureType::Dynamic);
883 result.group_interface.inputs.reinitialize(
tree.interface_inputs().size());
884 result.group_interface.outputs.reinitialize(
tree.interface_outputs().size());
885 if (
tree.has_available_link_cycle()) {
886 result.group_interface.inputs.fill(StructureType::Dynamic);
887 result.group_interface.outputs.fill({StructureType::Dynamic, {}});
901 tree, data_requirements, is_auto_structure_type,
result.socket_structure_types);
904 result.group_interface.inputs,
905 is_auto_structure_type,
906 result.socket_structure_types);
908 tree, node_interfaces,
result.socket_structure_types,
result.group_interface);
911 for (
const int i :
tree.all_sockets().index_range()) {
914 result.socket_structure_types[
i] = StructureType::Single;
924 for (
const int i :
tree.all_sockets().index_range()) {
926 socket.
runtime->inferred_structure_type =
result.socket_structure_types[
i];
928 if (
tree.runtime->structure_type_interface &&
929 *
tree.runtime->structure_type_interface ==
result.group_interface)
933 tree.runtime->structure_type_interface = std::make_unique<nodes::StructureTypeInterface>(
934 std::move(
result.group_interface));
#define GEO_NODE_SIMULATION_OUTPUT
#define NODE_CLOSURE_OUTPUT
#define GEO_NODE_REPEAT_OUTPUT
#define GEO_NODE_REPEAT_INPUT
#define GEO_NODE_SIMULATION_INPUT
#define BLI_assert_unreachable()
#define ENUM_OPERATORS(_type, _max)
@ NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO
BMesh const char void * data
MutableSpan< T > as_mutable_span()
void reinitialize(const int64_t new_size)
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void push(const T &value)
void append(const T &value)
void append_non_duplicates(const T &value)
Span< T > as_span() const
MutableBitSpan slice(const IndexRange range) const
const bNode * get_corresponding_output(const bNodeTree &tree, const bNode &input_bnode) const
Span< int > linked_input_indices() const
OutputSocketFieldType field_type() const
StructureType structure_type
OutputFieldDependency output_field_dependency
InputSocketFieldType input_field_type
void fill_index_range(MutableSpan< T > span, const T start=0)
void foreach_1_index(const BitSpanT &data, Fn &&fn)
static void store_group_input_structure_types(const bNodeTree &tree, const Span< DataRequirement > input_requirements, nodes::StructureTypeInterface &derived_interface)
static void store_auto_output_structure_types(const bNodeTree &tree, const Span< DataRequirement > input_requirements, const bits::BoundedBitSpan is_auto_structure_type, MutableSpan< StructureType > structure_types)
static void init_input_requirements(const bNodeTree &tree, const bits::BoundedBitSpan is_auto_structure_type, MutableSpan< DataRequirement > input_requirements)
static void propagate_right_to_left(const bNodeTree &tree, const Span< nodes::StructureTypeInterface > node_interfaces, MutableSpan< DataRequirement > input_requirements)
static DataRequirement merge(const DataRequirement a, const DataRequirement b)
static StructureType data_requirement_to_auto_structure_type(const DataRequirement requirement)
static StructureType left_to_right_merge(const StructureType a, const StructureType b)
static ZoneInOutChange simulation_zone_requirements_propagate(const bNode &input_node, const bNode &output_node, MutableSpan< DataRequirement > input_requirements)
static bool propagate_zone_status(const bNodeTree &tree, const bNode &node, MutableSpan< StructureType > structure_types)
static ZoneInOutChange simulation_zone_status_propagate(const bNode &input_node, const bNode &output_node, MutableSpan< StructureType > structure_types)
static StructureTypeInferenceResult calc_structure_type_interface(const bNodeTree &tree)
static ZoneInOutChange repeat_zone_requirements_propagate(const bNode &input_node, const bNode &output_node, MutableSpan< DataRequirement > input_requirements)
bool update_structure_type_interface(bNodeTree &tree)
static DataRequirement calc_output_socket_requirement(const bNodeSocket &output_socket, const Span< DataRequirement > input_requirements)
static Vector< int > find_dynamic_output_linked_inputs(const bNodeSocket &group_output, const Span< nodes::StructureTypeInterface > interface_by_node)
static nodes::StructureTypeInterface calc_node_interface(const bNode &node)
static void propagate_left_to_right(const bNodeTree &tree, const Span< nodes::StructureTypeInterface > node_interfaces, const Span< StructureType > group_input_structure_types, const bits::BoundedBitSpan is_auto_structure_type, MutableSpan< StructureType > structure_types)
static bool propagate_zone_data_requirements(const bNodeTree &tree, const bNode &node, MutableSpan< DataRequirement > input_requirements)
static ZoneInOutChange repeat_zone_status_propagate(const bNode &input_node, const bNode &output_node, MutableSpan< StructureType > structure_types)
static StructureType get_unconnected_input_structure_type(const nodes::SocketDeclaration &declaration)
static void store_group_output_structure_types(const bNodeTree &tree, const Span< nodes::StructureTypeInterface > interface_by_node, const Span< StructureType > structure_types, nodes::StructureTypeInterface &interface)
static Array< nodes::StructureTypeInterface > calc_node_interfaces(const bNodeTree &tree)
static void find_auto_structure_type_sockets(const bNodeTree &tree, bits::MutableBoundedBitSpan is_auto_structure_type)
const bNodeZoneType * zone_type_by_node_type(const int node_type)
bool socket_type_always_single(const eNodeSocketDatatype socket_type)
bNodeSocketRuntimeHandle * runtime
nodes::StructureTypeInterface group_interface
Array< StructureType > socket_structure_types
Array< int > linked_inputs
Array< StructureType > inputs