diff --git a/modules/gfx/pymod/__init__.py b/modules/gfx/pymod/__init__.py index badf23fbe8a0f766abe5f2defd45fbc298c30765..6ab82321fa2809603dbabab5bbc96d4e60a955a1 100644 --- a/modules/gfx/pymod/__init__.py +++ b/modules/gfx/pymod/__init__.py @@ -18,24 +18,30 @@ #------------------------------------------------------------------------------ from _gfx import * -WHITE=Color(0xffffff) -BLACK=Color(0x000000) -GREY=Color(0x7f7f7f) -RED=Color(0xff0000) -DARKRED=Color(0x7f0000) -LIGHTRED=Color(0xff7f7f) -GREEN=Color(0x00ff00) -DARKGREEN=Color(0x007f00) -LIGHTGREEN=Color(0x7fff7f) -BLUE=Color(0x0000ff) -DARKBLUE=Color(0x00007f) -LIGHTBLUE=Color(0x7f7fff) -YELLOW=Color(0xffff00) -DARKYELLOW=Color(0x7f7f00) -LIGHTYELLOW=Color(0xffff7f) -CYAN=Color(0x00ffff) -DARKCYAN=Color(0x007f7f) -LIGHTCYAN=Color(0x7fffff) -MAGENTA=Color(0xff00ff) -DARKMAGENTA=Color(0x7f00ff) -LIGHTMAGENTA=Color(0xff7fff) +WHITE=Color(1.0,1.0,1.0) +BLACK=Color(0.0,0.0,0.0) +GREY=Color(0.5,0.5,0.5) +RED=Color(1.0,0.0,0.0) +DARKRED=Color(0.5,0.0,0.0) +LIGHTRED=Color(1.0,0.5,0.5) +GREEN=Color(0.0,1.0,0.0) +DARKGREEN=Color(0.0,0.5,0.0) +LIGHTGREEN=Color(0.5,1.0,0.5) +BLUE=Color(0.0,0.0,1.0) +DARKBLUE=Color(0.0,0.0,0.5) +LIGHTBLUE=Color(0.5,0.5,1.0) +YELLOW=Color(1.0,1.0,0.0) +DARKYELLOW=Color(0.5,0.5,0.0) +LIGHTYELLOW=Color(1.0,1.0,0.5) +CYAN=Color(0.0,1.0,1.0) +DARKCYAN=Color(0.0,0.5,0.5) +LIGHTCYAN=Color(0.5,1.0,1.0) +MAGENTA=Color(1.0,0.0,1.0) +DARKMAGENTA=Color(0.5,0.0,0.5) +LIGHTMAGENTA=Color(1.0,0.5,1.0) +PURPLE=MAGENTA +DARKPURPLE=DARKMAGENTA +LIGHTPURPLE=LIGHTMAGENTA +ORANGE=Color(1.0,0.5,0.0) +DARKORANGE=Color(0.5,0.25,0.0) +LIGHTORANGE=Color(1.0,0.75,0.5) diff --git a/modules/gfx/pymod/wrap_gfx.cc b/modules/gfx/pymod/wrap_gfx.cc index 7c3655aa3db2136236f7bd9e4096db485391fc0f..430c355952b06bedbd884b5ac48d44335ca4c29a 100644 --- a/modules/gfx/pymod/wrap_gfx.cc +++ b/modules/gfx/pymod/wrap_gfx.cc @@ -147,14 +147,17 @@ BOOST_PYTHON_MODULE(_gfx) class_<Color>("Color",init<>()) - .def(init<int>()) .def(init<float, float, float, optional<float> >()) .def(self_ns::str(self)) .def("Red",color_get_red) .def("Green",color_get_green) .def("Blue",color_get_blue) .def("Alpha",color_get_alpha) + .def("ToHSV",&Color::ToHSV) + .def("FromRGBA",&Color::FromRGB) ; + + def("HSV",HSV); class_<Gradient>("Gradient", init<>()) .def(init<const String&>()) diff --git a/modules/gfx/src/color.cc b/modules/gfx/src/color.cc index 45398f486a46a5e22ce1a9c2d12294fc04a15801..a1de8265e5599c41f4f49ef2384c8af0d86ebc30 100644 --- a/modules/gfx/src/color.cc +++ b/modules/gfx/src/color.cc @@ -26,12 +26,108 @@ namespace ost { namespace gfx { -Color::Color(uint code) + namespace { + // maps hsv to rgb (0-1) + geom::Vec3 HSVtoRGB(const geom::Vec3& hsv) + { + geom::Vec3 rgb; + if (hsv[1]<1e-9){ + rgb[0]=hsv[2]; + rgb[1]=hsv[2]; + rgb[2]=hsv[2]; + } else { + double var_h=hsv[0]*6.0<6.0?hsv[0]*6.0:0.0; + int var_i =static_cast<int>(var_h); + double var_1 = hsv[2]*(1-hsv[1]); + double var_2 = hsv[2]*(1-hsv[1]*( var_h -var_i)); + double var_3 = hsv[2]*(1-hsv[1]*(1-(var_h-var_i))); + switch(var_i){ + case 0: + rgb[0]=hsv[2]; + rgb[1]=var_3; + rgb[2]=var_1; + break; + case 1: + rgb[0] = var_2; + rgb[1] = hsv[2]; + rgb[2] = var_1; + break; + case 2: + rgb[0] = var_1; + rgb[1] = hsv[2]; + rgb[2] = var_3; + break; + case 3: + rgb[0] = var_1 ; + rgb[1] = var_2 ; + rgb[2] = hsv[2]; + break; + case 4: + rgb[0] = var_3 ; + rgb[1] = var_1 ; + rgb[2] = hsv[2]; + break; + case 5: + rgb[0] = hsv[2] ; + rgb[1] = var_1 ; + rgb[2] = var_2; + break; + } + } + return rgb; + } + + // maps rgb (0-1) to hsv + geom::Vec3 RGBtoHSV(const geom::Vec3& rgb) + { + geom::Vec3 hsv; + double var_R = ( rgb[0] / 255.0 ); + double var_G = ( rgb[1] / 255.0 ); + double var_B = ( rgb[2] / 255.0 ); + + double var_Min = std::min(std::min( var_R, var_G), var_B ); + double var_Max = std::max(std::max( var_R, var_G), var_B ); + double del_Max = var_Max - var_Min; + + hsv[2] = var_Max; + + if ( del_Max < 1.0e-9 ){ + hsv[0] = 0.0; + hsv[1] = 0.0; + } else { + hsv[1] = del_Max / var_Max; + double del_R = ( ( ( var_Max - var_R ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + double del_G = ( ( ( var_Max - var_G ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + double del_B = ( ( ( var_Max - var_B ) / 6.0 ) + ( del_Max / 2.0 ) ) / del_Max; + + if ( var_R == var_Max ){ + hsv[0] = del_B - del_G; + } else if ( var_G == var_Max ){ + hsv[0] = ( 1.0 / 3.0 ) + del_R - del_B; + } else if ( var_B == var_Max ){ + hsv[0] = ( 2.0 / 3.0 ) + del_G - del_R; + } + if ( hsv[0] < 0 ){ + hsv[0] += 1; + } + if ( hsv[0] > 1 ){ + hsv[0] -= 1; + } + } + return hsv; + } + } // anon ns + +geom::Vec3 Color::ToHSV() +{ + return RGBtoHSV(geom::Vec3(rgba[0],rgba[1],rgba[2])); +} + + +Color HSV(double h, double s, double v) { - rgba[0]=static_cast<float>((code>>24)&0xff)/255.0; - rgba[1]=static_cast<float>((code>>16)&0xff)/255.0; - rgba[2]=static_cast<float>((code>>8)&0xff)/255.0; - rgba[3]=static_cast<float>((code)&0xff)/255.0; + geom::Vec3 rgb=HSVtoRGB(geom::Vec3(h,s,v)); + return Color(rgb[0],rgb[1],rgb[2]); } std::ostream& operator<<(std::ostream& s, const Color& c) diff --git a/modules/gfx/src/color.hh b/modules/gfx/src/color.hh index e28ed58c56a93c7f7ed171983416f7481a8cc4a5..6592311f6a1b7a6fe2c503c8a8317553c0be296d 100644 --- a/modules/gfx/src/color.hh +++ b/modules/gfx/src/color.hh @@ -28,6 +28,7 @@ #include <boost/operators.hpp> #include <ost/gfx/module_config.hh> +#include <ost/geom/geom.hh> namespace ost { namespace gfx { @@ -51,8 +52,6 @@ public: rgba[3]=a; } - explicit Color(uint hex_code); - float& Red() {return rgba[0];} const float& Red() const {return rgba[0];} float& Green() {return rgba[1];} @@ -68,7 +67,8 @@ public: return Color(f*static_cast<float>(r),f*static_cast<float>(g), f*static_cast<float>(b),f*static_cast<float>(a)); } - //static Color HSB(); + + geom::Vec3 ToHSV(); // these also take care of operator[](uint i) ! operator float* () {return rgba;} @@ -85,6 +85,8 @@ private: float rgba[4]; }; +Color HSV(double h, double s, double v); + DLLEXPORT_OST_GFX std::ostream& operator<<(std::ostream&, const Color& c); }}