Back to index

salome-gui  6.5.0
SVTK_UpdateRateDlg.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 
00023 //  SALOME VTKViewer : build VTK viewer into Salome desktop
00024 //  File   : 
00025 //  Author : 
00026 
00027 #include "SVTK_UpdateRateDlg.h"
00028 
00029 #include "SVTK_ViewWindow.h"
00030 #include "SVTK_RenderWindowInteractor.h"
00031 #include "VTKViewer_Algorithm.h"
00032 #include "SALOME_Actor.h"
00033 
00034 #include "QtxDoubleSpinBox.h"
00035 #include "QtxAction.h"
00036 
00037 #include <sstream>
00038 
00039 #include <QGroupBox>
00040 #include <QLabel>
00041 #include <QPushButton>
00042 #include <QGridLayout>
00043 #include <QLineEdit>
00044 
00045 #include <vtkGenericRenderWindowInteractor.h>
00046 #include <vtkCallbackCommand.h>
00047 #include <vtkRenderWindow.h>
00048 #include <vtkRenderer.h>
00049 #include <vtkMapper.h>
00050 #include <vtkDataSet.h>
00051 
00052 static vtkFloatingPointType OFF_UPDATE_RATE = 0.00001;
00053 static vtkFloatingPointType FLOAT_TOLERANCE = 1.0 / VTK_LARGE_FLOAT;
00054 
00055 namespace
00056 {
00057   //----------------------------------------------------------------------------
00058   inline
00059   QString 
00060   GetUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor)
00061   {
00062     if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
00063       vtkFloatingPointType aLastRenderTimeInSeconds = aRenderer->GetLastRenderTimeInSeconds();
00064       if(aLastRenderTimeInSeconds > FLOAT_TOLERANCE){
00065         std::ostringstream aStr;
00066         vtkFloatingPointType aFPS = 1.0 / aLastRenderTimeInSeconds;
00067         aStr<<aFPS;
00068         return QString(aStr.str().c_str());
00069       }
00070     }
00071     return "Inf";
00072   }
00073 
00074 
00075   //----------------------------------------------------------------------------
00076   struct TRenderTimeMultiplier
00077   {
00078     vtkFloatingPointType myVTKMultiplier;
00079     vtkFloatingPointType mySALOMEMultiplier;
00080 
00081     TRenderTimeMultiplier():
00082       myVTKMultiplier(0.0),
00083       mySALOMEMultiplier(0.0)
00084     {}
00085 
00086     void
00087     operator()(vtkActor* theActor)
00088     {
00089       if(theActor->GetVisibility()){
00090         myVTKMultiplier += theActor->GetAllocatedRenderTime();
00091         if(dynamic_cast<SALOME_Actor*>(theActor))
00092           mySALOMEMultiplier += theActor->GetAllocatedRenderTime();
00093       }
00094     }
00095   };
00096 
00097 
00098   //----------------------------------------------------------------------------
00099   inline
00100   vtkFloatingPointType 
00101   AdjustUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor,
00102                    vtkFloatingPointType theUpdateRate)
00103   {
00104     if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
00105       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00106       if(vtkActorCollection *anActorCollection = aCopy.GetActors()){
00107         TRenderTimeMultiplier aMultiplier;
00108         using namespace VTK;
00109         aMultiplier = ForEach<vtkActor>(anActorCollection,
00110                                         aMultiplier);
00111         if(aMultiplier.mySALOMEMultiplier > FLOAT_TOLERANCE)
00112           theUpdateRate *= aMultiplier.mySALOMEMultiplier / aMultiplier.myVTKMultiplier;
00113       }
00114     }
00115     return theUpdateRate;
00116   }
00117 
00118 
00119   //----------------------------------------------------------------------------
00120   struct TCellsCounter
00121   {
00122     vtkIdType myCounter;
00123     TCellsCounter():
00124       myCounter(0)
00125     {}
00126 
00127     void
00128     operator()(SALOME_Actor* theActor)
00129     {
00130       if(theActor->GetVisibility()){
00131         if(vtkMapper *aMapper = theActor->GetMapper()){
00132           if(vtkDataSet *aDataSet = aMapper->GetInput()){
00133             myCounter += aDataSet->GetNumberOfCells();
00134           }
00135         }
00136       }
00137     }
00138   };
00139 
00140 
00141   //----------------------------------------------------------------------------
00142   inline
00143   QString 
00144   GetNumberOfCells(SVTK_RenderWindowInteractor* theRWInteractor)
00145   {
00146     if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
00147       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
00148       if(vtkActorCollection *anActorCollection = aCopy.GetActors()){
00149         TCellsCounter aCounter;
00150         using namespace VTK;
00151         aCounter = ForEach<SALOME_Actor>(anActorCollection,
00152                                          aCounter);
00153         return QString::number(aCounter.myCounter);
00154       }
00155     }
00156     
00157     return QString::number(0);
00158   }
00159 }
00160 
00164 SVTK_UpdateRateDlg
00165 ::SVTK_UpdateRateDlg(QtxAction* theAction,
00166                      SVTK_ViewWindow* theParent,
00167                      const char* theName):
00168   ViewerTools_DialogBase(theAction,
00169                          theParent, 
00170                          theName),
00171   myPriority(0.0),
00172   myEventCallbackCommand(vtkCallbackCommand::New()),
00173   myRWInteractor(theParent->GetInteractor()),
00174   myAction(theAction)
00175 {
00176   vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
00177   bool anIsEnabledUpdateRate = false;
00178 
00179   setWindowTitle(tr("DLG_TITLE"));
00180   QVBoxLayout* aVBoxLayout = new QVBoxLayout(this);
00181   aVBoxLayout->setMargin(5);
00182   aVBoxLayout->setSpacing(5);
00183   {
00184     QGroupBox* aGroupBox = new QGroupBox(tr("INPUT_FRAME_TITLE"), this);
00185 
00186     aGroupBox->setCheckable(true);
00187     aGroupBox->setChecked(anIsEnabledUpdateRate);
00188     myIsEnableUpdateRateGroupBox = aGroupBox;
00189 
00190     QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
00191     aGridLayout->setSpacing( 6 );
00192     aGridLayout->setMargin( 11 );
00193     {
00194       QLabel* aLabel = new QLabel(tr("DESIRED"), aGroupBox);
00195       aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00196       aGridLayout->addWidget(aLabel, 0, 0);
00197 
00198       QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(OFF_UPDATE_RATE, VTK_LARGE_FLOAT, 2, aGroupBox);
00199       aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00200       aGridLayout->addWidget(aDblSpinBox, 0, 1);
00201 
00202       aDblSpinBox->setValue(aRWI->GetDesiredUpdateRate());
00203       aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
00204       connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
00205       myDesiredUpdateRateSblSpinBox = aDblSpinBox;
00206     }
00207     {
00208       QLabel* aLabel = new QLabel(tr("STILL"), aGroupBox);
00209       aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00210       aGridLayout->addWidget(aLabel, 1, 0);
00211 
00212       QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(OFF_UPDATE_RATE, VTK_LARGE_FLOAT, 2, aGroupBox);
00213       aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00214       aGridLayout->addWidget(aDblSpinBox, 1, 1);
00215 
00216       aDblSpinBox->setValue(aRWI->GetStillUpdateRate());
00217       aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
00218       connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
00219       myStillUpdateRateSblSpinBox = aDblSpinBox;
00220     }
00221     aVBoxLayout->addWidget(aGroupBox);
00222   }
00223   {
00224     QGroupBox* aGroupBox = new QGroupBox(tr("INFORMATION_FRAME_TITLE"), this);
00225     
00226     QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
00227     aGridLayout->layout()->setSpacing( 6 );
00228     aGridLayout->layout()->setMargin( 11 );
00229     {
00230       QLabel* aLabel = new QLabel(tr("CURRENT_FPS"), aGroupBox);
00231       aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00232       aGridLayout->addWidget(aLabel, 0, 0);
00233 
00234       QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
00235       aLineEdit->setReadOnly( TRUE );
00236       aGridLayout->addWidget(aLineEdit, 0, 1);
00237 
00238       myCurrentUpdateRateLineEdit = aLineEdit;
00239       myCurrentUpdateRateLineEdit->setText( GetUpdateRate(myRWInteractor) );
00240     }
00241     {
00242       QLabel* aLabel = new QLabel(tr("NUMBER_CELLS"), aGroupBox);
00243       aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
00244       aGridLayout->addWidget(aLabel, 1, 0);
00245 
00246       QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
00247       aLineEdit->setReadOnly( TRUE );
00248       aGridLayout->addWidget(aLineEdit, 1, 1);
00249 
00250       myNumberOfCellsLineEdit = aLineEdit;
00251       myNumberOfCellsLineEdit->setText( GetNumberOfCells(myRWInteractor) );
00252     }
00253     aVBoxLayout->addWidget(aGroupBox);
00254   }
00255   {
00256     QGroupBox* aGroupBox = new QGroupBox(this);
00257     QHBoxLayout* aHBoxLayout = new QHBoxLayout(aGroupBox);
00258     aHBoxLayout->setMargin(11);
00259     aHBoxLayout->setSpacing(6);
00260     {
00261       QPushButton* aPushButton = new QPushButton(tr("OK"), aGroupBox);
00262       aPushButton->setDefault(TRUE);
00263       aPushButton->setAutoDefault(TRUE);
00264       aHBoxLayout->addWidget(aPushButton);
00265       connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickOk()));
00266     }
00267     {
00268       QPushButton* aPushButton = new QPushButton(tr("Apply"), aGroupBox);
00269       aPushButton->setDefault(TRUE);
00270       aPushButton->setAutoDefault(TRUE);
00271       aHBoxLayout->addWidget(aPushButton);
00272       connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickApply()));
00273     }
00274     aHBoxLayout->addStretch();
00275     {
00276       QPushButton* aPushButton = new QPushButton(tr("Close"), aGroupBox);
00277       aPushButton->setDefault(TRUE);
00278       aPushButton->setAutoDefault(TRUE);
00279       aHBoxLayout->addWidget(aPushButton);
00280       connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickClose()));
00281     }
00282     aVBoxLayout->addWidget(aGroupBox);
00283   }
00284 
00285   if(!anIsEnabledUpdateRate){
00286     aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
00287     aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);  
00288   }
00289 
00290   myEventCallbackCommand->Delete();
00291   myEventCallbackCommand->SetClientData(this);
00292   myEventCallbackCommand->SetCallback(SVTK_UpdateRateDlg::ProcessEvents);
00293   vtkRenderer *aRenderer = myRWInteractor->getRenderer();
00294   aRenderer->AddObserver(vtkCommand::EndEvent,
00295                          myEventCallbackCommand.GetPointer(), 
00296                          myPriority);
00297 }
00298 
00302 SVTK_UpdateRateDlg
00303 ::~SVTK_UpdateRateDlg()
00304 {
00305   // no need to delete child widgets, Qt does it all for us
00306 }
00307 
00311 void 
00312 SVTK_UpdateRateDlg
00313 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
00314                 unsigned long theEvent,
00315                 void* theClientData, 
00316                 void* vtkNotUsed(theCallData))
00317 {
00318   SVTK_UpdateRateDlg* self = reinterpret_cast<SVTK_UpdateRateDlg*>(theClientData);
00319 
00320   if(theEvent == vtkCommand::EndEvent){
00321     self->myCurrentUpdateRateLineEdit->setText( GetUpdateRate(self->myRWInteractor) );
00322     self->myNumberOfCellsLineEdit->setText( GetNumberOfCells(self->myRWInteractor) );
00323   }
00324 }
00325 
00329 void 
00330 SVTK_UpdateRateDlg
00331 ::Update()
00332 {
00333   vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
00334 
00335   vtkFloatingPointType anUpdateRate;
00336   if(myIsEnableUpdateRateGroupBox->isChecked()){
00337     anUpdateRate = AdjustUpdateRate(myRWInteractor,myDesiredUpdateRateSblSpinBox->value());
00338     aRWI->SetDesiredUpdateRate(anUpdateRate);
00339     anUpdateRate = AdjustUpdateRate(myRWInteractor,myStillUpdateRateSblSpinBox->value());
00340     aRWI->SetStillUpdateRate(anUpdateRate);
00341   }else{
00342     aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
00343     aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
00344   }
00345 
00346   myRWInteractor->getRenderWindow()->Render();
00347 }
00348 
00352 void 
00353 SVTK_UpdateRateDlg
00354 ::onClickOk()
00355 {
00356   Update();
00357   onClickClose();
00358 }
00359 
00363 void
00364 SVTK_UpdateRateDlg
00365 ::onClickApply()
00366 {
00367   Update();
00368 }
00369 
00373 void 
00374 SVTK_UpdateRateDlg
00375 ::onClickClose()
00376 {
00377   reject();
00378 }