1 // SALOME VTKViewer : build VTK viewer into Salome desktop
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
29 #include "SVTK_UpdateRateDlg.h"
31 #include "SVTK_MainWindow.h"
32 #include "SVTK_RenderWindowInteractor.h"
33 #include "VTKViewer_Algorithm.h"
34 #include "SALOME_Actor.h"
36 #include "QtxDblSpinBox.h"
37 #include "QtxAction.h"
41 #include <qgroupbox.h>
43 #include <qpushbutton.h>
45 #include <qlineedit.h>
47 #include <vtkGenericRenderWindowInteractor.h>
48 #include <vtkCallbackCommand.h>
49 #include <vtkRenderWindow.h>
50 #include <vtkRenderer.h>
51 #include <vtkMapper.h>
52 #include <vtkDataSet.h>
54 static vtkFloatingPointType OFF_UPDATE_RATE = 0.00001;
55 static vtkFloatingPointType FLOAT_TOLERANCE = 1.0 / VTK_LARGE_FLOAT;
61 //----------------------------------------------------------------------------
64 GetUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor)
66 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
67 vtkFloatingPointType aLastRenderTimeInSeconds = aRenderer->GetLastRenderTimeInSeconds();
68 if(aLastRenderTimeInSeconds > FLOAT_TOLERANCE){
69 std::ostringstream aStr;
70 vtkFloatingPointType aFPS = 1.0 / aLastRenderTimeInSeconds;
72 return QString(aStr.str().c_str());
79 //----------------------------------------------------------------------------
80 struct TRenderTimeMultiplier
82 vtkFloatingPointType myVTKMultiplier;
83 vtkFloatingPointType mySALOMEMultiplier;
85 TRenderTimeMultiplier():
87 mySALOMEMultiplier(0.0)
91 operator()(vtkActor* theActor)
93 if(theActor->GetVisibility()){
94 myVTKMultiplier += theActor->GetAllocatedRenderTime();
95 if(dynamic_cast<SALOME_Actor*>(theActor))
96 mySALOMEMultiplier += theActor->GetAllocatedRenderTime();
102 //----------------------------------------------------------------------------
105 AdjustUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor,
106 vtkFloatingPointType theUpdateRate)
108 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
109 if(vtkActorCollection *anActorCollection = aRenderer->GetActors()){
110 TRenderTimeMultiplier aMultiplier;
112 aMultiplier = ForEach<vtkActor>(anActorCollection,
114 if(aMultiplier.mySALOMEMultiplier > FLOAT_TOLERANCE)
115 theUpdateRate *= aMultiplier.mySALOMEMultiplier / aMultiplier.myVTKMultiplier;
118 return theUpdateRate;
122 //----------------------------------------------------------------------------
131 operator()(SALOME_Actor* theActor)
133 if(theActor->GetVisibility()){
134 if(vtkMapper *aMapper = theActor->GetMapper()){
135 if(vtkDataSet *aDataSet = aMapper->GetInput()){
136 myCounter += aDataSet->GetNumberOfCells();
144 //----------------------------------------------------------------------------
147 GetNumberOfCells(SVTK_RenderWindowInteractor* theRWInteractor)
149 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
150 if(vtkActorCollection *anActorCollection = aRenderer->GetActors()){
151 TCellsCounter aCounter;
153 aCounter = ForEach<SALOME_Actor>(anActorCollection,
155 return QString::number(aCounter.myCounter);
159 return QString::number(0);
167 ::SVTK_UpdateRateDlg(QtxAction* theAction,
168 SVTK_MainWindow* theParent,
169 const char* theName):
170 SVTK_DialogBase(theAction,
174 myEventCallbackCommand(vtkCallbackCommand::New()),
175 myRWInteractor(theParent->GetInteractor()),
178 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
179 bool anIsEnabledUpdateRate = false;
181 setCaption(tr("DLG_TITLE"));
182 QVBoxLayout* aVBoxLayout = new QVBoxLayout(this, 5, 5);
184 QGroupBox* aGroupBox = new QGroupBox(tr("INPUT_FRAME_TITLE"), this);
185 aGroupBox->setColumnLayout(0, Qt::Vertical );
186 aGroupBox->layout()->setSpacing( 6 );
187 aGroupBox->layout()->setMargin( 11 );
189 aGroupBox->setCheckable(true);
190 aGroupBox->setChecked(anIsEnabledUpdateRate);
191 myIsEnableUpdateRateGroupBox = aGroupBox;
193 QGridLayout* aGridLayout = new QGridLayout(aGroupBox->layout());
195 QLabel* aLabel = new QLabel(tr("DESIRED"), aGroupBox);
196 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
197 aGridLayout->addWidget(aLabel, 0, 0);
199 QtxDblSpinBox* aDblSpinBox = new QtxDblSpinBox(OFF_UPDATE_RATE, VTK_LARGE_FLOAT, 2, aGroupBox);
200 aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
201 aGridLayout->addWidget(aDblSpinBox, 0, 1);
203 aDblSpinBox->setValue(aRWI->GetDesiredUpdateRate());
204 aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
205 connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
206 myDesiredUpdateRateSblSpinBox = aDblSpinBox;
209 QLabel* aLabel = new QLabel(tr("STILL"), aGroupBox);
210 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
211 aGridLayout->addWidget(aLabel, 1, 0);
213 QtxDblSpinBox* aDblSpinBox = new QtxDblSpinBox(OFF_UPDATE_RATE, VTK_LARGE_FLOAT, 2, aGroupBox);
214 aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
215 aGridLayout->addWidget(aDblSpinBox, 1, 1);
217 aDblSpinBox->setValue(aRWI->GetStillUpdateRate());
218 aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
219 connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
220 myStillUpdateRateSblSpinBox = aDblSpinBox;
222 aVBoxLayout->addWidget(aGroupBox);
225 QGroupBox* aGroupBox = new QGroupBox(tr("INFORMATION_FRAME_TITLE"), this);
226 aGroupBox->setColumnLayout(0, Qt::Vertical );
227 aGroupBox->layout()->setSpacing( 6 );
228 aGroupBox->layout()->setMargin( 11 );
230 QGridLayout* aGridLayout = new QGridLayout(aGroupBox->layout());
232 QLabel* aLabel = new QLabel(tr("CURRENT_FPS"), aGroupBox);
233 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
234 aGridLayout->addWidget(aLabel, 0, 0);
236 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
237 aLineEdit->setReadOnly( TRUE );
238 aGridLayout->addWidget(aLineEdit, 0, 1);
240 myCurrentUpdateRateLineEdit = aLineEdit;
241 myCurrentUpdateRateLineEdit->setText( GetUpdateRate(myRWInteractor) );
244 QLabel* aLabel = new QLabel(tr("NUMBER_CELLS"), aGroupBox);
245 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
246 aGridLayout->addWidget(aLabel, 1, 0);
248 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
249 aLineEdit->setReadOnly( TRUE );
250 aGridLayout->addWidget(aLineEdit, 1, 1);
252 myNumberOfCellsLineEdit = aLineEdit;
253 myNumberOfCellsLineEdit->setText( GetNumberOfCells(myRWInteractor) );
255 aVBoxLayout->addWidget(aGroupBox);
258 QGroupBox* aGroupBox = new QGroupBox(this);
259 QHBoxLayout* aHBoxLayout = new QHBoxLayout(aGroupBox);
260 aHBoxLayout->setMargin(11);
261 aHBoxLayout->setSpacing(6);
263 QPushButton* aPushButton = new QPushButton(tr("OK"), aGroupBox);
264 aPushButton->setDefault(TRUE);
265 aPushButton->setAutoDefault(TRUE);
266 aHBoxLayout->addWidget(aPushButton);
267 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickOk()));
270 QPushButton* aPushButton = new QPushButton(tr("Apply"), aGroupBox);
271 aPushButton->setDefault(TRUE);
272 aPushButton->setAutoDefault(TRUE);
273 aHBoxLayout->addWidget(aPushButton);
274 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickApply()));
276 aHBoxLayout->addStretch();
278 QPushButton* aPushButton = new QPushButton(tr("Close"), aGroupBox);
279 aPushButton->setDefault(TRUE);
280 aPushButton->setAutoDefault(TRUE);
281 aHBoxLayout->addWidget(aPushButton);
282 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickClose()));
284 aVBoxLayout->addWidget(aGroupBox);
287 if(!anIsEnabledUpdateRate){
288 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
289 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
292 myEventCallbackCommand->Delete();
293 myEventCallbackCommand->SetClientData(this);
294 myEventCallbackCommand->SetCallback(SVTK_UpdateRateDlg::ProcessEvents);
295 vtkRenderer *aRenderer = myRWInteractor->getRenderer();
296 aRenderer->AddObserver(vtkCommand::EndEvent,
297 myEventCallbackCommand.GetPointer(),
302 Destroys the object and frees any allocated resources
305 ::~SVTK_UpdateRateDlg()
307 // no need to delete child widgets, Qt does it all for us
315 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
316 unsigned long theEvent,
318 void* vtkNotUsed(theCallData))
320 SVTK_UpdateRateDlg* self = reinterpret_cast<SVTK_UpdateRateDlg*>(theClientData);
322 if(theEvent == vtkCommand::EndEvent){
323 self->myCurrentUpdateRateLineEdit->setText( GetUpdateRate(self->myRWInteractor) );
324 self->myNumberOfCellsLineEdit->setText( GetNumberOfCells(self->myRWInteractor) );
335 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
337 vtkFloatingPointType anUpdateRate;
338 if(myIsEnableUpdateRateGroupBox->isChecked()){
339 anUpdateRate = AdjustUpdateRate(myRWInteractor,myDesiredUpdateRateSblSpinBox->value());
340 aRWI->SetDesiredUpdateRate(anUpdateRate);
341 anUpdateRate = AdjustUpdateRate(myRWInteractor,myStillUpdateRateSblSpinBox->value());
342 aRWI->SetStillUpdateRate(anUpdateRate);
344 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
345 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
348 myRWInteractor->getRenderWindow()->Render();
363 SLOT on Apply clicked
373 SLOT on Close clicked