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 // File : VisuGUI_TimeAnimation.cxx
23 // Author : Vitaly SMETANNIKOV
26 #include "VisuGUI_TimeAnimation.h"
29 #include "VisuGUI_Tools.h"
30 #include "VisuGUI_ViewTools.h"
31 #include "VisuGUI_ScalarBarDlg.h"
32 #include "VisuGUI_DeformedShapeDlg.h"
33 #include "VisuGUI_CutPlanesDlg.h"
34 #include "VisuGUI_CutLinesDlg.h"
35 #include "VisuGUI_CutSegmentDlg.h"
36 #include "VisuGUI_Plot3DDlg.h"
37 #include "VisuGUI_VectorsDlg.h"
38 #include "VisuGUI_IsoSurfacesDlg.h"
39 #include "VisuGUI_StreamLinesDlg.h"
40 #include "VisuGUI_DeformedShapeAndScalarMapDlg.h"
41 #include "VisuGUI_GaussPointsDlg.h"
43 #include "VISU_TimeAnimation.h"
45 #include "VISU_ScalarMap_i.hh"
46 #include "VISU_IsoSurfaces_i.hh"
47 #include "VISU_DeformedShape_i.hh"
48 #include "VISU_CutPlanes_i.hh"
49 #include "VISU_Plot3D_i.hh"
50 #include "VISU_CutLines_i.hh"
51 #include "VISU_CutSegment_i.hh"
52 #include "VISU_Vectors_i.hh"
53 #include "VISU_StreamLines_i.hh"
54 #include "VISU_DeformedShapeAndScalarMap_i.hh"
55 #include "VISU_GaussPoints_i.hh"
57 #include "VISU_ViewManager_i.hh"
59 #include "VISU_ScalarBarActor.hxx"
60 #include "VISU_Actor.h"
62 #include "SalomeApp_Study.h"
63 #include "LightApp_Application.h"
65 #include "SVTK_ViewWindow.h"
67 #include "VTKViewer_Algorithm.h"
69 #include "SUIT_OverrideCursor.h"
70 #include "SUIT_MessageBox.h"
71 #include "SUIT_ResourceMgr.h"
72 #include "SUIT_Session.h"
73 #include "SUIT_Desktop.h"
74 #include "SUIT_FileDlg.h"
76 #include <vtkRenderer.h>
77 #include <vtkMapper.h>
79 #include <QGridLayout>
81 #include <QImageWriter>
85 #include <QListWidget>
87 #include <QToolButton>
91 #include <QRadioButton>
93 #include <QPushButton>
96 #include <qwt_wheel.h>
99 #define VALPRECISION 8
102 void GeneratePresentations(int theFieldId, VISU_TimeAnimation* theAnimator)
104 if(theAnimator->getNbFields() == 0)
107 theAnimator->generatePresentations(theFieldId);
108 FieldData& aFieldData = theAnimator->getFieldData(theFieldId);
111 int aRefFieldId = ( theAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ? theFieldId : 0;
112 if(VISU::ColoredPrs3d_i* aInitialPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(theAnimator->getFieldData(aRefFieldId).myPrs[0])){
113 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
114 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
116 // Special case for DeformedShape And ScalarMap presentation
117 // Restore time stamp number for all presentations
118 VISU::DeformedShapeAndScalarMap_i* aDeformedAndScalPrs = dynamic_cast<VISU::DeformedShapeAndScalarMap_i*>(aColoredPrs3d);
119 int aTimeStampNum = -1;
120 if(aDeformedAndScalPrs){
121 aTimeStampNum = aDeformedAndScalPrs->GetScalarTimeStampNumber();
123 aColoredPrs3d->SameAs(aInitialPrs3d);
125 if(aDeformedAndScalPrs){
126 aDeformedAndScalPrs->SetScalarField(aDeformedAndScalPrs->GetScalarEntity(),
127 aDeformedAndScalPrs->GetScalarFieldName(),
131 std::string aTitle = aColoredPrs3d->GetCTitle();
132 if ( aFrameId != 0 && theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
133 aColoredPrs3d->SetTitle(aTitle.c_str());
140 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
141 : QDialog(theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
142 myAnimator(theAnimator),
143 myViewWindow(theAnimator->getViewer())
148 QStringList aFieldNames;
149 // Find names of fields
150 for (int i = 0; i < myAnimator->getNbFields(); i++) {
151 _PTR(SObject) aSObject = myAnimator->getFieldData(i).myField;
152 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
153 aFieldNames.append(aRestoringMap["myName"]);
155 aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
156 aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
157 aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
158 myOffsets.append(aOffs);
160 myFieldLst->addItems(aFieldNames);
161 myFieldLst->setCurrentRow(0);
164 ArrangeDlg::ArrangeDlg(QWidget* theParent,
165 const SalomeApp_Module* theModule,
166 SVTK_ViewWindow* theViewWindow)
167 : QDialog(theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
169 myViewWindow(theViewWindow)
174 QStringList aPrsNames;
175 VTK::ActorCollectionCopy aCopy(myViewWindow->getRenderer()->GetActors());
176 vtkActorCollection *aCollection = aCopy.GetActors();
177 aCollection->InitTraversal();
178 while(vtkActor* anActor = aCollection->GetNextActor()){
179 if (VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor)) {
180 if(anVISUActor->GetVisibility() != 0){
181 if (VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d()){
182 if(!myPrsMap.contains(aPrs)){
183 Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
184 if(!anIO->hasEntry())
186 SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
187 VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
188 if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
189 _PTR(GenericAttribute) anAttr;
190 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
191 _PTR(AttributeName) aName(anAttr);
192 QString strIn(aName->Value().c_str());
193 aPrsNames.append(strIn);
194 myPrsMap[aPrs] = myOffsets.count();
196 anVISUActor->GetPosition(aOffs.myOffset);
197 myOffsets.append(aOffs);
203 } else { //if PointMap3d Actor
204 if (VISU_ActorBase* anActorBase = dynamic_cast<VISU_ActorBase*>(anActor))
205 if(anActorBase->GetVisibility() != 0)
206 if (VISU::PointMap3d_i* aPrs = dynamic_cast<VISU::PointMap3d_i*>(anActorBase->GetFactory())) {
207 if(!myPointMapPrsMap.contains(aPrs)){
208 Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
209 if(!anIO->hasEntry())
211 SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
212 VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
213 if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
214 _PTR(GenericAttribute) anAttr;
215 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
216 _PTR(AttributeName) aName(anAttr);
217 QString strIn(aName->Value().c_str());
218 aPrsNames.append(strIn);
219 myPointMapPrsMap[aPrs] = myOffsets.count();
221 anActorBase->GetPosition(aOffs.myOffset);
222 myOffsets.append(aOffs);
229 myFieldLst->addItems(aPrsNames);
230 myFieldLst->setCurrentRow(0);
233 void ArrangeDlg::init()
235 setWindowTitle("Arrange Presentations");
236 setSizeGripEnabled( TRUE );
238 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
239 aMainLayout->setMargin( 7 );
240 aMainLayout->setSpacing(5);
242 QButtonGroup* aBtnGrp = new QButtonGroup( this);
243 aBtnGrp->setExclusive(true);
244 //aMainLayout->addWidget(aBtnGrp);
246 QGroupBox* aBtnGB = new QGroupBox( this );
247 QHBoxLayout* aHBLay = new QHBoxLayout( aBtnGB );
248 aMainLayout->addWidget(aBtnGB);
250 QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGB);
251 aHBLay->addWidget( aAutoBtn );
252 aBtnGrp->addButton(aAutoBtn, AutoMode);
254 QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGB);
255 aHBLay->addWidget( aManualBtn );
256 aBtnGrp->addButton(aManualBtn, ManualMode);
258 aAutoBtn->setChecked( true );
260 myStackWgt = new QStackedWidget(this);
261 aMainLayout->addWidget(myStackWgt);
264 QWidget* aAutoPane = new QWidget(myStackWgt);
265 QVBoxLayout* aAutoLay = new QVBoxLayout( aAutoPane );
266 aAutoLay->setSpacing(5);
269 myAxisGrp = new QButtonGroup(aAutoPane);
271 QGroupBox* aAxisGB = new QGroupBox( "Axis", aAutoPane );
272 QHBoxLayout* aVBLay = new QHBoxLayout( aAxisGB );
273 aAutoLay->addWidget( aAxisGB );
275 QRadioButton* aXBtn = new QRadioButton("X",aAxisGB );
276 aVBLay->addWidget( aXBtn );
277 myAxisGrp->addButton(aXBtn, XAxis);
279 QRadioButton* aYBtn = new QRadioButton("Y",aAxisGB );
280 aVBLay->addWidget( aYBtn );
281 myAxisGrp->addButton(aYBtn, YAxis);
283 QRadioButton* aZBtn = new QRadioButton("Z",aAxisGB );
284 aVBLay->addWidget( aZBtn );
285 myAxisGrp->addButton(aZBtn, ZAxis);
287 aXBtn->setChecked( true );
290 QWidget* aDistPane = new QWidget(aAutoPane);
291 QHBoxLayout* aHLay = new QHBoxLayout( aDistPane );
292 aHLay->setSpacing(5);
293 aHLay->addWidget( new QLabel("Relative Distance", aDistPane) );
294 myDistVal = new QtxDoubleSpinBox (-10,10, 0.5, aDistPane);
295 myDistVal->setValue(1);
296 aHLay->addWidget( myDistVal );
298 aAutoLay->addWidget( aDistPane );
300 myStackWgt->insertWidget( AutoMode, aAutoPane);
303 QWidget* aManualPane = new QWidget(myStackWgt);
304 aHLay = new QHBoxLayout( aManualPane );
305 aHLay->setSpacing(10);
307 myFieldLst = new QListWidget(aManualPane);
308 aHLay->addWidget( myFieldLst );
309 connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
310 this, SLOT( onFieldChange(int) ) );
312 QWidget* aCoordPane = new QWidget( aManualPane);
313 aHLay->addWidget( aCoordPane );
314 QGridLayout* aCoordLayout = new QGridLayout( aCoordPane );
315 aCoordLayout->setSpacing(5);
317 aCoordLayout->addWidget( new QLabel("X", aCoordPane), 0, 0 );
318 myCoord[0] = new QtxDoubleSpinBox(aCoordPane);
319 myCoord[0]->setRange(-MAXVAL, MAXVAL);
320 aCoordLayout->addWidget( myCoord[0], 0, 1 );
322 aCoordLayout->addWidget( new QLabel("Y", aCoordPane), 1, 0 );
323 myCoord[1] = new QtxDoubleSpinBox(aCoordPane);
324 myCoord[1]->setRange(-MAXVAL, MAXVAL);
325 aCoordLayout->addWidget( myCoord[1], 1, 1 );
327 aCoordLayout->addWidget( new QLabel("Z", aCoordPane), 2, 0 );
328 myCoord[2] = new QtxDoubleSpinBox(aCoordPane);
329 myCoord[2]->setRange(-MAXVAL, MAXVAL);
330 aCoordLayout->addWidget( myCoord[2], 2, 1 );
332 myStackWgt->insertWidget(ManualMode, aManualPane );
334 myStackWgt->setCurrentIndex(AutoMode);
336 connect(aBtnGrp, SIGNAL(buttonClicked(int)), myStackWgt, SLOT(setCurrentIndex(int)) );
338 SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
339 SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
340 _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
341 if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
342 mySaveChk = new QCheckBox ("Save to presentation", this);
343 mySaveChk->setChecked(false);
344 aMainLayout->addWidget(mySaveChk);
349 // Common buttons ===========================================================
350 QGroupBox* GroupButtons = new QGroupBox( this );
351 //GroupButtons->setColumnLayout(0, Qt::Vertical );
352 //GroupButtons->layout()->setSpacing( 0 );
353 //GroupButtons->layout()->setMargin( 0 );
354 QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons );
355 GroupButtonsLayout->setAlignment( Qt::AlignTop );
356 GroupButtonsLayout->setSpacing( 6 );
357 GroupButtonsLayout->setMargin( 11 );
359 QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons );
360 buttonOk->setAutoDefault( TRUE );
361 buttonOk->setDefault( TRUE );
362 GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
363 GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
365 QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons );
366 buttonCancel->setAutoDefault( TRUE );
367 GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
369 aMainLayout->addWidget( GroupButtons );
371 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
372 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
375 void ArrangeDlg::accept()
377 if (myAnimator != NULL) {
385 void ArrangeDlg::onFieldChange(int theCurrent)
387 if (myCurrent != theCurrent) {
388 Offset& aOffs = myOffsets[myCurrent];
389 aOffs.myOffset[0] = myCoord[0]->value();
390 aOffs.myOffset[1] = myCoord[1]->value();
391 aOffs.myOffset[2] = myCoord[2]->value();
393 myCurrent = theCurrent;
394 const Offset& aNewOffs = myOffsets[myCurrent];
395 myCoord[0]->setValue(aNewOffs.myOffset[0]);
396 myCoord[1]->setValue(aNewOffs.myOffset[1]);
397 myCoord[2]->setValue(aNewOffs.myOffset[2]);
400 void ArrangeDlg::acceptAnimation()
402 if (getMode() == ManualMode) {
404 Offset& aOffs = myOffsets[myCurrent];
405 aOffs.myOffset[0] = myCoord[0]->value();
406 aOffs.myOffset[1] = myCoord[1]->value();
407 aOffs.myOffset[2] = myCoord[2]->value();
409 for (int i = 0; i < myAnimator->getNbFields(); i++) {
410 Offset aOffs = myOffsets[i];
411 myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
412 myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
413 myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
416 QApplication::setOverrideCursor( Qt::WaitCursor );
417 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentRow());
418 if (aData.myPrs.empty())
419 GeneratePresentations(myFieldLst->currentRow(),myAnimator);
420 vtkFloatingPointType aBounds[6];
421 aData.myPrs[0]->GetBounds(aBounds);
422 vtkFloatingPointType aDist = 0;
423 int aAxis = getAxis();
426 aDist = fabs(aBounds[1] - aBounds[0]);
429 aDist = fabs(aBounds[3] - aBounds[2]);
432 aDist = fabs(aBounds[5] - aBounds[4]);
435 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
436 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
437 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
438 vtkFloatingPointType max = (dx > dy) ? dx : dy;
439 max = (dz > max) ? dz : max;
443 // set base distance between centers of bounding boxes
444 // to minimal (but big enough) size of current bounding box
445 if (dx < max) dx = FLT_MAX;
446 if (dy < max) dy = FLT_MAX;
447 if (dz < max) dz = FLT_MAX;
449 aDist = (dx < dy) ? dx : dy;
450 aDist = (dz < aDist) ? dz : aDist;
452 aDist = aDist * getDistance();
453 for (int i = 0; i < myAnimator->getNbFields(); i++) {
454 myAnimator->getFieldData(i).myOffset[0] = 0;
455 myAnimator->getFieldData(i).myOffset[1] = 0;
456 myAnimator->getFieldData(i).myOffset[2] = 0;
457 myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
460 QApplication::restoreOverrideCursor();
464 void ArrangeDlg::acceptViewWindow()
466 if (getMode() == ManualMode) {
468 Offset& aOffs = myOffsets[myCurrent];
469 aOffs.myOffset[0] = myCoord[0]->value();
470 aOffs.myOffset[1] = myCoord[1]->value();
471 aOffs.myOffset[2] = myCoord[2]->value();
473 QMap<VISU::Prs3d_i*, int>::Iterator it;
474 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
475 VISU::Prs3d_i* aPrs = it.key();
476 Offset& aOffs = myOffsets[it.value()];
477 if (VISU_Actor* anActor = VISU::FindActor(myViewWindow, aPrs))
478 anActor->SetPosition(aOffs.myOffset);
480 if (mySaveChk->isChecked())
481 aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
483 QMap<VISU::PointMap3d_i*, int>::Iterator itt;
484 for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt) {
485 VISU::PointMap3d_i* aPrs = itt.key();
486 Offset& aOffs = myOffsets[itt.value()];
487 if (VISU_ActorBase* anActor = VISU::FindActorBase(myViewWindow, aPrs))
488 anActor->SetPosition(aOffs.myOffset);
490 if (mySaveChk->isChecked())
491 aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
494 vtkFloatingPointType aDist = 0;
495 vtkFloatingPointType aShift = 0;
496 vtkFloatingPointType aPrevDist = 0;
497 vtkFloatingPointType aPrevShift = 0;
499 QMap<VISU::Prs3d_i*, int>::Iterator it;
500 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it, i++) {
501 VISU::Prs3d_i* aPrs = it.key();
502 if (VISU_Actor* aActor = VISU::FindActor(myViewWindow, aPrs)) {
503 int aAxis = getAxis();
505 vtkFloatingPointType aZeroOffset[3];
506 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
507 aActor->SetPosition(aZeroOffset);
508 aActor->GetMapper()->Update();
510 vtkFloatingPointType aBounds[6];
511 aActor->GetBounds(aBounds);
514 aDist = fabs(aBounds[1] - aBounds[0]);
517 aDist = fabs(aBounds[3] - aBounds[2]);
520 aDist = fabs(aBounds[5] - aBounds[4]);
522 vtkFloatingPointType aOffset[3];
523 aOffset[0] = aOffset[1] = aOffset[2] = 0;
525 (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
528 vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
530 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
531 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
532 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
533 vtkFloatingPointType max = (dx > dy) ? dx : dy;
534 max = (dz > max) ? dz : max;
538 // set base distance between centers of bounding boxes
539 // to minimal (but big enough) size of current bounding box
540 if (dx < max) dx = FLT_MAX;
541 if (dy < max) dy = FLT_MAX;
542 if (dz < max) dz = FLT_MAX;
544 aCCDist = (dx < dy) ? dx : dy;
545 aCCDist = (dz < aCCDist) ? dz : aCCDist;
548 //-------------------------------->
552 // .--------------. .------.
553 //----------->| | | |
554 // aPrevShift '--------------' '------'
559 // (aDist + aPrevDist) * getDistance() / 2
561 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
564 aOffset[aAxis] += aShift;
565 aActor->SetPosition(aOffset);
567 if (mySaveChk->isChecked())
568 aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
573 } // end of myPrsMap loop
574 // Loop in PointMap3D the same as previous loop
575 QMap<VISU::PointMap3d_i*, int>::Iterator itt;
576 for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt, i++) {
577 VISU::PointMap3d_i* aPrs = itt.key();
578 if (VISU_ActorBase* aActor = VISU::FindActorBase(myViewWindow, aPrs)) {
579 int aAxis = getAxis();
581 vtkFloatingPointType aZeroOffset[3];
582 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
583 aActor->SetPosition(aZeroOffset);
584 aActor->GetMapper()->Update();
586 vtkFloatingPointType aBounds[6];
587 aActor->GetBounds(aBounds);
590 aDist = fabs(aBounds[1] - aBounds[0]);
593 aDist = fabs(aBounds[3] - aBounds[2]);
596 aDist = fabs(aBounds[5] - aBounds[4]);
598 vtkFloatingPointType aOffset[3];
599 aOffset[0] = aOffset[1] = aOffset[2] = 0;
601 (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
604 vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
606 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
607 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
608 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
609 vtkFloatingPointType max = (dx > dy) ? dx : dy;
610 max = (dz > max) ? dz : max;
614 // set base distance between centers of bounding boxes
615 // to minimal (but big enough) size of current bounding box
616 if (dx < max) dx = FLT_MAX;
617 if (dy < max) dy = FLT_MAX;
618 if (dz < max) dz = FLT_MAX;
620 aCCDist = (dx < dy) ? dx : dy;
621 aCCDist = (dz < aCCDist) ? dz : aCCDist;
623 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
626 aOffset[aAxis] += aShift;
627 aActor->SetPosition(aOffset);
629 if (mySaveChk->isChecked())
630 aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
635 } // end of myPointMapPrsMap loop
637 myViewWindow->getRenderer()->ResetCameraClippingRange();
638 myViewWindow->Repaint();
642 //------------------------------------------------------------------------
643 //------------------------------------------------------------------------
645 class SetupDlg::LineEdit : public QLineEdit
648 LineEdit( QWidget* p = 0 ) : QLineEdit( p ) {}
649 virtual ~LineEdit() {}
652 void focusOutEvent( QFocusEvent* e )
654 QLineEdit::focusOutEvent( e );
656 if ( text().isEmpty() )
657 emit editingFinished();
659 void keyPressEvent( QKeyEvent* e )
661 QLineEdit::keyPressEvent( e );
663 if ( text().isEmpty() && e->key() == Qt::Key_Return )
664 emit returnPressed();
669 //------------------------------------------------------------------------
670 //------------------------------------------------------------------------
672 SetupDlg::SetupDlg (QWidget* theParent,
674 VISU_TimeAnimation* theAnimator) :
676 Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
677 myAnimator(theAnimator),
679 myIsRegenerate( false )
682 setWindowTitle("Setup Animation");
683 setSizeGripEnabled( TRUE );
685 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
686 aMainLayout->setMargin( 7 );
687 aMainLayout->setSpacing(5);
689 // Range of time stamps
690 myUseRangeBox = new QGroupBox("Use range of time stamps", this);
691 myUseRangeBox->setCheckable( true );
692 myUseRangeBox->setChecked(myAnimator->isRangeDefined());
694 QHBoxLayout* aRangeLayout = new QHBoxLayout( myUseRangeBox );
695 aRangeLayout->setMargin( 11 );
696 aRangeLayout->setSpacing( 6 );
698 double aMaxTime = myAnimator->getMaxTime();
699 double aMinTime = myAnimator->getMinTime();
701 if( myAnimator->getNbFields() > 0 ) {
702 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
703 aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
704 else { // successive animation mode
705 std::pair<int,long> aLastFieldFrame(myAnimator->getNbFields() - 1,
706 myAnimator->getFieldData(myAnimator->getNbFields() - 1).myNbTimes - 1);
707 aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
711 QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
712 aRangeLayout->addWidget(aMinLbl);
713 //myMinVal = new QtxDoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
714 myMinVal = new LineEdit( myUseRangeBox );
715 myMinVal->setValidator( new QDoubleValidator( myMinVal ) );
716 if ( myUseRangeBox->isChecked() )
717 myMinVal->setText( QString::number( myAnimator->getMinRange() ) );
719 myMinVal->setText( QString::number( aMinTime ) );
721 // connect(myMinVal, SIGNAL( valueChanged(double)),
722 // this, SLOT( onMinValue(double) ));
723 connect( myMinVal, SIGNAL( returnPressed() ), this, SLOT( onMinValue() ) );
724 connect( myMinVal, SIGNAL( editingFinished() ), this, SLOT( onMinValue() ) );
725 // connect( myMinVal, SIGNAL( textChanged(const QString&)),
726 // this, SLOT( onMinValueEdit(const QString&) ));
727 aRangeLayout->addWidget(myMinVal);
729 QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
730 aRangeLayout->addWidget(aMaxLbl);
731 //myMaxVal = new QtxDoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
732 myMaxVal = new LineEdit( myUseRangeBox );
733 myMaxVal->setValidator( new QDoubleValidator( myMaxVal ) );
734 if ( myUseRangeBox->isChecked() )
735 myMaxVal->setText( QString::number( myAnimator->getMaxRange() ) );
737 myMaxVal->setText( QString::number( aMaxTime ) );
739 // connect(myMaxVal, SIGNAL( valueChanged(double)),
740 // this, SLOT( onMaxValue(double) ));
741 connect( myMaxVal, SIGNAL( returnPressed() ), this, SLOT( onMaxValue() ) );
742 connect( myMaxVal, SIGNAL( editingFinished() ), this, SLOT( onMaxValue() ) );
743 // connect(myMaxVal, SIGNAL( textChanged(const QString&)),
744 // this, SLOT( onMaxValueEdit(const QString&) ));
745 aRangeLayout->addWidget(myMaxVal);
747 connect(myUseRangeBox, SIGNAL( toggled(bool)),
748 this, SLOT( onRangeCheck(bool) ));
750 aMainLayout->addWidget(myUseRangeBox);
752 // Sequence of time stamps
753 myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
754 myUseSequenceBox->setCheckable( true );
755 myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
757 QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox );
758 aUseSequenceLayout->setAlignment( Qt::AlignTop );
759 aUseSequenceLayout->setSpacing( 6 );
760 aUseSequenceLayout->setMargin( 11 );
762 QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
763 myIndices = new QLineEdit( myUseSequenceBox );
765 myValues = new QListWidget( myUseSequenceBox );
766 myValues->setSelectionMode( QAbstractItemView::ExtendedSelection );
768 connect(myIndices, SIGNAL( textChanged(const QString&)),
769 this, SLOT( onIndicesChanged(const QString&) ));
771 connect(myValues, SIGNAL( itemSelectionChanged() ),
772 this, SLOT( onValuesChanged() ) );
774 connect(myUseSequenceBox, SIGNAL( toggled(bool)),
775 this, SLOT( onSequenceCheck(bool) ));
777 aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
778 aUseSequenceLayout->addWidget( myIndices, 0, 1 );
779 aUseSequenceLayout->addWidget( myValues, 1, 1, 1, 2 );
781 aMainLayout->addWidget(myUseSequenceBox);
783 // Fields and Properties
784 QWidget* aPropFrame = new QWidget(this);
785 QHBoxLayout* aHPropLayout = new QHBoxLayout( aPropFrame );
786 aHPropLayout->setSpacing(5);
787 aHPropLayout->setMargin(0);
789 QGroupBox* aNamesBox = new QGroupBox("Fields",aPropFrame);
790 aHPropLayout->addWidget( aNamesBox );
791 QVBoxLayout* aVBoxLayout = new QVBoxLayout( aNamesBox );
793 myFieldLst = new QListWidget(aNamesBox);
794 aVBoxLayout->addWidget( myFieldLst );
795 QStringList aFieldNames;
796 // Find names of fields
797 for (int i = 0; i < myAnimator->getNbFields(); i++) {
798 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
799 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
800 QString aFieldName(aRestoringMap["myName"]);
801 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
802 aFieldNames.append(aFieldName);
803 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
804 _PTR(SObject) aSObject = aSO->GetFather()->GetFather()->GetFather();
805 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
806 QString aFileName(aRestoringMap["myInitFileName"]);
807 aFileName = aFileName.right(aFileName.length() - (aFileName.lastIndexOf("/") + 1));
808 aFieldNames.append(aFileName + QString(" : ") + aFieldName);
811 myFieldLst->addItems(aFieldNames);
813 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
814 myFieldLst->setCurrentRow(0);
815 connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
816 this, SLOT( onFieldChange(int) ) );
818 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
819 myFieldLst->setSelectionMode(QAbstractItemView::NoSelection);
821 QWidget* aSetupBox = new QWidget(aPropFrame);
822 aHPropLayout->addWidget( aSetupBox );
823 aVBoxLayout = new QVBoxLayout( aSetupBox );
824 aVBoxLayout->setSpacing(5);
825 aVBoxLayout->setMargin(0);
827 QGroupBox* aPropBox = new QGroupBox("Properties", aSetupBox);
828 aVBoxLayout->addWidget( aPropBox );
829 QVBoxLayout* aPropVBLay = new QVBoxLayout( aPropBox );
831 //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
832 myTypeCombo = new QComboBox(aPropBox);
833 aPropVBLay->addWidget( myTypeCombo );
834 connect( myTypeCombo, SIGNAL( activated(int) ),
835 this, SLOT( onTypeChanged(int) ) );
837 // QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
838 //connect( aBarBtn, SIGNAL( clicked() ),
839 // this, SLOT( onScalarBarDlg() ) );
841 myPropBtn = new QPushButton("Properties...", aPropBox);
842 myPropBtn->setAutoDefault( false );
843 aPropVBLay->addWidget( myPropBtn );
844 // myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
845 connect( myPropBtn, SIGNAL( clicked() ),
846 this, SLOT( onPreferencesDlg() ) );
848 if (myAnimator->getNbFields() > 1 ) {
849 if( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
850 myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
851 aVBoxLayout->addWidget( myArrangeBtn );
852 connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
856 aMainLayout->addWidget(aPropFrame);
858 QWidget* aBtnBox = new QWidget(this);
859 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
860 aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
861 // aBtnLayout->addStretch();
863 QPushButton* closeBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
864 closeBtn->setAutoDefault( false );
865 aBtnLayout->addStretch();
866 aBtnLayout->addWidget( closeBtn );
867 connect( closeBtn, SIGNAL( clicked() ), this, SLOT( onClose() ) );
869 aMainLayout->addWidget( aBtnBox );
872 //------------------------------------------------------------------------
873 void SetupDlg::initialize()
877 _PTR(Study) aStudy = myAnimator->getStudy();
879 if( myAnimator->getNbFields() == 0 )
882 FieldData& aData = myAnimator->getFieldData( 0 );
883 _PTR(SObject) aField = aData.myField;
888 _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
889 anIter->Next(); // First is reference on support
890 for(int index = 1; anIter->More(); anIter->Next(), index++)
892 double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
893 QString itemText = QString("[%1] - %2").arg( index ).arg( aTime );
895 myValues->addItem( itemText );
898 QString anIndices( myAnimator->getAnimationSequence() );
899 myIndices->setText( anIndices );
902 //------------------------------------------------------------------------
904 TSCALARMAP_ITEM = 0, // VISU::TSCALARMAP
905 TISOSURFACES_ITEM = 1, // VISU::TISOSURFACES
906 TCUTPLANES_ITEM = 2, // VISU::TCUTPLANES
907 TCUTLINES_ITEM = 3, // VISU::TCUTLINES
908 TCUTSEGMENT_ITEM = 4, // VISU::TCUTSEGMENT
909 TPLOT3D_ITEM = 5, // VISU::TPLOT3D
910 TDEFORMEDSHAPE_ITEM = 6, // VISU::TDEFORMEDSHAPE
911 TVECTORS_ITEM = 7, // VISU::TVECTORS
912 TSTREAMLINES_ITEM = 8, // VISU::TSTREAMLINES
913 TGAUSSPOINTS_ITEM = 9, // VISU::TGAUSSPOINTS
914 TDEFORMEDSHAPEANDSCALARMAP_ITEM = 10 // VISU::TDEFORMEDSHAPEANDSCALARMAP
917 //------------------------------------------------------------------------
918 void SetupDlg::onClose()
920 if ( !myUseRangeBox->isChecked() )
921 myAnimator->setAnimationRange( 0, 0 );
924 double min = myMinVal->text().toDouble();
925 double max = myMaxVal->text().toDouble();
926 myAnimator->setAnimationRange( qMin( min, max ), qMax( min, max ) );
929 if ( !myUseSequenceBox->isChecked() )
930 myAnimator->setAnimationSequence( 0 );
935 //------------------------------------------------------------------------
936 void SetupDlg::onFieldChange (int theIndex)
938 myTypeCombo->clear();
939 myTypeId2ComboId.clear();
940 myComboId2TypeId.clear();
942 if( myAnimator->getNbFields() == 0 )
945 // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
946 myTypeCombo->addItem("Scalar Map"); // item 0
947 myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
948 myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
950 myTypeCombo->addItem("Iso Surfaces"); // item 1
951 myTypeId2ComboId[TISOSURFACES_ITEM] = myComboId2TypeId.size();
952 myComboId2TypeId.push_back(TISOSURFACES_ITEM);;
954 myTypeCombo->addItem("Cut Planes"); // item 2
955 myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
956 myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
958 myTypeCombo->addItem("Cut Lines"); // item 3
959 myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
960 myComboId2TypeId.push_back(TCUTLINES_ITEM);;
962 myTypeCombo->addItem("Cut Segment"); // item 4
963 myTypeId2ComboId[TCUTSEGMENT_ITEM] = myComboId2TypeId.size();
964 myComboId2TypeId.push_back(TCUTSEGMENT_ITEM);;
966 myTypeCombo->addItem("Plot 3D"); // item 5
967 myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
968 myComboId2TypeId.push_back(TPLOT3D_ITEM);;
970 bool anEnableItems = false;
971 bool anEnableGP = false;
972 VISU::VISUType aPrsType;
973 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) { // parallel animation mode
975 FieldData& aData = myAnimator->getFieldData(theIndex);
976 _PTR(SObject) aSObject = aData.myField;
977 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
978 long aNumComp = aRestoringMap["myNumComponent"].toLong();
979 anEnableItems = (aNumComp > 1);
981 long anEntityId = aRestoringMap["myEntityId"].toLong();
982 anEnableGP = (anEntityId == VISU::CELL);
984 aPrsType = aData.myPrsType;
987 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) { // successive animation mode
989 for (int i = 0; i < myAnimator->getNbFields(); i++) {
990 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
991 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
992 long aNumComp = aRestoringMap["myNumComponent"].toLong();
993 anEnableItems = (aNumComp > 1);
995 long anEntityId = aRestoringMap["myEntityId"].toLong();
996 anEnableGP = (anEntityId == VISU::CELL);
998 if ( !anEnableItems && !anEnableGP ) break;
1001 aPrsType = myAnimator->getFieldData(0).myPrsType;
1005 if (anEnableItems) {
1006 myTypeCombo->addItem("Deformed Shape"); // item 6
1007 myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
1008 myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
1010 myTypeCombo->addItem("Vectors"); // item 7
1011 myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
1012 myComboId2TypeId.push_back(TVECTORS_ITEM);;
1014 myTypeCombo->addItem("Stream Lines"); // item 8
1015 myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
1016 myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
1018 myTypeCombo->addItem("Deformed shape and Scalar map"); // item 10
1019 myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM] = myComboId2TypeId.size();
1020 myComboId2TypeId.push_back(TDEFORMEDSHAPEANDSCALARMAP_ITEM);;
1024 myTypeCombo->addItem("Gauss Points"); // item 9
1025 myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
1026 myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
1030 case VISU::TSCALARMAP: //Scalar Map
1031 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSCALARMAP_ITEM]);
1033 case VISU::TISOSURFACES: //Iso Surfaces
1034 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TISOSURFACES_ITEM]);
1036 case VISU::TCUTPLANES: //Cut Planes
1037 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTPLANES_ITEM]);
1039 case VISU::TCUTLINES: //Cut Lines
1040 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTLINES_ITEM]);
1042 case VISU::TCUTSEGMENT: //Cut Segment
1043 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTSEGMENT_ITEM]);
1045 case VISU::TPLOT3D: //Plot 3D
1046 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TPLOT3D_ITEM]);
1048 case VISU::TDEFORMEDSHAPE: //Deformed Shape
1049 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
1051 case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
1052 case VISU::TDEFORMEDSHAPEANDSCALARMAP:
1053 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM]);
1055 case VISU::TVECTORS: //Vectors
1056 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TVECTORS_ITEM]);
1058 case VISU::TSTREAMLINES: //Stream Lines
1059 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSTREAMLINES_ITEM]);
1061 case VISU::TGAUSSPOINTS: //Gauss Points
1062 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
1065 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1068 //------------------------------------------------------------------------
1069 void SetupDlg::onTypeChanged (int theIndex)
1071 int aType = myComboId2TypeId[theIndex];
1073 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1074 FieldData& aData = ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ?
1075 myAnimator->getFieldData(myFieldLst->currentRow()) :
1076 myAnimator->getFieldData(i);
1079 case TSCALARMAP_ITEM: //Scalar Map
1080 aData.myPrsType = VISU::TSCALARMAP;
1082 case TISOSURFACES_ITEM: //Iso Surfaces
1083 aData.myPrsType = VISU::TISOSURFACES;
1085 case TCUTPLANES_ITEM: //Cut Planes
1086 aData.myPrsType = VISU::TCUTPLANES;
1088 case TCUTLINES_ITEM: //Cut Lines
1089 aData.myPrsType = VISU::TCUTLINES;
1091 case TCUTSEGMENT_ITEM: //Cut Segment
1092 aData.myPrsType = VISU::TCUTSEGMENT;
1094 case TPLOT3D_ITEM: //Plot 3D
1095 aData.myPrsType = VISU::TPLOT3D;
1097 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1098 aData.myPrsType = VISU::TDEFORMEDSHAPE;
1100 case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1101 aData.myPrsType = VISU::TDEFORMEDSHAPEANDSCALARMAP;
1103 case TVECTORS_ITEM: //Vectors
1104 aData.myPrsType = VISU::TVECTORS;
1106 case TSTREAMLINES_ITEM: //Stream Lines
1107 aData.myPrsType = VISU::TSTREAMLINES;
1109 case TGAUSSPOINTS_ITEM: //Gauss Points
1110 aData.myPrsType = VISU::TGAUSSPOINTS;
1113 myAnimator->clearData(aData);
1115 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) // parallel animation mode
1118 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1119 //myAnimator->generatePresentations(myFieldLst->currentItem());
1123 //------------------------------------------------------------------------
1126 template<class TPrs3d, class TDialog>
1128 EditPrs(VisuGUI* theModule,
1130 VISU_TimeAnimation* theAnimator)
1132 TDialog* aDlg = new TDialog(theModule);
1133 TPrs3d* aPrs3d = dynamic_cast<TPrs3d*>(theData.myPrs[0]);
1134 aDlg->initFromPrsObject(aPrs3d, true);
1135 if (aDlg->exec() && aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(aPrs3d))) {
1137 for (long aFrameId = 1; aFrameId < theData.myNbFrames; aFrameId++){
1138 VISU::ColoredPrs3d_i* aColoredPrs3d = theData.myPrs[aFrameId];
1139 aColoredPrs3d->SameAs(aPrs3d);
1142 if ( theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1143 for (int aFieldId = 1; aFieldId < theAnimator->getNbFields(); aFieldId++) {
1144 FieldData& aFieldData = theAnimator->getFieldData(aFieldId);
1145 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1146 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1147 std::string aTitle = aColoredPrs3d->GetCTitle();
1148 aColoredPrs3d->SameAs(aPrs3d);
1149 aColoredPrs3d->SetTitle(aTitle.c_str());
1159 void SetupDlg::onPreferencesDlg()
1161 if(myAnimator->getNbFields() == 0){
1162 SUIT_MessageBox::warning(this,
1164 VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1169 SUIT_OverrideCursor c;
1171 VISU::Animation::AnimationMode aMode = myAnimator->getAnimationMode();
1172 int aRefFieldId = ( aMode == VISU::Animation::PARALLEL ) ? myFieldLst->currentRow() : 0;
1173 FieldData& aData = myAnimator->getFieldData(aRefFieldId);
1174 if (aData.myPrs.empty())
1175 myAnimator->generatePresentations(aRefFieldId);
1177 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1178 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1179 if ( i != aRefFieldId && myAnimator->getFieldData(i).myPrs.empty() )
1180 myAnimator->generatePresentations(i);
1184 if(!aData.myNbFrames || aData.myPrs.empty() || !aData.myPrs[0]){
1185 QApplication::restoreOverrideCursor();
1186 SUIT_MessageBox::warning(this,
1188 VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1193 int aType = myComboId2TypeId[myTypeCombo->currentIndex()];
1195 case TSCALARMAP_ITEM: //Scalar Map
1197 EditPrs<VISU::ScalarMap_i,VisuGUI_ScalarBarDlg>(myModule,aData,myAnimator);
1199 case TISOSURFACES_ITEM: //Iso Surfaces
1201 EditPrs<VISU::IsoSurfaces_i,VisuGUI_IsoSurfacesDlg>(myModule,aData,myAnimator);
1203 case TCUTPLANES_ITEM: //Cut Planes
1205 EditPrs<VISU::CutPlanes_i,VisuGUI_CutPlanesDlg>(myModule,aData,myAnimator);
1207 case TCUTLINES_ITEM: //Cut Lines
1209 EditPrs<VISU::CutLines_i,VisuGUI_CutLinesDlg>(myModule,aData,myAnimator);
1211 case TCUTSEGMENT_ITEM: //Cut Segment
1213 EditPrs<VISU::CutSegment_i,VisuGUI_CutSegmentDlg>(myModule,aData,myAnimator);
1215 case TPLOT3D_ITEM: //Plot 3D
1217 EditPrs<VISU::Plot3D_i,VisuGUI_Plot3DDlg>(myModule,aData,myAnimator);
1219 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1221 EditPrs<VISU::DeformedShape_i,VisuGUI_DeformedShapeDlg>(myModule,aData,myAnimator);
1223 case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1226 typedef VisuGUI_DeformedShapeAndScalarMapDlg DLG;
1227 typedef VISU::DeformedShapeAndScalarMap_i TYPE;
1228 DLG* aDlg = new DLG (myModule);
1229 TYPE* aPrs3d = dynamic_cast<TYPE*>(aData.myPrs[0]);
1230 aDlg->initFromPrsObject(aPrs3d, true);
1231 if (aDlg->exec() && aDlg->storeToPrsObject(aData.myPrs[0])) {
1232 for (long aFrameId = 1; aFrameId < aData.myNbFrames; aFrameId++){
1233 TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aData.myPrs[aFrameId]);
1234 //Set correct time stamp number
1235 int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1236 aDeformedPrs3d->SameAs(aPrs3d);
1237 aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1238 aDeformedPrs3d->GetScalarFieldName(),
1243 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1244 for (int aFieldId = 1; aFieldId < myAnimator->getNbFields(); aFieldId++) {
1245 FieldData& aFieldData = myAnimator->getFieldData(aFieldId);
1246 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1247 TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aFieldData.myPrs[aFrameId]);
1248 std::string aTitle = aDeformedPrs3d->GetCTitle();
1249 //Set correct time stamp number
1250 int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1251 aDeformedPrs3d->SameAs(aPrs3d);
1252 aDeformedPrs3d->SetTitle(aTitle.c_str());
1253 aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1254 aDeformedPrs3d->GetScalarFieldName(),
1264 case TVECTORS_ITEM: //Vectors
1266 EditPrs<VISU::Vectors_i,VisuGUI_VectorsDlg>(myModule,aData,myAnimator);
1268 case TSTREAMLINES_ITEM: //Stream Lines
1270 EditPrs<VISU::StreamLines_i,VisuGUI_StreamLinesDlg>(myModule,aData,myAnimator);
1272 case TGAUSSPOINTS_ITEM: //Gauss Points
1274 EditPrs<VISU::GaussPoints_i,VisuGUI_GaussPointsDlg>(myModule,aData,myAnimator);
1280 //------------------------------------------------------------------------
1281 void SetupDlg::onArrangeDlg()
1283 ArrangeDlg aDlg(this, myAnimator);
1287 //------------------------------------------------------------------------
1288 void SetupDlg::onRangeCheck (bool theCheck)
1292 myUseSequenceBox->blockSignals( true );
1293 myUseSequenceBox->setChecked( false );
1294 myUseSequenceBox->blockSignals( false );
1298 myAnimator->setAnimationRange(0, 0);
1300 myAnimator->setAnimationRange(myMinVal->text().toDouble(), myMaxVal->text().toDouble());
1302 setIsRegenerate( true );
1305 //------------------------------------------------------------------------
1306 void SetupDlg::onMinValue()
1308 double aVal = myMinVal->text().toDouble();
1309 aVal = qMax( qMin( aVal, myAnimator->getMaxRange() ), myAnimator->getMinTime() );
1310 myAnimator->setAnimationRange( aVal, myAnimator->getMaxRange() );
1311 myMinVal->setText( QString::number( aVal ) );
1312 myMinVal->setFocus();
1314 setIsRegenerate( true );
1317 //------------------------------------------------------------------------
1318 void SetupDlg::onMaxValue()
1320 double aVal = myMaxVal->text().toDouble();
1321 aVal = qMin( qMax( aVal, myAnimator->getMinRange() ), myAnimator->getMaxTime() );
1322 myAnimator->setAnimationRange( myAnimator->getMinRange(), aVal );
1323 myMaxVal->setText( QString::number( aVal ) );
1324 myMaxVal->setFocus();
1326 setIsRegenerate( true );
1329 //------------------------------------------------------------------------
1330 void SetupDlg::onMinValueEdit (const QString& theVal)
1332 double aVal = theVal.toDouble();
1333 if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())){
1334 myMinVal->setText( QString::number(myAnimator->getMinTime()) );
1335 myMinVal->setFocus();
1340 //------------------------------------------------------------------------
1341 void SetupDlg::onMaxValueEdit (const QString& theVal)
1343 double aVal = theVal.toDouble();
1344 if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())) {
1345 myMaxVal->setText( QString::number(myAnimator->getMaxTime()) );
1346 myMaxVal->setFocus();
1350 //------------------------------------------------------------------------
1351 void SetupDlg::onSequenceCheck( bool theCheck )
1355 myUseRangeBox->blockSignals( true );
1356 myUseRangeBox->setChecked( false );
1357 myUseRangeBox->blockSignals( false );
1360 QString anIndices = myIndices->text();
1361 myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1363 setIsRegenerate( true );
1366 //------------------------------------------------------------------------
1367 void SetupDlg::onIndicesChanged( const QString& theIndices )
1369 bool aCorrect = true;
1370 int aLimit = myValues->count();
1372 QList<long> anIndicesList;
1373 aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
1375 myValues->blockSignals( true );
1376 myValues->clearSelection();
1378 QList<long>::iterator indIt = anIndicesList.begin();
1379 QList<long>::iterator indItEnd = anIndicesList.end();
1380 for( int i = 0; indIt != indItEnd; ++indIt, i++ )
1382 long anIndex = *indIt;
1383 if( anIndex < 1 || anIndex > aLimit )
1386 myValues->clearSelection();
1389 myValues->item( anIndex-1 )->setSelected( true );
1392 myValues->blockSignals( false );
1394 QPalette palette = myIndices->palette();
1398 palette.setColor(myIndices->foregroundRole(), Qt::red);
1399 myIndices->setPalette(palette);
1403 palette.setColor(myIndices->foregroundRole(), Qt::black);
1404 myIndices->setPalette(palette);
1406 myAnimator->setAnimationSequence( theIndices.toLatin1().data() );
1408 setIsRegenerate( true );
1411 //------------------------------------------------------------------------
1412 void SetupDlg::onValuesChanged()
1414 int aLimit = myValues->count();
1418 for( int i = 0; i < aLimit; i++ )
1420 if( !myValues->item( i )->isSelected() )
1423 QString aString = QString::number( i+1 );
1425 bool aPrevSelected = i != 0 && myValues->item( i-1 )->isSelected();
1426 bool aNextSelected = i != aLimit - 1 && myValues->item( i+1 )->isSelected();
1442 anIndices += aString;
1445 if( anIndices.right( 1 ) == "," )
1446 anIndices.truncate( anIndices.length() - 1 );
1448 myIndices->blockSignals( true );
1450 QPalette palette = myIndices->palette();
1451 palette.setColor(myIndices->foregroundRole(), Qt::black);
1452 myIndices->setPalette(palette);
1454 myIndices->setText( anIndices );
1455 myIndices->blockSignals( false );
1457 myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1459 setIsRegenerate( true );
1462 //------------------------------------------------------------------------
1463 static const char * firstIco[] = {
1479 static const char * lastIco[] = {
1495 static const char * leftIco[] = {
1510 static const char * playIco[] = {
1529 static QPixmap MYplayPixmap(playIco);
1532 static const char * rightIco[] = {
1548 static const char * pauseIco[] = {
1567 static QPixmap MYpausePixmap(pauseIco);
1570 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule,
1571 _PTR(Study) theStudy,
1572 VISU::Animation::AnimationMode theMode) :
1573 QDialog(VISU::GetDesktop(theModule),
1574 Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
1575 myModule(theModule),
1578 setAttribute( Qt::WA_DeleteOnClose, true );
1580 if ( theMode == VISU::Animation::PARALLEL )
1581 setWindowTitle(tr("PARALLEL_ANIMATION"));
1583 setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
1584 setSizeGripEnabled( TRUE );
1586 myAnimator = new VISU_TimeAnimation (theStudy);
1587 myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
1588 connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
1589 connect(myAnimator, SIGNAL(stopped()), this, SLOT(onStop()));
1590 myAnimator->setAnimationMode(theMode);
1592 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
1593 aMainLayout->setMargin( 7 );
1594 aMainLayout->setSpacing(5);
1596 mySetupBtn = new QPushButton("Setup Animation...", this);
1597 connect( mySetupBtn, SIGNAL( clicked() ),
1598 this, SLOT( onSetupDlg() ) );
1599 aMainLayout->addWidget(mySetupBtn);
1601 myGenBtn = new QPushButton("Generate frames", this);
1602 connect( myGenBtn, SIGNAL( clicked() ),
1603 this, SLOT( createFrames() ) );
1604 aMainLayout->addWidget(myGenBtn);
1606 myPlayFrame = new QFrame(this);
1607 myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
1608 myPlayFrame->setLineWidth( 1 );
1611 // --- Play controls ---
1612 QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
1613 TopLayout->setSpacing( 6 );
1614 TopLayout->setMargin( 11 );
1616 myTimeLbl = new QLabel("0", myPlayFrame);
1617 TopLayout->addWidget(myTimeLbl, 0, 0, 1, 3, Qt::AlignHCenter);
1619 mySlider = new QSlider( myPlayFrame);
1620 mySlider->setOrientation(Qt::Horizontal);
1621 mySlider->setMinimum(0);
1622 mySlider->setMaximum(3);
1623 mySlider->setTickInterval(1);
1624 //mySlider->setTickmarks(QSlider::Below);
1625 mySlider->setTracking(false);
1626 connect( mySlider, SIGNAL( sliderMoved(int) ),
1627 this, SLOT( onWindowChanged(int) ) );
1628 TopLayout->addWidget(mySlider, 1, 0, 1, 3);
1630 myPlayBtn = new QPushButton(myPlayFrame);
1631 myPlayBtn->setIcon(MYplayPixmap);
1632 myPlayBtn->setCheckable(true);
1633 connect( myPlayBtn, SIGNAL( clicked() ),
1634 this, SLOT( onPlayPressed() ) );
1635 TopLayout->addWidget(myPlayBtn, 2, 0, 1, 2);
1637 QPushButton* aBackBtn = new QPushButton(myPlayFrame);
1638 aBackBtn->setIcon(QPixmap(leftIco));
1639 connect( aBackBtn, SIGNAL( clicked() ),
1640 this, SLOT( onBackPressed() ) );
1641 TopLayout->addWidget(aBackBtn, 3, 0);
1643 QPushButton* aForvardBtn = new QPushButton(myPlayFrame);
1644 aForvardBtn->setIcon(QPixmap(rightIco));
1645 connect( aForvardBtn, SIGNAL( clicked() ),
1646 this, SLOT( onForvardPressed() ) );
1647 TopLayout->addWidget(aForvardBtn, 3, 1);
1649 QPushButton* aFirstBtn = new QPushButton(myPlayFrame);
1650 aFirstBtn->setIcon(QPixmap(firstIco));
1651 connect( aFirstBtn, SIGNAL( clicked() ),
1652 this, SLOT( onFirstPressed() ) );
1653 TopLayout->addWidget(aFirstBtn, 4, 0);
1655 QPushButton* aLastBtn = new QPushButton(myPlayFrame);
1656 aLastBtn->setIcon(QPixmap(lastIco));
1657 connect( aLastBtn, SIGNAL( clicked() ),
1658 this, SLOT( onLastPressed() ) );
1659 TopLayout->addWidget(aLastBtn, 4, 1);
1661 QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
1662 TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
1664 QLCDNumber* aSpeedNum = new QLCDNumber( 2, myPlayFrame );
1665 aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
1666 aSpeedNum->display((int)myAnimator->getSpeed());
1667 TopLayout->addWidget(aSpeedNum, 4, 3);
1669 QwtWheel* aWheel = new QwtWheel(myPlayFrame);
1670 aWheel->setOrientation(Qt::Vertical);
1671 aWheel->setRange(1, 99, 1);
1672 aWheel->setValue((int)myAnimator->getSpeed());
1673 connect( aWheel, SIGNAL(valueChanged(double)),
1674 aSpeedNum, SLOT(display(double)) );
1675 connect( aWheel, SIGNAL(valueChanged(double)),
1676 this, SLOT(onSpeedChange(double)) );
1677 TopLayout->addWidget(aWheel, 1, 3, 3, 1, Qt::AlignRight);
1679 QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
1680 aCycleCheck->setChecked(myAnimator->isCycling());
1681 connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
1682 TopLayout->addWidget(aCycleCheck, 5, 0, 1, 4);
1684 QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
1685 aPropCheck->setChecked(myAnimator->isProportional());
1686 connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1687 TopLayout->addWidget(aPropCheck, 6, 0, 1, 4);
1689 // Pictures saving on disk
1690 QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1691 //aSaveBox->setColumnLayout(0, Qt::Horizontal );
1692 QGridLayout* aSaveLay = new QGridLayout(aSaveBox);
1693 aSaveLay->setSpacing( 5 );
1694 aSaveLay->setMargin( 5 );
1696 mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1697 connect(mySaveCheck, SIGNAL( toggled(bool)),
1698 this, SLOT( onCheckDump(bool) ));
1699 aSaveLay->addWidget(mySaveCheck, 0, 0, 1, 3);
1701 QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
1702 aFormatLbl->setEnabled(false);
1703 connect(mySaveCheck, SIGNAL( toggled(bool)),
1704 aFormatLbl, SLOT( setEnabled(bool) ));
1705 aSaveLay->addWidget(aFormatLbl, 1, 0, 1, 2);
1707 myPicsFormat = new QComboBox(aSaveBox);
1708 QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
1709 for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
1710 myPicsFormat->addItem(aDumpFormats.at(i));
1712 if (aDumpFormats.indexOf("jpeg") >= 0)
1713 myPicsFormat->setCurrentIndex(aDumpFormats.indexOf("jpeg"));
1715 myPicsFormat->setCurrentIndex(0);
1717 myPicsFormat->setEnabled(false);
1718 aSaveLay->addWidget(myPicsFormat, 1, 2);
1719 connect(mySaveCheck, SIGNAL( toggled(bool)),
1720 myPicsFormat, SLOT( setEnabled(bool) ));
1721 connect(myPicsFormat, SIGNAL( activated (int)),
1722 this, SLOT( onPicsFormatChanged()));
1724 QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1725 aPathLbl->setEnabled(false);
1726 connect(mySaveCheck, SIGNAL( toggled(bool)),
1727 aPathLbl, SLOT( setEnabled(bool) ));
1728 aSaveLay->addWidget(aPathLbl, 2, 0);
1730 myPathEdit = new QLineEdit(aSaveBox);
1731 myPathEdit->setReadOnly(true);
1732 myPathEdit->setEnabled(false);
1733 connect(mySaveCheck, SIGNAL( toggled(bool)),
1734 myPathEdit, SLOT( setEnabled(bool) ));
1735 aSaveLay->addWidget(myPathEdit, 2, 1);
1737 QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1738 aBrowseBtn->setEnabled(false);
1739 connect(mySaveCheck, SIGNAL( toggled(bool)),
1740 aBrowseBtn, SLOT( setEnabled(bool) ));
1741 connect(aBrowseBtn, SIGNAL( clicked()),
1742 this, SLOT( onBrowse() ));
1743 mySaveCheck->setChecked(false);
1744 aSaveLay->addWidget(aBrowseBtn, 2, 2);
1746 mySaveAVICheck = new QCheckBox("Save animation to AVI file", aSaveBox);
1747 connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1748 this, SLOT( onCheckDump(bool) ));
1749 aSaveLay->addWidget(mySaveAVICheck, 3, 0, 1, 3);
1751 myPathAVILbl = new QLabel("Path:", aSaveBox);
1752 myPathAVILbl->setEnabled(false);
1753 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1754 // myPathAVILbl, SLOT( setEnabled(bool) ));
1755 aSaveLay->addWidget(myPathAVILbl, 4, 0);
1757 myPathAVIEdit = new QLineEdit(aSaveBox);
1758 myPathAVIEdit->setReadOnly(true);
1759 myPathAVIEdit->setEnabled(false);
1760 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1761 // myPathAVIEdit, SLOT( setEnabled(bool) ));
1762 aSaveLay->addWidget(myPathAVIEdit, 4, 1);
1764 myBrowseAVIBtn = new QPushButton("Browse...", aSaveBox);
1765 myBrowseAVIBtn->setEnabled(false);
1766 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1767 // myBrowseAVIBtn, SLOT( setEnabled(bool) ));
1768 connect(myBrowseAVIBtn, SIGNAL( clicked()),
1769 this, SLOT( onBrowseAVI() ));
1770 aSaveLay->addWidget(myBrowseAVIBtn, 4, 2);
1772 mySaveAVICheck->setChecked(false);
1773 //mySaveAVICheck->setEnabled(myAnimator->checkAVIMaker());
1775 TopLayout->addWidget(aSaveBox, 7, 0, 1, 4);
1777 QCheckBox* aCleanMemCheck = new QCheckBox("Clean memory at each frame",myPlayFrame);
1778 aCleanMemCheck->setChecked(myAnimator->isCleaningMemoryAtEachFrame());
1779 connect(aCleanMemCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCleaningMemoryAtEachFrameSlot(bool)));
1780 TopLayout->addWidget(aCleanMemCheck, 8, 0, 1, 4);
1782 aMainLayout->addWidget(myPlayFrame);
1784 // Animation publishing in study
1785 QWidget* aPublishBox = new QWidget(this);
1786 QHBoxLayout* aPubHBLay = new QHBoxLayout( aPublishBox );
1787 aPubHBLay->setMargin( 0 );
1789 myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1790 aPubHBLay->addWidget( myPublishBtn );
1791 connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1793 mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1794 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1795 aPubHBLay->addWidget( mySaveBtn );
1796 connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1798 aMainLayout->addWidget(aPublishBox);
1801 QWidget* aBtnBox = new QWidget(this);
1802 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
1803 aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
1804 aBtnLayout->addStretch();
1806 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1807 aBtnLayout->addWidget( aCloseBtn );
1808 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1810 QPushButton* aHelpBtn = new QPushButton(tr("BUT_HELP"), aBtnBox);
1811 aBtnLayout->addWidget( aHelpBtn );
1812 connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
1814 SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1815 connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1817 connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
1818 connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
1820 aMainLayout->addWidget(aBtnBox);
1822 myPlayFrame->setEnabled(false);
1825 //------------------------------------------------------------------------
1826 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1828 if (myAnimator != NULL) {
1831 if ( VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule) )
1832 VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)->Repaint();
1836 //------------------------------------------------------------------------
1837 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1840 myPropBtn->setEnabled(index != 0);
1843 myPlayFrame->setEnabled(false);
1846 //------------------------------------------------------------------------
1847 bool VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1849 myPlayFrame->setEnabled(false);
1850 return myAnimator->addField(theSObject);
1853 //------------------------------------------------------------------------
1854 void VisuGUI_TimeAnimationDlg::createFrames()
1857 SUIT_OverrideCursor c;
1859 bool isRegenerate = mySetupDlg->isRegenerate();
1861 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1862 FieldData& aFieldData = myAnimator->getFieldData(i);
1863 if( aFieldData.myPrs.empty() )
1865 //myAnimator->generatePresentations(i);
1866 GeneratePresentations(i,myAnimator);
1871 // even if aFieldData is not empty, we must regenerate presentations,
1872 // when a range or a sequence of the animation has been changed
1875 GeneratePresentations(i,myAnimator);
1877 VISU::ColoredPrs3d_i* aPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(aFieldData.myPrs[0]);
1881 myAnimator->generatePresentations(i);
1883 aFieldData = myAnimator->getFieldData(i);
1884 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1885 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1886 std::string aTitle = aColoredPrs3d->GetCTitle();
1887 aColoredPrs3d->SameAs(aPrs3d);
1888 if ( aFrameId != 0 && myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1889 aColoredPrs3d->SetTitle(aTitle.c_str());
1896 mySetupDlg->setIsRegenerate( false );
1898 if (myAnimator->getNbFrames() == 0) {
1899 myPlayFrame->setEnabled(false);
1901 SUIT_MessageBox::warning(this,
1903 tr("MSG_NO_ANIMATIONDATA"),
1907 mySlider->setMaximum(myAnimator->getNbFrames()-1);
1908 myPlayFrame->setEnabled(true);
1909 if (!myAnimator->generateFrames()) {
1911 //myPlayFrame->setEnabled(false);
1912 SUIT_MessageBox::warning(this,
1914 myAnimator->getLastErrorMsg(),
1918 //myPlayFrame->setEnabled(true);
1921 //------------------------------------------------------------------------
1922 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1924 if (myPlayBtn->isChecked() && (!myAnimator->isRunning())) {
1925 myPlayBtn->setIcon(MYpausePixmap);
1926 if (mySaveCheck->isChecked()) {
1927 onPicsFormatChanged();
1930 } else if (mySaveAVICheck->isChecked()) {
1931 myAnimator->setDumpFormat("AVI");
1932 myAnimator->dumpTo(myPathAVIEdit->text().toLatin1().data());
1934 myAnimator->dumpTo("");
1936 mySetupBtn->setEnabled(false);
1937 myGenBtn->setEnabled(false);
1938 myAnimator->startAnimation();
1940 myPlayBtn->setIcon(MYplayPixmap);
1941 myAnimator->stopAnimation();
1942 mySetupBtn->setEnabled(true);
1943 myGenBtn->setEnabled(true);
1947 //------------------------------------------------------------------------
1948 void VisuGUI_TimeAnimationDlg::onBackPressed()
1951 myAnimator->prevFrame();
1954 //------------------------------------------------------------------------
1955 void VisuGUI_TimeAnimationDlg::onForvardPressed()
1958 myAnimator->nextFrame();
1961 //------------------------------------------------------------------------
1962 void VisuGUI_TimeAnimationDlg::onLastPressed()
1965 myAnimator->lastFrame();
1968 //------------------------------------------------------------------------
1969 void VisuGUI_TimeAnimationDlg::onFirstPressed()
1972 myAnimator->firstFrame();
1975 //------------------------------------------------------------------------
1976 void VisuGUI_TimeAnimationDlg::clearView()
1978 myAnimator->clearView();
1981 //------------------------------------------------------------------------
1982 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
1984 mySetupDlg = new SetupDlg(this,myModule, myAnimator);
1985 mySetupDlg->initialize();
1988 //------------------------------------------------------------------------
1989 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
1991 if (myAnimator != NULL) {
1992 myAnimator->stopAnimation();
1993 myAnimator->wait(500);
1994 if (myAnimator->isRunning() && (! myAnimator->isFinished())) {
1996 QCloseEvent* aNewCloseEvent = new QCloseEvent;
1997 QApplication::postEvent( this, aNewCloseEvent );
1999 QDialog::closeEvent(theEvent);
2002 QDialog::closeEvent(theEvent);
2006 //------------------------------------------------------------------------
2007 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
2009 if (myAnimator->isRunning()) return;
2010 myAnimator->gotoFrame(index);
2013 //------------------------------------------------------------------------
2014 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
2016 myAnimator->setSpeed((int)theSpeed);
2019 //------------------------------------------------------------------------
2020 void VisuGUI_TimeAnimationDlg::stopAnimation()
2022 myAnimator->stopAnimation();
2023 myPlayBtn->setChecked(false);
2024 myPlayBtn->setIcon(MYplayPixmap);
2025 mySetupBtn->setEnabled(true);
2026 myGenBtn->setEnabled(true);
2029 //------------------------------------------------------------------------
2030 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
2032 myTimeLbl->setText(QString("%1").arg(theTime));
2033 mySlider->setValue(theNewFrame);
2036 //------------------------------------------------------------------------
2037 void VisuGUI_TimeAnimationDlg::onSetupDlg()
2039 if (myAnimator->getNbFrames() > 0)
2040 myAnimator->firstFrame();
2042 myPlayFrame->setEnabled(false);
2045 //------------------------------------------------------------------------
2046 void VisuGUI_TimeAnimationDlg::onBrowse()
2048 // QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
2050 if (myPathEdit->text().isEmpty())
2051 aDir = getenv("HOME");
2053 aDir = myPathEdit->text();
2054 QString aPath = SUIT_FileDlg::getExistingDirectory(this, aDir, "Select path");
2055 if (!aPath.isEmpty())
2056 myPathEdit->setText(Qtx::addSlash(aPath));
2060 //------------------------------------------------------------------------
2061 void VisuGUI_TimeAnimationDlg::onBrowseAVI()
2063 QStringList aFilter;
2064 aFilter.append( "AVI Files (*.avi)" );
2065 aFilter.append( "All Files (*.*)" );
2068 if (myPathAVIEdit->text().isEmpty())
2069 aDir = getenv("HOME");
2071 QFileInfo aFile(myPathAVIEdit->text());
2072 aDir = aFile.absoluteDir().absolutePath();
2074 QString aPath = SUIT_FileDlg::getFileName(this, aDir, aFilter, "Select file", false);
2075 if (!aPath.isEmpty())
2076 myPathAVIEdit->setText(aPath);
2079 //------------------------------------------------------------------------
2080 void VisuGUI_TimeAnimationDlg::onCheckDump(bool)
2082 const QObject* source = sender();
2083 if (source == mySaveCheck) {
2084 if (mySaveCheck->isChecked()) {
2085 onPicsFormatChanged();
2087 if (mySaveAVICheck->isChecked())
2088 mySaveAVICheck->setChecked(false);
2090 myAnimator->dumpTo("");
2092 //mySaveAVICheck->setEnabled(!mySaveCheck->isChecked() && myAnimator->checkAVIMaker());
2093 mySaveAVICheck->setEnabled(!mySaveCheck->isChecked());
2095 else if (source == mySaveAVICheck) {
2096 if (mySaveAVICheck->isChecked()) {
2097 if (!myAnimator->checkAVIMaker()) {
2098 // AVI maker is not available
2099 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER"), tr("&OK"));
2100 mySaveAVICheck->setChecked(false);
2103 if (mySaveCheck->isChecked()) {
2104 mySaveCheck->setChecked(false);
2106 myPathAVILbl->setEnabled(true);
2107 myPathAVIEdit->setEnabled(true);
2108 myBrowseAVIBtn->setEnabled(true);
2112 // it is necessary in case of not available AVI maker,
2113 // because otherwise they will stay enabled
2114 // (??? slots, connected on SIGNAL(toggled(bool)) of mySaveAVICheck,
2115 // works in wrong order ???)
2116 myPathAVILbl->setEnabled(false);
2117 myPathAVIEdit->setEnabled(false);
2118 myBrowseAVIBtn->setEnabled(false);
2120 mySaveCheck->setEnabled(!mySaveAVICheck->isChecked());
2124 //------------------------------------------------------------------------
2125 void VisuGUI_TimeAnimationDlg::onStop()
2127 myPlayBtn->setChecked(false);
2128 myPlayBtn->setIcon(MYplayPixmap);
2129 mySetupBtn->setEnabled(true);
2130 myGenBtn->setEnabled(true);
2133 //------------------------------------------------------------------------
2134 void VisuGUI_TimeAnimationDlg::onHelp()
2136 QString aHelpFileName = "animating_page.html";
2137 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2139 app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
2143 platform = "winapplication";
2145 platform = "application";
2147 SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
2148 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
2149 arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
2150 QObject::tr("BUT_OK"));
2154 //------------------------------------------------------------------------
2155 void VisuGUI_TimeAnimationDlg::saveToStudy()
2157 myAnimator->saveAnimation();
2158 VISU::UpdateObjBrowser(myModule, true);
2161 //------------------------------------------------------------------------
2162 void VisuGUI_TimeAnimationDlg::publishToStudy()
2164 myAnimator->publishInStudy();
2165 VISU::UpdateObjBrowser(myModule, true);
2166 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2169 //------------------------------------------------------------------------
2170 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
2172 myAnimator->restoreFromStudy(theAnimation);
2173 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2174 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
2175 setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
2178 //------------------------------------------------------------------------
2179 void VisuGUI_TimeAnimationDlg::onPicsFormatChanged()
2181 QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
2182 if (aDumpFormats.count() < 1) {
2183 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_SUPPORTED_IMAGE_FORMATS"), tr("&OK"));
2186 if (myPicsFormat->currentIndex() < 0 || aDumpFormats.count() <= myPicsFormat->currentIndex()) {
2187 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_INVALID_IMAGE_FORMAT_INDEX"), tr("&OK"));
2190 myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentIndex()));
2193 //------------------------------------------------------------------------
2194 void VisuGUI_TimeAnimationDlg::onPathChanged()
2196 myAnimator->dumpTo(myPathEdit->text().toLatin1().data());
2199 //------------------------------------------------------------------------
2200 void VisuGUI_TimeAnimationDlg::keyPressEvent( QKeyEvent* e )
2202 QDialog::keyPressEvent( e );
2203 if ( e->isAccepted() )
2206 if ( e->key() == Qt::Key_F1 )