$darkmode
VCG Library
color4.h
1 /****************************************************************************
2 * VCGLib o o *
3 * Visual and Computer Graphics Library o o *
4 * _ O _ *
5 * Copyright(C) 2004-2016 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 
24 #ifndef __VCGLIB_COLOR4
25 #define __VCGLIB_COLOR4
26 
27 #include <vcg/space/point3.h>
28 #include <vcg/space/point4.h>
29 
30 namespace vcg {
31 
39 template <class T>
40 class Color4 : public Point4<T>
41 {
42  typedef Point4<T> Base;
43 public:
47  Black = 0xff000000,
48  Gray = 0xff808080,
49  White = 0xffffffff,
50 
51  Red = 0xff0000ff,
52  Green = 0xff00ff00,
53  Blue = 0xffff0000,
54 
55  Cyan = 0xffffff00,
56  Yellow = 0xff00ffff,
57  Magenta = 0xffff00ff,
58 
59  LightGray =0xffc0c0c0,
60  LightRed =0xff8080ff,
61  LightGreen =0xff80ff80,
62  LightBlue =0xffff8080,
63 
64  DarkGray =0xff404040,
65  DarkRed =0xff000040,
66  DarkGreen =0xff004000,
67  DarkBlue =0xff400000
68  };
69 
70  inline Color4 ( const T nx, const T ny, const T nz , const T nw ) :Point4<T>(nx,ny,nz,nw) {}
71  inline Color4 ( const Point4<T> &c) :Point4<T>(c) {}
72  inline Color4 (){}
73  inline Color4 (ColorConstant cc);
74  inline Color4 (unsigned int cc);
75 
76  template <class Q>
77  inline void Import(const Color4<Q> & b )
78  {
79  (*this)[0] = T(b[0]);
80  (*this)[1] = T(b[1]);
81  (*this)[2] = T(b[2]);
82  (*this)[3] = T(b[3]);
83  }
84 
85  template <class Q>
86  inline void Import(const Point4<Q> & b )
87  {
88  (*this)[0] = T(b[0]);
89  (*this)[1] = T(b[1]);
90  (*this)[2] = T(b[2]);
91  (*this)[3] = T(b[3]);
92  }
93 
94  template <class Q>
95  static inline Color4 Construct( const Color4<Q> & b )
96  {
97  return Color4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
98  }
99 
100  //inline void Import(const Color4<float> &b);
101  //inline void Import(const Color4<unsigned char> &b);
102 
103  inline Color4 operator + ( const Color4 & p) const
104  {
105  return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
106  }
107 
108  template <class ScalarInterpType>
109  inline void lerp(const Color4 &c0, const Color4 &c1, const ScalarInterpType x)
110  {
111  assert(x>=0);
112  assert(x<=1);
113 
114  (*this)[0]=(T)(c1.V()[0]*x + c0.V()[0]*(1.0f-x));
115  (*this)[1]=(T)(c1.V()[1]*x + c0.V()[1]*(1.0f-x));
116  (*this)[2]=(T)(c1.V()[2]*x + c0.V()[2]*(1.0f-x));
117  (*this)[3]=(T)(c1.V()[3]*x + c0.V()[3]*(1.0f-x));
118  }
119 
120  template <class ScalarInterpType>
121  inline void lerp(const Color4 &c0, const Color4 &c1, const Color4 &c2, const Point3<ScalarInterpType> &ip)
122  {
123  assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
124 
125  (*this)[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
126  (*this)[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
127  (*this)[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
128  (*this)[3]=(T)(c0[3]*ip[0] + c1[3]*ip[1]+ c2[3]*ip[2]);
129  }
130 
131 
133  inline void SetColorRamp(const float &minf,const float &maxf ,float v )
134  {
135  if(minf>maxf) { SetColorRamp(maxf,minf,maxf+(minf-v)); return; }
136 
137  float step=(maxf-minf)/4;
138  if(v < minf ) { *this=Color4<T>(Color4<T>::Red); return; }
139  v-=minf;
140  if(v<step) { lerp(Color4<T>(Color4<T>::Red), Color4<T>(Color4<T>::Yellow),v/step); return;}
141  v-=step;
142  if(v<step) { lerp(Color4<T>(Color4<T>::Yellow),Color4<T>(Color4<T>::Green), v/step); return;}
143  v-=step;
144  if(v<step) { lerp(Color4<T>(Color4<T>::Green), Color4<T>(Color4<T>::Cyan), v/step); return;}
145  v-=step;
146  if(v<step) { lerp(Color4<T>(Color4<T>::Cyan), Color4<T>(Color4<T>::Blue), v/step); return;}
147 
148  *this= Color4<T>(Color4<T>::Blue);
149  }
150 
151  inline void SetColorRampParula(const float &minf,const float &maxf ,float v)
152  {
153  if(minf>maxf) { SetColorRampParula(maxf,minf,maxf+(minf-v)); return; }
154  SetColorRampParula((v-minf)/(maxf-minf));
155  }
156 
157  inline void SetColorRampParula(float v)
158  {
159  if(v<0) v=0;
160  else if(v>1) v=1;
161 
162  unsigned int ParuVal[9]={0xff801627, 0xffe16303, 0xffd48514,
163  0xffc6a706, 0xff9eb938, 0xff73bf92,
164  0xff56bad9, 0xff2ecefc, 0xff0afaff};
165  int ind = int(floor(v*8.0f));
166  float div = (v*8.0f - ind);
167  if(div<0) div=0;
168  else if(div>1) div=1;
169  lerp(Color4<T>(ParuVal[ind]), Color4<T>(ParuVal[ind+1]), div);
170  }
171 
172  void SetHSVColor( float h, float s, float v)
173  {
174  float r,g,b;
175  if(s==0.0){ // gray color
176  r = g = b = v;
177  (*this)[0]=(unsigned char)(255*r);
178  (*this)[1]=(unsigned char)(255*g);
179  (*this)[2]=(unsigned char)(255*b);
180  (*this)[3]=255;
181  return;
182  }
183  float dummy;
184  h = modff(h,&dummy);
185  if(h==1.0) h = 0.0;
186 
187  int i = int( floor(h*6.0f) );
188  float f = float(h*6.0f- floor(h*6.0f));
189 
190  float p = v*(1.0f-s);
191  float q = v*(1.0f-s*f);
192  float t = v*(1.0f-s*(1.0f-f));
193 
194  switch(i)
195  {
196  case 0: r=v; g=t; b=p; break;
197  case 1: r=q; g=v; b=p; break;
198  case 2: r=p; g=v; b=t; break;
199  case 3: r=p; g=q; b=v; break;
200  case 4: r=t; g=p; b=v; break;
201  case 5: r=v; g=p; b=q; break;
202  default: r=0;g=0;b=0; assert(0);break;
203  }
204  (*this)[0]=(unsigned char)(255*r);
205  (*this)[1]=(unsigned char)(255*g);
206  (*this)[2]=(unsigned char)(255*b);
207  (*this)[3]=255;
208  }
209 
210 inline static Color4 GrayShade(float f)
211 {
212  if(f<0) f=0.0f;
213  else if(f>1) f=1.0f;
214 
215  return Color4(f,f,f,1);
216 }
217 
218 inline void SetGrayShade(float f)
219 {
220  if(f<0) f=0.0f;
221  else if(f>1) f=1.0f;
222 
223  Import(Color4<float>(f,f,f,1));
224 }
225 
226 
233 inline static Color4 Scatter(int range, int value,float Sat=.3f,float Val=.9f)
234 {
235  int b, k, m=range;
236  int r =range;
237 
238  for (b=0, k=1; k<range; k<<=1)
239  if (value<<1>=m) {
240  if (b==0) r = k;
241  b += k;
242  value -= (m+1)>>1;
243  m >>= 1;
244  }
245  else m = (m+1)>>1;
246 
247  if (r>range-b) r = range-b;
248 
249  //TRACE("Scatter range 0..%i, in %i out %i\n",n,a,b);
250  Color4 rc;
251  rc.SetHSVColor(float(b)/float(range),Sat,Val);
252  return rc;
253 }
254 
255 inline static Color4 ColorRamp(const float &minf,const float &maxf ,float v )
256 {
257  Color4 rc;
258  rc.SetColorRamp(minf,maxf,v);
259  return rc;
260 }
261 
262 inline static unsigned short ToUnsignedB5G5R5(const Color4 &) { return 0;}
263 inline static unsigned short ToUnsignedR5G5B5(const Color4 &) { return 0;}
264 inline static unsigned int ToUnsignedA8R8G8B8(const Color4 &) { return 0;}
265 
266 inline static Color4 FromUnsignedB5G5R5(unsigned short)
267 {
268  return Color4(Color4::White);
269 }
270 inline static Color4 FromUnsignedR5G5B5(unsigned short)
271 {
272  return Color4(Color4::White);
273 }
274 
275 };
276 
277 template <> template <>
279 {
280  (*this)[0]=b[0]/255.0f;
281  (*this)[1]=b[1]/255.0f;
282  (*this)[2]=b[2]/255.0f;
283  (*this)[3]=b[3]/255.0f;
284 }
285 
286 template <> template <>
287 inline void Color4<double>::Import(const Color4<unsigned char> &b)
288 {
289  (*this)[0]=b[0]/255.0;
290  (*this)[1]=b[1]/255.0;
291  (*this)[2]=b[2]/255.0;
292  (*this)[3]=b[3]/255.0;
293 }
294 
295 template <> template <>
296 inline void Color4<unsigned char>::Import(const Color4<float> &b)
297 {
298  (*this)[0]=(unsigned char)(b[0]*255.0f);
299  (*this)[1]=(unsigned char)(b[1]*255.0f);
300  (*this)[2]=(unsigned char)(b[2]*255.0f);
301  (*this)[3]=(unsigned char)(b[3]*255.0f);
302 }
303 
304 template <> template <>
305 inline void Color4<unsigned char>::Import(const Point4<float> &b)
306 {
307  (*this)[0]=(unsigned char)(b[0]*255.0f);
308  (*this)[1]=(unsigned char)(b[1]*255.0f);
309  (*this)[2]=(unsigned char)(b[2]*255.0f);
310  (*this)[3]=(unsigned char)(b[3]*255.0f);
311 }
312 
313 template <> template <>
314 inline void Color4<unsigned char>::Import(const Point4<double> &b)
315 {
316  (*this)[0]=(unsigned char)(b[0]*255.0);
317  (*this)[1]=(unsigned char)(b[1]*255.0);
318  (*this)[2]=(unsigned char)(b[2]*255.0);
319  (*this)[3]=(unsigned char)(b[3]*255.0);
320 }
321 
322 template <> template <>
323 inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
324 {
325  return Color4<unsigned char>(
326  (unsigned char)(b[0]*255.0f),
327  (unsigned char)(b[1]*255.0f),
328  (unsigned char)(b[2]*255.0f),
329  (unsigned char)(b[3]*255.0f));
330 }
331 
332 template <> template <>
333 inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
334 {
335  return Color4<float>(
336  (float)(b[0])/255.0f,
337  (float)(b[1])/255.0f,
338  (float)(b[2])/255.0f,
339  (float)(b[3])/255.0f);
340 }
341 
342 template <> template <>
343 inline Color4<double> Color4<double>::Construct( const Color4<unsigned char> & b )
344 {
345  return Color4<double>(
346  (double)(b[0])/255.0,
347  (double)(b[1])/255.0,
348  (double)(b[2])/255.0,
349  (double)(b[3])/255.0);
350 }
351 
352 template<>
353 inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
354 {
355  *((int *)this )= cc;
356 }
357 
358 template<>
359 inline Color4<float>::Color4(Color4<float>::ColorConstant cc)
360 {
361  Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
362 }
363 
364 template<>
365 inline Color4<double>::Color4(Color4<double>::ColorConstant cc)
366 {
367  Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
368 }
369 
370 template<>
371 inline Color4<unsigned char>::Color4(unsigned int cc)
372 {
373  *((int *)this )= cc;
374 }
375 
376 template<>
377 inline Color4<float>::Color4(unsigned int cc)
378 {
379  Import(Color4<unsigned char>(cc));
380 }
381 
382 template<>
383 inline Color4<double>::Color4(unsigned int cc)
384 {
385  Import(Color4<unsigned char>(cc));
386 }
387 
388 inline Color4<float> Clamp(Color4<float> &c)
389 {
390  c[0]=math::Clamp(c[0],0.0f,1.0f);
391  c[1]=math::Clamp(c[1],0.0f,1.0f);
392  c[2]=math::Clamp(c[2],0.0f,1.0f);
393  c[3]=math::Clamp(c[3],0.0f,1.0f);
394  return c;
395 }
396 
397 inline Color4<double> Clamp(Color4<double> &c)
398 {
399  c[0]=math::Clamp(c[0],0.0,1.0);
400  c[1]=math::Clamp(c[1],0.0,1.0);
401  c[2]=math::Clamp(c[2],0.0,1.0);
402  c[3]=math::Clamp(c[3],0.0,1.0);
403  return c;
404 }
405 
406 template<>
407 inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
408 {
409  return Color4<unsigned char>(
410  (unsigned char)(math::Clamp(int((*this)[0])+int(p[0]),0,255)),
411  (unsigned char)(math::Clamp(int((*this)[1])+int(p[1]),0,255)),
412  (unsigned char)(math::Clamp(int((*this)[2])+int(p[2]),0,255)),
413  (unsigned char)(math::Clamp(int((*this)[3])+int(p[3]),0,255))
414  );
415 }
416 
417 
418 typedef Color4<unsigned char> Color4b;
419 typedef Color4<float> Color4f;
420 typedef Color4<double> Color4d;
421 
422 
423 template<>
424 inline unsigned short Color4<unsigned char>::ToUnsignedB5G5R5(const Color4<unsigned char> &cc)
425 {
426  unsigned short r = cc[0]/8;
427  unsigned short g = cc[1]/8;
428  unsigned short b = cc[2]/8;
429  unsigned short res = b + g*32 + r*1024;
430  return res;
431 }
432 
433 template<>
434 inline unsigned short Color4<unsigned char>::ToUnsignedR5G5B5(const Color4<unsigned char> &cc)
435 {
436  unsigned short r = cc[0]/8;
437  unsigned short g = cc[1]/8;
438  unsigned short b = cc[2]/8;
439  unsigned short res = r + g*32 + b*1024;
440  return res;
441 }
442 
443 template<>
444 inline unsigned int Color4<unsigned char>::ToUnsignedA8R8G8B8(const Color4<unsigned char> &cc)
445 {
446  unsigned int r = cc[0];
447  unsigned int g = cc[1];
448  unsigned int b = cc[2];
449  unsigned int a = cc[3];
450  unsigned int res = (r << 16) | (g << 8) | (b) | (a << 24);
451  return res;
452 }
453 
454 
455 template<>
456 inline Color4<unsigned char> Color4<unsigned char>::FromUnsignedR5G5B5(unsigned short val)
457 {
458  unsigned short r = val % 32 *8;
459  unsigned short g = ((val/32)%32)*8;
460  unsigned short b = ((val/1024)%32)*8;
461  Color4b cc((unsigned char)r,(unsigned char)g,(unsigned char)b,(unsigned char)255);
462  return cc;
463 }
464 
465 template<>
466 inline Color4<unsigned char> Color4<unsigned char>::FromUnsignedB5G5R5(unsigned short val)
467 {
468  unsigned short b = val % 32 *8;
469  unsigned short g = ((val/32)%32)*8;
470  unsigned short r = ((val/1024)%32)*8;
471  Color4b cc((unsigned char)r,(unsigned char)g,(unsigned char)b,(unsigned char)255);
472  return cc;
473 }
474 
478 } // end of NameSpace
479 
480 #endif
Definition: color4.h:41
ColorConstant
Definition: color4.h:46
static Color4 Scatter(int range, int value, float Sat=.3f, float Val=.9f)
Definition: color4.h:233
void SetColorRamp(const float &minf, const float &maxf, float v)
given a float and a range set the corresponding color in the well known red->green->blue color ramp....
Definition: color4.h:133
Definition: namespaces.dox:6