28using bke::AttributeAccessor;
29using bke::GeometryComponent;
30using bke::GeometrySet;
31using bke::MutableAttributeAccessor;
32using bke::SocketValueVariant;
68 if (this->
id.component_type == GeometryComponent::Type::GreasePencil &&
69 ELEM(this->
id.domain, AttrDomain::Point, AttrDomain::Curve))
71 this->field_context.emplace(
72 *
geometry.get_grease_pencil(), this->id.domain, *this->id.layer_index);
75 this->field_context.emplace(*
geometry.get_component(this->id.component_type),
82 return *this->field_context->attributes();
87 if (this->
id.component_type == GeometryComponent::Type::GreasePencil &&
88 ELEM(this->
id.domain, AttrDomain::Point, AttrDomain::Curve))
122 int first_valid_item_i)
const;
161 user_data, body_compute_context.
hash());
164 lf::Context body_context{context.storage, &body_user_data, &body_local_user_data};
187 const Span<int> iterations_with_side_effects =
192 for (
const int i : iterations_with_side_effects) {
237 const bNode &output_bnode_;
267 output_bnode_(*zone.output_node()),
268 zone_info_(zone_info),
280 output_bnode_.storage);
282 BLI_assert(zone_.input_node()->output_socket(1).is_available() ==
283 (iteration_domain != AttrDomain::Corner));
285 const int input_items_num = node_storage.input_items.items_num;
286 const int main_items_num = node_storage.main_items.items_num;
287 const int generation_items_num = node_storage.generation_items.items_num;
291 iteration_domain == AttrDomain::Corner ? 1 : 2, input_items_num);
292 indices_.inputs.bsocket_outer = indices_.inputs.lf_outer;
293 indices_.inputs.bsocket_inner = indices_.inputs.lf_inner;
297 indices_.main.bsocket_outer = indices_.main.lf_outer;
298 indices_.main.bsocket_inner = indices_.main.lf_inner;
301 generation_items_num);
303 generation_items_num);
305 generation_items_num);
307 generation_items_num);
318 if (s->graph_executor_storage) {
319 s->graph_executor->destruct_storage(s->graph_executor_storage);
332 output_bnode_.storage);
336 if (!eval_storage.graph_executor) {
341 if (eval_storage.total_iterations_num == 0) {
342 if (!eval_storage.main_geometry.is_empty()) {
345 {zone_.input_node()->identifier,
346 {NodeWarningType::Info,
347 N_(
"Input geometry has no elements in the iteration domain.")}});
354 eval_storage.graph_executor_storage, context.user_data, context.local_user_data};
356 eval_storage.graph_executor->execute(
params, eval_graph_context);
366 zone_info_.indices.inputs.main[0])
378 for (
const int i :
inputs_.index_range()) {
382 for (
const int i :
outputs_.index_range()) {
410 if (btree_orig.
runtime->logged_zone_graphs) {
411 std::lock_guard
lock{btree_orig.
runtime->logged_zone_graphs->mutex};
412 btree_orig.
runtime->logged_zone_graphs->graph_by_zone_id.lookup_or_add_cb(
413 output_bnode_.identifier, [&]() { return lf_graph.to_dot(); });
426 const bNodeSocket &element_geometry_bsocket = zone_.input_node()->output_socket(1);
427 const bool create_element_geometries = element_geometry_bsocket.is_available() &&
428 element_geometry_bsocket.is_directly_linked();
434 if (src_component->type() == GeometryComponent::Type::GreasePencil &&
435 ELEM(iteration_domain, AttrDomain::Point, AttrDomain::Curve))
438 for (
const int layer_i : grease_pencil.layers().index_range()) {
440 grease_pencil.layer(layer_i));
441 if (drawing ==
nullptr) {
448 component_ids.
append({component_type, iteration_domain, layer_i});
452 const int domain_size = src_component->attribute_domain_size(iteration_domain);
453 if (domain_size > 0) {
454 component_ids.
append({component_type, iteration_domain});
461 zone_info_.indices.inputs.main[1])
465 int body_nodes_offset = 0;
467 for (
const int component_i : component_ids.
index_range()) {
470 component_info.
id = id;
483 zone_info_.indices.inputs.main[indices_.inputs.lf_outer[item_i]])
495 body_nodes_offset +=
mask.size();
502 if (create_element_geometries) {
509 element_geometries->index_range(), 256, [&](
const IndexRange range) {
510 for (const int i : range) {
511 (*component_info.element_geometries)[i] = SocketValueVariant::From(
512 (*element_geometries)[i]);
523 component_info.item_input_values[item_i].reinitialize(
mask.size());
524 const GVArray &values = component_info.field_evaluator->get_evaluated(item_i);
533 eval_storage.total_iterations_num = body_nodes_offset;
542 switch (
id.component_type) {
543 case GeometryComponent::Type::Mesh: {
547 case AttrDomain::Point: {
551 case AttrDomain::Edge: {
555 case AttrDomain::Face: {
565 element_geometries[
i].replace_mesh(meshes[
i]);
567 return element_geometries;
569 case GeometryComponent::Type::PointCloud: {
570 if (
id.domain != AttrDomain::Point) {
575 main_pointcloud,
mask, attribute_filter);
578 element_geometries[
i].replace_pointcloud(pointclouds[
i]);
580 return element_geometries;
582 case GeometryComponent::Type::Curve: {
586 case AttrDomain::Point: {
590 case AttrDomain::Curve: {
599 element_geometries[
i].replace_curves(element_curves[
i]);
601 return element_geometries;
603 case GeometryComponent::Type::Instance: {
604 if (
id.domain != AttrDomain::Instance) {
609 main_instances,
mask, attribute_filter);
612 element_geometries[
i].replace_instances(element_instances[
i]);
614 return element_geometries;
616 case GeometryComponent::Type::GreasePencil: {
620 case AttrDomain::Layer: {
622 main_grease_pencil,
mask, attribute_filter);
625 case AttrDomain::Point: {
627 main_grease_pencil, *
id.layer_index,
mask, attribute_filter);
630 case AttrDomain::Curve: {
632 main_grease_pencil, *
id.layer_index,
mask, attribute_filter);
640 element_geometries[
i].replace_grease_pencil(element_grease_pencils[
i]);
642 return element_geometries;
661 lf_body_nodes.
add_new(&lf_node);
665 for (
const int zone_output_i : body_fn_.indices.inputs.output_usages.index_range()) {
668 *graph_inputs[zone_info_.indices.inputs.output_usages[1 + zone_output_i]];
672 lf_node.
input(body_fn_.indices.inputs.output_usages[zone_output_i]));
676 const bNodeSocket &element_geometry_bsocket = zone_.input_node()->output_socket(1);
684 lf_body_node.
input(body_fn_.indices.inputs.main[0])
687 if (element_geometry_bsocket.is_available()) {
691 &empty_geometry_value;
696 lf_body_node.
input(body_fn_.indices.inputs.main[indices_.inputs.lf_inner[item_i]])
700 for (
const int border_link_i : zone_info_.indices.inputs.border_links.index_range()) {
702 *graph_inputs[zone_info_.indices.inputs.border_links[border_link_i]],
703 lf_body_node.
input(body_fn_.indices.inputs.border_links[border_link_i]));
706 for (
const auto &item : body_fn_.indices.inputs.reference_sets.items()) {
708 *graph_inputs[zone_info_.indices.inputs.reference_sets.lookup(item.key)],
709 lf_body_node.
input(item.value));
721 BLI_assert(body_main_outputs_num == body_fn_.indices.outputs.main.size());
725 lf_graph.
add_link(lf_body_node.
output(body_fn_.indices.outputs.main[item_i]),
726 lf_reduce.
input(
i * body_main_outputs_num + item_i));
730 lf_graph.
add_link(lf_body_node.
output(body_fn_.indices.outputs.main[body_output_i]),
731 lf_reduce.
input(
i * body_main_outputs_num + body_output_i));
736 lf_graph.
add_link(lf_reduce.
output(0), *graph_outputs[zone_info_.indices.outputs.main[0]]);
738 const int output_i = indices_.main.lf_outer[item_i];
740 *graph_outputs[zone_info_.indices.outputs.main[output_i]]);
743 const int output_i = indices_.generation.lf_outer[item_i];
745 *graph_outputs[zone_info_.indices.outputs.main[output_i]]);
749 static bool static_true{
true};
750 for (
const int i : zone_info_.indices.outputs.input_usages) {
751 graph_outputs[
i]->set_default_value(&static_true);
757 for (
const int border_link_i : zone_.border_links.index_range()) {
762 lf_body_node.
output(body_fn_.indices.outputs.border_link_usages[border_link_i]),
767 *graph_outputs[zone_info_.indices.outputs.border_link_usages[border_link_i]]);
793 (node_storage.main_items.items_num + node_storage.generation_items.items_num));
795 for ([[maybe_unused]]
const int i : eval_storage.
lf_body_nodes.index_range()) {
797 for (const int item_i : IndexRange(node_storage.main_items.items_num)) {
798 const NodeForeachGeometryElementMainItem &item = node_storage.main_items.items[item_i];
799 inputs_.append_as(item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Used);
802 for (
const int item_i :
IndexRange(node_storage.generation_items.items_num)) {
803 const NodeForeachGeometryElementGenerationItem &item =
804 node_storage.generation_items.items[item_i];
805 inputs_.append_as(item.name, CPPType::get<SocketValueVariant>(), lf::ValueUsage::Maybe);
812 for (
const int item_i :
IndexRange(node_storage.main_items.items_num)) {
813 const NodeForeachGeometryElementMainItem &item = node_storage.main_items.items[item_i];
814 outputs_.append_as(item.name, CPPType::get<SocketValueVariant>());
817 for (
const int item_i :
IndexRange(node_storage.generation_items.items_num)) {
818 const NodeForeachGeometryElementGenerationItem &item =
819 node_storage.generation_items.items[item_i];
820 outputs_.append_as(item.name, CPPType::get<SocketValueVariant>());
828 switch (component_type) {
829 case GeometryComponent::Type::Mesh:
830 case GeometryComponent::Type::PointCloud:
831 return AttrDomain::Point;
832 case GeometryComponent::Type::Curve:
833 return AttrDomain::Curve;
834 case GeometryComponent::Type::Instance:
835 return AttrDomain::Instance;
836 case GeometryComponent::Type::GreasePencil:
837 return AttrDomain::Layer;
848 parent_.output_bnode_.storage);
851 if (node_storage.generation_items.items_num == 0) {
862 parent_.output_bnode_.storage);
864 node_storage.generation_items.items_num;
866 const int main_geometry_output = 0;
867 if (
params.output_was_set(main_geometry_output)) {
874 for (
const int item_i :
IndexRange(node_storage.main_items.items_num)) {
878 if (!base_cpp_type) {
885 user_data.call_data->self_object()->id.name,
886 user_data.compute_context->hash(),
887 parent_.output_bnode_.identifier,
898 attribute_name, component_info.
id.
domain, cd_type);
907 mask.foreach_index([&](
const int i,
const int pos) {
908 const int lf_param_index =
pos * body_main_outputs_num + item_i;
919 auto attribute_field = std::make_shared<bke::AttributeFieldInput>(
923 parent_.output_bnode_.output_socket(
parent_.indices_.main.bsocket_outer[item_i])));
935 parent_.output_bnode_.storage);
938 if (first_valid_item_i == node_storage.generation_items.items_num) {
948 parent_.output_bnode_.storage);
952 for (; item_i < node_storage.generation_items.items_num; item_i++) {
954 node_storage.generation_items.items[item_i];
959 const int lf_socket_i =
parent_.indices_.generation.lf_outer[item_i];
960 if (!
params.output_was_set(lf_socket_i)) {
961 const int bsocket_i =
parent_.indices_.generation.bsocket_outer[item_i];
963 params, lf_socket_i,
parent_.zone_.output_node()->output_socket(bsocket_i));
973 parent_.output_bnode_.storage);
974 int previous_geometry_item_i = first_valid_item_i;
977 for (
const int item_i :
981 node_storage.generation_items.items[item_i];
987 previous_geometry_item_i,
989 previous_geometry_item_i = item_i;
995 previous_geometry_item_i,
997 node_storage.generation_items.items_num));
1003 const int geometry_item_i,
1004 const IndexRange generation_items_range)
const
1008 parent_.output_bnode_.storage);
1010 node_storage.generation_items.items_num;
1014 params, context, geometry_item_i, generation_items_range))
1027 for (
const int i : generation_items_range.
index_range()) {
1028 const int item_i = generation_items_range[
i];
1030 node_storage.generation_items.items[item_i];
1032 user_data.call_data->self_object()->id.name,
1033 user_data.compute_context->hash(),
1034 parent_.output_bnode_.identifier,
1042 struct NameWithType {
1061 mask.foreach_index([&](
const int element_i,
const int local_body_i) {
1063 const int geometry_param_i = body_i * body_main_outputs_num +
1064 parent_.indices_.generation.lf_inner[geometry_item_i];
1069 {GeometryComponent::Type::Mesh,
1070 GeometryComponent::Type::PointCloud,
1071 GeometryComponent::Type::Curve,
1072 GeometryComponent::Type::GreasePencil,
1073 GeometryComponent::Type::Instance})
1075 if (!
geometry.has(dst_component_type)) {
1083 const std::optional<AttrDomain> propagation_domain =
1085 if (!propagation_domain) {
1090 for (
const NameWithType &name_with_type : attributes_to_propagate) {
1107 if (!src_attribute) {
1117 name, *propagation_domain, data_type);
1126 for (
const int local_item_i : generation_items_range.
index_range()) {
1127 const int item_i = generation_items_range[local_item_i];
1129 node_storage.generation_items.items[item_i];
1131 const int field_param_i = body_i * body_main_outputs_num +
1132 parent_.indices_.generation.lf_inner[item_i];
1135 if (capture_domain == AttrDomain::Instance) {
1138 geometry.get_component_for_write(GeometryComponent::Type::Instance),
1139 attribute_names[local_item_i],
1147 {GeometryComponent::Type::Mesh,
1148 GeometryComponent::Type::PointCloud,
1149 GeometryComponent::Type::Curve,
1150 GeometryComponent::Type::GreasePencil})
1152 if (sub_geometry.
has(component_type)) {
1155 attribute_names[local_item_i],
1169 edit_data_geometry.
keep_only({GeometryComponent::Type::Edit});
1175 params.set_output(
parent_.indices_.generation.lf_outer[geometry_item_i],
1179 for (
const int local_item_i : generation_items_range.
index_range()) {
1180 const int item_i = generation_items_range[local_item_i];
1182 node_storage.generation_items.items[item_i];
1185 const StringRef attribute_name = attribute_names[local_item_i];
1186 auto attribute_field = std::make_shared<bke::AttributeFieldInput>(
1190 parent_.output_bnode_.output_socket(2 + node_storage.main_items.items_num + item_i)));
1191 params.set_output(
parent_.indices_.generation.lf_outer[item_i],
1199 const int geometry_item_i,
1200 const IndexRange generation_items_range)
const
1203 parent_.output_bnode_.storage);
1205 node_storage.generation_items.items_num;
1207 const int geometry_output_param =
parent_.indices_.generation.lf_outer[geometry_item_i];
1209 if (
params.output_was_set(geometry_output_param)) {
1216 const int start_bsocket_i =
parent_.indices_.generation.bsocket_outer[geometry_item_i];
1223 bool any_output_used =
false;
1227 any_output_used =
true;
1231 if (!any_output_used) {
1238 bool has_missing_input =
false;
1239 for (
const int body_i :
IndexRange(bodies_num)) {
1240 const int offset = body_i * body_main_outputs_num +
1241 parent_.indices_.generation.lf_inner[geometry_item_i];
1243 const bool is_available =
params.try_get_input_data_ptr_or_request(offset +
i) !=
nullptr;
1244 if (!is_available) {
1245 has_missing_input =
true;
1249 if (has_missing_input) {
1263 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)
static SocketValueVariant From(T &&value)
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
MutableAttributeAccessor attributes_for_write()
virtual std::optional< MutableAttributeAccessor > attributes_for_write()
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType 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
static SocketValueVariant From(T &&value)
linear_allocator::ChunkedList< WarningWithNode > node_warnings
LinearAllocator * allocator
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
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)
AttrType cpp_type_to_attribute_type(const CPPType &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)
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, bool allow_merging_instance_references=true)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
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)
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)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
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
Array< SocketValueVariant > index_values
std::optional< Array< SocketValueVariant > > element_geometries
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::@273312016272125124266321211240073263106341134120 inputs