1 // VISU VISUGUI : GUI of VISU component
3 // Copyright (C) 2003 CEA/DEN, EDF R&D
7 // File : VisuGUI_TimeAnimation.cxx
8 // Author : Vitaly SMETANNIKOV
11 #include "VisuGUI_TimeAnimation.h"
14 #include "VisuGUI_Tools.h"
15 #include "VisuGUI_DeformedShapeDlg.h"
16 #include "VisuGUI_CutPlanesDlg.h"
17 #include "VisuGUI_Plot3DDlg.h"
18 #include "VisuGUI_VectorsDlg.h"
19 #include "VisuGUI_IsoSurfacesDlg.h"
20 #include "VisuGUI_StreamLinesDlg.h"
22 #include "VISU_TimeAnimation.h"
24 #include "VISU_ScalarMap_i.hh"
25 #include "VISU_IsoSurfaces_i.hh"
26 #include "VISU_DeformedShape_i.hh"
27 #include "VISU_CutPlanes_i.hh"
28 #include "VISU_Plot3D_i.hh"
29 #include "VISU_CutLines_i.hh"
30 #include "VISU_Vectors_i.hh"
31 #include "VISU_StreamLines_i.hh"
33 #include "VISU_ViewManager_i.hh"
35 #include "VISU_ScalarBarActor.hxx"
36 #include "VISU_Actor.h"
38 #include "SalomeApp_Study.h"
39 #include "SalomeApp_Application.h"
41 #include "SVTK_ViewWindow.h"
43 #include "SUIT_OverrideCursor.h"
44 #include "SUIT_MessageBox.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_FileDlg.h"
48 #include <vtkRenderer.h>
56 #include <qwt_wheel.h>
57 #include <qhgroupbox.h>
58 #include <qlcdnumber.h>
59 #include <qvgroupbox.h>
63 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
64 : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
65 myAnimator(theAnimator), myViewWindow(theAnimator->getViewer())
69 QStringList aFieldNames;
70 // Find names of fields
71 for (int i = 0; i < theAnimator->getNbFields(); i++) {
72 aFieldNames.append(VISU::getValue(theAnimator->getFieldData(i).myField, "myName"));
74 aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
75 aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
76 aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
77 myOffsets.append(aOffs);
79 myFieldLst->insertStringList(aFieldNames);
80 myFieldLst->setSelected(0, true);
83 ArrangeDlg::ArrangeDlg(QWidget* theParent, SVTK_ViewWindow* theViewWindow)
84 : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize |
85 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
86 myAnimator(0), myViewWindow(theViewWindow)
90 QStringList aPrsNames;
92 vtkActorCollection *anActColl = myViewWindow->getRenderer()->GetActors();
93 for (anActColl->InitTraversal(); (anActor = anActColl->GetNextActor()) != NULL;) {
94 VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor);
96 if (anVISUActor->GetVisibility() != 0) {
97 VISU::Prs3d_i* aPrs = anVISUActor->GetParent()->GetPrs3d();
99 if (!myPrsMap.contains(aPrs)) {
100 SALOMEDS::SObject_var aSObject = aPrs->GetSObject();
101 if(!aSObject->_is_nil()){
102 SALOMEDS::GenericAttribute_var anAttr;
103 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
104 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
105 string aNam = aName->Value();
106 QString strIn(aNam.c_str());
107 aPrsNames.append(strIn);
108 myPrsMap[aPrs] = myOffsets.count();
110 anVISUActor->GetPosition(aOffs.myOffset);
111 myOffsets.append(aOffs);
118 myFieldLst->insertStringList(aPrsNames);
119 myFieldLst->setSelected(0, true);
122 void ArrangeDlg::init()
124 setCaption("Arrange Presentations");
125 setSizeGripEnabled( TRUE );
127 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
128 aMainLayout->setSpacing(5);
130 QButtonGroup* aBtnGrp = new QButtonGroup(2, Qt::Horizontal, this);
131 aBtnGrp->setExclusive(true);
132 aMainLayout->addWidget(aBtnGrp);
134 QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGrp);
135 aBtnGrp->insert(aAutoBtn, AutoMode);
137 QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGrp);
138 aBtnGrp->insert(aManualBtn, ManualMode);
139 aBtnGrp->setButton(AutoMode);
141 myStackWgt = new QWidgetStack(this);
142 aMainLayout->addWidget(myStackWgt);
145 QVBox* aAutoPane = new QVBox(myStackWgt);
146 aAutoPane->setSpacing(5);
148 myAxisGrp = new QButtonGroup(3, Qt::Horizontal,"Axis", aAutoPane);
150 QRadioButton* aXBtn = new QRadioButton("X",myAxisGrp );
151 myAxisGrp->insert(aXBtn, XAxis);
153 QRadioButton* aYBtn = new QRadioButton("Y",myAxisGrp );
154 myAxisGrp->insert(aYBtn, YAxis);
156 QRadioButton* aZBtn = new QRadioButton("Z",myAxisGrp );
157 myAxisGrp->insert(aZBtn, ZAxis);
159 myAxisGrp->setButton(XAxis);
162 QHBox* aDistPane = new QHBox(aAutoPane);
163 aDistPane->setSpacing(5);
164 new QLabel("Relative Distance", aDistPane);
165 myDistVal = new QtxDblSpinBox (-10,10, 0.5, aDistPane);
166 myDistVal->setValue(1);
168 myStackWgt->addWidget(aAutoPane, AutoMode);
171 QHBox* aManualPane = new QHBox(myStackWgt);
172 aManualPane->setSpacing(10);
174 myFieldLst = new QListBox(aManualPane);
175 connect( myFieldLst, SIGNAL( highlighted(int) ),
176 this, SLOT( onFieldChange(int) ) );
178 QGrid* aCoordPane = new QGrid(2, aManualPane);
179 aCoordPane->setSpacing(5);
181 new QLabel("X", aCoordPane);
182 myCoord[0] = new QtxDblSpinBox(aCoordPane);
183 myCoord[0]->setRange(-MAXVAL, MAXVAL);
185 new QLabel("Y", aCoordPane);
186 myCoord[1] = new QtxDblSpinBox(aCoordPane);
187 myCoord[1]->setRange(-MAXVAL, MAXVAL);
189 new QLabel("Z", aCoordPane);
190 myCoord[2] = new QtxDblSpinBox(aCoordPane);
191 myCoord[2]->setRange(-MAXVAL, MAXVAL);
193 myStackWgt->addWidget(aManualPane, ManualMode);
195 myStackWgt->raiseWidget(AutoMode);
197 connect(aBtnGrp, SIGNAL(clicked(int)), myStackWgt, SLOT(raiseWidget(int)) );
199 SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
200 SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
201 _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
202 if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
203 mySaveChk = new QCheckBox ("Save to presentation", this);
204 mySaveChk->setChecked(false);
205 aMainLayout->addWidget(mySaveChk);
210 // Common buttons ===========================================================
211 QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
212 GroupButtons->setColumnLayout(0, Qt::Vertical );
213 GroupButtons->layout()->setSpacing( 0 );
214 GroupButtons->layout()->setMargin( 0 );
215 QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons->layout() );
216 GroupButtonsLayout->setAlignment( Qt::AlignTop );
217 GroupButtonsLayout->setSpacing( 6 );
218 GroupButtonsLayout->setMargin( 11 );
220 QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons, "buttonOk" );
221 buttonOk->setAutoDefault( TRUE );
222 buttonOk->setDefault( TRUE );
223 GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
224 GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
226 QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons, "buttonCancel" );
227 buttonCancel->setAutoDefault( TRUE );
228 GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
230 aMainLayout->addWidget( GroupButtons );
232 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
233 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
236 void ArrangeDlg::accept()
246 void ArrangeDlg::onFieldChange(int theCurrent)
248 if (myCurrent != theCurrent) {
249 Offset& aOffs = myOffsets[myCurrent];
250 aOffs.myOffset[0] = myCoord[0]->value();
251 aOffs.myOffset[1] = myCoord[1]->value();
252 aOffs.myOffset[2] = myCoord[2]->value();
254 myCurrent = theCurrent;
255 const Offset& aNewOffs = myOffsets[myCurrent];
256 myCoord[0]->setValue(aNewOffs.myOffset[0]);
257 myCoord[1]->setValue(aNewOffs.myOffset[1]);
258 myCoord[2]->setValue(aNewOffs.myOffset[2]);
261 void ArrangeDlg::acceptAnimation()
263 if (getMode() == ManualMode) {
265 Offset& aOffs = myOffsets[myCurrent];
266 aOffs.myOffset[0] = myCoord[0]->value();
267 aOffs.myOffset[1] = myCoord[1]->value();
268 aOffs.myOffset[2] = myCoord[2]->value();
270 for (int i = 0; i < myAnimator->getNbFields(); i++) {
271 Offset aOffs = myOffsets[i];
272 myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
273 myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
274 myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
277 QApplication::setOverrideCursor( Qt::waitCursor );
278 FieldData& aData = myAnimator->getFieldData(0);
279 if (aData.myPrs.empty())
280 myAnimator->generatePresentations(0);
281 VISU_Actor* aActor = aData.myPrs[0]->CreateActor();
283 aActor->GetBounds(aBounds);
286 int aAxis = getAxis();
289 aDist = fabs(aBounds[1] - aBounds[0]);
292 aDist = fabs(aBounds[3] - aBounds[2]);
295 aDist = fabs(aBounds[5] - aBounds[4]);
298 float dx = fabs(aBounds[1] - aBounds[0]);
299 float dy = fabs(aBounds[3] - aBounds[2]);
300 float dz = fabs(aBounds[5] - aBounds[4]);
301 float max = (dx > dy) ? dx : dy;
302 max = (dz > max) ? dz : max;
306 // set base distance between centers of bounding boxes
307 // to minimal (but big enough) size of current bounding box
308 if (dx < max) dx = FLT_MAX;
309 if (dy < max) dy = FLT_MAX;
310 if (dz < max) dz = FLT_MAX;
312 aDist = (dx < dy) ? dx : dy;
313 aDist = (dz < aDist) ? dz : aDist;
315 aDist = aDist * getDistance();
316 for (int i = 0; i < myAnimator->getNbFields(); i++) {
317 myAnimator->getFieldData(i).myOffset[0] = 0;
318 myAnimator->getFieldData(i).myOffset[1] = 0;
319 myAnimator->getFieldData(i).myOffset[2] = 0;
320 myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
323 QApplication::restoreOverrideCursor();
327 void ArrangeDlg::acceptViewWindow()
329 if (getMode() == ManualMode) {
331 Offset& aOffs = myOffsets[myCurrent];
332 aOffs.myOffset[0] = myCoord[0]->value();
333 aOffs.myOffset[1] = myCoord[1]->value();
334 aOffs.myOffset[2] = myCoord[2]->value();
336 QMap<VISU::Prs3d_i*, int>::Iterator it;
337 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
338 VISU::Prs3d_i* aPrs = it.key();
339 Offset& aOffs = myOffsets[it.data()];
340 if (VISU_Actor* anActor = VISU::GetActor(aPrs, myViewWindow))
341 anActor->SetPosition(aOffs.myOffset);
343 if (mySaveChk->isChecked())
344 aPrs->SetOffset(aOffs.myOffset);
350 float aPrevShift = 0;
352 QMap<VISU::Prs3d_i*, int>::Iterator it;
353 for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
354 VISU::Prs3d_i* aPrs = it.key();
355 if (VISU_Actor* aActor = VISU::GetActor(aPrs, myViewWindow)) {
356 int aAxis = getAxis();
358 float aZeroOffset[3];
359 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
360 aActor->SetPosition(aZeroOffset);
361 aActor->GetMapper()->Update();
364 aActor->GetBounds(aBounds);
367 aDist = fabs(aBounds[1] - aBounds[0]);
370 aDist = fabs(aBounds[3] - aBounds[2]);
373 aDist = fabs(aBounds[5] - aBounds[4]);
376 aOffset[0] = (aBounds[1] < aBounds[0]) ? -aBounds[1] : -aBounds[0];
377 aOffset[1] = (aBounds[3] < aBounds[2]) ? -aBounds[3] : -aBounds[2];
378 aOffset[2] = (aBounds[5] < aBounds[4]) ? -aBounds[5] : -aBounds[4];
381 float aCCDist = (aDist + aPrevDist) / 2.0;
383 float dx = fabs(aBounds[1] - aBounds[0]);
384 float dy = fabs(aBounds[3] - aBounds[2]);
385 float dz = fabs(aBounds[5] - aBounds[4]);
386 float max = (dx > dy) ? dx : dy;
387 max = (dz > max) ? dz : max;
391 // set base distance between centers of bounding boxes
392 // to minimal (but big enough) size of current bounding box
393 if (dx < max) dx = FLT_MAX;
394 if (dy < max) dy = FLT_MAX;
395 if (dz < max) dz = FLT_MAX;
397 aCCDist = (dx < dy) ? dx : dy;
398 aCCDist = (dz < aCCDist) ? dz : aCCDist;
401 //-------------------------------->
405 // .--------------. .------.
406 //----------->| | | |
407 // aPrevShift '--------------' '------'
412 // (aDist + aPrevDist) * getDistance() / 2
414 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
417 aOffset[aAxis] += aShift;
418 aActor->SetPosition(aOffset);
420 if (mySaveChk->isChecked())
421 aPrs->SetOffset(aOffset);
428 myViewWindow->getRenderer()->ResetCameraClippingRange();
429 myViewWindow->Repaint();
433 //*****************************************************************************************************
434 //*****************************************************************************************************
435 //*****************************************************************************************************
436 SetupDlg::SetupDlg (VisuGUI* theModule, VISU_TimeAnimation* theAnimator)
437 : QDialog(VISU::GetDesktop(theModule), "SetupDlg", true, WStyle_Customize |
438 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
441 setCaption("Setup Animation");
442 setSizeGripEnabled( TRUE );
443 myAnimator = theAnimator;
445 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
446 aMainLayout->setSpacing(5);
449 QFrame* aRangeGrp = new QFrame(this);
450 QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
451 aRangeLayout->setSpacing( 6 );
452 aRangeLayout->setMargin( 11 );
453 aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
455 myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
456 aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
457 myUseRangeChk->setChecked(myAnimator->isRangeDefined());
459 QLabel* aMinLbl = new QLabel("From", aRangeGrp);
460 aMinLbl->setEnabled(myUseRangeChk->isChecked());
461 aRangeLayout->addWidget(aMinLbl, 1, 0);
462 double aStep = (myAnimator->getMaxTime() - myAnimator->getMinTime())/(theAnimator->getFieldData(0).myNbTimes - 1);
463 myMinVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
464 myMinVal->setEnabled(myUseRangeChk->isChecked());
465 if (myUseRangeChk->isChecked())
466 myMinVal->setValue( myAnimator->getMinRange() );
468 myMinVal->setValue( myAnimator->getMinTime() );
470 connect(myMinVal, SIGNAL( valueChanged(double)),
471 this, SLOT( onMinValue(double) ));
472 aRangeLayout->addWidget(myMinVal, 1, 1);
474 QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
475 aMaxLbl->setEnabled(myUseRangeChk->isChecked());
476 aRangeLayout->addWidget(aMaxLbl, 1, 2);
477 myMaxVal = new QtxDblSpinBox( myAnimator->getMinTime(), myAnimator->getMaxTime(), aStep, aRangeGrp );
478 myMaxVal->setEnabled(myUseRangeChk->isChecked());
479 if (myUseRangeChk->isChecked())
480 myMaxVal->setValue( myAnimator->getMaxRange() );
482 myMaxVal->setValue( myAnimator->getMaxTime() );
484 connect(myMaxVal, SIGNAL( valueChanged(double)),
485 this, SLOT( onMaxValue(double) ));
486 aRangeLayout->addWidget(myMaxVal, 1, 3);
488 connect(myUseRangeChk, SIGNAL( toggled(bool)),
489 aMinLbl, SLOT( setEnabled(bool) ));
490 connect(myUseRangeChk, SIGNAL( toggled(bool)),
491 aMaxLbl, SLOT( setEnabled(bool) ));
492 connect(myUseRangeChk, SIGNAL( toggled(bool)),
493 this, SLOT( onRangeCheck(bool) ));
495 aMainLayout->addWidget(aRangeGrp);
498 QHBox* aPropFrame = new QHBox(this);
499 aPropFrame->setSpacing(5);
501 QVGroupBox* aNamesBox = new QVGroupBox("Fields",aPropFrame);
502 myFieldLst = new QListBox(aNamesBox);
503 QStringList aFieldNames;
504 // Find names of fields
505 for (int i = 0; i < theAnimator->getNbFields(); i++) {
506 _PTR(SObject) aSO = theAnimator->getFieldData(i).myField;
507 aFieldNames.append(VISU::getValue(aSO, "myName"));
509 myFieldLst->insertStringList(aFieldNames);
510 myFieldLst->setSelected(0, true);
511 connect( myFieldLst, SIGNAL( highlighted(int) ),
512 this, SLOT( onFieldChange(int) ) );
515 QVBox* aSetupBox = new QVBox(aPropFrame);
516 aSetupBox->setSpacing(5);
518 QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
519 //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
520 myTypeCombo = new QComboBox(aPropBox);
521 connect( myTypeCombo, SIGNAL( activated(int) ),
522 this, SLOT( onTypeChanged(int) ) );
524 // QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
525 //connect( aBarBtn, SIGNAL( clicked() ),
526 // this, SLOT( onScalarBarDlg() ) );
528 myPropBtn = new QPushButton("Properties...", aPropBox);
529 // myPropBtn->setEnabled(theAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
530 connect( myPropBtn, SIGNAL( clicked() ),
531 this, SLOT( onPreferencesDlg() ) );
533 if (myAnimator->getNbFields() > 1) {
534 myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
535 connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
538 aMainLayout->addWidget(aPropFrame);
540 QHBox* aBtnBox = new QHBox(this);
541 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
542 aBtnLayout->addStretch();
544 QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
545 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
547 aMainLayout->addWidget(aBtnBox);
550 //************************************************************************
552 TSCALARMAP_ITEM = 0, // VISU::TSCALARMAP
553 TISOSURFACE_ITEM = 1, // VISU::TISOSURFACE
554 TCUTPLANES_ITEM = 2, // VISU::TCUTPLANES
555 TPLOT3D_ITEM = 3, // VISU::TPLOT3D
556 TDEFORMEDSHAPE_ITEM = 4, // VISU::TDEFORMEDSHAPE
557 TVECTORS_ITEM = 5, // VISU::TVECTORS
558 TSTREAMLINES_ITEM = 6 // VISU::TSTREAMLINES
561 //************************************************************************
562 void SetupDlg::onFieldChange (int theIndex)
564 FieldData& aData = myAnimator->getFieldData(theIndex);
565 myTypeCombo->clear();
566 // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
567 myTypeCombo->insertItem("Scalar Map"); // item 0
568 myTypeCombo->insertItem("Iso Surfaces"); // item 1
569 myTypeCombo->insertItem("Cut Planes"); // item 2
570 myTypeCombo->insertItem("Plot 3D"); // item 3
572 _PTR(SObject) aSObject = aData.myField;
573 long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
575 myTypeCombo->insertItem("Deformed Shape"); // item 4
576 myTypeCombo->insertItem("Vectors"); // item 5
577 myTypeCombo->insertItem("Stream Lines"); // item 6
579 switch (aData.myPrsType) {
580 case VISU::TSCALARMAP: //Scalar Map
581 myTypeCombo->setCurrentItem(TSCALARMAP_ITEM);
583 case VISU::TISOSURFACE: //Iso Surfaces
584 myTypeCombo->setCurrentItem(TISOSURFACE_ITEM);
586 case VISU::TCUTPLANES: //Cut Planes
587 myTypeCombo->setCurrentItem(TCUTPLANES_ITEM);
589 case VISU::TPLOT3D: //Plot 3D
590 myTypeCombo->setCurrentItem(TPLOT3D_ITEM);
592 case VISU::TDEFORMEDSHAPE: //Deformed Shape
593 myTypeCombo->setCurrentItem(TDEFORMEDSHAPE_ITEM);
595 case VISU::TVECTORS: //Vectors
596 myTypeCombo->setCurrentItem(TVECTORS_ITEM);
598 case VISU::TSTREAMLINES: //Stream Lines
599 myTypeCombo->setCurrentItem(TSTREAMLINES_ITEM);
600 aData.myPrsType = VISU::TSTREAMLINES;
603 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
606 //************************************************************************
607 void SetupDlg::onTypeChanged (int theIndex)
609 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
611 case TSCALARMAP_ITEM: //Scalar Map
612 aData.myPrsType = VISU::TSCALARMAP;
614 case TISOSURFACE_ITEM: //Iso Surfaces
615 aData.myPrsType = VISU::TISOSURFACE;
617 case TCUTPLANES_ITEM: //Cut Planes
618 aData.myPrsType = VISU::TCUTPLANES;
620 case TPLOT3D_ITEM: //Plot 3D
621 aData.myPrsType = VISU::TPLOT3D;
623 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
624 aData.myPrsType = VISU::TDEFORMEDSHAPE;
626 case TVECTORS_ITEM: //Vectors
627 aData.myPrsType = VISU::TVECTORS;
629 case TSTREAMLINES_ITEM: //Stream Lines
630 aData.myPrsType = VISU::TSTREAMLINES;
633 myAnimator->clearData(aData);
634 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
635 //myAnimator->generatePresentations(myFieldLst->currentItem());
638 //************************************************************************
639 /*void SetupDlg::onScalarBarDlg() {
640 QApplication::setOverrideCursor( Qt::waitCursor );
641 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
642 if (aData.myPrs == 0)
643 myAnimator->generatePresentations(myFieldLst->currentItem());
644 QApplication::restoreOverrideCursor();
646 VisuGUI_ScalarBarDlg* aScalarBarDlg = new VisuGUI_ScalarBarDlg();
647 aScalarBarDlg->initFromPrsObject(aData.myPrs[0]);
648 if (aScalarBarDlg->exec()) {
649 for (int i = 0; i < aData.myNbFrames; i++)
650 aScalarBarDlg->storeToPrsObject(aData.myPrs[i]);
655 //************************************************************************
656 void SetupDlg::onPreferencesDlg()
658 SUIT_OverrideCursor c;
659 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
660 if (aData.myPrs.empty())
661 myAnimator->generatePresentations(myFieldLst->currentItem());
663 // BUG VISU5725 : Compatibility gcc 2.95
664 // #define EDITPRS(TYPE, DLG) \
666 // DLG* aDlg = new DLG(); \
667 // aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(0))); \
668 // if (aDlg->exec()) { \
669 // for (int i = 0; i < aData.myNbFrames; i++) \
670 // aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs.at(i))); \
676 #define EDITPRS(TYPE, DLG) {\
677 DLG* aDlg = new DLG (myModule);\
678 aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0]));\
681 for (int i = 0; i < aData.myNbFrames; i++)\
682 aDlg->storeToPrsObject(dynamic_cast<TYPE*>(aData.myPrs[i]));\
686 switch (myTypeCombo->currentItem()) {
687 case TSCALARMAP_ITEM: //Scalar Map
689 EDITPRS(VISU::ScalarMap_i, VisuGUI_ScalarBarDlg);
691 case TISOSURFACE_ITEM: //Iso Surfaces
693 EDITPRS(VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg);
695 case TCUTPLANES_ITEM: //Cut Planes
697 EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
699 VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg (myModule);
700 //_CS_PhB :operator [] .at aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
701 aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
704 for (int i = 0; i < aData.myNbFrames; i++)
705 //_CS_PhB:operator [] .at aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(i)));
706 aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
711 case TPLOT3D_ITEM: //Plot 3D
713 EDITPRS(VISU::Plot3D_i, VisuGUI_Plot3DDlg);
715 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
717 EDITPRS(VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg);
719 case TVECTORS_ITEM: //Vectors
721 EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
723 case TSTREAMLINES_ITEM: //Stream Lines
725 EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
732 //************************************************************************
733 void SetupDlg::onArrangeDlg()
735 ArrangeDlg aDlg(this, myAnimator);
739 //************************************************************************
740 void SetupDlg::onRangeCheck (bool theCheck)
742 for (int i = 0; i < myAnimator->getNbFields(); i++)
743 myAnimator->clearData(myAnimator->getFieldData(i));
745 myMinVal->setEnabled(theCheck);
746 myMaxVal->setEnabled(theCheck);
749 myAnimator->setAnimationRange(0, 0);
751 // if (myMinVal->value() < myMaxVal->value())
752 myAnimator->setAnimationRange(myMinVal->value(), myMaxVal->value());
753 // else if (myMinVal->value() > myMaxVal->value())
754 // myAnimator->setAnimationRange(myMaxVal->value(), myMinVal->value());
755 // else // equal case
756 // myAnimator->setAnimationRange(0, 0);
760 //************************************************************************
761 void SetupDlg::onMinValue (double theVal)
763 if (theVal > myAnimator->getMaxRange()) {
764 myMinVal->setValue( myAnimator->getMinTime() );
765 myMinVal->setFocus();
768 for (int i = 0; i < myAnimator->getNbFields(); i++)
769 myAnimator->clearData(myAnimator->getFieldData(i));
770 myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
773 //************************************************************************
774 void SetupDlg::onMaxValue (double theVal)
776 if (theVal < myAnimator->getMinRange()) {
777 myMaxVal->setValue( myAnimator->getMaxTime() );
778 myMaxVal->setFocus();
781 for (int i = 0; i < myAnimator->getNbFields(); i++)
782 myAnimator->clearData(myAnimator->getFieldData(i));
783 myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
786 static const char * firstIco[] = {
802 static const char * lastIco[] = {
818 static const char * leftIco[] = {
833 static const char * playIco[] = {
852 static QPixmap MYplayPixmap(playIco);
855 static const char * rightIco[] = {
871 static const char * pauseIco[] = {
890 static QPixmap MYpausePixmap(pauseIco);
893 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule, _PTR(Study) theStudy)
894 : QDialog(VISU::GetDesktop(theModule), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
895 WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
899 setCaption("Animation");
900 setSizeGripEnabled( TRUE );
903 myAnimator = new VISU_TimeAnimation (theStudy);
904 myAnimator->setSpeed(1);
905 myAnimator->setViewer(VISU::GetViewWindow());
906 connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
907 connect(myAnimator, SIGNAL(stopped()), this, SLOT(onStop()));
909 QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 6);
910 aMainLayout->setSpacing(5);
912 mySetupBtn = new QPushButton("Setup Animation...", this);
913 connect( mySetupBtn, SIGNAL( clicked() ),
914 this, SLOT( onSetupDlg() ) );
915 aMainLayout->addWidget(mySetupBtn);
917 myGenBtn = new QPushButton("Generate frames", this);
918 connect( myGenBtn, SIGNAL( clicked() ),
919 this, SLOT( createFrames() ) );
920 aMainLayout->addWidget(myGenBtn);
922 myPlayFrame = new QFrame(this);
923 myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
924 myPlayFrame->setLineWidth( 1 );
927 // --- Play controls ---
928 QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
929 TopLayout->setSpacing( 6 );
930 TopLayout->setMargin( 11 );
932 myTimeLbl = new QLabel("0", myPlayFrame);
933 TopLayout->addMultiCellWidget(myTimeLbl, 0, 0, 0, 2, Qt::AlignHCenter);
935 mySlider = new QSlider(Qt::Horizontal, myPlayFrame);
936 mySlider->setMinValue(0);
937 mySlider->setMaxValue(3);
938 mySlider->setTickInterval(1);
939 //mySlider->setTickmarks(QSlider::Below);
940 mySlider->setTracking(false);
941 connect( mySlider, SIGNAL( valueChanged(int) ),
942 this, SLOT( onWindowChanged(int) ) );
943 TopLayout->addMultiCellWidget(mySlider, 1, 1, 0, 2);
945 myPlayBtn = new QToolButton(myPlayFrame);
946 myPlayBtn->setIconSet(MYplayPixmap);
947 myPlayBtn->setToggleButton(true);
948 connect( myPlayBtn, SIGNAL( clicked() ),
949 this, SLOT( onPlayPressed() ) );
950 TopLayout->addMultiCellWidget(myPlayBtn, 2, 2, 0, 1);
952 QToolButton* aBackBtn = new QToolButton(myPlayFrame);
953 aBackBtn->setIconSet(QPixmap(leftIco));
954 connect( aBackBtn, SIGNAL( clicked() ),
955 this, SLOT( onBackPressed() ) );
956 TopLayout->addWidget(aBackBtn, 3, 0);
958 QToolButton* aForvardBtn = new QToolButton(myPlayFrame);
959 aForvardBtn->setIconSet(QPixmap(rightIco));
960 connect( aForvardBtn, SIGNAL( clicked() ),
961 this, SLOT( onForvardPressed() ) );
962 TopLayout->addWidget(aForvardBtn, 3, 1);
964 QToolButton* aFirstBtn = new QToolButton(myPlayFrame);
965 aFirstBtn->setIconSet(QPixmap(firstIco));
966 connect( aFirstBtn, SIGNAL( clicked() ),
967 this, SLOT( onFirstPressed() ) );
968 TopLayout->addWidget(aFirstBtn, 4, 0);
970 QToolButton* aLastBtn = new QToolButton(myPlayFrame);
971 aLastBtn->setIconSet(QPixmap(lastIco));
972 connect( aLastBtn, SIGNAL( clicked() ),
973 this, SLOT( onLastPressed() ) );
974 TopLayout->addWidget(aLastBtn, 4, 1);
976 QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
977 TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
979 QLCDNumber* aSpeedNum = new QLCDNumber( 2, myPlayFrame );
980 aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
981 aSpeedNum->display(1);
982 TopLayout->addWidget(aSpeedNum, 4, 3);
984 QwtWheel* aWheel = new QwtWheel(myPlayFrame);
985 aWheel->setOrientation(Qt::Vertical);
986 aWheel->setRange(1, 99, 1);
987 connect( aWheel, SIGNAL(valueChanged(double)),
988 aSpeedNum, SLOT(display(double)) );
989 connect( aWheel, SIGNAL(valueChanged(double)),
990 this, SLOT(onSpeedChange(double)) );
991 TopLayout->addMultiCellWidget(aWheel, 1, 3, 3, 3, Qt::AlignRight);
993 QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
994 aCycleCheck->setChecked(myAnimator->isCycling());
995 connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
996 TopLayout->addMultiCellWidget(aCycleCheck, 5, 5, 0, 3);
998 QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
999 aPropCheck->setChecked(myAnimator->isProportional());
1000 connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1001 TopLayout->addMultiCellWidget(aPropCheck, 6, 6, 0, 3);
1003 QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1004 aSaveBox->setColumnLayout(0, Qt::Horizontal );
1005 QGridLayout* aSaveLay = new QGridLayout(aSaveBox->layout());
1006 aSaveLay->setSpacing( 5 );
1007 aSaveLay->setMargin( 5 );
1009 mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1010 aSaveLay->addMultiCellWidget(mySaveCheck, 0, 0, 0, 2);
1011 connect(mySaveCheck, SIGNAL( toggled(bool)),
1012 aWheel, SLOT( setDisabled(bool) ));
1014 QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1015 aPathLbl->setEnabled(false);
1016 connect(mySaveCheck, SIGNAL( toggled(bool)),
1017 aPathLbl, SLOT( setEnabled(bool) ));
1018 aSaveLay->addWidget(aPathLbl, 1, 0);
1020 myPathEdit = new QLineEdit(aSaveBox);
1021 myPathEdit->setEnabled(false);
1022 connect(mySaveCheck, SIGNAL( toggled(bool)),
1023 myPathEdit, SLOT( setEnabled(bool) ));
1024 aSaveLay->addWidget(myPathEdit, 1, 1);
1026 QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1027 aBrowseBtn->setEnabled(false);
1028 connect(mySaveCheck, SIGNAL( toggled(bool)),
1029 aBrowseBtn, SLOT( setEnabled(bool) ));
1030 connect(aBrowseBtn, SIGNAL( clicked()),
1031 this, SLOT( onBrowse() ));
1032 mySaveCheck->setChecked(false);
1033 aSaveLay->addWidget(aBrowseBtn, 1, 2);
1035 TopLayout->addMultiCellWidget(aSaveBox, 7, 7, 0, 3);
1037 aMainLayout->addWidget(myPlayFrame);
1039 QHBox* aPublishBox = new QHBox(this);
1040 aPublishBox->setSpacing(5);
1042 myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1043 connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1045 mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1046 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1047 connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1049 aMainLayout->addWidget(aPublishBox);
1052 QHBox* aBtnBox = new QHBox(this);
1053 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox->layout());
1054 aBtnLayout->addStretch();
1056 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1057 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1059 SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1060 connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1062 aMainLayout->addWidget(aBtnBox);
1064 myPlayFrame->setEnabled(false);
1067 //************************************************************************
1068 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1073 //************************************************************************
1074 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1077 myPropBtn->setEnabled(index != 0);
1080 myPlayFrame->setEnabled(false);
1083 //************************************************************************
1084 void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1086 myPlayFrame->setEnabled(false);
1087 myAnimator->addField(VISU::GetSObject(theSObject));
1090 //************************************************************************
1091 void VisuGUI_TimeAnimationDlg::createFrames()
1094 SUIT_OverrideCursor c;
1096 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1097 if (myAnimator->getFieldData(i).myPrs.empty())
1098 myAnimator->generatePresentations(i);
1100 if (myAnimator->getNbFrames() == 0) {
1101 myPlayFrame->setEnabled(false);
1103 SUIT_MessageBox::warn1(this,
1105 tr("MSG_NO_ANIMATIONDATA"),
1109 mySlider->setMaxValue(myAnimator->getNbFrames()-1);
1110 myPlayFrame->setEnabled(true);
1111 if (!myAnimator->generateFrames()) {
1113 //myPlayFrame->setEnabled(false);
1114 SUIT_MessageBox::warn1(this,
1116 myAnimator->getLastErrorMsg(),
1120 //myPlayFrame->setEnabled(true);
1123 //************************************************************************
1124 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1126 if (myPlayBtn->isOn() && (!myAnimator->running())) {
1127 myPlayBtn->setIconSet(MYpausePixmap);
1128 if (mySaveCheck->isChecked())
1129 myAnimator->dumpTo(myPathEdit->text());
1131 myAnimator->dumpTo("");
1132 mySetupBtn->setEnabled(false);
1133 myGenBtn->setEnabled(false);
1134 myAnimator->startAnimation();
1136 myPlayBtn->setIconSet(MYplayPixmap);
1137 myAnimator->stopAnimation();
1138 mySetupBtn->setEnabled(true);
1139 myGenBtn->setEnabled(true);
1143 //************************************************************************
1144 void VisuGUI_TimeAnimationDlg::onBackPressed()
1147 myAnimator->prevFrame();
1150 //************************************************************************
1151 void VisuGUI_TimeAnimationDlg::onForvardPressed()
1153 myAnimator->nextFrame();
1156 //************************************************************************
1157 void VisuGUI_TimeAnimationDlg::onLastPressed()
1159 myAnimator->lastFrame();
1162 //************************************************************************
1163 void VisuGUI_TimeAnimationDlg::onFirstPressed()
1165 myAnimator->firstFrame();
1168 //************************************************************************
1169 void VisuGUI_TimeAnimationDlg::clearView()
1171 myAnimator->clearView();
1174 //************************************************************************
1175 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
1177 myAnimator->stopAnimation();
1178 myAnimator->wait(500);
1179 if (myAnimator->running() && (! myAnimator->finished())) {
1183 QDialog::closeEvent(theEvent);
1187 //************************************************************************
1188 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
1190 if (myAnimator->isRunning()) return;
1191 myAnimator->gotoFrame(index);
1194 //************************************************************************
1195 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
1197 myAnimator->setSpeed((int)theSpeed);
1200 //************************************************************************
1201 void VisuGUI_TimeAnimationDlg::stopAnimation()
1203 myAnimator->stopAnimation();
1204 myPlayBtn->setOn(false);
1205 myPlayBtn->setIconSet(MYplayPixmap);
1206 mySetupBtn->setEnabled(true);
1207 myGenBtn->setEnabled(true);
1210 //************************************************************************
1211 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
1213 myTimeLbl->setText(QString("%1").arg(theTime));
1214 mySlider->setValue(theNewFrame);
1217 //************************************************************************
1218 void VisuGUI_TimeAnimationDlg::onSetupDlg()
1220 if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
1221 SetupDlg* aDlg = new SetupDlg (myModule, myAnimator);
1223 myPlayFrame->setEnabled(false);
1227 //************************************************************************
1228 void VisuGUI_TimeAnimationDlg::onBrowse()
1230 QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/","Select path");
1231 if (!aPath.isEmpty())
1232 myPathEdit->setText(aPath);
1235 //************************************************************************
1236 void VisuGUI_TimeAnimationDlg::onStop()
1239 QDialog::closeEvent(myEvent);
1241 myPlayBtn->setOn(false);
1242 myPlayBtn->setIconSet(MYplayPixmap);
1243 mySetupBtn->setEnabled(true);
1244 myGenBtn->setEnabled(true);
1248 //************************************************************************
1249 void VisuGUI_TimeAnimationDlg::saveToStudy()
1251 myAnimator->saveAnimation();
1252 VISU::UpdateObjBrowser(myModule, true);
1255 //************************************************************************
1256 void VisuGUI_TimeAnimationDlg::publishToStudy()
1258 myAnimator->publishInStudy();
1259 VISU::UpdateObjBrowser(myModule, true);
1260 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1263 //************************************************************************
1264 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
1266 myAnimator->restoreFromStudy(theAnimation);
1267 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());