Blender V4.3
type_conversions.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
8
9#include "BLI_color.hh"
10#include "BLI_math_euler.hh"
12#include "BLI_math_vector.hh"
13
14namespace blender::bke {
15
16using mf::DataType;
17
18template<typename From, typename To, To (*ConversionF)(const From &)>
20{
21 static const CPPType &from_type = CPPType::get<From>();
22 static const CPPType &to_type = CPPType::get<To>();
23 static const std::string conversion_name = from_type.name() + " to " + to_type.name();
24
25 static auto multi_function = mf::build::SI1_SO<From, To>(
26 conversion_name.c_str(),
27 /* Use lambda instead of passing #ConversionF directly, because otherwise the compiler won't
28 * inline the function. */
29 [](const From &a) { return ConversionF(a); },
30 mf::build::exec_presets::AllSpanOrSingle());
31 static auto convert_single_to_initialized = [](const void *src, void *dst) {
32 *(To *)dst = ConversionF(*(const From *)src);
33 };
34 static auto convert_single_to_uninitialized = [](const void *src, void *dst) {
35 new (dst) To(ConversionF(*(const From *)src));
36 };
37 conversions.add(mf::DataType::ForSingle<From>(),
38 mf::DataType::ForSingle<To>(),
39 multi_function,
40 convert_single_to_initialized,
41 convert_single_to_uninitialized);
42}
43
44static float2 float_to_float2(const float &a)
45{
46 return float2(a);
47}
48static float3 float_to_float3(const float &a)
49{
50 return float3(a);
51}
52static int32_t float_to_int(const float &a)
53{
54 return int32_t(a);
55}
56static int2 float_to_int2(const float &a)
57{
58 return int2(a);
59}
60static bool float_to_bool(const float &a)
61{
62 return a > 0.0f;
63}
64static int8_t float_to_int8(const float &a)
65{
66 return std::clamp(
67 a, float(std::numeric_limits<int8_t>::min()), float(std::numeric_limits<int8_t>::max()));
68}
69static ColorGeometry4f float_to_color(const float &a)
70{
71 return ColorGeometry4f(a, a, a, 1.0f);
72}
74{
75 return float_to_color(a).encode();
76}
78{
80}
81
83{
84 return float3(a.x, a.y, 0.0f);
85}
86static float float2_to_float(const float2 &a)
87{
88 return (a.x + a.y) / 2.0f;
89}
90static int float2_to_int(const float2 &a)
91{
92 return int32_t((a.x + a.y) / 2.0f);
93}
94static int2 float2_to_int2(const float2 &a)
95{
96 return int2(a.x, a.y);
97}
98static bool float2_to_bool(const float2 &a)
99{
100 return !math::is_zero(a);
101}
103{
104 return float_to_int8((a.x + a.y) / 2.0f);
105}
107{
108 return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f);
109}
111{
112 return float2_to_color(a).encode();
113}
114
115static bool float3_to_bool(const float3 &a)
116{
117 return !math::is_zero(a);
118}
120{
121 return float_to_int8((a.x + a.y + a.z) / 3.0f);
122}
123static float float3_to_float(const float3 &a)
124{
125 return (a.x + a.y + a.z) / 3.0f;
126}
127static int float3_to_int(const float3 &a)
128{
129 return int((a.x + a.y + a.z) / 3.0f);
130}
131static int2 float3_to_int2(const float3 &a)
132{
133 return int2(a.x, a.y);
134}
136{
137 return float2(a);
138}
140{
141 return ColorGeometry4f(a.x, a.y, a.z, 1.0f);
142}
144{
145 return float3_to_color(a).encode();
146}
147
148static bool int_to_bool(const int32_t &a)
149{
150 return a > 0;
151}
152static int8_t int_to_int8(const int32_t &a)
153{
154 return std::clamp(
155 a, int(std::numeric_limits<int8_t>::min()), int(std::numeric_limits<int8_t>::max()));
156}
157static int2 int_to_int2(const int32_t &a)
158{
159 return int2(a);
160}
161static float int_to_float(const int32_t &a)
162{
163 return float(a);
164}
166{
167 return float2(float(a));
168}
170{
171 return float3(float(a));
172}
174{
175 return ColorGeometry4f(float(a), float(a), float(a), 1.0f);
176}
178{
179 return int_to_color(a).encode();
180}
181
182static bool int2_to_bool(const int2 &a)
183{
184 return !math::is_zero(a);
185}
186static float2 int2_to_float2(const int2 &a)
187{
188 return float2(a);
189}
190static int int2_to_int(const int2 &a)
191{
192 return math::midpoint(a.x, a.y);
193}
194static int8_t int2_to_int8(const int2 &a)
195{
196 return int_to_int8(int2_to_int(a));
197}
198static float int2_to_float(const int2 &a)
199{
200 return float2_to_float(float2(a));
201}
202static float3 int2_to_float3(const int2 &a)
203{
204 return float3(float(a.x), float(a.y), 0.0f);
205}
207{
208 return ColorGeometry4f(float(a.x), float(a.y), 0.0f, 1.0f);
209}
211{
212 return int2_to_color(a).encode();
213}
214
215static bool int8_to_bool(const int8_t &a)
216{
217 return a > 0;
218}
219static int int8_to_int(const int8_t &a)
220{
221 return int(a);
222}
223static int2 int8_to_int2(const int8_t &a)
224{
225 return int2(a);
226}
227static float int8_to_float(const int8_t &a)
228{
229 return float(a);
230}
232{
233 return float2(float(a));
234}
236{
237 return float3(float(a));
238}
243
245{
246 return ColorGeometry4f(float(a), float(a), float(a), 1.0f);
247}
249{
250 return int8_to_color(a).encode();
251}
252
253static float bool_to_float(const bool &a)
254{
255 return bool(a);
256}
257static int8_t bool_to_int8(const bool &a)
258{
259 return int8_t(a);
260}
261static int32_t bool_to_int(const bool &a)
262{
263 return int32_t(a);
264}
265static int2 bool_to_int2(const bool &a)
266{
267 return int2(a);
268}
269static float2 bool_to_float2(const bool &a)
270{
271 return (a) ? float2(1.0f) : float2(0.0f);
272}
273static float3 bool_to_float3(const bool &a)
274{
275 return (a) ? float3(1.0f) : float3(0.0f);
276}
277static ColorGeometry4f bool_to_color(const bool &a)
278{
279 return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f);
280}
282{
283 return bool_to_color(a).encode();
284}
285
286static bool color_to_bool(const ColorGeometry4f &a)
287{
288 return rgb_to_grayscale(a) > 0.0f;
289}
290static float color_to_float(const ColorGeometry4f &a)
291{
292 return rgb_to_grayscale(a);
293}
295{
296 return int(rgb_to_grayscale(a));
297}
299{
300 return int2(a.r, a.g);
301}
303{
304 return int_to_int8(color_to_int(a));
305}
307{
308 return float2(a.r, a.g);
309}
311{
312 return float3(a.r, a.g, a.b);
313}
315{
316 return a.encode();
317}
318
320{
321 return a.r > 0 || a.g > 0 || a.b > 0;
322}
324{
325 return color_to_float(a.decode());
326}
328{
329 return color_to_int(a.decode());
330}
332{
333 return int2(a.r, a.g);
334}
336{
337 return color_to_int8(a.decode());
338}
340{
341 return color_to_float2(a.decode());
342}
344{
345 return color_to_float3(a.decode());
346}
348{
349 return a.decode();
350}
351
356
358{
359 return float3(math::to_euler(a).xyz());
360}
361
366
368{
369 DataTypeConversions conversions;
370
380
389
399
408
417
426
435
444
453
455
458
459 return conversions;
460}
461
463{
464 static const DataTypeConversions conversions = create_implicit_conversions();
465 return conversions;
466}
467
469 const CPPType &to_type,
470 const void *from_value,
471 void *to_value) const
472{
473 if (from_type == to_type) {
474 from_type.copy_construct(from_value, to_value);
475 return;
476 }
477
478 const ConversionFunctions *functions = this->get_conversion_functions(
479 DataType::ForSingle(from_type), DataType::ForSingle(to_type));
480 BLI_assert(functions != nullptr);
481
482 functions->convert_single_to_uninitialized(from_value, to_value);
483}
484
486 const mf::MultiFunction &fn,
487 const IndexMask &mask,
488 GMutableSpan to)
489{
490 mf::ParamsBuilder params{fn, &mask};
491 params.add_readonly_single_input(from);
492 params.add_uninitialized_single_output(to);
493 mf::ContextBuilder context;
494 fn.call_auto(mask, params, context);
495}
496
498 const mf::MultiFunction &fn,
499 GMutableSpan to)
500{
501 call_convert_to_uninitialized_fn(from, fn, IndexMask(from.size()), to);
502}
503
505{
506 const CPPType &from_type = from_span.type();
507 const CPPType &to_type = to_span.type();
508
509 BLI_assert(from_span.size() == to_span.size());
510 BLI_assert(this->is_convertible(from_type, to_type));
511
513 DataType::ForSingle(to_type));
514
515 to_type.destruct_n(to_span.data(), to_span.size());
516 call_convert_to_uninitialized_fn(GVArray::ForSpan(from_span), *fn, to_span);
517}
518
520 private:
521 GVArray varray_;
522 const CPPType &from_type_;
523 ConversionFunctions old_to_new_conversions_;
524
525 public:
527 const CPPType &to_type,
528 const DataTypeConversions &conversions)
529 : GVArrayImpl(to_type, varray.size()), varray_(std::move(varray)), from_type_(varray_.type())
530 {
531 old_to_new_conversions_ = *conversions.get_conversion_functions(from_type_, to_type);
532 }
533
534 private:
535 void get(const int64_t index, void *r_value) const override
536 {
537 BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
538 varray_.get(index, buffer);
539 old_to_new_conversions_.convert_single_to_initialized(buffer, r_value);
540 from_type_.destruct(buffer);
541 }
542
543 void get_to_uninitialized(const int64_t index, void *r_value) const override
544 {
545 BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
546 varray_.get(index, buffer);
547 old_to_new_conversions_.convert_single_to_uninitialized(buffer, r_value);
548 from_type_.destruct(buffer);
549 }
550
551 void materialize(const IndexMask &mask, void *dst) const override
552 {
553 type_->destruct_n(dst, mask.min_array_size());
554 this->materialize_to_uninitialized(mask, dst);
555 }
556
557 void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override
558 {
560 *old_to_new_conversions_.multi_function,
561 mask,
562 {this->type(), dst, mask.min_array_size()});
563 }
564};
565
567 private:
568 GVMutableArray varray_;
569 const CPPType &from_type_;
570 ConversionFunctions old_to_new_conversions_;
571 ConversionFunctions new_to_old_conversions_;
572
573 public:
575 const CPPType &to_type,
576 const DataTypeConversions &conversions)
577 : GVMutableArrayImpl(to_type, varray.size()),
578 varray_(std::move(varray)),
579 from_type_(varray_.type())
580 {
581 old_to_new_conversions_ = *conversions.get_conversion_functions(from_type_, to_type);
582 new_to_old_conversions_ = *conversions.get_conversion_functions(to_type, from_type_);
583 }
584
585 private:
586 void get(const int64_t index, void *r_value) const override
587 {
588 BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
589 varray_.get(index, buffer);
590 old_to_new_conversions_.convert_single_to_initialized(buffer, r_value);
591 from_type_.destruct(buffer);
592 }
593
594 void get_to_uninitialized(const int64_t index, void *r_value) const override
595 {
596 BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
597 varray_.get(index, buffer);
598 old_to_new_conversions_.convert_single_to_uninitialized(buffer, r_value);
599 from_type_.destruct(buffer);
600 }
601
602 void set_by_move(const int64_t index, void *value) override
603 {
604 BUFFER_FOR_CPP_TYPE_VALUE(from_type_, buffer);
605 new_to_old_conversions_.convert_single_to_uninitialized(value, buffer);
606 varray_.set_by_relocate(index, buffer);
607 }
608
609 void materialize(const IndexMask &mask, void *dst) const override
610 {
611 type_->destruct_n(dst, mask.min_array_size());
612 this->materialize_to_uninitialized(mask, dst);
613 }
614
615 void materialize_to_uninitialized(const IndexMask &mask, void *dst) const override
616 {
618 *old_to_new_conversions_.multi_function,
619 mask,
620 {this->type(), dst, mask.min_array_size()});
621 }
622};
623
625{
626 const CPPType &from_type = varray.type();
627 if (from_type == to_type) {
628 return varray;
629 }
630 if (!this->is_convertible(from_type, to_type)) {
631 return {};
632 }
633 return GVArray::For<GVArray_For_ConvertedGVArray>(std::move(varray), to_type, *this);
634}
635
637 const CPPType &to_type) const
638{
639 const CPPType &from_type = varray.type();
640 if (from_type == to_type) {
641 return varray;
642 }
643 if (!this->is_convertible(from_type, to_type)) {
644 return {};
645 }
647 std::move(varray), to_type, *this);
648}
649
651{
652 const CPPType &from_type = field.cpp_type();
653 if (from_type == to_type) {
654 return field;
655 }
656 if (!this->is_convertible(from_type, to_type)) {
657 return {};
658 }
660 mf::DataType::ForSingle(from_type), mf::DataType::ForSingle(to_type));
661 return {fn::FieldOperation::Create(fn, {std::move(field)})};
662}
663
664} // namespace blender::bke
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
MINLINE float rgb_to_grayscale(const float rgb[3])
void destruct_n(void *ptr, int64_t n) const
StringRefNull name() const
static const CPPType & get()
void copy_construct(const void *src, void *dst) const
void destruct(void *ptr) const
ChannelStorageType r
Definition BLI_color.hh:88
ColorSceneLinearByteEncoded4b< Alpha > encode() const
Definition BLI_color.hh:163
const CPPType & type() const
const CPPType & type() const
int64_t size() const
void get(int64_t index, void *r_value) const
static GVArray For(Args &&...args)
static GVArray ForSpan(GSpan span)
static GVMutableArray For(Args &&...args)
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
void add(mf::DataType from_type, mf::DataType to_type, const mf::MultiFunction &fn, void(*convert_single_to_initialized)(const void *src, void *dst), void(*convert_single_to_uninitialized)(const void *src, void *dst))
void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const
const ConversionFunctions * get_conversion_functions(mf::DataType from, mf::DataType to) const
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
GVArray try_convert(GVArray varray, const CPPType &to_type) const
const mf::MultiFunction * get_conversion_multi_function(mf::DataType from, mf::DataType to) 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)
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
Definition FN_field.hh:244
void call_auto(const IndexMask &mask, Params params, Context context) const
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static int2 bool_to_int2(const bool &a)
static float3 quaternion_to_float3(const math::Quaternion &a)
static float3 color_to_float3(const ColorGeometry4f &a)
static float bool_to_float(const bool &a)
static int2 int_to_int2(const int32_t &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 int2 int8_to_int2(const int8_t &a)
static float2 float_to_float2(const float &a)
static float int2_to_float(const int2 &a)
static ColorGeometry4b int_to_byte_color(const int32_t &a)
static int2 float_to_int2(const float &a)
static float2 int2_to_float2(const int2 &a)
static bool float_to_bool(const float &a)
static void add_implicit_conversion(DataTypeConversions &conversions)
static int8_t int2_to_int8(const int2 &a)
static bool int2_to_bool(const int2 &a)
static int8_t float2_to_int8(const float2 &a)
static ColorGeometry4b int2_to_byte_color(const int2 &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 math::Quaternion float_to_quaternion(const float &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 int2 byte_color_to_int2(const ColorGeometry4b &a)
static int2 float3_to_int2(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 int2 color_to_int2(const ColorGeometry4f &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 float4x4 quaternion_to_float4x4(const math::Quaternion &a)
static int int2_to_int(const int2 &a)
static float3 int_to_float3(const int32_t &a)
static float byte_color_to_float(const ColorGeometry4b &a)
static float3 int2_to_float3(const int2 &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 math::Quaternion float3_to_quaternion(const float3 &a)
static ColorGeometry4f int_to_color(const int32_t &a)
static ColorGeometry4b bool_to_byte_color(const bool &a)
static ColorGeometry4f int2_to_color(const int2 &a)
static int32_t float_to_int(const float &a)
static bool int_to_bool(const int32_t &a)
static math::Quaternion float4x4_to_quaternion(const float4x4 &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 int2 float2_to_int2(const float2 &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 void call_convert_to_uninitialized_fn(const GVArray &from, const mf::MultiFunction &fn, const IndexMask &mask, GMutableSpan to)
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)
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
bool is_zero(const T &a)
T midpoint(const T &a, const T &b)
QuaternionBase< T > normalized_to_quaternion_safe(const MatBase< T, 3, 3 > &mat)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
MatT from_rotation(const RotationT &rotation)
Euler3Base< T > to_euler(const AxisAngleBase< T, AngleT > &axis_angle, EulerOrder order)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition BLI_color.hh:337
VecBase< float, 3 > float3
__int64 int64_t
Definition stdint.h:89
signed int int32_t
Definition stdint.h:77
signed char int8_t
Definition stdint.h:75
const mf::MultiFunction * multi_function
void(* convert_single_to_uninitialized)(const void *src, void *dst)
void(* convert_single_to_initialized)(const void *src, void *dst)