1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SALOME VTKViewer : build VTK viewer into Salome desktop
28 #include "SVTK_UpdateRateDlg.h"
30 #include "SVTK_ViewWindow.h"
31 #include "SVTK_RenderWindowInteractor.h"
32 #include "VTKViewer_Algorithm.h"
33 #include "SALOME_Actor.h"
35 #include "QtxDoubleSpinBox.h"
36 #include "QtxAction.h"
42 #include <QPushButton>
43 #include <QGridLayout>
46 #include <vtkGenericRenderWindowInteractor.h>
47 #include <vtkCallbackCommand.h>
48 #include <vtkRenderWindow.h>
49 #include <vtkRenderer.h>
50 #include <vtkMapper.h>
51 #include <vtkDataSet.h>
53 static vtkFloatingPointType OFF_UPDATE_RATE = 0.00001;
54 static vtkFloatingPointType FLOAT_TOLERANCE = 1.0 / VTK_LARGE_FLOAT;
60 //----------------------------------------------------------------------------
63 GetUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor)
65 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
66 vtkFloatingPointType aLastRenderTimeInSeconds = aRenderer->GetLastRenderTimeInSeconds();
67 if(aLastRenderTimeInSeconds > FLOAT_TOLERANCE){
68 std::ostringstream aStr;
69 vtkFloatingPointType aFPS = 1.0 / aLastRenderTimeInSeconds;
71 return QString(aStr.str().c_str());
78 //----------------------------------------------------------------------------
79 struct TRenderTimeMultiplier
81 vtkFloatingPointType myVTKMultiplier;
82 vtkFloatingPointType mySALOMEMultiplier;
84 TRenderTimeMultiplier():
86 mySALOMEMultiplier(0.0)
90 operator()(vtkActor* theActor)
92 if(theActor->GetVisibility()){
93 myVTKMultiplier += theActor->GetAllocatedRenderTime();
94 if(dynamic_cast<SALOME_Actor*>(theActor))
95 mySALOMEMultiplier += theActor->GetAllocatedRenderTime();
101 //----------------------------------------------------------------------------
104 AdjustUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor,
105 vtkFloatingPointType theUpdateRate)
107 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
108 if(vtkActorCollection *anActorCollection = aRenderer->GetActors()){
109 TRenderTimeMultiplier aMultiplier;
111 aMultiplier = ForEach<vtkActor>(anActorCollection,
113 if(aMultiplier.mySALOMEMultiplier > FLOAT_TOLERANCE)
114 theUpdateRate *= aMultiplier.mySALOMEMultiplier / aMultiplier.myVTKMultiplier;
117 return theUpdateRate;
121 //----------------------------------------------------------------------------
130 operator()(SALOME_Actor* theActor)
132 if(theActor->GetVisibility()){
133 if(vtkMapper *aMapper = theActor->GetMapper()){
134 if(vtkDataSet *aDataSet = aMapper->GetInput()){
135 myCounter += aDataSet->GetNumberOfCells();
143 //----------------------------------------------------------------------------
146 GetNumberOfCells(SVTK_RenderWindowInteractor* theRWInteractor)
148 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
149 if(vtkActorCollection *anActorCollection = aRenderer->GetActors()){
150 TCellsCounter aCounter;
152 aCounter = ForEach<SALOME_Actor>(anActorCollection,
154 return QString::number(aCounter.myCounter);
158 return QString::number(0);
166 ::SVTK_UpdateRateDlg(QtxAction* theAction,
167 SVTK_ViewWindow* theParent,
168 const char* theName):
169 SVTK_DialogBase(theAction,
173 myEventCallbackCommand(vtkCallbackCommand::New()),
174 myRWInteractor(theParent->GetInteractor()),
177 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
178 bool anIsEnabledUpdateRate = false;
180 setWindowTitle(tr("DLG_TITLE"));
181 QVBoxLayout* aVBoxLayout = new QVBoxLayout(this);
182 aVBoxLayout->setMargin(5);
183 aVBoxLayout->setSpacing(5);
185 QGroupBox* aGroupBox = new QGroupBox(tr("INPUT_FRAME_TITLE"), this);
187 aGroupBox->setCheckable(true);
188 aGroupBox->setChecked(anIsEnabledUpdateRate);
189 myIsEnableUpdateRateGroupBox = aGroupBox;
191 QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
192 aGridLayout->setSpacing( 6 );
193 aGridLayout->setMargin( 11 );
195 QLabel* aLabel = new QLabel(tr("DESIRED"), aGroupBox);
196 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
197 aGridLayout->addWidget(aLabel, 0, 0);
199 QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(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 QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(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);
227 QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
228 aGridLayout->layout()->setSpacing( 6 );
229 aGridLayout->layout()->setMargin( 11 );
231 QLabel* aLabel = new QLabel(tr("CURRENT_FPS"), aGroupBox);
232 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
233 aGridLayout->addWidget(aLabel, 0, 0);
235 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
236 aLineEdit->setReadOnly( TRUE );
237 aGridLayout->addWidget(aLineEdit, 0, 1);
239 myCurrentUpdateRateLineEdit = aLineEdit;
240 myCurrentUpdateRateLineEdit->setText( GetUpdateRate(myRWInteractor) );
243 QLabel* aLabel = new QLabel(tr("NUMBER_CELLS"), aGroupBox);
244 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
245 aGridLayout->addWidget(aLabel, 1, 0);
247 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
248 aLineEdit->setReadOnly( TRUE );
249 aGridLayout->addWidget(aLineEdit, 1, 1);
251 myNumberOfCellsLineEdit = aLineEdit;
252 myNumberOfCellsLineEdit->setText( GetNumberOfCells(myRWInteractor) );
254 aVBoxLayout->addWidget(aGroupBox);
257 QGroupBox* aGroupBox = new QGroupBox(this);
258 QHBoxLayout* aHBoxLayout = new QHBoxLayout(aGroupBox);
259 aHBoxLayout->setMargin(11);
260 aHBoxLayout->setSpacing(6);
262 QPushButton* aPushButton = new QPushButton(tr("OK"), aGroupBox);
263 aPushButton->setDefault(TRUE);
264 aPushButton->setAutoDefault(TRUE);
265 aHBoxLayout->addWidget(aPushButton);
266 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickOk()));
269 QPushButton* aPushButton = new QPushButton(tr("Apply"), aGroupBox);
270 aPushButton->setDefault(TRUE);
271 aPushButton->setAutoDefault(TRUE);
272 aHBoxLayout->addWidget(aPushButton);
273 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickApply()));
275 aHBoxLayout->addStretch();
277 QPushButton* aPushButton = new QPushButton(tr("Close"), aGroupBox);
278 aPushButton->setDefault(TRUE);
279 aPushButton->setAutoDefault(TRUE);
280 aHBoxLayout->addWidget(aPushButton);
281 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickClose()));
283 aVBoxLayout->addWidget(aGroupBox);
286 if(!anIsEnabledUpdateRate){
287 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
288 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
291 myEventCallbackCommand->Delete();
292 myEventCallbackCommand->SetClientData(this);
293 myEventCallbackCommand->SetCallback(SVTK_UpdateRateDlg::ProcessEvents);
294 vtkRenderer *aRenderer = myRWInteractor->getRenderer();
295 aRenderer->AddObserver(vtkCommand::EndEvent,
296 myEventCallbackCommand.GetPointer(),
301 Destroys the object and frees any allocated resources
304 ::~SVTK_UpdateRateDlg()
306 // no need to delete child widgets, Qt does it all for us
314 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
315 unsigned long theEvent,
317 void* vtkNotUsed(theCallData))
319 SVTK_UpdateRateDlg* self = reinterpret_cast<SVTK_UpdateRateDlg*>(theClientData);
321 if(theEvent == vtkCommand::EndEvent){
322 self->myCurrentUpdateRateLineEdit->setText( GetUpdateRate(self->myRWInteractor) );
323 self->myNumberOfCellsLineEdit->setText( GetNumberOfCells(self->myRWInteractor) );
334 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
336 vtkFloatingPointType anUpdateRate;
337 if(myIsEnableUpdateRateGroupBox->isChecked()){
338 anUpdateRate = AdjustUpdateRate(myRWInteractor,myDesiredUpdateRateSblSpinBox->value());
339 aRWI->SetDesiredUpdateRate(anUpdateRate);
340 anUpdateRate = AdjustUpdateRate(myRWInteractor,myStillUpdateRateSblSpinBox->value());
341 aRWI->SetStillUpdateRate(anUpdateRate);
343 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
344 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
347 myRWInteractor->getRenderWindow()->Render();
362 SLOT on Apply clicked
372 SLOT on Close clicked