Blender  V3.3
type_conversions.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
4 
5 #include "DNA_meshdata_types.h"
6 
8 
9 #include "BLI_color.hh"
10 #include "BLI_math_vector.hh"
11 
12 namespace blender::bke {
13 
14 using fn::MFDataType;
15 
16 template<typename From, typename To, To (*ConversionF)(const From &)>
18 {
19  static const CPPType &from_type = CPPType::get<From>();
20  static const CPPType &to_type = CPPType::get<To>();
21  static const std::string conversion_name = from_type.name() + " to " + to_type.name();
22 
23  static fn::CustomMF_SI_SO<From, To> multi_function{
24  conversion_name.c_str(),
25  /* Use lambda instead of passing #ConversionF directly, because otherwise the compiler won't
26  * inline the function. */
27  [](const From &a) { return ConversionF(a); },
29  static auto convert_single_to_initialized = [](const void *src, void *dst) {
30  *(To *)dst = ConversionF(*(const From *)src);
31  };
32  static auto convert_single_to_uninitialized = [](const void *src, void *dst) {
33  new (dst) To(ConversionF(*(const From *)src));
34  };
35  conversions.add(fn::MFDataType::ForSingle<From>(),
36  fn::MFDataType::ForSingle<To>(),
37  multi_function,
38  convert_single_to_initialized,
39  convert_single_to_uninitialized);
40 }
41 
42 static float2 float_to_float2(const float &a)
43 {
44  return float2(a);
45 }
46 static float3 float_to_float3(const float &a)
47 {
48  return float3(a);
49 }
50 static int32_t float_to_int(const float &a)
51 {
52  return (int32_t)a;
53 }
54 static bool float_to_bool(const float &a)
55 {
56  return a > 0.0f;
57 }
58 static int8_t float_to_int8(const float &a)
59 {
60  return std::clamp(
62 }
63 static ColorGeometry4f float_to_color(const float &a)
64 {
65  return ColorGeometry4f(a, a, a, 1.0f);
66 }
68 {
69  return float_to_color(a).encode();
70 }
71 
73 {
74  return float3(a.x, a.y, 0.0f);
75 }
76 static float float2_to_float(const float2 &a)
77 {
78  return (a.x + a.y) / 2.0f;
79 }
80 static int float2_to_int(const float2 &a)
81 {
82  return (int32_t)((a.x + a.y) / 2.0f);
83 }
84 static bool float2_to_bool(const float2 &a)
85 {
86  return !math::is_zero(a);
87 }
88 static int8_t float2_to_int8(const float2 &a)
89 {
90  return float_to_int8((a.x + a.y) / 2.0f);
91 }
93 {
94  return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f);
95 }
97 {
98  return float2_to_color(a).encode();
99 }
100 
101 static bool float3_to_bool(const float3 &a)
102 {
103  return !math::is_zero(a);
104 }
106 {
107  return float_to_int8((a.x + a.y + a.z) / 3.0f);
108 }
109 static float float3_to_float(const float3 &a)
110 {
111  return (a.x + a.y + a.z) / 3.0f;
112 }
113 static int float3_to_int(const float3 &a)
114 {
115  return (int)((a.x + a.y + a.z) / 3.0f);
116 }
118 {
119  return float2(a);
120 }
122 {
123  return ColorGeometry4f(a.x, a.y, a.z, 1.0f);
124 }
126 {
127  return float3_to_color(a).encode();
128 }
129 
130 static bool int_to_bool(const int32_t &a)
131 {
132  return a > 0;
133 }
134 static int8_t int_to_int8(const int32_t &a)
135 {
136  return std::clamp(
138 }
139 static float int_to_float(const int32_t &a)
140 {
141  return (float)a;
142 }
144 {
145  return float2((float)a);
146 }
148 {
149  return float3((float)a);
150 }
152 {
153  return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
154 }
156 {
157  return int_to_color(a).encode();
158 }
159 
160 static bool int8_to_bool(const int8_t &a)
161 {
162  return a > 0;
163 }
164 static int int8_to_int(const int8_t &a)
165 {
166  return static_cast<int>(a);
167 }
168 static float int8_to_float(const int8_t &a)
169 {
170  return (float)a;
171 }
173 {
174  return float2((float)a);
175 }
177 {
178  return float3((float)a);
179 }
181 {
182  return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f);
183 }
185 {
186  return int8_to_color(a).encode();
187 }
188 
189 static float bool_to_float(const bool &a)
190 {
191  return (bool)a;
192 }
193 static int8_t bool_to_int8(const bool &a)
194 {
195  return static_cast<int8_t>(a);
196 }
197 static int32_t bool_to_int(const bool &a)
198 {
199  return (int32_t)a;
200 }
201 static float2 bool_to_float2(const bool &a)
202 {
203  return (a) ? float2(1.0f) : float2(0.0f);
204 }
205 static float3 bool_to_float3(const bool &a)
206 {
207  return (a) ? float3(1.0f) : float3(0.0f);
208 }
209 static ColorGeometry4f bool_to_color(const bool &a)
210 {
211  return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f);
212 }
214 {
215  return bool_to_color(a).encode();
216 }
217 
218 static bool color_to_bool(const ColorGeometry4f &a)
219 {
220  return rgb_to_grayscale(a) > 0.0f;
221 }
222 static float color_to_float(const ColorGeometry4f &a)
223 {
224  return rgb_to_grayscale(a);
225 }
227 {
228  return (int)rgb_to_grayscale(a);
229 }
231 {
232  return int_to_int8(color_to_int(a));
233 }
235 {
236  return float2(a.r, a.g);
237 }
239 {
240  return float3(a.r, a.g, a.b);
241 }
243 {
244  return a.encode();
245 }
246 
248 {
249  return a.r > 0 || a.g > 0 || a.b > 0;
250 }
252 {
253  return color_to_float(a.decode());
254 }
256 {
257  return color_to_int(a.decode());
258 }
260 {
261  return color_to_int8(a.decode());
262 }
264 {
265  return color_to_float2(a.decode());
266 }
268 {
269  return color_to_float3(a.decode());
270 }
272 {
273  return a.decode();
274 }
275 
277 {
278  DataTypeConversions conversions;
279 
280  add_implicit_conversion<float, float2, float_to_float2>(conversions);
281  add_implicit_conversion<float, float3, float_to_float3>(conversions);
282  add_implicit_conversion<float, int32_t, float_to_int>(conversions);
283  add_implicit_conversion<float, bool, float_to_bool>(conversions);
284  add_implicit_conversion<float, int8_t, float_to_int8>(conversions);
285  add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions);
286  add_implicit_conversion<float, ColorGeometry4b, float_to_byte_color>(conversions);
287 
288  add_implicit_conversion<float2, float3, float2_to_float3>(conversions);
289  add_implicit_conversion<float2, float, float2_to_float>(conversions);
290  add_implicit_conversion<float2, int32_t, float2_to_int>(conversions);
291  add_implicit_conversion<float2, bool, float2_to_bool>(conversions);
292  add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions);
293  add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions);
294  add_implicit_conversion<float2, ColorGeometry4b, float2_to_byte_color>(conversions);
295 
296  add_implicit_conversion<float3, bool, float3_to_bool>(conversions);
297  add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions);
298  add_implicit_conversion<float3, float, float3_to_float>(conversions);
299  add_implicit_conversion<float3, int32_t, float3_to_int>(conversions);
300  add_implicit_conversion<float3, float2, float3_to_float2>(conversions);
301  add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions);
302  add_implicit_conversion<float3, ColorGeometry4b, float3_to_byte_color>(conversions);
303 
304  add_implicit_conversion<int32_t, bool, int_to_bool>(conversions);
305  add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions);
306  add_implicit_conversion<int32_t, float, int_to_float>(conversions);
307  add_implicit_conversion<int32_t, float2, int_to_float2>(conversions);
308  add_implicit_conversion<int32_t, float3, int_to_float3>(conversions);
309  add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions);
310  add_implicit_conversion<int32_t, ColorGeometry4b, int_to_byte_color>(conversions);
311 
312  add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions);
313  add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions);
314  add_implicit_conversion<int8_t, float, int8_to_float>(conversions);
315  add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions);
316  add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions);
317  add_implicit_conversion<int8_t, ColorGeometry4f, int8_to_color>(conversions);
318  add_implicit_conversion<int8_t, ColorGeometry4b, int8_to_byte_color>(conversions);
319 
320  add_implicit_conversion<bool, float, bool_to_float>(conversions);
321  add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions);
322  add_implicit_conversion<bool, int32_t, bool_to_int>(conversions);
323  add_implicit_conversion<bool, float2, bool_to_float2>(conversions);
324  add_implicit_conversion<bool, float3, bool_to_float3>(conversions);
325  add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions);
326  add_implicit_conversion<bool, ColorGeometry4b, bool_to_byte_color>(conversions);
327 
328  add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions);
329  add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions);
330  add_implicit_conversion<ColorGeometry4f, float, color_to_float>(conversions);
331  add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions);
332  add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions);
333  add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions);
334  add_implicit_conversion<ColorGeometry4f, ColorGeometry4b, color_to_byte_color>(conversions);
335 
336  add_implicit_conversion<ColorGeometry4b, bool, byte_color_to_bool>(conversions);
337  add_implicit_conversion<ColorGeometry4b, int8_t, byte_color_to_int8>(conversions);
338  add_implicit_conversion<ColorGeometry4b, float, byte_color_to_float>(conversions);
339  add_implicit_conversion<ColorGeometry4b, int32_t, byte_color_to_int>(conversions);
340  add_implicit_conversion<ColorGeometry4b, float2, byte_color_to_float2>(conversions);
341  add_implicit_conversion<ColorGeometry4b, float3, byte_color_to_float3>(conversions);
342  add_implicit_conversion<ColorGeometry4b, ColorGeometry4f, byte_color_to_color>(conversions);
343 
344  return conversions;
345 }
346 
348 {
349  static const DataTypeConversions conversions = create_implicit_conversions();
350  return conversions;
351 }
352 
354  const CPPType &to_type,
355  const void *from_value,
356  void *to_value) const
357 {
358  if (from_type == to_type) {
359  from_type.copy_construct(from_value, to_value);
360  return;
361  }
362 
365  BLI_assert(functions != nullptr);
366 
367  functions->convert_single_to_uninitialized(from_value, to_value);
368 }
369 
371 {
372  const CPPType &from_type = from_span.type();
373  const CPPType &to_type = to_span.type();
374  BLI_assert(from_span.size() == to_span.size());
375  BLI_assert(this->is_convertible(from_type, to_type));
378  fn::MFParamsBuilder params{*fn, from_span.size()};
379  params.add_readonly_single_input(from_span);
380  to_type.destruct_n(to_span.data(), to_span.size());
381  params.add_uninitialized_single_output(to_span);
383  fn->call_auto(IndexRange(from_span.size()), params, context);
384 }
385 
387  private:
388  GVArray varray_;
389  const CPPType &from_type_;
390  ConversionFunctions old_to_new_conversions_;
391 
392  public:
394  const CPPType &to_type,
395  const DataTypeConversions &conversions)
396  : GVArrayImpl(to_type, varray.size()), varray_(std::move(varray)), from_type_(varray_.type())
397  {
398  old_to_new_conversions_ = *conversions.get_conversion_functions(from_type_, to_type);
399  }
400 
401  private:
402  void get(const int64_t index, void *r_value) const override
403  {
404  BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
405  varray_.get(index, buffer);
406  old_to_new_conversions_.convert_single_to_initialized(buffer, r_value);
407  from_type_.destruct(buffer);
408  }
409 
410  void get_to_uninitialized(const int64_t index, void *r_value) const override
411  {
412  BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
413  varray_.get(index, buffer);
414  old_to_new_conversions_.convert_single_to_uninitialized(buffer, r_value);
415  from_type_.destruct(buffer);
416  }
417 };
418 
420  private:
421  GVMutableArray varray_;
422  const CPPType &from_type_;
423  ConversionFunctions old_to_new_conversions_;
424  ConversionFunctions new_to_old_conversions_;
425 
426  public:
428  const CPPType &to_type,
429  const DataTypeConversions &conversions)
430  : GVMutableArrayImpl(to_type, varray.size()),
431  varray_(std::move(varray)),
432  from_type_(varray_.type())
433  {
434  old_to_new_conversions_ = *conversions.get_conversion_functions(from_type_, to_type);
435  new_to_old_conversions_ = *conversions.get_conversion_functions(to_type, from_type_);
436  }
437 
438  private:
439  void get(const int64_t index, void *r_value) const override
440  {
441  BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
442  varray_.get(index, buffer);
443  old_to_new_conversions_.convert_single_to_initialized(buffer, r_value);
444  from_type_.destruct(buffer);
445  }
446 
447  void get_to_uninitialized(const int64_t index, void *r_value) const override
448  {
449  BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
450  varray_.get(index, buffer);
451  old_to_new_conversions_.convert_single_to_uninitialized(buffer, r_value);
452  from_type_.destruct(buffer);
453  }
454 
455  void set_by_move(const int64_t index, void *value) override
456  {
457  BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
458  new_to_old_conversions_.convert_single_to_uninitialized(value, buffer);
459  varray_.set_by_relocate(index, buffer);
460  }
461 };
462 
464 {
465  const CPPType &from_type = varray.type();
466  if (from_type == to_type) {
467  return varray;
468  }
469  if (!this->is_convertible(from_type, to_type)) {
470  return {};
471  }
472  return GVArray::For<GVArray_For_ConvertedGVArray>(std::move(varray), to_type, *this);
473 }
474 
476  const CPPType &to_type) const
477 {
478  const CPPType &from_type = varray.type();
479  if (from_type == to_type) {
480  return varray;
481  }
482  if (!this->is_convertible(from_type, to_type)) {
483  return {};
484  }
485  return GVMutableArray::For<GVMutableArray_For_ConvertedGVMutableArray>(
486  std::move(varray), to_type, *this);
487 }
488 
490 {
491  const CPPType &from_type = field.cpp_type();
492  if (from_type == to_type) {
493  return field;
494  }
495  if (!this->is_convertible(from_type, to_type)) {
496  return {};
497  }
498  const fn::MultiFunction &fn =
501  return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})};
502 }
503 
504 } // namespace blender::bke
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
MINLINE float rgb_to_grayscale(const float rgb[3])
long functions
StringRefNull name() const
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
ColorSceneLinearByteEncoded4b< Alpha > encode() const
Definition: BLI_color.hh:172
const CPPType & type() const
const CPPType & type() const
int64_t size() const
const CPPType & type() const
void get(int64_t index, void *r_value) const
const CPPType & type() const
void set_by_relocate(int64_t index, void *value)
void convert_to_uninitialized(const CPPType &from_type, const CPPType &to_type, const void *from_value, void *to_value) const
const ConversionFunctions * get_conversion_functions(fn::MFDataType from, fn::MFDataType to) const
void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const
void add(fn::MFDataType from_type, fn::MFDataType to_type, const fn::MultiFunction &fn, void(*convert_single_to_initialized)(const void *src, void *dst), void(*convert_single_to_uninitialized)(const void *src, void *dst))
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
const fn::MultiFunction * get_conversion_multi_function(fn::MFDataType from, fn::MFDataType to) const
GVArray try_convert(GVArray varray, const CPPType &to_type) const
GVArray_For_ConvertedGVArray(GVArray varray, const CPPType &to_type, const DataTypeConversions &conversions)
GVMutableArray_For_ConvertedGVMutableArray(GVMutableArray varray, const CPPType &to_type, const DataTypeConversions &conversions)
const CPPType & cpp_type() const
Definition: FN_field.hh:122
void call_auto(IndexMask mask, MFParams params, MFContext context) const
SyclQueue void void * src
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_global float * buffer
static unsigned a[3]
Definition: RandGen.cpp:78
static float3 color_to_float3(const ColorGeometry4f &a)
static float bool_to_float(const bool &a)
static ColorGeometry4b float_to_byte_color(const float &a)
static ColorGeometry4f float_to_color(const float &a)
static ColorGeometry4f byte_color_to_color(const ColorGeometry4b &a)
static int8_t float_to_int8(const float &a)
static float color_to_float(const ColorGeometry4f &a)
static float2 float_to_float2(const float &a)
static ColorGeometry4b int_to_byte_color(const int32_t &a)
static bool float_to_bool(const float &a)
static void add_implicit_conversion(DataTypeConversions &conversions)
static int8_t float2_to_int8(const float2 &a)
const DataTypeConversions & get_implicit_type_conversions()
static float float3_to_float(const float3 &a)
static float3 float2_to_float3(const float2 &a)
static float float2_to_float(const float2 &a)
static float2 bool_to_float2(const bool &a)
static int8_t bool_to_int8(const bool &a)
static ColorGeometry4b float3_to_byte_color(const float3 &a)
static float3 int8_to_float3(const int8_t &a)
static int32_t color_to_int(const ColorGeometry4f &a)
static float3 float_to_float3(const float &a)
static ColorGeometry4f float3_to_color(const float3 &a)
static int float2_to_int(const float2 &a)
static bool byte_color_to_bool(const ColorGeometry4b &a)
static bool float2_to_bool(const float2 &a)
static bool color_to_bool(const ColorGeometry4f &a)
static ColorGeometry4f float2_to_color(const float2 &a)
static float2 int_to_float2(const int32_t &a)
static float int8_to_float(const int8_t &a)
static DataTypeConversions create_implicit_conversions()
static bool float3_to_bool(const float3 &a)
static float2 int8_to_float2(const int8_t &a)
static bool int8_to_bool(const int8_t &a)
static float3 int_to_float3(const int32_t &a)
static float byte_color_to_float(const ColorGeometry4b &a)
static ColorGeometry4b float2_to_byte_color(const float2 &a)
static int32_t byte_color_to_int(const ColorGeometry4b &a)
static int32_t bool_to_int(const bool &a)
static int float3_to_int(const float3 &a)
static float int_to_float(const int32_t &a)
static ColorGeometry4f int_to_color(const int32_t &a)
static ColorGeometry4b bool_to_byte_color(const bool &a)
static int32_t float_to_int(const float &a)
static bool int_to_bool(const int32_t &a)
static ColorGeometry4f int8_to_color(const int8_t &a)
static int8_t byte_color_to_int8(const ColorGeometry4b &a)
static float2 float3_to_float2(const float3 &a)
static int8_t int_to_int8(const int32_t &a)
static float2 byte_color_to_float2(const ColorGeometry4b &a)
static int8_t float3_to_int8(const float3 &a)
static ColorGeometry4b int8_to_byte_color(const int8_t &a)
static ColorGeometry4b color_to_byte_color(const ColorGeometry4f &a)
static float2 color_to_float2(const ColorGeometry4f &a)
static int int8_to_int(const int8_t &a)
static int8_t color_to_int8(const ColorGeometry4f &a)
static ColorGeometry4f bool_to_color(const bool &a)
static float3 byte_color_to_float3(const ColorGeometry4b &a)
static float3 bool_to_float3(const bool &a)
static Type to_type(const eGPUType type)
T clamp(const T &a, const T &min, const T &max)
bool is_zero(const T &a)
vec_base< float, 3 > float3
vec_base< float, 2 > float2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition: BLI_color.hh:346
#define min(a, b)
Definition: sort.c:35
__int64 int64_t
Definition: stdint.h:89
signed int int32_t
Definition: stdint.h:77
signed char int8_t
Definition: stdint.h:75
void(* convert_single_to_uninitialized)(const void *src, void *dst)
void(* convert_single_to_initialized)(const void *src, void *dst)
float max