Back to index

salome-smesh  6.5.0
SMESH_ScalarBarActor.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
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 GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File   : SMESH_ScalarBarActor.cxx
00023 //  Author : Roman NIKOLAEV
00024 //  Module : SMESH
00025 //
00026 
00027 #include "SMESH_ScalarBarActor.h"
00028 
00029 #include <vtkCellArray.h>
00030 #include <vtkCellData.h>
00031 #include <vtkObjectFactory.h>
00032 #include <vtkPolyData.h>
00033 #include <vtkPolyDataMapper2D.h>
00034 #include <vtkScalarsToColors.h>
00035 #include <vtkTextMapper.h>
00036 #include <vtkTextProperty.h>
00037 #include <vtkViewport.h>
00038 #include <vtkWindow.h>
00039 #include <vtkLookupTable.h>
00040 #include <vtkProperty2D.h>
00041 
00042 #define SHRINK_COEF 0.08;
00043 
00044 vtkStandardNewMacro(SMESH_ScalarBarActor);
00045 
00046 vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LookupTable,vtkScalarsToColors);
00047 vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LabelTextProperty,vtkTextProperty);
00048 vtkCxxSetObjectMacro(SMESH_ScalarBarActor,TitleTextProperty,vtkTextProperty);
00049 
00050 //----------------------------------------------------------------------------
00051 // Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label
00052 // format, no title, and vertical orientation. The initial scalar bar
00053 // size is (0.05 x 0.8) of the viewport size.
00054 SMESH_ScalarBarActor::SMESH_ScalarBarActor() {
00055   this->LookupTable = NULL;
00056   this->Position2Coordinate->SetValue(0.17, 0.8);
00057   
00058   this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport();
00059   this->PositionCoordinate->SetValue(0.82,0.1);
00060   
00061   this->MaximumNumberOfColors = 64;
00062   this->NumberOfLabels = 5;
00063   this->NumberOfLabelsBuilt = 0;
00064   this->Orientation = VTK_ORIENT_VERTICAL;
00065   this->Title = NULL;
00066 
00067   this->LabelTextProperty = vtkTextProperty::New();
00068   this->LabelTextProperty->SetFontSize(12);
00069   this->LabelTextProperty->SetBold(1);
00070   this->LabelTextProperty->SetItalic(1);
00071   this->LabelTextProperty->SetShadow(1);
00072   this->LabelTextProperty->SetFontFamilyToArial();
00073 
00074   this->TitleTextProperty = vtkTextProperty::New();
00075   this->TitleTextProperty->ShallowCopy(this->LabelTextProperty);
00076 
00077   this->LabelFormat = new char[8]; 
00078   sprintf(this->LabelFormat,"%s","%-#6.3g");
00079 
00080   this->TitleMapper = vtkTextMapper::New();
00081   this->TitleActor = vtkActor2D::New();
00082   this->TitleActor->SetMapper(this->TitleMapper);
00083   this->TitleActor->GetPositionCoordinate()->
00084     SetReferenceCoordinate(this->PositionCoordinate);
00085   
00086   this->TextMappers = NULL;
00087   this->TextActors = NULL;
00088 
00089   this->ScalarBar = vtkPolyData::New();
00090   this->ScalarBarMapper = vtkPolyDataMapper2D::New();
00091   this->ScalarBarMapper->SetInput(this->ScalarBar);
00092   this->ScalarBarActor = vtkActor2D::New();
00093   this->ScalarBarActor->SetMapper(this->ScalarBarMapper);
00094   this->ScalarBarActor->GetPositionCoordinate()->
00095     SetReferenceCoordinate(this->PositionCoordinate);
00096   this->LastOrigin[0] = 0;
00097   this->LastOrigin[1] = 0;
00098   this->LastSize[0] = 0;
00099   this->LastSize[1] = 0;
00100 
00101 
00102   // rnv begin
00103   // Customization of the vtkScalarBarActor to show distribution histogram.
00104   myDistribution = vtkPolyData::New();
00105   myDistributionMapper = vtkPolyDataMapper2D::New();
00106   myDistributionMapper->SetInput(this->myDistribution);
00107   
00108   myDistributionActor = vtkActor2D::New();
00109   myDistributionActor->SetMapper(this->myDistributionMapper);
00110   myDistributionActor->GetPositionCoordinate()->
00111     SetReferenceCoordinate(this->PositionCoordinate);
00112 
00113   // By default distribution histogram is invisible
00114   myDistributionActor->SetVisibility(0);
00115 
00116   // By default monocolor
00117   myDistributionColoringType = SMESH_MONOCOLOR_TYPE;
00118   // rnv end
00119 }
00120 
00121 //----------------------------------------------------------------------------
00122 // Release any graphics resources that are being consumed by this actor.
00123 // The parameter window could be used to determine which graphic
00124 // resources to release.
00125 void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win)
00126 {
00127   this->TitleActor->ReleaseGraphicsResources(win);
00128   if (this->TextMappers != NULL )
00129     {
00130     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
00131       {
00132       this->TextActors[i]->ReleaseGraphicsResources(win);
00133       }
00134     }
00135   this->ScalarBarActor->ReleaseGraphicsResources(win);
00136   // rnv begin
00137   // Customization of the vtkScalarBarActor to show distribution histogram.
00138   myDistributionActor->ReleaseGraphicsResources(win);
00139 }
00140 
00141 
00142 /*--------------------------------------------------------------------------*/
00143 SMESH_ScalarBarActor::~SMESH_ScalarBarActor() {
00144   if (this->LabelFormat) 
00145     {
00146     delete [] this->LabelFormat;
00147     this->LabelFormat = NULL;
00148     }
00149 
00150   this->TitleMapper->Delete();
00151   this->TitleActor->Delete();
00152 
00153   if (this->TextMappers != NULL )
00154     {
00155     for (int i=0; i < this->NumberOfLabelsBuilt; i++)
00156       {
00157       this->TextMappers[i]->Delete();
00158       this->TextActors[i]->Delete();
00159       }
00160     delete [] this->TextMappers;
00161     delete [] this->TextActors;
00162     }
00163 
00164   this->ScalarBar->Delete();
00165   this->ScalarBarMapper->Delete();
00166   this->ScalarBarActor->Delete();
00167 
00168   if (this->Title)
00169     {
00170     delete [] this->Title;
00171     this->Title = NULL;
00172     }
00173   
00174   this->SetLookupTable(NULL);
00175   this->SetLabelTextProperty(NULL);
00176   this->SetTitleTextProperty(NULL);
00177   
00178   // rnv begin
00179   // Customization of the vtkScalarBarActor to show distribution histogram:
00180   myDistribution->Delete();
00181   myDistributionMapper->Delete();
00182   myDistributionActor->Delete();
00183   // rnv end
00184 }
00185 
00186 //----------------------------------------------------------------------------
00187 int SMESH_ScalarBarActor::RenderOverlay(vtkViewport *viewport)
00188 {
00189   int renderedSomething = 0;
00190   int i;
00191   
00192   // Everything is built, just have to render
00193   if (this->Title != NULL)
00194     {
00195     renderedSomething += this->TitleActor->RenderOverlay(viewport);
00196     }
00197   this->ScalarBarActor->RenderOverlay(viewport);
00198   this->myDistributionActor->RenderOverlay(viewport);
00199   if( this->TextActors == NULL)
00200     {
00201      vtkWarningMacro(<<"Need a mapper to render a scalar bar");
00202      return renderedSomething;
00203     }
00204   
00205   for (i=0; i<this->NumberOfLabels; i++)
00206     {
00207     renderedSomething += this->TextActors[i]->RenderOverlay(viewport);
00208     }
00209 
00210   renderedSomething = (renderedSomething > 0)?(1):(0);
00211 
00212   return renderedSomething;
00213 }
00214 
00215 
00216 //----------------------------------------------------------------------------
00217 int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport)
00218 {
00219   int renderedSomething = 0;
00220   int i;
00221   int size[2];
00222   
00223   if (!this->LookupTable)
00224     {
00225     vtkWarningMacro(<<"Need a mapper to render a scalar bar");
00226     return 0;
00227     }
00228 
00229   if (!this->TitleTextProperty)
00230     {
00231     vtkErrorMacro(<<"Need title text property to render a scalar bar");
00232     return 0;
00233     }
00234 
00235   if (!this->LabelTextProperty)
00236     {
00237     vtkErrorMacro(<<"Need label text property to render a scalar bar");
00238     return 0;
00239     }
00240 
00241   // Check to see whether we have to rebuild everything
00242   int positionsHaveChanged = 0;
00243   if (viewport->GetMTime() > this->BuildTime || 
00244       (viewport->GetVTKWindow() && 
00245        viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
00246     {
00247     // if the viewport has changed we may - or may not need
00248     // to rebuild, it depends on if the projected coords chage
00249     int *barOrigin;
00250     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
00251     size[0] = 
00252       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
00253       barOrigin[0];
00254     size[1] = 
00255       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
00256       barOrigin[1];
00257     if (this->LastSize[0] != size[0] || 
00258         this->LastSize[1] != size[1] ||
00259         this->LastOrigin[0] != barOrigin[0] || 
00260         this->LastOrigin[1] != barOrigin[1])
00261       {
00262       positionsHaveChanged = 1;
00263       }
00264     }
00265   
00266   // Check to see whether we have to rebuild everything
00267   if (positionsHaveChanged ||
00268       this->GetMTime() > this->BuildTime || 
00269       this->LookupTable->GetMTime() > this->BuildTime ||
00270       this->LabelTextProperty->GetMTime() > this->BuildTime ||
00271       this->TitleTextProperty->GetMTime() > this->BuildTime)
00272     {
00273     vtkDebugMacro(<<"Rebuilding subobjects");
00274 
00275     // Delete previously constructed objects
00276     //
00277     if (this->TextMappers != NULL )
00278       {
00279       for (i=0; i < this->NumberOfLabelsBuilt; i++)
00280         {
00281         this->TextMappers[i]->Delete();
00282         this->TextActors[i]->Delete();
00283         }
00284       delete [] this->TextMappers;
00285       delete [] this->TextActors;
00286       }
00287 
00288     // Build scalar bar object; determine its type
00289     //
00290     // is this a vtkLookupTable or a subclass of vtkLookupTable 
00291     // with its scale set to log
00292     // NOTE: it's possible we could to without the 'lut' variable
00293     // later in the code, but if the vtkLookupTableSafeDownCast operation
00294     // fails for some reason, this code will break in new ways. So, the 'LUT'
00295     // variable is used for this operation only
00296     vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
00297     int isLogTable = 0;
00298     if ( LUT )
00299       {
00300       if ( LUT->GetScale() == VTK_SCALE_LOG10 )
00301         {
00302         isLogTable = 1; 
00303         }
00304       }
00305     
00306     // we hard code how many steps to display
00307     vtkScalarsToColors *lut = this->LookupTable;
00308     int numColors = this->MaximumNumberOfColors;
00309     double *range = lut->GetRange();
00310 
00311     int numPts = 2*(numColors + 1);
00312     vtkPoints *pts = vtkPoints::New();
00313     pts->SetNumberOfPoints(numPts);
00314     vtkCellArray *polys = vtkCellArray::New();
00315     polys->Allocate(polys->EstimateSize(numColors,4));
00316     vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New();
00317     colors->SetNumberOfComponents(3);
00318     colors->SetNumberOfTuples(numColors);
00319 
00320 
00321     // rnv begin
00322     // Customization of the vtkScalarBarActor to show distribution histogram.
00323     bool distrVisibility =  (numColors == this->myNbValues.size());
00324     vtkPoints *distrPts;
00325     vtkCellArray *distrPolys;
00326     vtkUnsignedCharArray *distColors = 0;
00327     int numDistrPts = 0, numPositiveVal=0, maxValue=0;
00328     if(!distrVisibility)
00329       vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()");
00330 
00331     if (distrVisibility && GetDistributionVisibility()) {
00332       for( i=0 ;i<myNbValues.size();i++ ) {
00333         if(myNbValues[i]) {
00334           numPositiveVal++;
00335           maxValue = std::max(maxValue,myNbValues[i]);
00336         } 
00337       }
00338       numDistrPts = 4*(numPositiveVal);
00339       distrPts = vtkPoints::New();
00340       distrPolys = vtkCellArray::New();
00341       distrPts->SetNumberOfPoints(numDistrPts);
00342       distrPolys->Allocate(distrPolys->EstimateSize(numPositiveVal,4));
00343       this->myDistribution->Initialize();
00344       this->myDistribution->SetPoints(distrPts);
00345       this->myDistribution->SetPolys(distrPolys);
00346       distrPts->Delete();
00347       distrPolys->Delete();
00348       if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) {
00349         distColors = vtkUnsignedCharArray::New();
00350         distColors->SetNumberOfComponents(3);
00351         distColors->SetNumberOfTuples(numPositiveVal);
00352         this->myDistribution->GetCellData()->SetScalars(distColors);
00353         distColors->Delete();
00354       } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){
00355         this->myDistribution->GetCellData()->SetScalars(NULL);
00356       }
00357     } else {
00358       myDistribution->Reset();
00359     }
00360     // rnv end
00361 
00362     this->ScalarBarActor->SetProperty(this->GetProperty());
00363     this->ScalarBar->Initialize();
00364     this->ScalarBar->SetPoints(pts);
00365     this->ScalarBar->SetPolys(polys);
00366     this->ScalarBar->GetCellData()->SetScalars(colors);
00367     pts->Delete(); polys->Delete(); colors->Delete();
00368 
00369     // get the viewport size in display coordinates
00370     int *barOrigin, barWidth, barHeight, distrHeight;
00371     barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport);
00372     size[0] = 
00373       this->Position2Coordinate->GetComputedViewportValue(viewport)[0] -
00374       barOrigin[0];
00375     size[1] = 
00376       this->Position2Coordinate->GetComputedViewportValue(viewport)[1] -
00377       barOrigin[1];
00378     this->LastOrigin[0] = barOrigin[0];
00379     this->LastOrigin[1] = barOrigin[1];
00380     this->LastSize[0] = size[0];
00381     this->LastSize[1] = size[1];
00382     
00383     // Update all the composing objects
00384     this->TitleActor->SetProperty(this->GetProperty());
00385     this->TitleMapper->SetInput(this->Title);
00386     if (this->TitleTextProperty->GetMTime() > this->BuildTime)
00387       {
00388       // Shallow copy here so that the size of the title prop is not affected
00389       // by the automatic adjustment of its text mapper's size (i.e. its
00390       // mapper's text property is identical except for the font size
00391       // which will be modified later). This allows text actors to
00392       // share the same text property, and in that case specifically allows
00393       // the title and label text prop to be the same.
00394       this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty);
00395       this->TitleMapper->GetTextProperty()->SetJustificationToCentered();
00396       }
00397     
00398     // find the best size for the title font
00399     int titleSize[2];
00400     this->SizeTitle(titleSize, size, viewport);
00401     
00402     // find the best size for the ticks
00403     int labelSize[2];
00404     this->AllocateAndSizeLabels(labelSize, size, viewport,range);
00405     this->NumberOfLabelsBuilt = this->NumberOfLabels;
00406     
00407     // generate points
00408     double x[3]; x[2] = 0.0;
00409     double delta, itemH, shrink;
00410     if ( this->Orientation == VTK_ORIENT_VERTICAL ) {
00411       // rnv begin
00412       // Customization of the vtkScalarBarActor to show distribution histogram.
00413       double delimeter=0.0;
00414       if(GetDistributionVisibility() && distrVisibility) {
00415         delimeter=0.01*size[0]; //1 % from horizontal size of the full presentation size.
00416         barWidth = size[0] - 4 - labelSize[0];
00417         distrHeight = barWidth/2;
00418       } else {
00419         barWidth = size[0] - 4 - labelSize[0];
00420         distrHeight = 0;
00421       }
00422 
00423       barHeight = (int)(0.86*size[1]);
00424       delta=(double)barHeight/numColors;
00425       
00426       for ( i=0; i<numPts/2; i++ ) {
00427         x[0] = distrHeight+delimeter/2.0;
00428         x[1] = i*delta;
00429         pts->SetPoint(2*i,x);
00430         x[0] = barWidth;
00431         pts->SetPoint(2*i+1,x);
00432       }
00433 
00434       if(GetDistributionVisibility() && distrVisibility) {
00435         // Distribution points 
00436         shrink = delta*SHRINK_COEF;
00437         vtkIdType distPtsId=0;
00438         vtkIdType distPtsIds[4];
00439         for(i=0; i<numColors; i++) {
00440           if(myNbValues[i]) {
00441             itemH = distrHeight*((double)myNbValues[i]/maxValue);
00442             
00443             if(distrHeight == itemH) 
00444               itemH = itemH - delimeter/2;
00445 
00446             x[1] = i*delta+shrink;
00447 
00448             // first point of polygon (quadrangle)
00449             x[0] = 0; 
00450             distPtsIds[0] = distPtsId;
00451             distrPts->SetPoint(distPtsId++,x);
00452 
00453             // second point of polygon (quadrangle)
00454             x[0] = itemH;
00455             distPtsIds[1] = distPtsId;
00456             distrPts->SetPoint(distPtsId++,x);
00457 
00458             x[1] = i*delta+delta-shrink;
00459 
00460             // third point of polygon (quadrangle)
00461             x[0] = 0; 
00462             distPtsIds[3] = distPtsId;
00463             distrPts->SetPoint(distPtsId++,x);
00464 
00465             // fourth point of polygon (quadrangle)
00466             x[0] = itemH;
00467             distPtsIds[2] = distPtsId;
00468             distrPts->SetPoint(distPtsId++,x);
00469 
00470             //Inser Quadrangle
00471             distrPolys->InsertNextCell(4,distPtsIds);
00472           }
00473         }
00474       }    
00475     }
00476     // rnv end
00477     else {
00478       barWidth = size[0];
00479       
00480       // rnv begin
00481       // Customization of the vtkScalarBarActor to show distribution histogram.
00482       double coef1, delimeter=0.0;
00483       if(GetDistributionVisibility() && distrVisibility) {
00484         coef1=0.62;
00485         distrHeight = (int)((coef1/2)*size[1]);
00486         //delimeter between distribution diagram and scalar bar 
00487         delimeter=0.02*size[1];
00488       }
00489       else {
00490         coef1=0.4;
00491         barHeight = (int)(coef1*size[1]);
00492         distrHeight = 0;
00493       }
00494       
00495       barHeight = (int)(coef1*size[1]);
00496       
00497       delta=(double)barWidth/numColors;
00498       for (i=0; i<numPts/2; i++) {
00499         x[0] = i*delta;
00500         x[1] = barHeight;
00501         pts->SetPoint(2*i,x);                        
00502         x[1] = distrHeight + delimeter;
00503         pts->SetPoint(2*i+1,x);
00504       }
00505       
00506       if(GetDistributionVisibility() && distrVisibility) {
00507         // Distribution points 
00508         shrink = delta*SHRINK_COEF;
00509         vtkIdType distPtsId=0;
00510         vtkIdType distPtsIds[4];
00511         for(i=0; i<numColors; i++) {
00512           if(myNbValues[i]) {
00513             itemH = distrHeight*((double)myNbValues[i]/maxValue);
00514             
00515             // first point of polygon (quadrangle)
00516             x[0] = i*delta+shrink; 
00517             x[1] = 0;
00518             distPtsIds[0] = distPtsId;
00519             distrPts->SetPoint(distPtsId++,x);
00520             
00521             // second point of polygon (quadrangle)
00522             x[0] = i*delta+shrink; 
00523             x[1] = itemH;
00524             distPtsIds[3] = distPtsId;
00525             distrPts->SetPoint(distPtsId++,x);
00526             
00527             // third point of polygon (quadrangle)
00528             x[0] = i*delta+delta-shrink; 
00529             x[1] = 0;
00530             distPtsIds[1] = distPtsId;
00531             distrPts->SetPoint(distPtsId++,x);
00532             
00533             // fourth point of polygon (quadrangle)
00534             x[0] = i*delta+delta-shrink; 
00535             x[1] = itemH;
00536             distPtsIds[2] = distPtsId;
00537             distrPts->SetPoint(distPtsId++,x);
00538             
00539             // Add polygon into poly data
00540             distrPolys->InsertNextCell(4,distPtsIds);
00541           }
00542         } 
00543       }
00544       // rnv end
00545     }
00546     
00547     //polygons & cell colors
00548     unsigned char *rgba, *rgb;
00549     vtkIdType ptIds[4], dcCount=0;
00550     for (i=0; i<numColors; i++)
00551       {
00552       ptIds[0] = 2*i;
00553       ptIds[1] = ptIds[0] + 1;
00554       ptIds[2] = ptIds[1] + 2;
00555       ptIds[3] = ptIds[0] + 2;
00556       polys->InsertNextCell(4,ptIds);
00557 
00558       if ( isLogTable )
00559         {
00560         double rgbval = log10(range[0]) + 
00561           i*(log10(range[1])-log10(range[0]))/(numColors -1);
00562         rgba = lut->MapValue(pow(10.0,rgbval));
00563         }
00564       else
00565         {
00566         rgba = lut->MapValue(range[0] + (range[1] - range[0])*
00567                              ((double)i /(numColors-1.0)));
00568         }
00569 
00570       rgb = colors->GetPointer(3*i); //write into array directly
00571       rgb[0] = rgba[0];
00572       rgb[1] = rgba[1];
00573       rgb[2] = rgba[2];
00574       
00575       // rnv begin
00576       // Customization of the vtkScalarBarActor to show distribution histogram.
00577       if(myNbValues[i] && myDistributionColoringType == SMESH_MULTICOLOR_TYPE && GetDistributionVisibility() && distrVisibility)
00578         {
00579           rgb = distColors->GetPointer(3*dcCount); //write into array directly
00580           rgb[0] = rgba[0];
00581           rgb[1] = rgba[1];
00582           rgb[2] = rgba[2];
00583           dcCount++;
00584         }
00585       }
00586 
00587     // Now position everything properly
00588     //
00589     double val;
00590     if (this->Orientation == VTK_ORIENT_VERTICAL)
00591       {
00592       int sizeTextData[2];
00593       
00594       // center the title
00595       this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]);
00596       
00597       for (i=0; i < this->NumberOfLabels; i++)
00598         {
00599         if (this->NumberOfLabels > 1)
00600           {
00601           val = (double)i/(this->NumberOfLabels-1) *barHeight;
00602           }
00603         else 
00604           {
00605           val = 0.5*barHeight;
00606           }
00607         this->TextMappers[i]->GetSize(viewport,sizeTextData);
00608         this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft();
00609         this->TextActors[i]->SetPosition(barWidth+3,
00610                                          val - sizeTextData[1]/2);
00611         }
00612       }
00613     else
00614       {
00615       this->TitleActor->SetPosition(size[0]/2, 
00616                                     barHeight + labelSize[1] + 0.1*size[1]);
00617       for (i=0; i < this->NumberOfLabels; i++)
00618         {
00619         this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered();
00620         if (this->NumberOfLabels > 1)
00621           {
00622           val = (double)i/(this->NumberOfLabels-1) * barWidth;
00623           }
00624         else
00625           {
00626           val = 0.5*barWidth;
00627           }
00628         this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]);
00629         }
00630       }
00631 
00632     this->BuildTime.Modified();
00633     }
00634 
00635   // Everything is built, just have to render
00636   if (this->Title != NULL)
00637     {
00638     renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport);
00639     }
00640   this->ScalarBarActor->RenderOpaqueGeometry(viewport);
00641   this->myDistributionActor->RenderOpaqueGeometry(viewport);
00642   for (i=0; i<this->NumberOfLabels; i++)
00643     {
00644     renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport);
00645     }
00646 
00647   renderedSomething = (renderedSomething > 0)?(1):(0);
00648 
00649   return renderedSomething;
00650 }
00651 
00652 //----------------------------------------------------------------------------
00653 void SMESH_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent)
00654 {
00655   this->Superclass::PrintSelf(os,indent);
00656 
00657   if ( this->LookupTable )
00658     {
00659     os << indent << "Lookup Table:\n";
00660     this->LookupTable->PrintSelf(os,indent.GetNextIndent());
00661     }
00662   else
00663     {
00664     os << indent << "Lookup Table: (none)\n";
00665     }
00666 
00667   if (this->TitleTextProperty)
00668     {
00669     os << indent << "Title Text Property:\n";
00670     this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent());
00671     }
00672   else
00673     {
00674     os << indent << "Title Text Property: (none)\n";
00675     }
00676 
00677   if (this->LabelTextProperty)
00678     {
00679     os << indent << "Label Text Property:\n";
00680     this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent());
00681     }
00682   else
00683     {
00684     os << indent << "Label Text Property: (none)\n";
00685     }
00686 
00687   os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n";
00688   os << indent << "Maximum Number Of Colors: " 
00689      << this->MaximumNumberOfColors << "\n";
00690   os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n";
00691   os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n";
00692 
00693   os << indent << "Orientation: ";
00694   if ( this->Orientation == VTK_ORIENT_HORIZONTAL )
00695     {
00696     os << "Horizontal\n";
00697     }
00698   else
00699     {
00700     os << "Vertical\n";
00701     }
00702 
00703   os << indent << "Label Format: " << this->LabelFormat << "\n";
00704 }
00705 
00706 //----------------------------------------------------------------------------
00707 void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop)
00708 {
00709   SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop);
00710   if ( a != NULL )
00711     {
00712     this->SetPosition2(a->GetPosition2());
00713     this->SetLookupTable(a->GetLookupTable());
00714     this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors());
00715     this->SetOrientation(a->GetOrientation());
00716     this->SetLabelTextProperty(a->GetLabelTextProperty());
00717     this->SetTitleTextProperty(a->GetTitleTextProperty());
00718     this->SetLabelFormat(a->GetLabelFormat());
00719     this->SetTitle(a->GetTitle());
00720     this->GetPositionCoordinate()->SetCoordinateSystem(
00721       a->GetPositionCoordinate()->GetCoordinateSystem());    
00722     this->GetPositionCoordinate()->SetValue(
00723       a->GetPositionCoordinate()->GetValue());
00724     this->GetPosition2Coordinate()->SetCoordinateSystem(
00725       a->GetPosition2Coordinate()->GetCoordinateSystem());    
00726     this->GetPosition2Coordinate()->SetValue(
00727       a->GetPosition2Coordinate()->GetValue());
00728     }
00729 
00730   // Now do superclass
00731   this->vtkActor2D::ShallowCopy(prop);
00732 }
00733 
00734 //----------------------------------------------------------------------------
00735 void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, 
00736                                               int *size,
00737                                               vtkViewport *viewport,
00738                                               double *range)
00739 {
00740   labelSize[0] = labelSize[1] = 0;
00741 
00742   this->TextMappers = new vtkTextMapper * [this->NumberOfLabels];
00743   this->TextActors = new vtkActor2D * [this->NumberOfLabels];
00744 
00745   char string[512];
00746 
00747   double val;
00748   int i;
00749   
00750   // TODO: this should be optimized, maybe by keeping a list of
00751   // allocated mappers, in order to avoid creation/destruction of
00752   // their underlying text properties (i.e. each time a mapper is
00753   // created, text properties are created and shallow-assigned a font size
00754   // which value might be "far" from the target font size).
00755 
00756   // is this a vtkLookupTable or a subclass of vtkLookupTable 
00757   // with its scale set to log
00758   vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable );
00759   int isLogTable = 0;
00760   if ( LUT )
00761     {
00762     if ( LUT->GetScale() == VTK_SCALE_LOG10 )
00763       {
00764       isLogTable = 1; 
00765       }
00766     }
00767 
00768   for (i=0; i < this->NumberOfLabels; i++)
00769     {
00770     this->TextMappers[i] = vtkTextMapper::New();
00771 
00772     if ( isLogTable )
00773       {
00774       double lval;
00775       if (this->NumberOfLabels > 1)
00776         {
00777         lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) *
00778           (log10(range[1])-log10(range[0]));
00779         }
00780       else
00781         {
00782         lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0]));
00783         }
00784       val = pow(10.0,lval);
00785       }
00786     else
00787       {
00788       if (this->NumberOfLabels > 1)
00789         {
00790         val = range[0] + 
00791           (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]);
00792         }
00793       else
00794         {
00795         val = range[0] + 0.5*(range[1]-range[0]);
00796         }
00797       }
00798 
00799     sprintf(string, this->LabelFormat, val);
00800     this->TextMappers[i]->SetInput(string);
00801 
00802     // Shallow copy here so that the size of the label prop is not affected
00803     // by the automatic adjustment of its text mapper's size (i.e. its
00804     // mapper's text property is identical except for the font size
00805     // which will be modified later). This allows text actors to
00806     // share the same text property, and in that case specifically allows
00807     // the title and label text prop to be the same.
00808     this->TextMappers[i]->GetTextProperty()->ShallowCopy(
00809       this->LabelTextProperty);
00810 
00811     this->TextActors[i] = vtkActor2D::New();
00812     this->TextActors[i]->SetMapper(this->TextMappers[i]);
00813     this->TextActors[i]->SetProperty(this->GetProperty());
00814     this->TextActors[i]->GetPositionCoordinate()->
00815       SetReferenceCoordinate(this->PositionCoordinate);
00816     }
00817 
00818   if (this->NumberOfLabels)
00819     {
00820     int targetWidth, targetHeight;
00821     // rnv begin
00822     // Customization of the vtkScalarBarActor to show distribution histogram.
00823     bool distrVisibility = this->MaximumNumberOfColors == this->myNbValues.size();
00824     double coef;
00825     if( GetDistributionVisibility() && distrVisibility )
00826       if(this->Orientation == VTK_ORIENT_VERTICAL)
00827         coef = 0.4;
00828       else 
00829         coef = 0.18;
00830     else 
00831       if(this->Orientation == VTK_ORIENT_VERTICAL)
00832         coef = 0.6;
00833       else 
00834         coef=0.25;
00835 
00836 
00837     if ( this->Orientation == VTK_ORIENT_VERTICAL )
00838       {
00839       targetWidth = (int)(coef*size[0]);
00840       targetHeight = (int)(0.86*size[1]/this->NumberOfLabels);
00841       }
00842     else
00843       {
00844       targetWidth = (int)(size[0]*0.8/this->NumberOfLabels);
00845       targetHeight = (int)(coef*size[1]);
00846       }
00847     // rnv end
00848     
00849     vtkTextMapper::SetMultipleConstrainedFontSize(viewport, 
00850                                                   targetWidth, 
00851                                                   targetHeight,
00852                                                   this->TextMappers,
00853                                                   this->NumberOfLabels,
00854                                                   labelSize);
00855     }
00856 }
00857 
00858 //----------------------------------------------------------------------------
00859 void SMESH_ScalarBarActor::SizeTitle(int *titleSize, 
00860                                   int *size, 
00861                                   vtkViewport *viewport)
00862 {
00863   titleSize[0] = titleSize[1] = 0;
00864 
00865   if (this->Title == NULL || !strlen(this->Title))
00866     {
00867     return;
00868     }
00869 
00870   int targetWidth, targetHeight;
00871   
00872   targetWidth = size[0];
00873   // rnv begin
00874   // Customization of the vtkScalarBarActor to show distribution histogram.
00875   bool distrVisibility =  this->MaximumNumberOfColors == this->myNbValues.size();
00876   double coef;
00877   if( GetDistributionVisibility() && distrVisibility ) 
00878     coef=0.18;
00879   else 
00880     coef=0.25;
00881 
00882   if ( this->Orientation == VTK_ORIENT_VERTICAL )
00883     {
00884       targetHeight = (int)(0.1*size[1]);
00885     }
00886   else
00887     {
00888       targetHeight = (int)(coef*size[1]);
00889     }
00890 
00891   this->TitleMapper->SetConstrainedFontSize(
00892     viewport, targetWidth, targetHeight);
00893 
00894   this->TitleMapper->GetSize(viewport, titleSize);
00895 }
00896 
00897 
00898 /*--------------------------------------------------------------------------*/
00899 void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) {
00900   myDistributionActor->SetVisibility(flag);
00901   Modified();
00902 }
00903 
00904 
00905 /*--------------------------------------------------------------------------*/
00906 int SMESH_ScalarBarActor::GetDistributionVisibility() {
00907   return myDistributionActor->GetVisibility();
00908 }
00909 
00910 
00911 void SMESH_ScalarBarActor::SetDistribution(std::vector<int> theNbValues) {
00912   myNbValues = theNbValues;
00913 } 
00914 
00915 
00916 void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) {
00917   myDistributionActor->GetProperty()->SetColor(rgb);
00918   Modified();
00919 }
00920 
00921 void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) {
00922   myDistributionActor->GetProperty()->GetColor(rgb);
00923 }