1 // File : VisuGUI_TimeAnimation.cxx
2 // Created : 28 / 03 / 2003
3 // Author : Vitaly SMETANNIKOV
6 // Copyright : Open CASCADE
9 #include "VisuGUI_TimeAnimation.h"
14 #include <qhgroupbox.h>
15 #include <qmessagebox.h>
16 #include <qwt_wheel.h>
17 #include <qlcdnumber.h>
19 #include <qvgroupbox.h>
22 #include "QAD_Application.h"
23 #include "QAD_Desktop.h"
24 #include "QAD_FileDlg.h"
26 #include "VTKViewer_ViewFrame.h"
27 #include "VISU_ScalarBarActor.hxx"
29 #include "VisuGUI_MagnitudeDlg.h"
30 #include "VisuGUI_CutPlanesDlg.h"
31 #include "VisuGUI_VectorsDlg.h"
32 #include "VisuGUI_IsoSurfacesDlg.h"
33 #include "VisuGUI_StreamLinesDlg.h"
34 #include "VISU_TimeAnimation.h"
36 static double MAXVALUE = 1.0E+300;
40 SetupDlg::SetupDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
41 : QDialog( theParent, "SetupDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
43 setCaption("Setup Animation");
44 setSizeGripEnabled( TRUE );
45 myAnimator = theAnimator;
47 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
48 aMainLayout->setSpacing(5);
51 QFrame* aRangeGrp = new QFrame(this);
52 QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
53 aRangeLayout->setSpacing( 6 );
54 aRangeLayout->setMargin( 11 );
55 aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
57 myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
58 aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
59 myUseRangeChk->setChecked(myAnimator->isRangeDefined());
61 QLabel* aMinLbl = new QLabel("From", aRangeGrp);
62 aMinLbl->setEnabled(myUseRangeChk->isChecked());
63 aRangeLayout->addWidget(aMinLbl, 1, 0);
64 myMinVal = new QAD_SpinBoxDbl(aRangeGrp, -MAXVALUE, MAXVALUE, 0.1 );
65 myMinVal->setEnabled(myUseRangeChk->isChecked());
66 myMinVal->setValue( 0 );
67 connect(myMinVal, SIGNAL( valueChanged(double)),
68 this, SLOT( onMinValue(double) ));
69 aRangeLayout->addWidget(myMinVal, 1, 1);
71 QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
72 aMaxLbl->setEnabled(myUseRangeChk->isChecked());
73 aRangeLayout->addWidget(aMaxLbl, 1, 2);
74 myMaxVal = new QAD_SpinBoxDbl(aRangeGrp, -MAXVALUE, MAXVALUE, 0.1 );
75 myMaxVal->setEnabled(myUseRangeChk->isChecked());
76 myMaxVal->setValue( 0 );
77 connect(myMaxVal, SIGNAL( valueChanged(double)),
78 this, SLOT( onMaxValue(double) ));
79 aRangeLayout->addWidget(myMaxVal, 1, 3);
81 connect(myUseRangeChk, SIGNAL( toggled(bool)),
82 aMinLbl, SLOT( setEnabled(bool) ));
83 connect(myUseRangeChk, SIGNAL( toggled(bool)),
84 aMaxLbl, SLOT( setEnabled(bool) ));
85 connect(myUseRangeChk, SIGNAL( toggled(bool)),
86 this, SLOT( onRangeCheck(bool) ));
88 aMainLayout->addWidget(aRangeGrp);
91 QHBox* aPropFrame = new QHBox(this);
92 aPropFrame->setSpacing(5);
94 QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
95 myFieldLst = new QListBox(aNamesBox);
96 QStringList aFieldNames;
97 // Find names of fields
98 for (int i = 0; i < theAnimator->getNbFields(); i++) {
99 aFieldNames.append(VisuGUI::getValue(theAnimator->getFieldData(i).myField, "myName"));
101 myFieldLst->insertStringList(aFieldNames);
102 myFieldLst->setSelected(0, true);
103 connect( myFieldLst, SIGNAL( highlighted(int) ),
104 this, SLOT( onFieldChange(int) ) );
107 QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
108 myTypeCombo = new QComboBox(aPropBox);
109 connect( myTypeCombo, SIGNAL( activated(int) ),
110 this, SLOT( onTypeChanged(int) ) );
112 QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
113 connect( aBarBtn, SIGNAL( clicked() ),
114 this, SLOT( onScalarBarDlg() ) );
116 myPropBtn = new QPushButton("Properties...", aPropBox);
117 myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
118 connect( myPropBtn, SIGNAL( clicked() ),
119 this, SLOT( onPreferencesDlg() ) );
122 aMainLayout->addWidget(aPropFrame);
124 QHBox* aBtnBox = new QHBox(this);
125 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
126 aBtnLayout->addStretch();
128 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
129 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
131 aMainLayout->addWidget(aBtnBox);
135 //************************************************************************
136 void SetupDlg::onFieldChange(int theIndex) {
137 FieldData& aData = myAnimator->getFieldData(theIndex);
138 myTypeCombo->clear();
139 myTypeCombo->insertItem("Scalar Map");
140 myTypeCombo->insertItem("Iso Surfaces");
141 myTypeCombo->insertItem("Cut Planes");
143 SALOMEDS::SObject_var aSObject = aData.myField;
144 long aNumComp = VisuGUI::getValue(aSObject, "myNumComponent").toLong();
146 myTypeCombo->insertItem("Deformed Shape");
147 myTypeCombo->insertItem("Vectors");
148 myTypeCombo->insertItem("Stream Lines");
150 switch (aData.myPrsType) {
151 case VISU::TSCALARMAP: //Scalar Map
152 myTypeCombo->setCurrentItem(0);
154 case VISU::TISOSURFACE: //Iso Surfaces
155 myTypeCombo->setCurrentItem(1);
157 case VISU::TCUTPLANES: //Cut Planes
158 myTypeCombo->setCurrentItem(2);
160 case VISU::TDEFORMEDSHAPE: //Deformed Shape
161 myTypeCombo->setCurrentItem(3);
163 case VISU::TVECTORS: //Vectors
164 myTypeCombo->setCurrentItem(4);
166 case VISU::TSTREAMLINES: //Stream Lines
167 myTypeCombo->setCurrentItem(5);
168 aData.myPrsType = VISU::TSTREAMLINES;
171 myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
174 //************************************************************************
175 void SetupDlg::onTypeChanged(int theIndex) {
176 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
179 aData.myPrsType = VISU::TSCALARMAP;
181 case 1: //Iso Surfaces
182 aData.myPrsType = VISU::TISOSURFACE;
185 aData.myPrsType = VISU::TCUTPLANES;
187 case 3: //Deformed Shape
188 aData.myPrsType = VISU::TDEFORMEDSHAPE;
191 aData.myPrsType = VISU::TVECTORS;
193 case 5: //Stream Lines
194 aData.myPrsType = VISU::TSTREAMLINES;
197 myAnimator->clearData(aData);
198 myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
199 //myAnimator->generatePresentations(myFieldLst->currentItem());
203 //************************************************************************
204 void SetupDlg::onScalarBarDlg() {
205 QApplication::setOverrideCursor( Qt::waitCursor );
206 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
207 if (aData.myPrs == 0)
208 myAnimator->generatePresentations(myFieldLst->currentItem());
209 QApplication::restoreOverrideCursor();
211 VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
212 aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
213 if (aScalarBarDlg->exec()) {
214 for (int i = 0; i < aData.myNbTimes; i++)
215 aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
219 //************************************************************************
220 void SetupDlg::onPreferencesDlg() {
221 QApplication::setOverrideCursor( Qt::waitCursor );
222 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
223 if (aData.myPrs == 0)
224 myAnimator->generatePresentations(myFieldLst->currentItem());
225 QApplication::restoreOverrideCursor();
227 switch (myTypeCombo->currentItem()) {
228 case 1: //Iso Surfaces
230 VisuGUI_IsoSurfacesDlg* aDlg = new VisuGUI_IsoSurfacesDlg();
231 aDlg->initFromPrsObject(dynamic_cast<VISU::IsoSurfaces_i*>(aData.myPrs[0]));
233 for (int i = 0; i < aData.myNbTimes; i++)
234 aDlg->storeToPrsObject(dynamic_cast<VISU::IsoSurfaces_i*>(aData.myPrs[i]));
240 VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg();
241 aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
243 for (int i = 0; i < aData.myNbTimes; i++)
244 aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
248 case 3: //Deformed Shape
250 VisuGUI_MagnitudeDlg* aDlg = new VisuGUI_MagnitudeDlg();
251 aDlg->initFromPrsObject(dynamic_cast<VISU::DeformedShape_i*>(aData.myPrs[0]));
253 for (int i = 0; i < aData.myNbTimes; i++)
254 aDlg->storeToPrsObject(dynamic_cast<VISU::DeformedShape_i*>(aData.myPrs[i]));
260 VisuGUI_VectorsDlg* aDlg = new VisuGUI_VectorsDlg();
261 aDlg->initFromPrsObject(dynamic_cast<VISU::Vectors_i*>(aData.myPrs[0]));
263 for (int i = 0; i < aData.myNbTimes; i++)
264 aDlg->storeToPrsObject(dynamic_cast<VISU::Vectors_i*>(aData.myPrs[i]));
268 case 5: //Stream Lines
270 VisuGUI_StreamLinesDlg* aDlg = new VisuGUI_StreamLinesDlg();
271 aDlg->initFromPrsObject(dynamic_cast<VISU::StreamLines_i*>(aData.myPrs[0]));
273 for (int i = 0; i < aData.myNbTimes; i++)
274 aDlg->storeToPrsObject(dynamic_cast<VISU::StreamLines_i*>(aData.myPrs[i]));
281 //************************************************************************
282 void SetupDlg::onRangeCheck(bool theCheck) {
283 for (int i = 0; i < myAnimator->getNbFields(); i++)
284 myAnimator->clearData(myAnimator->getFieldData(i));
286 myMinVal->setEnabled(theCheck);
287 myMaxVal->setEnabled(theCheck);
290 myAnimator->setAnimationRange(0, 0);
293 //************************************************************************
294 void SetupDlg::onMinValue(double theVal) {
295 for (int i = 0; i < myAnimator->getNbFields(); i++)
296 myAnimator->clearData(myAnimator->getFieldData(i));
297 myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
300 //************************************************************************
301 void SetupDlg::onMaxValue(double theVal) {
302 for (int i = 0; i < myAnimator->getNbFields(); i++)
303 myAnimator->clearData(myAnimator->getFieldData(i));
304 myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
308 static const char * firstIco[] = {
324 static const char * lastIco[] = {
340 static const char * leftIco[] = {
355 static const char * playIco[] = {
374 static QPixmap MYplayPixmap(playIco);
378 static const char * rightIco[] = {
394 static const char * pauseIco[] = {
413 static QPixmap MYpausePixmap(pauseIco);
416 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg(SALOMEDS::Study_var theStudy)
417 : QDialog( QAD_Application::getDesktop(), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
419 setCaption("Animation");
420 setSizeGripEnabled( TRUE );
423 myAnimator = new VISU_TimeAnimation(theStudy);
424 myAnimator->setSpeed(1);
425 myAnimator->setViewer(VisuGUI::GetVtkViewFrame());
426 connect( myAnimator, SIGNAL( frameChanged(long, double) ),
427 this, SLOT( onExecution(long, double) ) );
429 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
430 aMainLayout->setSpacing(5);
432 QPushButton* aSetupBtn = new QPushButton("Setup Animation...", this);
433 connect( aSetupBtn, SIGNAL( clicked() ),
434 this, SLOT( onSetupDlg() ) );
435 aMainLayout->addWidget(aSetupBtn);
437 QPushButton* aGenBtn = new QPushButton("Generate frames", this);
438 connect( aGenBtn, SIGNAL( clicked() ),
439 this, SLOT( createFrames() ) );
440 aMainLayout->addWidget(aGenBtn);
442 myPlayFrame = new QFrame(this);
443 myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
444 myPlayFrame->setLineWidth( 1 );
447 // --- Play controls ---
448 QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
449 TopLayout->setSpacing( 6 );
450 TopLayout->setMargin( 11 );
452 myTimeLbl = new QLabel("0", myPlayFrame);
453 TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
455 mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
456 mySlider->setMinValue(0);
457 mySlider->setMaxValue(3);
458 mySlider->setTickInterval(1);
459 //mySlider->setTickmarks(QSlider::Below);
460 mySlider->setTracking(false);
461 connect( mySlider, SIGNAL( valueChanged(int) ),
462 this, SLOT( onFrameChanged(int) ) );
463 TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
465 myPlayBtn = new QToolButton(myPlayFrame);
466 myPlayBtn->setIconSet(MYplayPixmap);
467 myPlayBtn->setToggleButton(true);
468 connect( myPlayBtn, SIGNAL( clicked() ),
469 this, SLOT( onPlayPressed() ) );
470 TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
472 QToolButton* aBackBtn = new QToolButton(myPlayFrame);
473 aBackBtn->setIconSet(QPixmap(leftIco));
474 connect( aBackBtn, SIGNAL( clicked() ),
475 this, SLOT( onBackPressed() ) );
476 TopLayout->addWidget(aBackBtn, 3, 0);
478 QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
479 aForvardBtn->setIconSet(QPixmap(rightIco));
480 connect( aForvardBtn, SIGNAL( clicked() ),
481 this, SLOT( onForvardPressed() ) );
482 TopLayout->addWidget(aForvardBtn, 3, 1);
484 QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
485 aFirstBtn->setIconSet(QPixmap(firstIco));
486 connect( aFirstBtn, SIGNAL( clicked() ),
487 this, SLOT( onFirstPressed() ) );
488 TopLayout->addWidget(aFirstBtn, 4, 0);
490 QToolButton* aLastBtn = new QToolButton(myPlayFrame);
491 aLastBtn->setIconSet(QPixmap(lastIco));
492 connect( aLastBtn, SIGNAL( clicked() ),
493 this, SLOT( onLastPressed() ) );
494 TopLayout->addWidget(aLastBtn, 4, 1);
496 QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
497 TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
499 QLCDNumber* aSpeedNum = new QLCDNumber( 2, myPlayFrame );
500 aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
501 aSpeedNum->display(1);
502 TopLayout->addWidget(aSpeedNum, 4, 3);
504 QwtWheel* aWheel = new QwtWheel(myPlayFrame);
505 aWheel->setOrientation(Qt::Vertical);
506 aWheel->setRange(1, 99, 1);
507 connect( aWheel, SIGNAL(valueChanged(double)),
508 aSpeedNum, SLOT(display(double)) );
509 connect( aWheel, SIGNAL(valueChanged(double)),
510 this, SLOT(onSpeedChange(double)) );
511 TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
513 QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
514 aPropCheck->setChecked(myAnimator->isProportional());
515 connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportional(bool)));
516 TopLayout->addMultiCellWidget(aPropCheck, 5, 5, 0, 3);
518 mySaveCheck = new QCheckBox("Save pictures to directory",myPlayFrame);
519 mySaveCheck->setChecked(false);
520 TopLayout->addMultiCellWidget(mySaveCheck, 6, 6, 0, 3);
522 QLabel* aPathLbl = new QLabel("Path:", myPlayFrame);
523 aPathLbl->setEnabled(false);
524 connect(mySaveCheck, SIGNAL( toggled(bool)),
525 aPathLbl, SLOT( setEnabled(bool) ));
526 TopLayout->addWidget(aPathLbl, 7, 0);
528 myPathEdit = new QLineEdit(myPlayFrame);
529 connect(mySaveCheck, SIGNAL( toggled(bool)),
530 myPathEdit, SLOT( setEnabled(bool) ));
531 TopLayout->addMultiCellWidget(myPathEdit, 7, 7, 1, 2);
533 QPushButton* aBrowseBtn = new QPushButton("Browse...", myPlayFrame);
534 connect(mySaveCheck, SIGNAL( toggled(bool)),
535 aBrowseBtn, SLOT( setEnabled(bool) ));
536 connect(aBrowseBtn, SIGNAL( clicked()),
537 this, SLOT( onBrowse() ));
538 TopLayout->addWidget(aBrowseBtn, 7, 3);
540 aMainLayout->addWidget(myPlayFrame);
542 QHBox* aBtnBox = new QHBox(this);
543 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
544 aBtnLayout->addStretch();
546 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
547 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
549 aMainLayout->addWidget(aBtnBox);
551 myPlayFrame->setEnabled(false);
555 //************************************************************************
556 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg() {
557 VTKViewer_ViewFrame* aView = myAnimator->getViewer();
563 //************************************************************************
564 void VisuGUI_TimeAnimationDlg::onTypeChange(int index) {
566 myPropBtn->setEnabled(index != 0);
569 myPlayFrame->setEnabled(false);
573 //************************************************************************
574 void VisuGUI_TimeAnimationDlg::addField(SALOMEDS::SObject_var theSObject) {
575 myPlayFrame->setEnabled(false);
576 myAnimator->addField(theSObject);
581 //************************************************************************
582 void VisuGUI_TimeAnimationDlg::createFrames() {
584 QApplication::setOverrideCursor( Qt::waitCursor );
586 for (int i = 0; i < myAnimator->getNbFields(); i++) {
587 if (myAnimator->getFieldData(i).myPrs == 0)
588 myAnimator->generatePresentations(i);
590 mySlider->setMaxValue(myAnimator->getNbFrames()-1);
591 if (!myAnimator->generateFrames()) {
592 QApplication::restoreOverrideCursor();
593 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), "Defined presentation can not be created");
596 myPlayFrame->setEnabled(true);
597 QApplication::restoreOverrideCursor();
602 //************************************************************************
603 void VisuGUI_TimeAnimationDlg::onPlayPressed() {
604 if (myPlayBtn->isOn()) {
605 myPlayBtn->setIconSet(MYpausePixmap);
606 if (mySaveCheck->isChecked())
607 myAnimator->dumpTo(myPathEdit->text());
609 myAnimator->dumpTo("");
610 myAnimator->startAnimation();
612 myPlayBtn->setIconSet(MYplayPixmap);
613 myAnimator->stopAnimation();
617 //************************************************************************
618 void VisuGUI_TimeAnimationDlg::onBackPressed() {
620 myAnimator->prevFrame();
624 //************************************************************************
625 void VisuGUI_TimeAnimationDlg::onForvardPressed() {
627 myAnimator->nextFrame();
631 //************************************************************************
632 void VisuGUI_TimeAnimationDlg::onLastPressed() {
634 myAnimator->lastFrame();
638 //************************************************************************
639 void VisuGUI_TimeAnimationDlg::onFirstPressed() {
641 myAnimator->firstFrame();
646 //************************************************************************
647 void VisuGUI_TimeAnimationDlg::clearView() {
648 myAnimator->clearView();
652 //************************************************************************
653 void VisuGUI_TimeAnimationDlg::closeEvent(QCloseEvent* theEvent) {
656 QDialog::closeEvent(theEvent);
660 //************************************************************************
661 void VisuGUI_TimeAnimationDlg::onFrameChanged(int index) {
662 if (myAnimator->isRunning()) return;
663 myAnimator->gotoFrame(index);
667 //************************************************************************
668 void VisuGUI_TimeAnimationDlg::onSpeedChange(double theSpeed) {
669 myAnimator->setSpeed((int)theSpeed);
673 //************************************************************************
674 void VisuGUI_TimeAnimationDlg::stopAnimation() {
675 myAnimator->stopAnimation();
676 myPlayBtn->setOn(false);
677 myPlayBtn->setIconSet(MYplayPixmap);
680 //************************************************************************
681 void VisuGUI_TimeAnimationDlg::onExecution(long theNewFrame, double theTime) {
682 myTimeLbl->setText(QString("%1").arg(theTime));
683 mySlider->setValue(theNewFrame);
687 //************************************************************************
688 void VisuGUI_TimeAnimationDlg::onSetupDlg() {
689 SetupDlg* aDlg = new SetupDlg(this, myAnimator);
694 //************************************************************************
695 void VisuGUI_TimeAnimationDlg::onBrowse() {
696 myPathEdit->setText(QAD_FileDlg::getExistingDirectory(this, "/","Select path"));