20using nodes::StructureType;
21namespace aal = nodes::anonymous_attribute_lifetime;
32 if (node.is_undefined() || !node.declaration() || node.declaration()->skip_updating_sockets) {
38 if (node.is_reroute()) {
53 if (dependency.
type != StructureType::Dynamic) {
82 for (
const int i :
nodes.index_range()) {
122 case StructureType::Dynamic: {
126 case StructureType::Single: {
130 case StructureType::Grid: {
134 case StructureType::Field: {
146 if (!output_socket.is_available()) {
149 for (
const bNodeSocket *socket : output_socket.directly_linked_sockets()) {
150 if (!socket->is_available()) {
153 requirement =
merge(requirement, input_requirements[socket->index_in_all_inputs()]);
165 for (
const bNode *node :
tree.group_input_nodes()) {
169 interface_requirements[
i] =
merge(
175 for (
const int i :
tree.interface_inputs().index_range()) {
183 switch (requirement) {
185 derived_interface.
inputs[
i] = StructureType::Dynamic;
188 derived_interface.
inputs[
i] = StructureType::Field;
191 derived_interface.
inputs[
i] = StructureType::Single;
194 derived_interface.
inputs[
i] = StructureType::Grid;
197 derived_interface.
inputs[
i] = StructureType::Dynamic;
211 const bNode &input_node,
212 const bNode &output_node,
216 for (
const int i : output_node.output_sockets().index_range()) {
218 const bNodeSocket &socket_input = input_node.input_socket(
i);
219 const bNodeSocket &socket_output = output_node.output_socket(
i);
221 input_requirements[socket_input.index_in_all_inputs()],
223 if (input_requirements[socket_input.index_in_all_inputs()] != new_value) {
224 input_requirements[socket_input.index_in_all_inputs()] = new_value;
227 if (input_requirements[socket_input.index_in_all_inputs()] != new_value) {
228 input_requirements[socket_input.index_in_all_inputs()] = new_value;
236 const bNode &input_node,
237 const bNode &output_node,
241 for (
const int i : output_node.output_sockets().index_range()) {
242 const bNodeSocket &socket_input = input_node.input_socket(
i + 1);
243 const bNodeSocket &socket_output = output_node.output_socket(
i);
245 input_requirements[socket_input.index_in_all_inputs()],
247 if (input_requirements[socket_input.index_in_all_inputs()] != new_value) {
248 input_requirements[socket_input.index_in_all_inputs()] = new_value;
251 if (input_requirements[socket_input.index_in_all_inputs()] != new_value) {
252 input_requirements[socket_input.index_in_all_inputs()] = new_value;
267 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
269 node, *output_node, input_requirements);
277 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeSimulationInput")) {
281 *input_node, node, input_requirements);
291 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
293 node, *output_node, input_requirements);
301 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeRepeatInput")) {
305 *input_node, node, input_requirements);
323 bool need_update =
false;
325 for (
const bNode *node :
tree.toposort_right_to_left()) {
333 for (
const bNodeSocket *socket : output_socket.directly_linked_sockets()) {
334 if (!socket->is_available()) {
337 output_requirement =
merge(output_requirement,
338 input_requirements[socket->index_in_all_inputs()]);
348 if (input_socket.is_directly_linked()) {
349 inputs_with_links.
append(input_socket.index_in_all_inputs());
352 if (inputs_with_links.
size() == 1) {
353 input_requirements[inputs_with_links.
first()] = output_requirement;
356 for (
const int input : inputs_with_links) {
379 if ((a == StructureType::Dynamic &&
b == StructureType::Single) ||
380 (a == StructureType::Single &&
b == StructureType::Dynamic))
382 return StructureType::Dynamic;
384 if ((a == StructureType::Dynamic &&
b == StructureType::Field) ||
385 (a == StructureType::Field &&
b == StructureType::Dynamic))
387 return StructureType::Field;
389 if ((a == StructureType::Dynamic &&
b == StructureType::Grid) ||
390 (a == StructureType::Grid &&
b == StructureType::Dynamic))
392 return StructureType::Grid;
394 if ((a == StructureType::Field &&
b == StructureType::Grid) ||
395 (a == StructureType::Grid &&
b == StructureType::Field))
397 return StructureType::Grid;
399 if ((a == StructureType::Single &&
b == StructureType::Field) ||
400 (a == StructureType::Field &&
b == StructureType::Single))
402 return StructureType::Field;
404 if ((a == StructureType::Single &&
b == StructureType::Grid) ||
405 (a == StructureType::Grid &&
b == StructureType::Single))
407 return StructureType::Grid;
414 const bNode &output_node,
418 for (
const int i : output_node.output_sockets().index_range()) {
423 structure_types[
output.index_in_tree()]);
424 if (structure_types[
input.index_in_tree()] != new_value) {
425 structure_types[
input.index_in_tree()] = new_value;
428 if (structure_types[
output.index_in_tree()] != new_value) {
429 structure_types[
output.index_in_tree()] = new_value;
437 const bNode &output_node,
441 for (
const int i : output_node.output_sockets().index_range()) {
445 structure_types[
output.index_in_tree()]);
446 if (structure_types[
input.index_in_tree()] != new_value) {
447 structure_types[
input.index_in_tree()] = new_value;
450 if (structure_types[
output.index_in_tree()] != new_value) {
451 structure_types[
output.index_in_tree()] = new_value;
466 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
468 node, *output_node, structure_types);
476 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeSimulationInput")) {
480 *input_node, node, structure_types);
490 if (
const bNode *output_node =
tree.node_by_id(
data.output_node_id)) {
492 node, *output_node, structure_types);
500 for (
const bNode *input_node :
tree.nodes_by_type(
"GeometryNodeRepeatInput")) {
504 *input_node, node, structure_types);
521 return StructureType::Field;
523 return StructureType::Single;
532 if (
input->owner_node().is_undefined()) {
535 if (!
input->is_directly_linked()) {
543 bool need_update =
false;
544 for (
const bNode *node :
tree.toposort_left_to_right()) {
545 if (node->is_undefined()) {
550 if (node->is_group_input()) {
552 structure_types[output_sockets[
i]->index_in_tree()] = group_input_structure_types[
i];
558 if (!
input->is_available()) {
562 std::optional<StructureType> input_type;
564 if (!link->is_used()) {
567 const StructureType new_type = structure_types[link->fromsock->index_in_tree()];
572 input_type = new_type;
576 structure_types[
input->index_in_tree()] = *input_type;
582 for (
const int output_index :
node_interface.outputs.index_range()) {
584 if (!
output.is_available() || !
output.runtime->declaration) {
589 std::optional<StructureType> output_type;
590 for (
const int input_index :
node_interface.outputs[output_index].linked_inputs) {
592 if (!
input.is_available()) {
595 const StructureType new_type = structure_types[
input.index_in_tree()];
600 output_type = new_type;
624 handled_sockets.
add(&group_output);
625 sockets_to_check.
push(&group_output);
629 while (!sockets_to_check.
is_empty()) {
631 if (!input_socket->is_directly_linked()) {
635 for (
const bNodeSocket *origin_socket : input_socket->directly_linked_sockets()) {
636 const bNode &origin_node = origin_socket->owner_node();
637 if (origin_node.is_group_input()) {
643 for (
const int input_index :
node_interface.outputs[origin_socket->index()].linked_inputs) {
645 if (!
input.is_available()) {
664 const bNode *group_output_node =
tree.group_output_node();
665 if (!group_output_node) {
667 output.type = StructureType::Dynamic;
676 interface.outputs[
i] = {StructureType(interface_outputs[
i]->structure_type), {}};
680 interface.outputs[
i].type = structure_types[sockets[
i]->index_in_tree()];
681 if (
interface.outputs[
i].type == StructureType::Dynamic) {
692 tree.ensure_topology_cache();
693 tree.ensure_interface_cache();
695 auto derived_interface = std::make_unique<nodes::StructureTypeInterface>();
696 derived_interface->inputs.reinitialize(
tree.interface_inputs().size());
697 derived_interface->outputs.reinitialize(
tree.interface_outputs().size());
698 if (
tree.has_available_link_cycle()) {
699 derived_interface->inputs.fill(StructureType::Dynamic);
700 derived_interface->outputs.fill({StructureType::Dynamic, {}});
701 return derived_interface;
715 return derived_interface;
722 if (
tree.runtime->structure_type_interface &&
723 *
tree.runtime->structure_type_interface == *new_interface)
727 tree.runtime->structure_type_interface = std::move(new_interface);
#define GEO_NODE_SIMULATION_OUTPUT
#define GEO_NODE_REPEAT_OUTPUT
#define GEO_NODE_REPEAT_INPUT
#define GEO_NODE_SIMULATION_INPUT
#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
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)
static void store_group_input_structure_types(const bNodeTree &tree, const Span< DataRequirement > input_requirements, nodes::StructureTypeInterface &derived_interface)
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 void propagate_left_to_right(const bNodeTree &tree, const Span< nodes::StructureTypeInterface > node_interfaces, const Span< StructureType > group_input_structure_types, MutableSpan< StructureType > structure_types)
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 ZoneInOutChange repeat_zone_requirements_propagate(const bNode &input_node, const bNode &output_node, MutableSpan< DataRequirement > input_requirements)
static void init_input_requirements(const bNodeTree &tree, 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 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 std::unique_ptr< nodes::StructureTypeInterface > calc_structure_type_interface(const bNodeTree &tree)
bNodeSocketRuntimeHandle * runtime
Array< int > linked_inputs
Array< StructureType > inputs