Changeset View
Changeset View
Standalone View
Standalone View
source/blender/functions/intern/field.cc
| Show First 20 Lines • Show All 618 Lines • ▼ Show 20 Lines | FieldInput::FieldInput(const CPPType &type, std::string debug_name) | ||||
| field_inputs->deduplicated_nodes.add_new(*this); | field_inputs->deduplicated_nodes.add_new(*this); | ||||
| field_inputs_ = std::move(field_inputs); | field_inputs_ = std::move(field_inputs); | ||||
| } | } | ||||
| /* -------------------------------------------------------------------- | /* -------------------------------------------------------------------- | ||||
| * FieldEvaluator. | * FieldEvaluator. | ||||
| */ | */ | ||||
| static Vector<int64_t> indices_from_selection(const VArray<bool> &selection) | static Vector<int64_t> indices_from_selection(IndexMask mask, const VArray<bool> &selection) | ||||
| { | { | ||||
| /* If the selection is just a single value, it's best to avoid calling this | /* If the selection is just a single value, it's best to avoid calling this | ||||
| * function when constructing an IndexMask and use an IndexRange instead. */ | * function when constructing an IndexMask and use an IndexRange instead. */ | ||||
| BLI_assert(!selection.is_single()); | BLI_assert(!selection.is_single()); | ||||
| Vector<int64_t> indices; | Vector<int64_t> indices; | ||||
| if (selection.is_span()) { | if (selection.is_span()) { | ||||
| Span<bool> span = selection.get_internal_span(); | Span<bool> span = selection.get_internal_span(); | ||||
| for (const int64_t i : span.index_range()) { | for (const int64_t i : mask) { | ||||
| if (span[i]) { | if (span[i]) { | ||||
| indices.append(i); | indices.append(i); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (const int i : selection.index_range()) { | for (const int i : mask) { | ||||
| if (selection[i]) { | if (selection[i]) { | ||||
| indices.append(i); | indices.append(i); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return indices; | return indices; | ||||
| } | } | ||||
| Show All 24 Lines | |||||
| int FieldEvaluator::add(GField field) | int FieldEvaluator::add(GField field) | ||||
| { | { | ||||
| const int field_index = fields_to_evaluate_.append_and_get_index(std::move(field)); | const int field_index = fields_to_evaluate_.append_and_get_index(std::move(field)); | ||||
| dst_varrays_.append(nullptr); | dst_varrays_.append(nullptr); | ||||
| output_pointer_infos_.append({}); | output_pointer_infos_.append({}); | ||||
| return field_index; | return field_index; | ||||
| } | } | ||||
| static IndexMask evaluate_selection(const Field<bool> &selection_field, | |||||
| const FieldContext &context, | |||||
| IndexMask full_mask, | |||||
| ResourceScope &scope) | |||||
| { | |||||
| if (selection_field) { | |||||
| VArray<bool> selection = | |||||
| evaluate_fields(scope, {selection_field}, full_mask, context)[0].typed<bool>(); | |||||
| if (selection.is_single()) { | |||||
| if (selection.get_internal_single()) { | |||||
| return full_mask; | |||||
| } | |||||
| return IndexRange(0); | |||||
| } | |||||
| return scope.add_value(indices_from_selection(full_mask, selection)).as_span(); | |||||
| } | |||||
| return full_mask; | |||||
| } | |||||
| void FieldEvaluator::evaluate() | void FieldEvaluator::evaluate() | ||||
| { | { | ||||
| BLI_assert_msg(!is_evaluated_, "Cannot evaluate fields twice."); | BLI_assert_msg(!is_evaluated_, "Cannot evaluate fields twice."); | ||||
| selection_mask_ = evaluate_selection(selection_field_, context_, mask_, scope_); | |||||
| Array<GFieldRef> fields(fields_to_evaluate_.size()); | Array<GFieldRef> fields(fields_to_evaluate_.size()); | ||||
| for (const int i : fields_to_evaluate_.index_range()) { | for (const int i : fields_to_evaluate_.index_range()) { | ||||
| fields[i] = fields_to_evaluate_[i]; | fields[i] = fields_to_evaluate_[i]; | ||||
| } | } | ||||
| evaluated_varrays_ = evaluate_fields(scope_, fields, mask_, context_, dst_varrays_); | evaluated_varrays_ = evaluate_fields(scope_, fields, selection_mask_, context_, dst_varrays_); | ||||
| BLI_assert(fields_to_evaluate_.size() == evaluated_varrays_.size()); | BLI_assert(fields_to_evaluate_.size() == evaluated_varrays_.size()); | ||||
| for (const int i : fields_to_evaluate_.index_range()) { | for (const int i : fields_to_evaluate_.index_range()) { | ||||
| OutputPointerInfo &info = output_pointer_infos_[i]; | OutputPointerInfo &info = output_pointer_infos_[i]; | ||||
| if (info.dst != nullptr) { | if (info.dst != nullptr) { | ||||
| info.set(info.dst, evaluated_varrays_[i], scope_); | info.set(info.dst, evaluated_varrays_[i], scope_); | ||||
| } | } | ||||
| } | } | ||||
| is_evaluated_ = true; | is_evaluated_ = true; | ||||
| } | } | ||||
| IndexMask FieldEvaluator::get_evaluated_as_mask(const int field_index) | IndexMask FieldEvaluator::get_evaluated_as_mask(const int field_index) | ||||
| { | { | ||||
| VArray<bool> varray = this->get_evaluated(field_index).typed<bool>(); | VArray<bool> varray = this->get_evaluated(field_index).typed<bool>(); | ||||
| if (varray.is_single()) { | if (varray.is_single()) { | ||||
| if (varray.get_internal_single()) { | if (varray.get_internal_single()) { | ||||
| return IndexRange(varray.size()); | return IndexRange(varray.size()); | ||||
| } | } | ||||
| return IndexRange(0); | return IndexRange(0); | ||||
| } | } | ||||
| return scope_.add_value(indices_from_selection(varray)).as_span(); | return scope_.add_value(indices_from_selection(mask_, varray)).as_span(); | ||||
| } | |||||
| IndexMask FieldEvaluator::get_evaluated_selection_as_mask() | |||||
| { | |||||
| BLI_assert(is_evaluated_); | |||||
| return selection_mask_; | |||||
| } | } | ||||
| } // namespace blender::fn | } // namespace blender::fn | ||||