27using bke::AttributeAccessor;
28using bke::GeometryComponent;
29using bke::GeometrySet;
30using bke::MutableAttributeAccessor;
31using bke::SocketValueVariant;
67 if (this->
id.component_type == GeometryComponent::Type::GreasePencil &&
68 ELEM(this->
id.domain, AttrDomain::Point, AttrDomain::Curve))
70 this->field_context.emplace(
74 this->field_context.emplace(*
geometry.get_component(
this->id.component_type),
81 return *this->field_context->attributes();
86 if (this->
id.component_type == GeometryComponent::Type::GreasePencil &&
87 ELEM(this->
id.domain, AttrDomain::Point, AttrDomain::Curve))
121 int first_valid_item_i)
const;
160 user_data, body_compute_context.
hash());
163 lf::Context body_context{context.storage, &body_user_data, &body_local_user_data};
186 const Span<int> iterations_with_side_effects =
191 for (
const int i : iterations_with_side_effects) {
236 const bNode &output_bnode_;
266 output_bnode_(*zone.output_node()),
267 zone_info_(zone_info),
279 output_bnode_.storage);
281 BLI_assert(zone_.input_node()->output_socket(1).is_available() ==
282 (iteration_domain != AttrDomain::Corner));
284 const int input_items_num = node_storage.input_items.items_num;
285 const int main_items_num = node_storage.main_items.items_num;
286 const int generation_items_num = node_storage.generation_items.items_num;
290 iteration_domain == AttrDomain::Corner ? 1 : 2, input_items_num);
291 indices_.inputs.bsocket_outer = indices_.inputs.lf_outer;
292 indices_.inputs.bsocket_inner = indices_.inputs.lf_inner;
296 indices_.main.bsocket_outer = indices_.main.lf_outer;
297 indices_.main.bsocket_inner = indices_.main.lf_inner;
300 generation_items_num);
302 generation_items_num);
304 generation_items_num);
306 generation_items_num);
317 if (s->graph_executor_storage) {
318 s->graph_executor->destruct_storage(s->graph_executor_storage);
331 output_bnode_.storage);
335 if (!eval_storage.graph_executor) {
340 if (eval_storage.total_iterations_num == 0) {
341 if (!eval_storage.main_geometry.is_empty()) {
344 {zone_.input_node()->identifier,
345 {NodeWarningType::Info,
346 N_(
"Input geometry has no elements in the iteration domain.")}});
353 eval_storage.graph_executor_storage, context.user_data, context.local_user_data};
355 eval_storage.graph_executor->execute(
params, eval_graph_context);
364 zone_info_.indices.inputs.main[0]);
375 for (
const int i :
inputs_.index_range()) {
379 for (
const int i :
outputs_.index_range()) {
407 if (btree_orig.
runtime->logged_zone_graphs) {
408 std::lock_guard
lock{btree_orig.
runtime->logged_zone_graphs->mutex};
409 btree_orig.
runtime->logged_zone_graphs->graph_by_zone_id.lookup_or_add_cb(
410 output_bnode_.identifier, [&]() { return lf_graph.to_dot(); });
423 const bNodeSocket &element_geometry_bsocket = zone_.input_node()->output_socket(1);
424 const bool create_element_geometries = element_geometry_bsocket.is_available() &&
425 element_geometry_bsocket.is_directly_linked();
431 if (src_component->type() == GeometryComponent::Type::GreasePencil &&
432 ELEM(iteration_domain, AttrDomain::Point, AttrDomain::Curve))
435 for (
const int layer_i : grease_pencil.layers().index_range()) {
437 grease_pencil.layer(layer_i));
438 if (drawing ==
nullptr) {
445 component_ids.
append({component_type, iteration_domain, layer_i});
449 const int domain_size = src_component->attribute_domain_size(iteration_domain);
450 if (domain_size > 0) {
451 component_ids.
append({component_type, iteration_domain});
458 zone_info_.indices.inputs.main[1])
462 int body_nodes_offset = 0;
464 for (
const int component_i : component_ids.
index_range()) {
467 component_info.
id = id;
480 zone_info_.indices.inputs.main[indices_.inputs.lf_outer[item_i]])
492 body_nodes_offset +=
mask.size();
499 if (create_element_geometries) {
528 switch (
id.component_type) {
529 case GeometryComponent::Type::Mesh: {
533 case AttrDomain::Point: {
537 case AttrDomain::Edge: {
541 case AttrDomain::Face: {
551 element_geometries[
i].replace_mesh(meshes[
i]);
553 return element_geometries;
555 case GeometryComponent::Type::PointCloud: {
556 if (
id.domain != AttrDomain::Point) {
561 main_pointcloud,
mask, attribute_filter);
564 element_geometries[
i].replace_pointcloud(pointclouds[
i]);
566 return element_geometries;
568 case GeometryComponent::Type::Curve: {
572 case AttrDomain::Point: {
576 case AttrDomain::Curve: {
585 element_geometries[
i].replace_curves(element_curves[
i]);
587 return element_geometries;
589 case GeometryComponent::Type::Instance: {
590 if (
id.domain != AttrDomain::Instance) {
595 main_instances,
mask, attribute_filter);
598 element_geometries[
i].replace_instances(element_instances[
i]);
600 return element_geometries;
602 case GeometryComponent::Type::GreasePencil: {
606 case AttrDomain::Layer: {
608 main_grease_pencil,
mask, attribute_filter);
611 case AttrDomain::Point: {
613 main_grease_pencil, *
id.layer_index,
mask, attribute_filter);
616 case AttrDomain::Curve: {
618 main_grease_pencil, *
id.layer_index,
mask, attribute_filter);
626 element_geometries[
i].replace_grease_pencil(element_grease_pencils[
i]);
628 return element_geometries;
647 lf_body_nodes.
add_new(&lf_node);
651 for (
const int zone_output_i : body_fn_.indices.inputs.output_usages.index_range()) {
654 *graph_inputs[zone_info_.indices.inputs.output_usages[1 + zone_output_i]];
658 lf_node.
input(body_fn_.indices.inputs.output_usages[zone_output_i]));
662 const bNodeSocket &element_geometry_bsocket = zone_.input_node()->output_socket(1);
670 lf_body_node.
input(body_fn_.indices.inputs.main[0])
673 if (element_geometry_bsocket.is_available()) {
681 lf_body_node.
input(body_fn_.indices.inputs.main[indices_.inputs.lf_inner[item_i]])
685 for (
const int border_link_i : zone_info_.indices.inputs.border_links.index_range()) {
687 *graph_inputs[zone_info_.indices.inputs.border_links[border_link_i]],
688 lf_body_node.
input(body_fn_.indices.inputs.border_links[border_link_i]));
691 for (
const auto &item : body_fn_.indices.inputs.reference_sets.items()) {
693 *graph_inputs[zone_info_.indices.inputs.reference_sets.lookup(item.key)],
694 lf_body_node.
input(item.value));
706 BLI_assert(body_main_outputs_num == body_fn_.indices.outputs.main.size());
710 lf_graph.
add_link(lf_body_node.
output(body_fn_.indices.outputs.main[item_i]),
711 lf_reduce.
input(
i * body_main_outputs_num + item_i));
715 lf_graph.
add_link(lf_body_node.
output(body_fn_.indices.outputs.main[body_output_i]),
716 lf_reduce.
input(
i * body_main_outputs_num + body_output_i));
721 lf_graph.
add_link(lf_reduce.
output(0), *graph_outputs[zone_info_.indices.outputs.main[0]]);
723 const int output_i = indices_.main.lf_outer[item_i];
725 *graph_outputs[zone_info_.indices.outputs.main[output_i]]);
728 const int output_i = indices_.generation.lf_outer[item_i];
730 *graph_outputs[zone_info_.indices.outputs.main[output_i]]);
734 static bool static_true{
true};
735 for (
const int i : zone_info_.indices.outputs.input_usages) {
736 graph_outputs[
i]->set_default_value(&static_true);
742 for (
const int border_link_i : zone_.border_links.index_range()) {
747 lf_body_node.
output(body_fn_.indices.outputs.border_link_usages[border_link_i]),
752 *graph_outputs[zone_info_.indices.outputs.border_link_usages[border_link_i]]);
778 (node_storage.main_items.items_num + node_storage.generation_items.items_num));
782 for (const int item_i : IndexRange(node_storage.main_items.items_num)) {
783 const NodeForeachGeometryElementMainItem &item = node_storage.main_items.items[item_i];
784 const bNodeSocket &socket = parent.output_bnode_.input_socket(
785 parent_.indices_.main.bsocket_inner[item_i]);
787 item.name, *socket.typeinfo->geometry_nodes_cpp_type, lf::ValueUsage::Used);
790 for (
const int item_i :
IndexRange(node_storage.generation_items.items_num)) {
791 const NodeForeachGeometryElementGenerationItem &item =
792 node_storage.generation_items.items[item_i];
793 const bNodeSocket &socket = parent.output_bnode_.input_socket(
794 parent_.indices_.generation.bsocket_inner[item_i]);
796 item.name, *socket.typeinfo->geometry_nodes_cpp_type, lf::ValueUsage::Maybe);
803 for (
const int item_i :
IndexRange(node_storage.main_items.items_num)) {
804 const NodeForeachGeometryElementMainItem &item = node_storage.main_items.items[item_i];
805 const bNodeSocket &socket = parent.output_bnode_.output_socket(
806 parent_.indices_.main.bsocket_outer[item_i]);
807 outputs_.append_as(item.name, *socket.typeinfo->geometry_nodes_cpp_type);
810 for (
const int item_i :
IndexRange(node_storage.generation_items.items_num)) {
811 const NodeForeachGeometryElementGenerationItem &item =
812 node_storage.generation_items.items[item_i];
813 const bNodeSocket &socket = parent.output_bnode_.output_socket(
814 parent_.indices_.generation.bsocket_outer[item_i]);
815 outputs_.append_as(item.name, *socket.typeinfo->geometry_nodes_cpp_type);
823 switch (component_type) {
824 case GeometryComponent::Type::Mesh:
825 case GeometryComponent::Type::PointCloud:
826 return AttrDomain::Point;
827 case GeometryComponent::Type::Curve:
828 return AttrDomain::Curve;
829 case GeometryComponent::Type::Instance:
830 return AttrDomain::Instance;
831 case GeometryComponent::Type::GreasePencil:
832 return AttrDomain::Layer;
843 parent_.output_bnode_.storage);
846 if (node_storage.generation_items.items_num == 0) {
857 parent_.output_bnode_.storage);
859 node_storage.generation_items.items_num;
861 const int main_geometry_output = 0;
862 if (
params.output_was_set(main_geometry_output)) {
869 for (
const int item_i :
IndexRange(node_storage.main_items.items_num)) {
873 if (!base_cpp_type) {
880 user_data.call_data->self_object()->id.name,
881 user_data.compute_context->hash(),
882 parent_.output_bnode_.identifier,
893 attribute_name, component_info.
id.
domain, cd_type);
902 mask.foreach_index([&](
const int i,
const int pos) {
903 const int lf_param_index =
pos * body_main_outputs_num + item_i;
905 value_variant.convert_to_single();
914 auto attribute_field = std::make_shared<bke::AttributeFieldInput>(
918 parent_.output_bnode_.output_socket(
parent_.indices_.main.bsocket_outer[item_i])));
920 params.set_output(1 + item_i, std::move(attribute_value_variant));
924 params.set_output(main_geometry_output, std::move(output_geometry));
931 parent_.output_bnode_.storage);
934 if (first_valid_item_i == node_storage.generation_items.items_num) {
944 parent_.output_bnode_.storage);
948 for (; item_i < node_storage.generation_items.items_num; item_i++) {
950 node_storage.generation_items.items[item_i];
955 const int lf_socket_i =
parent_.indices_.generation.lf_outer[item_i];
956 if (!
params.output_was_set(lf_socket_i)) {
957 const int bsocket_i =
parent_.indices_.generation.bsocket_outer[item_i];
959 params, lf_socket_i,
parent_.zone_.output_node()->output_socket(bsocket_i));
969 parent_.output_bnode_.storage);
970 int previous_geometry_item_i = first_valid_item_i;
973 for (
const int item_i :
977 node_storage.generation_items.items[item_i];
983 previous_geometry_item_i,
985 previous_geometry_item_i = item_i;
991 previous_geometry_item_i,
993 node_storage.generation_items.items_num));
999 const int geometry_item_i,
1000 const IndexRange generation_items_range)
const
1004 parent_.output_bnode_.storage);
1006 node_storage.generation_items.items_num;
1010 params, context, geometry_item_i, generation_items_range))
1023 for (
const int i : generation_items_range.
index_range()) {
1024 const int item_i = generation_items_range[
i];
1026 node_storage.generation_items.items[item_i];
1028 user_data.call_data->self_object()->id.name,
1029 user_data.compute_context->hash(),
1030 parent_.output_bnode_.identifier,
1038 struct NameWithType {
1057 mask.foreach_index([&](
const int element_i,
const int local_body_i) {
1059 const int geometry_param_i = body_i * body_main_outputs_num +
1060 parent_.indices_.generation.lf_inner[geometry_item_i];
1065 {GeometryComponent::Type::Mesh,
1066 GeometryComponent::Type::PointCloud,
1067 GeometryComponent::Type::Curve,
1068 GeometryComponent::Type::GreasePencil,
1069 GeometryComponent::Type::Instance})
1071 if (!
geometry.has(dst_component_type)) {
1079 const std::optional<AttrDomain> propagation_domain =
1081 if (!propagation_domain) {
1086 for (
const NameWithType &name_with_type : attributes_to_propagate) {
1103 if (!src_attribute) {
1121 for (
const int local_item_i : generation_items_range.
index_range()) {
1122 const int item_i = generation_items_range[local_item_i];
1124 node_storage.generation_items.items[item_i];
1126 const int field_param_i = body_i * body_main_outputs_num +
1127 parent_.indices_.generation.lf_inner[item_i];
1130 if (capture_domain == AttrDomain::Instance) {
1133 geometry.get_component_for_write(GeometryComponent::Type::Instance),
1134 attribute_names[local_item_i],
1142 {GeometryComponent::Type::Mesh,
1143 GeometryComponent::Type::PointCloud,
1144 GeometryComponent::Type::Curve,
1145 GeometryComponent::Type::GreasePencil})
1147 if (sub_geometry.
has(component_type)) {
1150 attribute_names[local_item_i],
1164 edit_data_geometry.
keep_only({GeometryComponent::Type::Edit});
1170 params.set_output(
parent_.indices_.generation.lf_outer[geometry_item_i],
1171 std::move(joined_geometry));
1174 for (
const int local_item_i : generation_items_range.
index_range()) {
1175 const int item_i = generation_items_range[local_item_i];
1177 node_storage.generation_items.items[item_i];
1180 const StringRef attribute_name = attribute_names[local_item_i];
1181 auto attribute_field = std::make_shared<bke::AttributeFieldInput>(
1185 parent_.output_bnode_.output_socket(2 + node_storage.main_items.items_num + item_i)));
1187 params.set_output(
parent_.indices_.generation.lf_outer[item_i],
1188 std::move(attribute_value_variant));
1195 const int geometry_item_i,
1196 const IndexRange generation_items_range)
const
1199 parent_.output_bnode_.storage);
1201 node_storage.generation_items.items_num;
1203 const int geometry_output_param =
parent_.indices_.generation.lf_outer[geometry_item_i];
1205 if (
params.output_was_set(geometry_output_param)) {
1212 const int start_bsocket_i =
parent_.indices_.generation.bsocket_outer[geometry_item_i];
1219 bool any_output_used =
false;
1223 any_output_used =
true;
1227 if (!any_output_used) {
1234 bool has_missing_input =
false;
1235 for (
const int body_i :
IndexRange(bodies_num)) {
1236 const int offset = body_i * body_main_outputs_num +
1237 parent_.indices_.generation.lf_inner[geometry_item_i];
1239 const bool is_available =
params.try_get_input_data_ptr_or_request(offset +
i) !=
nullptr;
1240 if (!is_available) {
1241 has_missing_input =
true;
1245 if (has_missing_input) {
1259 btree, zone, zone_info, body_fn);
Low-level operations for curves.
Low-level operations for grease pencil.
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
T * DEG_get_original(T *id)
__forceinline float extract(const int4 &b)
for(;discarded_id_iter !=nullptr;discarded_id_iter=static_cast< ID * >(discarded_id_iter->next))
const T & last(const int64_t n=0) const
IndexRange index_range() const
static const CPPType & get()
void value_initialize_indices(void *ptr, const IndexMask &mask) const
void fill_assign_n(const void *value, void *dst, int64_t n) const
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
const ComputeContextHash & hash() const
const CPPType & type() const
void get_to_uninitialized(int64_t index, void *r_value) const
constexpr int64_t size() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
static constexpr IndexRange from_begin_size(const int64_t begin, const int64_t size)
constexpr IndexRange index_range() const
destruct_ptr< T > construct(Args &&...args)
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
T & construct(Args &&...args)
IndexRange index_range() const
void add_new(const Key &key)
void append(const T &value)
IndexRange index_range() const
Span< T > as_span() const
bool is_builtin(const StringRef attribute_id) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
bool contains(StringRef attribute_id) const
GVArray adapt_domain(const GVArray &varray, const AttrDomain from_domain, const AttrDomain to_domain) const
GAttributeReader lookup(const StringRef attribute_id) const
int domain_size(const AttrDomain domain) const
eCustomDataType data_type
MutableAttributeAccessor attributes_for_write()
virtual std::optional< MutableAttributeAccessor > attributes_for_write()
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
const void * get_single_ptr_raw() const
void * allocate_single(eNodeSocketDatatype socket_type)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
const LazyFunction & function() const
void update_node_indices()
FunctionNode & add_function(const LazyFunction &fn)
void add_link(OutputSocket &from, InputSocket &to)
GraphOutputSocket & add_output(const CPPType &type, std::string name="")
GraphInputSocket & add_input(const CPPType &type, std::string name="")
Vector< Output > outputs_
virtual std::string name() const
const InputSocket & input(int index) const
const OutputSocket & output(int index) const
const bNode * output_bnode_
VectorSet< lf::FunctionNode * > * lf_body_nodes_
void execute_node(const lf::FunctionNode &node, lf::Params ¶ms, const lf::Context &context) const override
Vector< const lf::FunctionNode * > get_nodes_with_side_effects(const lf::Context &context) const override
const bNode * output_bnode_
Span< lf::FunctionNode * > lf_body_nodes_
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
std::optional< Array< GeometrySet > > try_extract_element_geometries(const GeometrySet &main_geometry, const ForeachElementComponentID &id, const IndexMask &mask, const bke::AttributeFilter &attribute_filter) const
void initialize_execution_graph(lf::Params ¶ms, ForeachGeometryElementEvalStorage &eval_storage, const NodeGeometryForeachGeometryElementOutput &node_storage) const
void prepare_components(lf::Params ¶ms, ForeachGeometryElementEvalStorage &eval_storage, const NodeGeometryForeachGeometryElementOutput &node_storage) const
std::string input_name(const int i) const override
LazyFunctionForForeachGeometryElementZone(const bNodeTree &btree, const bke::bNodeTreeZone &zone, ZoneBuildInfo &zone_info, const ZoneBodyFunction &body_fn)
std::string output_name(const int i) const override
void * init_storage(LinearAllocator<> &allocator) const override
void build_graph_contents(ForeachGeometryElementEvalStorage &eval_storage, const NodeGeometryForeachGeometryElementOutput &node_storage, Span< lf::GraphInputSocket * > graph_inputs, Span< lf::GraphOutputSocket * > graph_outputs) const
void destruct_storage(void *storage) const override
linear_allocator::ChunkedList< WarningWithNode > node_warnings
LinearAllocator * allocator
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
bool try_capture_field_on_geometry(MutableAttributeAccessor attributes, const fn::FieldContext &field_context, const StringRef attribute_id, AttrDomain domain, const fn::Field< bool > &selection, const fn::GField &field)
const CPPType * socket_type_to_geo_nodes_base_cpp_type(eNodeSocketDatatype type)
std::string hash_to_anonymous_attribute_name(Args &&...args)
OutputSocket GraphInputSocket
Array< bke::Instances * > extract_instances(const bke::Instances &instances, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< GreasePencil * > extract_greasepencil_layer_points(const GreasePencil &grease_pencil, int layer_i, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< Mesh * > extract_mesh_faces(const Mesh &mesh, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< Mesh * > extract_mesh_vertices(const Mesh &mesh, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< Curves * > extract_curves(const Curves &curves, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< Curves * > extract_curves_points(const Curves &curves, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< GreasePencil * > extract_greasepencil_layers(const GreasePencil &grease_pencil, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< GreasePencil * > extract_greasepencil_layer_curves(const GreasePencil &grease_pencil, int layer_i, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt)
Array< PointCloud * > extract_pointcloud_points(const PointCloud &pointcloud, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
Array< Mesh * > extract_mesh_edges(const Mesh &mesh, const IndexMask &mask, const bke::AttributeFilter &attribute_filter)
static std::optional< AttrDomain > get_foreach_attribute_propagation_target_domain(const GeometryComponent::Type component_type)
void initialize_zone_wrapper(const bNodeTreeZone &zone, ZoneBuildInfo &zone_info, const ZoneBodyFunction &body_fn, const bool expose_all_reference_sets, Vector< lf::Input > &r_inputs, Vector< lf::Output > &r_outputs)
bool should_log_socket_values_for_context(const GeoNodesUserData &user_data, const ComputeContextHash hash)
std::string make_anonymous_attribute_socket_inspection_string(const bNodeSocket &socket)
void set_default_value_for_output_socket(lf::Params ¶ms, const int lf_index, const bNodeSocket &bsocket)
std::string zone_wrapper_output_name(const ZoneBuildInfo &zone_info, const bNodeTreeZone &zone, const Span< lf::Output > outputs, const int lf_socket_i)
LazyFunction & build_foreach_geometry_element_zone_lazy_function(ResourceScope &scope, const bNodeTree &btree, const bke::bNodeTreeZone &zone, ZoneBuildInfo &zone_info, const ZoneBodyFunction &body_fn)
std::string zone_wrapper_input_name(const ZoneBuildInfo &zone_info, const bNodeTreeZone &zone, const Span< lf::Input > inputs, const int lf_socket_i)
NodeForeachGeometryElementInputItems input_items
NodeForeachGeometryElementMainItems main_items
NodeForeachGeometryElementGenerationItems generation_items
bNodeTreeRuntimeHandle * runtime
bool allow_skip(const StringRef name) const
void keep_only(Span< GeometryComponent::Type > component_types)
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
const GreasePencil * get_grease_pencil() const
Vector< const GeometryComponent * > get_components() const
bool has(const GeometryComponent::Type component_type) const
const Curves * get_curves() const
const Instances * get_instances() const
const PointCloud * get_pointcloud() const
const Mesh * get_mesh() const
GeometryComponent::Type component_type
std::optional< int > layer_index
std::optional< Array< GeometrySet > > element_geometries
Array< SocketValueVariant > index_values
AttributeAccessor input_attributes() const
void emplace_field_context(const GeometrySet &geometry)
MutableAttributeAccessor attributes_for_write(GeometrySet &geometry) const
ForeachElementComponentID id
std::optional< fn::FieldEvaluator > field_evaluator
std::optional< bke::GeometryFieldContext > field_context
Array< Array< SocketValueVariant > > item_input_values
IndexRange body_nodes_range
GeometrySet main_geometry
std::optional< LazyFunctionForReduceForeachGeometryElement > reduce_function
VectorSet< lf::FunctionNode * > lf_body_nodes
std::optional< lf::GraphExecutor > graph_executor
LinearAllocator allocator
std::optional< LazyFunctionForLogicalOr > or_function
std::optional< ForeachGeometryElementZoneSideEffectProvider > side_effect_provider
Array< ForeachElementComponent > components
void * graph_executor_storage
std::optional< ForeachGeometryElementNodeExecuteWrapper > body_execute_wrapper
const GeoNodesSideEffectNodes * side_effect_nodes
MultiValueMap< std::pair< ComputeContextHash, int32_t >, int > iterations_by_iteration_zone
const ComputeContext * compute_context
const GeoNodesCallData * call_data
LazyFunctionForReduceForeachGeometryElement(const LazyFunctionForForeachGeometryElementZone &parent, ForeachGeometryElementEvalStorage &eval_storage)
void handle_main_items_and_geometry(lf::Params ¶ms, const lf::Context &context) const
void handle_generation_items_group(lf::Params ¶ms, const lf::Context &context, int geometry_item_i, IndexRange generation_items_range) const
void handle_generation_item_groups(lf::Params ¶ms, const lf::Context &context, int first_valid_item_i) const
ForeachGeometryElementEvalStorage & eval_storage_
const LazyFunctionForForeachGeometryElementZone & parent_
void execute_impl(lf::Params ¶ms, const lf::Context &context) const override
bool handle_generation_items_group_lazyness(lf::Params ¶ms, const lf::Context &context, int geometry_item_i, IndexRange generation_items_range) const
void handle_generation_items(lf::Params ¶ms, const lf::Context &context) const
int handle_invalid_generation_items(lf::Params ¶ms) const
ZoneFunctionIndices indices
struct blender::nodes::ZoneFunctionIndices::@165160011314225015162310017251113363101175306052 inputs