ai_color.h
Go to the documentation of this file.
1 // Copyright 2020 Autodesk, Inc. All rights reserved.
2 //
3 // Use of this software is subject to the terms of the Autodesk license
4 // agreement provided at the time of installation or download, or which
5 // otherwise accompanies this software in either electronic or hard copy form.
6 
12 #pragma once
13 #include "ai_comparison.h"
14 #include "ai_math.h"
15 #include "ai_string.h"
16 #include "ai_constants.h"
17 #include "ai_api.h"
18 
19 struct AtRGBA;
20 
31 struct AtRGB
32 {
33  float r, g, b;
34 
35  AtRGB() = default;
36  AI_DEVICE constexpr explicit AtRGB(float c) : r(c), g(c), b(c) { }
37  AI_DEVICE constexpr AtRGB(float r, float g, float b) : r(r), g(g), b(b) { }
38  AI_DEVICE constexpr explicit AtRGB(const AtRGBA& rgba);
39 
40  AI_DEVICE constexpr AtRGB operator+(const AtRGB& rgb) const
41  {
42  return AtRGB(r + rgb.r,
43  g + rgb.g,
44  b + rgb.b);
45  }
46 
47  AI_DEVICE AtRGB& operator+=(const AtRGB& rgb)
48  {
49  r += rgb.r;
50  g += rgb.g;
51  b += rgb.b;
52  return *this;
53  }
54 
55  AI_DEVICE constexpr AtRGB operator+(float f) const
56  {
57  return AtRGB(r + f,
58  g + f,
59  b + f);
60  }
61 
62  AI_DEVICE AtRGB& operator+=(float f)
63  {
64  r += f;
65  g += f;
66  b += f;
67  return *this;
68  }
69 
70  AI_DEVICE constexpr AtRGB operator-(const AtRGB& rgb) const
71  {
72  return AtRGB(r - rgb.r,
73  g - rgb.g,
74  b - rgb.b);
75  }
76 
77  AI_DEVICE AtRGB& operator-=(const AtRGB& rgb)
78  {
79  r -= rgb.r;
80  g -= rgb.g;
81  b -= rgb.b;
82  return *this;
83  }
84 
85  AI_DEVICE constexpr AtRGB operator-(float f) const
86  {
87  return AtRGB(r - f,
88  g - f,
89  b - f);
90  }
91 
92  AI_DEVICE AtRGB& operator-=(float f)
93  {
94  r -= f;
95  g -= f;
96  b -= f;
97  return *this;
98  }
99 
100  AI_DEVICE constexpr AtRGB operator-() const
101  {
102  return AtRGB(-r, -g, -b);
103  }
104 
105  AI_DEVICE constexpr AtRGB operator*(const AtRGB& rgb) const
106  {
107  return AtRGB(r * rgb.r,
108  g * rgb.g,
109  b * rgb.b);
110  }
111 
112  AI_DEVICE AtRGB operator*=(const AtRGB& rgb)
113  {
114  r *= rgb.r;
115  g *= rgb.g;
116  b *= rgb.b;
117  return *this;
118  }
119 
120  AI_DEVICE constexpr AtRGB operator*(float f) const
121  {
122  return AtRGB(r * f,
123  g * f,
124  b * f);
125  }
126 
127  AI_DEVICE AtRGB operator*=(float f)
128  {
129  r *= f;
130  g *= f;
131  b *= f;
132  return *this;
133  }
134 
135  AI_DEVICE constexpr AtRGB operator/(const AtRGB& rgb) const
136  {
137  return AtRGB(r / rgb.r,
138  g / rgb.g,
139  b / rgb.b);
140  }
141 
142  AI_DEVICE AtRGB operator/=(const AtRGB& rgb)
143  {
144  r /= rgb.r;
145  g /= rgb.g;
146  b /= rgb.b;
147  return *this;
148  }
149 
150  AI_DEVICE AtRGB operator/(float f) const
151  {
152  return AtRGB(r / f,
153  g / f,
154  b / f);
155  }
156 
157  AI_DEVICE AtRGB operator/=(float f)
158  {
159  r /= f;
160  g /= f;
161  b /= f;
162  return *this;
163  }
164 
165  AI_DEVICE constexpr bool operator==(const AtRGB& rgb) const
166  {
167  return (r == rgb.r && g == rgb.g && b == rgb.b);
168  }
169 
170  AI_DEVICE constexpr bool operator!=(const AtRGB& rgb) const
171  {
172  return !(*this == rgb);
173  }
174 
175  AI_DEVICE AtRGB& operator=(float f)
176  {
177  r = f;
178  g = f;
179  b = f;
180  return *this;
181  }
182 
183  AI_DEVICE float& operator[](unsigned int i)
184  {
185  return *(&r + i); // warning: no bounds checking!
186  }
187 
188  AI_DEVICE constexpr const float& operator[](unsigned int i) const
189  {
190  return *(&r + i); // warning: no bounds checking!
191  }
192 
193  AI_DEVICE friend constexpr AtRGB operator*(float f, const AtRGB& rgb);
194  AI_DEVICE friend constexpr AtRGB operator+(float f, const AtRGB& rgb);
195  AI_DEVICE friend constexpr AtRGB operator-(float f, const AtRGB& rgb);
196 };
197 
198 AI_DEVICE inline constexpr AtRGB operator*(float f, const AtRGB& rgb)
199 {
200  return rgb * f;
201 }
202 
203 AI_DEVICE inline constexpr AtRGB operator+(float f, const AtRGB& rgb)
204 {
205  return rgb + f;
206 }
207 
208 AI_DEVICE inline constexpr AtRGB operator-(float f, const AtRGB& rgb)
209 {
210  return AtRGB(f - rgb.r,
211  f - rgb.g,
212  f - rgb.b);
213 }
214 
215 AI_DEVICE inline constexpr AtRGB operator/(float f, const AtRGB& rgb)
216 {
217  return AtRGB(f / rgb.r,
218  f / rgb.g,
219  f / rgb.b);
220 }
221 
222 AI_DEVICE inline AtBooleanMask<3> operator<(const AtRGB& lhs, const AtRGB& rhs)
223 {
224  return AtBooleanMask<3>::lt(&(lhs[0]), &(rhs[0]));
225 }
226 
227 AI_DEVICE inline AtBooleanMask<3> operator<=(const AtRGB& lhs, const AtRGB& rhs)
228 {
229  return AtBooleanMask<3>::le(&(lhs[0]), &(rhs[0]));
230 }
231 
232 AI_DEVICE inline AtBooleanMask<3> operator>(const AtRGB& lhs, const AtRGB& rhs)
233 {
234  return AtBooleanMask<3>::gt(&(lhs[0]), &(rhs[0]));
235 }
236 
237 AI_DEVICE inline AtBooleanMask<3> operator>=(const AtRGB& lhs, const AtRGB& rhs)
238 {
239  return AtBooleanMask<3>::ge(&(lhs[0]), &(rhs[0]));
240 }
241 
242 AI_DEVICE inline AtBooleanMask<3> operator<(const AtRGB& lhs, float rhs)
243 {
244  return AtBooleanMask<3>::lt(&(lhs[0]), rhs);
245 }
246 
247 AI_DEVICE inline AtBooleanMask<3> operator<=(const AtRGB& lhs, float rhs)
248 {
249  return AtBooleanMask<3>::le(&(lhs[0]), rhs);
250 }
251 
252 AI_DEVICE inline AtBooleanMask<3> operator>(const AtRGB& lhs, float rhs)
253 {
254  return AtBooleanMask<3>::gt(&(lhs[0]), rhs);
255 }
256 
257 AI_DEVICE inline AtBooleanMask<3> operator>=(const AtRGB& lhs, float rhs)
258 {
259  return AtBooleanMask<3>::ge(&(lhs[0]), rhs);
260 }
261 
262 
266 struct AtRGBA
267 {
268  float r, g, b, a;
269 
270  AtRGBA() = default;
271  AI_DEVICE constexpr AtRGBA(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) { }
272  AI_DEVICE constexpr AtRGBA(const AtRGB& rgb, float a=1) : r(rgb.r), g(rgb.g), b(rgb.b), a(a) { }
273 
274  AI_DEVICE AtRGB& rgb()
275  {
276  return *static_cast<AtRGB*>(static_cast<void*>(this));
277  }
278 
279  AI_DEVICE const AtRGB& rgb() const
280  {
281  return *static_cast<const AtRGB*>(static_cast<const void*>(this));
282  }
283 
284  AI_DEVICE constexpr AtRGBA operator+(const AtRGBA& rgba) const
285  {
286  return AtRGBA(r + rgba.r,
287  g + rgba.g,
288  b + rgba.b,
289  a + rgba.a);
290  }
291 
292  AI_DEVICE AtRGBA& operator+=(const AtRGBA& rgba)
293  {
294  r += rgba.r;
295  g += rgba.g;
296  b += rgba.b;
297  a += rgba.a;
298  return *this;
299  }
300 
301  AI_DEVICE constexpr AtRGBA operator+(float f) const
302  {
303  return AtRGBA(r + f,
304  g + f,
305  b + f,
306  a + f);
307  }
308 
309  AI_DEVICE AtRGBA& operator+=(float f)
310  {
311  r += f;
312  g += f;
313  b += f;
314  a += f;
315  return *this;
316  }
317 
318  AI_DEVICE constexpr AtRGBA operator-(const AtRGBA& rgba) const
319  {
320  return AtRGBA(r - rgba.r,
321  g - rgba.g,
322  b - rgba.b,
323  a - rgba.a);
324  }
325 
326  AI_DEVICE AtRGBA& operator-=(const AtRGBA& rgba)
327  {
328  r -= rgba.r;
329  g -= rgba.g;
330  b -= rgba.b;
331  a -= rgba.a;
332  return *this;
333  }
334 
335  AI_DEVICE constexpr AtRGBA operator-(float f) const
336  {
337  return AtRGBA(r - f,
338  g - f,
339  b - f,
340  a - f);
341  }
342 
343  AI_DEVICE AtRGBA& operator-=(float f)
344  {
345  r -= f;
346  g -= f;
347  b -= f;
348  a -= f;
349  return *this;
350  }
351 
352  AI_DEVICE constexpr AtRGBA operator-() const
353  {
354  return AtRGBA(-r, -g, -b, -a);
355  }
356 
357  AI_DEVICE constexpr AtRGBA operator*(const AtRGBA& rgba) const
358  {
359  return AtRGBA(r * rgba.r,
360  g * rgba.g,
361  b * rgba.b,
362  a * rgba.a);
363  }
364 
365  AI_DEVICE AtRGBA operator*=(const AtRGBA& rgba)
366  {
367  r *= rgba.r;
368  g *= rgba.g;
369  b *= rgba.b;
370  a *= rgba.a;
371  return *this;
372  }
373 
374  AI_DEVICE constexpr AtRGBA operator*(float f) const
375  {
376  return AtRGBA(r * f,
377  g * f,
378  b * f,
379  a * f);
380  }
381 
382  AI_DEVICE AtRGBA operator*=(float f)
383  {
384  r *= f;
385  g *= f;
386  b *= f;
387  a *= f;
388  return *this;
389  }
390 
391  AI_DEVICE constexpr AtRGBA operator/(const AtRGBA& rgba) const
392  {
393  return AtRGBA(r / rgba.r,
394  g / rgba.g,
395  b / rgba.b,
396  a / rgba.a);
397  }
398 
399  AI_DEVICE AtRGBA operator/=(const AtRGBA& rgba)
400  {
401  r /= rgba.r;
402  g /= rgba.g;
403  b /= rgba.b;
404  a /= rgba.a;
405  return *this;
406  }
407 
408  AI_DEVICE AtRGBA operator/(float f) const
409  {
410  return AtRGBA(r / f,
411  g / f,
412  b / f,
413  a / f);
414  }
415 
416  AI_DEVICE AtRGBA operator/=(float f)
417  {
418  r /= f;
419  g /= f;
420  b /= f;
421  a /= f;
422  return *this;
423  }
424 
425  AI_DEVICE constexpr bool operator==(const AtRGBA& rgba) const
426  {
427  return (r == rgba.r && g == rgba.g && b == rgba.b && a == rgba.a);
428  }
429 
430  AI_DEVICE constexpr bool operator!=(const AtRGBA& rgba) const
431  {
432  return !(*this == rgba);
433  }
434 
435  AI_DEVICE AtRGBA& operator=(float f)
436  {
437  r = f;
438  g = f;
439  b = f;
440  a = f;
441  return *this;
442  }
443 
444  AI_DEVICE float& operator[](unsigned int i)
445  {
446  return *(&r + i); // warning: no bounds checking!
447  }
448 
449  AI_DEVICE constexpr const float& operator[](unsigned int i) const
450  {
451  return *(&r + i); // warning: no bounds checking!
452  }
453 
454  AI_DEVICE friend constexpr AtRGBA operator*(float f, const AtRGBA& rgba);
455  AI_DEVICE friend constexpr AtRGBA operator+(float f, const AtRGBA& rgba);
456  AI_DEVICE friend constexpr AtRGBA operator-(float f, const AtRGBA& rgba);
457 };
458 
459 AI_DEVICE inline constexpr AtRGBA operator*(float f, const AtRGBA& rgba)
460 {
461  return rgba * f;
462 }
463 
464 AI_DEVICE inline constexpr AtRGBA operator+(float f, const AtRGBA& rgba)
465 {
466  return rgba + f;
467 }
468 
469 AI_DEVICE inline constexpr AtRGBA operator-(float f, const AtRGBA& rgba)
470 {
471  return AtRGBA(f - rgba.r,
472  f - rgba.g,
473  f - rgba.b,
474  f - rgba.a);
475 }
476 
477 inline AtBooleanMask<4> operator<(const AtRGBA& lhs, const AtRGBA& rhs)
478 {
479  return AtBooleanMask<4>::lt(&(lhs[0]), &(rhs[0]));
480 }
481 
482 inline AtBooleanMask<4> operator<=(const AtRGBA& lhs, const AtRGBA& rhs)
483 {
484  return AtBooleanMask<4>::le(&(lhs[0]), &(rhs[0]));
485 }
486 
487 inline AtBooleanMask<4> operator>(const AtRGBA& lhs, const AtRGBA& rhs)
488 {
489  return AtBooleanMask<4>::gt(&(lhs[0]), &(rhs[0]));
490 }
491 
492 inline AtBooleanMask<4> operator>=(const AtRGBA& lhs, const AtRGBA& rhs)
493 {
494  return AtBooleanMask<4>::ge(&(lhs[0]), &(rhs[0]));
495 }
496 
497 inline AtBooleanMask<4> operator<(const AtRGBA& lhs, float rhs)
498 {
499  return AtBooleanMask<4>::lt(&(lhs[0]), rhs);
500 }
501 
502 inline AtBooleanMask<4> operator<=(const AtRGBA& lhs, float rhs)
503 {
504  return AtBooleanMask<4>::le(&(lhs[0]), rhs);
505 }
506 
507 inline AtBooleanMask<4> operator>(const AtRGBA& lhs, float rhs)
508 {
509  return AtBooleanMask<4>::gt(&(lhs[0]), rhs);
510 }
511 
512 inline AtBooleanMask<4> operator>=(const AtRGBA& lhs, float rhs)
513 {
514  return AtBooleanMask<4>::ge(&(lhs[0]), rhs);
515 }
516 
517 AI_DEVICE inline constexpr AtRGB::AtRGB(const AtRGBA& rgba) : r(rgba.r), g(rgba.g), b(rgba.b) { }
518 
519 
527 AI_DEVICE inline constexpr AtRGB AiRGBClamp(const AtRGB& c, float lo, float hi)
528 {
529  return AtRGB(AiClamp(c.r, lo, hi),
530  AiClamp(c.g, lo, hi),
531  AiClamp(c.b, lo, hi));
532 }
533 
537 AI_DEVICE inline constexpr AtRGBA AiRGBAClamp(const AtRGBA& c, float lo, float hi)
538 {
539  return AtRGBA(AiClamp(c.r, lo, hi),
540  AiClamp(c.g, lo, hi),
541  AiClamp(c.b, lo, hi),
542  AiClamp(c.a, lo, hi));
543 }
544 
548 AI_DEVICE inline void AiColorClipToZero(AtRGB& c)
549 {
550  c.r = AiMax(c.r, 0.0f);
551  c.g = AiMax(c.g, 0.0f);
552  c.b = AiMax(c.b, 0.0f);
553 }
554 
558 AI_DEVICE inline bool AiColorIsSmall(const AtRGB& c, float epsilon = AI_EPSILON)
559 {
560  return std::abs(c.r) < epsilon && std::abs(c.g) < epsilon && std::abs(c.b) < epsilon;
561 }
562 
566 AI_DEVICE inline AtRGB AiColorABS(const AtRGB& c)
567 {
568  return AtRGB(std::abs(c.r),
569  std::abs(c.g),
570  std::abs(c.b));
571 }
572 
576 AI_DEVICE inline AtRGBA AiColorABS(const AtRGBA& c)
577 {
578  return AtRGBA(std::abs(c.r),
579  std::abs(c.g),
580  std::abs(c.b),
581  std::abs(c.a));
582 }
583 
587 AI_DEVICE inline constexpr float AiColorMaxRGB(const AtRGB& c)
588 {
589  return AiMax(c.r, c.g, c.b);
590 }
591 
595 AI_DEVICE inline constexpr float AiColorMaxRGB(const AtRGBA& c)
596 {
597  return AiMax(c.r, c.g, c.b);
598 }
599 
603 inline bool AiColorThreshold(const AtRGB& c1, const AtRGB& c2, float t)
604 {
605  return std::abs(c1.r - c2.r) >= t || std::abs(c1.g - c2.g) >= t || std::abs(c1.b - c2.b) >= t;
606 }
607 
611 AI_DEVICE inline constexpr float AiColorToGrey(const AtRGB& c)
612 {
613  return (c.r + c.g + c.b) / 3;
614 }
615 
619 AI_DEVICE inline constexpr float AiColorToGrey(const AtRGBA& rgba)
620 {
621  return (rgba.r + rgba.g + rgba.b) / 3;
622 }
623 
627 AI_API AI_PURE bool AiRGBIsFinite(const AtRGB& rgba);
628 
632 AI_API AI_PURE bool AiRGBAIsFinite(const AtRGBA& rgba);
633 
637 inline AtRGB AiBerpRGB(float a, float b, const AtRGB& c0, const AtRGB& c1, const AtRGB& c2)
638 {
639  float c = 1 - (a+b);
640  return c*c0 + a*c1 + b*c2;
641 }
642 
643 AI_API AI_DEVICE AI_PURE AtRGB AiColorHeatMap(const AtRGB* map_colors, const float* map_values, unsigned int map_length, float lookup);
644 
645 /*\}*/
646 
650 #ifdef AI_CPU_COMPILER
651 static constexpr const AtRGB AI_RGB_BLACK (0.0f, 0.0f, 0.0f);
652 static constexpr const AtRGB AI_RGB_ZERO (0.0f, 0.0f, 0.0f);
653 static constexpr const AtRGB AI_RGB_RED (1.0f, 0.0f, 0.0f);
654 static constexpr const AtRGB AI_RGB_GREEN (0.0f, 1.0f, 0.0f);
655 static constexpr const AtRGB AI_RGB_BLUE (0.0f, 0.0f, 1.0f);
656 static constexpr const AtRGB AI_RGB_50GREY(0.5f, 0.5f, 0.5f);
657 static constexpr const AtRGB AI_RGB_WHITE (1.0f, 1.0f, 1.0f);
658 #else
659 __device__ static const AtRGB AI_RGB_BLACK (0.0f, 0.0f, 0.0f);
660 __device__ static const AtRGB AI_RGB_ZERO (0.0f, 0.0f, 0.0f);
661 __device__ static const AtRGB AI_RGB_RED (1.0f, 0.0f, 0.0f);
662 __device__ static const AtRGB AI_RGB_GREEN (0.0f, 1.0f, 0.0f);
663 __device__ static const AtRGB AI_RGB_BLUE (0.0f, 0.0f, 1.0f);
664 __device__ static const AtRGB AI_RGB_50GREY(0.5f, 0.5f, 0.5f);
665 __device__ static const AtRGB AI_RGB_WHITE (1.0f, 1.0f, 1.0f);
666 #endif
667 
668 #ifdef AI_CPU_COMPILER
669 static constexpr const AtRGBA AI_RGBA_ZERO (0.0f, 0.0f, 0.0f, 0.0f);
670 static constexpr const AtRGBA AI_RGBA_RED (1.0f, 0.0f, 0.0f, 1.0f);
671 static constexpr const AtRGBA AI_RGBA_GREEN (0.0f, 1.0f, 0.0f, 1.0f);
672 static constexpr const AtRGBA AI_RGBA_BLUE (0.0f, 0.0f, 1.0f, 1.0f);
673 static constexpr const AtRGBA AI_RGBA_50GREY(0.5f, 0.5f, 0.5f, 1.0f);
674 static constexpr const AtRGBA AI_RGBA_WHITE (1.0f, 1.0f, 1.0f, 1.0f);
675 #else
676 __device__ static const AtRGBA AI_RGBA_ZERO (0.0f, 0.0f, 0.0f, 0.0f);
677 __device__ static const AtRGBA AI_RGBA_RED (1.0f, 0.0f, 0.0f, 1.0f);
678 __device__ static const AtRGBA AI_RGBA_GREEN (0.0f, 1.0f, 0.0f, 1.0f);
679 __device__ static const AtRGBA AI_RGBA_BLUE (0.0f, 0.0f, 1.0f, 1.0f);
680 __device__ static const AtRGBA AI_RGBA_50GREY(0.5f, 0.5f, 0.5f, 1.0f);
681 __device__ static const AtRGBA AI_RGBA_WHITE (1.0f, 1.0f, 1.0f, 1.0f);
682 #endif
683 
684 /*\}*/
685 
686 /*\}*/
RGB color.
Definition: ai_color.h:31
Definition: ai_comparison.h:16
AI_API AI_PURE bool AiRGBIsFinite(const AtRGB &rgba)
Check to see if an RGB color has any corrupted components (nan or infinite).
Definition: ai_color.cpp:53
Math operations.
AI_DEVICE constexpr T AiMax(T a, T b)
Maximum of 'a' and 'b'.
Definition: ai_math.h:43
AI_API AI_PURE bool AiRGBAIsFinite(const AtRGBA &rgba)
Check to see if an RGBA color has any corrupted components (nan or infinite).
Definition: ai_color.cpp:61
DLL export prefix for API functions (necessary for multi-platform development)
AI_DEVICE constexpr AtRGBA AiRGBAClamp(const AtRGBA &c, float lo, float hi)
Clamp the RGBA color vector to the specified range.
Definition: ai_color.h:537
AI_API AI_DEVICE AI_PURE AtRGB AiColorHeatMap(const AtRGB *map_colors, const float *map_values, unsigned int map_length, float lookup)
Interpolate a value according to a heat map (piecewise linear color map).
Definition: ai_color.cpp:18
AI_DEVICE constexpr T AiClamp(T v, T lo, T hi)
Clamp the input to the specified range.
Definition: ai_math.h:101
AtRGB AiBerpRGB(float a, float b, const AtRGB &c0, const AtRGB &c1, const AtRGB &c2)
Barycentric interpolation of triangle vertex colors.
Definition: ai_color.h:637
bool AiColorThreshold(const AtRGB &c1, const AtRGB &c2, float t)
Check to see if two colors differ by more than a threhsold.
Definition: ai_color.h:603
#define AI_EPSILON
System epsilon value.
Definition: ai_constants.h:41
AI_DEVICE constexpr AtRGB AiRGBClamp(const AtRGB &c, float lo, float hi)
Clamp the RGB color vector to the specified range.
Definition: ai_color.h:527
Comparison.
RGB color + alpha.
Definition: ai_color.h:266
Various useful constants.
AI_DEVICE constexpr float AiColorMaxRGB(const AtRGB &c)
Max RGB component of color.
Definition: ai_color.h:587
AI_DEVICE AtRGB AiColorABS(const AtRGB &c)
Absolute value of color.
Definition: ai_color.h:566
AI_DEVICE void AiColorClipToZero(AtRGB &c)
Clip negative values.
Definition: ai_color.h:548
AI_DEVICE constexpr float AiColorToGrey(const AtRGB &c)
Convert a RGB color to grey scale (take average of R, G, B)
Definition: ai_color.h:611
AtString class for fast comparisons.
AI_DEVICE bool AiColorIsSmall(const AtRGB &c, float epsilon=AI_EPSILON)
Check for almost black.
Definition: ai_color.h:558

© 2020 Autodesk, Inc. · All rights reserved · www.arnoldrenderer.com