1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : VisuGUI_TimeAnimation.cxx
24 // Author : Vitaly SMETANNIKOV
27 #include "VisuGUI_TimeAnimation.h"
30 #include "VisuGUI_Tools.h"
31 #include "VisuGUI_ViewTools.h"
32 #include "VisuGUI_ScalarBarDlg.h"
33 #include "VisuGUI_DeformedShapeDlg.h"
34 #include "VisuGUI_CutPlanesDlg.h"
35 #include "VisuGUI_CutLinesDlg.h"
36 #include "VisuGUI_CutSegmentDlg.h"
37 #include "VisuGUI_Plot3DDlg.h"
38 #include "VisuGUI_VectorsDlg.h"
39 #include "VisuGUI_IsoSurfacesDlg.h"
40 #include "VisuGUI_StreamLinesDlg.h"
41 #include "VisuGUI_DeformedShapeAndScalarMapDlg.h"
42 #include "VisuGUI_GaussPointsDlg.h"
44 #include "VISU_TimeAnimation.h"
46 #include "VISU_ScalarMap_i.hh"
47 #include "VISU_IsoSurfaces_i.hh"
48 #include "VISU_DeformedShape_i.hh"
49 #include "VISU_CutPlanes_i.hh"
50 #include "VISU_Plot3D_i.hh"
51 #include "VISU_CutLines_i.hh"
52 #include "VISU_CutSegment_i.hh"
53 #include "VISU_Vectors_i.hh"
54 #include "VISU_StreamLines_i.hh"
55 #include "VISU_DeformedShapeAndScalarMap_i.hh"
56 #include "VISU_GaussPoints_i.hh"
58 #include "VISU_ViewManager_i.hh"
60 #include "VISU_ScalarBarActor.hxx"
61 #include "VISU_Actor.h"
63 #include <SalomeApp_DoubleSpinBox.h>
64 #include <SalomeApp_IntSpinBox.h>
65 #include "SalomeApp_Study.h"
66 #include "LightApp_Application.h"
68 #include "SVTK_ViewWindow.h"
70 #include "VTKViewer_Algorithm.h"
72 #include "SUIT_OverrideCursor.h"
73 #include "SUIT_MessageBox.h"
74 #include "SUIT_ResourceMgr.h"
75 #include "SUIT_Session.h"
76 #include "SUIT_Desktop.h"
77 #include "SUIT_FileDlg.h"
79 #include <vtkRenderer.h>
80 #include <vtkMapper.h>
82 #include <QGridLayout>
84 #include <QImageWriter>
88 #include <QListWidget>
90 #include <QToolButton>
94 #include <QRadioButton>
96 #include <QPushButton>
99 #include <qwt_wheel.h>
102 #define VALPRECISION 8
105 void GeneratePresentations(int theFieldId, VISU_TimeAnimation* theAnimator)
107 if(theAnimator->getNbFields() == 0)
110 int aRefFieldId = ( theAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ? theFieldId : 0;
112 VISU::ColoredPrs3d_i* aInitialPrs3d = 0;
113 if (theAnimator->getFieldData(aRefFieldId).myPrs.size() > 0)
114 aInitialPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(theAnimator->getFieldData(aRefFieldId).myPrs[0]);
116 theAnimator->generatePresentations(theFieldId);
119 aInitialPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(theAnimator->getFieldData(aRefFieldId).myPrs[0]);
122 FieldData& aFieldData = theAnimator->getFieldData(theFieldId);
123 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
124 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
126 // Special case for DeformedShape And ScalarMap presentation
127 // Restore time stamp number for all presentations
128 VISU::DeformedShapeAndScalarMap_i* aDeformedAndScalPrs = dynamic_cast<VISU::DeformedShapeAndScalarMap_i*>(aColoredPrs3d);
129 int aTimeStampNum = -1;
130 if(aDeformedAndScalPrs){
131 aTimeStampNum = aDeformedAndScalPrs->GetScalarTimeStampNumber();
134 aColoredPrs3d->SameAs(aInitialPrs3d);
136 // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
137 // special case for the "Gauss Points" presentation,
138 // update the LookupTable in the mapper, after assign properties of the presentation
139 // using SameAs(...) method.
140 if(aFieldData.myPrsType == VISU::TGAUSSPOINTS) {
141 aColoredPrs3d->UpdateMapperLookupTable();
144 if(aDeformedAndScalPrs){
145 aDeformedAndScalPrs->SetScalarField(aDeformedAndScalPrs->GetScalarEntity(),
146 aDeformedAndScalPrs->GetScalarFieldName(),
150 std::string aTitle = aColoredPrs3d->GetCTitle();
151 if ( aFrameId != 0 && theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
152 aColoredPrs3d->SetTitle(aTitle.c_str());
159 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
160 : QDialog(theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
161 myAnimator(theAnimator),
162 myViewWindow(theAnimator->getViewer())
167 QStringList aFieldNames;
168 // Find names of fields
169 for (int i = 0; i < myAnimator->getNbFields(); i++) {
170 _PTR(SObject) aSObject = myAnimator->getFieldData(i).myField;
171 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
172 aFieldNames.append(aRestoringMap["myName"]);
174 aOffs.myOffset[0] = myAnimator->getFieldData(i).myOffset[0];
175 aOffs.myOffset[1] = myAnimator->getFieldData(i).myOffset[1];
176 aOffs.myOffset[2] = myAnimator->getFieldData(i).myOffset[2];
177 myOffsets.append(aOffs);
179 myFieldLst->addItems(aFieldNames);
180 myFieldLst->setCurrentRow(0);
183 ArrangeDlg::ArrangeDlg(QWidget* theParent,
184 const SalomeApp_Module* theModule,
185 SVTK_ViewWindow* theViewWindow)
186 : QDialog(theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
188 myViewWindow(theViewWindow)
193 QStringList aPrsNames;
194 VTK::ActorCollectionCopy aCopy(myViewWindow->getRenderer()->GetActors());
195 vtkActorCollection *aCollection = aCopy.GetActors();
196 aCollection->InitTraversal();
197 while(vtkActor* anActor = aCollection->GetNextActor()){
198 if (VISU_Actor* anVISUActor = dynamic_cast<VISU_Actor*>(anActor)) {
199 if(anVISUActor->GetVisibility() != 0){
200 if (VISU::Prs3d_i* aPrs = anVISUActor->GetPrs3d()){
201 if(!myPrsMap.contains(aPrs)){
202 Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
203 if(!anIO->hasEntry())
205 SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
206 VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
207 if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
208 _PTR(GenericAttribute) anAttr;
209 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
210 _PTR(AttributeName) aName(anAttr);
211 QString strIn(aName->Value().c_str());
212 aPrsNames.append(strIn);
213 myPrsMap[aPrs] = myOffsets.count();
215 anVISUActor->GetPosition(aOffs.myOffset);
216 myOffsets.append(aOffs);
222 } else { //if PointMap3d Actor
223 if (VISU_ActorBase* anActorBase = dynamic_cast<VISU_ActorBase*>(anActor))
224 if(anActorBase->GetVisibility() != 0)
225 if (VISU::PointMap3d_i* aPrs = dynamic_cast<VISU::PointMap3d_i*>(anActorBase->GetFactory())) {
226 if(!myPointMapPrsMap.contains(aPrs)){
227 Handle(SALOME_InteractiveObject) anIO = aPrs->GetIO();
228 if(!anIO->hasEntry())
230 SalomeApp_Study* aStudy = VISU::GetAppStudy(theModule);
231 VISU::TObjectInfo anObjectInfo = VISU::GetObjectByEntry(aStudy, anIO->getEntry());
232 if(_PTR(SObject) aSObject = anObjectInfo.mySObject){
233 _PTR(GenericAttribute) anAttr;
234 if (aSObject->FindAttribute(anAttr, "AttributeName")) {
235 _PTR(AttributeName) aName(anAttr);
236 QString strIn(aName->Value().c_str());
237 aPrsNames.append(strIn);
238 myPointMapPrsMap[aPrs] = myOffsets.count();
240 anActorBase->GetPosition(aOffs.myOffset);
241 myOffsets.append(aOffs);
248 myFieldLst->addItems(aPrsNames);
249 myFieldLst->setCurrentRow(0);
252 void ArrangeDlg::init()
254 setWindowTitle("Arrange Presentations");
255 setSizeGripEnabled( TRUE );
257 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
258 aMainLayout->setMargin( 7 );
259 aMainLayout->setSpacing(5);
261 QButtonGroup* aBtnGrp = new QButtonGroup( this);
262 aBtnGrp->setExclusive(true);
263 //aMainLayout->addWidget(aBtnGrp);
265 QGroupBox* aBtnGB = new QGroupBox( this );
266 QHBoxLayout* aHBLay = new QHBoxLayout( aBtnGB );
267 aMainLayout->addWidget(aBtnGB);
269 QRadioButton* aAutoBtn = new QRadioButton("Auto", aBtnGB);
270 aHBLay->addWidget( aAutoBtn );
271 aBtnGrp->addButton(aAutoBtn, AutoMode);
273 QRadioButton* aManualBtn = new QRadioButton("Manual", aBtnGB);
274 aHBLay->addWidget( aManualBtn );
275 aBtnGrp->addButton(aManualBtn, ManualMode);
277 aAutoBtn->setChecked( true );
279 myStackWgt = new QStackedWidget(this);
280 aMainLayout->addWidget(myStackWgt);
283 QWidget* aAutoPane = new QWidget(myStackWgt);
284 QVBoxLayout* aAutoLay = new QVBoxLayout( aAutoPane );
285 aAutoLay->setSpacing(5);
288 myAxisGrp = new QButtonGroup(aAutoPane);
290 QGroupBox* aAxisGB = new QGroupBox( "Axis", aAutoPane );
291 QHBoxLayout* aVBLay = new QHBoxLayout( aAxisGB );
292 aAutoLay->addWidget( aAxisGB );
294 QRadioButton* aXBtn = new QRadioButton("X",aAxisGB );
295 aVBLay->addWidget( aXBtn );
296 myAxisGrp->addButton(aXBtn, XAxis);
298 QRadioButton* aYBtn = new QRadioButton("Y",aAxisGB );
299 aVBLay->addWidget( aYBtn );
300 myAxisGrp->addButton(aYBtn, YAxis);
302 QRadioButton* aZBtn = new QRadioButton("Z",aAxisGB );
303 aVBLay->addWidget( aZBtn );
304 myAxisGrp->addButton(aZBtn, ZAxis);
306 aXBtn->setChecked( true );
309 QWidget* aDistPane = new QWidget(aAutoPane);
310 QHBoxLayout* aHLay = new QHBoxLayout( aDistPane );
311 aHLay->setSpacing(5);
312 aHLay->addWidget( new QLabel("Relative Distance", aDistPane) );
313 myDistVal = new SalomeApp_DoubleSpinBox( aDistPane );
314 VISU::initSpinBox( myDistVal, -10., 10., 0.5, "length_precision" );
315 myDistVal->setValue(1);
316 aHLay->addWidget( myDistVal );
318 aAutoLay->addWidget( aDistPane );
320 myStackWgt->insertWidget( AutoMode, aAutoPane);
323 QWidget* aManualPane = new QWidget(myStackWgt);
324 aHLay = new QHBoxLayout( aManualPane );
325 aHLay->setSpacing(10);
327 myFieldLst = new QListWidget(aManualPane);
328 aHLay->addWidget( myFieldLst );
329 connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
330 this, SLOT( onFieldChange(int) ) );
332 QWidget* aCoordPane = new QWidget( aManualPane);
333 aHLay->addWidget( aCoordPane );
334 QGridLayout* aCoordLayout = new QGridLayout( aCoordPane );
335 aCoordLayout->setSpacing(5);
337 aCoordLayout->addWidget( new QLabel("X", aCoordPane), 0, 0 );
338 myCoord[0] = new SalomeApp_DoubleSpinBox(aCoordPane);
339 VISU::initSpinBox( myCoord[0], -MAXVAL, MAXVAL, 1., "length_precision" );
340 aCoordLayout->addWidget( myCoord[0], 0, 1 );
342 aCoordLayout->addWidget( new QLabel("Y", aCoordPane), 1, 0 );
343 myCoord[1] = new SalomeApp_DoubleSpinBox(aCoordPane);
344 VISU::initSpinBox( myCoord[1], -MAXVAL, MAXVAL, 1., "length_precision" );
345 aCoordLayout->addWidget( myCoord[1], 1, 1 );
347 aCoordLayout->addWidget( new QLabel("Z", aCoordPane), 2, 0 );
348 myCoord[2] = new SalomeApp_DoubleSpinBox(aCoordPane);
349 VISU::initSpinBox( myCoord[2], -MAXVAL, MAXVAL, 1., "length_precision" );
350 aCoordLayout->addWidget( myCoord[2], 2, 1 );
352 myStackWgt->insertWidget(ManualMode, aManualPane );
354 myStackWgt->setCurrentIndex(AutoMode);
356 connect(aBtnGrp, SIGNAL(buttonClicked(int)), myStackWgt, SLOT(setCurrentIndex(int)) );
358 SUIT_Study* aSUITStudy = myViewWindow->getViewManager()->study();
359 SalomeApp_Study* anAppStudy = dynamic_cast<SalomeApp_Study*>(aSUITStudy);
360 _PTR(Study) aCStudy = VISU::GetCStudy(anAppStudy);
361 if (!myAnimator && !aCStudy->GetProperties()->IsLocked()) {
362 mySaveChk = new QCheckBox ("Save to presentation", this);
363 mySaveChk->setChecked(false);
364 aMainLayout->addWidget(mySaveChk);
369 // Common buttons ===========================================================
370 QGroupBox* GroupButtons = new QGroupBox( this );
371 //GroupButtons->setColumnLayout(0, Qt::Vertical );
372 //GroupButtons->layout()->setSpacing( 0 );
373 //GroupButtons->layout()->setMargin( 0 );
374 QGridLayout* GroupButtonsLayout = new QGridLayout( GroupButtons );
375 GroupButtonsLayout->setAlignment( Qt::AlignTop );
376 GroupButtonsLayout->setSpacing( 6 );
377 GroupButtonsLayout->setMargin( 11 );
379 QPushButton* buttonOk = new QPushButton( tr( "&OK" ), GroupButtons );
380 buttonOk->setAutoDefault( TRUE );
381 buttonOk->setDefault( TRUE );
382 GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
383 GroupButtonsLayout->addItem( new QSpacerItem( 5, 5, QSizePolicy::Expanding, QSizePolicy::Minimum ), 0, 1 );
385 QPushButton* buttonCancel = new QPushButton( tr( "&Cancel" ) , GroupButtons );
386 buttonCancel->setAutoDefault( TRUE );
387 GroupButtonsLayout->addWidget( buttonCancel, 0, 2 );
389 aMainLayout->addWidget( GroupButtons );
391 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
392 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
395 void ArrangeDlg::accept()
397 if (myAnimator != NULL) {
405 void ArrangeDlg::onFieldChange(int theCurrent)
407 if (myCurrent != theCurrent) {
408 Offset& aOffs = myOffsets[myCurrent];
409 aOffs.myOffset[0] = myCoord[0]->value();
410 aOffs.myOffset[1] = myCoord[1]->value();
411 aOffs.myOffset[2] = myCoord[2]->value();
413 myCurrent = theCurrent;
414 const Offset& aNewOffs = myOffsets[myCurrent];
415 myCoord[0]->setValue(aNewOffs.myOffset[0]);
416 myCoord[1]->setValue(aNewOffs.myOffset[1]);
417 myCoord[2]->setValue(aNewOffs.myOffset[2]);
420 void ArrangeDlg::acceptAnimation()
422 if (getMode() == ManualMode) {
424 Offset& aOffs = myOffsets[myCurrent];
425 aOffs.myOffset[0] = myCoord[0]->value();
426 aOffs.myOffset[1] = myCoord[1]->value();
427 aOffs.myOffset[2] = myCoord[2]->value();
429 for (int i = 0; i < myAnimator->getNbFields(); i++) {
430 Offset aOffs = myOffsets[i];
431 myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
432 myAnimator->getFieldData(i).myOffset[1] = aOffs.myOffset[1];
433 myAnimator->getFieldData(i).myOffset[2] = aOffs.myOffset[2];
436 QApplication::setOverrideCursor( Qt::WaitCursor );
437 FieldData& aData = myAnimator->getFieldData(myFieldLst->currentRow());
438 if (aData.myPrs.empty())
439 GeneratePresentations(myFieldLst->currentRow(),myAnimator);
440 vtkFloatingPointType aBounds[6];
441 aData.myPrs[0]->GetBounds(aBounds);
442 vtkFloatingPointType aDist = 0;
443 int aAxis = getAxis();
446 aDist = fabs(aBounds[1] - aBounds[0]);
449 aDist = fabs(aBounds[3] - aBounds[2]);
452 aDist = fabs(aBounds[5] - aBounds[4]);
455 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
456 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
457 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
458 vtkFloatingPointType max = (dx > dy) ? dx : dy;
459 max = (dz > max) ? dz : max;
463 // set base distance between centers of bounding boxes
464 // to minimal (but big enough) size of current bounding box
465 if (dx < max) dx = FLT_MAX;
466 if (dy < max) dy = FLT_MAX;
467 if (dz < max) dz = FLT_MAX;
469 aDist = (dx < dy) ? dx : dy;
470 aDist = (dz < aDist) ? dz : aDist;
472 aDist = aDist * getDistance();
473 for (int i = 0; i < myAnimator->getNbFields(); i++) {
474 myAnimator->getFieldData(i).myOffset[0] = 0;
475 myAnimator->getFieldData(i).myOffset[1] = 0;
476 myAnimator->getFieldData(i).myOffset[2] = 0;
477 myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
480 QApplication::restoreOverrideCursor();
484 void ArrangeDlg::acceptViewWindow()
486 if (getMode() == ManualMode) {
488 Offset& aOffs = myOffsets[myCurrent];
489 aOffs.myOffset[0] = myCoord[0]->value();
490 aOffs.myOffset[1] = myCoord[1]->value();
491 aOffs.myOffset[2] = myCoord[2]->value();
493 QMap<VISU::Prs3d_i*, int>::Iterator it;
494 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
495 VISU::Prs3d_i* aPrs = it.key();
496 Offset& aOffs = myOffsets[it.value()];
497 if (VISU_Actor* anActor = VISU::FindActor(myViewWindow, aPrs))
498 anActor->SetPosition(aOffs.myOffset);
500 if (mySaveChk->isChecked())
501 aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
503 QMap<VISU::PointMap3d_i*, int>::Iterator itt;
504 for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt) {
505 VISU::PointMap3d_i* aPrs = itt.key();
506 Offset& aOffs = myOffsets[itt.value()];
507 if (VISU_ActorBase* anActor = VISU::FindActorBase(myViewWindow, aPrs))
508 anActor->SetPosition(aOffs.myOffset);
510 if (mySaveChk->isChecked())
511 aPrs->SetOffset(aOffs.myOffset[0],aOffs.myOffset[1],aOffs.myOffset[2]);
514 vtkFloatingPointType aDist = 0;
515 vtkFloatingPointType aShift = 0;
516 vtkFloatingPointType aPrevDist = 0;
517 vtkFloatingPointType aPrevShift = 0;
519 QMap<VISU::Prs3d_i*, int>::Iterator it;
520 for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it, i++) {
521 VISU::Prs3d_i* aPrs = it.key();
522 if (VISU_Actor* aActor = VISU::FindActor(myViewWindow, aPrs)) {
523 int aAxis = getAxis();
525 vtkFloatingPointType aZeroOffset[3];
526 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
527 aActor->SetPosition(aZeroOffset);
528 aActor->GetMapper()->Update();
530 vtkFloatingPointType aBounds[6];
531 aActor->GetBounds(aBounds);
534 aDist = fabs(aBounds[1] - aBounds[0]);
537 aDist = fabs(aBounds[3] - aBounds[2]);
540 aDist = fabs(aBounds[5] - aBounds[4]);
542 vtkFloatingPointType aOffset[3];
543 aOffset[0] = aOffset[1] = aOffset[2] = 0;
545 (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
548 vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
550 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
551 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
552 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
553 vtkFloatingPointType max = (dx > dy) ? dx : dy;
554 max = (dz > max) ? dz : max;
558 // set base distance between centers of bounding boxes
559 // to minimal (but big enough) size of current bounding box
560 if (dx < max) dx = FLT_MAX;
561 if (dy < max) dy = FLT_MAX;
562 if (dz < max) dz = FLT_MAX;
564 aCCDist = (dx < dy) ? dx : dy;
565 aCCDist = (dz < aCCDist) ? dz : aCCDist;
568 //-------------------------------->
572 // .--------------. .------.
573 //----------->| | | |
574 // aPrevShift '--------------' '------'
579 // (aDist + aPrevDist) * getDistance() / 2
581 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
584 aOffset[aAxis] += aShift;
585 aActor->SetPosition(aOffset);
587 if (mySaveChk->isChecked())
588 aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
593 } // end of myPrsMap loop
594 // Loop in PointMap3D the same as previous loop
595 QMap<VISU::PointMap3d_i*, int>::Iterator itt;
596 for (itt = myPointMapPrsMap.begin(); itt != myPointMapPrsMap.end(); ++itt, i++) {
597 VISU::PointMap3d_i* aPrs = itt.key();
598 if (VISU_ActorBase* aActor = VISU::FindActorBase(myViewWindow, aPrs)) {
599 int aAxis = getAxis();
601 vtkFloatingPointType aZeroOffset[3];
602 aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
603 aActor->SetPosition(aZeroOffset);
604 aActor->GetMapper()->Update();
606 vtkFloatingPointType aBounds[6];
607 aActor->GetBounds(aBounds);
610 aDist = fabs(aBounds[1] - aBounds[0]);
613 aDist = fabs(aBounds[3] - aBounds[2]);
616 aDist = fabs(aBounds[5] - aBounds[4]);
618 vtkFloatingPointType aOffset[3];
619 aOffset[0] = aOffset[1] = aOffset[2] = 0;
621 (aBounds[2*aAxis+1] < aBounds[2*aAxis]) ? -aBounds[2*aAxis+1] : -aBounds[2*aAxis];
624 vtkFloatingPointType aCCDist = (aDist + aPrevDist) / 2.0;
626 vtkFloatingPointType dx = fabs(aBounds[1] - aBounds[0]);
627 vtkFloatingPointType dy = fabs(aBounds[3] - aBounds[2]);
628 vtkFloatingPointType dz = fabs(aBounds[5] - aBounds[4]);
629 vtkFloatingPointType max = (dx > dy) ? dx : dy;
630 max = (dz > max) ? dz : max;
634 // set base distance between centers of bounding boxes
635 // to minimal (but big enough) size of current bounding box
636 if (dx < max) dx = FLT_MAX;
637 if (dy < max) dy = FLT_MAX;
638 if (dz < max) dz = FLT_MAX;
640 aCCDist = (dx < dy) ? dx : dy;
641 aCCDist = (dz < aCCDist) ? dz : aCCDist;
643 aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
646 aOffset[aAxis] += aShift;
647 aActor->SetPosition(aOffset);
649 if (mySaveChk->isChecked())
650 aPrs->SetOffset(aOffset[0],aOffset[1],aOffset[2]);
655 } // end of myPointMapPrsMap loop
657 myViewWindow->getRenderer()->ResetCameraClippingRange();
658 myViewWindow->Repaint();
662 //------------------------------------------------------------------------
663 //------------------------------------------------------------------------
665 class SetupDlg::LineEdit : public QLineEdit
668 LineEdit( QWidget* p = 0 ) : QLineEdit( p ) {}
669 virtual ~LineEdit() {}
672 void focusOutEvent( QFocusEvent* e )
674 QLineEdit::focusOutEvent( e );
676 if ( text().isEmpty() )
677 emit editingFinished();
679 void keyPressEvent( QKeyEvent* e )
681 QLineEdit::keyPressEvent( e );
683 if ( text().isEmpty() && e->key() == Qt::Key_Return )
684 emit returnPressed();
689 //------------------------------------------------------------------------
690 //------------------------------------------------------------------------
692 SetupDlg::SetupDlg (QWidget* theParent,
694 VISU_TimeAnimation* theAnimator) :
696 Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
697 myAnimator(theAnimator),
699 myIsRegenerate( false )
702 setWindowTitle("Setup Animation");
703 setSizeGripEnabled( TRUE );
705 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
706 aMainLayout->setMargin( 7 );
707 aMainLayout->setSpacing(5);
709 // Range of time stamps
710 myUseRangeBox = new QGroupBox("Use range of time stamps", this);
711 myUseRangeBox->setCheckable( true );
712 myUseRangeBox->setChecked(myAnimator->isRangeDefined());
714 QHBoxLayout* aRangeLayout = new QHBoxLayout( myUseRangeBox );
715 aRangeLayout->setMargin( 11 );
716 aRangeLayout->setSpacing( 6 );
718 double aMaxTime = myAnimator->getMaxTime();
719 double aMinTime = myAnimator->getMinTime();
721 if( myAnimator->getNbFields() > 0 ) {
722 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
723 aStep = (aMaxTime - aMinTime) / (myAnimator->getFieldData(0).myNbTimes - 1);
724 else { // successive animation mode
725 std::pair<int,long> aLastFieldFrame(myAnimator->getNbFields() - 1,
726 myAnimator->getFieldData(myAnimator->getNbFields() - 1).myNbTimes - 1);
727 aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
731 QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
732 aRangeLayout->addWidget(aMinLbl);
733 //myMinVal = new SalomeApp_DoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
734 //VISU::initSpinBox( myMinVal, aMinTime, aMaxTime, aStep, "visual_data_precision" );
735 myMinVal = new LineEdit( myUseRangeBox );
736 myMinVal->setValidator( new QDoubleValidator( myMinVal ) );
737 if ( myUseRangeBox->isChecked() )
738 myMinVal->setText( QString::number( myAnimator->getMinRange() ) );
740 myMinVal->setText( QString::number( aMinTime ) );
742 // connect(myMinVal, SIGNAL( valueChanged(double)),
743 // this, SLOT( onMinValue(double) ));
744 connect( myMinVal, SIGNAL( returnPressed() ), this, SLOT( onMinValue() ) );
745 connect( myMinVal, SIGNAL( editingFinished() ), this, SLOT( onMinValue() ) );
746 // connect( myMinVal, SIGNAL( textChanged(const QString&)),
747 // this, SLOT( onMinValueEdit(const QString&) ));
748 aRangeLayout->addWidget(myMinVal);
750 QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
751 aRangeLayout->addWidget(aMaxLbl);
752 //myMaxVal = new SalomeApp_DoubleSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
753 //VISU::initSpinBox( myMaxVal, aMinTime, aMaxTime, aStep, "visual_data_precision" );
754 myMaxVal = new LineEdit( myUseRangeBox );
755 myMaxVal->setValidator( new QDoubleValidator( myMaxVal ) );
756 if ( myUseRangeBox->isChecked() )
757 myMaxVal->setText( QString::number( myAnimator->getMaxRange() ) );
759 myMaxVal->setText( QString::number( aMaxTime ) );
761 // connect(myMaxVal, SIGNAL( valueChanged(double)),
762 // this, SLOT( onMaxValue(double) ));
763 connect( myMaxVal, SIGNAL( returnPressed() ), this, SLOT( onMaxValue() ) );
764 connect( myMaxVal, SIGNAL( editingFinished() ), this, SLOT( onMaxValue() ) );
765 // connect(myMaxVal, SIGNAL( textChanged(const QString&)),
766 // this, SLOT( onMaxValueEdit(const QString&) ));
767 aRangeLayout->addWidget(myMaxVal);
769 connect(myUseRangeBox, SIGNAL( toggled(bool)),
770 this, SLOT( onRangeCheck(bool) ));
772 aMainLayout->addWidget(myUseRangeBox);
774 // Sequence of time stamps
775 myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
776 myUseSequenceBox->setCheckable( true );
777 myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
779 QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox );
780 aUseSequenceLayout->setAlignment( Qt::AlignTop );
781 aUseSequenceLayout->setSpacing( 6 );
782 aUseSequenceLayout->setMargin( 11 );
784 QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
785 myIndices = new QLineEdit( myUseSequenceBox );
787 myValues = new QListWidget( myUseSequenceBox );
788 myValues->setSelectionMode( QAbstractItemView::ExtendedSelection );
790 connect(myIndices, SIGNAL( textChanged(const QString&)),
791 this, SLOT( onIndicesChanged(const QString&) ));
793 connect(myValues, SIGNAL( itemSelectionChanged() ),
794 this, SLOT( onValuesChanged() ) );
796 connect(myUseSequenceBox, SIGNAL( toggled(bool)),
797 this, SLOT( onSequenceCheck(bool) ));
799 aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
800 aUseSequenceLayout->addWidget( myIndices, 0, 1 );
801 aUseSequenceLayout->addWidget( myValues, 1, 1, 1, 2 );
803 aMainLayout->addWidget(myUseSequenceBox);
805 // Fields and Properties
806 QWidget* aPropFrame = new QWidget(this);
807 QHBoxLayout* aHPropLayout = new QHBoxLayout( aPropFrame );
808 aHPropLayout->setSpacing(5);
809 aHPropLayout->setMargin(0);
811 QGroupBox* aNamesBox = new QGroupBox("Fields",aPropFrame);
812 aHPropLayout->addWidget( aNamesBox );
813 QVBoxLayout* aVBoxLayout = new QVBoxLayout( aNamesBox );
815 myFieldLst = new QListWidget(aNamesBox);
816 aVBoxLayout->addWidget( myFieldLst );
817 QStringList aFieldNames;
818 // Find names of fields
819 for (int i = 0; i < myAnimator->getNbFields(); i++) {
820 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
821 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
822 QString aFieldName(aRestoringMap["myName"]);
823 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL )
824 aFieldNames.append(aFieldName);
825 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
826 _PTR(SObject) aSObject = aSO->GetFather()->GetFather()->GetFather();
827 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
828 QString aFileName(aRestoringMap["myInitFileName"]);
829 aFileName = aFileName.right(aFileName.length() - (aFileName.lastIndexOf("/") + 1));
830 aFieldNames.append(aFileName + QString(" : ") + aFieldName);
833 myFieldLst->addItems(aFieldNames);
835 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
836 myFieldLst->setCurrentRow(0);
837 connect( myFieldLst, SIGNAL( currentRowChanged(int) ),
838 this, SLOT( onFieldChange(int) ) );
840 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
841 myFieldLst->setSelectionMode(QAbstractItemView::NoSelection);
843 QWidget* aSetupBox = new QWidget(aPropFrame);
844 aHPropLayout->addWidget( aSetupBox );
845 aVBoxLayout = new QVBoxLayout( aSetupBox );
846 aVBoxLayout->setSpacing(5);
847 aVBoxLayout->setMargin(0);
849 QGroupBox* aPropBox = new QGroupBox("Properties", aSetupBox);
850 aVBoxLayout->addWidget( aPropBox );
851 QVBoxLayout* aPropVBLay = new QVBoxLayout( aPropBox );
853 //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
854 myTypeCombo = new QComboBox(aPropBox);
855 aPropVBLay->addWidget( myTypeCombo );
856 connect( myTypeCombo, SIGNAL( activated(int) ),
857 this, SLOT( onTypeChanged(int) ) );
859 // QPushButton* aBarBtn = new QPushButton("Scalar Bar...", aPropBox);
860 //connect( aBarBtn, SIGNAL( clicked() ),
861 // this, SLOT( onScalarBarDlg() ) );
863 myPropBtn = new QPushButton("Properties...", aPropBox);
864 myPropBtn->setAutoDefault( false );
865 aPropVBLay->addWidget( myPropBtn );
866 // myPropBtn->setEnabled(myAnimator->getFieldData(0).myPrsType != VISU::TSCALARMAP);
867 connect( myPropBtn, SIGNAL( clicked() ),
868 this, SLOT( onPreferencesDlg() ) );
870 if (myAnimator->getNbFields() > 1 ) {
871 if( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) {
872 myArrangeBtn = new QPushButton("Arrange...", aSetupBox);
873 aVBoxLayout->addWidget( myArrangeBtn );
874 connect( myArrangeBtn, SIGNAL( clicked() ), this, SLOT( onArrangeDlg() ) );
878 aMainLayout->addWidget(aPropFrame);
880 QWidget* aBtnBox = new QWidget(this);
881 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
882 aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
883 // aBtnLayout->addStretch();
885 QPushButton* closeBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
886 closeBtn->setAutoDefault( false );
887 aBtnLayout->addStretch();
888 aBtnLayout->addWidget( closeBtn );
889 connect( closeBtn, SIGNAL( clicked() ), this, SLOT( onClose() ) );
891 aMainLayout->addWidget( aBtnBox );
894 //------------------------------------------------------------------------
895 void SetupDlg::initialize()
899 _PTR(Study) aStudy = myAnimator->getStudy();
901 if( myAnimator->getNbFields() == 0 )
904 FieldData& aData = myAnimator->getFieldData( 0 );
905 _PTR(SObject) aField = aData.myField;
910 _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
911 anIter->Next(); // First is reference on support
912 for(int index = 1; anIter->More(); anIter->Next(), index++)
914 double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
915 QString itemText = QString("[%1] - %2").arg( index ).arg( aTime );
917 myValues->addItem( itemText );
920 QString anIndices( myAnimator->getAnimationSequence() );
921 myIndices->setText( anIndices );
924 //------------------------------------------------------------------------
926 TSCALARMAP_ITEM = 0, // VISU::TSCALARMAP
927 TISOSURFACES_ITEM = 1, // VISU::TISOSURFACES
928 TCUTPLANES_ITEM = 2, // VISU::TCUTPLANES
929 TCUTLINES_ITEM = 3, // VISU::TCUTLINES
930 TCUTSEGMENT_ITEM = 4, // VISU::TCUTSEGMENT
931 TPLOT3D_ITEM = 5, // VISU::TPLOT3D
932 TDEFORMEDSHAPE_ITEM = 6, // VISU::TDEFORMEDSHAPE
933 TVECTORS_ITEM = 7, // VISU::TVECTORS
934 TSTREAMLINES_ITEM = 8, // VISU::TSTREAMLINES
935 TGAUSSPOINTS_ITEM = 9, // VISU::TGAUSSPOINTS
936 TDEFORMEDSHAPEANDSCALARMAP_ITEM = 10 // VISU::TDEFORMEDSHAPEANDSCALARMAP
939 //------------------------------------------------------------------------
940 void SetupDlg::onClose()
942 if ( !myUseRangeBox->isChecked() )
943 myAnimator->setAnimationRange( 0, 0 );
946 double min = myMinVal->text().toDouble();
947 double max = myMaxVal->text().toDouble();
948 myAnimator->setAnimationRange( qMin( min, max ), qMax( min, max ) );
951 if ( !myUseSequenceBox->isChecked() )
952 myAnimator->setAnimationSequence( 0 );
957 //------------------------------------------------------------------------
958 void SetupDlg::onFieldChange (int theIndex)
960 myTypeCombo->clear();
961 myTypeId2ComboId.clear();
962 myComboId2TypeId.clear();
964 if( myAnimator->getNbFields() == 0 )
967 // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
968 myTypeCombo->addItem("Scalar Map"); // item 0
969 myTypeId2ComboId[TSCALARMAP_ITEM] = myComboId2TypeId.size();
970 myComboId2TypeId.push_back(TSCALARMAP_ITEM);;
972 myTypeCombo->addItem("Iso Surfaces"); // item 1
973 myTypeId2ComboId[TISOSURFACES_ITEM] = myComboId2TypeId.size();
974 myComboId2TypeId.push_back(TISOSURFACES_ITEM);;
976 myTypeCombo->addItem("Cut Planes"); // item 2
977 myTypeId2ComboId[TCUTPLANES_ITEM] = myComboId2TypeId.size();
978 myComboId2TypeId.push_back(TCUTPLANES_ITEM);;
980 myTypeCombo->addItem("Cut Lines"); // item 3
981 myTypeId2ComboId[TCUTLINES_ITEM] = myComboId2TypeId.size();
982 myComboId2TypeId.push_back(TCUTLINES_ITEM);;
984 myTypeCombo->addItem("Cut Segment"); // item 4
985 myTypeId2ComboId[TCUTSEGMENT_ITEM] = myComboId2TypeId.size();
986 myComboId2TypeId.push_back(TCUTSEGMENT_ITEM);;
988 myTypeCombo->addItem("Plot 3D"); // item 5
989 myTypeId2ComboId[TPLOT3D_ITEM] = myComboId2TypeId.size();
990 myComboId2TypeId.push_back(TPLOT3D_ITEM);;
992 bool anEnableItems = false;
993 bool anEnableGP = false;
994 VISU::VISUType aPrsType;
995 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) { // parallel animation mode
997 FieldData& aData = myAnimator->getFieldData(theIndex);
998 _PTR(SObject) aSObject = aData.myField;
999 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSObject);
1000 long aNumComp = aRestoringMap["myNumComponent"].toLong();
1001 anEnableItems = (aNumComp > 1);
1003 long anEntityId = aRestoringMap["myEntityId"].toLong();
1004 anEnableGP = (anEntityId == VISU::CELL);
1006 aPrsType = aData.myPrsType;
1009 else if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) { // successive animation mode
1011 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1012 _PTR(SObject) aSO = myAnimator->getFieldData(i).myField;
1013 VISU::Storable::TRestoringMap aRestoringMap = VISU::Storable::GetStorableMap(aSO);
1014 long aNumComp = aRestoringMap["myNumComponent"].toLong();
1015 anEnableItems = (aNumComp > 1);
1017 long anEntityId = aRestoringMap["myEntityId"].toLong();
1018 anEnableGP = (anEntityId == VISU::CELL);
1020 if ( !anEnableItems && !anEnableGP ) break;
1023 aPrsType = myAnimator->getFieldData(0).myPrsType;
1027 if (anEnableItems) {
1028 myTypeCombo->addItem("Deformed Shape"); // item 6
1029 myTypeId2ComboId[TDEFORMEDSHAPE_ITEM] = myComboId2TypeId.size();
1030 myComboId2TypeId.push_back(TDEFORMEDSHAPE_ITEM);;
1032 myTypeCombo->addItem("Vectors"); // item 7
1033 myTypeId2ComboId[TVECTORS_ITEM] = myComboId2TypeId.size();
1034 myComboId2TypeId.push_back(TVECTORS_ITEM);;
1036 myTypeCombo->addItem("Stream Lines"); // item 8
1037 myTypeId2ComboId[TSTREAMLINES_ITEM] = myComboId2TypeId.size();
1038 myComboId2TypeId.push_back(TSTREAMLINES_ITEM);;
1040 myTypeCombo->addItem("Deformed shape and Scalar map"); // item 10
1041 myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM] = myComboId2TypeId.size();
1042 myComboId2TypeId.push_back(TDEFORMEDSHAPEANDSCALARMAP_ITEM);;
1046 myTypeCombo->addItem("Gauss Points"); // item 9
1047 myTypeId2ComboId[TGAUSSPOINTS_ITEM] = myComboId2TypeId.size();
1048 myComboId2TypeId.push_back(TGAUSSPOINTS_ITEM);;
1052 case VISU::TSCALARMAP: //Scalar Map
1053 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSCALARMAP_ITEM]);
1055 case VISU::TISOSURFACES: //Iso Surfaces
1056 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TISOSURFACES_ITEM]);
1058 case VISU::TCUTPLANES: //Cut Planes
1059 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTPLANES_ITEM]);
1061 case VISU::TCUTLINES: //Cut Lines
1062 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTLINES_ITEM]);
1064 case VISU::TCUTSEGMENT: //Cut Segment
1065 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TCUTSEGMENT_ITEM]);
1067 case VISU::TPLOT3D: //Plot 3D
1068 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TPLOT3D_ITEM]);
1070 case VISU::TDEFORMEDSHAPE: //Deformed Shape
1071 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPE_ITEM]);
1073 case VISU::TSCALARMAPONDEFORMEDSHAPE: //Scalar Map on Deformed Shape
1074 case VISU::TDEFORMEDSHAPEANDSCALARMAP:
1075 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TDEFORMEDSHAPEANDSCALARMAP_ITEM]);
1077 case VISU::TVECTORS: //Vectors
1078 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TVECTORS_ITEM]);
1080 case VISU::TSTREAMLINES: //Stream Lines
1081 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TSTREAMLINES_ITEM]);
1083 case VISU::TGAUSSPOINTS: //Gauss Points
1084 myTypeCombo->setCurrentIndex(myTypeId2ComboId[TGAUSSPOINTS_ITEM]);
1087 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1090 //------------------------------------------------------------------------
1091 void SetupDlg::onTypeChanged (int theIndex)
1093 int aType = myComboId2TypeId[theIndex];
1095 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1096 FieldData& aData = ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) ?
1097 myAnimator->getFieldData(myFieldLst->currentRow()) :
1098 myAnimator->getFieldData(i);
1101 case TSCALARMAP_ITEM: //Scalar Map
1102 aData.myPrsType = VISU::TSCALARMAP;
1104 case TISOSURFACES_ITEM: //Iso Surfaces
1105 aData.myPrsType = VISU::TISOSURFACES;
1107 case TCUTPLANES_ITEM: //Cut Planes
1108 aData.myPrsType = VISU::TCUTPLANES;
1110 case TCUTLINES_ITEM: //Cut Lines
1111 aData.myPrsType = VISU::TCUTLINES;
1113 case TCUTSEGMENT_ITEM: //Cut Segment
1114 aData.myPrsType = VISU::TCUTSEGMENT;
1116 case TPLOT3D_ITEM: //Plot 3D
1117 aData.myPrsType = VISU::TPLOT3D;
1119 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1120 aData.myPrsType = VISU::TDEFORMEDSHAPE;
1122 case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1123 aData.myPrsType = VISU::TDEFORMEDSHAPEANDSCALARMAP;
1125 case TVECTORS_ITEM: //Vectors
1126 aData.myPrsType = VISU::TVECTORS;
1128 case TSTREAMLINES_ITEM: //Stream Lines
1129 aData.myPrsType = VISU::TSTREAMLINES;
1131 case TGAUSSPOINTS_ITEM: //Gauss Points
1132 aData.myPrsType = VISU::TGAUSSPOINTS;
1135 myAnimator->clearData(aData);
1137 if ( myAnimator->getAnimationMode() == VISU::Animation::PARALLEL ) // parallel animation mode
1140 //myPropBtn->setEnabled(aData.myPrsType != VISU::TSCALARMAP);
1141 //myAnimator->generatePresentations(myFieldLst->currentItem());
1145 //------------------------------------------------------------------------
1148 template<class TPrs3d, class TDialog>
1150 EditPrs(VisuGUI* theModule,
1152 VISU_TimeAnimation* theAnimator)
1154 TDialog* aDlg = new TDialog(theModule);
1155 TPrs3d* aPrs3d = dynamic_cast<TPrs3d*>(theData.myPrs[0]);
1156 aDlg->initFromPrsObject(aPrs3d, true);
1157 if (aDlg->exec() && aDlg->storeToPrsObject(dynamic_cast<TPrs3d*>(aPrs3d))) {
1159 for (long aFrameId = 1; aFrameId < theData.myNbFrames; aFrameId++){
1160 VISU::ColoredPrs3d_i* aColoredPrs3d = theData.myPrs[aFrameId];
1161 aColoredPrs3d->SameAs(aPrs3d);
1162 // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
1163 // special case for the "Gauss Points" presentation,
1164 // update the LookupTable in the mapper, after assign properties of the presentation
1165 // using SameAs(...) method.
1166 if(theData.myPrsType == VISU::TGAUSSPOINTS) {
1167 aColoredPrs3d->UpdateMapperLookupTable();
1171 if ( theAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1172 for (int aFieldId = 1; aFieldId < theAnimator->getNbFields(); aFieldId++) {
1173 FieldData& aFieldData = theAnimator->getFieldData(aFieldId);
1174 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1175 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1176 std::string aTitle = aColoredPrs3d->GetCTitle();
1177 aColoredPrs3d->SameAs(aPrs3d);
1178 // rnv: fix for the 20870: EDF 1410 VISU: Anomaly in the Gauss point representation.
1179 // special case for the "Gauss Points" presentation,
1180 // update the LookupTable in the mapper, after assign properties of the presentation
1181 // using SameAs(...) method.
1182 if(theData.myPrsType == VISU::TGAUSSPOINTS) {
1183 aColoredPrs3d->UpdateMapperLookupTable();
1186 aColoredPrs3d->SetTitle(aTitle.c_str());
1196 void SetupDlg::onPreferencesDlg()
1198 if(myAnimator->getNbFields() == 0){
1199 SUIT_MessageBox::warning(this,
1201 VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1206 SUIT_OverrideCursor c;
1208 VISU::Animation::AnimationMode aMode = myAnimator->getAnimationMode();
1209 int aRefFieldId = ( aMode == VISU::Animation::PARALLEL ) ? myFieldLst->currentRow() : 0;
1210 FieldData& aData = myAnimator->getFieldData(aRefFieldId);
1211 if (aData.myPrs.empty())
1212 myAnimator->generatePresentations(aRefFieldId);
1214 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1215 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1216 if ( i != aRefFieldId && myAnimator->getFieldData(i).myPrs.empty() )
1217 myAnimator->generatePresentations(i);
1221 if(!aData.myNbFrames || aData.myPrs.empty() || !aData.myPrs[0]){
1222 QApplication::restoreOverrideCursor();
1223 SUIT_MessageBox::warning(this,
1225 VisuGUI_TimeAnimationDlg::tr("MSG_NO_ANIMATIONDATA"),
1230 int aType = myComboId2TypeId[myTypeCombo->currentIndex()];
1232 case TSCALARMAP_ITEM: //Scalar Map
1234 EditPrs<VISU::ScalarMap_i,VisuGUI_ScalarBarDlg>(myModule,aData,myAnimator);
1236 case TISOSURFACES_ITEM: //Iso Surfaces
1238 EditPrs<VISU::IsoSurfaces_i,VisuGUI_IsoSurfacesDlg>(myModule,aData,myAnimator);
1240 case TCUTPLANES_ITEM: //Cut Planes
1242 EditPrs<VISU::CutPlanes_i,VisuGUI_CutPlanesDlg>(myModule,aData,myAnimator);
1244 case TCUTLINES_ITEM: //Cut Lines
1246 EditPrs<VISU::CutLines_i,VisuGUI_CutLinesDlg>(myModule,aData,myAnimator);
1248 case TCUTSEGMENT_ITEM: //Cut Segment
1250 EditPrs<VISU::CutSegment_i,VisuGUI_CutSegmentDlg>(myModule,aData,myAnimator);
1252 case TPLOT3D_ITEM: //Plot 3D
1254 EditPrs<VISU::Plot3D_i,VisuGUI_Plot3DDlg>(myModule,aData,myAnimator);
1256 case TDEFORMEDSHAPE_ITEM: //Deformed Shape
1258 EditPrs<VISU::DeformedShape_i,VisuGUI_DeformedShapeDlg>(myModule,aData,myAnimator);
1260 case TDEFORMEDSHAPEANDSCALARMAP_ITEM: //Scalar Map on Deformed Shape
1263 typedef VisuGUI_DeformedShapeAndScalarMapDlg DLG;
1264 typedef VISU::DeformedShapeAndScalarMap_i TYPE;
1265 DLG* aDlg = new DLG (myModule);
1266 TYPE* aPrs3d = dynamic_cast<TYPE*>(aData.myPrs[0]);
1267 aDlg->initFromPrsObject(aPrs3d, true);
1268 if (aDlg->exec() && aDlg->storeToPrsObject(aData.myPrs[0])) {
1269 for (long aFrameId = 1; aFrameId < aData.myNbFrames; aFrameId++){
1270 TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aData.myPrs[aFrameId]);
1271 //Set correct time stamp number
1272 int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1273 aDeformedPrs3d->SameAs(aPrs3d);
1274 aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1275 aDeformedPrs3d->GetScalarFieldName(),
1280 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1281 for (int aFieldId = 1; aFieldId < myAnimator->getNbFields(); aFieldId++) {
1282 FieldData& aFieldData = myAnimator->getFieldData(aFieldId);
1283 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1284 TYPE* aDeformedPrs3d = dynamic_cast<TYPE*>(aFieldData.myPrs[aFrameId]);
1285 std::string aTitle = aDeformedPrs3d->GetCTitle();
1286 //Set correct time stamp number
1287 int aTimeStampNum = aDeformedPrs3d->GetScalarTimeStampNumber();
1288 aDeformedPrs3d->SameAs(aPrs3d);
1289 aDeformedPrs3d->SetTitle(aTitle.c_str());
1290 aDeformedPrs3d->SetScalarField(aDeformedPrs3d->GetScalarEntity(),
1291 aDeformedPrs3d->GetScalarFieldName(),
1301 case TVECTORS_ITEM: //Vectors
1303 EditPrs<VISU::Vectors_i,VisuGUI_VectorsDlg>(myModule,aData,myAnimator);
1305 case TSTREAMLINES_ITEM: //Stream Lines
1307 EditPrs<VISU::StreamLines_i,VisuGUI_StreamLinesDlg>(myModule,aData,myAnimator);
1309 case TGAUSSPOINTS_ITEM: //Gauss Points
1311 EditPrs<VISU::GaussPoints_i,VisuGUI_GaussPointsDlg>(myModule,aData,myAnimator);
1317 //------------------------------------------------------------------------
1318 void SetupDlg::onArrangeDlg()
1320 ArrangeDlg aDlg(this, myAnimator);
1324 //------------------------------------------------------------------------
1325 void SetupDlg::onRangeCheck (bool theCheck)
1329 myUseSequenceBox->blockSignals( true );
1330 myUseSequenceBox->setChecked( false );
1331 myUseSequenceBox->blockSignals( false );
1335 myAnimator->setAnimationRange(0, 0);
1337 myAnimator->setAnimationRange(myMinVal->text().toDouble(), myMaxVal->text().toDouble());
1339 setIsRegenerate( true );
1342 //------------------------------------------------------------------------
1343 void SetupDlg::onMinValue()
1345 double aVal = myMinVal->text().toDouble();
1346 aVal = qMax( qMin( aVal, myAnimator->getMaxRange() ), myAnimator->getMinTime() );
1347 myAnimator->setAnimationRange( aVal, myAnimator->getMaxRange() );
1348 myMinVal->setText( QString::number( aVal ) );
1349 // myMinVal->setFocus();
1351 setIsRegenerate( true );
1354 //------------------------------------------------------------------------
1355 void SetupDlg::onMaxValue()
1357 double aVal = myMaxVal->text().toDouble();
1358 aVal = qMin( qMax( aVal, myAnimator->getMinRange() ), myAnimator->getMaxTime() );
1359 myAnimator->setAnimationRange( myAnimator->getMinRange(), aVal );
1360 myMaxVal->setText( QString::number( aVal ) );
1361 // myMaxVal->setFocus();
1363 setIsRegenerate( true );
1366 //------------------------------------------------------------------------
1367 void SetupDlg::onMinValueEdit (const QString& theVal)
1369 double aVal = theVal.toDouble();
1370 if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())){
1371 myMinVal->setText( QString::number(myAnimator->getMinTime()) );
1372 myMinVal->setFocus();
1377 //------------------------------------------------------------------------
1378 void SetupDlg::onMaxValueEdit (const QString& theVal)
1380 double aVal = theVal.toDouble();
1381 if ((aVal > myAnimator->getMaxRange()) || (aVal < myAnimator->getMinRange())) {
1382 myMaxVal->setText( QString::number(myAnimator->getMaxTime()) );
1383 myMaxVal->setFocus();
1387 //------------------------------------------------------------------------
1388 void SetupDlg::onSequenceCheck( bool theCheck )
1392 myUseRangeBox->blockSignals( true );
1393 myUseRangeBox->setChecked( false );
1394 myUseRangeBox->blockSignals( false );
1397 QString anIndices = myIndices->text();
1398 myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1400 setIsRegenerate( true );
1403 //------------------------------------------------------------------------
1404 void SetupDlg::onIndicesChanged( const QString& theIndices )
1406 bool aCorrect = true;
1407 int aLimit = myValues->count();
1409 QList<long> anIndicesList;
1410 aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
1412 myValues->blockSignals( true );
1413 myValues->clearSelection();
1415 QList<long>::iterator indIt = anIndicesList.begin();
1416 QList<long>::iterator indItEnd = anIndicesList.end();
1417 for( int i = 0; indIt != indItEnd; ++indIt, i++ )
1419 long anIndex = *indIt;
1420 if( anIndex < 1 || anIndex > aLimit )
1423 myValues->clearSelection();
1426 myValues->item( anIndex-1 )->setSelected( true );
1429 myValues->blockSignals( false );
1431 QPalette palette = myIndices->palette();
1435 palette.setColor(myIndices->foregroundRole(), Qt::red);
1436 myIndices->setPalette(palette);
1440 palette.setColor(myIndices->foregroundRole(), Qt::black);
1441 myIndices->setPalette(palette);
1443 myAnimator->setAnimationSequence( theIndices.toLatin1().data() );
1445 setIsRegenerate( true );
1448 //------------------------------------------------------------------------
1449 void SetupDlg::onValuesChanged()
1451 int aLimit = myValues->count();
1455 for( int i = 0; i < aLimit; i++ )
1457 if( !myValues->item( i )->isSelected() )
1460 QString aString = QString::number( i+1 );
1462 bool aPrevSelected = i != 0 && myValues->item( i-1 )->isSelected();
1463 bool aNextSelected = i != aLimit - 1 && myValues->item( i+1 )->isSelected();
1479 anIndices += aString;
1482 if( anIndices.right( 1 ) == "," )
1483 anIndices.truncate( anIndices.length() - 1 );
1485 myIndices->blockSignals( true );
1487 QPalette palette = myIndices->palette();
1488 palette.setColor(myIndices->foregroundRole(), Qt::black);
1489 myIndices->setPalette(palette);
1491 myIndices->setText( anIndices );
1492 myIndices->blockSignals( false );
1494 myAnimator->setAnimationSequence( anIndices.toLatin1().data() );
1496 setIsRegenerate( true );
1499 //------------------------------------------------------------------------
1500 static const char * firstIco[] = {
1516 static const char * lastIco[] = {
1532 static const char * leftIco[] = {
1547 static const char * playIco[] = {
1566 static QPixmap MYplayPixmap(playIco);
1569 static const char * rightIco[] = {
1585 static const char * pauseIco[] = {
1604 static QPixmap MYpausePixmap(pauseIco);
1607 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule,
1608 _PTR(Study) theStudy,
1609 VISU::Animation::AnimationMode theMode) :
1610 QDialog(VISU::GetDesktop(theModule),
1611 Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
1612 myModule(theModule),
1615 setAttribute( Qt::WA_DeleteOnClose, true );
1617 if ( theMode == VISU::Animation::PARALLEL )
1618 setWindowTitle(tr("PARALLEL_ANIMATION"));
1620 setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
1621 setSizeGripEnabled( TRUE );
1623 myAnimator = new VISU_TimeAnimation (theStudy);
1624 myAnimator->setViewer(VISU::GetActiveViewWindow<SVTK_ViewWindow>(theModule));
1625 connect(myAnimator, SIGNAL(frameChanged(long, double)), this, SLOT(onExecution(long, double)));
1626 connect(myAnimator, SIGNAL(stopped()), this, SLOT(onStop()));
1627 myAnimator->setAnimationMode(theMode);
1629 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
1630 aMainLayout->setMargin( 7 );
1631 aMainLayout->setSpacing(5);
1633 mySetupBtn = new QPushButton("Setup Animation...", this);
1634 connect( mySetupBtn, SIGNAL( clicked() ),
1635 this, SLOT( onSetupDlg() ) );
1636 aMainLayout->addWidget(mySetupBtn);
1638 myGenBtn = new QPushButton("Generate frames", this);
1639 connect( myGenBtn, SIGNAL( clicked() ),
1640 this, SLOT( createFrames() ) );
1641 aMainLayout->addWidget(myGenBtn);
1643 myPlayFrame = new QFrame(this);
1644 myPlayFrame->setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
1645 myPlayFrame->setLineWidth( 1 );
1648 // --- Play controls ---
1649 QGridLayout* TopLayout = new QGridLayout( myPlayFrame );
1650 TopLayout->setSpacing( 6 );
1651 TopLayout->setMargin( 11 );
1653 myTimeLbl = new QLabel("0", myPlayFrame);
1654 TopLayout->addWidget(myTimeLbl, 0, 0, 1, 3, Qt::AlignHCenter);
1656 mySlider = new QSlider( myPlayFrame);
1657 mySlider->setOrientation(Qt::Horizontal);
1658 mySlider->setMinimum(0);
1659 mySlider->setMaximum(3);
1660 mySlider->setTickInterval(1);
1661 //mySlider->setTickmarks(QSlider::Below);
1662 mySlider->setTracking(false);
1663 connect( mySlider, SIGNAL( sliderMoved(int) ),
1664 this, SLOT( onWindowChanged(int) ) );
1665 TopLayout->addWidget(mySlider, 1, 0, 1, 3);
1667 myPlayBtn = new QPushButton(myPlayFrame);
1668 myPlayBtn->setIcon(MYplayPixmap);
1669 myPlayBtn->setCheckable(true);
1670 connect( myPlayBtn, SIGNAL( clicked() ),
1671 this, SLOT( onPlayPressed() ) );
1672 TopLayout->addWidget(myPlayBtn, 2, 0, 1, 2);
1674 QPushButton* aBackBtn = new QPushButton(myPlayFrame);
1675 aBackBtn->setIcon(QPixmap(leftIco));
1676 connect( aBackBtn, SIGNAL( clicked() ),
1677 this, SLOT( onBackPressed() ) );
1678 TopLayout->addWidget(aBackBtn, 3, 0);
1680 QPushButton* aForvardBtn = new QPushButton(myPlayFrame);
1681 aForvardBtn->setIcon(QPixmap(rightIco));
1682 connect( aForvardBtn, SIGNAL( clicked() ),
1683 this, SLOT( onForvardPressed() ) );
1684 TopLayout->addWidget(aForvardBtn, 3, 1);
1686 QPushButton* aFirstBtn = new QPushButton(myPlayFrame);
1687 aFirstBtn->setIcon(QPixmap(firstIco));
1688 connect( aFirstBtn, SIGNAL( clicked() ),
1689 this, SLOT( onFirstPressed() ) );
1690 TopLayout->addWidget(aFirstBtn, 4, 0);
1692 QPushButton* aLastBtn = new QPushButton(myPlayFrame);
1693 aLastBtn->setIcon(QPixmap(lastIco));
1694 connect( aLastBtn, SIGNAL( clicked() ),
1695 this, SLOT( onLastPressed() ) );
1696 TopLayout->addWidget(aLastBtn, 4, 1);
1698 QLabel* aSpeedLbl = new QLabel("Speed", myPlayFrame);
1699 TopLayout->addWidget(aSpeedLbl, 4, 2, Qt::AlignRight);
1701 QLCDNumber* aSpeedNum = new QLCDNumber( 2, myPlayFrame );
1702 aSpeedNum->setSegmentStyle(QLCDNumber::Flat);
1703 aSpeedNum->display((int)myAnimator->getSpeed());
1704 TopLayout->addWidget(aSpeedNum, 4, 3);
1706 QwtWheel* aWheel = new QwtWheel(myPlayFrame);
1707 aWheel->setOrientation(Qt::Vertical);
1708 aWheel->setRange(1, 99, 1);
1709 aWheel->setValue((int)myAnimator->getSpeed());
1710 connect( aWheel, SIGNAL(valueChanged(double)),
1711 aSpeedNum, SLOT(display(double)) );
1712 connect( aWheel, SIGNAL(valueChanged(double)),
1713 this, SLOT(onSpeedChange(double)) );
1714 TopLayout->addWidget(aWheel, 1, 3, 3, 1, Qt::AlignRight);
1716 QCheckBox* aCycleCheck = new QCheckBox("Cycled animation",myPlayFrame);
1717 aCycleCheck->setChecked(myAnimator->isCycling());
1718 connect(aCycleCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCyclingSlot(bool)));
1719 TopLayout->addWidget(aCycleCheck, 5, 0, 1, 4);
1721 QCheckBox* aPropCheck = new QCheckBox("Use proportional timing",myPlayFrame);
1722 aPropCheck->setChecked(myAnimator->isProportional());
1723 connect(aPropCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setProportionalSlot(bool)));
1724 TopLayout->addWidget(aPropCheck, 6, 0, 1, 4);
1726 // Pictures saving on disk
1727 QGroupBox* aSaveBox = new QGroupBox( "Saving", myPlayFrame );
1728 //aSaveBox->setColumnLayout(0, Qt::Horizontal );
1729 QGridLayout* aSaveLay = new QGridLayout(aSaveBox);
1730 aSaveLay->setSpacing( 5 );
1731 aSaveLay->setMargin( 5 );
1733 mySaveCheck = new QCheckBox("Save pictures to directory", aSaveBox);
1734 connect(mySaveCheck, SIGNAL( toggled(bool)),
1735 this, SLOT( onCheckDump(bool) ));
1736 aSaveLay->addWidget(mySaveCheck, 0, 0, 1, 3);
1738 QLabel* aFormatLbl = new QLabel("Saving format:", aSaveBox);
1739 aFormatLbl->setEnabled(false);
1740 connect(mySaveCheck, SIGNAL( toggled(bool)),
1741 aFormatLbl, SLOT( setEnabled(bool) ));
1742 aSaveLay->addWidget(aFormatLbl, 1, 0, 1, 2);
1744 myPicsFormat = new QComboBox(aSaveBox);
1745 QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
1746 for (unsigned int i = 0; i < aDumpFormats.count(); i++) {
1747 myPicsFormat->addItem(aDumpFormats.at(i));
1749 if (aDumpFormats.indexOf("jpeg") >= 0)
1750 myPicsFormat->setCurrentIndex(aDumpFormats.indexOf("jpeg"));
1752 myPicsFormat->setCurrentIndex(0);
1754 myPicsFormat->setEnabled(false);
1755 aSaveLay->addWidget(myPicsFormat, 1, 2);
1756 connect(mySaveCheck, SIGNAL( toggled(bool)),
1757 myPicsFormat, SLOT( setEnabled(bool) ));
1758 connect(myPicsFormat, SIGNAL( activated (int)),
1759 this, SLOT( onPicsFormatChanged()));
1761 QLabel* aPathLbl = new QLabel("Path:", aSaveBox);
1762 aPathLbl->setEnabled(false);
1763 connect(mySaveCheck, SIGNAL( toggled(bool)),
1764 aPathLbl, SLOT( setEnabled(bool) ));
1765 aSaveLay->addWidget(aPathLbl, 2, 0);
1767 myPathEdit = new QLineEdit(aSaveBox);
1768 myPathEdit->setReadOnly(true);
1769 myPathEdit->setEnabled(false);
1770 connect(mySaveCheck, SIGNAL( toggled(bool)),
1771 myPathEdit, SLOT( setEnabled(bool) ));
1772 aSaveLay->addWidget(myPathEdit, 2, 1);
1774 QPushButton* aBrowseBtn = new QPushButton("Browse...", aSaveBox);
1775 aBrowseBtn->setEnabled(false);
1776 connect(mySaveCheck, SIGNAL( toggled(bool)),
1777 aBrowseBtn, SLOT( setEnabled(bool) ));
1778 connect(aBrowseBtn, SIGNAL( clicked()),
1779 this, SLOT( onBrowse() ));
1780 mySaveCheck->setChecked(false);
1781 aSaveLay->addWidget(aBrowseBtn, 2, 2);
1783 mySaveAVICheck = new QCheckBox("Save animation to AVI file", aSaveBox);
1784 connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1785 this, SLOT( onCheckDump(bool) ));
1786 aSaveLay->addWidget(mySaveAVICheck, 3, 0, 1, 3);
1788 myPathAVILbl = new QLabel("Path:", aSaveBox);
1789 myPathAVILbl->setEnabled(false);
1790 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1791 // myPathAVILbl, SLOT( setEnabled(bool) ));
1792 aSaveLay->addWidget(myPathAVILbl, 4, 0);
1794 myPathAVIEdit = new QLineEdit(aSaveBox);
1795 myPathAVIEdit->setReadOnly(true);
1796 myPathAVIEdit->setEnabled(false);
1797 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1798 // myPathAVIEdit, SLOT( setEnabled(bool) ));
1799 aSaveLay->addWidget(myPathAVIEdit, 4, 1);
1801 myBrowseAVIBtn = new QPushButton("Browse...", aSaveBox);
1802 myBrowseAVIBtn->setEnabled(false);
1803 //connect(mySaveAVICheck, SIGNAL( toggled(bool)),
1804 // myBrowseAVIBtn, SLOT( setEnabled(bool) ));
1805 connect(myBrowseAVIBtn, SIGNAL( clicked()),
1806 this, SLOT( onBrowseAVI() ));
1807 aSaveLay->addWidget(myBrowseAVIBtn, 4, 2);
1809 myFrequencyLbl = new QLabel("Time stamp frequency:", aSaveBox);
1810 myFrequencyLbl->setEnabled(false);
1811 aSaveLay->addWidget(myFrequencyLbl, 5, 0, 1, 2);
1813 myFrequencySpin = new SalomeApp_IntSpinBox(aSaveBox);
1814 VISU::initSpinBox(myFrequencySpin, 1, 100, 1);
1815 myFrequencySpin->setValue(myAnimator->getTimeStampFrequency());
1816 myFrequencySpin->setEnabled(false);
1817 aSaveLay->addWidget(myFrequencySpin, 5, 2);
1819 mySaveAVICheck->setChecked(false);
1820 //mySaveAVICheck->setEnabled(myAnimator->checkAVIMaker());
1822 int aDumpMode = myAnimator->getDumpMode();
1823 if(aDumpMode == VISU_TimeAnimation::DM_Picture)
1824 mySaveCheck->setChecked(true);
1825 else if(aDumpMode == VISU_TimeAnimation::DM_Video && myAnimator->checkAVIMaker())
1826 mySaveAVICheck->setChecked(true);
1828 TopLayout->addWidget(aSaveBox, 7, 0, 1, 4);
1830 QCheckBox* aCleanMemCheck = new QCheckBox("Clean memory at each frame",myPlayFrame);
1831 aCleanMemCheck->setChecked(myAnimator->isCleaningMemoryAtEachFrame());
1832 connect(aCleanMemCheck, SIGNAL(toggled(bool)), myAnimator, SLOT(setCleaningMemoryAtEachFrameSlot(bool)));
1833 TopLayout->addWidget(aCleanMemCheck, 8, 0, 1, 4);
1835 aMainLayout->addWidget(myPlayFrame);
1837 // Animation publishing in study
1838 QWidget* aPublishBox = new QWidget(this);
1839 QHBoxLayout* aPubHBLay = new QHBoxLayout( aPublishBox );
1840 aPubHBLay->setMargin( 0 );
1842 myPublishBtn = new QPushButton("Publish to study", aPublishBox);
1843 aPubHBLay->addWidget( myPublishBtn );
1844 connect(myPublishBtn, SIGNAL(clicked()), this, SLOT(publishToStudy()));
1846 mySaveBtn = new QPushButton("Save Animation", aPublishBox);
1847 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
1848 aPubHBLay->addWidget( mySaveBtn );
1849 connect(mySaveBtn, SIGNAL(clicked()), this, SLOT(saveToStudy()));
1851 aMainLayout->addWidget(aPublishBox);
1854 QWidget* aBtnBox = new QWidget(this);
1855 QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnBox);
1856 aBtnLayout->setContentsMargins( 5, 5, 0, 5 );
1857 aBtnLayout->addStretch();
1859 QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
1860 aBtnLayout->addWidget( aCloseBtn );
1861 connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
1863 QPushButton* aHelpBtn = new QPushButton(tr("BUT_HELP"), aBtnBox);
1864 aBtnLayout->addWidget( aHelpBtn );
1865 connect(aHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp()));
1867 SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
1868 connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
1870 connect(myAnimator->getViewer(), SIGNAL(destroyed()), this, SLOT(close()));
1871 connect(myAnimator->getViewer(), SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(close()));
1873 aMainLayout->addWidget(aBtnBox);
1875 myPlayFrame->setEnabled(false);
1878 //------------------------------------------------------------------------
1879 VisuGUI_TimeAnimationDlg::~VisuGUI_TimeAnimationDlg()
1881 if (myAnimator != NULL) {
1884 if ( VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule) )
1885 VISU::GetActiveViewWindow<SVTK_ViewWindow>(myModule)->Repaint();
1889 //------------------------------------------------------------------------
1890 void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
1893 myPropBtn->setEnabled(index != 0);
1896 myPlayFrame->setEnabled(false);
1899 //------------------------------------------------------------------------
1900 bool VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
1902 myPlayFrame->setEnabled(false);
1903 return myAnimator->addField(theSObject);
1906 //------------------------------------------------------------------------
1907 void VisuGUI_TimeAnimationDlg::createFrames()
1910 SUIT_OverrideCursor c;
1912 bool isRegenerate = mySetupDlg->isRegenerate();
1914 for (int i = 0; i < myAnimator->getNbFields(); i++) {
1915 FieldData& aFieldData = myAnimator->getFieldData(i);
1916 if( aFieldData.myPrs.empty() )
1918 //myAnimator->generatePresentations(i);
1919 GeneratePresentations(i,myAnimator);
1924 // even if aFieldData is not empty, we must regenerate presentations,
1925 // when a range or a sequence of the animation has been changed
1928 GeneratePresentations(i,myAnimator);
1930 VISU::ColoredPrs3d_i* aPrs3d = dynamic_cast<VISU::ColoredPrs3d_i*>(aFieldData.myPrs[0]);
1934 myAnimator->generatePresentations(i);
1936 aFieldData = myAnimator->getFieldData(i);
1937 for (long aFrameId = 0; aFrameId < aFieldData.myNbFrames; aFrameId++) {
1938 VISU::ColoredPrs3d_i* aColoredPrs3d = aFieldData.myPrs[aFrameId];
1939 std::string aTitle = aColoredPrs3d->GetCTitle();
1940 aColoredPrs3d->SameAs(aPrs3d);
1941 if ( aFrameId != 0 && myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE ) {
1942 aColoredPrs3d->SetTitle(aTitle.c_str());
1949 mySetupDlg->setIsRegenerate( false );
1951 if (myAnimator->getNbFrames() == 0) {
1952 myPlayFrame->setEnabled(false);
1954 SUIT_MessageBox::warning(this,
1956 tr("MSG_NO_ANIMATIONDATA"),
1960 mySlider->setMaximum(myAnimator->getNbFrames()-1);
1961 myPlayFrame->setEnabled(true);
1962 if (!myAnimator->generateFrames()) {
1964 //myPlayFrame->setEnabled(false);
1965 SUIT_MessageBox::warning(this,
1967 myAnimator->getLastErrorMsg(),
1971 //myPlayFrame->setEnabled(true);
1974 //------------------------------------------------------------------------
1975 void VisuGUI_TimeAnimationDlg::onPlayPressed()
1977 if (myPlayBtn->isChecked() && (!myAnimator->isRunning())) {
1978 myPlayBtn->setIcon(MYpausePixmap);
1979 if (mySaveCheck->isChecked()) {
1980 onPicsFormatChanged();
1983 } else if (mySaveAVICheck->isChecked()) {
1984 myAnimator->setDumpFormat("AVI");
1985 myAnimator->dumpTo(myPathAVIEdit->text().toLatin1().data());
1986 myAnimator->setTimeStampFrequency(myFrequencySpin->value());
1988 myAnimator->dumpTo("");
1990 mySetupBtn->setEnabled(false);
1991 myGenBtn->setEnabled(false);
1992 myAnimator->startAnimation();
1994 myPlayBtn->setIcon(MYplayPixmap);
1995 myAnimator->stopAnimation();
1996 mySetupBtn->setEnabled(true);
1997 myGenBtn->setEnabled(true);
2001 //------------------------------------------------------------------------
2002 void VisuGUI_TimeAnimationDlg::onBackPressed()
2005 myAnimator->prevFrame();
2008 //------------------------------------------------------------------------
2009 void VisuGUI_TimeAnimationDlg::onForvardPressed()
2012 myAnimator->nextFrame();
2015 //------------------------------------------------------------------------
2016 void VisuGUI_TimeAnimationDlg::onLastPressed()
2019 myAnimator->lastFrame();
2022 //------------------------------------------------------------------------
2023 void VisuGUI_TimeAnimationDlg::onFirstPressed()
2026 myAnimator->firstFrame();
2029 //------------------------------------------------------------------------
2030 void VisuGUI_TimeAnimationDlg::clearView()
2032 myAnimator->clearView();
2035 //------------------------------------------------------------------------
2036 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
2038 mySetupDlg = new SetupDlg(this,myModule, myAnimator);
2039 mySetupDlg->initialize();
2042 //------------------------------------------------------------------------
2043 void VisuGUI_TimeAnimationDlg::closeEvent (QCloseEvent* theEvent)
2045 if (myAnimator != NULL) {
2046 myAnimator->stopAnimation();
2047 myAnimator->wait(500);
2048 if (myAnimator->isRunning() && (! myAnimator->isFinished())) {
2050 QCloseEvent* aNewCloseEvent = new QCloseEvent;
2051 QApplication::postEvent( this, aNewCloseEvent );
2053 QDialog::closeEvent(theEvent);
2056 QDialog::closeEvent(theEvent);
2060 //------------------------------------------------------------------------
2061 void VisuGUI_TimeAnimationDlg::onWindowChanged (int index)
2063 if (myAnimator->isRunning()) return;
2064 myAnimator->gotoFrame(index);
2067 //------------------------------------------------------------------------
2068 void VisuGUI_TimeAnimationDlg::onSpeedChange (double theSpeed)
2070 myAnimator->setSpeed((int)theSpeed);
2073 //------------------------------------------------------------------------
2074 void VisuGUI_TimeAnimationDlg::stopAnimation()
2076 myAnimator->stopAnimation();
2077 myPlayBtn->setChecked(false);
2078 myPlayBtn->setIcon(MYplayPixmap);
2079 mySetupBtn->setEnabled(true);
2080 myGenBtn->setEnabled(true);
2083 //------------------------------------------------------------------------
2084 void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
2086 myTimeLbl->setText(QString("%1").arg(theTime));
2087 mySlider->setValue(theNewFrame);
2090 //------------------------------------------------------------------------
2091 void VisuGUI_TimeAnimationDlg::onSetupDlg()
2093 if (myAnimator->getNbFrames() > 0)
2094 myAnimator->firstFrame();
2096 myPlayFrame->setEnabled(false);
2099 //------------------------------------------------------------------------
2100 void VisuGUI_TimeAnimationDlg::onBrowse()
2102 // QString aPath = SUIT_FileDlg::getExistingDirectory(this, "/", "Select path");
2104 if (myPathEdit->text().isEmpty())
2105 aDir = getenv("HOME");
2107 aDir = myPathEdit->text();
2108 QString aPath = SUIT_FileDlg::getExistingDirectory(this, aDir, "Select path");
2109 if (!aPath.isEmpty())
2110 myPathEdit->setText(Qtx::addSlash(aPath));
2114 //------------------------------------------------------------------------
2115 void VisuGUI_TimeAnimationDlg::onBrowseAVI()
2117 QStringList aFilter;
2118 aFilter.append( "AVI Files (*.avi)" );
2119 aFilter.append( "All Files (*.*)" );
2122 if (myPathAVIEdit->text().isEmpty())
2123 aDir = getenv("HOME");
2125 QFileInfo aFile(myPathAVIEdit->text());
2126 aDir = aFile.absoluteDir().absolutePath();
2128 QString aPath = SUIT_FileDlg::getFileName(this, aDir, aFilter, "Select file", false);
2129 if (!aPath.isEmpty())
2130 myPathAVIEdit->setText(aPath);
2133 //------------------------------------------------------------------------
2134 void VisuGUI_TimeAnimationDlg::onCheckDump(bool)
2136 const QObject* source = sender();
2137 if (source == mySaveCheck) {
2138 if (mySaveCheck->isChecked()) {
2139 onPicsFormatChanged();
2141 if (mySaveAVICheck->isChecked())
2142 mySaveAVICheck->setChecked(false);
2144 myAnimator->dumpTo("");
2146 //mySaveAVICheck->setEnabled(!mySaveCheck->isChecked() && myAnimator->checkAVIMaker());
2147 mySaveAVICheck->setEnabled(!mySaveCheck->isChecked());
2149 else if (source == mySaveAVICheck) {
2150 if (mySaveAVICheck->isChecked()) {
2151 if (!myAnimator->checkAVIMaker()) {
2152 // AVI maker is not available
2153 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_AVI_MAKER"), tr("&OK"));
2154 mySaveAVICheck->setChecked(false);
2157 if (mySaveCheck->isChecked()) {
2158 mySaveCheck->setChecked(false);
2160 myPathAVILbl->setEnabled(true);
2161 myPathAVIEdit->setEnabled(true);
2162 myBrowseAVIBtn->setEnabled(true);
2163 myFrequencyLbl->setEnabled(true);
2164 myFrequencySpin->setEnabled(true);
2168 // it is necessary in case of not available AVI maker,
2169 // because otherwise they will stay enabled
2170 // (??? slots, connected on SIGNAL(toggled(bool)) of mySaveAVICheck,
2171 // works in wrong order ???)
2172 myPathAVILbl->setEnabled(false);
2173 myPathAVIEdit->setEnabled(false);
2174 myBrowseAVIBtn->setEnabled(false);
2175 myFrequencyLbl->setEnabled(false);
2176 myFrequencySpin->setEnabled(false);
2178 mySaveCheck->setEnabled(!mySaveAVICheck->isChecked());
2182 //------------------------------------------------------------------------
2183 void VisuGUI_TimeAnimationDlg::onStop()
2185 myPlayBtn->setChecked(false);
2186 myPlayBtn->setIcon(MYplayPixmap);
2187 mySetupBtn->setEnabled(true);
2188 myGenBtn->setEnabled(true);
2191 //------------------------------------------------------------------------
2192 void VisuGUI_TimeAnimationDlg::onHelp()
2194 QString aHelpFileName = "animating_page.html";
2195 LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2197 app->onHelpContextModule(myModule ? app->moduleName(myModule->moduleName()) : QString(""), aHelpFileName);
2201 platform = "winapplication";
2203 platform = "application";
2205 SUIT_MessageBox::warning(0, QObject::tr("WRN_WARNING"),
2206 QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
2207 arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(aHelpFileName),
2208 QObject::tr("BUT_OK"));
2212 //------------------------------------------------------------------------
2213 void VisuGUI_TimeAnimationDlg::saveToStudy()
2215 myAnimator->saveAnimation();
2216 VISU::UpdateObjBrowser(myModule, true);
2219 //------------------------------------------------------------------------
2220 void VisuGUI_TimeAnimationDlg::publishToStudy()
2222 myAnimator->publishInStudy();
2223 VISU::UpdateObjBrowser(myModule, true);
2224 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2227 //------------------------------------------------------------------------
2228 void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
2230 myAnimator->restoreFromStudy(theAnimation);
2231 mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
2232 if ( myAnimator->getAnimationMode() == VISU::Animation::SUCCESSIVE )
2233 setWindowTitle(tr("SUCCESSIVE_ANIMATION"));
2236 //------------------------------------------------------------------------
2237 void VisuGUI_TimeAnimationDlg::onPicsFormatChanged()
2239 QList<QByteArray> aDumpFormats = QImageWriter::supportedImageFormats();
2240 if (aDumpFormats.count() < 1) {
2241 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_NO_SUPPORTED_IMAGE_FORMATS"), tr("&OK"));
2244 if (myPicsFormat->currentIndex() < 0 || aDumpFormats.count() <= myPicsFormat->currentIndex()) {
2245 SUIT_MessageBox::warning(this, tr("ERROR"), tr("MSG_INVALID_IMAGE_FORMAT_INDEX"), tr("&OK"));
2248 myAnimator->setDumpFormat(aDumpFormats.at(myPicsFormat->currentIndex()));
2251 //------------------------------------------------------------------------
2252 void VisuGUI_TimeAnimationDlg::onPathChanged()
2254 myAnimator->dumpTo(myPathEdit->text().toLatin1().data());
2257 //------------------------------------------------------------------------
2258 void VisuGUI_TimeAnimationDlg::keyPressEvent( QKeyEvent* e )
2260 QDialog::keyPressEvent( e );
2261 if ( e->isAccepted() )
2264 if ( e->key() == Qt::Key_F1 )