00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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
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
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 }