1 // Copyright (C) 2007-2023 CEA, EDF, 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, or (at your option) any later version.
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
23 // SALOME VTKViewer : build VTK viewer into Salome desktop
27 #include "SVTK_UpdateRateDlg.h"
29 #include "SVTK_ViewWindow.h"
30 #include "SVTK_RenderWindowInteractor.h"
31 #include "VTKViewer_Algorithm.h"
32 #include "SALOME_Actor.h"
34 #include "QtxDoubleSpinBox.h"
35 #include "QtxAction.h"
41 #include <QPushButton>
42 #include <QGridLayout>
45 #include <vtkGenericRenderWindowInteractor.h>
46 #include <vtkCallbackCommand.h>
47 #include <vtkRenderWindow.h>
48 #include <vtkRenderer.h>
49 #include <vtkMapper.h>
50 #include <vtkDataSet.h>
52 static double OFF_UPDATE_RATE = 0.0001;
53 static double FLOAT_TOLERANCE = 1.0 / VTK_FLOAT_MAX;
57 //----------------------------------------------------------------------------
60 GetUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor)
62 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
63 double aLastRenderTimeInSeconds = aRenderer->GetLastRenderTimeInSeconds();
64 if(aLastRenderTimeInSeconds > FLOAT_TOLERANCE){
65 std::ostringstream aStr;
66 double aFPS = 1.0 / aLastRenderTimeInSeconds;
68 return QString(aStr.str().c_str());
75 //----------------------------------------------------------------------------
76 struct TRenderTimeMultiplier
78 double myVTKMultiplier;
79 double mySALOMEMultiplier;
81 TRenderTimeMultiplier():
83 mySALOMEMultiplier(0.0)
87 operator()(vtkActor* theActor)
89 if(theActor->GetVisibility()){
90 myVTKMultiplier += theActor->GetAllocatedRenderTime();
91 if(dynamic_cast<SALOME_Actor*>(theActor))
92 mySALOMEMultiplier += theActor->GetAllocatedRenderTime();
98 //----------------------------------------------------------------------------
101 AdjustUpdateRate(SVTK_RenderWindowInteractor* theRWInteractor,
102 double theUpdateRate)
104 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
105 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
106 if(vtkActorCollection *anActorCollection = aCopy.GetActors()){
107 TRenderTimeMultiplier aMultiplier;
109 aMultiplier = ForEach<vtkActor>(anActorCollection,
111 if(aMultiplier.mySALOMEMultiplier > FLOAT_TOLERANCE)
112 theUpdateRate *= aMultiplier.mySALOMEMultiplier / aMultiplier.myVTKMultiplier;
115 return theUpdateRate;
119 //----------------------------------------------------------------------------
128 operator()(SALOME_Actor* theActor)
130 if(theActor->GetVisibility()){
131 if(vtkMapper *aMapper = theActor->GetMapper()){
132 if(vtkDataSet *aDataSet = aMapper->GetInput()){
133 myCounter += aDataSet->GetNumberOfCells();
141 //----------------------------------------------------------------------------
144 GetNumberOfCells(SVTK_RenderWindowInteractor* theRWInteractor)
146 if(vtkRenderer *aRenderer = theRWInteractor->getRenderer()){
147 VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
148 if(vtkActorCollection *anActorCollection = aCopy.GetActors()){
149 TCellsCounter aCounter;
151 aCounter = ForEach<SALOME_Actor>(anActorCollection,
153 return QString::number(aCounter.myCounter);
157 return QString::number(0);
165 ::SVTK_UpdateRateDlg(QtxAction* theAction,
166 SVTK_ViewWindow* theParent,
167 const char* theName):
168 ViewerTools_DialogBase(theAction,
171 myRWInteractor(theParent->GetInteractor()),
174 myEventCallbackCommand(vtkCallbackCommand::New())
176 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
177 bool anIsEnabledUpdateRate = false;
179 setWindowTitle(tr("DLG_TITLE"));
180 QVBoxLayout* aVBoxLayout = new QVBoxLayout(this);
181 aVBoxLayout->setMargin(5);
182 aVBoxLayout->setSpacing(5);
184 QGroupBox* aGroupBox = new QGroupBox(tr("INPUT_FRAME_TITLE"), this);
186 aGroupBox->setCheckable(true);
187 aGroupBox->setChecked(anIsEnabledUpdateRate);
188 myIsEnableUpdateRateGroupBox = aGroupBox;
190 QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
191 aGridLayout->setSpacing( 6 );
192 aGridLayout->setMargin( 11 );
194 QLabel* aLabel = new QLabel(tr("DESIRED"), aGroupBox);
195 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
196 aGridLayout->addWidget(aLabel, 0, 0);
198 QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(OFF_UPDATE_RATE, VTK_FLOAT_MAX, 2, aGroupBox);
199 aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
200 aGridLayout->addWidget(aDblSpinBox, 0, 1);
202 aDblSpinBox->setValue(aRWI->GetDesiredUpdateRate());
203 aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
204 connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
205 myDesiredUpdateRateSblSpinBox = aDblSpinBox;
208 QLabel* aLabel = new QLabel(tr("STILL"), aGroupBox);
209 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
210 aGridLayout->addWidget(aLabel, 1, 0);
212 QtxDoubleSpinBox* aDblSpinBox = new QtxDoubleSpinBox(OFF_UPDATE_RATE, VTK_FLOAT_MAX, 2, aGroupBox);
213 aDblSpinBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
214 aGridLayout->addWidget(aDblSpinBox, 1, 1);
216 aDblSpinBox->setValue(aRWI->GetStillUpdateRate());
217 aDblSpinBox->setEnabled(anIsEnabledUpdateRate);
218 connect(aGroupBox, SIGNAL(toggled(bool)), aDblSpinBox, SLOT(setEnabled(bool)));
219 myStillUpdateRateSblSpinBox = aDblSpinBox;
221 aVBoxLayout->addWidget(aGroupBox);
224 QGroupBox* aGroupBox = new QGroupBox(tr("INFORMATION_FRAME_TITLE"), this);
226 QGridLayout* aGridLayout = new QGridLayout(aGroupBox);
227 aGridLayout->layout()->setSpacing( 6 );
228 aGridLayout->layout()->setMargin( 11 );
230 QLabel* aLabel = new QLabel(tr("CURRENT_FPS"), aGroupBox);
231 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
232 aGridLayout->addWidget(aLabel, 0, 0);
234 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
235 aLineEdit->setReadOnly( true );
236 aGridLayout->addWidget(aLineEdit, 0, 1);
238 myCurrentUpdateRateLineEdit = aLineEdit;
239 myCurrentUpdateRateLineEdit->setText( GetUpdateRate(myRWInteractor) );
242 QLabel* aLabel = new QLabel(tr("NUMBER_CELLS"), aGroupBox);
243 aLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
244 aGridLayout->addWidget(aLabel, 1, 0);
246 QLineEdit* aLineEdit = new QLineEdit( aGroupBox );
247 aLineEdit->setReadOnly( true );
248 aGridLayout->addWidget(aLineEdit, 1, 1);
250 myNumberOfCellsLineEdit = aLineEdit;
251 myNumberOfCellsLineEdit->setText( GetNumberOfCells(myRWInteractor) );
253 aVBoxLayout->addWidget(aGroupBox);
256 QGroupBox* aGroupBox = new QGroupBox(this);
257 QHBoxLayout* aHBoxLayout = new QHBoxLayout(aGroupBox);
258 aHBoxLayout->setMargin(11);
259 aHBoxLayout->setSpacing(6);
261 QPushButton* aPushButton = new QPushButton(tr("OK"), aGroupBox);
262 aPushButton->setDefault(true);
263 aPushButton->setAutoDefault(true);
264 aHBoxLayout->addWidget(aPushButton);
265 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickOk()));
268 QPushButton* aPushButton = new QPushButton(tr("Apply"), aGroupBox);
269 aPushButton->setDefault(true);
270 aPushButton->setAutoDefault(true);
271 aHBoxLayout->addWidget(aPushButton);
272 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickApply()));
274 aHBoxLayout->addStretch();
276 QPushButton* aPushButton = new QPushButton(tr("Close"), aGroupBox);
277 aPushButton->setDefault(true);
278 aPushButton->setAutoDefault(true);
279 aHBoxLayout->addWidget(aPushButton);
280 connect(aPushButton, SIGNAL(clicked()), this, SLOT(onClickClose()));
282 aVBoxLayout->addWidget(aGroupBox);
285 if(!anIsEnabledUpdateRate){
286 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
287 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
290 myEventCallbackCommand->Delete();
291 myEventCallbackCommand->SetClientData(this);
292 myEventCallbackCommand->SetCallback(SVTK_UpdateRateDlg::ProcessEvents);
293 vtkRenderer *aRenderer = myRWInteractor->getRenderer();
294 aRenderer->AddObserver(vtkCommand::EndEvent,
295 myEventCallbackCommand.GetPointer(),
300 Destroys the object and frees any allocated resources
303 ::~SVTK_UpdateRateDlg()
305 // no need to delete child widgets, Qt does it all for us
313 ::ProcessEvents(vtkObject* vtkNotUsed(theObject),
314 unsigned long theEvent,
316 void* vtkNotUsed(theCallData))
318 SVTK_UpdateRateDlg* self = reinterpret_cast<SVTK_UpdateRateDlg*>(theClientData);
320 if(theEvent == vtkCommand::EndEvent){
321 self->myCurrentUpdateRateLineEdit->setText( GetUpdateRate(self->myRWInteractor) );
322 self->myNumberOfCellsLineEdit->setText( GetNumberOfCells(self->myRWInteractor) );
333 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
335 double aDesirableUpdateRate = aRWI->GetDesiredUpdateRate();
336 double aStillUpdateRate = aRWI->GetStillUpdateRate();
337 bool isUpdateRate = (aDesirableUpdateRate != OFF_UPDATE_RATE) || (aStillUpdateRate != OFF_UPDATE_RATE);
339 myIsEnableUpdateRateGroupBox->setChecked(isUpdateRate);
340 myDesiredUpdateRateSblSpinBox->setValue(aDesirableUpdateRate);
341 myStillUpdateRateSblSpinBox->setValue(aStillUpdateRate);
356 SLOT on Apply clicked
362 vtkRenderWindowInteractor* aRWI = myRWInteractor->GetDevice();
364 if (myIsEnableUpdateRateGroupBox->isChecked()) {
365 anUpdateRate = AdjustUpdateRate(myRWInteractor,myDesiredUpdateRateSblSpinBox->value());
366 aRWI->SetDesiredUpdateRate(anUpdateRate);
367 anUpdateRate = AdjustUpdateRate(myRWInteractor,myStillUpdateRateSblSpinBox->value());
368 aRWI->SetStillUpdateRate(anUpdateRate);
371 aRWI->SetDesiredUpdateRate(OFF_UPDATE_RATE);
372 aRWI->SetStillUpdateRate(OFF_UPDATE_RATE);
375 myRWInteractor->getRenderWindow()->Render();
379 SLOT on Close clicked