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
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 # include <Inventor/fields/SoMFString.h>
00029 # include <Inventor/nodes/SoBaseColor.h>
00030 # include <Inventor/nodes/SoCoordinate3.h>
00031 # include <Inventor/nodes/SoIndexedFaceSet.h>
00032 # include <Inventor/nodes/SoMaterial.h>
00033 # include <Inventor/nodes/SoText2.h>
00034 # include <Inventor/nodes/SoTransform.h>
00035 # include <Inventor/nodes/SoTransparencyType.h>
00036 #endif
00037
00038 #include "SoFCColorGradient.h"
00039 #include "DlgSettingsColorGradientImp.h"
00040 #include "MainWindow.h"
00041 #include "MDIView.h"
00042
00043 using namespace Gui;
00044
00045 SO_NODE_SOURCE(SoFCColorGradient);
00046
00050 SoFCColorGradient::SoFCColorGradient() : _fMaxX(4.5f), _fMinX(4.0f), _fMaxY(4.0f), _fMinY(-4.0f), _bOutInvisible(false), _precision(3)
00051 {
00052 SO_NODE_CONSTRUCTOR(SoFCColorGradient);
00053 coords = new SoCoordinate3;
00054 coords->ref();
00055 labels = new SoSeparator;
00056 labels->ref();
00057
00058 _cColGrad.setStyle(App::ColorGradient::FLOW);
00059 setColorModel( App::ColorGradient::TRIA );
00060 setRange(-0.5f, 0.5f, 1);
00061 }
00062
00066 SoFCColorGradient::~SoFCColorGradient()
00067 {
00068
00069 coords->unref();
00070 labels->unref();
00071 }
00072
00073
00074 void SoFCColorGradient::initClass(void)
00075 {
00076 SO_NODE_INIT_CLASS(SoFCColorGradient,SoFCColorBarBase,"Separator");
00077 }
00078
00079 void SoFCColorGradient::finish()
00080 {
00081 atexit_cleanup();
00082 }
00083
00084 void SoFCColorGradient::setMarkerLabel( const SoMFString& label )
00085 {
00086 labels->removeAllChildren();
00087
00088 float fH=8.0f;
00089 int num = label.getNum();
00090 if ( num > 1 )
00091 {
00092 float fStep = fH / ((float)num-1);
00093 SoTransform* trans = new SoTransform;
00094 trans->translation.setValue(_fMaxX+0.1f,_fMaxY-0.05f+fStep,0.0f);
00095 labels->addChild(trans);
00096
00097 for ( int i=0; i<num; i++ )
00098 {
00099 SoTransform* trans = new SoTransform;
00100 SoBaseColor* color = new SoBaseColor;
00101 SoText2 * text2 = new SoText2;
00102
00103 trans->translation.setValue(0,-fStep,0);
00104 color->rgb.setValue(0,0,0);
00105 text2->string.setValue( label[i] );
00106 labels->addChild(trans);
00107 labels->addChild(color);
00108 labels->addChild(text2);
00109 }
00110 }
00111 }
00112
00113 void SoFCColorGradient::setViewportSize( const SbVec2s& size )
00114 {
00115
00116 float fRatio = ((float)size[0])/((float)size[1]);
00117 float fMinX= 4.0f, fMaxX=4.5f;
00118 float fMinY= -4.0f, fMaxY=4.0f;
00119
00120 if ( fRatio > 1.0f )
00121 {
00122 fMinX = 4.0f * fRatio;
00123 fMaxX = fMinX+0.5f;
00124 }
00125 else if ( fRatio < 1.0f )
00126 {
00127 fMinY = -4.0f / fRatio;
00128 fMaxY = 4.0f / fRatio;
00129 }
00130
00131 _fMaxX = fMaxX;
00132 _fMinX = fMinX;
00133 _fMaxY = fMaxY;
00134 _fMinY = fMinY;
00135
00136
00137 int num=0;
00138 for ( int i=0; i<labels->getNumChildren(); i++ )
00139 {
00140 if ( labels->getChild(i)->getTypeId() == SoTransform::getClassTypeId() )
00141 num++;
00142 }
00143
00144 if ( num > 2 )
00145 {
00146 bool first=true;
00147 float fStep = (fMaxY-fMinY) / ((float)num-2);
00148
00149 for ( int j=0; j<labels->getNumChildren(); j++ )
00150 {
00151 if ( labels->getChild(j)->getTypeId() == SoTransform::getClassTypeId() )
00152 {
00153 if ( first )
00154 {
00155 first = false;
00156 static_cast<SoTransform*>(labels->getChild(j))->translation.setValue(fMaxX+0.1f,fMaxY-0.05f+fStep,0.0f);
00157 }
00158 else
00159 {
00160 static_cast<SoTransform*>(labels->getChild(j))->translation.setValue(0,-fStep,0.0f);
00161 }
00162 }
00163 }
00164 }
00165
00166
00167 int ct = coords->point.getNum()/2;
00168 for ( int j=0; j<ct; j++ )
00169 {
00170 float w = (float)j/(float)(ct-1);
00171 float fPosY = (1.0f-w)*_fMaxY + w*_fMinY;
00172 coords->point.set1Value(2*j, _fMinX, fPosY, 0.0f);
00173 coords->point.set1Value(2*j+1, _fMaxX, fPosY, 0.0f);
00174 }
00175 }
00176
00177 void SoFCColorGradient::setRange( float fMin, float fMax, int prec )
00178 {
00179 _cColGrad.setRange(fMin, fMax);
00180
00181 SoMFString label;
00182
00183 float fFac = (float)pow(10.0, (double)prec);
00184
00185 int i=0;
00186 std::vector<float> marks = getMarkerValues(fMin, fMax, _cColGrad.getCountColors());
00187 for ( std::vector<float>::iterator it = marks.begin(); it != marks.end(); ++it )
00188 {
00189 std::stringstream s;
00190 s.precision(prec);
00191 s.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos);
00192 float fValue = *it;
00193 if ( fabs(fValue*fFac) < 1.0 )
00194 fValue = 0.0f;
00195 s << fValue;
00196 label.set1Value(i++, s.str().c_str());
00197 }
00198
00199 setMarkerLabel( label );
00200 }
00201
00202 std::vector<float> SoFCColorGradient::getMarkerValues(float fMin, float fMax, int count) const
00203 {
00204 std::vector<float> labels;
00205
00206
00207 if ( fMin < 0.0f && fMax > 0.0f && _cColGrad.getStyle() == App::ColorGradient::ZERO_BASED )
00208 {
00209 if ( count % 2 == 0) count++;
00210 int half = count / 2;
00211 for (int j=0; j<half+1; j++)
00212 {
00213 float w = (float)j/((float)half);
00214 float fValue = (1.0f-w)*fMax;
00215 labels.push_back( fValue );
00216 }
00217 for (int k=half+1; k<count; k++)
00218 {
00219 float w = (float)(k-half+1)/((float)(count-half));
00220 float fValue = w*fMin;
00221 labels.push_back( fValue );
00222 }
00223 }
00224 else
00225 {
00226 for (int j=0; j<count; j++)
00227 {
00228 float w = (float)j/((float)count-1.0f);
00229 float fValue = (1.0f-w)*fMax+w*fMin;
00230 labels.push_back( fValue );
00231 }
00232 }
00233
00234 return labels;
00235 }
00236
00237 void SoFCColorGradient::setColorModel( App::ColorGradient::TColorModel tModel )
00238 {
00239 _cColGrad.setColorModel( tModel );
00240 rebuildGradient();
00241 }
00242
00243 void SoFCColorGradient::setColorStyle (App::ColorGradient::TStyle tStyle)
00244 {
00245 _cColGrad.setStyle( tStyle );
00246 rebuildGradient();
00247 }
00248
00249 void SoFCColorGradient::rebuildGradient()
00250 {
00251 App::ColorModel model = _cColGrad.getColorModel();
00252 int uCtColors = (int)model._usColors;
00253
00254 coords->point.setNum(2*uCtColors);
00255 for ( int i=0; i<uCtColors; i++ )
00256 {
00257 float w = (float)i/(float)(uCtColors-1);
00258 float fPosY = (1.0f-w)*_fMaxY + w*_fMinY;
00259 coords->point.set1Value(2*i, _fMinX, fPosY, 0.0f);
00260 coords->point.set1Value(2*i+1, _fMaxX, fPosY, 0.0f);
00261 }
00262
00263
00264
00265 SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
00266 faceset->coordIndex.setNum(8*(uCtColors-1));
00267 for ( int j=0; j<uCtColors-1; j++ )
00268 {
00269 faceset->coordIndex.set1Value(8*j, 2*j);
00270 faceset->coordIndex.set1Value(8*j+1, 2*j+3);
00271 faceset->coordIndex.set1Value(8*j+2, 2*j+1);
00272 faceset->coordIndex.set1Value(8*j+3, SO_END_FACE_INDEX);
00273 faceset->coordIndex.set1Value(8*j+4, 2*j);
00274 faceset->coordIndex.set1Value(8*j+5, 2*j+2);
00275 faceset->coordIndex.set1Value(8*j+6, 2*j+3);
00276 faceset->coordIndex.set1Value(8*j+7, SO_END_FACE_INDEX);
00277 }
00278
00279
00280 SoTransparencyType* ttype = new SoTransparencyType;
00281 ttype->value = SoGLRenderAction::DELAYED_BLEND;
00282 SoMaterial* mat = new SoMaterial;
00283
00284 mat->diffuseColor.setNum(2*uCtColors);
00285 for ( int k=0; k<uCtColors; k++ )
00286 {
00287 App::Color col = model._pclColors[uCtColors-k-1];
00288 mat->diffuseColor.set1Value(2*k, col.r, col.g, col.b);
00289 mat->diffuseColor.set1Value(2*k+1, col.r, col.g, col.b);
00290 }
00291
00292 SoMaterialBinding* matBinding = new SoMaterialBinding;
00293 matBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
00294
00295
00296 if ( getNumChildren() > 0 )
00297 removeAllChildren();
00298 addChild(ttype);
00299 addChild(labels);
00300 addChild(coords);
00301 addChild(mat);
00302 addChild(matBinding);
00303 addChild(faceset);
00304 }
00305
00306 bool SoFCColorGradient::isVisible (float fVal) const
00307 {
00308 if (_bOutInvisible == true)
00309 {
00310 float fMin, fMax;
00311 _cColGrad.getRange(fMin, fMax);
00312 if ((fVal > fMax) || (fVal < fMin))
00313 return false;
00314 else
00315 return true;
00316 }
00317
00318 return true;
00319 }
00320
00321 bool SoFCColorGradient::customize()
00322 {
00323 QWidget* parent = Gui::getMainWindow()->activeWindow();
00324 Gui::Dialog::DlgSettingsColorGradientImp dlg(parent);
00325
00326 dlg.setColorModel( _cColGrad.getColorModelType() );
00327 dlg.setColorStyle( _cColGrad.getStyle() );
00328 dlg.setOutGrayed( _cColGrad.isOutsideGrayed() );
00329 dlg.setOutInvisible( _bOutInvisible );
00330 dlg.setNumberOfLabels( _cColGrad.getCountColors() );
00331 dlg.setNumberOfDecimals( _precision );
00332 float fMin, fMax;
00333 _cColGrad.getRange(fMin, fMax);
00334 dlg.setRange(fMin, fMax);
00335
00336 QPoint pos(QCursor::pos());
00337 pos += QPoint((int)(-1.1*dlg.width()),(int)(-0.1*dlg.height()));
00338 dlg.move( pos );
00339
00340 if ( dlg.exec() == QDialog::Accepted )
00341 {
00342 _cColGrad.setColorModel( dlg.colorModel() );
00343 _cColGrad.setStyle( dlg.colorStyle() );
00344 _cColGrad.setOutsideGrayed( dlg.isOutGrayed() );
00345 _bOutInvisible = dlg.isOutInvisible();
00346 _cColGrad.setCountColors( dlg.numberOfLabels() );
00347 _precision = dlg.numberOfDecimals();
00348 dlg.getRange( fMin, fMax );
00349 int dec = dlg.numberOfDecimals();
00350 setRange( fMin, fMax, dec );
00351 rebuildGradient();
00352
00353 return true;
00354 }
00355
00356 return false;
00357 }