/*************************************************************************** * Copyright (c) 2005 Werner Mayer * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef APP_COLORMODEL_H #define APP_COLORMODEL_H #include "Material.h" #include #include #include #include #define CCR_EPS 1.0e-5f namespace App { /** * Abstract base class that calculates the matching RGB color to a given value. */ class AppExport ValueFloatToRGB { public: virtual Color getColor(float fVal) const = 0; protected: ValueFloatToRGB (void) {} virtual ~ValueFloatToRGB () {} }; class AppExport ColorModel { public: ColorModel (unsigned short usCt); ColorModel (const ColorModel &rclM); virtual ~ColorModel (); ColorModel& operator = (const ColorModel &rclM); unsigned short _usColors; Color *_pclColors; }; class AppExport ColorModelTria : public ColorModel { public: ColorModelTria (void) : ColorModel(5) { _pclColors[0] = Color( 0, 0, 1); _pclColors[1] = Color( 0, 1, 1); _pclColors[2] = Color( 0, 1, 0); _pclColors[3] = Color( 1, 1, 0); _pclColors[4] = Color( 1, 0, 0); } }; class AppExport ColorModelTriaBottom : public ColorModel { public: ColorModelTriaBottom (void) : ColorModel(3) { _pclColors[0] = Color( 0, 0, 1); _pclColors[1] = Color( 0, 1, 1); _pclColors[2] = Color( 0, 1, 0); } }; class AppExport ColorModelTriaTop : public ColorModel { public: ColorModelTriaTop (void) : ColorModel(3) { _pclColors[0] = Color( 0, 1, 0); _pclColors[1] = Color( 1, 1, 0); _pclColors[2] = Color( 1, 0, 0); } }; class AppExport ColorModelInverseTria : public ColorModel { public: ColorModelInverseTria (void) : ColorModel(5) { _pclColors[0] = Color( 1, 0, 0); _pclColors[1] = Color( 1, 1, 0); _pclColors[2] = Color( 0, 1, 0); _pclColors[3] = Color( 0, 1, 1); _pclColors[4] = Color( 0, 0, 1); } }; class AppExport ColorModelInverseTriaTop : public ColorModel { public: ColorModelInverseTriaTop (void) : ColorModel(3) { _pclColors[2] = Color( 0, 0, 1); _pclColors[1] = Color( 0, 1, 1); _pclColors[0] = Color( 0, 1, 0); } }; class AppExport ColorModelInverseTriaBottom : public ColorModel { public: ColorModelInverseTriaBottom (void) : ColorModel(3) { _pclColors[2] = Color( 0, 1, 0); _pclColors[1] = Color( 1, 1, 0); _pclColors[0] = Color( 1, 0, 0); } }; class AppExport ColorModelGray : public ColorModel { public: ColorModelGray (void) : ColorModel(2) { _pclColors[0] = Color( 0, 0, 0); _pclColors[1] = Color( 1, 1, 1); } }; class AppExport ColorModelGrayBottom : public ColorModel { public: ColorModelGrayBottom (void) : ColorModel(2) { _pclColors[0] = Color( 0.0f, 0.0f, 0.0f); _pclColors[1] = Color( 0.5f, 0.5f, 0.5f); } }; class AppExport ColorModelGrayTop : public ColorModel { public: ColorModelGrayTop (void) : ColorModel(2) { _pclColors[0] = Color( 0.5f, 0.5f, 0.5f); _pclColors[1] = Color( 1.0f, 1.0f, 1.0f); } }; class AppExport ColorModelInverseGray : public ColorModel { public: ColorModelInverseGray (void) : ColorModel(2) { _pclColors[0] = Color( 1, 1, 1); _pclColors[1] = Color( 0, 0, 0); } }; class AppExport ColorModelInverseGrayBottom : public ColorModel { public: ColorModelInverseGrayBottom (void) : ColorModel(2) { _pclColors[0] = Color( 1.0f, 1.0f, 1.0f); _pclColors[1] = Color( 0.5f, 0.5f, 0.5f); } }; class AppExport ColorModelInverseGrayTop : public ColorModel { public: ColorModelInverseGrayTop (void) : ColorModel(2) { _pclColors[0] = Color( 0.5f, 0.5f, 0.5f); _pclColors[1] = Color( 0.0f, 0.0f, 0.0f); } }; class AppExport ColorField { public: ColorField (void); ColorField (const ColorField &rclCF); ColorField (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt); virtual ~ColorField (); ColorField& operator = (const ColorField &rclCF); unsigned short getCountColors (void) const { return _usCtColors; } void set (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt); void setCountColors (unsigned short usCt) { set(_clModel, _fMin, _fMax, usCt); } void setRange (float fMin, float fMax) { set(_clModel, fMin, fMax, _usCtColors); } void getRange (float &rfMin, float &rfMax) { rfMin = _fMin; rfMax = _fMax; } unsigned short getMinColors (void) const { return _clModel._usColors; } void setColorModel (const ColorModel &rclModel); const ColorModel& getColorModel (void) const { return _clModel; } void setDirect (unsigned short usInd, Color clCol) { _aclField[usInd] = clCol; } float getMinValue (void) const { return _fMin; } float getMaxValue (void) const { return _fMax; } Color getColor (unsigned short usIndex) const { return _aclField[usIndex]; } inline Color getColor (float fVal) const; inline unsigned short getColorIndex (float fVal) const; protected: ColorModel _clModel; float _fMin, _fMax; float _fAscent, _fConstant; // Index := _fConstant + _fAscent * WERT unsigned short _usCtColors; std::vector _aclField; void rebuild (void); void interpolate (Color clCol1, unsigned short usPos1, Color clCol2, unsigned short usPos2); }; inline Color ColorField::getColor (float fVal) const { #if 1 // if the value is outside or at the border of the range unsigned short ct = _clModel._usColors-1; if ( fVal <= _fMin ) return _clModel._pclColors[0]; else if ( fVal >= _fMax ) return _clModel._pclColors[ct]; // get the color field position (with 0 < t < 1) float t = (fVal-_fMin) / (_fMax-_fMin); Color col(1.0f, 1.0f, 1.0f); // white as default for ( unsigned short i=0; i(std::max(int(_fConstant + _fAscent * fVal), 0), int(_usCtColors-1))); } class AppExport ColorGradient { public: enum TStyle { FLOW, ZERO_BASED }; enum TColorModel { TRIA, INVERSE_TRIA, GRAY, INVERSE_GRAY }; ColorGradient (void); ColorGradient (float fMin, float fMax, unsigned short usCtColors, TStyle tS, bool bOG = false); ColorGradient (const ColorGradient &rclCR); ColorGradient& operator = (const ColorGradient &rclCR); void set (float fMin, float fMax, unsigned short usCt, TStyle tS, bool bOG); void setRange (float fMin, float fMax) { set(fMin, fMax, _usCtColors, _tStyle, _bOutsideGrayed); } void getRange (float &rfMin, float &rfMax) const { rfMin = _fMin; rfMax = _fMax; } unsigned short getCountColors (void) const { return _usCtColors; } void setCountColors (unsigned short usCt) { set(_fMin, _fMax, usCt, _tStyle, _bOutsideGrayed); } void setStyle (TStyle tS) { set(_fMin, _fMax, _usCtColors, tS, _bOutsideGrayed); } unsigned short getMinColors (void) const; TStyle getStyle (void) const { return _tStyle; } void setOutsideGrayed (bool bGrayed) { _bOutsideGrayed = bGrayed; } bool isOutsideGrayed (void) const { return _bOutsideGrayed; } void setColorModel (TColorModel tModel); TColorModel getColorModelType (void) const { return _tColorModel; } inline const ColorModel& getColorModel (void) const; float getMinValue (void) const { return _fMin; } float getMaxValue (void) const { return _fMax; } inline Color getColor (float fVal) const; inline unsigned short getColorIndex (float fVal) const; protected: ColorField _clColFld1, _clColFld2; TColorModel _tColorModel; TStyle _tStyle; float _fMin, _fMax; unsigned short _usCtColors; bool _bOutsideGrayed; ColorModel _clTotal, _clTop, _clBottom; void rebuild (void); void setColorModel (void); }; class AppExport ColorLegend { public: ColorLegend (void); ColorLegend (const ColorLegend &rclCL); virtual ~ColorLegend () {} ColorLegend& operator = (const ColorLegend &rclCL); bool operator == (const ColorLegend &rclCL) const; bool operator != (const ColorLegend &rclCL) const { return !(*this == rclCL); } void resize (unsigned long ulN); bool addMin (const std::string &rclName); bool addMax (const std::string &rclName); bool remove (unsigned long ulPos); void removeFirst (void); void removeLast (void); Color getColor (unsigned long ulPos) const; uint32_t getPackedColor (unsigned long ulPos) const; bool setColor (unsigned long ulPos, float ucRed, float ucGreen, float ucBlue); bool setColor (unsigned long ulPos, unsigned long ulColor); float getValue (unsigned long ulPos) const; bool setValue (unsigned long ulPos, float fVal); std::string getText (unsigned long ulPos) const; bool setText (unsigned long ulPos, const std::string &rclName); unsigned long hasNumberOfFields (void) const { return (unsigned long)_aclColorFields.size(); } void setOutsideGrayed (bool bOS) { _bOutsideGrayed = bOS; } bool isOutsideGrayed (void) const { return _bOutsideGrayed; } inline float getMinValue (void) const; inline float getMaxValue (void) const; inline Color getColor (float fVal) const; inline unsigned short getColorIndex (float fVal) const; protected: std::deque _aclColorFields; std::deque _aclNames; std::deque _aclValues; bool _bOutsideGrayed; }; inline Color ColorLegend::getColor (float fVal) const { std::deque::const_iterator pI; for (pI = _aclValues.begin(); pI != _aclValues.end(); ++pI) { if (fVal < *pI) break; } if (_bOutsideGrayed == true) { if ((pI == _aclValues.begin()) || (pI == _aclValues.end())) return Color(0.5f, 0.5f, 0.5f); else return _aclColorFields[pI - _aclValues.begin() - 1]; } if (pI == _aclValues.begin()) return *_aclColorFields.begin(); else if (pI == _aclValues.end()) return *(_aclColorFields.end()-1); else return _aclColorFields[pI - _aclValues.begin() - 1]; } inline unsigned short ColorLegend::getColorIndex (float fVal) const { std::deque::const_iterator pI; for (pI = _aclValues.begin(); pI != _aclValues.end(); ++pI) { if (fVal < *pI) break; } if (pI == _aclValues.begin()) return 0; else if (pI == _aclValues.end()) return (unsigned short)(_aclColorFields.size() - 1); else return pI - _aclValues.begin() - 1; } inline float ColorLegend::getMinValue (void) const { return *_aclValues.begin(); } inline float ColorLegend::getMaxValue (void) const { return *(_aclValues.end()-1); } inline Color ColorGradient::getColor (float fVal) const { if (_bOutsideGrayed == true) { if ((fVal < _fMin) || (fVal > _fMax)) return Color(0.5f, 0.5f, 0.5f); } switch (_tStyle) { case ZERO_BASED: { if ((_fMin < 0.0f) && (_fMax > 0.0f)) { if (fVal < 0.0f) return _clColFld1.getColor(fVal); else return _clColFld2.getColor(fVal); } else return _clColFld1.getColor(fVal); } default: case FLOW: { return _clColFld1.getColor(fVal); } } } inline unsigned short ColorGradient::getColorIndex (float fVal) const { switch (_tStyle) { case ZERO_BASED: { if ((_fMin < 0.0f) && (_fMax > 0.0f)) { if (fVal < 0.0f) return _clColFld1.getColorIndex(fVal); else return (unsigned short)(_clColFld1.getCountColors() + _clColFld2.getColorIndex(fVal)); } else return _clColFld1.getColorIndex(fVal); } default: case FLOW: { return _clColFld1.getColorIndex(fVal); } } } inline const ColorModel& ColorGradient::getColorModel (void) const { if ( _tStyle == ZERO_BASED ) { if ( _fMax <= 0.0f ) return _clBottom; else if ( _fMin >= 0.0f ) return _clTop; else return _clTotal; } else { return _clTotal; } } } // namespace App #endif // APP_COLORMODEL_H