SoFCColorLegend.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 
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 #endif
00036 
00037 #include "SoFCColorLegend.h"
00038 
00039 
00040 using namespace Gui;
00041 
00042 SO_NODE_SOURCE(SoFCColorLegend);
00043 
00047 SoFCColorLegend::SoFCColorLegend() : _fPosX(4.0f), _fPosY(4.0f)
00048 {
00049   SO_NODE_CONSTRUCTOR(SoFCColorLegend);
00050   _cColRamp.setStyle(App::ColorGradient::FLOW);
00051 
00052   coords = new SoCoordinate3;
00053   coords->ref();
00054   labels = new SoSeparator;
00055   labels->ref();
00056 
00057   setColorModel( App::ColorGradient::TRIA );
00058   setRange(-0.5f,0.5f,1);
00059 }
00060 
00064 SoFCColorLegend::~SoFCColorLegend()
00065 {
00066   //delete THIS;
00067   coords->unref();
00068   labels->unref();
00069 }
00070 
00071 // doc from parent
00072 void SoFCColorLegend::initClass(void)
00073 {
00074   SO_NODE_INIT_CLASS(SoFCColorLegend,SoFCColorBarBase,"Separator");
00075 }
00076 
00077 void SoFCColorLegend::finish()
00078 {
00079   atexit_cleanup();
00080 }
00081 
00082 void SoFCColorLegend::setMarkerLabel( const SoMFString& label )
00083 {
00084   labels->removeAllChildren();
00085 
00086   int num = label.getNum();
00087   if ( num > 1 )
00088   {
00089     float fStep = 8.0f / ((float)num-1);
00090     SoTransform* trans = new SoTransform;
00091     trans->translation.setValue(_fPosX+0.1f,_fPosY-0.05f+fStep,0.0f);
00092     labels->addChild(trans);
00093 
00094     for ( int i=0; i<num; i++ )
00095     {
00096       SoTransform* trans = new SoTransform;
00097       SoBaseColor* color = new SoBaseColor;
00098       SoText2    * text2 = new SoText2;
00099 
00100       trans->translation.setValue(0,-fStep,0);
00101       color->rgb.setValue(0,0,0);
00102       text2->string.setValue( label[i] );
00103       labels->addChild(trans);
00104       labels->addChild(color);
00105       labels->addChild(text2);
00106     }
00107   }
00108 }
00109 
00110 void SoFCColorLegend::setViewportSize( const SbVec2s& size )
00111 {
00112   float fRatio = ((float)size[0])/((float)size[1]);
00113   float fMinX=  4.0f, fMaxX=4.5f;
00114   float fMinY= -4.0f, fMaxY=4.0f;
00115 
00116   if ( fRatio > 1.0f )
00117   {
00118     fMinX = 4.0f * fRatio;
00119     fMaxX = fMinX+0.5f;
00120   }
00121   else if ( fRatio < 1.0f )
00122   {
00123     fMinY =  -4.0f / fRatio;
00124     fMaxY =   4.0f / fRatio;
00125   }
00126 
00127   _fPosX = fMaxX;
00128   _fPosY = fMaxY;
00129 
00130   // search for the labels
00131   int num=0;
00132   for ( int i=0; i<labels->getNumChildren(); i++ )
00133   {
00134     if ( labels->getChild(i)->getTypeId() == SoTransform::getClassTypeId() )
00135       num++;
00136   }
00137 
00138   if ( num > 2 )
00139   {
00140     bool first=true;
00141     float fStep = (fMaxY-fMinY) / ((float)num-2);
00142 
00143     for ( int j=0; j<labels->getNumChildren(); j++ )
00144     {
00145       if ( labels->getChild(j)->getTypeId() == SoTransform::getClassTypeId() )
00146       {
00147         if ( first )
00148         {
00149           first = false;
00150           static_cast<SoTransform*>(labels->getChild(j))->translation.setValue(fMaxX+0.1f,fMaxY-0.05f+fStep,0.0f);
00151         }
00152         else
00153         {
00154           static_cast<SoTransform*>(labels->getChild(j))->translation.setValue(0,-fStep,0.0f);
00155         }
00156       }
00157     }
00158   }
00159 
00160   // set the vertices spanning the faces for the color gradient
00161   int ct = coords->point.getNum()/2;
00162   for ( int j=0; j<ct; j++ )
00163   {
00164     float w = (float)j/(float)(ct-1);
00165     float fPosY = (1.0f-w)*fMaxY + w*fMinY;
00166     coords->point.set1Value(2*j, fMinX, fPosY, 0.0f);
00167     coords->point.set1Value(2*j+1, fMaxX, fPosY, 0.0f);
00168   }
00169 }
00170 
00171 void SoFCColorLegend::setRange( float fMin, float fMax, int prec )
00172 {
00173   SoMFString label;
00174   for (int j=0; j<9; j++)
00175   {
00176     std::stringstream s;
00177     s.precision(prec);
00178     s.setf(std::ios::fixed | std::ios::showpoint | std::ios::showpos);
00179     float fValue = (1.0f-0.125f*(float)j)*fMax + (0.125f*(float)j)*fMin;
00180     s << fValue;
00181     label.set1Value(j, s.str().c_str());
00182   }
00183 
00184   setMarkerLabel( label );
00185   _cColRamp.setRange(fMin, fMax);
00186 }
00187 
00188 void SoFCColorLegend::setColorModel( App::ColorGradient::TColorModel tModel )
00189 {
00190   _cColRamp.setColorModel( tModel );
00191   App::ColorModel model = _cColRamp.getColorModel();
00192   int uCtColors = (int)model._usColors;
00193 
00194   // don't know why the parameter range isn't between [-1,+1]
00195   float fMinX=  4.0f, fMaxX=4.5f;
00196   float fMinY= -4.0f, fMaxY=4.0f;
00197   coords->point.setNum(2*uCtColors);
00198   for ( int i=0; i<uCtColors; i++ )
00199   {
00200     float w = (float)i/(float)(uCtColors-1);
00201     float fPosY = (1.0f-w)*fMaxY + w*fMinY;
00202     coords->point.set1Value(2*i, fMinX, fPosY, 0.0f);
00203     coords->point.set1Value(2*i+1, fMaxX, fPosY, 0.0f);
00204   }
00205 
00206   // for uCtColors colors we need 2*(uCtColors-1) facets and therefore an array with
00207   // 8*(uCtColors-1) face indices
00208   SoIndexedFaceSet * faceset = new SoIndexedFaceSet;
00209   faceset->coordIndex.setNum(8*(uCtColors-1));
00210   for ( int j=0; j<uCtColors-1; j++ )
00211   {
00212     faceset->coordIndex.set1Value(8*j,   2*j);
00213     faceset->coordIndex.set1Value(8*j+1, 2*j+3);
00214     faceset->coordIndex.set1Value(8*j+2, 2*j+1);
00215     faceset->coordIndex.set1Value(8*j+3, SO_END_FACE_INDEX);
00216     faceset->coordIndex.set1Value(8*j+4, 2*j);
00217     faceset->coordIndex.set1Value(8*j+5, 2*j+2);
00218     faceset->coordIndex.set1Value(8*j+6, 2*j+3);
00219     faceset->coordIndex.set1Value(8*j+7, SO_END_FACE_INDEX);
00220   }
00221 
00222   SoMaterial* mat = new SoMaterial;
00223   //mat->transparency = 0.3f;
00224   mat->diffuseColor.setNum(2*uCtColors);
00225   for ( int k=0; k<uCtColors; k++ )
00226   {
00227     App::Color col = model._pclColors[uCtColors-k-1];
00228     mat->diffuseColor.set1Value(2*k, col.r, col.g, col.b);
00229     mat->diffuseColor.set1Value(2*k+1, col.r, col.g, col.b);
00230   }
00231 
00232   SoMaterialBinding* matBinding = new SoMaterialBinding;
00233   matBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
00234 
00235   // first clear the children
00236   if ( getNumChildren() > 0 )
00237     removeAllChildren();
00238   addChild(labels);
00239   addChild(coords);
00240   addChild(mat);
00241   addChild(matBinding);
00242   addChild(faceset);
00243 }

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