Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/intern/multi_functions/vectorize.cc')
-rw-r--r--source/blender/functions/intern/multi_functions/vectorize.cc128
1 files changed, 128 insertions, 0 deletions
diff --git a/source/blender/functions/intern/multi_functions/vectorize.cc b/source/blender/functions/intern/multi_functions/vectorize.cc
new file mode 100644
index 00000000000..773301597a6
--- /dev/null
+++ b/source/blender/functions/intern/multi_functions/vectorize.cc
@@ -0,0 +1,128 @@
+#include "vectorize.h"
+
+#include "BLI_array_cxx.h"
+#include "BLI_rand_cxx.h"
+
+namespace FN {
+
+using BLI::Array;
+
+MF_SimpleVectorize::MF_SimpleVectorize(const MultiFunction &function,
+ ArrayRef<bool> input_is_vectorized)
+ : m_function(function), m_input_is_vectorized(input_is_vectorized)
+{
+ BLI_assert(input_is_vectorized.contains(true));
+
+ MFSignatureBuilder signature = this->get_builder(function.name() + " (Vectorized)");
+ signature.copy_used_contexts(function);
+
+ bool found_output_param = false;
+ UNUSED_VARS_NDEBUG(found_output_param);
+
+ for (uint param_index : function.param_indices()) {
+ MFParamType param_type = function.param_type(param_index);
+ MFDataType data_type = param_type.data_type();
+ StringRef param_name = function.param_name(param_index);
+
+ switch (param_type.type()) {
+ case MFParamType::VectorInput:
+ case MFParamType::VectorOutput:
+ case MFParamType::MutableVector:
+ case MFParamType::MutableSingle: {
+ BLI_assert(false);
+ break;
+ }
+ case MFParamType::SingleInput: {
+ BLI_assert(!found_output_param);
+ if (input_is_vectorized[param_index]) {
+ signature.vector_input(param_name + " (List)", data_type.single__cpp_type());
+ m_vectorized_inputs.append(param_index);
+ }
+ else {
+ signature.single_input(param_name, data_type.single__cpp_type());
+ }
+ break;
+ }
+ case MFParamType::SingleOutput: {
+ signature.vector_output(param_name + " (List)", data_type.single__cpp_type());
+ m_output_indices.append(param_index);
+ found_output_param = true;
+ break;
+ }
+ }
+ }
+}
+
+static void get_vectorization_lengths(IndexMask mask,
+ MFParams params,
+ ArrayRef<uint> vectorized_param_indices,
+ MutableArrayRef<int> r_lengths)
+{
+ r_lengths.fill_indices(mask.indices(), -1);
+
+ for (uint param_index : vectorized_param_indices) {
+ GenericVirtualListListRef values = params.readonly_vector_input(param_index);
+ for (uint i : mask.indices()) {
+ if (r_lengths[i] != 0) {
+ uint sublist_size = values.sublist_size(i);
+ r_lengths[i] = std::max<int>(r_lengths[i], sublist_size);
+ }
+ }
+ }
+}
+
+void MF_SimpleVectorize::call(IndexMask mask, MFParams params, MFContext context) const
+{
+ if (mask.size() == 0) {
+ return;
+ }
+
+ Array<int> vectorization_lengths(mask.min_array_size());
+ get_vectorization_lengths(mask, params, m_vectorized_inputs, vectorization_lengths);
+
+ MFContextBuilder sub_context_builder;
+ sub_context_builder.add_global_contexts(context);
+
+ for (uint index : mask.indices()) {
+ uint length = vectorization_lengths[index];
+ MFParamsBuilder params_builder(m_function, length);
+
+ for (uint param_index : m_function.param_indices()) {
+ MFParamType param_type = m_function.param_type(param_index);
+ switch (param_type.type()) {
+ case MFParamType::VectorInput:
+ case MFParamType::VectorOutput:
+ case MFParamType::MutableVector:
+ case MFParamType::MutableSingle: {
+ BLI_assert(false);
+ break;
+ }
+ case MFParamType::SingleInput: {
+ if (m_input_is_vectorized[param_index]) {
+ GenericVirtualListListRef input_list_list = params.readonly_vector_input(param_index);
+ GenericVirtualListRef repeated_input = input_list_list.repeated_sublist(index, length);
+ params_builder.add_readonly_single_input(repeated_input);
+ }
+ else {
+ GenericVirtualListRef input_list = params.readonly_single_input(param_index);
+ GenericVirtualListRef repeated_input = input_list.repeated_element(index, length);
+ params_builder.add_readonly_single_input(repeated_input);
+ }
+ break;
+ }
+ case MFParamType::SingleOutput: {
+ GenericVectorArray &output_array_list = params.vector_output(param_index);
+ GenericMutableArrayRef output_array = output_array_list.allocate_single(index, length);
+ params_builder.add_single_output(output_array);
+ break;
+ }
+ }
+ }
+
+ /* TODO: Pass modified per element contexts. */
+ ArrayRef<uint> sub_mask_indices = IndexRange(length).as_array_ref();
+ m_function.call(sub_mask_indices, params_builder, sub_context_builder);
+ }
+}
+
+} // namespace FN