00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #ifndef __VCGLIB_COLOR4
00075 #define __VCGLIB_COLOR4
00076
00077 #include <vcg/space/point3.h>
00078 #include <vcg/space/point4.h>
00079
00080 namespace vcg {
00081
00089 template <class T>
00090 class Color4 : public Point4<T>
00091 {
00092 typedef Point4<T> Base;
00093 public:
00096 enum ColorConstant {
00097 Black =0xff000000,
00098 Gray =0xff808080,
00099 White =0xffffffff,
00100
00101 Red =0xff0000ff,
00102 Green =0xff00ff00,
00103 Blue =0xffff0000,
00104
00105 Cyan =0xffffff00,
00106 Yellow =0xff00ffff,
00107 Magenta=0xffff00ff,
00108
00109 LightGray =0xffc0c0c0,
00110 LightRed =0xff8080ff,
00111 LightGreen =0xff80ff80,
00112 LightBlue =0xffff8080,
00113
00114 DarkGray =0xff404040,
00115 DarkRed =0xff000040,
00116 DarkGreen =0xff004000,
00117 DarkBlue =0xff400000
00118 };
00119
00120 inline Color4 ( const T nx, const T ny, const T nz , const T nw ) :Point4<T>(nx,ny,nz,nw) {};
00121
00122 inline Color4 ( const Point4<T> &c) :Point4<T>(c) {};
00123 inline Color4 (){};
00124 inline Color4 (ColorConstant cc);
00125 #ifdef VCG_USE_EIGEN
00126 template<typename OtherDerived>
00127 inline Color4 (const Eigen::MatrixBase<OtherDerived>& other) : Base(other)
00128 {
00129
00130 }
00131 #endif
00132
00133 template <class Q>
00134 inline void Import(const Color4<Q> & b )
00135 {
00136 (*this)[0] = T(b[0]);
00137 (*this)[1] = T(b[1]);
00138 (*this)[2] = T(b[2]);
00139 (*this)[3] = T(b[3]);
00140 }
00141
00142 template <class Q>
00143 inline void Import(const Point4<Q> & b )
00144 {
00145 (*this)[0] = T(b[0]);
00146 (*this)[1] = T(b[1]);
00147 (*this)[2] = T(b[2]);
00148 (*this)[3] = T(b[3]);
00149 }
00150
00151 template <class Q>
00152 static inline Color4 Construct( const Color4<Q> & b )
00153 {
00154 return Color4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
00155 }
00156
00157
00158
00159
00160 inline Color4 operator + ( const Color4 & p) const
00161 {
00162 return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
00163 }
00164
00165
00166 inline void lerp(const Color4 &c0, const Color4 &c1, const float x);
00167 inline void lerp(const Color4 &c0, const Color4 &c1, const Color4 &c2, const Point3f &ip);
00169 inline void ColorRamp(const float &minf,const float &maxf ,float v );
00170
00171 inline void SetRGB( unsigned char r, unsigned char g, unsigned char b )
00172 {
00173 (*this)[0] = r;
00174 (*this)[1] = g;
00175 (*this)[2] = b;
00176 (*this)[3] = 0;
00177 }
00178
00179 void SetHSVColor( float h, float s, float v){
00180 float r,g,b;
00181 if(s==0.0){
00182 r = g = b = v;
00183 (*this)[0]=(unsigned char)(255*r);
00184 (*this)[1]=(unsigned char)(255*g);
00185 (*this)[2]=(unsigned char)(255*b);
00186 (*this)[3]=255;
00187 return;
00188 }
00189 if(h==1.0) h = 0.0;
00190
00191 int i = int( floor(h*6.0) );
00192 float f = float(h*6.0f - floor(h*6.0f));
00193
00194 float p = v*(1.0f-s);
00195 float q = v*(1.0f-s*f);
00196 float t = v*(1.0f-s*(1.0f-f));
00197
00198 switch(i){
00199 case 0: r=v; g=t; b=p; break;
00200 case 1: r=q; g=v; b=p; break;
00201 case 2: r=p; g=v; b=t; break;
00202 case 3: r=p; g=q; b=v; break;
00203 case 4: r=t; g=p; b=v; break;
00204 case 5: r=v; g=p; b=q; break;
00205 default: r=0;g=0;b=0; assert(0);break;
00206 }
00207 (*this)[0]=(unsigned char)(255*r);
00208 (*this)[1]=(unsigned char)(255*g);
00209 (*this)[2]=(unsigned char)(255*b);
00210 (*this)[3]=255;
00211
00212 }
00213
00214 inline static Color4 GrayShade(float f)
00215 {
00216 return Color4(f,f,f,1);
00217 }
00218
00219 inline void SetGrayShade(float f)
00220 {
00221 Import(Color4<float>(f,f,f,1));
00222 }
00223
00224
00231 inline static Color4 Scatter(int n, int a,float Sat=.3f,float Val=.9f)
00232 {
00233 int b, k, m=n;
00234 int r =n;
00235
00236 for (b=0, k=1; k<n; k<<=1)
00237 if (a<<1>=m) {
00238 if (b==0) r = k;
00239 b += k;
00240 a -= (m+1)>>1;
00241 m >>= 1;
00242 }
00243 else m = (m+1)>>1;
00244 if (r>n-b) r = n-b;
00245
00246
00247 Color4 rc;
00248 rc.SetHSVColor(float(b)/float(n),Sat,Val);
00249 return rc;
00250 }
00251
00252 };
00253 template <class T>
00254 inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const float x)
00255 {
00256 assert(x>=0);
00257 assert(x<=1);
00258
00259 (*this)[0]=(T)(c1.V()[0]*x + c0.V()[0]*(1.0f-x));
00260 (*this)[1]=(T)(c1.V()[1]*x + c0.V()[1]*(1.0f-x));
00261 (*this)[2]=(T)(c1.V()[2]*x + c0.V()[2]*(1.0f-x));
00262 (*this)[3]=(T)(c1.V()[3]*x + c0.V()[3]*(1.0f-x));
00263 }
00264
00265 template <class T>
00266 inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Color4<T> &c2, const Point3f &ip)
00267 {
00268 assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
00269
00270 (*this)[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
00271 (*this)[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
00272 (*this)[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
00273 (*this)[3]=(T)(c0[3]*ip[0] + c1[3]*ip[1]+ c2[3]*ip[2]);
00274 }
00275
00276
00277 template <class T>
00278 inline void Color4<T>::ColorRamp(const float &minf,const float &maxf ,float v )
00279 {
00280 if(minf>maxf) { ColorRamp(maxf,minf,maxf+(minf-v)); return; }
00281 if(v < minf ) { *this=Color4<T>(Color4<T>::Red); return; }
00282
00283
00284 float step=(maxf-minf)/4;
00285 v-=minf;
00286 if(v<step) {lerp(Color4<T>(Color4<T>::Red), Color4<T>(Color4<T>::Yellow),v/step); return;}
00287 v-=step;
00288 if(v<step) {lerp(Color4<T>(Color4<T>::Yellow),Color4<T>(Color4<T>::Green),v/step);return;}
00289 v-=step;
00290 if(v<step) {lerp(Color4<T>(Color4<T>::Green),Color4<T>(Color4<T>::Cyan),v/step); return;}
00291 v-=step;
00292 if(v<step) {lerp(Color4<T>(Color4<T>::Cyan),Color4<T>(Color4<T>::Blue),v/step); return;}
00293
00294 *this= Color4<T>(Color4<T>::Blue);
00295
00296 }
00297
00298
00299 #if !defined(__GNUC__) || (__GNUC__ > 3)
00300 template <>
00301 #endif
00302 template <>
00303 inline void Color4<float>::Import(const Color4<unsigned char> &b)
00304 {
00305 (*this)[0]=b[0]/255.0f;
00306 (*this)[1]=b[1]/255.0f;
00307 (*this)[2]=b[2]/255.0f;
00308 (*this)[3]=b[3]/255.0f;
00309 }
00310
00311 #if !defined(__GNUC__) || (__GNUC__ > 3)
00312 template <>
00313 #endif
00314 template <>
00315 inline void Color4<unsigned char>::Import(const Color4<float> &b)
00316 {
00317 (*this)[0]=(unsigned char)(b[0]*255.0f);
00318 (*this)[1]=(unsigned char)(b[1]*255.0f);
00319 (*this)[2]=(unsigned char)(b[2]*255.0f);
00320 (*this)[3]=(unsigned char)(b[3]*255.0f);
00321 }
00322
00323 #if !defined(__GNUC__) || (__GNUC__ > 3)
00324 template <>
00325 #endif
00326 template <>
00327 inline void Color4<unsigned char>::Import(const Point4<float> &b)
00328 {
00329 (*this)[0]=(unsigned char)(b[0]*255.0f);
00330 (*this)[1]=(unsigned char)(b[1]*255.0f);
00331 (*this)[2]=(unsigned char)(b[2]*255.0f);
00332 (*this)[3]=(unsigned char)(b[3]*255.0f);
00333 }
00334
00335 #if !defined(__GNUC__) || (__GNUC__ > 3)
00336 template <>
00337 #endif
00338 template <>
00339 inline Color4<unsigned char> Color4<unsigned char>::Construct( const Color4<float> & b )
00340 {
00341 return Color4<unsigned char>(
00342 (unsigned char)(b[0]*255.0f),
00343 (unsigned char)(b[1]*255.0f),
00344 (unsigned char)(b[2]*255.0f),
00345 (unsigned char)(b[3]*255.0f));
00346 }
00347
00348 #if !defined(__GNUC__) || (__GNUC__ > 3)
00349 template <>
00350 #endif
00351 template <>
00352 inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
00353 {
00354 return Color4<float>(
00355 (float)(b[0])/255.0f,
00356 (float)(b[1])/255.0f,
00357 (float)(b[2])/255.0f,
00358 (float)(b[3])/255.0f);
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 template<>
00371 inline Color4<unsigned char>::Color4(Color4<unsigned char>::ColorConstant cc)
00372 {
00373 *((int *)this )= cc;
00374 }
00375
00376 template<>
00377 inline Color4<float>::Color4(Color4<float>::ColorConstant cc)
00378 {
00379 Import(Color4<unsigned char>((Color4<unsigned char>::ColorConstant)cc));
00380 }
00381
00382 inline Color4<float> Clamp(Color4<float> &c)
00383 {
00384 c[0]=math::Clamp(c[0],0.0f,1.0f);
00385 c[1]=math::Clamp(c[1],0.0f,1.0f);
00386 c[2]=math::Clamp(c[2],0.0f,1.0f);
00387 c[3]=math::Clamp(c[3],0.0f,1.0f);
00388 return c;
00389 }
00390
00391 template<>
00392 inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
00393 {
00394 return Color4<unsigned char>(
00395 (unsigned char)(math::Clamp(int((*this)[0])+int(p[0]),0,255)),
00396 (unsigned char)(math::Clamp(int((*this)[1])+int(p[1]),0,255)),
00397 (unsigned char)(math::Clamp(int((*this)[2])+int(p[2]),0,255)),
00398 (unsigned char)(math::Clamp(int((*this)[3])+int(p[3]),0,255))
00399 );
00400 }
00401
00402
00403 typedef Color4<unsigned char> Color4b;
00404 typedef Color4<float> Color4f;
00405 typedef Color4<double> Color4d;
00406
00410 }
00411
00412 #endif