| 
									
										
										
										
											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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | namespace blender::fn { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  |   MFSignatureBuilder signature{"Constant"}; | 
					
						
							|  |  |  |   signature.single_output("Value", type); | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   signature_ = signature.build(); | 
					
						
							|  |  |  |   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_) { | 
					
						
							|  |  |  |     signature_.param_types[0].data_type().single_type().destruct((void *)value_); | 
					
						
							|  |  |  |     MEM_freeN((void *)value_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | void CustomMF_GenericConstant::call(IndexMask mask, | 
					
						
							|  |  |  |                                     MFParams params, | 
					
						
							|  |  |  |                                     MFContext UNUSED(context)) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   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
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-28 13:13:52 +02: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(); | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  |   MFSignatureBuilder signature{"Constant Vector"}; | 
					
						
							|  |  |  |   signature.vector_output("Value", type); | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   signature_ = signature.build(); | 
					
						
							|  |  |  |   this->set_signature(&signature_); | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CustomMF_GenericConstantArray::call(IndexMask mask, | 
					
						
							|  |  |  |                                          MFParams params, | 
					
						
							|  |  |  |                                          MFContext UNUSED(context)) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   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_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  | CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<MFDataType> input_types, | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |                                                Span<MFDataType> output_types) | 
					
						
							|  |  |  |     : output_amount_(output_types.size()) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  |   MFSignatureBuilder signature{"Default Output"}; | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |   for (MFDataType data_type : input_types) { | 
					
						
							|  |  |  |     signature.input("Input", data_type); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (MFDataType data_type : output_types) { | 
					
						
							|  |  |  |     signature.output("Output", data_type); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-03-22 11:57:24 +01:00
										 |  |  |   signature_ = signature.build(); | 
					
						
							|  |  |  |   this->set_signature(&signature_); | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   for (int param_index : this->param_indices()) { | 
					
						
							| 
									
										
										
										
											2020-07-16 13:38:23 +02:00
										 |  |  |     MFParamType param_type = this->param_type(param_index); | 
					
						
							|  |  |  |     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
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  | CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type) | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-11-21 12:37:04 +01:00
										 |  |  |   MFSignatureBuilder signature{"Copy"}; | 
					
						
							| 
									
										
										
										
											2021-09-09 12:54:20 +02:00
										 |  |  |   signature.input("Input", data_type); | 
					
						
							|  |  |  |   signature.output("Output", data_type); | 
					
						
							|  |  |  |   signature_ = signature.build(); | 
					
						
							|  |  |  |   this->set_signature(&signature_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const MFDataType data_type = this->param_type(0).data_type(); | 
					
						
							|  |  |  |   switch (data_type.category()) { | 
					
						
							|  |  |  |     case MFDataType::Single: { | 
					
						
							|  |  |  |       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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     case MFDataType::Vector: { | 
					
						
							|  |  |  |       const GVVectorArray &inputs = params.readonly_vector_input(0, "Input"); | 
					
						
							|  |  |  |       GVectorArray &outputs = params.vector_output(1, "Output"); | 
					
						
							|  |  |  |       outputs.extend(mask, inputs); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 19:34:35 +02:00
										 |  |  | }  // namespace blender::fn
 |