| 
									
										
										
										
											2022-02-11 09:07:11 +11:00
										 |  |  | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "FN_multi_function_builder.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-08 15:04:28 +02:00
										 |  |  | #include "BLI_hash.hh"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | namespace blender::fn::multi_function { | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 13:05:20 +02:00
										 |  |  | CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, | 
					
						
							|  |  |  |                                                    const void *value, | 
					
						
							|  |  |  |                                                    bool make_value_copy) | 
					
						
							|  |  |  |     : type_(type), owns_value_(make_value_copy) | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-11 13:05:20 +02:00
										 |  |  |   if (make_value_copy) { | 
					
						
							|  |  |  |     void *copied_value = MEM_mallocN_aligned(type.size(), type.alignment(), __func__); | 
					
						
							|  |  |  |     type.copy_construct(value, copied_value); | 
					
						
							|  |  |  |     value = copied_value; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   value_ = value; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   SignatureBuilder builder{"Constant", signature_}; | 
					
						
							| 
									
										
										
										
											2023-01-07 16:30:56 +01:00
										 |  |  |   builder.single_output("Value", type); | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   this->set_signature(&signature_); | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-11 13:05:20 +02:00
										 |  |  | CustomMF_GenericConstant::~CustomMF_GenericConstant() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (owns_value_) { | 
					
						
							| 
									
										
										
										
											2023-01-07 16:51:26 +01:00
										 |  |  |     signature_.params[0].type.data_type().single_type().destruct(const_cast<void *>(value_)); | 
					
						
							| 
									
										
										
										
											2022-09-25 17:39:45 +02:00
										 |  |  |     MEM_freeN(const_cast<void *>(value_)); | 
					
						
							| 
									
										
										
										
											2021-09-11 13:05:20 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, Context /*context*/) const | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GMutableSpan output = params.uninitialized_single_output(0); | 
					
						
							| 
									
										
										
										
											2021-06-28 13:13:52 +02:00
										 |  |  |   type_.fill_construct_indices(value_, output.data(), mask); | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  | uint64_t CustomMF_GenericConstant::hash() const | 
					
						
							| 
									
										
										
										
											2020-07-08 15:04:28 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-25 18:33:28 +10:00
										 |  |  |   return type_.hash_or_fallback(value_, uintptr_t(this)); | 
					
						
							| 
									
										
										
										
											2020-07-08 15:04:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CustomMF_GenericConstant::equals(const MultiFunction &other) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const CustomMF_GenericConstant *_other = dynamic_cast<const CustomMF_GenericConstant *>(&other); | 
					
						
							|  |  |  |   if (_other == nullptr) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (type_ != _other->type_) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-10 12:56:57 +02:00
										 |  |  |   return type_.is_equal(value_, _other->value_); | 
					
						
							| 
									
										
										
										
											2020-07-08 15:04:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const CPPType &type = array.type(); | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   SignatureBuilder builder{"Constant Vector", signature_}; | 
					
						
							| 
									
										
										
										
											2023-01-07 16:30:56 +01:00
										 |  |  |   builder.vector_output("Value", type); | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   this->set_signature(&signature_); | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CustomMF_GenericConstantArray::call(IndexMask mask, | 
					
						
							|  |  |  |                                          MFParams params, | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |                                          Context /*context*/) const | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GVectorArray &vectors = params.vector_output(0); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   for (int64_t i : mask) { | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  |     vectors.extend(i, array_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<DataType> input_types, | 
					
						
							|  |  |  |                                                Span<DataType> output_types) | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |     : output_amount_(output_types.size()) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   SignatureBuilder builder{"Default Output", signature_}; | 
					
						
							|  |  |  |   for (DataType data_type : input_types) { | 
					
						
							| 
									
										
										
										
											2023-01-07 16:30:56 +01:00
										 |  |  |     builder.input("Input", data_type); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   for (DataType data_type : output_types) { | 
					
						
							| 
									
										
										
										
											2023-01-07 16:30:56 +01:00
										 |  |  |     builder.output("Output", data_type); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   this->set_signature(&signature_); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, Context /*context*/) const | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   for (int param_index : this->param_indices()) { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |     ParamType param_type = this->param_type(param_index); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |     if (!param_type.is_output()) { | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (param_type.data_type().is_single()) { | 
					
						
							|  |  |  |       GMutableSpan span = params.uninitialized_single_output(param_index); | 
					
						
							|  |  |  |       const CPPType &type = span.type(); | 
					
						
							| 
									
										
										
										
											2021-06-28 13:13:52 +02:00
										 |  |  |       type.fill_construct_indices(type.default_value(), span.data(), mask); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | CustomMF_GenericCopy::CustomMF_GenericCopy(DataType data_type) | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   SignatureBuilder builder{"Copy", signature_}; | 
					
						
							| 
									
										
										
										
											2023-01-07 16:30:56 +01:00
										 |  |  |   builder.input("Input", data_type); | 
					
						
							|  |  |  |   builder.output("Output", data_type); | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  |   this->set_signature(&signature_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, Context /*context*/) const | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |   const DataType data_type = this->param_type(0).data_type(); | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  |   switch (data_type.category()) { | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |     case DataType::Single: { | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  |       const GVArray &inputs = params.readonly_single_input(0, "Input"); | 
					
						
							|  |  |  |       GMutableSpan outputs = params.uninitialized_single_output(1, "Output"); | 
					
						
							|  |  |  |       inputs.materialize_to_uninitialized(mask, outputs.data()); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  |     case DataType::Vector: { | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  |       const GVVectorArray &inputs = params.readonly_vector_input(0, "Input"); | 
					
						
							|  |  |  |       GVectorArray &outputs = params.vector_output(1, "Output"); | 
					
						
							|  |  |  |       outputs.extend(mask, inputs); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-07 17:32:28 +01:00
										 |  |  | }  // namespace blender::fn::multi_function
 |