From ecac0b4d0c2464dfea7d3b8555fe13d849733840 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 29 Jan 2022 15:29:07 +0100 Subject: [PATCH] App: rework ColorGradient and allow to easily extend it with further color models --- src/App/ColorModel.cpp | 151 +++++++++++-------- src/App/ColorModel.h | 187 +++++++++++++++--------- src/Gui/DlgSettingsColorGradientImp.cpp | 38 ++--- src/Gui/DlgSettingsColorGradientImp.h | 5 +- src/Gui/SoFCColorGradient.cpp | 7 +- src/Gui/SoFCColorGradient.h | 5 +- src/Gui/SoFCColorLegend.cpp | 6 +- src/Gui/SoFCColorLegend.h | 5 +- 8 files changed, 235 insertions(+), 169 deletions(-) diff --git a/src/App/ColorModel.cpp b/src/App/ColorModel.cpp index 99731c15fe..555e4a1510 100644 --- a/src/App/ColorModel.cpp +++ b/src/App/ColorModel.cpp @@ -31,15 +31,57 @@ using namespace App; +ColorModelPack ColorModelPack::createRedGreenBlue() +{ + ColorModelPack pack{ColorModelBlueGreenRed(), + ColorModelGreenYellowRed(), + ColorModelBlueCyanGreen(), + "Red-Yellow-Green-Cyan-Blue"}; + return pack; +} + +ColorModelPack ColorModelPack::createBlueGreenRed() +{ + ColorModelPack pack{ColorModelRedGreenBlue(), + ColorModelGreenCyanBlue(), + ColorModelRedYellowGreen(), + "Blue-Cyan-Green-Yellow-Red"}; + return pack; +} + +ColorModelPack ColorModelPack::createWhiteBlack() +{ + ColorModelPack pack{ColorModelBlackWhite(), + ColorModelGrayWhite(), + ColorModelBlackGray(), + "White-Black"}; + return pack; +} + +ColorModelPack ColorModelPack::createBlackWhite() +{ + ColorModelPack pack{ColorModelWhiteBlack(), + ColorModelGrayBlack(), + ColorModelWhiteGray(), + "Black-White"}; + return pack; +} + +ColorModelPack ColorModelPack::createRedWhiteBlue() +{ + ColorModelPack pack{ColorModelBlueWhiteRed(), + ColorModelWhiteRed(), + ColorModelBlueWhite(), + "Red-White-Blue"}; + return pack; +} ColorField::ColorField () - : colorModel(ColorModelTria()) { - set(ColorModelTria(), -1.0f, 1.0f, 13); + set(ColorModelBlueGreenRed(), -1.0f, 1.0f, 13); } ColorField::ColorField (const ColorModel &rclModel, float fMin, float fMax, std::size_t usCt) - : colorModel(ColorModelTria()) { set(rclModel, fMin, fMax, usCt); } @@ -124,29 +166,43 @@ void ColorField::interpolate (Color clCol1, std::size_t usInd1, Color clCol2, st ColorGradient::ColorGradient () -: tColorModel(TRIA), - tStyle(ZERO_BASED), +: tStyle(ZERO_BASED), outsideGrayed(false), - totalModel(ColorModelTria()), - topModel(ColorModelTriaTop()), - bottomModel(ColorModelTriaBottom()) + tColorModel(0) { + createStandardPacks(); setColorModel(); set(-1.0f, 1.0f, 13, ZERO_BASED, false); } ColorGradient::ColorGradient (float fMin, float fMax, std::size_t usCtColors, TStyle tS, bool bOG) -: tColorModel(TRIA), - tStyle(tS), +: tStyle(tS), outsideGrayed(false), - totalModel(ColorModelTria()), - topModel(ColorModelTriaTop()), - bottomModel(ColorModelTriaBottom()) + tColorModel(0) { + createStandardPacks(); setColorModel(); set(fMin, fMax, usCtColors, tS, bOG); } +void ColorGradient::createStandardPacks() +{ + modelPacks.push_back(ColorModelPack::createRedGreenBlue()); + modelPacks.push_back(ColorModelPack::createBlueGreenRed()); + modelPacks.push_back(ColorModelPack::createRedWhiteBlue()); + modelPacks.push_back(ColorModelPack::createWhiteBlack()); + modelPacks.push_back(ColorModelPack::createBlackWhite()); +} + +std::vector ColorGradient::getColorModelNames() const +{ + std::vector names; + names.reserve(modelPacks.size()); + for (const auto& it : modelPacks) + names.push_back(it.description); + return names; +} + void ColorGradient::set (float fMin, float fMax, std::size_t usCt, TStyle tS, bool bOG) { _fMin = std::min(fMin, fMax); @@ -163,20 +219,20 @@ void ColorGradient::rebuild () { case FLOW: { - colorField1.set(totalModel, _fMin, _fMax, ctColors); + colorField1.set(currentModelPack.totalModel, _fMin, _fMax, ctColors); break; } case ZERO_BASED: { if ((_fMin < 0.0f) && (_fMax > 0.0f)) { - colorField1.set(bottomModel, _fMin, 0.0f, ctColors / 2); - colorField2.set(topModel, 0.0f, _fMax, ctColors / 2); + colorField1.set(currentModelPack.bottomModel, _fMin, 0.0f, ctColors / 2); + colorField2.set(currentModelPack.topModel, 0.0f, _fMax, ctColors / 2); } else if (_fMin >= 0.0f) - colorField1.set(topModel, 0.0f, _fMax, ctColors); + colorField1.set(currentModelPack.topModel, 0.0f, _fMax, ctColors); else - colorField1.set(bottomModel, _fMin, 0.0f, ctColors); + colorField1.set(currentModelPack.bottomModel, _fMin, 0.0f, ctColors); break; } } @@ -199,7 +255,7 @@ std::size_t ColorGradient::getMinColors () const return 2; } -void ColorGradient::setColorModel (TColorModel tModel) +void ColorGradient::setColorModel (std::size_t tModel) { tColorModel = tModel; setColorModel(); @@ -208,52 +264,23 @@ void ColorGradient::setColorModel (TColorModel tModel) void ColorGradient::setColorModel () { - switch (tColorModel) - { - case TRIA: - { - totalModel = ColorModelTria(); - topModel = ColorModelTriaTop(); - bottomModel = ColorModelTriaBottom(); - break; - } - case INVERSE_TRIA: - { - totalModel = ColorModelInverseTria(); - topModel = ColorModelInverseTriaTop(); - bottomModel = ColorModelInverseTriaBottom(); - break; - } - case GRAY: - { - totalModel = ColorModelGray(); - topModel = ColorModelGrayTop(); - bottomModel = ColorModelGrayBottom(); - break; - } - case INVERSE_GRAY: - { - totalModel = ColorModelInverseGray(); - topModel = ColorModelInverseGrayTop(); - bottomModel = ColorModelInverseGrayBottom(); - break; - } - } + if (tColorModel < modelPacks.size()) + currentModelPack = modelPacks[tColorModel]; switch (tStyle) { - case FLOW: - { - colorField1.setColorModel(totalModel); - colorField2.setColorModel(bottomModel); - break; - } - case ZERO_BASED: - { - colorField1.setColorModel(topModel); - colorField2.setColorModel(bottomModel); - break; - } + case FLOW: + { + colorField1.setColorModel(currentModelPack.totalModel); + colorField2.setColorModel(currentModelPack.bottomModel); + break; + } + case ZERO_BASED: + { + colorField1.setColorModel(currentModelPack.topModel); + colorField2.setColorModel(currentModelPack.bottomModel); + break; + } } } diff --git a/src/App/ColorModel.h b/src/App/ColorModel.h index 270303e860..b0b9efff61 100644 --- a/src/App/ColorModel.h +++ b/src/App/ColorModel.h @@ -53,6 +53,7 @@ protected: class AppExport ColorModel { public: + ColorModel() = default; ColorModel (std::size_t usCt) { colors.resize(usCt); } @@ -65,136 +66,184 @@ public: std::vector colors; }; -class AppExport ColorModelTria : public ColorModel +class AppExport ColorModelBlueGreenRed : public ColorModel { public: - ColorModelTria () : ColorModel(5) + ColorModelBlueGreenRed () : ColorModel(5) { - colors[0] = Color( 0, 0, 1); - colors[1] = Color( 0, 1, 1); - colors[2] = Color( 0, 1, 0); - colors[3] = Color( 1, 1, 0); - colors[4] = Color( 1, 0, 0); + colors[0] = Color(0, 0, 1); + colors[1] = Color(0, 1, 1); + colors[2] = Color(0, 1, 0); + colors[3] = Color(1, 1, 0); + colors[4] = Color(1, 0, 0); } }; -class AppExport ColorModelTriaBottom : public ColorModel +class AppExport ColorModelBlueCyanGreen : public ColorModel { public: - ColorModelTriaBottom () : ColorModel(3) + ColorModelBlueCyanGreen () : ColorModel(3) { - colors[0] = Color( 0, 0, 1); - colors[1] = Color( 0, 1, 1); - colors[2] = Color( 0, 1, 0); + colors[0] = Color(0, 0, 1); + colors[1] = Color(0, 1, 1); + colors[2] = Color(0, 1, 0); } }; -class AppExport ColorModelTriaTop : public ColorModel +class AppExport ColorModelGreenYellowRed : public ColorModel { public: - ColorModelTriaTop () : ColorModel(3) + ColorModelGreenYellowRed () : ColorModel(3) { - colors[0] = Color( 0, 1, 0); - colors[1] = Color( 1, 1, 0); - colors[2] = Color( 1, 0, 0); + colors[0] = Color(0, 1, 0); + colors[1] = Color(1, 1, 0); + colors[2] = Color(1, 0, 0); } }; -class AppExport ColorModelInverseTria : public ColorModel +class AppExport ColorModelRedGreenBlue : public ColorModel { public: - ColorModelInverseTria () : ColorModel(5) + ColorModelRedGreenBlue () : ColorModel(5) { - colors[0] = Color( 1, 0, 0); - colors[1] = Color( 1, 1, 0); - colors[2] = Color( 0, 1, 0); - colors[3] = Color( 0, 1, 1); - colors[4] = Color( 0, 0, 1); + colors[0] = Color(1, 0, 0); + colors[1] = Color(1, 1, 0); + colors[2] = Color(0, 1, 0); + colors[3] = Color(0, 1, 1); + colors[4] = Color(0, 0, 1); } }; -class AppExport ColorModelInverseTriaTop : public ColorModel +class AppExport ColorModelGreenCyanBlue : public ColorModel { public: - ColorModelInverseTriaTop () : ColorModel(3) + ColorModelGreenCyanBlue () : ColorModel(3) { - colors[2] = Color( 0, 0, 1); - colors[1] = Color( 0, 1, 1); - colors[0] = Color( 0, 1, 0); + colors[0] = Color(0, 1, 0); + colors[1] = Color(0, 1, 1); + colors[2] = Color(0, 0, 1); } }; -class AppExport ColorModelInverseTriaBottom : public ColorModel +class AppExport ColorModelRedYellowGreen : public ColorModel { public: - ColorModelInverseTriaBottom () : ColorModel(3) + ColorModelRedYellowGreen () : ColorModel(3) { - colors[2] = Color( 0, 1, 0); - colors[1] = Color( 1, 1, 0); - colors[0] = Color( 1, 0, 0); + colors[0] = Color(1, 0, 0); + colors[1] = Color(1, 1, 0); + colors[2] = Color(0, 1, 0); } }; -class AppExport ColorModelGray : public ColorModel +class AppExport ColorModelBlueWhiteRed : public ColorModel { public: - ColorModelGray () : ColorModel(2) + ColorModelBlueWhiteRed () : ColorModel(5) { - colors[0] = Color( 0, 0, 0); - colors[1] = Color( 1, 1, 1); + colors[0] = Color(0, 0, 1); + colors[1] = Color(85.0/255, 170.0/255, 1); + colors[2] = Color(1, 1, 1); + colors[3] = Color(1, 85.0/255, 0); + colors[4] = Color(1, 0, 0); } }; -class AppExport ColorModelGrayBottom : public ColorModel +class AppExport ColorModelBlueWhite : public ColorModel { public: - ColorModelGrayBottom () : ColorModel(2) + ColorModelBlueWhite () : ColorModel(3) { - colors[0] = Color( 0.0f, 0.0f, 0.0f); - colors[1] = Color( 0.5f, 0.5f, 0.5f); + colors[0] = Color(0, 0, 1); + colors[1] = Color(85.0/255, 170.0/255, 1); + colors[2] = Color(1, 1, 1); } }; -class AppExport ColorModelGrayTop : public ColorModel +class AppExport ColorModelWhiteRed : public ColorModel { public: - ColorModelGrayTop () : ColorModel(2) + ColorModelWhiteRed () : ColorModel(3) { - colors[0] = Color( 0.5f, 0.5f, 0.5f); - colors[1] = Color( 1.0f, 1.0f, 1.0f); + colors[0] = Color(1, 1, 1); + colors[1] = Color(1, 85.0/255, 0); + colors[2] = Color(0, 1, 0); } }; -class AppExport ColorModelInverseGray : public ColorModel +class AppExport ColorModelBlackWhite : public ColorModel { public: - ColorModelInverseGray () : ColorModel(2) + ColorModelBlackWhite () : ColorModel(2) { - colors[0] = Color( 1, 1, 1); - colors[1] = Color( 0, 0, 0); + colors[0] = Color(0, 0, 0); + colors[1] = Color(1, 1, 1); } }; -class AppExport ColorModelInverseGrayBottom : public ColorModel +class AppExport ColorModelBlackGray : public ColorModel { public: - ColorModelInverseGrayBottom () : ColorModel(2) + ColorModelBlackGray () : ColorModel(2) { - colors[0] = Color( 1.0f, 1.0f, 1.0f); - colors[1] = Color( 0.5f, 0.5f, 0.5f); + colors[0] = Color(0.0f, 0.0f, 0.0f); + colors[1] = Color(0.5f, 0.5f, 0.5f); } }; -class AppExport ColorModelInverseGrayTop : public ColorModel +class AppExport ColorModelGrayWhite : public ColorModel { public: - ColorModelInverseGrayTop () : ColorModel(2) + ColorModelGrayWhite () : ColorModel(2) { - colors[0] = Color( 0.5f, 0.5f, 0.5f); - colors[1] = Color( 0.0f, 0.0f, 0.0f); + colors[0] = Color(0.5f, 0.5f, 0.5f); + colors[1] = Color(1.0f, 1.0f, 1.0f); } }; +class AppExport ColorModelWhiteBlack : public ColorModel +{ +public: + ColorModelWhiteBlack () : ColorModel(2) + { + colors[0] = Color(1, 1, 1); + colors[1] = Color(0, 0, 0); + } +}; + +class AppExport ColorModelWhiteGray : public ColorModel +{ +public: + ColorModelWhiteGray () : ColorModel(2) + { + colors[0] = Color(1.0f, 1.0f, 1.0f); + colors[1] = Color(0.5f, 0.5f, 0.5f); + } +}; + +class AppExport ColorModelGrayBlack : public ColorModel +{ +public: + ColorModelGrayBlack () : ColorModel(2) + { + colors[0] = Color(0.5f, 0.5f, 0.5f); + colors[1] = Color(0.0f, 0.0f, 0.0f); + } +}; + +struct AppExport ColorModelPack +{ + ColorModel totalModel = ColorModelBlueGreenRed(); + ColorModel topModel = ColorModelGreenYellowRed(); + ColorModel bottomModel = ColorModelBlueCyanGreen(); + std::string description; + static ColorModelPack createRedGreenBlue(); + static ColorModelPack createBlueGreenRed(); + static ColorModelPack createWhiteBlack(); + static ColorModelPack createBlackWhite(); + static ColorModelPack createRedWhiteBlue(); +}; + class AppExport ColorField { public: @@ -273,7 +322,6 @@ class AppExport ColorGradient { public: enum TStyle { FLOW, ZERO_BASED }; - enum TColorModel { TRIA, INVERSE_TRIA, GRAY, INVERSE_GRAY }; ColorGradient (); ColorGradient (float fMin, float fMax, std::size_t usCtColors, TStyle tS, bool bOG = false); @@ -290,23 +338,28 @@ public: TStyle getStyle () const { return tStyle; } void setOutsideGrayed (bool bGrayed) { outsideGrayed = bGrayed; } bool isOutsideGrayed () const { return outsideGrayed; } - void setColorModel (TColorModel tModel); - TColorModel getColorModelType () const { return tColorModel; } + void setColorModel (std::size_t tModel); + std::size_t getColorModelType () const { return tColorModel; } inline const ColorModel& getColorModel () const; + std::vector getColorModelNames() const; float getMinValue () const { return _fMin; } float getMaxValue () const { return _fMax; } inline Color getColor (float fVal) const; inline std::size_t getColorIndex (float fVal) const; +protected: + void createStandardPacks(); + protected: ColorField colorField1, colorField2; - TColorModel tColorModel; TStyle tStyle; float _fMin, _fMax; std::size_t ctColors; bool outsideGrayed; - ColorModel totalModel, topModel, bottomModel; + std::size_t tColorModel; + ColorModelPack currentModelPack; + std::vector modelPacks; void rebuild (); void setColorModel (); @@ -467,15 +520,15 @@ inline const ColorModel& ColorGradient::getColorModel () const if ( tStyle == ZERO_BASED ) { if ( _fMax <= 0.0f ) - return bottomModel; + return currentModelPack.bottomModel; else if ( _fMin >= 0.0f ) - return topModel; + return currentModelPack.topModel; else - return totalModel; + return currentModelPack.totalModel; } else { - return totalModel; + return currentModelPack.totalModel; } } diff --git a/src/Gui/DlgSettingsColorGradientImp.cpp b/src/Gui/DlgSettingsColorGradientImp.cpp index f0bdcaad35..a7d320f421 100644 --- a/src/Gui/DlgSettingsColorGradientImp.cpp +++ b/src/Gui/DlgSettingsColorGradientImp.cpp @@ -63,36 +63,22 @@ DlgSettingsColorGradientImp::~DlgSettingsColorGradientImp() // no need to delete child widgets, Qt does it all for us } -void DlgSettingsColorGradientImp::setColorModel( App::ColorGradient::TColorModel tModel) +void DlgSettingsColorGradientImp::setColorModel(std::size_t index) { - switch (tModel) - { - case App::ColorGradient::TRIA: - ui->comboBoxModel->setCurrentIndex(0); - break; - case App::ColorGradient::INVERSE_TRIA: - ui->comboBoxModel->setCurrentIndex(1); - break; - case App::ColorGradient::GRAY: - ui->comboBoxModel->setCurrentIndex(2); - break; - case App::ColorGradient::INVERSE_GRAY: - ui->comboBoxModel->setCurrentIndex(3); - break; - } + ui->comboBoxModel->setCurrentIndex(index); } -App::ColorGradient::TColorModel DlgSettingsColorGradientImp::colorModel() const +std::size_t DlgSettingsColorGradientImp::colorModel() const { - int item = ui->comboBoxModel->currentIndex(); - if ( item == 0 ) - return App::ColorGradient::TRIA; - else if ( item == 1 ) - return App::ColorGradient::INVERSE_TRIA; - else if ( item == 2 ) - return App::ColorGradient::GRAY; - else - return App::ColorGradient::INVERSE_GRAY; + return static_cast(ui->comboBoxModel->currentIndex()); +} + +void DlgSettingsColorGradientImp::setColorModelNames(const std::vector& names) +{ + ui->comboBoxModel->clear(); + for (const auto& it : names) { + ui->comboBoxModel->addItem(QString::fromStdString(it)); + } } void DlgSettingsColorGradientImp::setColorStyle( App::ColorGradient::TStyle tStyle ) diff --git a/src/Gui/DlgSettingsColorGradientImp.h b/src/Gui/DlgSettingsColorGradientImp.h index 986ab3d7bf..c4412c5888 100644 --- a/src/Gui/DlgSettingsColorGradientImp.h +++ b/src/Gui/DlgSettingsColorGradientImp.h @@ -51,8 +51,9 @@ public: /** @name Color model */ //@{ - void setColorModel( App::ColorGradient::TColorModel tModel); - App::ColorGradient::TColorModel colorModel() const; + void setColorModel(std::size_t tModel); + std::size_t colorModel() const; + void setColorModelNames(const std::vector&); //@} /** @name Color style */ //@{ diff --git a/src/Gui/SoFCColorGradient.cpp b/src/Gui/SoFCColorGradient.cpp index 294403e39d..c0819cdf51 100644 --- a/src/Gui/SoFCColorGradient.cpp +++ b/src/Gui/SoFCColorGradient.cpp @@ -57,7 +57,7 @@ SoFCColorGradient::SoFCColorGradient() : _fMaxX(4.5f), _fMinX(4.0f), _fMaxY(4.0f labels->ref(); _cColGrad.setStyle(App::ColorGradient::FLOW); - setColorModel( App::ColorGradient::TRIA ); + setColorModel(0); setRange(-0.5f, 0.5f, 1); } @@ -235,9 +235,9 @@ std::vector SoFCColorGradient::getMarkerValues(float fMin, float fMax, in return labels; } -void SoFCColorGradient::setColorModel( App::ColorGradient::TColorModel tModel ) +void SoFCColorGradient::setColorModel(std::size_t index) { - _cColGrad.setColorModel( tModel ); + _cColGrad.setColorModel(index); rebuildGradient(); } @@ -324,6 +324,7 @@ bool SoFCColorGradient::customize() QWidget* parent = Gui::getMainWindow()->activeWindow(); Gui::Dialog::DlgSettingsColorGradientImp dlg(parent); + dlg.setColorModelNames( _cColGrad.getColorModelNames() ); dlg.setColorModel( _cColGrad.getColorModelType() ); dlg.setColorStyle( _cColGrad.getStyle() ); dlg.setOutGrayed( _cColGrad.isOutsideGrayed() ); diff --git a/src/Gui/SoFCColorGradient.h b/src/Gui/SoFCColorGradient.h index 967efc777d..514f47e105 100644 --- a/src/Gui/SoFCColorGradient.h +++ b/src/Gui/SoFCColorGradient.h @@ -81,10 +81,9 @@ protected: virtual ~SoFCColorGradient(); /** - * Sets the color model of the underlying color gradient to \a tModel. \a tModel either can - * be \c TRIA, \c INVERSE_TRIA, \c GRAY or \c INVERSE_GRAY + * Sets the color model of the underlying color gradient to \a index. */ - void setColorModel (App::ColorGradient::TColorModel tModel); + void setColorModel (std::size_t index); /** * Sets the color style of the underlying color gradient to \a tStyle. \a tStyle either can * be \c FLOW or \c ZERO_BASED diff --git a/src/Gui/SoFCColorLegend.cpp b/src/Gui/SoFCColorLegend.cpp index 7441d876e7..fe8a7c428d 100644 --- a/src/Gui/SoFCColorLegend.cpp +++ b/src/Gui/SoFCColorLegend.cpp @@ -55,7 +55,7 @@ SoFCColorLegend::SoFCColorLegend() : _fPosX(4.0f), _fPosY(4.0f) labels = new SoSeparator; labels->ref(); - setColorModel( App::ColorGradient::TRIA ); + setColorModel(0); setRange(-0.5f,0.5f,1); } @@ -186,9 +186,9 @@ void SoFCColorLegend::setRange( float fMin, float fMax, int prec ) _cColRamp.setRange(fMin, fMax); } -void SoFCColorLegend::setColorModel( App::ColorGradient::TColorModel tModel ) +void SoFCColorLegend::setColorModel(std::size_t index) { - _cColRamp.setColorModel( tModel ); + _cColRamp.setColorModel(index); App::ColorModel model = _cColRamp.getColorModel(); int uCtColors = (int)model.getCountColors(); diff --git a/src/Gui/SoFCColorLegend.h b/src/Gui/SoFCColorLegend.h index cfcb2db5dd..40aacbdfcd 100644 --- a/src/Gui/SoFCColorLegend.h +++ b/src/Gui/SoFCColorLegend.h @@ -52,10 +52,9 @@ public: */ void setRange( float fMin, float fMax, int prec=3 ); /** - * Sets the color model of the underlying color ramp to \a tModel. \a tModel either can - * be \c TRIA, \c INVERSE_TRIA or \c GRAY + * Sets the color model of the underlying color ramp to \a index. */ - void setColorModel (App::ColorGradient::TColorModel tModel); + void setColorModel (std::size_t index); unsigned short getColorIndex (float fVal) const { return _cColRamp.getColorIndex(fVal); } App::Color getColor (float fVal) const { return _cColRamp.getColor(fVal); }