Changeset View
Changeset View
Standalone View
Standalone View
source/blender/functions/intern/field.cc
| Show First 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | static void build_multi_function_procedure_for_fields(MFProcedure &procedure, | ||||
| /* Add output parameters to the procedure. */ | /* Add output parameters to the procedure. */ | ||||
| Set<MFVariable *> already_output_variables; | Set<MFVariable *> already_output_variables; | ||||
| for (const GFieldRef &field : output_fields) { | for (const GFieldRef &field : output_fields) { | ||||
| MFVariable *variable = variable_by_field.lookup(field); | MFVariable *variable = variable_by_field.lookup(field); | ||||
| if (!already_output_variables.add(variable)) { | if (!already_output_variables.add(variable)) { | ||||
| /* One variable can be output at most once. To output the same value twice, we have to make | /* One variable can be output at most once. To output the same value twice, we have to make | ||||
| * a copy first. */ | * a copy first. */ | ||||
| const MultiFunction ©_fn = scope.construct<CustomMF_GenericCopy>("copy", | const MultiFunction ©_fn = scope.construct<CustomMF_GenericCopy>(variable->data_type()); | ||||
| variable->data_type()); | |||||
| variable = builder.add_call<1>(copy_fn, {variable})[0]; | variable = builder.add_call<1>(copy_fn, {variable})[0]; | ||||
| } | } | ||||
| builder.add_output_parameter(*variable); | builder.add_output_parameter(*variable); | ||||
| } | } | ||||
| /* Remove the variables that should not be destructed from the map. */ | /* Remove the variables that should not be destructed from the map. */ | ||||
| for (const GFieldRef &field : output_fields) { | for (const GFieldRef &field : output_fields) { | ||||
| variable_by_field.remove(field); | variable_by_field.remove(field); | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | Vector<GVArray> evaluate_fields(ResourceScope &scope, | ||||
| } | } | ||||
| /* Evaluate varying fields if necessary. */ | /* Evaluate varying fields if necessary. */ | ||||
| if (!varying_fields_to_evaluate.is_empty()) { | if (!varying_fields_to_evaluate.is_empty()) { | ||||
| /* Build the procedure for those fields. */ | /* Build the procedure for those fields. */ | ||||
| MFProcedure procedure; | MFProcedure procedure; | ||||
| build_multi_function_procedure_for_fields( | build_multi_function_procedure_for_fields( | ||||
| procedure, scope, field_tree_info, varying_fields_to_evaluate); | procedure, scope, field_tree_info, varying_fields_to_evaluate); | ||||
| MFProcedureExecutor procedure_executor{"Procedure", procedure}; | MFProcedureExecutor procedure_executor{procedure}; | ||||
| /* Add multi threading capabilities to the field evaluation. */ | /* Add multi threading capabilities to the field evaluation. */ | ||||
| const int grain_size = 10000; | const int grain_size = 10000; | ||||
| fn::ParallelMultiFunction parallel_procedure_executor{procedure_executor, grain_size}; | fn::ParallelMultiFunction parallel_procedure_executor{procedure_executor, grain_size}; | ||||
| /* Utility variable to make easy to switch the executor. */ | /* Utility variable to make easy to switch the executor. */ | ||||
| const MultiFunction &executor_fn = parallel_procedure_executor; | const MultiFunction &executor_fn = parallel_procedure_executor; | ||||
| MFParamsBuilder mf_params{executor_fn, &mask}; | MFParamsBuilder mf_params{executor_fn, &mask}; | ||||
| MFContextBuilder mf_context; | MFContextBuilder mf_context; | ||||
| Show All 40 Lines | Vector<GVArray> evaluate_fields(ResourceScope &scope, | ||||
| } | } | ||||
| /* Evaluate constant fields if necessary. */ | /* Evaluate constant fields if necessary. */ | ||||
| if (!constant_fields_to_evaluate.is_empty()) { | if (!constant_fields_to_evaluate.is_empty()) { | ||||
| /* Build the procedure for those fields. */ | /* Build the procedure for those fields. */ | ||||
| MFProcedure procedure; | MFProcedure procedure; | ||||
| build_multi_function_procedure_for_fields( | build_multi_function_procedure_for_fields( | ||||
| procedure, scope, field_tree_info, constant_fields_to_evaluate); | procedure, scope, field_tree_info, constant_fields_to_evaluate); | ||||
| MFProcedureExecutor procedure_executor{"Procedure", procedure}; | MFProcedureExecutor procedure_executor{procedure}; | ||||
| MFParamsBuilder mf_params{procedure_executor, 1}; | MFParamsBuilder mf_params{procedure_executor, 1}; | ||||
| MFContextBuilder mf_context; | MFContextBuilder mf_context; | ||||
| /* Provide inputs to the procedure executor. */ | /* Provide inputs to the procedure executor. */ | ||||
| for (const GVArray &varray : field_context_inputs) { | for (const GVArray &varray : field_context_inputs) { | ||||
| mf_params.add_readonly_single_input(varray); | mf_params.add_readonly_single_input(varray); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
| GField make_field_constant_if_possible(GField field) | GField make_field_constant_if_possible(GField field) | ||||
| { | { | ||||
| if (field.node().depends_on_input()) { | if (field.node().depends_on_input()) { | ||||
| return field; | return field; | ||||
| } | } | ||||
| const CPPType &type = field.cpp_type(); | const CPPType &type = field.cpp_type(); | ||||
| BUFFER_FOR_CPP_TYPE_VALUE(type, buffer); | BUFFER_FOR_CPP_TYPE_VALUE(type, buffer); | ||||
| evaluate_constant_field(field, buffer); | evaluate_constant_field(field, buffer); | ||||
| auto constant_fn = std::make_unique<CustomMF_GenericConstant>(type, buffer, true); | GField new_field = make_constant_field(type, buffer); | ||||
| type.destruct(buffer); | type.destruct(buffer); | ||||
| return new_field; | |||||
| } | |||||
| GField make_constant_field(const CPPType &type, const void *value) | |||||
| { | |||||
| auto constant_fn = std::make_unique<CustomMF_GenericConstant>(type, value, true); | |||||
| auto operation = std::make_shared<FieldOperation>(std::move(constant_fn)); | auto operation = std::make_shared<FieldOperation>(std::move(constant_fn)); | ||||
| return GField{operation, 0}; | return GField{std::move(operation), 0}; | ||||
| } | } | ||||
| GVArray FieldContext::get_varray_for_input(const FieldInput &field_input, | GVArray FieldContext::get_varray_for_input(const FieldInput &field_input, | ||||
| IndexMask mask, | IndexMask mask, | ||||
| ResourceScope &scope) const | ResourceScope &scope) const | ||||
| { | { | ||||
| /* By default ask the field input to create the varray. Another field context might overwrite | /* By default ask the field input to create the varray. Another field context might overwrite | ||||
| * the context here. */ | * the context here. */ | ||||
| ▲ Show 20 Lines • Show All 176 Lines • Show Last 20 Lines | |||||