]> SALOME platform Git repositories - modules/visu.git/commitdiff
Salome HOME
NPAL16018 - EDF 419 VISU : Animation, choose non consecutive moments V4_1_0a3
authorouv <ouv@opencascade.com>
Wed, 31 Oct 2007 15:14:06 +0000 (15:14 +0000)
committerouv <ouv@opencascade.com>
Wed, 31 Oct 2007 15:14:06 +0000 (15:14 +0000)
idl/VISU_Gen.idl
src/VISUGUI/VISU_msg_en.po
src/VISUGUI/VisuGUI_TimeAnimation.cxx
src/VISUGUI/VisuGUI_TimeAnimation.h
src/VISU_I/VISU_TimeAnimation.cxx
src/VISU_I/VISU_TimeAnimation.h

index 74ab36c1951756980bebd1c98ae15058717b799d..1d86b315da93e01125c82c20386013dc32ed0325 100644 (file)
@@ -1617,6 +1617,26 @@ module VISU {
      */
     boolean isRangeDefined();
 
+    /*! Sets the sequence of the animation. The sequence is defined on the basis of
+     *  the time stamps of the field which have been used for generation of the animation.
+     *  This method allows to set the sequence of generated frames.
+     *  If this method is not used, the animation will be generated
+     *  on the basis of all time stamps contained in the field.
+     *  Format of the sequence: '1,9,2-5,7-8'
+     *  \param theSequence The sequence of time stamps indices which will be used for generation of the animation.
+     */
+    void setAnimationSequence(in string theSequence);
+
+    /*! Gets the animation sequence.
+     */
+    string getAnimationSequence();
+
+    /*! Returns True if the sequence of the animation has been defined
+     *  by the method <VAR>setAnimationSequence</VAR>. Otherwise
+     *  the animation will be generated on the basis of all time stamps contained in the field.
+     */
+    boolean isSequenceDefined();
+
     /*! Saves all the frames composing the animation into a definite directory.
      *  Pictures format is set with method <VAR>setDumpFormat()</VAR>.
      *  \param thePath The directory where all the frames will be saved.
index 2f10ac9ac2456418d1ceaaa10bb3fa31dfa170fd..daea97ef04ee00eea60386e3cbe0a76766d576b2 100644 (file)
@@ -736,8 +736,11 @@ msgstr "Minimum value:"
 msgid "VisuGUI_IsoSurfPane::NB_SURFACES"
 msgstr "Number of surfaces:"
 
-msgid "VisuGUI_IsoSurfacesDlg::DEFINE_ISOSURFACES"
-msgstr "Iso Surfaces Definition"
+msgid "VisuGUI_IsoSurfPane::SHOW_LEVEL_LINES"
+msgstr "Show level lines"
+
+msgid "VisuGUI_IsoSurfPane::SHOW_LEVEL_LABELS"
+msgstr "Show level labels"
 
 
 #: VisuGUI_NonIsometricDlg.cxx
index abb75081d02a5bf91b7334e0788682c3e1f456c0..b47b0eae3fec8b1af90d121855c6d42013dec74e 100644 (file)
 #include <qslider.h>
 #include <qthread.h>
 #include <qlistbox.h>
+#include <qlineedit.h>
 #include <qwt_wheel.h>
-#include <qhgroupbox.h>
 #include <qlcdnumber.h>
+#include <qhgroupbox.h>
 #include <qvgroupbox.h>
 #include <qtoolbutton.h>
 
@@ -481,15 +482,9 @@ SetupDlg::SetupDlg (QWidget* theParent,
   aMainLayout->setSpacing(5);
 
   // Range of time stamps
-  QFrame* aRangeGrp = new QFrame(this);
-  QGridLayout* aRangeLayout = new QGridLayout( aRangeGrp );
-  aRangeLayout->setSpacing( 6 );
-  aRangeLayout->setMargin( 11 );
-  aRangeGrp->setFrameStyle(QFrame::Box | QFrame::Raised);
-
-  myUseRangeChk = new QCheckBox("Use range of time stamps", aRangeGrp);
-  aRangeLayout->addMultiCellWidget(myUseRangeChk, 0, 0, 0, 3);
-  myUseRangeChk->setChecked(myAnimator->isRangeDefined());
+  myUseRangeBox = new QHGroupBox("Use range of time stamps", this);
+  myUseRangeBox->setCheckable( true );
+  myUseRangeBox->setChecked(myAnimator->isRangeDefined());
 
   double aMaxTime = myAnimator->getMaxTime();
   double aMinTime = myAnimator->getMinTime();
@@ -502,42 +497,65 @@ SetupDlg::SetupDlg (QWidget* theParent,
     aStep = (aMaxTime - aMinTime) / myAnimator->getAbsoluteFrameNumber(aLastFieldFrame);
   }
 
-  QLabel* aMinLbl = new QLabel("From", aRangeGrp);
-  aMinLbl->setEnabled(myUseRangeChk->isChecked());
-  aRangeLayout->addWidget(aMinLbl, 1, 0);
-  myMinVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, aRangeGrp );
-  myMinVal->setEnabled(myUseRangeChk->isChecked());
-  if (myUseRangeChk->isChecked())
+  QLabel* aMinLbl = new QLabel("From", myUseRangeBox);
+  myMinVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
+  if (myUseRangeBox->isChecked())
     myMinVal->setValue( myAnimator->getMinRange() );
   else
     myMinVal->setValue( aMinTime );
 
   connect(myMinVal, SIGNAL( valueChanged(double)),
          this, SLOT( onMinValue(double) ));
-  aRangeLayout->addWidget(myMinVal, 1, 1);
-
-  QLabel* aMaxLbl = new QLabel("To", aRangeGrp);
-  aMaxLbl->setEnabled(myUseRangeChk->isChecked());
-  aRangeLayout->addWidget(aMaxLbl, 1, 2);
-  myMaxVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, aRangeGrp );
-  myMaxVal->setEnabled(myUseRangeChk->isChecked());
-  if (myUseRangeChk->isChecked())
+
+  QLabel* aMaxLbl = new QLabel("To", myUseRangeBox);
+  myMaxVal = new QtxDblSpinBox( aMinTime, aMaxTime, aStep, myUseRangeBox );
+  if (myUseRangeBox->isChecked())
     myMaxVal->setValue( myAnimator->getMaxRange() );
   else
     myMaxVal->setValue( aMaxTime );
 
   connect(myMaxVal, SIGNAL( valueChanged(double)),
          this, SLOT( onMaxValue(double) ));
-  aRangeLayout->addWidget(myMaxVal, 1, 3);
 
-  connect(myUseRangeChk, SIGNAL( toggled(bool)),
-         aMinLbl, SLOT( setEnabled(bool) ));
-  connect(myUseRangeChk, SIGNAL( toggled(bool)),
-         aMaxLbl, SLOT( setEnabled(bool) ));
-  connect(myUseRangeChk, SIGNAL( toggled(bool)),
+  connect(myUseRangeBox, SIGNAL( toggled(bool)),
          this, SLOT( onRangeCheck(bool) ));
 
-  aMainLayout->addWidget(aRangeGrp);
+  aMainLayout->addWidget(myUseRangeBox);
+
+
+  // Sequence of time stamps
+  myUseSequenceBox = new QGroupBox("Use sequence of time stamps", this);
+  myUseSequenceBox->setCheckable( true );
+  myUseSequenceBox->setChecked( myAnimator->isSequenceDefined() );
+
+  myUseSequenceBox->setColumnLayout(0, Qt::Vertical);
+  myUseSequenceBox->layout()->setSpacing( 0 );
+  myUseSequenceBox->layout()->setMargin( 0 );
+  QGridLayout* aUseSequenceLayout = new QGridLayout( myUseSequenceBox->layout() );
+  aUseSequenceLayout->setAlignment( Qt::AlignTop );
+  aUseSequenceLayout->setSpacing( 6 );
+  aUseSequenceLayout->setMargin( 11 );
+
+  QLabel* anIndicesLbl = new QLabel("Indices", myUseSequenceBox);
+  myIndices = new QLineEdit( myUseSequenceBox );
+
+  myValues = new QListBox( myUseSequenceBox );
+  myValues->setSelectionMode( QListBox::Extended );
+
+  connect(myIndices, SIGNAL( textChanged(const QString&)),
+         this, SLOT( onIndicesChanged(const QString&) ));
+
+  connect(myValues, SIGNAL( selectionChanged() ),
+         this, SLOT( onValuesChanged() ) );
+
+  connect(myUseSequenceBox, SIGNAL( toggled(bool)),
+         this, SLOT( onSequenceCheck(bool) ));
+
+  aUseSequenceLayout->addWidget( anIndicesLbl, 0, 0 );
+  aUseSequenceLayout->addWidget( myIndices, 0, 1 );
+  aUseSequenceLayout->addMultiCellWidget( myValues, 1, 1, 0, 1 );
+
+  aMainLayout->addWidget(myUseSequenceBox);
 
 
   // Fields and Properties
@@ -604,11 +622,37 @@ SetupDlg::SetupDlg (QWidget* theParent,
   aBtnLayout->addStretch();
 
   QPushButton* aCloseBtn = new QPushButton(tr("BUT_OK"), aBtnBox);
-  connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
+  connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
 
   aMainLayout->addWidget(aBtnBox);
 }
 
+//------------------------------------------------------------------------
+void SetupDlg::initialize()
+{
+  myValues->clear();
+
+  _PTR(Study) aStudy = myAnimator->getStudy();
+
+  FieldData& aData = myAnimator->getFieldData( 0 );
+  _PTR(SObject) aField = aData.myField;
+
+  _PTR(ChildIterator) anIter = aStudy->NewChildIterator(aField);
+  anIter->Next(); // First is reference on support
+  for(int index = 1; anIter->More(); anIter->Next(), index++)
+  {
+    QString aPrefix( "[" );
+    aPrefix += QString::number( index );
+    aPrefix += "] - ";
+
+    double aTime = VISU_TimeAnimation::getTimeValue(anIter->Value());
+    myValues->insertItem( aPrefix + QString::number( aTime ) );
+  }
+
+  QString anIndices( myAnimator->getAnimationSequence() );
+  myIndices->setText( anIndices );
+}
+
 //------------------------------------------------------------------------
 enum PrsComboItem {
   TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
@@ -623,6 +667,21 @@ enum PrsComboItem {
   TSCALARMAPONDEFORMEDSHAPE_ITEM = 9 // VISU::TSCALARMAPONDEFORMEDSHAPE
 };
 
+//------------------------------------------------------------------------
+void SetupDlg::onClose()
+{
+  for (int i = 0; i < myAnimator->getNbFields(); i++)
+    myAnimator->clearData(myAnimator->getFieldData(i));
+
+  if( !myUseRangeBox->isChecked() )
+    myAnimator->setAnimationRange( 0, 0 );
+  
+  if( !myUseSequenceBox->isChecked() )
+    myAnimator->setAnimationSequence( 0 );
+  
+  close();
+}
+
 //------------------------------------------------------------------------
 void SetupDlg::onFieldChange (int theIndex)
 {
@@ -927,8 +986,12 @@ void SetupDlg::onArrangeDlg()
 //------------------------------------------------------------------------
 void SetupDlg::onRangeCheck (bool theCheck)
 {
-  myMinVal->setEnabled(theCheck);
-  myMaxVal->setEnabled(theCheck);
+  if( theCheck )
+  {
+    myUseSequenceBox->blockSignals( true );
+    myUseSequenceBox->setChecked( false );
+    myUseSequenceBox->blockSignals( false );
+  }
 
   if (!theCheck)
     myAnimator->setAnimationRange(0, 0);
@@ -944,8 +1007,6 @@ void SetupDlg::onMinValue (double theVal)
     myMinVal->setFocus();
     return;
   }
-  for (int i = 0; i < myAnimator->getNbFields(); i++)
-    myAnimator->clearData(myAnimator->getFieldData(i));
   myAnimator->setAnimationRange(theVal, myAnimator->getMaxRange());
 }
 
@@ -957,11 +1018,104 @@ void SetupDlg::onMaxValue (double theVal)
     myMaxVal->setFocus();
     return;
   }
-  for (int i = 0; i < myAnimator->getNbFields(); i++)
-    myAnimator->clearData(myAnimator->getFieldData(i));
   myAnimator->setAnimationRange(myAnimator->getMinRange(), theVal);
 }
 
+//------------------------------------------------------------------------
+void SetupDlg::onSequenceCheck( bool theCheck )
+{
+  if( theCheck )
+  {
+    myUseRangeBox->blockSignals( true );
+    myUseRangeBox->setChecked( false );
+    myUseRangeBox->blockSignals( false );
+  }
+}
+
+//------------------------------------------------------------------------
+void SetupDlg::onIndicesChanged( const QString& theIndices )
+{
+  bool aCorrect = true;
+  int aLimit = myValues->count();
+
+  QValueList<long> anIndicesList;
+  aCorrect = myAnimator->getIndicesFromSequence( theIndices, anIndicesList );
+
+  myValues->blockSignals( true );
+  myValues->clearSelection();
+
+  QValueList<long>::iterator indIt = anIndicesList.begin();
+  QValueList<long>::iterator indItEnd = anIndicesList.end();
+  for( int i = 0; indIt != indItEnd; ++indIt, i++ )
+  {
+    long anIndex = *indIt;
+    if( anIndex < 1 || anIndex > aLimit )
+    {
+      aCorrect = false;
+      myValues->clearSelection();
+      break;
+    }
+    myValues->setSelected( anIndex-1, true );
+  }
+
+  myValues->blockSignals( false );
+
+  if( !aCorrect )
+  {
+    myIndices->setPaletteForegroundColor( Qt::red );
+    return;
+  }
+
+  myIndices->setPaletteForegroundColor( Qt::black );
+
+  myAnimator->setAnimationSequence( theIndices.latin1() );
+}
+
+//------------------------------------------------------------------------
+void SetupDlg::onValuesChanged()
+{
+  int aLimit = myValues->count();
+
+  QString anIndices;
+
+  for( int i = 0; i < aLimit; i++ )
+  {
+    if( !myValues->isSelected( i ) )
+      continue;
+
+    QString aString = QString::number( i+1 );
+
+    bool aPrevSelected = i != 0 && myValues->isSelected( i-1 );
+    bool aNextSelected = i != aLimit - 1 && myValues->isSelected( i+1 );
+    if( aPrevSelected )
+    {
+      if( aNextSelected )
+       aString = "";
+      else
+       aString += ",";
+    }
+    else
+    {
+      if( aNextSelected )
+       aString += "-";
+      else
+       aString += ",";
+    }
+
+    anIndices += aString;
+  }
+
+  if( anIndices.right( 1 ) == "," )
+    anIndices.truncate( anIndices.length() - 1 );
+
+  myIndices->blockSignals( true );
+  myIndices->setText( anIndices );
+  myIndices->blockSignals( false );
+
+  myAnimator->setAnimationSequence( anIndices.latin1() );
+}
+
+//------------------------------------------------------------------------
 static const char * firstIco[] = {
 "18 10 2 1",
 "      g None",
@@ -1437,6 +1591,7 @@ void VisuGUI_TimeAnimationDlg::clearView()
 void VisuGUI_TimeAnimationDlg::showEvent(QShowEvent* theEvent)
 {
   mySetupDlg = new SetupDlg(this,myModule, myAnimator);
+  mySetupDlg->initialize();
 }
 
 //------------------------------------------------------------------------
index a3640e602a31eeecaf34e28eb9b2d4dbe923e657..d19f78724ae7e29512c339e213dc89f4412d0ad4 100644 (file)
@@ -56,8 +56,10 @@ class QtxDblSpinBox;
 class QLabel;
 class QSlider;
 class QListBox;
+class QLineEdit;
 class QCheckBox;
 class QComboBox;
+class QGroupBox;
 class QToolButton;
 
 /*!
@@ -123,7 +125,11 @@ class SetupDlg: public QDialog {
           VISU_TimeAnimation* theAnimator);
   ~SetupDlg() {};
 
+ public:
+  void initialize();
+
  private slots:
+  void onClose();
   void onFieldChange(int theIndex);
   void onTypeChanged(int theIndex);
   //  void onScalarBarDlg();
@@ -131,6 +137,9 @@ class SetupDlg: public QDialog {
   void onRangeCheck(bool theCheck);
   void onMinValue(double theVal);
   void onMaxValue(double theVal);
+  void onSequenceCheck(bool theCheck);
+  void onIndicesChanged(const QString& theIndices);
+  void onValuesChanged();
   void onArrangeDlg();
 
  private:
@@ -144,9 +153,14 @@ class SetupDlg: public QDialog {
 
   QPushButton* myPropBtn;
   QPushButton* myArrangeBtn;
-  QCheckBox* myUseRangeChk;
+
+  QGroupBox* myUseRangeBox;
   QtxDblSpinBox* myMinVal;
   QtxDblSpinBox* myMaxVal;
+
+  QGroupBox* myUseSequenceBox;
+  QLineEdit* myIndices;
+  QListBox* myValues;
 };
 
 
index 15e1b06ccb8b4b17f850f2dca7abfd3bce08f2a2..07d8b54fdfc07bf543afa3145f90569ef28c5cde 100644 (file)
@@ -351,13 +351,20 @@ namespace
                        VISU::Result_i* theResult,
                        bool theIsRangeDefined,
                        CORBA::Double theTimeMin,
-                       CORBA::Double theTimeMax)
+                       CORBA::Double theTimeMax,
+                       QValueList<long> theSequence)
   {
     _PTR(ChildIterator) anIter = theStudy->NewChildIterator(theData.myField);
     anIter->Next(); // First is reference on support
 
+    long aSequenceLength = theSequence.count();
+    bool isSequenceDefined = aSequenceLength > 0;
+    if (isSequenceDefined)
+      theData.myPrs.resize(aSequenceLength,NULL);
+
     long aFrameId = 0;
-    for(; anIter->More(); anIter->Next()){
+    long aSequenceIndex = 1;
+    for(; anIter->More(); anIter->Next(), aSequenceIndex++){
       if (aFrameId == theData.myNbTimes) {
        MESSAGE("There are extra timestamps in field");
        return;
@@ -366,6 +373,8 @@ namespace
       if(!aTimeStamp) 
        continue;
 
+      long aSequenceId = -1;
+
       theData.myTiming[aFrameId] = VISU_TimeAnimation::getTimeValue(aTimeStamp);
       if (theIsRangeDefined) {
        if (theData.myTiming[aFrameId] < theTimeMin) 
@@ -373,6 +382,11 @@ namespace
        if (theData.myTiming[aFrameId] > theTimeMax) 
          break;
       }
+      else if (isSequenceDefined) {
+       aSequenceId = theSequence.findIndex( aSequenceIndex );
+       if( aSequenceId == -1 )
+         continue;
+      }
 
       VISU::Storable::TRestoringMap aTimeMap = VISU::Storable::GetStorableMap(aTimeStamp);
       QString aMeshName = VISU::Storable::FindValue(aTimeMap,"myMeshName");
@@ -395,7 +409,15 @@ namespace
         try{
 #endif
           if(aPresent->Apply(false)){
-            theData.myPrs[aFrameId++] = aPresent;
+           /*
+           if(isSequenceDefined)
+           {
+             theData.myPrs[aSequenceId] = aPresent;
+             aFrameId++;
+           }
+           else
+           */
+           theData.myPrs[aFrameId++] = aPresent;
             anIsCreated = true;
           }
 #ifdef NO_CAS_CATCH
@@ -484,6 +506,14 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
   aData.myPrs.resize(aData.myNbTimes,NULL);
   aData.myTiming.resize(aData.myNbTimes);
 
+  QValueList<long> aSequence;
+  if( isSequenceDefined() )
+  {
+    bool ok = getIndicesFromSequence( mySequence, aSequence );
+    if( !ok )
+      return;
+  }
+
   using namespace VISU;
   switch (aData.myPrsType) {
   case VISU::TSCALARMAP:
@@ -492,7 +522,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                       aResult,
                                       isRangeDefined(),
                                       myTimeMinVal,
-                                      myTimeMaxVal);
+                                      myTimeMaxVal,
+                                      aSequence);
     break;
   case VISU::TISOSURFACES: // Iso Surfaces
     GeneratePresentations<IsoSurfaces_i>(myStudy,
@@ -500,7 +531,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                         aResult,
                                         isRangeDefined(),
                                         myTimeMinVal,
-                                        myTimeMaxVal);
+                                        myTimeMaxVal,
+                                        aSequence);
     break;
   case VISU::TCUTPLANES: // Cut Planes
     GeneratePresentations<CutPlanes_i>(myStudy,
@@ -508,7 +540,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                       aResult,
                                       isRangeDefined(),
                                       myTimeMinVal,
-                                      myTimeMaxVal);
+                                      myTimeMaxVal,
+                                      aSequence);
     break;
   case VISU::TCUTLINES: // Cut Lines
     GeneratePresentations<CutLines_i>(myStudy,
@@ -516,7 +549,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                      aResult,
                                      isRangeDefined(),
                                      myTimeMinVal,
-                                     myTimeMaxVal);
+                                     myTimeMaxVal,
+                                     aSequence);
     break;
   case VISU::TPLOT3D: // Plot3d
     GeneratePresentations<Plot3D_i>(myStudy,
@@ -524,7 +558,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                    aResult,
                                    isRangeDefined(),
                                    myTimeMinVal,
-                                   myTimeMaxVal);
+                                   myTimeMaxVal,
+                                   aSequence);
     break;
   case VISU::TDEFORMEDSHAPE: // Deformed Shape
     GeneratePresentations<DeformedShape_i>(myStudy,
@@ -532,7 +567,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                           aResult,
                                           isRangeDefined(),
                                           myTimeMinVal,
-                                          myTimeMaxVal);
+                                          myTimeMaxVal,
+                                          aSequence);
     break;
   case VISU::TVECTORS: // Vectors
     GeneratePresentations<Vectors_i>(myStudy,
@@ -540,7 +576,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                     aResult,
                                     isRangeDefined(),
                                     myTimeMinVal,
-                                    myTimeMaxVal);
+                                    myTimeMaxVal,
+                                    aSequence);
     break;
   case VISU::TSTREAMLINES: // Stream Lines
     GeneratePresentations<StreamLines_i>(myStudy,
@@ -548,7 +585,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                         aResult,
                                         isRangeDefined(),
                                         myTimeMinVal,
-                                        myTimeMaxVal);
+                                        myTimeMaxVal,
+                                        aSequence);
     break;
   case VISU::TGAUSSPOINTS: // Gauss Points
     GeneratePresentations<GaussPoints_i>(myStudy,
@@ -556,7 +594,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                         aResult,
                                         isRangeDefined(),
                                         myTimeMinVal,
-                                        myTimeMaxVal);
+                                        myTimeMaxVal,
+                                        aSequence);
     break;
   case VISU::TSCALARMAPONDEFORMEDSHAPE: // Scalar map on deformed shape
     GeneratePresentations<ScalarMapOnDeformedShape_i>(myStudy,
@@ -564,7 +603,8 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
                                                      aResult,
                                                      isRangeDefined(),
                                                      myTimeMinVal,
-                                                     myTimeMaxVal);
+                                                     myTimeMaxVal,
+                                                     aSequence);
     break;
   default:
     MESSAGE("Not implemented for this presentation type: " << aData.myPrsType);
@@ -572,7 +612,7 @@ void VISU_TimeAnimation::generatePresentations(CORBA::Long theFieldNum) {
   }
   
   if ( myAnimationMode == VISU::Animation::SUCCESSIVE ) { // successive animation mode
-    if ( isRangeDefined() ) {
+    if ( isRangeDefined() || isSequenceDefined() ) {
       if ( myFieldsAbsFrames.size() == getNbFields() ) 
        myFieldsAbsFrames.clear();
       if ( theFieldNum > 0 )
@@ -1485,6 +1525,81 @@ void VISU_TimeAnimation::setSpeed(CORBA::Long theSpeed)
   mySpeed = (theSpeed<1)? 1 : theSpeed;
 }
 
+//------------------------------------------------------------------------
+void VISU_TimeAnimation::setAnimationSequence(const char* theSequence)
+{
+  mySequence = QString( theSequence );
+}
+
+//------------------------------------------------------------------------
+char* VISU_TimeAnimation::getAnimationSequence()
+{
+  return (char*)mySequence.latin1();
+}
+
+//------------------------------------------------------------------------
+CORBA::Boolean VISU_TimeAnimation::isSequenceDefined()
+{
+  return !mySequence.isEmpty();
+}
+
+//------------------------------------------------------------------------
+bool VISU_TimeAnimation::getIndicesFromSequence( QString theSequence, QValueList<long>& theIndices )
+{
+  bool isCorrect = true;
+
+  theIndices.clear();
+
+  QStringList aList = QStringList::split( ",", theSequence );
+  QStringList::iterator it = aList.begin();
+  QStringList::iterator itEnd = aList.end();
+  for( ; it != itEnd; ++it )
+  {
+    if( !isCorrect )
+      break;
+
+    isCorrect = false;
+
+    QString aString = *it;
+    if( aString.isEmpty() )
+      continue;
+
+    bool ok = false;
+    int aSingleIndex = aString.toLong( &ok );
+    if( ok )
+    {
+      theIndices.append( aSingleIndex );
+      isCorrect = true;
+    }
+    else if( aString.contains( '-' ) == 1 )
+    {
+      QString aLeftIndexStr = aString.section( '-', 0, 0 );
+      QString aRightIndexStr = aString.section( '-', -1 );
+
+      ok = false;
+      int aLeftIndex = aLeftIndexStr.toLong( &ok );
+      if( !ok )
+       continue;
+
+      ok = false;
+      int aRightIndex = aRightIndexStr.toLong( &ok );
+      if( !ok )
+       continue;
+
+      if( aLeftIndex >= aRightIndex )
+       continue;
+
+      for( int i = aLeftIndex; i <= aRightIndex; i++ )
+       theIndices.append( i );
+
+      isCorrect = true;
+    }
+  }
+
+  return isCorrect;
+}
+
+//------------------------------------------------------------------------
 std::string VISU_TimeAnimation::setDumpFormat(const char* theFormat)
 {
   myDumpFormat = theFormat;
@@ -1573,9 +1688,10 @@ SALOMEDS::SObject_ptr VISU_TimeAnimation::publishInStudy()
   std::string aSComponentEntry = aSComponent->GetID();
 
   QString aComment;
-  aComment.sprintf("myComment=ANIMATION;myTimeMinVal=%g;myTimeMaxVal=%g;myMode=%d",
+  aComment.sprintf("myComment=ANIMATION;myTimeMinVal=%g;myTimeMaxVal=%g;mySequence=%s;myMode=%d",
                    myTimeMinVal,
                   myTimeMaxVal,
+                  mySequence.latin1(),
                   myAnimationMode);
 
   string anEntry = VISU::CreateAttributes(myStudy,
@@ -1637,6 +1753,7 @@ void VISU_TimeAnimation::saveAnimation()
   aComment.sprintf("myComment=ANIMATION;myTimeMinVal=%g;myTimeMaxVal=%g;myMode=%d",
                    myTimeMinVal,
                   myTimeMaxVal,
+                  mySequence.latin1(),
                   myAnimationMode);
 
   _PTR(GenericAttribute) anAttr;
@@ -1707,6 +1824,7 @@ void VISU_TimeAnimation::restoreFromStudy(_PTR(SObject) theField)
   bool isExist;
   myTimeMinVal = VISU::Storable::FindValue(aMap,"myTimeMinVal",&isExist).toDouble();
   myTimeMaxVal = VISU::Storable::FindValue(aMap,"myTimeMaxVal",&isExist).toDouble();
+  mySequence = VISU::Storable::FindValue(aMap,"mySequence",&isExist);
   myAnimationMode = VISU::Animation::AnimationMode(VISU::Storable::FindValue(aMap,"myMode",&isExist).toInt());
 
   _PTR(ChildIterator) anIter = myStudy->NewChildIterator(aAnimSObject);
@@ -1717,7 +1835,7 @@ void VISU_TimeAnimation::restoreFromStudy(_PTR(SObject) theField)
       continue;
 
     addField(aFieldObj);
-    if ( isRangeDefined() ) 
+    if ( isRangeDefined() || isSequenceDefined() 
       myFieldsAbsFrames.pop_back();
 
     FieldData& aData = getFieldData(getNbFields()-1);
@@ -2034,6 +2152,21 @@ CORBA::Boolean VISU_TimeAnimation_i::isRangeDefined()
   return myAnim->isRangeDefined();
 }
 
+void VISU_TimeAnimation_i::setAnimationSequence (const char* theSequence)
+{
+  myAnim->setAnimationSequence(theSequence);
+}
+
+char* VISU_TimeAnimation_i::getAnimationSequence()
+{
+  return myAnim->getAnimationSequence();
+}
+
+CORBA::Boolean VISU_TimeAnimation_i::isSequenceDefined()
+{
+  return myAnim->isRangeDefined();
+}
+
 void VISU_TimeAnimation_i::dumpTo (const char* thePath)
 {
   myAnim->dumpTo(thePath);
index c32552a0b302bc189f76b6f34963a7a9bada11f8..04cacfc1e35b03b150ac44ad2604b42dfdc02c19 100644 (file)
@@ -140,6 +140,12 @@ class VISU_I_EXPORT VISU_TimeAnimation: public QObject, public QThread
   CORBA::Double getMaxRange() { return myTimeMaxVal; }
   CORBA::Boolean isRangeDefined() { return !((myTimeMaxVal == 0) && (myTimeMinVal == myTimeMaxVal)); }
 
+  void setAnimationSequence(const char* theSequence);
+  char* getAnimationSequence();
+  CORBA::Boolean isSequenceDefined();
+
+  bool getIndicesFromSequence( QString theSequence, QValueList<long>& theIndices );
+
   void dumpTo(const char* thePath) { myDumpPath = thePath; }
   std::string setDumpFormat(const char* theFormat);
   bool checkAVIMaker() const;
@@ -161,6 +167,7 @@ class VISU_I_EXPORT VISU_TimeAnimation: public QObject, public QThread
   void restoreFromStudy(_PTR(SObject) theField);
   void saveAnimation();
   bool isSavedInStudy() const { return !myAnimEntry.isEmpty(); }
+  _PTR(Study) getStudy() const { return myStudy; }
 
   void setAnimationMode(VISU::Animation::AnimationMode theMode) { myAnimationMode = theMode; }
   VISU::Animation::AnimationMode  getAnimationMode() { return myAnimationMode; }
@@ -199,6 +206,7 @@ class VISU_I_EXPORT VISU_TimeAnimation: public QObject, public QThread
   VISU::Animation::AnimationMode myAnimationMode;
   double myTimeMinVal, myTimeMaxVal; //!< Range of time stams, set by user
   double myTimeMin   , myTimeMax   ; //!< Range of time stams, available for animation
+  QString mySequence;
   QString myDumpPath;
   QString myDumpFormat;
   QString myAVIMaker;
@@ -260,6 +268,10 @@ public:
   virtual CORBA::Double getMaxRange();
   virtual CORBA::Boolean isRangeDefined();
 
+  virtual void setAnimationSequence(const char* theSequence);
+  virtual char* getAnimationSequence();
+  virtual CORBA::Boolean isSequenceDefined();
+
   virtual void dumpTo(const char* thePath);
   virtual char* setDumpFormat(const char* theFormat);