ColorModel.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <cstdlib>
00027 #endif
00028 
00029 #include "ColorModel.h"
00030 
00031 using namespace App;
00032 
00033 
00034 ColorModel::ColorModel (unsigned short usCt)
00035   : _usColors(usCt), _pclColors(0)
00036 {
00037     if (usCt > 0)
00038         _pclColors = new Color[usCt];
00039 }
00040 
00041 ColorModel::ColorModel (const ColorModel &rclM)
00042   : _pclColors(0)
00043 {
00044     *this = rclM;
00045 }
00046 
00047 ColorModel::~ColorModel ()
00048 {
00049     delete [] _pclColors;
00050 }
00051 
00052 ColorModel& ColorModel::operator = (const ColorModel &rclM)
00053 {
00054     // first check if both objects are identical
00055     if (this->_pclColors && this->_pclColors == rclM._pclColors)
00056         return *this;
00057 
00058     delete [] _pclColors;
00059 
00060     _usColors = rclM._usColors;
00061     if (_usColors == 0)
00062         return *this; 
00063 
00064     _pclColors = new Color[rclM._usColors];
00065     for (int i = 0; i < rclM._usColors; i++)
00066         _pclColors[i] = rclM._pclColors[i]; 
00067 
00068     return *this;
00069 }
00070 
00071 ColorField::ColorField (void)
00072   : _clModel(ColorModelTria())
00073 {
00074     set(ColorModelTria(), -1.0f, 1.0f, 13);
00075 }
00076 
00077 ColorField::ColorField (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt)
00078 : _clModel(ColorModelTria())
00079 {
00080     set(rclModel, fMin, fMax, usCt);
00081 }
00082 
00083 ColorField::~ColorField ()
00084 {
00085 }    
00086 
00087 ColorField::ColorField (const ColorField &rclCF)
00088   : _clModel(ColorModelTria())
00089 {
00090     *this = rclCF;
00091 }
00092 
00093 ColorField& ColorField::operator = (const ColorField &rclCF)
00094 {
00095     _aclField = rclCF._aclField;
00096     return *this;
00097 }
00098 
00099 void ColorField::set (const ColorModel &rclModel, float fMin, float fMax, unsigned short usCt)
00100 {
00101     _clModel = rclModel;
00102     _fMin = std::min<float>(fMin, fMax);
00103     _fMax = std::max<float>(_fMin + CCR_EPS, fMax);
00104     _usCtColors = std::max<unsigned short>(usCt, _clModel._usColors);
00105     rebuild();
00106 }
00107 
00108 void ColorField::setColorModel (const ColorModel &rclModel)
00109 {
00110     _clModel = rclModel;
00111     rebuild();
00112 }
00113 
00114 void ColorField::rebuild (void)
00115 {
00116     unsigned short usInd1, usInd2, usStep, i;
00117 
00118     _aclField.resize(_usCtColors);
00119 
00120 
00121     usStep = std::min<unsigned short>(_usCtColors / (_clModel._usColors-1), _usCtColors-1);
00122     usInd1 = 0;
00123     usInd2 = usStep;
00124     for (i = 0; i < (_clModel._usColors - 1); i++) {
00125         interpolate(_clModel._pclColors[i], usInd1, _clModel._pclColors[i+1], usInd2);
00126         usInd1 = usInd2;
00127         if ((i + 1) == (_clModel._usColors - 2))
00128             usInd2 = _usCtColors - 1;
00129         else
00130             usInd2 += usStep;
00131     }
00132 
00133     _fAscent   = float(_usCtColors) / (_fMax - _fMin);
00134     _fConstant = -_fAscent * _fMin;
00135 }
00136 
00137 // fuellt das Array von Farbe 1, Index 1 bis Farbe 2, Index 2
00138 void ColorField::interpolate (Color clCol1, unsigned short usInd1, Color clCol2, unsigned short usInd2)
00139 {
00140     unsigned short i;
00141     float ucR, ucG, ucB;
00142     float fR, fG, fB, fStep = 1.0f, fLen = float(usInd2 - usInd1);
00143 
00144     _aclField[usInd1] = clCol1;
00145     _aclField[usInd2] = clCol2;
00146 
00147     fR = (float(clCol2.r) - float(clCol1.r)) / fLen;
00148     fG = (float(clCol2.g) - float(clCol1.g)) / fLen;
00149     fB = (float(clCol2.b) - float(clCol1.b)) / fLen;
00150 
00151     for (i = (usInd1 + 1); i < usInd2; i++) {
00152         ucR = clCol1.r + fR * fStep;
00153         ucG = clCol1.g + fG * fStep;
00154         ucB = clCol1.b + fB * fStep;
00155         _aclField[i] = Color(ucR, ucG, ucB);
00156         fStep += 1.0f;
00157     }
00158 }
00159 
00160 
00161 ColorGradient::ColorGradient (void)
00162 :  _tColorModel(TRIA),
00163    _bOutsideGrayed(false),
00164    _clTotal(ColorModelTria()),
00165    _clTop(ColorModelTriaTop()),
00166    _clBottom(ColorModelTriaBottom())
00167 {
00168     setColorModel();
00169     set(-1.0f, 1.0f, 13, ZERO_BASED, false);
00170 }
00171 
00172 ColorGradient::ColorGradient (float fMin, float fMax, unsigned short usCtColors, TStyle tS, bool bOG)
00173 :  _tColorModel(TRIA),
00174    _bOutsideGrayed(false),
00175    _clTotal(ColorModelTria()),
00176    _clTop(ColorModelTriaTop()),
00177    _clBottom(ColorModelTriaBottom())
00178 {
00179     setColorModel();
00180     set(fMin, fMax, usCtColors, tS, bOG);
00181 }
00182 
00183 ColorGradient::ColorGradient (const ColorGradient &rclCR)
00184 :  _tColorModel(TRIA),
00185    _clTotal(ColorModelTria()),
00186    _clTop(ColorModelTriaTop()),
00187    _clBottom(ColorModelTriaBottom())
00188 {
00189     *this = rclCR;
00190 }
00191 
00192 ColorGradient& ColorGradient::operator = (const ColorGradient &rclCR)
00193 {
00194     _tColorModel    = rclCR._tColorModel;
00195     _clTotal        = rclCR._clTotal;
00196     _clTop          = rclCR._clTop;
00197     _clBottom       = rclCR._clBottom;
00198     _bOutsideGrayed = rclCR._bOutsideGrayed;
00199     _clColFld1      = rclCR._clColFld1;
00200     _clColFld2      = rclCR._clColFld2;
00201     _tStyle         = rclCR._tStyle;
00202     _fMin           = rclCR._fMin;
00203     _fMax           = rclCR._fMax;
00204     _usCtColors     = rclCR._usCtColors;
00205 
00206     return *this;
00207 }
00208 
00209 void ColorGradient::set (float fMin, float fMax, unsigned short usCt, TStyle tS, bool bOG)
00210 {
00211     _fMin = std::min<float>(fMin, fMax);
00212     _fMax = std::max<float>(_fMin + CCR_EPS, fMax);
00213     _usCtColors = std::max<unsigned short>(usCt, getMinColors());
00214     _tStyle = tS;
00215     _bOutsideGrayed = bOG;
00216     rebuild();
00217 }
00218 
00219 void ColorGradient::rebuild (void)
00220 {
00221     switch (_tStyle)
00222     {
00223         case FLOW:
00224         {
00225             _clColFld1.set(_clTotal, _fMin, _fMax, _usCtColors);
00226             break;
00227         }
00228         case ZERO_BASED:
00229         {
00230             if ((_fMin < 0.0f) && (_fMax > 0.0f))
00231             {
00232                 _clColFld1.set(_clBottom, _fMin, 0.0f, _usCtColors / 2);
00233                 _clColFld2.set(_clTop, 0.0f, _fMax, _usCtColors / 2);
00234             }
00235             else if (_fMin >= 0.0f)
00236                 _clColFld1.set(_clTop, 0.0f, _fMax, _usCtColors);
00237             else
00238                 _clColFld1.set(_clBottom, _fMin, 0.0f, _usCtColors);
00239             break;
00240         }
00241     }
00242 }
00243 
00244 unsigned short ColorGradient::getMinColors (void) const
00245 {
00246     switch (_tStyle)
00247     {
00248         case FLOW:   
00249             return _clColFld1.getMinColors();
00250         case ZERO_BASED: 
00251         {
00252             if ((_fMin < 0.0f) && (_fMax > 0.0f))
00253                 return _clColFld1.getMinColors() + _clColFld2.getMinColors();
00254             else
00255                 return _clColFld1.getMinColors();
00256         }
00257     }
00258     return 2;
00259 }
00260 
00261 void ColorGradient::setColorModel (TColorModel tModel)
00262 {
00263     _tColorModel = tModel;
00264     setColorModel();
00265     rebuild();
00266 }
00267 
00268 void ColorGradient::setColorModel (void)
00269 {
00270     switch (_tColorModel)
00271     {
00272         case TRIA:
00273         {
00274             _clTotal  = ColorModelTria(); 
00275             _clTop    = ColorModelTriaTop();
00276             _clBottom = ColorModelTriaBottom();
00277             break;
00278         }
00279         case INVERSE_TRIA:
00280         {
00281             _clTotal  = ColorModelInverseTria();
00282             _clTop    = ColorModelInverseTriaTop();
00283             _clBottom = ColorModelInverseTriaBottom();
00284             break;
00285         }
00286         case GRAY:
00287         {
00288             _clTotal  = ColorModelGray();
00289             _clTop    = ColorModelGrayTop();
00290             _clBottom = ColorModelGrayBottom();
00291             break;
00292         }
00293         case INVERSE_GRAY:
00294         {
00295             _clTotal  = ColorModelInverseGray();
00296             _clTop    = ColorModelInverseGrayTop();
00297             _clBottom = ColorModelInverseGrayBottom();
00298             break;
00299         }
00300     }
00301 
00302     switch (_tStyle)
00303     {
00304         case FLOW:   
00305         {
00306             _clColFld1.setColorModel(_clTotal);
00307             _clColFld2.setColorModel(_clBottom);
00308             break;
00309         }
00310         case ZERO_BASED: 
00311         {
00312             _clColFld1.setColorModel(_clTop);
00313             _clColFld2.setColorModel(_clBottom);
00314             break;
00315         }
00316     }
00317 }
00318 
00319 ColorLegend::ColorLegend (void)
00320 : _bOutsideGrayed(false)
00321 {
00322     // default  green, red
00323     _aclColorFields.push_back(Color(0, 1, 0));
00324     _aclColorFields.push_back(Color(1, 0, 0));
00325 
00326     _aclNames.push_back("Min");
00327     _aclNames.push_back("Max");
00328 
00329     _aclValues.push_back(-1.0f);
00330     _aclValues.push_back(0.0f);
00331     _aclValues.push_back(1.0f);
00332 }
00333 
00334 ColorLegend::ColorLegend (const ColorLegend &rclCL)
00335 {
00336     *this = rclCL;
00337 }
00338 
00339 ColorLegend& ColorLegend::operator = (const ColorLegend &rclCL)
00340 {
00341     _aclColorFields = rclCL._aclColorFields;
00342     _aclNames       = rclCL._aclNames;
00343     _aclValues      = rclCL._aclValues;
00344     _bOutsideGrayed = rclCL._bOutsideGrayed;
00345 
00346     return *this;
00347 }
00348 
00349 bool ColorLegend::operator == (const ColorLegend &rclCL) const
00350 {
00351   return (_aclColorFields.size() == rclCL._aclColorFields.size())                                     &&
00352          (_aclNames.size() == rclCL._aclNames.size())                                                 &&
00353          (_aclValues.size() == rclCL._aclValues.size())                                               &&
00354           std::equal(_aclColorFields.begin(), _aclColorFields.end(), rclCL._aclColorFields.begin())   &&
00355           std::equal(_aclNames.begin(), _aclNames.end(), rclCL._aclNames.begin())                     &&
00356           std::equal(_aclValues.begin(), _aclValues.end(), rclCL._aclValues.begin())                  &&
00357           _bOutsideGrayed == rclCL._bOutsideGrayed;
00358 }
00359 
00360 float ColorLegend::getValue (unsigned long ulPos) const
00361 {
00362     if (ulPos < _aclValues.size())
00363         return _aclValues[ulPos];
00364     else
00365         return 0.0f;
00366 }
00367 
00368 bool ColorLegend::setValue (unsigned long ulPos, float fVal)
00369 {
00370     if (ulPos < _aclValues.size())
00371     {
00372         _aclValues[ulPos] = fVal;
00373         return true;
00374     }
00375     else
00376         return false;
00377 }
00378 
00379 Color ColorLegend::getColor (unsigned long ulPos) const
00380 {
00381     if (ulPos < _aclColorFields.size())
00382         return _aclColorFields[ulPos];
00383     else
00384         return Color();
00385 }
00386 
00387 // color as: 0x00rrggbb
00388 uint32_t ColorLegend::getPackedColor (unsigned long ulPos) const
00389 {
00390     Color clRGB = getColor(ulPos);
00391     return clRGB.getPackedValue();
00392 }
00393 
00394 std::string ColorLegend::getText (unsigned long ulPos) const
00395 {
00396     if (ulPos < _aclNames.size())
00397         return _aclNames[ulPos];
00398     else
00399         return "";
00400 }
00401 
00402 bool ColorLegend::addMin (const std::string &rclName)
00403 {
00404     _aclNames.push_front(rclName);
00405     _aclValues.push_front(*_aclValues.begin() - 1.0f);
00406 
00407     Color clNewRGB;
00408     clNewRGB.r = ((float)rand() / (float)RAND_MAX);
00409     clNewRGB.g = ((float)rand() / (float)RAND_MAX);
00410     clNewRGB.b = ((float)rand() / (float)RAND_MAX);
00411 
00412     _aclColorFields.push_front(clNewRGB);
00413 
00414     return true;
00415 }
00416 
00417 bool ColorLegend::addMax (const std::string &rclName)
00418 {
00419     _aclNames.push_back(rclName);
00420     _aclValues.push_back(*(_aclValues.end()-1) + 1.0f);
00421 
00422     Color clNewRGB;
00423     clNewRGB.r = ((float)rand() / (float)RAND_MAX);
00424     clNewRGB.g = ((float)rand() / (float)RAND_MAX);
00425     clNewRGB.b = ((float)rand() / (float)RAND_MAX);
00426 
00427     _aclColorFields.push_back(clNewRGB);
00428 
00429     return true;
00430 }
00431 
00432 bool ColorLegend::remove (unsigned long ulPos)
00433 {
00434     if (ulPos < _aclColorFields.size())
00435     {
00436         _aclColorFields.erase(_aclColorFields.begin() + ulPos);
00437         _aclNames.erase(_aclNames.begin() + ulPos);
00438         _aclValues.erase(_aclValues.begin() + ulPos);
00439 
00440         return true;
00441     }
00442 
00443     return false;
00444 }
00445 
00446 void ColorLegend::removeFirst (void)
00447 {
00448     if (_aclColorFields.size() > 0)
00449     {
00450         _aclColorFields.erase(_aclColorFields.begin());
00451         _aclNames.erase(_aclNames.begin());
00452         _aclValues.erase(_aclValues.begin()); 
00453     }
00454 }
00455 
00456 void ColorLegend::removeLast (void)
00457 {
00458     if (_aclColorFields.size() > 0)
00459     {
00460         _aclColorFields.erase(_aclColorFields.end()-1);
00461         _aclNames.erase(_aclNames.end()-1);
00462         _aclValues.erase(_aclValues.end()-1); 
00463     }
00464 }
00465 
00466 void ColorLegend::resize (unsigned long ulCt)
00467 {
00468     if ((ulCt < 2) || (ulCt == _aclColorFields.size()))
00469         return;
00470 
00471     if (ulCt > _aclColorFields.size())
00472     {
00473         int k = ulCt - _aclColorFields.size();
00474         for (int i = 0; i < k; i++)
00475             addMin("new");
00476     }
00477     else
00478     {
00479         int k = _aclColorFields.size() - ulCt;
00480         for (int i = 0; i < k; i++)
00481             removeLast();
00482     }
00483 }
00484 
00485 bool ColorLegend::setColor (unsigned long ulPos, float ucRed, float ucGreen, float ucBlue)
00486 {
00487     if (ulPos < _aclNames.size())
00488     {
00489         _aclColorFields[ulPos] = Color(ucRed, ucGreen, ucBlue);
00490         return true;
00491     }
00492     else
00493         return false;
00494 }
00495 
00496 // color as 0x00rrggbb
00497 bool ColorLegend::setColor (unsigned long ulPos, unsigned long ulColor)
00498 {
00499     unsigned char ucRed   = (unsigned char)((ulColor & 0x00ff0000) >> 16);
00500     unsigned char ucGreen = (unsigned char)((ulColor & 0x0000ff00) >> 8);
00501     unsigned char ucBlue  = (unsigned char)(ulColor & 0x000000ff);
00502     return setColor(ulPos, ucRed, ucGreen, ucBlue);
00503 }
00504 
00505 bool ColorLegend::setText (unsigned long ulPos, const std::string &rclName)
00506 {
00507     if (ulPos < _aclNames.size())
00508     {
00509         _aclNames[ulPos] = rclName;
00510         return true;
00511     }
00512     else
00513         return false;
00514 }

Generated on Wed Nov 23 19:00:01 2011 for FreeCAD by  doxygen 1.6.1