1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : VisuGUI_TimeAnimation.cxx
21 // Author : Vitaly SMETANNIKOV
24 #include "VisuGUI_TimeAnimation.h"
27 #include "VisuGUI_Tools.h"
28 #include "VisuGUI_ViewTools.h"
29 #include "VisuGUI_ScalarBarDlg.h"
30 #include "VisuGUI_DeformedShapeDlg.h"
31 #include "VisuGUI_CutPlanesDlg.h"
32 #include "VisuGUI_CutLinesDlg.h"
33 #include "VisuGUI_Plot3DDlg.h"
34 #include "VisuGUI_VectorsDlg.h"
35 #include "VisuGUI_IsoSurfacesDlg.h"
36 #include "VisuGUI_StreamLinesDlg.h"
37 #include "VisuGUI_ScalarMapOnDeformedShapeDlg.h"
38 #include "VisuGUI_GaussPointsDlg.h"
40 #include "VISU_TimeAnimation.h"
42 #include "VISU_ScalarMap_i.hh"
43 #include "VISU_IsoSurfaces_i.hh"
44 #include "VISU_DeformedShape_i.hh"
45 #include "VISU_CutPlanes_i.hh"
46 #include "VISU_Plot3D_i.hh"
47 #include "VISU_CutLines_i.hh"
48 #include "VISU_Vectors_i.hh"
49 #include "VISU_StreamLines_i.hh"
50 #include "VISU_ScalarMapOnDeformedShape_i.hh"
51 #include "VISU_GaussPoints_i.hh"
53 #include "VISU_ViewManager_i.hh"
55 #include "VISU_ScalarBarActor.hxx"
56 #include "VISU_Actor.h"
58 #include "SalomeApp_Study.h"
59 #include "LightApp_Application.h"
61 #include "SVTK_ViewWindow.h"
63 #include "SUIT_OverrideCursor.h"
64 #include "SUIT_MessageBox.h"
65 #include "SUIT_ResourceMgr.h"
66 #include "SUIT_Session.h"
67 #include "SUIT_Desktop.h"
68 #include "SUIT_FileDlg.h"
70 #include <vtkRenderer.h>
71 #include <vtkMapper.h>
80 #include <qlineedit.h>
81 #include <qwt_wheel.h>
82 #include <qlcdnumber.h>
83 #include <qhgroupbox.h>
84 #include <qvgroupbox.h>
85 #include <qtoolbutton.h>
89 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
90 : QDialog(theParent, "ArrangeDlg", true,
91 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
92 myAnimator(theAnimator),
93 myViewWindow(theAnimator->getViewer())
97 QStringList aFieldNames;
98 // Find names of fields
99 for (int i = 0; i < myAnimator->getNbFields(); i++) {
100 _PTR(SObject) aSObject = myAnimator->getFieldData(i).myField;
101 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
102 aFieldNames.append(aRestoringMap["myName"]);
104 aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
105 aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
106 aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
107 myOffsets.append(aOffs);
109 myFieldLst->insertStringList(aFieldNames);
110 myFieldLst->setSelected(0, true);
113 ArrangeDlg::ArrangeDlg(QWidget* theParent,
114 const SalomeApp_Module* theModule,
115 SVTK_ViewWindow* theViewWindow)
116 : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize |
117 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
119 myViewWindow(theViewWindow)
123 QStringList aPrsNames;
124 vtkActorCollection *aCollection = myViewWindow->getRenderer()->GetActors();
125 aCollection->InitTraversal();
126 while(vtkActor* anActor = aCollection->GetNextActor()){
127 if (VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor))
128 if(anVISUActor->GetVisibility() != 0){
129 if (VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d()){
130 if(!myPrsMap.contains(aPrs)){
131 Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
132 if(!anIO->hasEntry())
134 SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
135 VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
136 if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
137 _PTR(GenericAttribute) anAttr;
138 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
139 _PTR(AttributeName) aName(anAttr);
140 QString strIn(aName->Value().c_str());
141 aPrsNames.append(strIn);
142 myPrsMap[aPrs] = myOffsets.count();
144 anVISUActor->GetPosition(aOffs.myOffset);
145 myOffsets.append(aOffs);
152 myFieldLst->insertStringList(aPrsNames);
153 myFieldLst->setSelected(0, true);
156 void ArrangeDlg::init()
158 setCaption("Arrange Presentations");
159 setSizeGripEnabled( TRUE );
161 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
162 aMainLayout->setSpacing(5);
164 QButtonGroup* aBtnGrp = new QButtonGroup(2, Qt::Horizontal, this);
165 aBtnGrp->setExclusive(true);
166 aMainLayout->addWidget(aBtnGrp);
168 QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGrp);
169 aBtnGrp->insert(aAutoBtn, AutoMode);
171 QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGrp);
172 aBtnGrp->insert(aManualBtn, ManualMode);
173 aBtnGrp->setButton(AutoMode);
175 myStackWgt = new QWidgetStack(this);
176 aMainLayout->addWidget(myStackWgt);
179 QVBox* aAutoPane = new QVBox(myStackWgt);
180 aAutoPane->setSpacing(5);
182 myAxisGrp = new QButtonGroup(3, Qt::Horizontal,"Axis", aAutoPane);
184 QRadioButton* aXBtn = new QRadioButton("X",myAxisGrp );
185 myAxisGrp->insert(aXBtn, XAxis);
187 QRadioButton* aYBtn = new QRadioButton("Y",myAxisGrp );
188 myAxisGrp->insert(aYBtn, YAxis);
190 QRadioButton* aZBtn = new QRadioButton("Z",myAxisGrp );
191 myAxisGrp->insert(aZBtn, ZAxis);
193 myAxisGrp->setButton(XAxis);
196 QHBox* aDistPane = new QHBox(aAutoPane);
197 aDistPane->setSpacing(5);
198 new QLabel("Relative Distance", aDistPane);
199 myDistVal = new QtxDblSpinBox (-10,10, 0.5, aDistPane);
200 myDistVal->setValue(1);
202 myStackWgt->addWidget(aAutoPane, AutoMode);
205 QHBox* aManualPane = new QHBox(myStackWgt);
206 aManualPane->setSpacing(10);
208 myFieldLst = new QListBox(aManualPane);
209 connect( myFieldLst, SIGNAL( highlighted(int) ),
210 this, SLOT( onFieldChange(int) ) );
212 QGrid* aCoordPane = new QGrid(2, aManualPane);
213 aCoordPane->setSpacing(5);
215 new QLabel("X", aCoordPane);
216 myCoord[0] = new QtxDblSpinBox(aCoordPane);
217 myCoord[0]->setRange(-MAXVAL, MAXVAL);
219 new QLabel("Y", aCoordPane);
220 myCoord[1] = new QtxDblSpinBox(aCoordPane);
221 myCoord[1]->setRange(-MAXVAL, MAXVAL);
223 new QLabel("Z", aCoordPane);
224 myCoord[2] = new QtxDblSpinBox(aCoordPane);
225 myCoord[2]->setRange(-MAXVAL, MAXVAL);
227 myStackWgt->addWidget(aManualPane, ManualMode);
229 myStackWgt->raiseWidget(AutoMode);
231 connect(aBtnGrp, SIGNAL(clicked(int)), myStackWgt, SLOT(raiseWidget(int)) );
233 SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
234 SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
235 _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
236 if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
237 mySaveChk = new QCheckBox ("Save to presentation", this);
238 mySaveChk->setChecked(false);
239 aMainLayout->addWidget(mySaveChk);
244 // Common buttons ===========================================================
245 QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
246 GroupButtons->setColumnLayout(0, Qt::Vertical );
247 GroupButtons->layout()->setSpacing( 0 );
248 GroupButtons->layout()->setMargin( 0 );
249 QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
250 GroupButtonsLayout->setAlignment( Qt::AlignTop );
251 GroupButtonsLayout->setSpacing( 6 );
252 GroupButtonsLayout->setMargin( 11 );
254 QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons, "buttonOk" );
255 buttonOk->setAutoDefault( TRUE );
256 buttonOk->setDefault( TRUE );
257 GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
258 GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
260 QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons, "buttonCancel" );
261 buttonCancel->setAutoDefault( TRUE );
262 GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
264 aMainLayout->addWidget( GroupButtons );
266 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
267 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
270 void ArrangeDlg::accept()
272 if (myAnimator != NULL) {
280 void ArrangeDlg::onFieldChange(int theCurrent)
282 if (myCurrent != theCurrent) {
283 Offset& aOffs = myOffsets[myCurrent];
284 aOffs.myOffset[0] = myCoord[0]->value();
285 aOffs.myOffset[1] = myCoord[1]->value();
286 aOffs.myOffset[2] = myCoord[2]->value();
288 myCurrent = theCurrent;
289 const Offset& aNewOffs = myOffsets[myCurrent];
290 myCoord[0]->setValue(aNewOffs.myOffset[0]);
291 myCoord[1]->setValue(aNewOffs.myOffset[1]);
292 myCoord[2]->setValue(aNewOffs.myOffset[2]);
295 void ArrangeDlg::acceptAnimation()
297 if (getMode() == ManualMode) {
299 Offset& aOffs = myOffsets[myCurrent];
300 aOffs.myOffset[0] = myCoord[0]->value();
301 aOffs.myOffset[1] = myCoord[1]->value();
302 aOffs.myOffset[2] = myCoord[2]->value();
304 for (int i = 0; i < myAnimator->getNbFields(); i++) {
305 Offset aOffs = myOffsets[i];
306 myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
307 myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
308 myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
311 QApplication::setOverrideCursor( Qt::waitCursor );
312 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
313 if (aData.myPrs.empty())
314 myAnimator->generatePresentations(myFieldLst->currentItem());
315 vtkFloatingPointType aBounds[6];
316 aData.myPrs[0]->GetBounds(aBounds);
317 vtkFloatingPointType aDist = 0;
318 int aAxis = getAxis();
321 aDist = fabs(aBounds[1] - aBounds[0]);
324 aDist = fabs(aBounds[3] - aBounds[2]);
327 aDist = fabs(aBounds[5] - aBounds[4]);
330 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
331 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
332 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
333 vtkFloatingPointType max = (dx > dy) ? dx : dy;
334 max = (dz > max) ? dz : max;
338 // set base distance between centers of bounding boxes
339 // to minimal (but big enough) size of current bounding box
340 if (dx < max) dx = FLT_MAX;
341 if (dy < max) dy = FLT_MAX;
342 if (dz < max) dz = FLT_MAX;
344 aDist = (dx < dy) ? dx : dy;
345 aDist = (dz < aDist) ? dz : aDist;
347 aDist = aDist * getDistance();
348 for (int i = 0; i < myAnimator->getNbFields(); i++) {
349 myAnimator->getFieldData(i).myOffset[0] = 0;
350 myAnimator->getFieldData(i).myOffset[1] = 0;
351 myAnimator->getFieldData(i).myOffset[2] = 0;
352 myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
355 QApplication::restoreOverrideCursor();
359 void ArrangeDlg::acceptViewWindow()
361 if (getMode() == ManualMode) {
363 Offset& aOffs = myOffsets[myCurrent];
364 aOffs.myOffset[0] = myCoord[0]->value();
365 aOffs.myOffset[1] = myCoord[1]->value();
366 aOffs.myOffset[2] = myCoord[2]->value();
368 QMap<VISU::Prs3d_i*, int>::Iterator it;
369 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
370 VISU::Prs3d_i* aPrs = it.key();
371 Offset& aOffs = myOffsets[it.data()];
372 if (VISU_Actor* anActor = VISU::FindActor(myViewWindow, aPrs))
373 anActor->SetPosition(aOffs.myOffset);
375 if (mySaveChk->isChecked())
376 aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
379 vtkFloatingPointType aDist = 0;
380 vtkFloatingPointType aShift = 0;
381 vtkFloatingPointType aPrevDist = 0;
382 vtkFloatingPointType aPrevShift = 0;
384 QMap<VISU::Prs3d_i*, int>::Iterator it;
385 for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
386 VISU::Prs3d_i* aPrs = it.key();
387 if (VISU_Actor* aActor = VISU::FindActor(myViewWindow, aPrs)) {
388 int aAxis = getAxis();
390 vtkFloatingPointType aZeroOffset[3];
391 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
392 aActor->SetPosition(aZeroOffset);
393 aActor->GetMapper()->Update();
395 vtkFloatingPointType aBounds[6];
396 aActor->GetBounds(aBounds);
399 aDist = fabs(aBounds[1] - aBounds[0]);
402 aDist = fabs(aBounds[3] - aBounds[2]);
405 aDist = fabs(aBounds[5] - aBounds[4]);
407 vtkFloatingPointType aOffset[3];
408 aOffset[0] = aOffset[1] = aOffset[2] = 0;
410 (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
413 vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
415 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
416 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
417 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
418 vtkFloatingPointType max = (dx > dy) ? dx : dy;
419 max = (dz > max) ? dz : max;
423 // set base distance between centers of bounding boxes
424 // to minimal (but big enough) size of current bounding box
425 if (dx < max) dx = FLT_MAX;
426 if (dy < max) dy = FLT_MAX;
427 if (dz < max) dz = FLT_MAX;
429 aCCDist = (dx < dy) ? dx : dy;
430 aCCDist = (dz < aCCDist) ? dz : aCCDist;
433 //-------------------------------->
437 // .--------------. .------.
438 //----------->| | | |
439 // aPrevShift '--------------' '------'
444 // (aDist + aPrevDist) * getDistance() / 2
446 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
449 aOffset[aAxis] += aShift;
450 aActor->SetPosition(aOffset);
452 if (mySaveChk->isChecked())
453 aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
460 myViewWindow->getRenderer()->ResetCameraClippingRange();
461 myViewWindow->Repaint();
465 //------------------------------------------------------------------------
466 //------------------------------------------------------------------------
467 //------------------------------------------------------------------------
468 SetupDlg::SetupDlg (QWidget* theParent,
470 VISU_TimeAnimation* theAnimator) :
474 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
475 myAnimator(theAnimator),
477 myIsRegenerate( false )
479 setCaption("Setup Animation");
480 setSizeGripEnabled( TRUE );
482 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
483 aMainLayout->setSpacing(5);
485 // Range of time stamps
486 myUseRangeBox = new QHGroupBox("Use range of time stamps", this);
487 myUseRangeBox->setCheckable( true );
488 myUseRangeBox->setChecked(myAnimator->isRangeDefined());
490 double aMaxTime = myAnimator->getMaxTime();
491 double aMinTime = myAnimator->getMinTime();
493 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
494 aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
495 else { // successive animation mode
496 std::pair<int,long> aLastFieldFrame(myAnimator->getNbFields() - 1,
497 myAnimator->getFieldData(myAnimator->getNbFields() - 1).myNbTimes - 1);
498 aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
501 QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
502 myMinVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
503 if (myUseRangeBox->isChecked())
504 myMinVal->setValue( myAnimator->getMinRange() );
506 myMinVal->setValue( aMinTime );
508 connect(myMinVal, SIGNAL( valueChanged(double)),
509 this, SLOT( onMinValue(double) ));
511 QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
512 myMaxVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
513 if (myUseRangeBox->isChecked())
514 myMaxVal->setValue( myAnimator->getMaxRange() );
516 myMaxVal->setValue( aMaxTime );
518 connect(myMaxVal, SIGNAL( valueChanged(double)),
519 this, SLOT( onMaxValue(double) ));
521 connect(myUseRangeBox, SIGNAL( toggled(bool)),
522 this, SLOT( onRangeCheck(bool) ));
524 aMainLayout->addWidget(myUseRangeBox);
527 // Sequence of time stamps
528 myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
529 myUseSequenceBox->setCheckable( true );
530 myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
532 myUseSequenceBox->setColumnLayout(0, Qt::Vertical);
533 myUseSequenceBox->layout()->setSpacing( 0 );
534 myUseSequenceBox->layout()->setMargin( 0 );
535 QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox->layout() );
536 aUseSequenceLayout->setAlignment( Qt::AlignTop );
537 aUseSequenceLayout->setSpacing( 6 );
538 aUseSequenceLayout->setMargin( 11 );
540 QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
541 myIndices = new QLineEdit( myUseSequenceBox );
543 myValues = new QListBox( myUseSequenceBox );
544 myValues->setSelectionMode( QListBox::Extended );
546 connect(myIndices, SIGNAL( textChanged(const QString&)),
547 this, SLOT( onIndicesChanged(const QString&) ));
549 connect(myValues, SIGNAL( selectionChanged() ),
550 this, SLOT( onValuesChanged() ) );
552 connect(myUseSequenceBox, SIGNAL( toggled(bool)),
553 this, SLOT( onSequenceCheck(bool) ));
555 aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
556 aUseSequenceLayout->addWidget( myIndices, 0, 1 );
557 aUseSequenceLayout->addMultiCellWidget( myValues, 1, 1, 0, 1 );
559 aMainLayout->addWidget(myUseSequenceBox);
562 // Fields and Properties
563 QHBox* aPropFrame = new QHBox(this);
564 aPropFrame->setSpacing(5);
566 QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
567 myFieldLst = new QListBox(aNamesBox);
568 QStringList aFieldNames;
569 // Find names of fields
570 for (int i = 0; i < myAnimator->getNbFields(); i++) {
571 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
572 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
573 QString aFieldName(aRestoringMap["myName"]);
574 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
575 aFieldNames.append(aFieldName);
576 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
577 _PTR(SObject) aSObject = aSO->GetFather()->GetFather()->GetFather();
578 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
579 QString aFileName(aRestoringMap["myInitFileName"]);
580 aFileName = aFileName.right(aFileName.length() - (aFileName.findRev("/") + 1));
581 aFieldNames.append(aFileName + QString(" : ") + aFieldName);
584 myFieldLst->insertStringList(aFieldNames);
586 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
587 myFieldLst->setSelected(0, true);
588 connect( myFieldLst, SIGNAL( highlighted(int) ),
589 this, SLOT( onFieldChange(int) ) );
591 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
592 myFieldLst->setSelectionMode(QListBox::NoSelection);
594 QVBox* aSetupBox = new QVBox(aPropFrame);
595 aSetupBox->setSpacing(5);
597 QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
598 //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
599 myTypeCombo = new QComboBox(aPropBox);
600 connect( myTypeCombo, SIGNAL( activated(int) ),
601 this, SLOT( onTypeChanged(int) ) );
603 // QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
604 //connect( aBarBtn, SIGNAL( clicked() ),
605 // this, SLOT( onScalarBarDlg() ) );
607 myPropBtn = new QPushButton("Properties...", aPropBox);
608 // myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
609 connect( myPropBtn, SIGNAL( clicked() ),
610 this, SLOT( onPreferencesDlg() ) );
612 if (myAnimator->getNbFields() > 1 ) {
613 if( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
614 myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
615 connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
619 aMainLayout->addWidget(aPropFrame);
621 QHBox* aBtnBox = new QHBox(this);
622 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
623 aBtnLayout->addStretch();
625 QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
626 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
628 aMainLayout->addWidget(aBtnBox);
631 //------------------------------------------------------------------------
632 void SetupDlg::initialize()
636 _PTR(Study) aStudy = myAnimator->getStudy();
638 FieldData& aData = myAnimator->getFieldData( 0 );
639 _PTR(SObject) aField = aData.myField;
641 _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
642 anIter->Next(); // First is reference on support
643 for(int index = 1; anIter->More(); anIter->Next(), index++)
645 QString aPrefix( "[" );
646 aPrefix += QString::number( index );
649 double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
650 myValues->insertItem( aPrefix + QString::number( aTime ) );
653 QString anIndices( myAnimator->getAnimationSequence() );
654 myIndices->setText( anIndices );
657 //------------------------------------------------------------------------
659 TSCALARMAP_ITEM = 0, // VISU::TSCALARMAP
660 TISOSURFACES_ITEM = 1, // VISU::TISOSURFACES
661 TCUTPLANES_ITEM = 2, // VISU::TCUTPLANES
662 TCUTLINES_ITEM = 3, // VISU::TCUTLINES
663 TPLOT3D_ITEM = 4, // VISU::TPLOT3D
664 TDEFORMEDSHAPE_ITEM = 5, // VISU::TDEFORMEDSHAPE
665 TVECTORS_ITEM = 6, // VISU::TVECTORS
666 TSTREAMLINES_ITEM = 7, // VISU::TSTREAMLINES
667 TGAUSSPOINTS_ITEM = 8, // VISU::TGAUSSPOINTS
668 TSCALARMAPONDEFORMEDSHAPE_ITEM = 9 // VISU::TSCALARMAPONDEFORMEDSHAPE
671 //------------------------------------------------------------------------
672 void SetupDlg::onClose()
674 if( !myUseRangeBox->isChecked() )
675 myAnimator->setAnimationRange( 0, 0 );
677 if( !myUseSequenceBox->isChecked() )
678 myAnimator->setAnimationSequence( 0 );
683 //------------------------------------------------------------------------
684 void SetupDlg::onFieldChange (int theIndex)
686 myTypeCombo->clear();
687 myTypeId2ComboId.clear();
688 myComboId2TypeId.clear();
690 // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
691 myTypeCombo->insertItem("Scalar Map"); // item 0
692 myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
693 myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
695 myTypeCombo->insertItem("Iso Surfaces"); // item 1
696 myTypeId2ComboId[TISOSURFACES_ITEM] = myComboId2TypeId.size();
697 myComboId2TypeId.push_back(TISOSURFACES_ITEM);;
699 myTypeCombo->insertItem("Cut Planes"); // item 2
700 myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
701 myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
703 myTypeCombo->insertItem("Cut Lines"); // item 3
704 myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
705 myComboId2TypeId.push_back(TCUTLINES_ITEM);;
707 myTypeCombo->insertItem("Plot 3D"); // item 4
708 myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
709 myComboId2TypeId.push_back(TPLOT3D_ITEM);;
711 bool anEnableItems = false;
712 bool anEnableGP = false;
713 VISU::VISUType aPrsType;
714 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) { // parallel animation mode
716 FieldData& aData = myAnimator->getFieldData(theIndex);
717 _PTR(SObject) aSObject = aData.myField;
718 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
719 long aNumComp = aRestoringMap["myNumComponent"].toLong();
720 anEnableItems = (aNumComp > 1);
722 long anEntityId = aRestoringMap["myEntityId"].toLong();
723 anEnableGP = (anEntityId == VISU::CELL);
725 aPrsType = aData.myPrsType;
728 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) { // successive animation mode
730 for (int i = 0; i < myAnimator->getNbFields(); i++) {
731 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
732 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
733 long aNumComp = aRestoringMap["myNumComponent"].toLong();
734 anEnableItems = (aNumComp > 1);
736 long anEntityId = aRestoringMap["myEntityId"].toLong();
737 anEnableGP = (anEntityId == VISU::CELL);
739 if ( !anEnableItems && !anEnableGP ) break;
742 aPrsType = myAnimator->getFieldData(0).myPrsType;
747 myTypeCombo->insertItem("Deformed Shape"); // item 5
748 myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
749 myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
751 myTypeCombo->insertItem("Vectors"); // item 6
752 myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
753 myComboId2TypeId.push_back(TVECTORS_ITEM);;
755 myTypeCombo->insertItem("Stream Lines"); // item 7
756 myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
757 myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
759 myTypeCombo->insertItem("Scalar map on Deformed shape"); // item 9
760 myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
761 myComboId2TypeId.push_back(TSCALARMAPONDEFORMEDSHAPE_ITEM);;
765 myTypeCombo->insertItem("Gauss Points"); // item 8
766 myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
767 myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
771 case VISU::TSCALARMAP: //Scalar Map
772 myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAP_ITEM]);
774 case VISU::TISOSURFACES: //Iso Surfaces
775 myTypeCombo->setCurrentItem(myTypeId2ComboId[TISOSURFACES_ITEM]);
777 case VISU::TCUTPLANES: //Cut Planes
778 myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTPLANES_ITEM]);
780 case VISU::TCUTLINES: //Cut Lines
781 myTypeCombo->setCurrentItem(myTypeId2ComboId[TCUTLINES_ITEM]);
783 case VISU::TPLOT3D: //Plot 3D
784 myTypeCombo->setCurrentItem(myTypeId2ComboId[TPLOT3D_ITEM]);
786 case VISU::TDEFORMEDSHAPE: //Deformed Shape
787 myTypeCombo->setCurrentItem(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
789 case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
790 myTypeCombo->setCurrentItem(myTypeId2ComboId[TSCALARMAPONDEFORMEDSHAPE_ITEM]);
792 case VISU::TVECTORS: //Vectors
793 myTypeCombo->setCurrentItem(myTypeId2ComboId[TVECTORS_ITEM]);
795 case VISU::TSTREAMLINES: //Stream Lines
796 myTypeCombo->setCurrentItem(myTypeId2ComboId[TSTREAMLINES_ITEM]);
798 case VISU::TGAUSSPOINTS: //Gauss Points
799 myTypeCombo->setCurrentItem(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
802 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
805 //------------------------------------------------------------------------
806 void SetupDlg::onTypeChanged (int theIndex)
808 int aType = myComboId2TypeId[theIndex];
810 for (int i = 0; i < myAnimator->getNbFields(); i++) {
811 FieldData& aData = ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ?
812 myAnimator->getFieldData(myFieldLst->currentItem()) :
813 myAnimator->getFieldData(i);
816 case TSCALARMAP_ITEM: //Scalar Map
817 aData.myPrsType = VISU::TSCALARMAP;
819 case TISOSURFACES_ITEM: //Iso Surfaces
820 aData.myPrsType = VISU::TISOSURFACES;
822 case TCUTPLANES_ITEM: //Cut Planes
823 aData.myPrsType = VISU::TCUTPLANES;
825 case TCUTLINES_ITEM: //Cut Lines
826 aData.myPrsType = VISU::TCUTLINES;
828 case TPLOT3D_ITEM: //Plot 3D
829 aData.myPrsType = VISU::TPLOT3D;
831 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
832 aData.myPrsType = VISU::TDEFORMEDSHAPE;
834 case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
835 aData.myPrsType = VISU::TSCALARMAPONDEFORMEDSHAPE;
837 case TVECTORS_ITEM: //Vectors
838 aData.myPrsType = VISU::TVECTORS;
840 case TSTREAMLINES_ITEM: //Stream Lines
841 aData.myPrsType = VISU::TSTREAMLINES;
843 case TGAUSSPOINTS_ITEM: //Gauss Points
844 aData.myPrsType = VISU::TGAUSSPOINTS;
847 myAnimator->clearData(aData);
849 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) // parallel animation mode
852 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
853 //myAnimator->generatePresentations(myFieldLst->currentItem());
857 //------------------------------------------------------------------------
860 template<class TPrs3d, class TDialog>
862 EditPrs(VisuGUI* theModule,
864 VISU_TimeAnimation* theAnimator)
866 TDialog* aDlg = new TDialog(theModule);
867 TPrs3d* aPrs3d = dynamic_cast<TPrs3d*>(theData.myPrs[0]);
868 aDlg->initFromPrsObject(aPrs3d, true);
869 if (aDlg->exec() && aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(aPrs3d))) {
871 for (long aFrameId = 1; aFrameId < theData.myNbFrames; aFrameId++){
872 VISU::ColoredPrs3d_i* aColoredPrs3d = theData.myPrs[aFrameId];
873 aColoredPrs3d->SameAs(aPrs3d);
876 if ( theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
877 for (int aFieldId = 1; aFieldId < theAnimator->getNbFields(); aFieldId++) {
878 FieldData& aFieldData = theAnimator->getFieldData(aFieldId);
879 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
880 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
881 std::string aTitle = aColoredPrs3d->GetCTitle();
882 aColoredPrs3d->SameAs(aPrs3d);
883 aColoredPrs3d->SetTitle(aTitle.c_str());
893 void SetupDlg::onPreferencesDlg()
895 SUIT_OverrideCursor c;
897 VISU::Animation::AnimationMode aMode = myAnimator->getAnimationMode();
898 int aRefFieldId = ( aMode == VISU::Animation::PARALLEL ) ? myFieldLst->currentItem() : 0;
899 FieldData& aData = myAnimator->getFieldData(aRefFieldId);
900 if (aData.myPrs.empty())
901 myAnimator->generatePresentations(aRefFieldId);
903 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
904 for (int i = 0; i < myAnimator->getNbFields(); i++) {
905 if ( i != aRefFieldId && myAnimator->getFieldData(i).myPrs.empty() )
906 myAnimator->generatePresentations(i);
910 if(!aData.myNbFrames || !aData.myPrs[0]){
911 QApplication::restoreOverrideCursor();
912 SUIT_MessageBox::warn1(this,
914 VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
919 int aType = myComboId2TypeId[myTypeCombo->currentItem()];
921 case TSCALARMAP_ITEM: //Scalar Map
923 EditPrs<VISU::ScalarMap_i, VisuGUI_ScalarBarDlg>(myModule, aData, myAnimator);
925 case TISOSURFACES_ITEM: //Iso Surfaces
927 EditPrs<VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg>(myModule, aData, myAnimator);
929 case TCUTPLANES_ITEM: //Cut Planes
931 EditPrs<VISU::CutPlanes_i, VisuGUI_CutPlanesDlg>(myModule, aData, myAnimator);
933 case TCUTLINES_ITEM: //Cut Lines
935 EditPrs<VISU::CutLines_i, VisuGUI_CutLinesDlg>(myModule, aData, myAnimator);
937 case TPLOT3D_ITEM: //Plot 3D
939 EditPrs<VISU::Plot3D_i, VisuGUI_Plot3DDlg>(myModule, aData, myAnimator);
941 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
943 EditPrs<VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg>(myModule, aData, myAnimator);
945 case TSCALARMAPONDEFORMEDSHAPE_ITEM: //Scalar Map on Deformed Shape
948 typedef VisuGUI_ScalarMapOnDeformedShapeDlg DLG;
949 typedef VISU::ScalarMapOnDeformedShape_i TYPE;
950 DLG* aDlg = new DLG (myModule);
951 TYPE* aPrs3d = dynamic_cast<TYPE*>(aData.myPrs[0]);
952 aDlg->initFromPrsObject(aPrs3d, true);
953 if (aDlg->exec() && aDlg->storeToPrsObject(aData.myPrs[0])) {
954 for (int i = 1; i < aData.myNbFrames; i++){
955 aData.myPrs[i]->SameAs(aData.myPrs[0]);
961 case TVECTORS_ITEM: //Vectors
963 EditPrs<VISU::Vectors_i, VisuGUI_VectorsDlg>(myModule, aData, myAnimator);
965 case TSTREAMLINES_ITEM: //Stream Lines
967 EditPrs<VISU::StreamLines_i, VisuGUI_StreamLinesDlg>(myModule, aData, myAnimator);
969 case TGAUSSPOINTS_ITEM: //Gauss Points
971 EditPrs<VISU::GaussPoints_i, VisuGUI_GaussPointsDlg>(myModule, aData, myAnimator);
977 //------------------------------------------------------------------------
978 void SetupDlg::onArrangeDlg()
980 ArrangeDlg aDlg(this, myAnimator);
984 //------------------------------------------------------------------------
985 void SetupDlg::onRangeCheck (bool theCheck)
989 myUseSequenceBox->blockSignals( true );
990 myUseSequenceBox->setChecked( false );
991 myUseSequenceBox->blockSignals( false );
995 myAnimator->setAnimationRange(0, 0);
997 myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
999 setIsRegenerate( true );
1002 //------------------------------------------------------------------------
1003 void SetupDlg::onMinValue (double theVal)
1005 if (theVal > myAnimator->getMaxRange()) {
1006 myMinVal->setValue( myAnimator->getMinTime() );
1007 myMinVal->setFocus();
1010 myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
1012 setIsRegenerate( true );
1015 //------------------------------------------------------------------------
1016 void SetupDlg::onMaxValue (double theVal)
1018 if (theVal < myAnimator->getMinRange()) {
1019 myMaxVal->setValue( myAnimator->getMaxTime() );
1020 myMaxVal->setFocus();
1023 myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
1025 setIsRegenerate( true );
1028 //------------------------------------------------------------------------
1029 void SetupDlg::onSequenceCheck( bool theCheck )
1033 myUseRangeBox->blockSignals( true );
1034 myUseRangeBox->setChecked( false );
1035 myUseRangeBox->blockSignals( false );
1038 QString anIndices = myIndices->text();
1039 myAnimator->setAnimationSequence( anIndices.latin1() );
1041 setIsRegenerate( true );
1044 //------------------------------------------------------------------------
1045 void SetupDlg::onIndicesChanged( const QString& theIndices )
1047 bool aCorrect = true;
1048 int aLimit = myValues->count();
1050 QValueList<long> anIndicesList;
1051 aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
1053 myValues->blockSignals( true );
1054 myValues->clearSelection();
1056 QValueList<long>::iterator indIt = anIndicesList.begin();
1057 QValueList<long>::iterator indItEnd = anIndicesList.end();
1058 for( int i = 0; indIt != indItEnd; ++indIt, i++ )
1060 long anIndex = *indIt;
1061 if( anIndex < 1 || anIndex > aLimit )
1064 myValues->clearSelection();
1067 myValues->setSelected( anIndex-1, true );
1070 myValues->blockSignals( false );
1074 myIndices->setPaletteForegroundColor( Qt::red );
1078 myIndices->setPaletteForegroundColor( Qt::black );
1080 myAnimator->setAnimationSequence( theIndices.latin1() );
1082 setIsRegenerate( true );
1085 //------------------------------------------------------------------------
1086 void SetupDlg::onValuesChanged()
1088 int aLimit = myValues->count();
1092 for( int i = 0; i < aLimit; i++ )
1094 if( !myValues->isSelected( i ) )
1097 QString aString = QString::number( i+1 );
1099 bool aPrevSelected = i != 0 && myValues->isSelected( i-1 );
1100 bool aNextSelected = i != aLimit - 1 && myValues->isSelected( i+1 );
1116 anIndices += aString;
1119 if( anIndices.right( 1 ) == "," )
1120 anIndices.truncate( anIndices.length() - 1 );
1122 myIndices->blockSignals( true );
1123 myIndices->setPaletteForegroundColor( Qt::black );
1124 myIndices->setText( anIndices );
1125 myIndices->blockSignals( false );
1127 myAnimator->setAnimationSequence( anIndices.latin1() );
1129 setIsRegenerate( true );
1132 //------------------------------------------------------------------------
1133 static const char * firstIco[] = {
1149 static const char * lastIco[] = {
1165 static const char * leftIco[] = {
1180 static const char * playIco[] = {
1199 static QPixmap MYplayPixmap(playIco);
1202 static const char * rightIco[] = {
1218 static const char * pauseIco[] = {
1237 static QPixmap MYpausePixmap(pauseIco);
1240 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule,
1241 _PTR(Study) theStudy,
1242 VISU::Animation::AnimationMode theMode) :
1243 QDialog(VISU::GetDesktop(theModule),
1244 "VisuGUI_TimeAnimationDlg",
1246 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
1247 myModule(theModule),
1250 if ( theMode == VISU::Animation::PARALLEL )
1251 setCaption(tr("PARALLEL_ANIMATION"));
1253 setCaption(tr("SUCCESSIVE_ANIMATION"));
1254 setSizeGripEnabled( TRUE );
1256 myAnimator = new VISU_TimeAnimation (theStudy);
1257 myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
1258 connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
1259 connect(myAnimator, SIGNAL(stopped()), this, SLOT(onStop()));
1260 myAnimator->setAnimationMode(theMode);
1262 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
1263 aMainLayout->setSpacing(5);
1265 mySetupBtn = new QPushButton("Setup Animation...", this);
1266 connect( mySetupBtn, SIGNAL( clicked() ),
1267 this, SLOT( onSetupDlg() ) );
1268 aMainLayout->addWidget(mySetupBtn);
1270 myGenBtn = new QPushButton("Generate frames", this);
1271 connect( myGenBtn, SIGNAL( clicked() ),
1272 this, SLOT( createFrames() ) );
1273 aMainLayout->addWidget(myGenBtn);
1275 myPlayFrame = new QFrame(this);
1276 myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
1277 myPlayFrame->setLineWidth( 1 );
1280 // --- Play controls ---
1281 QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
1282 TopLayout->setSpacing( 6 );
1283 TopLayout->setMargin( 11 );
1285 myTimeLbl = new QLabel("0", myPlayFrame);
1286 TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
1288 mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
1289 mySlider->setMinValue(0);
1290 mySlider->setMaxValue(3);
1291 mySlider->setTickInterval(1);
1292 //mySlider->setTickmarks(QSlider::Below);
1293 mySlider->setTracking(false);
1294 connect( mySlider, SIGNAL( valueChanged(int) ),
1295 this, SLOT( onWindowChanged(int) ) );
1296 TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
1298 myPlayBtn = new QToolButton(myPlayFrame);
1299 myPlayBtn->setIconSet(MYplayPixmap);
1300 myPlayBtn->setToggleButton(true);
1301 connect( myPlayBtn, SIGNAL( clicked() ),
1302 this, SLOT( onPlayPressed() ) );
1303 TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
1305 QToolButton* aBackBtn = new QToolButton(myPlayFrame);
1306 aBackBtn->setIconSet(QPixmap(leftIco));
1307 connect( aBackBtn, SIGNAL( clicked() ),
1308 this, SLOT( onBackPressed() ) );
1309 TopLayout->addWidget(aBackBtn, 3, 0);
1311 QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
1312 aForvardBtn->setIconSet(QPixmap(rightIco));
1313 connect( aForvardBtn, SIGNAL( clicked() ),
1314 this, SLOT( onForvardPressed() ) );
1315 TopLayout->addWidget(aForvardBtn, 3, 1);
1317 QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
1318 aFirstBtn->setIconSet(QPixmap(firstIco));
1319 connect( aFirstBtn, SIGNAL( clicked() ),
1320 this, SLOT( onFirstPressed() ) );
1321 TopLayout->addWidget(aFirstBtn, 4, 0);
1323 QToolButton* aLastBtn = new QToolButton(myPlayFrame);
1324 aLastBtn->setIconSet(QPixmap(lastIco));
1325 connect( aLastBtn, SIGNAL( clicked() ),
1326 this, SLOT( onLastPressed() ) );
1327 TopLayout->addWidget(aLastBtn, 4, 1);
1329 QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
1330 TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
1332 QLCDNumber* aSpeedNum = new QLCDNumber( 2, myPlayFrame );
1333 aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
1334 aSpeedNum->display((int)myAnimator->getSpeed());
1335 TopLayout->addWidget(aSpeedNum, 4, 3);
1337 QwtWheel* aWheel = new QwtWheel(myPlayFrame);
1338 aWheel->setOrientation(Qt::Vertical);
1339 aWheel->setRange(1, 99, 1);
1340 aWheel->setValue((int)myAnimator->getSpeed());
1341 connect( aWheel, SIGNAL(valueChanged(double)),
1342 aSpeedNum, SLOT(display(double)) );
1343 connect( aWheel, SIGNAL(valueChanged(double)),
1344 this, SLOT(onSpeedChange(double)) );
1345 TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
1347 QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
1348 aCycleCheck->setChecked(myAnimator->isCycling());
1349 connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
1350 TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
1352 QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
1353 aPropCheck->setChecked(myAnimator->isProportional());
1354 connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1355 TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
1357 // Pictures saving on disk
1358 QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1359 aSaveBox->setColumnLayout(0, Qt::Horizontal );
1360 QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
1361 aSaveLay->setSpacing( 5 );
1362 aSaveLay->setMargin( 5 );
1364 mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1365 connect(mySaveCheck, SIGNAL( toggled(bool)),
1366 this, SLOT( onCheckDump(bool) ));
1367 aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
1369 QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
1370 aFormatLbl->setEnabled(false);
1371 connect(mySaveCheck, SIGNAL( toggled(bool)),
1372 aFormatLbl, SLOT( setEnabled(bool) ));
1373 aSaveLay->addMultiCellWidget(aFormatLbl, 1, 1, 0, 1);
1375 myPicsFormat = new QComboBox(aSaveBox);
1376 QStrList aDumpFormats = QImageIO::outputFormats();
1377 for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
1378 myPicsFormat->insertItem(aDumpFormats.at(i));
1380 if (aDumpFormats.find("JPEG"))
1381 myPicsFormat->setCurrentItem(aDumpFormats.find("JPEG"));
1383 myPicsFormat->setCurrentItem(0);
1384 myPicsFormat->setEnabled(false);
1385 aSaveLay->addWidget(myPicsFormat, 1, 2);
1386 connect(mySaveCheck, SIGNAL( toggled(bool)),
1387 myPicsFormat, SLOT( setEnabled(bool) ));
1388 connect(myPicsFormat, SIGNAL( activated (int)),
1389 this, SLOT( onPicsFormatChanged()));
1391 QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1392 aPathLbl->setEnabled(false);
1393 connect(mySaveCheck, SIGNAL( toggled(bool)),
1394 aPathLbl, SLOT( setEnabled(bool) ));
1395 aSaveLay->addWidget(aPathLbl, 2, 0);
1397 myPathEdit = new QLineEdit(aSaveBox);
1398 myPathEdit->setReadOnly(true);
1399 myPathEdit->setEnabled(false);
1400 connect(mySaveCheck, SIGNAL( toggled(bool)),
1401 myPathEdit, SLOT( setEnabled(bool) ));
1402 aSaveLay->addWidget(myPathEdit, 2, 1);
1404 QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1405 aBrowseBtn->setEnabled(false);
1406 connect(mySaveCheck, SIGNAL( toggled(bool)),
1407 aBrowseBtn, SLOT( setEnabled(bool) ));
1408 connect(aBrowseBtn, SIGNAL( clicked()),
1409 this, SLOT( onBrowse() ));
1410 mySaveCheck->setChecked(false);
1411 aSaveLay->addWidget(aBrowseBtn, 2, 2);
1413 mySaveAVICheck = new QCheckBox("Save animation to AVI file", aSaveBox);
1414 connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1415 this, SLOT( onCheckDump(bool) ));
1416 aSaveLay->addMultiCellWidget(mySaveAVICheck, 3, 3, 0, 2);
1418 myPathAVILbl = new QLabel("Path:", aSaveBox);
1419 myPathAVILbl->setEnabled(false);
1420 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1421 // myPathAVILbl, SLOT( setEnabled(bool) ));
1422 aSaveLay->addWidget(myPathAVILbl, 4, 0);
1424 myPathAVIEdit = new QLineEdit(aSaveBox);
1425 myPathAVIEdit->setReadOnly(true);
1426 myPathAVIEdit->setEnabled(false);
1427 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1428 // myPathAVIEdit, SLOT( setEnabled(bool) ));
1429 aSaveLay->addWidget(myPathAVIEdit, 4, 1);
1431 myBrowseAVIBtn = new QPushButton("Browse...", aSaveBox);
1432 myBrowseAVIBtn->setEnabled(false);
1433 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1434 // myBrowseAVIBtn, SLOT( setEnabled(bool) ));
1435 connect(myBrowseAVIBtn, SIGNAL( clicked()),
1436 this, SLOT( onBrowseAVI() ));
1437 aSaveLay->addWidget(myBrowseAVIBtn, 4, 2);
1439 mySaveAVICheck->setChecked(false);
1440 //mySaveAVICheck->setEnabled(myAnimator->checkAVIMaker());
1442 TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
1444 QCheckBox* aCleanMemCheck = new QCheckBox("Clean memory at each frame",myPlayFrame);
1445 aCleanMemCheck->setChecked(myAnimator->isCleaningMemoryAtEachFrame());
1446 connect(aCleanMemCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCleaningMemoryAtEachFrameSlot(bool)));
1447 TopLayout->addMultiCellWidget(aCleanMemCheck, 8, 8, 0, 3);
1449 aMainLayout->addWidget(myPlayFrame);
1451 // Animation publishing in study
1452 QHBox* aPublishBox = new QHBox(this);
1453 aPublishBox->setSpacing(5);
1455 myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1456 connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1458 mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1459 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1460 connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1462 aMainLayout->addWidget(aPublishBox);
1465 QHBox* aBtnBox = new QHBox(this);
1466 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
1467 aBtnLayout->addStretch();
1469 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1470 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1472 QPushButton* aHelpBtn = new QPushButton(tr("BUT_HELP"), aBtnBox);
1473 connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
1475 SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1476 connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1478 connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
1479 connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
1481 aMainLayout->addWidget(aBtnBox);
1483 myPlayFrame->setEnabled(false);
1486 //------------------------------------------------------------------------
1487 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1489 if (myAnimator != NULL) {
1492 if ( VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule) )
1493 VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)->Repaint();
1497 //------------------------------------------------------------------------
1498 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1501 myPropBtn->setEnabled(index != 0);
1504 myPlayFrame->setEnabled(false);
1507 //------------------------------------------------------------------------
1508 bool VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1510 myPlayFrame->setEnabled(false);
1511 return myAnimator->addField(theSObject);
1514 //------------------------------------------------------------------------
1515 void VisuGUI_TimeAnimationDlg::createFrames()
1518 SUIT_OverrideCursor c;
1520 bool isRegenerate = mySetupDlg->isRegenerate();
1522 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1523 FieldData& aFieldData = myAnimator->getFieldData(i);
1524 if( aFieldData.myPrs.empty() )
1526 myAnimator->generatePresentations(i);
1531 // even if aFieldData is not empty, we must regenerate presentations,
1532 // when a range or a sequence of the animation has been changed
1535 VISU::ColoredPrs3d_i* aPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(aFieldData.myPrs[0]);
1539 myAnimator->generatePresentations(i);
1541 aFieldData = myAnimator->getFieldData(i);
1542 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1543 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1544 std::string aTitle = aColoredPrs3d->GetCTitle();
1545 aColoredPrs3d->SameAs(aPrs3d);
1546 if ( aFrameId != 0 && myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1547 aColoredPrs3d->SetTitle(aTitle.c_str());
1553 mySetupDlg->setIsRegenerate( false );
1555 if (myAnimator->getNbFrames() == 0) {
1556 myPlayFrame->setEnabled(false);
1558 SUIT_MessageBox::warn1(this,
1560 tr("MSG_NO_ANIMATIONDATA"),
1564 mySlider->setMaxValue(myAnimator->getNbFrames()-1);
1565 myPlayFrame->setEnabled(true);
1566 if (!myAnimator->generateFrames()) {
1568 //myPlayFrame->setEnabled(false);
1569 SUIT_MessageBox::warn1(this,
1571 myAnimator->getLastErrorMsg(),
1575 //myPlayFrame->setEnabled(true);
1578 //------------------------------------------------------------------------
1579 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1581 if (myPlayBtn->isOn() && (!myAnimator->running())) {
1582 myPlayBtn->setIconSet(MYpausePixmap);
1583 if (mySaveCheck->isChecked()) {
1584 onPicsFormatChanged();
1587 } else if (mySaveAVICheck->isChecked()) {
1588 myAnimator->setDumpFormat("AVI");
1589 myAnimator->dumpTo(myPathAVIEdit->text());
1591 myAnimator->dumpTo("");
1593 mySetupBtn->setEnabled(false);
1594 myGenBtn->setEnabled(false);
1595 myAnimator->startAnimation();
1597 myPlayBtn->setIconSet(MYplayPixmap);
1598 myAnimator->stopAnimation();
1599 mySetupBtn->setEnabled(true);
1600 myGenBtn->setEnabled(true);
1604 //------------------------------------------------------------------------
1605 void VisuGUI_TimeAnimationDlg::onBackPressed()
1608 myAnimator->prevFrame();
1611 //------------------------------------------------------------------------
1612 void VisuGUI_TimeAnimationDlg::onForvardPressed()
1614 myAnimator->nextFrame();
1617 //------------------------------------------------------------------------
1618 void VisuGUI_TimeAnimationDlg::onLastPressed()
1620 myAnimator->lastFrame();
1623 //------------------------------------------------------------------------
1624 void VisuGUI_TimeAnimationDlg::onFirstPressed()
1626 myAnimator->firstFrame();
1629 //------------------------------------------------------------------------
1630 void VisuGUI_TimeAnimationDlg::clearView()
1632 myAnimator->clearView();
1635 //------------------------------------------------------------------------
1636 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
1638 mySetupDlg = new SetupDlg(this,myModule, myAnimator);
1639 mySetupDlg->initialize();
1642 //------------------------------------------------------------------------
1643 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
1645 if (myAnimator != NULL) {
1646 myAnimator->stopAnimation();
1647 myAnimator->wait(500);
1648 if (myAnimator->running() && (! myAnimator->finished())) {
1650 QCloseEvent* aNewCloseEvent = new QCloseEvent;
1651 QApplication::postEvent( this, aNewCloseEvent );
1653 QDialog::closeEvent(theEvent);
1656 QDialog::closeEvent(theEvent);
1660 //------------------------------------------------------------------------
1661 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
1663 if (myAnimator->isRunning()) return;
1664 myAnimator->gotoFrame(index);
1667 //------------------------------------------------------------------------
1668 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
1670 myAnimator->setSpeed((int)theSpeed);
1673 //------------------------------------------------------------------------
1674 void VisuGUI_TimeAnimationDlg::stopAnimation()
1676 myAnimator->stopAnimation();
1677 myPlayBtn->setOn(false);
1678 myPlayBtn->setIconSet(MYplayPixmap);
1679 mySetupBtn->setEnabled(true);
1680 myGenBtn->setEnabled(true);
1683 //------------------------------------------------------------------------
1684 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
1686 myTimeLbl->setText(QString("%1").arg(theTime));
1687 mySlider->setValue(theNewFrame);
1690 //------------------------------------------------------------------------
1691 void VisuGUI_TimeAnimationDlg::onSetupDlg()
1693 if (myAnimator->getNbFrames() > 0)
1694 myAnimator->firstFrame();
1696 myPlayFrame->setEnabled(false);
1699 //------------------------------------------------------------------------
1700 void VisuGUI_TimeAnimationDlg::onBrowse()
1702 // QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
1704 if (myPathEdit->text().isEmpty())
1705 aDir = getenv("HOME");
1707 aDir = myPathEdit->text();
1708 QString aPath = SUIT_FileDlg::getExistingDirectory(this, aDir, "Select path");
1709 if (!aPath.isEmpty())
1710 myPathEdit->setText(Qtx::addSlash(aPath));
1714 //------------------------------------------------------------------------
1715 void VisuGUI_TimeAnimationDlg::onBrowseAVI()
1717 QStringList aFilter;
1718 aFilter.append( "AVI Files (*.avi)" );
1719 aFilter.append( "All Files (*.*)" );
1722 if (myPathAVIEdit->text().isEmpty())
1723 aDir = getenv("HOME");
1725 QFileInfo aFile(myPathAVIEdit->text());
1726 aDir = aFile.dirPath(true);
1728 QString aPath = SUIT_FileDlg::getFileName(this, aDir, aFilter, "Select file", false);
1729 if (!aPath.isEmpty())
1730 myPathAVIEdit->setText(aPath);
1733 //------------------------------------------------------------------------
1734 void VisuGUI_TimeAnimationDlg::onCheckDump(bool)
1736 const QObject* source = sender();
1737 if (source == mySaveCheck) {
1738 if (mySaveCheck->isChecked()) {
1739 onPicsFormatChanged();
1741 if (mySaveAVICheck->isChecked())
1742 mySaveAVICheck->setChecked(false);
1744 myAnimator->dumpTo("");
1746 //mySaveAVICheck->setEnabled(!mySaveCheck->isChecked() && myAnimator->checkAVIMaker());
1747 mySaveAVICheck->setEnabled(!mySaveCheck->isChecked());
1749 else if (source == mySaveAVICheck) {
1750 if (mySaveAVICheck->isChecked()) {
1751 if (!myAnimator->checkAVIMaker()) {
1752 // AVI maker is not available
1753 SUIT_MessageBox::warn1(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER"), tr("&OK"));
1754 mySaveAVICheck->setChecked(false);
1757 if (mySaveCheck->isChecked()) {
1758 mySaveCheck->setChecked(false);
1760 myPathAVILbl->setEnabled(true);
1761 myPathAVIEdit->setEnabled(true);
1762 myBrowseAVIBtn->setEnabled(true);
1766 // it is necessary in case of not available AVI maker,
1767 // because otherwise they will stay enabled
1768 // (??? slots, connected on SIGNAL(toggled(bool)) of mySaveAVICheck,
1769 // works in wrong order ???)
1770 myPathAVILbl->setEnabled(false);
1771 myPathAVIEdit->setEnabled(false);
1772 myBrowseAVIBtn->setEnabled(false);
1774 mySaveCheck->setEnabled(!mySaveAVICheck->isChecked());
1778 //------------------------------------------------------------------------
1779 void VisuGUI_TimeAnimationDlg::onStop()
1781 myPlayBtn->setOn(false);
1782 myPlayBtn->setIconSet(MYplayPixmap);
1783 mySetupBtn->setEnabled(true);
1784 myGenBtn->setEnabled(true);
1787 //------------------------------------------------------------------------
1788 void VisuGUI_TimeAnimationDlg::onHelp()
1790 QString aHelpFileName = "animating_page.html";
1791 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1793 app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
1797 platform = "winapplication";
1799 platform = "application";
1801 SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
1802 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1803 arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
1804 QObject::tr("BUT_OK"));
1808 //------------------------------------------------------------------------
1809 void VisuGUI_TimeAnimationDlg::saveToStudy()
1811 myAnimator->saveAnimation();
1812 VISU::UpdateObjBrowser(myModule, true);
1815 //------------------------------------------------------------------------
1816 void VisuGUI_TimeAnimationDlg::publishToStudy()
1818 myAnimator->publishInStudy();
1819 VISU::UpdateObjBrowser(myModule, true);
1820 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1823 //------------------------------------------------------------------------
1824 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
1826 myAnimator->restoreFromStudy(theAnimation);
1827 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1828 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
1829 setCaption(tr("SUCCESSIVE_ANIMATION"));
1832 //------------------------------------------------------------------------
1833 void VisuGUI_TimeAnimationDlg::onPicsFormatChanged()
1835 QStrList aDumpFormats = QImageIO::outputFormats();
1836 myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentItem()));
1839 //------------------------------------------------------------------------
1840 void VisuGUI_TimeAnimationDlg::onPathChanged()
1842 myAnimator->dumpTo(myPathEdit->text());
1845 //------------------------------------------------------------------------
1846 void VisuGUI_TimeAnimationDlg::keyPressEvent( QKeyEvent* e )
1848 QDialog::keyPressEvent( e );
1849 if ( e->isAccepted() )
1852 if ( e->key() == Key_F1 )