Salome HOME
Fix a regression
[modules/visu.git] / src / VISUGUI / VisuGUI_TimeAnimation.cxx
index 0a6ea6722b0cb30ee6d662c0744bb1ac186de243..0598764e379343b0ef5915d9b230453c50914dfd 100644 (file)
@@ -14,6 +14,7 @@
 #include "VisuGUI_Tools.h"
 #include "VisuGUI_DeformedShapeDlg.h"
 #include "VisuGUI_CutPlanesDlg.h"
+#include "VisuGUI_Plot3DDlg.h"
 #include "VisuGUI_VectorsDlg.h"
 #include "VisuGUI_IsoSurfacesDlg.h"
 #include "VisuGUI_StreamLinesDlg.h"
@@ -24,6 +25,7 @@
 #include "VISU_IsoSurfaces_i.hh"
 #include "VISU_DeformedShape_i.hh"
 #include "VISU_CutPlanes_i.hh"
+#include "VISU_Plot3D_i.hh"
 #include "VISU_CutLines_i.hh"
 #include "VISU_Vectors_i.hh"
 #include "VISU_StreamLines_i.hh"
@@ -46,7 +48,7 @@
 #include <vtkRenderer.h>
 
 #include <qhbox.h>
-#include <qgrid.h> 
+#include <qgrid.h>
 #include <qlayout.h>
 #include <qslider.h>
 #include <qthread.h>
 
 #define  MAXVAL 1e10
 
-
 ArrangeDlg::ArrangeDlg(QWidget* theParent, VISU_TimeAnimation* theAnimator)
   : QDialog(theParent, "ArrangeDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
-    myAnimator(theAnimator), myViewWindow(0)
+    myAnimator(theAnimator), myViewWindow(theAnimator->getViewer())
 {
   myCurrent = 0;
   init();
@@ -171,16 +172,16 @@ void ArrangeDlg::init()
   aManualPane->setSpacing(10);
 
   myFieldLst = new QListBox(aManualPane);
-  connect( myFieldLst, SIGNAL( highlighted(int) ), 
+  connect( myFieldLst, SIGNAL( highlighted(int) ),
           this, SLOT( onFieldChange(int) ) );
 
   QGrid* aCoordPane = new QGrid(2, aManualPane);
   aCoordPane->setSpacing(5);
-  
+
   new QLabel("X", aCoordPane);
   myCoord[0] = new QtxDblSpinBox(aCoordPane);
   myCoord[0]->setRange(-MAXVAL, MAXVAL);
-  
+
   new QLabel("Y", aCoordPane);
   myCoord[1] = new QtxDblSpinBox(aCoordPane);
   myCoord[1]->setRange(-MAXVAL, MAXVAL);
@@ -242,7 +243,7 @@ void ArrangeDlg::accept()
   QDialog::accept();
 }
 
-void ArrangeDlg::onFieldChange(int theCurrent) 
+void ArrangeDlg::onFieldChange(int theCurrent)
 {
   if (myCurrent != theCurrent) {
     Offset& aOffs = myOffsets[myCurrent];
@@ -265,7 +266,7 @@ void ArrangeDlg::acceptAnimation()
     aOffs.myOffset[0] = myCoord[0]->value();
     aOffs.myOffset[1] = myCoord[1]->value();
     aOffs.myOffset[2] = myCoord[2]->value();
-    
+
     for (int i = 0; i < myAnimator->getNbFields(); i++) {
       Offset aOffs = myOffsets[i];
       myAnimator->getFieldData(i).myOffset[0] = aOffs.myOffset[0];
@@ -277,7 +278,7 @@ void ArrangeDlg::acceptAnimation()
     FieldData& aData = myAnimator->getFieldData(0);
     if (aData.myPrs.empty())
       myAnimator->generatePresentations(0);
-    VISU_Actor* aActor = aActor = aData.myPrs[0]->CreateActor();
+    VISU_Actor* aActor = aData.myPrs[0]->CreateActor();
     float aBounds[6];
     aActor->GetBounds(aBounds);
     aActor->Delete();
@@ -287,20 +288,38 @@ void ArrangeDlg::acceptAnimation()
     case XAxis:
       aDist = fabs(aBounds[1] - aBounds[0]);
       break;
-    case YAxis: 
+    case YAxis:
       aDist = fabs(aBounds[3] - aBounds[2]);
       break;
     case ZAxis:
       aDist = fabs(aBounds[5] - aBounds[4]);
     }
-    aDist = aDist*getDistance();
+
+    float dx = fabs(aBounds[1] - aBounds[0]);
+    float dy = fabs(aBounds[3] - aBounds[2]);
+    float dz = fabs(aBounds[5] - aBounds[4]);
+    float max = (dx > dy) ? dx : dy;
+    max = (dz > max) ? dz : max;
+    max /= 100.0;
+
+    if (aDist < max) {
+      // set base distance between centers of bounding boxes
+      // to minimal (but big enough) size of current bounding box
+      if (dx < max) dx = FLT_MAX;
+      if (dy < max) dy = FLT_MAX;
+      if (dz < max) dz = FLT_MAX;
+
+      aDist = (dx < dy) ? dx : dy;
+      aDist = (dz < aDist) ? dz : aDist;
+    }
+    aDist = aDist * getDistance();
     for (int i = 0; i < myAnimator->getNbFields(); i++) {
       myAnimator->getFieldData(i).myOffset[0] = 0;
       myAnimator->getFieldData(i).myOffset[1] = 0;
       myAnimator->getFieldData(i).myOffset[2] = 0;
       myAnimator->getFieldData(i).myOffset[aAxis] = aDist * i;
     }
-    
+
     QApplication::restoreOverrideCursor();
   }
 }
@@ -318,62 +337,106 @@ void ArrangeDlg::acceptViewWindow()
     for (it = myPrsMap.begin(); it != myPrsMap.end(); ++it) {
       VISU::Prs3d_i* aPrs = it.key();
       Offset& aOffs = myOffsets[it.data()];
-      if (VISU_Actor* anActor = VISU::GetActor(aPrs, myViewWindow)) anActor->SetPosition(aOffs.myOffset);
+      if (VISU_Actor* anActor = VISU::GetActor(aPrs, myViewWindow))
+        anActor->SetPosition(aOffs.myOffset);
       if (mySaveChk)
-       if (mySaveChk->isChecked()) 
+       if (mySaveChk->isChecked())
          aPrs->SetOffset(aOffs.myOffset);
     }
   } else {
     float aDist = 0;
     float aShift = 0;
     float aPrevDist = 0;
-    //    bool aInit = true;
+    float aPrevShift = 0;
     int i;
     QMap<VISU::Prs3d_i*, int>::Iterator it;
     for (it = myPrsMap.begin(), i = 0; it != myPrsMap.end(); ++it, i++) {
       VISU::Prs3d_i* aPrs = it.key();
-      if (VISU_Actor* aActor = VISU::GetActor(aPrs, myViewWindow)){
+      if (VISU_Actor* aActor = VISU::GetActor(aPrs, myViewWindow)) {
        int aAxis = getAxis();
-       //      if (aInit) {
+
+       float aZeroOffset[3];
+        aZeroOffset[0] = aZeroOffset[1] = aZeroOffset[2] = 0;
+       aActor->SetPosition(aZeroOffset);
+        aActor->GetMapper()->Update();
+
        float aBounds[6];
        aActor->GetBounds(aBounds);
        switch (aAxis) {
        case XAxis:
          aDist = fabs(aBounds[1] - aBounds[0]);
          break;
-       case YAxis: 
+       case YAxis:
          aDist = fabs(aBounds[3] - aBounds[2]);
          break;
        case ZAxis:
          aDist = fabs(aBounds[5] - aBounds[4]);
        }
-       //        aInit = false;
-       //      }
        float aOffset[3];
-       aOffset[0] = aOffset[1] = aOffset[2] = 0;
-
-       aShift = (i == 0)? 0 : aShift + (aDist + aPrevDist) * getDistance() / 2;
-
-       aOffset[aAxis] = aShift;
+       aOffset[0] = (aBounds[1] < aBounds[0]) ? -aBounds[1] : -aBounds[0];
+        aOffset[1] = (aBounds[3] < aBounds[2]) ? -aBounds[3] : -aBounds[2];
+        aOffset[2] = (aBounds[5] < aBounds[4]) ? -aBounds[5] : -aBounds[4];
+
+        if (i > 0) {
+          float aCCDist = (aDist + aPrevDist) / 2.0;
+
+          float dx = fabs(aBounds[1] - aBounds[0]);
+          float dy = fabs(aBounds[3] - aBounds[2]);
+          float dz = fabs(aBounds[5] - aBounds[4]);
+          float max = (dx > dy) ? dx : dy;
+          max = (dz > max) ? dz : max;
+          max /= 100.0;
+
+          if (aCCDist < max) {
+            // set base distance between centers of bounding boxes
+            // to minimal (but big enough) size of current bounding box
+            if (dx < max) dx = FLT_MAX;
+            if (dy < max) dy = FLT_MAX;
+            if (dz < max) dz = FLT_MAX;
+
+            aCCDist = (dx < dy) ? dx : dy;
+            aCCDist = (dz < aCCDist) ? dz : aCCDist;
+          }
+
+          //-------------------------------->
+          //             aShift
+          //                                 aDist / 2
+          //                                 <-->
+          //            .--------------.     .------.
+          //----------->|              |     |      |
+          // aPrevShift '--------------'     '------'
+          //            <------>
+          //            aPrevDist / 2
+          //
+          //                    <--------------->
+          //                    (aDist + aPrevDist) * getDistance() / 2
+
+          aShift = aPrevShift + aPrevDist/2.0 + aCCDist*getDistance() - aDist/2.0;
+        }
+
+       aOffset[aAxis] += aShift;
        aActor->SetPosition(aOffset);
        if (mySaveChk)
          if (mySaveChk->isChecked())
            aPrs->SetOffset(aOffset);
+
        aPrevDist = aDist;
+       aPrevShift = aShift;
       }
     }
   }
-  myViewWindow->getRenderer()->ResetCameraClippingRange(); 
-  myViewWindow->Repaint(); 
+  myViewWindow->getRenderer()->ResetCameraClippingRange();
+  myViewWindow->Repaint();
 }
 
 
 //*****************************************************************************************************
 //*****************************************************************************************************
 //*****************************************************************************************************
-SetupDlg::SetupDlg (QWidget* theParent, VISU_TimeAnimation* theAnimator)
-     : QDialog(theParent, "SetupDlg", true, WStyle_Customize |
-               WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+SetupDlg::SetupDlg (VisuGUI* theModule, VISU_TimeAnimation* theAnimator)
+     : QDialog(VISU::GetDesktop(theModule), "SetupDlg", true, WStyle_Customize |
+               WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
+       myModule(theModule)
 {
   setCaption("Setup Animation");
   setSizeGripEnabled( TRUE );
@@ -452,7 +515,7 @@ SetupDlg::SetupDlg (QWidget* theParent, VISU_TimeAnimation* theAnimator)
   QVBox* aSetupBox = new QVBox(aPropFrame);
   aSetupBox->setSpacing(5);
 
-  QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);  
+  QVGroupBox* aPropBox = new QVGroupBox("Properties", aSetupBox);
   //QVGroupBox* aPropBox = new QVGroupBox("Properties", aPropFrame);
   myTypeCombo = new QComboBox(aPropBox);
   connect( myTypeCombo, SIGNAL( activated(int) ),
@@ -484,40 +547,56 @@ SetupDlg::SetupDlg (QWidget* theParent, VISU_TimeAnimation* theAnimator)
   aMainLayout->addWidget(aBtnBox);
 }
 
+//************************************************************************
+enum PrsComboItem {
+  TSCALARMAP_ITEM     = 0, // VISU::TSCALARMAP
+  TISOSURFACE_ITEM    = 1, // VISU::TISOSURFACE
+  TCUTPLANES_ITEM     = 2, // VISU::TCUTPLANES
+  TPLOT3D_ITEM        = 3, // VISU::TPLOT3D
+  TDEFORMEDSHAPE_ITEM = 4, // VISU::TDEFORMEDSHAPE
+  TVECTORS_ITEM       = 5, // VISU::TVECTORS
+  TSTREAMLINES_ITEM   = 6  // VISU::TSTREAMLINES
+};
+
 //************************************************************************
 void SetupDlg::onFieldChange (int theIndex)
 {
   FieldData& aData = myAnimator->getFieldData(theIndex);
   myTypeCombo->clear();
-  myTypeCombo->insertItem("Scalar Map");
-  myTypeCombo->insertItem("Iso Surfaces");
-  myTypeCombo->insertItem("Cut Planes");
+  // ATTENTION: append items in the same order like it is done in the PrsComboItem enumeration
+  myTypeCombo->insertItem("Scalar Map");   // item 0
+  myTypeCombo->insertItem("Iso Surfaces"); // item 1
+  myTypeCombo->insertItem("Cut Planes");   // item 2
+  myTypeCombo->insertItem("Plot 3D");      // item 3
 
   _PTR(SObject) aSObject = aData.myField;
   long aNumComp = VISU::getValue(aSObject, "myNumComponent").toLong();
   if (aNumComp > 1) {
-    myTypeCombo->insertItem("Deformed Shape");
-    myTypeCombo->insertItem("Vectors");
-    myTypeCombo->insertItem("Stream Lines");
+    myTypeCombo->insertItem("Deformed Shape"); // item 4
+    myTypeCombo->insertItem("Vectors");        // item 5
+    myTypeCombo->insertItem("Stream Lines");   // item 6
   }
   switch (aData.myPrsType) {
   case VISU::TSCALARMAP: //Scalar Map
-    myTypeCombo->setCurrentItem(0);
+    myTypeCombo->setCurrentItem(TSCALARMAP_ITEM);
     break;
   case VISU::TISOSURFACE: //Iso Surfaces
-    myTypeCombo->setCurrentItem(1);
+    myTypeCombo->setCurrentItem(TISOSURFACE_ITEM);
     break;
   case VISU::TCUTPLANES: //Cut Planes
-    myTypeCombo->setCurrentItem(2);
+    myTypeCombo->setCurrentItem(TCUTPLANES_ITEM);
+    break;
+  case VISU::TPLOT3D: //Plot 3D
+    myTypeCombo->setCurrentItem(TPLOT3D_ITEM);
     break;
   case VISU::TDEFORMEDSHAPE: //Deformed Shape
-    myTypeCombo->setCurrentItem(3);
+    myTypeCombo->setCurrentItem(TDEFORMEDSHAPE_ITEM);
     break;
   case VISU::TVECTORS: //Vectors
-    myTypeCombo->setCurrentItem(4);
+    myTypeCombo->setCurrentItem(TVECTORS_ITEM);
     break;
   case VISU::TSTREAMLINES: //Stream Lines
-    myTypeCombo->setCurrentItem(5);
+    myTypeCombo->setCurrentItem(TSTREAMLINES_ITEM);
     aData.myPrsType = VISU::TSTREAMLINES;
     break;
   }
@@ -529,22 +608,25 @@ void SetupDlg::onTypeChanged (int theIndex)
 {
   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
   switch (theIndex) {
-  case 0: //Scalar Map
+  case TSCALARMAP_ITEM: //Scalar Map
     aData.myPrsType = VISU::TSCALARMAP;
     break;
-  case 1: //Iso Surfaces
+  case TISOSURFACE_ITEM: //Iso Surfaces
     aData.myPrsType = VISU::TISOSURFACE;
     break;
-  case 2: //Cut Planes
+  case TCUTPLANES_ITEM: //Cut Planes
     aData.myPrsType = VISU::TCUTPLANES;
     break;
-  case 3: //Deformed Shape
+  case TPLOT3D_ITEM: //Plot 3D
+    aData.myPrsType = VISU::TPLOT3D;
+    break;
+  case TDEFORMEDSHAPE_ITEM: //Deformed Shape
     aData.myPrsType = VISU::TDEFORMEDSHAPE;
     break;
-  case 4: //Vectors
+  case TVECTORS_ITEM: //Vectors
     aData.myPrsType = VISU::TVECTORS;
     break;
-  case 5: //Stream Lines
+  case TSTREAMLINES_ITEM: //Stream Lines
     aData.myPrsType = VISU::TSTREAMLINES;
     break;
   }
@@ -573,7 +655,6 @@ void SetupDlg::onTypeChanged (int theIndex)
 //************************************************************************
 void SetupDlg::onPreferencesDlg()
 {
-  MESSAGE("SetupDlg::onPreferencesDlg() is not implemented");
   SUIT_OverrideCursor c;
   FieldData& aData = myAnimator->getFieldData(myFieldLst->currentItem());
   if (aData.myPrs.empty())
@@ -593,7 +674,7 @@ void SetupDlg::onPreferencesDlg()
 
 
 #define EDITPRS(TYPE, DLG) {\
-        DLG* aDlg = new DLG(this);\
+        DLG* aDlg = new DLG (myModule);\
         aDlg->initFromPrsObject(dynamic_cast<TYPE*>(aData.myPrs[0]));\
         if (aDlg->exec())\
         { \
@@ -603,19 +684,19 @@ void SetupDlg::onPreferencesDlg()
         delete aDlg;}
 
   switch (myTypeCombo->currentItem()) {
-  case 0: //Scalar Map
+  case TSCALARMAP_ITEM: //Scalar Map
     c.suspend();
     EDITPRS(VISU::ScalarMap_i, VisuGUI_ScalarBarDlg);
     break;
-  case 1: //Iso Surfaces
+  case TISOSURFACE_ITEM: //Iso Surfaces
     c.suspend();
     EDITPRS(VISU::IsoSurfaces_i, VisuGUI_IsoSurfacesDlg);
     break;
-  case 2: //Cut Planes
-    //    EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
-    {
-      c.suspend();
-      VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg(false, true);
+  case TCUTPLANES_ITEM: //Cut Planes
+    c.suspend();
+    EDITPRS(VISU::CutPlanes_i, VisuGUI_CutPlanesDlg);
+    /*{
+      VisuGUI_CutPlanesDlg* aDlg = new VisuGUI_CutPlanesDlg (myModule);
       //_CS_PhB :operator [] .at      aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs.at(0)));
       aDlg->initFromPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[0]));
 
@@ -625,28 +706,31 @@ void SetupDlg::onPreferencesDlg()
          aDlg->storeToPrsObject(dynamic_cast<VISU::CutPlanes_i*>(aData.myPrs[i]));
       }
       delete aDlg;
-    }
+    }*/
+    break;
+  case TPLOT3D_ITEM: //Plot 3D
+    c.suspend();
+    EDITPRS(VISU::Plot3D_i, VisuGUI_Plot3DDlg);
     break;
-  case 3: //Deformed Shape
+  case TDEFORMEDSHAPE_ITEM: //Deformed Shape
     c.suspend();
     EDITPRS(VISU::DeformedShape_i, VisuGUI_DeformedShapeDlg);
     break;
-  case 4: //Vectors
+  case TVECTORS_ITEM: //Vectors
     c.suspend();
     EDITPRS(VISU::Vectors_i, VisuGUI_VectorsDlg);
     break;
-  case 5: //Stream Lines
+  case TSTREAMLINES_ITEM: //Stream Lines
     c.suspend();
     EDITPRS(VISU::StreamLines_i, VisuGUI_StreamLinesDlg);
     break;
   }
 #undef EDITPRS
-
 }
 
 
 //************************************************************************
-void SetupDlg::onArrangeDlg() 
+void SetupDlg::onArrangeDlg()
 {
   ArrangeDlg aDlg(this, myAnimator);
   aDlg.exec();
@@ -806,19 +890,16 @@ static const char * pauseIco[] = {
 static QPixmap MYpausePixmap(pauseIco);
 
 
-//VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (QWidget* parent, _PTR(Study) theStudy)
-//     : QDialog(parent, "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
 VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule, _PTR(Study) theStudy)
      : QDialog(VISU::GetDesktop(theModule), "VisuGUI_TimeAnimationDlg", false, WStyle_Customize |
-               WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose)
+               WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+       myModule(theModule),
+       myStudy(theStudy)
 {
   setCaption("Animation");
   setSizeGripEnabled( TRUE );
-  myModule = theModule;
-  myStudy = theStudy;
   isClosing = false;
 
-  //myAnimator = new VISU_TimeAnimation (VISU::GetDSStudy(theStudy));
   myAnimator = new VISU_TimeAnimation (theStudy);
   myAnimator->setSpeed(1);
   myAnimator->setViewer(VISU::GetViewWindow());
@@ -975,6 +1056,9 @@ VisuGUI_TimeAnimationDlg::VisuGUI_TimeAnimationDlg (VisuGUI* theModule, _PTR(Stu
   QPushButton* aCloseBtn = new QPushButton(tr("BUT_CLOSE"), aBtnBox);
   connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
 
+  SUIT_Study* aStudy = VISU::GetAppStudy(myModule);
+  connect(aStudy, SIGNAL(destroyed()), this, SLOT(close()));
+
   aMainLayout->addWidget(aBtnBox);
 
   myPlayFrame->setEnabled(false);
@@ -1000,7 +1084,7 @@ void VisuGUI_TimeAnimationDlg::onTypeChange (int index)
 void VisuGUI_TimeAnimationDlg::addField (_PTR(SObject) theSObject)
 {
   myPlayFrame->setEnabled(false);
-  myAnimator->addField(VISU::GetSObject(theSObject));
+  myAnimator->addField(theSObject);
 }
 
 //************************************************************************
@@ -1134,7 +1218,7 @@ void VisuGUI_TimeAnimationDlg::onExecution (long theNewFrame, double theTime)
 void VisuGUI_TimeAnimationDlg::onSetupDlg()
 {
   if (myAnimator->getNbFrames() > 0) myAnimator->firstFrame();
-  SetupDlg* aDlg = new SetupDlg(this, myAnimator);
+  SetupDlg* aDlg = new SetupDlg (myModule, myAnimator);
   aDlg->exec();
   myPlayFrame->setEnabled(false);
   delete aDlg;
@@ -1162,22 +1246,22 @@ void VisuGUI_TimeAnimationDlg::onStop()
 }
 
 //************************************************************************
-void VisuGUI_TimeAnimationDlg::saveToStudy() 
+void VisuGUI_TimeAnimationDlg::saveToStudy()
 {
   myAnimator->saveAnimation();
-  myModule->updateObjBrowser( true );
+  VISU::UpdateObjBrowser(myModule, true);
 }
 
 //************************************************************************
 void VisuGUI_TimeAnimationDlg::publishToStudy()
 {
   myAnimator->publishInStudy();
-  myModule->updateObjBrowser( true );
+  VISU::UpdateObjBrowser(myModule, true);
   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());
 }
 
 //************************************************************************
-void VisuGUI_TimeAnimationDlg::restoreFromStudy(SALOMEDS::SObject_var theAnimation)
+void VisuGUI_TimeAnimationDlg::restoreFromStudy(_PTR(SObject) theAnimation)
 {
   myAnimator->restoreFromStudy(theAnimation);
   mySaveBtn->setEnabled(myAnimator->isSavedInStudy());