Blender  V2.93
FN_multi_function_builder.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
25 #include <functional>
26 
27 #include "FN_multi_function.hh"
28 
29 namespace blender::fn {
30 
39 template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunction {
40  private:
41  using FunctionT = std::function<void(IndexMask, const VArray<In1> &, MutableSpan<Out1>)>;
42  FunctionT function_;
43  MFSignature signature_;
44 
45  public:
46  CustomMF_SI_SO(StringRef name, FunctionT function) : function_(std::move(function))
47  {
49  signature.single_input<In1>("In1");
50  signature.single_output<Out1>("Out1");
51  signature_ = signature.build();
52  this->set_signature(&signature_);
53  }
54 
55  template<typename ElementFuncT>
56  CustomMF_SI_SO(StringRef name, ElementFuncT element_fn)
58  {
59  }
60 
61  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
62  {
63  return [=](IndexMask mask, const VArray<In1> &in1, MutableSpan<Out1> out1) {
64  /* Devirtualization results in a 2-3x speedup for some simple functions. */
65  devirtualize_varray(in1, [&](const auto &in1) {
66  mask.foreach_index(
67  [&](int i) { new (static_cast<void *>(&out1[i])) Out1(element_fn(in1[i])); });
68  });
69  };
70  }
71 
73  {
74  const VArray<In1> &in1 = params.readonly_single_input<In1>(0);
75  MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(1);
76  function_(mask, in1, out1);
77  }
78 };
79 
86 template<typename In1, typename In2, typename Out1>
88  private:
89  using FunctionT =
90  std::function<void(IndexMask, const VArray<In1> &, const VArray<In2> &, MutableSpan<Out1>)>;
91  FunctionT function_;
92  MFSignature signature_;
93 
94  public:
95  CustomMF_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function))
96  {
98  signature.single_input<In1>("In1");
99  signature.single_input<In2>("In2");
100  signature.single_output<Out1>("Out1");
101  signature_ = signature.build();
102  this->set_signature(&signature_);
103  }
104 
105  template<typename ElementFuncT>
106  CustomMF_SI_SI_SO(StringRef name, ElementFuncT element_fn)
108  {
109  }
110 
111  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
112  {
113  return [=](IndexMask mask,
114  const VArray<In1> &in1,
115  const VArray<In2> &in2,
116  MutableSpan<Out1> out1) {
117  /* Devirtualization results in a 2-3x speedup for some simple functions. */
118  devirtualize_varray2(in1, in2, [&](const auto &in1, const auto &in2) {
119  mask.foreach_index(
120  [&](int i) { new (static_cast<void *>(&out1[i])) Out1(element_fn(in1[i], in2[i])); });
121  });
122  };
123  }
124 
126  {
127  const VArray<In1> &in1 = params.readonly_single_input<In1>(0);
128  const VArray<In2> &in2 = params.readonly_single_input<In2>(1);
129  MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(2);
130  function_(mask, in1, in2, out1);
131  }
132 };
133 
141 template<typename In1, typename In2, typename In3, typename Out1>
143  private:
144  using FunctionT = std::function<void(IndexMask,
145  const VArray<In1> &,
146  const VArray<In2> &,
147  const VArray<In3> &,
149  FunctionT function_;
150  MFSignature signature_;
151 
152  public:
153  CustomMF_SI_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function))
154  {
156  signature.single_input<In1>("In1");
157  signature.single_input<In2>("In2");
158  signature.single_input<In3>("In3");
159  signature.single_output<Out1>("Out1");
160  signature_ = signature.build();
161  this->set_signature(&signature_);
162  }
163 
164  template<typename ElementFuncT>
165  CustomMF_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn)
167  {
168  }
169 
170  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
171  {
172  return [=](IndexMask mask,
173  const VArray<In1> &in1,
174  const VArray<In2> &in2,
175  const VArray<In3> &in3,
176  MutableSpan<Out1> out1) {
177  mask.foreach_index([&](int i) {
178  new (static_cast<void *>(&out1[i])) Out1(element_fn(in1[i], in2[i], in3[i]));
179  });
180  };
181  }
182 
184  {
185  const VArray<In1> &in1 = params.readonly_single_input<In1>(0);
186  const VArray<In2> &in2 = params.readonly_single_input<In2>(1);
187  const VArray<In3> &in3 = params.readonly_single_input<In3>(2);
188  MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(3);
189  function_(mask, in1, in2, in3, out1);
190  }
191 };
192 
201 template<typename In1, typename In2, typename In3, typename In4, typename Out1>
203  private:
204  using FunctionT = std::function<void(IndexMask,
205  const VArray<In1> &,
206  const VArray<In2> &,
207  const VArray<In3> &,
208  const VArray<In4> &,
210  FunctionT function_;
211  MFSignature signature_;
212 
213  public:
214  CustomMF_SI_SI_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function))
215  {
217  signature.single_input<In1>("In1");
218  signature.single_input<In2>("In2");
219  signature.single_input<In3>("In3");
220  signature.single_input<In4>("In4");
221  signature.single_output<Out1>("Out1");
222  signature_ = signature.build();
223  this->set_signature(&signature_);
224  }
225 
226  template<typename ElementFuncT>
227  CustomMF_SI_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn)
229  {
230  }
231 
232  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
233  {
234  return [=](IndexMask mask,
235  const VArray<In1> &in1,
236  const VArray<In2> &in2,
237  const VArray<In3> &in3,
238  const VArray<In4> &in4,
239  MutableSpan<Out1> out1) {
240  mask.foreach_index([&](int i) {
241  new (static_cast<void *>(&out1[i])) Out1(element_fn(in1[i], in2[i], in3[i], in4[i]));
242  });
243  };
244  }
245 
247  {
248  const VArray<In1> &in1 = params.readonly_single_input<In1>(0);
249  const VArray<In2> &in2 = params.readonly_single_input<In2>(1);
250  const VArray<In3> &in3 = params.readonly_single_input<In3>(2);
251  const VArray<In4> &in4 = params.readonly_single_input<In4>(3);
252  MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(4);
253  function_(mask, in1, in2, in3, in4, out1);
254  }
255 };
256 
261 template<typename Mut1> class CustomMF_SM : public MultiFunction {
262  private:
263  using FunctionT = std::function<void(IndexMask, MutableSpan<Mut1>)>;
264  FunctionT function_;
265  MFSignature signature_;
266 
267  public:
268  CustomMF_SM(StringRef name, FunctionT function) : function_(std::move(function))
269  {
271  signature.single_mutable<Mut1>("Mut1");
272  signature_ = signature.build();
273  this->set_signature(&signature_);
274  }
275 
276  template<typename ElementFuncT>
277  CustomMF_SM(StringRef name, ElementFuncT element_fn)
279  {
280  }
281 
282  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
283  {
284  return [=](IndexMask mask, MutableSpan<Mut1> mut1) {
285  mask.foreach_index([&](int i) { element_fn(mut1[i]); });
286  };
287  }
288 
290  {
291  MutableSpan<Mut1> mut1 = params.single_mutable<Mut1>(0);
292  function_(mask, mut1);
293  }
294 };
295 
299 template<typename From, typename To> class CustomMF_Convert : public MultiFunction {
300  public:
302  {
304  this->set_signature(&signature);
305  }
306 
308  {
309  std::string name = CPPType::get<From>().name() + " to " + CPPType::get<To>().name();
310  MFSignatureBuilder signature{std::move(name)};
311  signature.single_input<From>("Input");
312  signature.single_output<To>("Output");
313  return signature.build();
314  }
315 
317  {
318  const VArray<From> &inputs = params.readonly_single_input<From>(0);
319  MutableSpan<To> outputs = params.uninitialized_single_output<To>(1);
320 
321  for (int64_t i : mask) {
322  new (static_cast<void *>(&outputs[i])) To(inputs[i]);
323  }
324  }
325 };
326 
332  private:
333  const CPPType &type_;
334  const void *value_;
335  MFSignature signature_;
336 
337  template<typename T> friend class CustomMF_Constant;
338 
339  public:
340  CustomMF_GenericConstant(const CPPType &type, const void *value);
341  void call(IndexMask mask, MFParams params, MFContext context) const override;
342  uint64_t hash() const override;
343  bool equals(const MultiFunction &other) const override;
344 };
345 
351  private:
352  GSpan array_;
353  MFSignature signature_;
354 
355  public:
357  void call(IndexMask mask, MFParams params, MFContext context) const override;
358 };
359 
363 template<typename T> class CustomMF_Constant : public MultiFunction {
364  private:
365  T value_;
366  MFSignature signature_;
367 
368  public:
369  template<typename U> CustomMF_Constant(U &&value) : value_(std::forward<U>(value))
370  {
371  MFSignatureBuilder signature{"Constant"};
372  std::stringstream ss;
373  ss << value_;
374  signature.single_output<T>(ss.str());
375  signature_ = signature.build();
376  this->set_signature(&signature_);
377  }
378 
380  {
381  MutableSpan<T> output = params.uninitialized_single_output<T>(0);
382  mask.foreach_index([&](int i) { new (&output[i]) T(value_); });
383  }
384 
385  uint64_t hash() const override
386  {
387  return get_default_hash(value_);
388  }
389 
390  bool equals(const MultiFunction &other) const override
391  {
392  const CustomMF_Constant *other1 = dynamic_cast<const CustomMF_Constant *>(&other);
393  if (other1 != nullptr) {
394  return value_ == other1->value_;
395  }
396  const CustomMF_GenericConstant *other2 = dynamic_cast<const CustomMF_GenericConstant *>(
397  &other);
398  if (other2 != nullptr) {
399  const CPPType &type = CPPType::get<T>();
400  if (type == other2->type_) {
401  return type.is_equal(static_cast<const void *>(&value_), other2->value_);
402  }
403  }
404  return false;
405  }
406 };
407 
409  private:
410  int output_amount_;
411  MFSignature signature_;
412 
413  public:
415  Span<MFDataType> input_types,
416  Span<MFDataType> output_types);
417  void call(IndexMask mask, MFParams params, MFContext context) const override;
418 };
419 
420 } // namespace blender::fn
#define UNUSED(x)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
unsigned int U
Definition: btGjkEpa3.h:78
#define output
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
bool equals(const MultiFunction &other) const override
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
CustomMF_DefaultOutput(StringRef name, Span< MFDataType > input_types, Span< MFDataType > output_types)
void call(IndexMask mask, MFParams params, MFContext context) const override
void call(IndexMask mask, MFParams params, MFContext context) const override
CustomMF_GenericConstant(const CPPType &type, const void *value)
void call(IndexMask mask, MFParams params, MFContext context) const override
bool equals(const MultiFunction &other) const override
CustomMF_SI_SI_SI_SI_SO(StringRef name, FunctionT function)
static FunctionT create_function(ElementFuncT element_fn)
CustomMF_SI_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn)
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
CustomMF_SI_SI_SI_SO(StringRef name, FunctionT function)
CustomMF_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn)
static FunctionT create_function(ElementFuncT element_fn)
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
CustomMF_SI_SI_SO(StringRef name, FunctionT function)
CustomMF_SI_SI_SO(StringRef name, ElementFuncT element_fn)
static FunctionT create_function(ElementFuncT element_fn)
static FunctionT create_function(ElementFuncT element_fn)
CustomMF_SI_SO(StringRef name, ElementFuncT element_fn)
CustomMF_SI_SO(StringRef name, FunctionT function)
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
CustomMF_SM(StringRef name, ElementFuncT element_fn)
static FunctionT create_function(ElementFuncT element_fn)
CustomMF_SM(StringRef name, FunctionT function)
StringRefNull name() const
void set_signature(const MFSignature *signature)
const MFSignature & signature() const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define T
void devirtualize_varray(const VArray< T > &varray, const Func &func, bool enable=true)
void devirtualize_varray2(const VArray< T1 > &varray1, const VArray< T2 > &varray2, const Func &func, bool enable=true)
uint64_t get_default_hash(const T &v)
Definition: BLI_hash.hh:209
static bNodeSocketTemplate outputs[]
static bNodeSocketTemplate inputs[]
struct SELECTID_Context context
Definition: select_engine.c:47
__int64 int64_t
Definition: stdint.h:92
unsigned __int64 uint64_t
Definition: stdint.h:93
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)