Salome HOME
0020977: EDF 1520 SMESH: Create a clipping plane on several groups
authorouv <ouv@opencascade.com>
Mon, 25 Oct 2010 13:43:31 +0000 (13:43 +0000)
committerouv <ouv@opencascade.com>
Mon, 25 Oct 2010 13:43:31 +0000 (13:43 +0000)
14 files changed:
doc/salome/gui/SMESH/images/a-clipping2.png
doc/salome/gui/SMESH/images/image79.jpg
doc/salome/gui/SMESH/images/image99.gif
doc/salome/gui/SMESH/input/clipping.doc
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Actor.h
src/OBJECT/SMESH_ActorDef.h
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_ClippingDlg.cxx
src/SMESHGUI/SMESHGUI_ClippingDlg.h
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESHGUI/SMESH_msg_en.ts

index bfac4cea53acd9b713925ea20e3e34e0edf45f19..9d1249c68694fb6d24d18e92d9246522b8648574 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/a-clipping2.png and b/doc/salome/gui/SMESH/images/a-clipping2.png differ
index 6d164167fb70656b96bdf17c574eb4ed3765009c..0efc736950fdfe0da08551e01812327ecde6a5f0 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image79.jpg and b/doc/salome/gui/SMESH/images/image79.jpg differ
index 4959ed82548939a522238bb5b9c57adb0d1dfb6d..2672e99f3241466518910e294744154285d7cc9b 100755 (executable)
Binary files a/doc/salome/gui/SMESH/images/image99.gif and b/doc/salome/gui/SMESH/images/image99.gif differ
index f3b19f3742cd61033b1c20584a5f0a2482270206..df3e39495f7902a152e70f6465df1f64c3fd70c9 100644 (file)
@@ -9,11 +9,14 @@ To start, click on the \em New button.
 
 \image html a-clipping2.png
 
-Now you can define the parameters of your cross-section: \b Orientation
-(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the
-object, if it is set to 0.5 the object is split in two halves; and
-\b Rotation (in angle degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to
-Z). If the <b>Show preview</b> button is on, you can see the clipping plane
+Now you can define the parameters of your cross-section: list of
+<b>meshes, sub-meshes and groups</b> the cross-section will be applied to
+(<b>Select all</b> button allows to select and deselect all available
+objects at once), \b Orientation (X-Y, X-Z or Y-Z); \b Distance between the
+opposite extremities of the boundary box of selected objects, if it is set
+to 0.5 the boundary box is split in two halves; and \b Rotation (in angle
+degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to Z).
+If the <b>Show preview</b> button is on, you can see the clipping plane
 in the <b>3D Viewer</b>.
 
 \image html image79.jpg "The plane and the cut object"
index 4e2943ba66ba0d94a6a3822f43d3a52b3869921c..8386faf3aa6d70c2ab2ff85e141452967c0a9ff0 100644 (file)
@@ -500,6 +500,9 @@ SMESH_ActorDef::~SMESH_ActorDef()
 {
   if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<<this);
 
+  // caught by SMESHGUI::ProcessEvents() static method
+  this->InvokeEvent( SMESH::DeleteActorEvent, NULL );
+
   myScalarBarActor->Delete();
   myLookupTable->Delete();
 
@@ -1823,92 +1826,6 @@ GetClippingPlane(vtkIdType theID)
   return myCippingPlaneCont[theID].Get();
 }
 
-
-static void ComputeBoundsParam(vtkDataSet* theDataSet,
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType theMinPnt[3],
-                               vtkFloatingPointType& theMaxBoundPrj, vtkFloatingPointType& theMinBoundPrj)
-{
-  vtkFloatingPointType aBounds[6];
-  theDataSet->GetBounds(aBounds);
-
-  //Enlarge bounds in order to avoid conflicts of precision
-  for(int i = 0; i < 6; i += 2){
-    static double EPS = 1.0E-3;
-    vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
-    aBounds[i] -= aDelta;
-    aBounds[i+1] += aDelta;
-  }
-
-  vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
-                               {aBounds[1],aBounds[2],aBounds[4]},
-                               {aBounds[0],aBounds[3],aBounds[4]},
-                               {aBounds[1],aBounds[3],aBounds[4]},
-                               {aBounds[0],aBounds[2],aBounds[5]},
-                               {aBounds[1],aBounds[2],aBounds[5]}, 
-                               {aBounds[0],aBounds[3],aBounds[5]}, 
-                               {aBounds[1],aBounds[3],aBounds[5]}};
-
-  int aMaxId = 0, aMinId = aMaxId;
-  theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
-  theMinBoundPrj = theMaxBoundPrj;
-  for(int i = 1; i < 8; i++){
-    vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
-    if(theMaxBoundPrj < aTmp){
-      theMaxBoundPrj = aTmp;
-      aMaxId = i;
-    }
-    if(theMinBoundPrj > aTmp){
-      theMinBoundPrj = aTmp;
-      aMinId = i;
-    }
-  }
-  vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
-  theMinPnt[0] = aMinPnt[0];
-  theMinPnt[1] = aMinPnt[1];
-  theMinPnt[2] = aMinPnt[2];
-}
-
-
-static void DistanceToPosition(vtkDataSet* theDataSet,
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType theDist, vtkFloatingPointType thePos[3])
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
-  thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
-  thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
-  thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
-}
-
-
-static void PositionToDistance(vtkDataSet* theDataSet, 
-                               vtkFloatingPointType theDirection[3], vtkFloatingPointType thePos[3], vtkFloatingPointType& theDist)
-{
-  vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
-  vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
-  theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
-}
-
-
-void SMESH_ActorDef::SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane)
-{
-  thePlane->SetNormal(theDir);
-  vtkFloatingPointType anOrigin[3];
-  ::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin);
-  thePlane->SetOrigin(anOrigin);
-}
-
-
-void SMESH_ActorDef::GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane)
-{
-  thePlane->GetNormal(theDir);
-
-  vtkFloatingPointType anOrigin[3];
-  thePlane->GetOrigin(anOrigin);
-  ::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist);
-}
-
 void SMESH_ActorDef::UpdateScalarBar()
 {
   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
index 31d5b9f3e8733c371c72aca4029888471680b2d0..c2d46098ace0ea04e78bb854302efa2ab6492ca7 100644 (file)
@@ -31,6 +31,8 @@
 #include <SALOME_Actor.h>
 #include "SMESH_Object.h"
 
+#include <vtkCommand.h>
+
 class vtkUnstructuredGrid;
 
 class vtkScalarBarActor;
@@ -38,6 +40,11 @@ class vtkScalarBarActor;
 class vtkPlane;
 class vtkImplicitBoolean;
 
+namespace SMESH
+{
+  const vtkIdType DeleteActorEvent = vtkCommand::UserEvent + 100;
+}
+
 class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
 {
   static SMESH_Actor* New() { return NULL;}
@@ -123,9 +130,6 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
 
   virtual vtkScalarBarActor* GetScalarBarActor() = 0;
 
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) = 0;
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) = 0;
-
   virtual void RemoveAllClippingPlanes() = 0; 
   virtual vtkIdType GetNumberOfClippingPlanes() = 0; 
   virtual vtkPlane* GetClippingPlane(vtkIdType theID) = 0; 
index 44bc4f56afa374598a5bbd436edd86032b6fb2bb..9b1c4df1dfda65c3ece32903b7defe4649ecd472 100644 (file)
@@ -189,9 +189,6 @@ class SMESH_ActorDef : public SMESH_Actor
 
   virtual vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
 
-  virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane);
-  virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane);
-
   virtual void RemoveAllClippingPlanes();
   virtual vtkIdType GetNumberOfClippingPlanes();
   virtual vtkPlane* GetClippingPlane(vtkIdType theID);
index f766be62e12e820a3b5c8d9756f289440d352f14..8601f8147924b75fe4fe73731a17a3897fcdf80f 100644 (file)
 #include <vtkCamera.h>
 #include <vtkRenderer.h>
 #include <vtkPlane.h>
+#include <vtkCallbackCommand.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_Study.hxx>
     if( !aSel || !appStudy )
       return;
 
+    if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection
+      if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
+        aModule->EmitSignalDeactivateDialog();
+        if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
+          (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show();
+      }
+      return;
+    }
+
     _PTR(Study) aStudy = appStudy->studyDS();
 
     aSel->selectedObjects( selected );
 
     if(selected.Extent() >= 1){
       switch(theCommandID){
-      case 1134:{
-        SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
-        (new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show();
-        return;
-      }
       case 1133:{
         SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
         (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
@@ -1419,6 +1424,12 @@ LightApp_Module( "SMESH" )
   myState = -1;
   myDisplayer = 0;
 
+  myEventCallbackCommand = vtkCallbackCommand::New();
+  myEventCallbackCommand->Delete();
+  myEventCallbackCommand->SetClientData( this );
+  myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
+  myPriority = 0.0;
+
   SMESH::GetFilterManager();
   SMESH::GetPattern();
 
@@ -3682,14 +3693,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->insert( action( 1133 ), -1, -1 );
   popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
 
-  //-------------------------------------------------
-  // Clipping
-  //-------------------------------------------------
-  popupMgr()->insert( action( 1134 ), -1, -1 );
-  popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule );
-
-  popupMgr()->insert( separator(), -1, -1 );
-
   //-------------------------------------------------
   // Controls
   //-------------------------------------------------
@@ -3815,8 +3818,19 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   popupMgr()->insert( separator(), -1, -1 );
 
+  //-------------------------------------------------
+  // Clipping
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1134 ), -1, -1 );
+  popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
            this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
+
+  connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
+           this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
 }
 
 //================================================================================
@@ -3973,6 +3987,49 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
     SMESH::UpdateSelectionProp( this );
 }
 
+void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
+{
+  if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() )
+    myClippingPlaneInfoMap.erase( theViewManager );
+}
+
+void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor )
+{
+  theActor->AddObserver( SMESH::DeleteActorEvent,
+                         myEventCallbackCommand.GetPointer(),
+                         myPriority );
+}
+
+void SMESHGUI::ProcessEvents( vtkObject* theObject,
+                              unsigned long theEvent,
+                              void* theClientData,
+                              void* theCallData )
+{
+  if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
+    if( theObject && theEvent == SMESH::DeleteActorEvent ) {
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
+        SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
+        SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
+        for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) {
+          SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+          SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin();
+          for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+            SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+            std::list<vtkActor*>& anActorList = aClippingPlaneInfo.ActorList;
+            SMESH::TActorList::iterator anIter3 = anActorList.begin();
+            for ( ; anIter3 != anActorList.end(); anIter3++ ) {
+              if( anActor == *anIter3 ) {
+                anActorList.erase( anIter3 );
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
 void SMESHGUI::createPreferences()
 {
   // General tab ------------------------------------------------------------------------
@@ -4481,12 +4538,9 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
       if( aTolerance < 1 )
         break;
     }
-    //cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl;
 
     aHue = (int)( 360.0 * rand() / RAND_MAX );
-    //cout << "Hue = " << aHue << endl;
 
-    //cout << "Auto colors : ";
     bool ok = true;
     QList<SALOMEDS::Color>::const_iterator it = theReservedColors.constBegin();
     QList<SALOMEDS::Color>::const_iterator itEnd = theReservedColors.constEnd();
@@ -4497,21 +4551,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
 
       int h, s, v;
       aQColor.getHsv( &h, &s, &v );
-      //cout << h << " ";
       if( abs( h - aHue ) < aTolerance )
       {
         ok = false;
-        //cout << "break (diff = " << abs( h - aHue ) << ")";
         break;
       }
     }
-    //cout << endl;
 
     if( ok )
       break;
   }
 
-  //cout << "Hue of the returned color = " << aHue << endl;
   QColor aColor;
   aColor.setHsv( aHue, 255, 255 );
 
@@ -4599,6 +4649,37 @@ void SMESHGUI::storeVisualParameters (int savePoint)
     // saving VTK actors properties
     if (vType == SVTK_Viewer::Type())
     {
+      // store the clipping planes attached to the view manager
+      SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList;
+      SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman );
+      if( anIter != myClippingPlaneInfoMap.end() )
+        aClippingPlaneInfoList = anIter->second;
+
+      if( !aClippingPlaneInfoList.empty() ) {
+        SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin();
+        for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ )
+        {
+          const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter;
+          SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane;
+
+          QString aPropertyName( "ClippingPlane" );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( vtkViewers );
+          aPropertyName += gSeparator;
+          aPropertyName += QString::number( anId );
+
+          QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData();
+          aPropertyValue += gDigitsSep;
+          aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData();
+
+          ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() );
+        }
+      }
+
       QVector<SUIT_ViewWindow*> views = vman->getViews();
       for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++)
       {
@@ -4724,22 +4805,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
 
                   // Clipping
                   param = vtkParam + "ClippingPlane";
-                  int nPlanes = aSmeshActor->GetNumberOfClippingPlanes();
-                  if (!nPlanes)
-                    ip->setParameter(entry, param, "Off");
-                  for (int ipl = 0; ipl < nPlanes; ipl++) {
-                    //vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl);
-                    SMESH::Orientation anOrientation;
-                    double aDistance;
-                    vtkFloatingPointType anAngle[2];
-                    SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle);
-                    std::string planeValue = QString::number((int)anOrientation).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data();
-                    planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data();
-
-                    ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue);
+                  int aPlaneId = 0;
+                  if( !aClippingPlaneInfoList.empty() ) {
+                    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin();
+                    for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ )
+                    {
+                      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1;
+                      std::list<vtkActor*> anActorList = aClippingPlaneInfo.ActorList;
+                      SMESH::TActorList::iterator anIter2 = anActorList.begin();
+                      for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+                        if( aSmeshActor == *anIter2 ) {
+                          ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(),
+                                            QString::number( anId ).toLatin1().constData() );                          
+                          break;
+                        }
+                      }
+                    }
                   }
+                  if( aPlaneId == 0 )
+                    ip->setParameter( entry, param, "Off" );
                 } // if (io->hasEntry())
               } // SMESH_Actor && hasIO
             } // isVisible
@@ -4751,6 +4835,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
   } // for (viewManagers)
 }
 
+// data structures for clipping planes processing
+typedef struct {
+  int Id;
+  vtkIdType Orientation;
+  vtkFloatingPointType Distance;
+  vtkFloatingPointType Angle[2];
+} TPlaneData;
+typedef std::list<TPlaneData>         TPlaneDataList;
+typedef std::map<int, TPlaneDataList> TPlaneDataMap;
+
+typedef std::list<vtkActor*>          TActorList;
+typedef struct {
+  int PlaneId;
+  TActorList ActorList;
+  SUIT_ViewManager* ViewManager;
+} TPlaneInfo;
+typedef std::list<TPlaneInfo>         TPlaneInfoList;
+typedef std::map<int, TPlaneInfoList> TPlaneInfoMap;
+
 /*!
  * \brief Restore visual parameters
  *
@@ -4775,8 +4878,9 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                                                              savePoint);
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
 
-  // restore map of custom markers
+  // restore map of custom markers and map of clipping planes
   VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ];
+  TPlaneDataMap aPlaneDataMap;
 
   std::vector<std::string> properties = ip->getProperties();
   for (std::vector<std::string>::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt)
@@ -4786,52 +4890,103 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     QString aPropertyValue( ip->getProperty( property ).c_str() );
 
     QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts );
-    if( aPropertyNameList.size() != 2 )
+    if( aPropertyNameList.isEmpty() )
       continue;
 
-    int anId = 0;
-    bool ok = false;
-    if( aPropertyNameList[0] == "texture" )
-      anId = aPropertyNameList[1].toInt( &ok );
+    QString aPropertyType = aPropertyNameList[0];
+    if( aPropertyType == "texture" )
+    {
+      if( aPropertyNameList.size() != 2 )
+        continue;
 
-    if( !ok || anId < 1 )
-      continue;
+      bool ok = false;
+      int anId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || anId < 1 )
+        continue;
 
-    QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
-    if( aPropertyValueList.size() != 2 )
-      continue;
+      QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 2 )
+        continue;
 
-    std::string aMarkerFileName = aPropertyValueList[0].toStdString();
-    QString aMarkerTextureString = aPropertyValueList[1];
-    QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
-    if( aMarkerTextureStringList.size() != 3 )
-      continue;
+      std::string aMarkerFileName = aPropertyValueList[0].toStdString();
+      QString aMarkerTextureString = aPropertyValueList[1];
+      QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aMarkerTextureStringList.size() != 3 )
+        continue;
 
-    ok = false;
-    ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
-    if( !ok )
-      continue;
+      ok = false;
+      ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
+      if( !ok )
+        continue;
 
-    ok = false;
-    ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
-    if( !ok )
-      continue;
+      ok = false;
+      ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
+      if( !ok )
+        continue;
 
-    VTK::MarkerTexture aMarkerTexture;
-    aMarkerTexture.push_back( aWidth );
-    aMarkerTexture.push_back( aHeight );
+      VTK::MarkerTexture aMarkerTexture;
+      aMarkerTexture.push_back( aWidth );
+      aMarkerTexture.push_back( aHeight );
 
-    QString aMarkerTextureData = aMarkerTextureStringList[2];
-    for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
-    {
-      QChar aChar = aMarkerTextureData.at( i );
-      if( aChar.isDigit() )
-        aMarkerTexture.push_back( aChar.digitValue() );
+      QString aMarkerTextureData = aMarkerTextureStringList[2];
+      for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
+      {
+        QChar aChar = aMarkerTextureData.at( i );
+        if( aChar.isDigit() )
+          aMarkerTexture.push_back( aChar.digitValue() );
+      }
+
+      aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
     }
+    else if( aPropertyType == "ClippingPlane" )
+    {
+      if( aPropertyNameList.size() != 3 )
+        continue;
 
-    aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
+      bool ok = false;
+      int aViewId = aPropertyNameList[1].toInt( &ok );
+      if( !ok || aViewId < 0 )
+        continue;
+
+      ok = false;
+      int aClippingPlaneId = aPropertyNameList[2].toInt( &ok );
+      if( !ok || aClippingPlaneId < 0 )
+        continue;
+
+      QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts );
+      if( aPropertyValueList.size() != 4 )
+        continue;
+
+      TPlaneData aPlaneData;
+      aPlaneData.Id = aClippingPlaneId;
+
+      ok = false;
+      aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      ok = false;
+      aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok );
+      if( !ok )
+        continue;
+
+      TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ];
+      aPlaneDataList.push_back( aPlaneData );      
+    }
   }
 
+  TPlaneInfoMap aPlaneInfoMap;
+
   std::vector<std::string> entries = ip->getEntries();
 
   for (std::vector<std::string>::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt)
@@ -4878,39 +5033,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
         if (vtkActors.IsBound(viewIndex))
           aSmeshActor = vtkActors.Find(viewIndex);
 
+        QList<SUIT_ViewManager*> lst;
+        getApp()->viewManagers(viewerTypStr, lst);
+
+        // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
+        SUIT_ViewManager* vman = NULL;
+        if (viewIndex >= 0 && viewIndex < lst.count())
+          vman = lst.at(viewIndex);
+
         if (paramNameStr == "Visibility")
         {
-          if (!aSmeshActor && displayer())
+          if (!aSmeshActor && displayer() && vman)
           {
-            QList<SUIT_ViewManager*> lst;
-            getApp()->viewManagers(viewerTypStr, lst);
-
-            // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
-            if (viewIndex >= 0 && viewIndex < lst.count()) {
-              SUIT_ViewManager* vman = lst.at(viewIndex);
-              SUIT_ViewModel* vmodel = vman->getViewModel();
-              // SVTK view model can be casted to SALOME_View
-              displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
-
-              // store displayed actor in a temporary map for quicker
-              // access later when restoring other parameters
-              SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-              vtkRenderer* Renderer = vtkView->getRenderer();
-              VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
-              vtkActorCollection* theActors = aCopy.GetActors();
-              theActors->InitTraversal();
-              bool isFound = false;
-              vtkActor *ac = theActors->GetNextActor();
-              for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
-                if (ac->IsA("SMESH_Actor")) {
-                  SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
-                  if (aGeomAc->hasIO()) {
-                    Handle(SALOME_InteractiveObject) io =
-                      Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
-                    if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
-                      isFound = true;
-                      vtkActors.Bind(viewIndex, aGeomAc);
-                    }
+            SUIT_ViewModel* vmodel = vman->getViewModel();
+            // SVTK view model can be casted to SALOME_View
+            displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
+
+            // store displayed actor in a temporary map for quicker
+            // access later when restoring other parameters
+            SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
+            vtkRenderer* Renderer = vtkView->getRenderer();
+            VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
+            vtkActorCollection* theActors = aCopy.GetActors();
+            theActors->InitTraversal();
+            bool isFound = false;
+            vtkActor *ac = theActors->GetNextActor();
+            for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
+              if (ac->IsA("SMESH_Actor")) {
+                SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
+                if (aGeomAc->hasIO()) {
+                  Handle(SALOME_InteractiveObject) io =
+                    Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
+                  if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
+                    isFound = true;
+                    vtkActors.Bind(viewIndex, aGeomAc);
                   }
                 }
               }
@@ -5027,14 +5183,16 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
             }
             // Clipping
             else if (paramNameStr.startsWith("ClippingPlane")) {
-              cout << "$$$ ClippingPlane 1" << endl;
-              if (paramNameStr == "ClippingPlane1" || val == "Off")
-                aSmeshActor->RemoveAllClippingPlanes();
-              if (val != "Off") {
-                cout << "$$$ ClippingPlane 2" << endl;
-                QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
-                if (vals.count() == 4) { // format check: 4 values
-                  cout << "$$$ ClippingPlane 3" << endl;
+              QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
+              // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles)
+              // new format - val looks like "Off" or "0" (plane id)
+              // (note: in new format "Off" value is used only for consistency,
+              //  so it is processed together with values in old format)
+              bool anIsOldFormat = ( vals.count() == 4 || val == "Off" );
+              if( anIsOldFormat ) {
+                if (paramNameStr == "ClippingPlane1" || val == "Off")
+                  aSmeshActor->RemoveAllClippingPlanes();
+                if (val != "Off") {
                   SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt();
                   double aDistance = vals[1].toFloat();
                   vtkFloatingPointType anAngle[2];
@@ -5047,8 +5205,43 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                   if (viewIndex >= 0 && viewIndex < lst.count()) {
                     SUIT_ViewManager* vman = lst.at(viewIndex);
                     SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
-                    SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView,
-                                                   anOrientation, aDistance, anAngle);
+
+                    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ];
+
+                    SMESH::TActorList anActorList;
+                    anActorList.push_back( aSmeshActor );
+                    SMESH::OrientedPlane* aPlane =
+                      SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle);
+                    if( aPlane ) {
+                      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+                      aClippingPlaneInfo.Plane = aPlane;
+                      aClippingPlaneInfo.ActorList = anActorList;
+                      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+                    }
+                  }
+                }
+              }
+              else {
+                bool ok = false;
+                int aPlaneId = val.toInt( &ok );
+                if( ok && aPlaneId >= 0 ) {
+                  bool anIsDefinedPlane = false;
+                  TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ];
+                  TPlaneInfoList::iterator anIter = aPlaneInfoList.begin();
+                  for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
+                    TPlaneInfo& aPlaneInfo = *anIter;
+                    if( aPlaneInfo.PlaneId == aPlaneId ) {
+                      aPlaneInfo.ActorList.push_back( aSmeshActor );
+                      anIsDefinedPlane = true;
+                      break;
+                    }
+                  }
+                  if( !anIsDefinedPlane ) {
+                    TPlaneInfo aPlaneInfo;
+                    aPlaneInfo.PlaneId = aPlaneId;
+                    aPlaneInfo.ActorList.push_back( aSmeshActor );
+                    aPlaneInfo.ViewManager = vman;
+                    aPlaneInfoList.push_back( aPlaneInfo );
                   }
                 }
               }
@@ -5059,6 +5252,55 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     } // for names/parameters iterator
   } // for entries iterator
 
+  // add clipping planes to actors according to the restored parameters
+  // and update the clipping plane map
+  TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin();
+  for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) {
+    int aViewId = anIter1->first;
+    const TPlaneInfoList& aPlaneInfoList = anIter1->second;
+
+    TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId );
+    if( anIter2 == aPlaneDataMap.end() )
+      continue;
+    const TPlaneDataList& aPlaneDataList = anIter2->second;
+
+    TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
+    for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
+      const TPlaneInfo& aPlaneInfo = *anIter3;
+      int aPlaneId = aPlaneInfo.PlaneId;
+      const TActorList& anActorList = aPlaneInfo.ActorList;
+      SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager;
+      if( !aViewManager )
+        continue;
+
+      SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>( aViewManager->getActiveView() );
+      if( !aViewWindow )
+        continue;
+
+      SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ];
+
+      TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin();
+      for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) {
+        const TPlaneData& aPlaneData = *anIter4;
+        if( aPlaneData.Id == aPlaneId ) {
+          SMESH::OrientedPlane* aPlane =
+            SMESHGUI_ClippingDlg::AddPlane( anActorList,
+                                            aViewWindow,
+                                            (SMESH::Orientation)aPlaneData.Orientation,
+                                            aPlaneData.Distance,
+                                            aPlaneData.Angle );
+          if( aPlane ) {
+            SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+            aClippingPlaneInfo.Plane = aPlane;
+            aClippingPlaneInfo.ActorList = anActorList;
+            aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
+          }
+          break;
+        }
+      }
+    }
+  }
+
   // update all VTK views
   QList<SUIT_ViewManager*> lst;
   getApp()->viewManagers(lst);
index 4a82e5c1a8b0b08e430cc254965affb14b5ad741..8f86faf6d20d65c48d7f4e4729e36b51bfc6df8b 100644 (file)
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Gen)
 
+// VTK includes
+#include <vtkSmartPointer.h>
+#include <vtkType.h>
+
+class vtkActor;
+class vtkCallbackCommand;
+class vtkObject;
+
 class QDialog;
 
 class SUIT_Desktop;
@@ -52,10 +60,24 @@ class SalomeApp_Study;
 class LightApp_Selection;
 class LightApp_SelectionMgr;
 
+class SMESH_Actor;
 class SMESHGUI_FilterLibraryDlg;
 
 typedef std::map<int, VTK::MarkerMap> SMESHGUI_StudyId2MarkerMap;
 
+namespace SMESH
+{
+  class OrientedPlane;
+  struct ClippingPlaneInfo
+  {
+    OrientedPlane*       Plane;
+    std::list<vtkActor*> ActorList;
+  };
+}
+
+typedef std::list<SMESH::ClippingPlaneInfo>                         SMESHGUI_ClippingPlaneInfoList;
+typedef std::map<SUIT_ViewManager*, SMESHGUI_ClippingPlaneInfoList> SMESHGUI_ClippingPlaneInfoMap;
+
 //=================================================================================
 // class    : SMESHGUI
 // purpose  :
@@ -122,6 +144,10 @@ public :
   virtual void                    storeVisualParameters  (int savePoint);
   virtual void                    restoreVisualParameters(int savePoint);
 
+  virtual void                    addActorAsObserver( SMESH_Actor* theActor );
+
+  SMESHGUI_ClippingPlaneInfoMap&  getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; }
+
 public slots:
   virtual bool                    deactivateModule( SUIT_Study* );
   virtual bool                    activateModule( SUIT_Study* );
@@ -130,6 +156,7 @@ public slots:
 private slots:
   void                            OnGUIEvent();
   void                            onViewManagerActivated( SUIT_ViewManager* );
+  void                            onViewManagerRemoved( SUIT_ViewManager* );
   void                            onOperationCommited( SUIT_Operation* );
   void                            onOperationAborted( SUIT_Operation* );
   void                            onHypothesisEdit( int result );
@@ -159,6 +186,11 @@ protected:
 
   virtual bool                    reusableOperation( const int id ); 
 
+  static void                     ProcessEvents( vtkObject* theObject, 
+                                                 unsigned long theEvent,
+                                                 void* theClientData, 
+                                                 void* theCallData );
+
 private:
   void                            OnEditDelete();
   int                             addVtkFontPref( const QString& label, 
@@ -175,6 +207,10 @@ private :
   SMESHGUI_FilterLibraryDlg*      myFilterLibraryDlg;
 
   SMESHGUI_StudyId2MarkerMap      myMarkerMap;
+  SMESHGUI_ClippingPlaneInfoMap   myClippingPlaneInfoMap;
+
+  vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
+  vtkFloatingPointType            myPriority;
 };
 
 #endif // SMESHGUI_H
index 13bdc8eb44e3c04518864cba9480e5b489f2bd76..ac190be77b4c17d6a890f56631cf20e4e67b2fd2 100644 (file)
 #include <SUIT_OverrideCursor.h>
 #include <SUIT_MessageBox.h>
 #include <SUIT_ResourceMgr.h>
+#include <SUIT_ViewManager.h>
 
 #include <SALOME_ListIO.hxx>
 
+#include <SalomeApp_Study.h>
+
 #include <LightApp_Application.h>
-#include <LightApp_SelectionMgr.h>
+
+#include <VTKViewer_Algorithm.h>
 
 #include <SVTK_ViewWindow.h>
 
 #include <QGridLayout>
 #include <QGroupBox>
 #include <QKeyEvent>
+#include <QListWidget>
 
 // VTK includes
 #include <vtkMath.h>
-#include <vtkPlane.h>
 #include <vtkDataSet.h>
 #include <vtkDataSetMapper.h>
 #include <vtkPlaneSource.h>
 #include <vtkProperty.h>
+#include <vtkRenderer.h>
 
 #define SPACING 6
 #define MARGIN  11
 
-class OrientedPlane: public vtkPlane
+//=================================================================================
+// class    : OrientedPlane
+// purpose  :
+//=================================================================================
+SMESH::OrientedPlane* SMESH::OrientedPlane::New()
 {
-  QPointer<SVTK_ViewWindow> myViewWindow;
-
-  vtkDataSetMapper* myMapper;
-
-public:
-  static OrientedPlane *New()
-  {
-    return new OrientedPlane();
-  }
-  static OrientedPlane *New(SVTK_ViewWindow* theViewWindow)
-  {
-    return new OrientedPlane(theViewWindow);
-  }
-  vtkTypeMacro (OrientedPlane, vtkPlane);
-
-  SMESH::Orientation myOrientation;
-  float myDistance;
-  double myAngle[2];
+  return new OrientedPlane();
+}
 
-  vtkPlaneSource* myPlaneSource;
-  SALOME_Actor *myActor;
+SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow)
+{
+  return new OrientedPlane(theViewWindow);
+}
 
-  void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
-  SMESH::Orientation GetOrientation() { return myOrientation; }
+void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane)
+{
+  SetNormal(theOrientedPlane->GetNormal());
+  SetOrigin(theOrientedPlane->GetOrigin());
 
-  void SetDistance (float theDistance) { myDistance = theDistance; }
-  float GetDistance() { return myDistance; }
+  myOrientation = theOrientedPlane->GetOrientation();
+  myDistance = theOrientedPlane->GetDistance();
 
-  void ShallowCopy (OrientedPlane* theOrientedPlane)
-  {
-    SetNormal(theOrientedPlane->GetNormal());
-    SetOrigin(theOrientedPlane->GetOrigin());
+  myAngle[0] = theOrientedPlane->myAngle[0];
+  myAngle[1] = theOrientedPlane->myAngle[1];
 
-    myOrientation = theOrientedPlane->GetOrientation();
-    myDistance = theOrientedPlane->GetDistance();
+  myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
+  myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
+  myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
+  myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
+}
 
-    myAngle[0] = theOrientedPlane->myAngle[0];
-    myAngle[1] = theOrientedPlane->myAngle[1];
+SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow):
+  myViewWindow(theViewWindow),
+  myOrientation(SMESH::XY),
+  myDistance(0.5)
+{
+  Init();
+  myViewWindow->AddActor(myActor);
+}
 
-    myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal());
-    myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin());
-    myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1());
-    myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2());
-  }
+SMESH::OrientedPlane::OrientedPlane():
+  myOrientation(SMESH::XY),
+  myViewWindow(NULL),
+  myDistance(0.5)
+{
+  Init();
+}
 
-protected:
-  OrientedPlane(SVTK_ViewWindow* theViewWindow):
-    myViewWindow(theViewWindow),
-    myOrientation(SMESH::XY),
-    myDistance(0.5)
-  {
-    Init();
-    myViewWindow->AddActor(myActor);
-  }
+void SMESH::OrientedPlane::Init()
+{
+  myPlaneSource = vtkPlaneSource::New();
+
+  myAngle[0] = myAngle[1] = 0.0;
+
+  // Create and display actor
+  myMapper = vtkDataSetMapper::New();
+  myMapper->SetInput(myPlaneSource->GetOutput());
+
+  myActor = SALOME_Actor::New();
+  myActor->VisibilityOff();
+  myActor->PickableOff();
+  myActor->SetInfinitive(true);
+  myActor->SetMapper(myMapper);
+
+  vtkFloatingPointType anRGB[3];
+  vtkProperty* aProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aProp->SetOpacity(0.75);
+  myActor->SetProperty(aProp);
+  aProp->Delete();
+
+  vtkProperty* aBackProp = vtkProperty::New();
+  SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
+  aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
+  aBackProp->SetOpacity(0.75);
+  myActor->SetBackfaceProperty(aBackProp);
+  aBackProp->Delete();
+}
 
-  OrientedPlane():
-    myOrientation(SMESH::XY),
-    myViewWindow(NULL),
-    myDistance(0.5)
-  {
-    Init();
-  }
+SMESH::OrientedPlane::~OrientedPlane()
+{
+  if (myViewWindow)
+    myViewWindow->RemoveActor(myActor);
+  myActor->Delete();
+    
+  myMapper->RemoveAllInputs();
+  myMapper->Delete();
 
-  void Init()
-  {
-    myPlaneSource = vtkPlaneSource::New();
-
-    myAngle[0] = myAngle[1] = 0.0;
-
-    // Create and display actor
-    myMapper = vtkDataSetMapper::New();
-    myMapper->SetInput(myPlaneSource->GetOutput());
-
-    myActor = SALOME_Actor::New();
-    myActor->VisibilityOff();
-    myActor->PickableOff();
-    myActor->SetInfinitive(true);
-    myActor->SetMapper(myMapper);
-
-    vtkFloatingPointType anRGB[3];
-    vtkProperty* aProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
-    aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aProp->SetOpacity(0.75);
-    myActor->SetProperty(aProp);
-    aProp->Delete();
-
-    vtkProperty* aBackProp = vtkProperty::New();
-    SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) );
-    aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]);
-    aBackProp->SetOpacity(0.75);
-    myActor->SetBackfaceProperty(aBackProp);
-    aBackProp->Delete();
-  }
+  // commented: porting to vtk 5.0
+  //    myPlaneSource->UnRegisterAllOutputs();
+  myPlaneSource->Delete();
+}
 
-  ~OrientedPlane(){
-    if (myViewWindow)
-      myViewWindow->RemoveActor(myActor);
-    myActor->Delete();
-    
-    myMapper->RemoveAllInputs();
-    myMapper->Delete();
+//=================================================================================
+// class    : ActorItem
+// purpose  :
+//=================================================================================
+class ActorItem : public QListWidgetItem
+{
+public:
+  ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) :
+    QListWidgetItem( theName, theListWidget ),
+    myActor( theActor ) {}
 
-    // commented: porting to vtk 5.0
-    //    myPlaneSource->UnRegisterAllOutputs();
-    myPlaneSource->Delete();
-  };
+  SMESH_Actor* getActor() const { return myActor; }
 
 private:
-  // Not implemented.
-  OrientedPlane (const OrientedPlane&);
-  void operator= (const OrientedPlane&);
-
+  SMESH_Actor* myActor;
 };
 
-struct TSetVisiblity {
-  TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){}
-  void operator()(SMESH::TVTKPlane& theOrientedPlane){
-    theOrientedPlane->myActor->SetVisibility(myIsVisible);
+//=================================================================================
+// class    : TSetVisibility
+// purpose  :
+//=================================================================================
+struct TSetVisibility {
+  TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){}
+  void operator()(SMESH::TPlaneData& thePlaneData){
+    thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible);
   }
   int myIsVisible;
 };
@@ -200,13 +203,13 @@ struct TSetVisiblity {
 // used in SMESHGUI::restoreVisualParameters() to avoid
 // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
 //=================================================================================
-void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
-                                     SVTK_ViewWindow*     theViewWindow,
-                                     SMESH::Orientation   theOrientation,
-                                     double               theDistance,
-                                     vtkFloatingPointType theAngle[2])
+SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList          theActorList,
+                                                      SVTK_ViewWindow*           theViewWindow,
+                                                      SMESH::Orientation         theOrientation,
+                                                      double                     theDistance,
+                                                      const vtkFloatingPointType theAngle[2])
 {
-  OrientedPlane* aPlane = OrientedPlane::New(theViewWindow);
+  SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow);
 
   aPlane->myAngle[0] = theAngle[0];
   aPlane->myAngle[1] = theAngle[1];
@@ -256,14 +259,26 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
     vtkMath::Cross(aNormal,aDir[1],aDir[0]);
   }
 
-  // ???
-  theActor->SetPlaneParam(aNormal, theDistance, aPlane);
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+  bool anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
+                                                       aNormal,
+                                                       theDistance,
+                                                       aBounds,
+                                                       anOrigin );
+  if( !anIsOk )
+    return NULL;
 
-  vtkDataSet* aDataSet = theActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
+  aPlane->SetNormal( aNormal );
+  aPlane->SetOrigin( anOrigin );
 
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
+  vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                   ( aBounds[2] + aBounds[3] ) / 2.,
+                                   ( aBounds[4] + aBounds[5] ) / 2. };
+
+  vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                   pow( aBounds[3] - aBounds[2], 2 ) +
+                                   pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
 
   vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
                                        {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
@@ -299,28 +314,13 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor*         theActor,
   aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
   aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
 
-  theActor->AddClippingPlane(aPlane);
-  aPlane->Delete();
-}
+  SMESH::TActorList::iterator anIter = theActorList.begin();
+  for ( ; anIter != theActorList.end(); anIter++ )
+    if( vtkActor* aVTKActor = *anIter )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->AddClippingPlane( aPlane );
 
-//=================================================================================
-// used in SMESHGUI::restoreVisualParameters() to avoid
-// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-//=================================================================================
-void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
-                                          int                   thePlaneIndex,
-                                          SMESH::Orientation&   theOrientation,
-                                          double&               theDistance,
-                                          vtkFloatingPointType* theAngle)
-{
-  if (vtkPlane* aPln = theActor->GetClippingPlane(thePlaneIndex)) {
-    if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aPln)) {
-      theOrientation = aPlane->GetOrientation();
-      theDistance = aPlane->GetDistance();
-      theAngle[0] = aPlane->myAngle[0];
-      theAngle[1] = aPlane->myAngle[1];
-    }
-  }
+  return aPlane;
 }
 
 //=================================================================================
@@ -328,11 +328,10 @@ void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor*          theActor,
 // purpose  :
 //
 //=================================================================================
-SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
+SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ):
   QDialog( SMESH::GetDesktop(theModule) ),
-  mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
-  mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
-  mySMESHGUI(theModule)
+  mySMESHGUI(theModule),
+  myViewWindow(theViewWindow)
 {
   setModal( false );
   setAttribute( Qt::WA_DeleteOnClose, true );
@@ -345,7 +344,7 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   // Controls for selecting, creating, deleting planes
   QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this);
-  QHBoxLayout* GroupPlanesLayout = new QHBoxLayout(GroupPlanes);
+  QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes);
   GroupPlanesLayout->setSpacing(SPACING);
   GroupPlanesLayout->setMargin(MARGIN);
 
@@ -355,10 +354,21 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes);
 
-  GroupPlanesLayout->addWidget(ComboBoxPlanes);
-  GroupPlanesLayout->addStretch();
-  GroupPlanesLayout->addWidget(buttonNew);
-  GroupPlanesLayout->addWidget(buttonDelete);
+  QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes);
+
+  ActorList = new QListWidget(GroupPlanes);
+  ActorList->setSelectionMode(QAbstractItemView::SingleSelection);
+
+  SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes);
+
+  GroupPlanesLayout->addWidget(ComboBoxPlanes,    0, 0);
+  GroupPlanesLayout->addWidget(new QWidget(),     0, 1);
+  GroupPlanesLayout->addWidget(buttonNew,         0, 2);
+  GroupPlanesLayout->addWidget(buttonDelete,      0, 3);
+  GroupPlanesLayout->addWidget(aLabel,            1, 0, 1, 4);
+  GroupPlanesLayout->addWidget(ActorList,         2, 0, 1, 4);
+  GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4);
+  GroupPlanesLayout->setColumnStretch( 1, 1 );
 
   // Controls for defining plane parameters
   QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this);
@@ -437,9 +447,10 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 
   SpinBoxDistance->SetValue(0.5);
 
-  myActor = 0;
   myIsSelectPlane = false;
-  onSelectionChanged();
+
+  initializePlaneData();
+  synchronize();
 
   myHelpFileName = "clipping_page.html";
 
@@ -447,6 +458,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int)));
   connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew()));
   connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete()));
+  connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*)));
+  connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int)));
   connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int)));
   connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
   connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam()));
@@ -458,7 +471,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
   connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
-  connect(mySelectionMgr,  SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged()));
   /* to close dialog if study frame change */
   connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel()));
 
@@ -472,10 +484,9 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ):
 SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg()
 {
   // no need to delete child widgets, Qt does it all for us
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-  if (mySMESHGUI)
-    if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI))
-      SMESH::RenderViewWindow(aViewWindow);
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false));
+  if (myViewWindow)
+    SMESH::RenderViewWindow(myViewWindow);
 }
 
 double SMESHGUI_ClippingDlg::getDistance() const
@@ -504,27 +515,56 @@ double SMESHGUI_ClippingDlg::getRotation2() const
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnApply()
 {
-  if (!myActor)
-    return;
-
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
+  if (myViewWindow) {
     SUIT_OverrideCursor wc;
     
     QWidget *aCurrWid = this->focusWidget();
     aCurrWid->clearFocus();
     aCurrWid->setFocus();
 
-    myActor->RemoveAllClippingPlanes();
-
-    SMESH::TPlanes::iterator anIter = myPlanes.begin();
-    for ( ; anIter != myPlanes.end(); anIter++) {
-      OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-      anOrientedPlane->ShallowCopy(anIter->GetPointer());
-      myActor->AddClippingPlane(anOrientedPlane);
-      anOrientedPlane->Delete();
+    SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+    SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ];
+
+    // clean memory allocated for planes
+    SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin();
+    for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ )
+      if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane )
+        aPlane->Delete();
+
+    aClippingPlaneInfoList.clear();
+
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActor->RemoveAllClippingPlanes();
+
+    SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin();
+    for( ; anIter2 != myPlanes.end(); anIter2++ ) {
+      SMESH::TPlaneData aPlaneData = *anIter2;
+      SMESH::TPlane aPlane = aPlaneData.Plane;
+      SMESH::TActorList anActorList = aPlaneData.ActorList;
+      if( anActorList.empty() )
+        continue;
+
+      SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
+      anOrientedPlane->ShallowCopy(aPlane.GetPointer());
+
+      SMESH::TActorList::iterator anIter3 = anActorList.begin();
+      for( ; anIter3 != anActorList.end(); anIter3++ )
+        if( vtkActor* aVTKActor = *anIter3 )
+          if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+            anActor->AddClippingPlane(anOrientedPlane);
+
+      SMESH::ClippingPlaneInfo aClippingPlaneInfo;
+      aClippingPlaneInfo.Plane = anOrientedPlane;
+      aClippingPlaneInfo.ActorList = anActorList;
+
+      aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
     }
 
-    SMESH::RenderViewWindow(aViewWindow);
+    SMESH::RenderViewWindow( myViewWindow );
   }
 }
 
@@ -571,53 +611,17 @@ void SMESHGUI_ClippingDlg::ClickOnHelp()
   }
 }
 
-//=================================================================================
-// function : onSelectionChanged()
-// purpose  : Called when selection is changed
-//=================================================================================
-void SMESHGUI_ClippingDlg::onSelectionChanged()
-{
-  if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) {
-    const SALOME_ListIO& aList = mySelector->StoredIObjects();
-    if (aList.Extent() > 0) {
-      Handle(SALOME_InteractiveObject) IOS = aList.First();
-      myActor = SMESH::FindActorByEntry(IOS->getEntry());
-      if (myActor) {
-        std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false));
-        myPlanes.clear();
-
-        vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes();
-        for ( ; anId < anEnd; anId++) {
-          if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) {
-            if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){
-              OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow);
-              SMESH::TVTKPlane aTVTKPlane(anOrientedPlane);
-              anOrientedPlane->Delete();
-              aTVTKPlane->ShallowCopy(aPlane);
-              myPlanes.push_back(aTVTKPlane);
-            }
-          }
-        }
-
-        std::for_each(myPlanes.begin(),myPlanes.end(),
-                      TSetVisiblity(PreviewCheckBox->isChecked()));
-      }
-    }
-    SMESH::RenderViewWindow(aViewWindow);
-  }
-  Sinchronize();
-}
-
 //=======================================================================
 // function : onSelectPlane()
 // purpose  :
 //=======================================================================
 void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
-  OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[theIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   // Orientation
   SMESH::Orientation anOrientation = aPlane->GetOrientation();
@@ -644,6 +648,11 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
     break;
   }
   myIsSelectPlane = false;
+
+  // Actors
+  bool anIsBlocked = ActorList->blockSignals( true );
+  updateActorList();
+  ActorList->blockSignals( anIsBlocked );
 }
 
 //=======================================================================
@@ -652,19 +661,31 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex)
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnNew()
 {
-  if (!myActor)
-    return;
+  if(myViewWindow){
+    SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow);
+    SMESH::TPlane aTPlane(aPlane);
+
+    SMESH::TActorList anActorList;
+    VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+    vtkActorCollection* anAllActors = aCopy.GetActors();
+    anAllActors->InitTraversal();
+    while( vtkActor* aVTKActor = anAllActors->GetNextActor() )
+      if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+        anActorList.push_back( anActor );
 
-  if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){
-    OrientedPlane* aPlane = OrientedPlane::New(aViewWindow);
-    SMESH::TVTKPlane aTVTKPlane(aPlane);
-    myPlanes.push_back(aTVTKPlane);
+    SMESH::TPlaneData aPlaneData(aTPlane, anActorList);
+
+    myPlanes.push_back(aPlaneData);
 
     if (PreviewCheckBox->isChecked())
-      aTVTKPlane->myActor->VisibilityOn();
-    
-    Sinchronize();
+      aTPlane->myActor->VisibilityOn();
+
+    bool anIsBlocked = ActorList->blockSignals( true );
+
+    synchronize();
     SetCurrentPlaneParam();
+
+    ActorList->blockSignals( anIsBlocked );
   }
 }
 
@@ -674,20 +695,105 @@ void SMESHGUI_ClippingDlg::ClickOnNew()
 //=======================================================================
 void SMESHGUI_ClippingDlg::ClickOnDelete()
 {
-  if (!myActor || myPlanes.empty())
+  if (myPlanes.empty())
     return;
 
   int aPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex;
-  anIter->GetPointer()->myActor->SetVisibility(false);
+  SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex;
+  SMESH::TPlaneData aPlaneData = *anIter;
+  aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false);
   myPlanes.erase(anIter);
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  Sinchronize();
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  synchronize();
+  SMESH::RenderViewWindow( myViewWindow );
+}
+
+//=======================================================================
+// function : updateActorItem()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem,
+                                            bool theUpdateSelectAll,
+                                            bool theUpdateClippingPlaneMap )
+{
+  // update Select All check box
+  if( theUpdateSelectAll ) {
+    int aNbItems = ActorList->count(), aNbChecked = 0;
+    for( int i = 0; i < aNbItems; i++ )
+      if( QListWidgetItem* anItem = ActorList->item( i ) )
+        if( anItem->checkState() == Qt::Checked )
+          aNbChecked++;
+
+    Qt::CheckState aCheckState = Qt::Unchecked;
+    if( aNbChecked == aNbItems )
+      aCheckState = Qt::Checked;
+    else if( aNbChecked > 0 )
+      aCheckState = Qt::PartiallyChecked;
+
+    bool anIsBlocked = SelectAllCheckBox->blockSignals( true );
+    SelectAllCheckBox->setCheckState( aCheckState );
+    SelectAllCheckBox->blockSignals( anIsBlocked );
+  }
+
+  // update clipping plane map
+  if( theUpdateClippingPlaneMap ) {
+    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( theItem ) ) {
+      if( SMESH_Actor* anActor = anItem->getActor() ) {
+        SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+        SMESH::TActorList& anActorList = aPlaneData.ActorList;
+        bool anIsPushed = false;
+        SMESH::TActorList::iterator anIter = anActorList.begin();
+        for ( ; anIter != anActorList.end(); anIter++ ) {
+          if( anActor == *anIter ) {
+            anIsPushed = true;
+            break;
+          }
+        }
+        if( theItem->checkState() == Qt::Checked && !anIsPushed )
+          anActorList.push_back( anActor );
+        else if( theItem->checkState() == Qt::Unchecked && anIsPushed )
+          anActorList.remove( anActor );
+      }
+    }
+  }
+}
+
+//=======================================================================
+// function : onActorItemChanged()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem )
+{
+  updateActorItem( theItem, true, true );
+  SetCurrentPlaneParam();
+}
+
+//=======================================================================
+// function : onSelectAll()
+// purpose  :
+//=======================================================================
+void SMESHGUI_ClippingDlg::onSelectAll( int theState )
+{
+  if( theState == Qt::PartiallyChecked ) {
+    SelectAllCheckBox->setCheckState( Qt::Checked );
+    return;
+  }
+
+  bool anIsBlocked = ActorList->blockSignals( true );
+  for( int i = 0, n = ActorList->count(); i < n; i++ ) {
+    if( QListWidgetItem* anItem = ActorList->item( i ) ) {
+      anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked );
+      updateActorItem( anItem, false, true );
+    }
+  }
+  SelectAllCheckBox->setTristate( false );
+  ActorList->blockSignals( anIsBlocked );
+  SetCurrentPlaneParam();
 }
 
 //=======================================================================
@@ -717,10 +823,10 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem)
 }
 
 //=======================================================================
-// function : Sinchronize()
+// function : synchronize()
 // purpose  :
 //=======================================================================
-void SMESHGUI_ClippingDlg::Sinchronize()
+void SMESHGUI_ClippingDlg::synchronize()
 {
   int aNbPlanes = myPlanes.size();
   ComboBoxPlanes->clear();
@@ -737,17 +843,22 @@ void SMESHGUI_ClippingDlg::Sinchronize()
   bool anIsControlsEnable = (aPos >= 0);
   if (anIsControlsEnable) {
     onSelectPlane(aPos);
+    updateActorList();
   } else {
     ComboBoxPlanes->addItem(tr("NO_PLANES"));
+    ActorList->clear();
     SpinBoxRot1->SetValue(0.0);
     SpinBoxRot2->SetValue(0.0);
     SpinBoxDistance->SetValue(0.5);
   }
 
+  ActorList->setEnabled(anIsControlsEnable);
+  SelectAllCheckBox->setEnabled(anIsControlsEnable);
   buttonDelete->setEnabled(anIsControlsEnable);
-  buttonApply->setEnabled(anIsControlsEnable);
-  PreviewCheckBox->setEnabled(anIsControlsEnable);
-  AutoApplyCheckBox->setEnabled(anIsControlsEnable);
+  // the following 3 controls should be enabled
+  //buttonApply->setEnabled(anIsControlsEnable);
+  //PreviewCheckBox->setEnabled(anIsControlsEnable);
+  //AutoApplyCheckBox->setEnabled(anIsControlsEnable);
   ComboBoxOrientation->setEnabled(anIsControlsEnable);
   SpinBoxDistance->setEnabled(anIsControlsEnable);
   SpinBoxRot1->setEnabled(anIsControlsEnable);
@@ -775,7 +886,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 
   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer();
+  SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex];
+  SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer();
 
   vtkFloatingPointType aNormal[3];
   SMESH::Orientation anOrientation;
@@ -833,52 +945,69 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
   aPlane->SetOrientation(anOrientation);
   aPlane->SetDistance(getDistance());
 
-  myActor->SetPlaneParam(aNormal, getDistance(), aPlane);
-
-  vtkDataSet* aDataSet = myActor->GetInput();
-  vtkFloatingPointType *aPnt = aDataSet->GetCenter();
-
-  vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
-  vtkFloatingPointType aDel = aDataSet->GetLength()/2.0;
-
-  vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
-                                       {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
-  vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
-
-  vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
-                                    aPnt[1] - aDelta[0][1] - aDelta[1][1],
-                                    aPnt[2] - aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
-                                    aPnt01[1] + aNormal[1],
-                                    aPnt01[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
-
-  vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
-                                    aPnt[1] - aDelta[0][1] + aDelta[1][1],
-                                    aPnt[2] - aDelta[0][2] + aDelta[1][2]};
-  vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
-                                    aPnt11[1] + aNormal[1],
-                                    aPnt11[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
-
-  vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
-                                    aPnt[1] + aDelta[0][1] - aDelta[1][1],
-                                    aPnt[2] + aDelta[0][2] - aDelta[1][2]};
-  vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
-                                    aPnt21[1] + aNormal[1],
-                                    aPnt21[2] + aNormal[2]};
-  vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
-
-  vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
-  aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
-  aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
-  aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
-  aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  SMESH::TActorList anActorList = aPlaneData.ActorList;
+
+  vtkFloatingPointType aBounds[6];
+  vtkFloatingPointType anOrigin[3];
+  bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList,
+                                                       aNormal,
+                                                       getDistance(),
+                                                       aBounds,
+                                                       anOrigin );
+
+  aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() );
+
+  if( anIsOk ) {
+    aPlane->SetNormal( aNormal );
+    aPlane->SetOrigin( anOrigin );
+
+    vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2.,
+                                     ( aBounds[2] + aBounds[3] ) / 2.,
+                                     ( aBounds[4] + aBounds[5] ) / 2. };
+
+    vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) +
+                                     pow( aBounds[3] - aBounds[2], 2 ) +
+                                     pow( aBounds[5] - aBounds[4], 2 ), 0.5 );
+
+    vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel},
+                                         {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}};
+    vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3];
+
+    vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0],
+                                      aPnt01[1] + aNormal[1],
+                                      aPnt01[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0);
+
+    vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0],
+                                      aPnt[1] - aDelta[0][1] + aDelta[1][1],
+                                      aPnt[2] - aDelta[0][2] + aDelta[1][2]};
+    vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0],
+                                      aPnt11[1] + aNormal[1],
+                                      aPnt11[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1);
+
+    vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0],
+                                      aPnt[1] + aDelta[0][1] - aDelta[1][1],
+                                      aPnt[2] + aDelta[0][2] - aDelta[1][2]};
+    vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0],
+                                      aPnt21[1] + aNormal[1],
+                                      aPnt21[2] + aNormal[2]};
+    vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2);
+
+    vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource;
+    aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]);
+    aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]);
+    aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]);
+    aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]);
+  }
 
   if(AutoApplyCheckBox->isChecked())
     ClickOnApply();
 
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=======================================================================
@@ -887,8 +1016,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam()
 //=======================================================================
 void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled)
 {
-  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled));
-  SMESH::RenderViewWindow(SMESH::GetCurrentVtkView());
+  std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled));
+  SMESH::RenderViewWindow( myViewWindow );
 }
 
 //=================================================================================
@@ -906,3 +1035,124 @@ void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e )
     ClickOnHelp();
   }
 }
+
+//=================================================================================
+// function : initializePlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::initializePlaneData()
+{
+  const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap();
+  SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() );
+  if( anIter1 != aClippingPlaneInfoMap.end() ) {
+    const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
+    SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin();
+    for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
+      const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
+      SMESH::TPlane aTPlane( aClippingPlaneInfo.Plane );
+      SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList );
+      myPlanes.push_back( aPlaneData );
+    }
+  }
+  std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) );
+}
+
+//=================================================================================
+// function : updateActorList()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::updateActorList()
+{
+  ActorList->clear();
+
+  SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy();
+  if( !anAppStudy )
+    return;
+
+  _PTR(Study) aStudy = anAppStudy->studyDS();
+  if( !aStudy )
+    return;
+
+  if( !myViewWindow )
+    return;
+
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ];
+  const SMESH::TActorList& anActorList = aPlaneData.ActorList;
+
+  VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() );
+  vtkActorCollection* anAllActors = aCopy.GetActors();
+  anAllActors->InitTraversal();
+  while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) {
+    if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+      if( anActor->hasIO() ) {
+        Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+        if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) {
+          bool anIsChecked = false;
+          SMESH::TActorList::const_iterator anIter = anActorList.begin();
+          for ( ; anIter != anActorList.end(); anIter++ ) {
+            if( vtkActor* aVTKActorRef = *anIter ) {
+              if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) {
+                if( anActorRef == anActor ) {
+                  anIsChecked = true;
+                  break;
+                }
+              }
+            }
+          }
+          QString aName = QString( aSObj->GetName().c_str() );
+          QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList );
+          anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked );
+          updateActorItem( anItem, true, false );
+        }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : getCurrentActors()
+// purpose  :
+//=================================================================================
+SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors()
+{
+  SMESH::TActorList anActorList;
+  for( int i = 0, n = ActorList->count(); i < n; i++ )
+    if( ActorItem* anItem = dynamic_cast<ActorItem*>( ActorList->item( i ) ) )
+      if( anItem->checkState() == Qt::Checked )
+        if( SMESH_Actor* anActor = anItem->getActor() )
+          anActorList.push_back( anActor );
+  return anActorList;
+}
+
+//=================================================================================
+// function : dumpPlaneData()
+// purpose  :
+//=================================================================================
+void SMESHGUI_ClippingDlg::dumpPlaneData() const
+{
+  printf( "----------- Plane Data -----------\n" );
+  int anId = 1;
+  SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin();
+  for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) {
+    SMESH::TPlaneData aPlaneData = *anIter1;
+    SMESH::TPlane aPlane = aPlaneData.Plane;
+    vtkFloatingPointType* aNormal = aPlane->GetNormal();
+    vtkFloatingPointType* anOrigin = aPlane->GetOrigin();
+    printf( "Plane N%d:\n", anId );
+    printf( "  Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] );
+    printf( "  Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] );
+
+    SMESH::TActorList anActorList = aPlaneData.ActorList;
+    SMESH::TActorList::const_iterator anIter2 = anActorList.begin();
+    for ( ; anIter2 != anActorList.end(); anIter2++ ) {
+      if( vtkActor* aVTKActor = *anIter2 ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) )
+          printf( "  - Actor: '%s'\n", anActor->getName() );
+      }
+      else
+        printf( "  - Actor: NULL\n");
+    }
+  }
+  printf( "----------------------------------\n" );
+}
index 0c70ca9c212aaaea79dace5f175ed6bd2ae031c8..87a4b7b9d72f4fc1752b8f49b2fceccf8efd4517 100644 (file)
 
 // Qt includes
 #include <QDialog>
+#include <QPointer>
 
 // VTK includes
+#include <vtkPlane.h>
 #include <vtkSmartPointer.h>
 
 // STL includes
+#include <list>
+#include <map>
 #include <vector>
 
 class QLabel;
 class QPushButton;
 class QCheckBox;
 class QComboBox;
-class LightApp_SelectionMgr;
-class SVTK_Selector;
+class QListWidget;
+class QListWidgetItem;
+class SALOME_Actor;
 class SMESHGUI;
 class SMESH_Actor;
-class OrientedPlane;
 class SMESHGUI_SpinBox;
+class vtkActor;
+class vtkDataSetMapper;
+class vtkPlaneSource;
 
 namespace SMESH
 {
-  typedef vtkSmartPointer<OrientedPlane> TVTKPlane;
-  typedef std::vector<TVTKPlane> TPlanes;
   enum Orientation { XY, YZ, ZX };
-};
 
+  class OrientedPlane: public vtkPlane
+  {
+    QPointer<SVTK_ViewWindow> myViewWindow;
+    vtkDataSetMapper* myMapper;
+
+  public:
+    static OrientedPlane *New();
+    static OrientedPlane *New(SVTK_ViewWindow* theViewWindow);
+    vtkTypeMacro (OrientedPlane, vtkPlane);
+
+    SMESH::Orientation myOrientation;
+    float myDistance;
+    double myAngle[2];
+
+    vtkPlaneSource* myPlaneSource;
+    SALOME_Actor *myActor;
+
+    void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
+    SMESH::Orientation GetOrientation() { return myOrientation; }
+
+    void SetDistance (float theDistance) { myDistance = theDistance; }
+    float GetDistance() { return myDistance; }
+
+    void ShallowCopy (OrientedPlane* theOrientedPlane);
+
+  protected:
+    OrientedPlane(SVTK_ViewWindow* theViewWindow);
+    OrientedPlane();
+
+    void Init();
+
+    ~OrientedPlane();
+  private:
+    // Not implemented.
+    OrientedPlane (const OrientedPlane&);
+    void operator= (const OrientedPlane&);
+  };
+
+  typedef vtkSmartPointer<OrientedPlane>    TPlane;
+  typedef std::list<vtkActor*>              TActorList;
+
+  struct TPlaneData
+  {
+    TPlaneData( TPlane thePlane,
+                TActorList theActorList )
+    {
+      Plane = thePlane;
+      ActorList = theActorList;
+    }
+    TPlane     Plane;
+    TActorList ActorList;
+  };
+
+  typedef std::vector<TPlane>               TPlaneVector;
+  typedef std::vector<TPlaneData>           TPlaneDataVector;
+};
 
 //=================================================================================
 // class    : SMESHGUI_ClippingDlg
@@ -70,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog
   Q_OBJECT
 
 public:
-  SMESHGUI_ClippingDlg( SMESHGUI* );
+  SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* );
   ~SMESHGUI_ClippingDlg();
   
   double                  getDistance() const;
@@ -78,35 +138,42 @@ public:
   double                  getRotation1() const;
   double                  getRotation2() const;
   void                    setRotation( const double, const double );
-  void                    Sinchronize();
 
   // used in SMESHGUI::restoreVisualParameters() to avoid
   // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
-  static void             AddPlane (SMESH_Actor*         theActor,
-                                    SVTK_ViewWindow*     theViewWindow,
-                                    SMESH::Orientation   theOrientation,
-                                    double               theDistance,
-                                    vtkFloatingPointType theAngle[2]);
-
-  static void             GetPlaneParam (SMESH_Actor*          theActor,
-                                         int                   thePlaneIndex,
-                                         SMESH::Orientation&   theOrientation,
-                                         double&               theDistance,
-                                         vtkFloatingPointType* theAngle);
+  static SMESH::OrientedPlane* AddPlane (SMESH::TActorList          theActorList,
+                                         SVTK_ViewWindow*           theViewWindow,
+                                         SMESH::Orientation         theOrientation,
+                                         double                     theDistance,
+                                         const vtkFloatingPointType theAngle[2]);
 
 protected:  
   void                    keyPressEvent( QKeyEvent* );
 
 private:
-  LightApp_SelectionMgr*  mySelectionMgr;
-  SVTK_Selector*          mySelector;
+  void                    initializePlaneData();
+
+  void                    synchronize();
+
+  void                    updateActorList();
+  SMESH::TActorList       getCurrentActors();
+
+  void                    updateActorItem( QListWidgetItem* theItem,
+                                           bool theUpdateSelectAll,
+                                           bool theUpdateClippingPlaneMap );
+
+  void                    dumpPlaneData() const;
+
+private:
   SMESHGUI*               mySMESHGUI;
-  SMESH_Actor*            myActor;
-  SMESH::TPlanes          myPlanes;
+  SVTK_ViewWindow*        myViewWindow;
+  SMESH::TPlaneDataVector myPlanes;
   
   QComboBox*              ComboBoxPlanes;
   QPushButton*            buttonNew;
   QPushButton*            buttonDelete;
+  QListWidget*            ActorList;
+  QCheckBox*              SelectAllCheckBox;
   QLabel*                 TextLabelOrientation;
   QComboBox*              ComboBoxOrientation;
   QLabel*                 TextLabelDistance;
@@ -129,9 +196,10 @@ public slots:
   void                    onSelectPlane( int );
   void                    ClickOnNew();
   void                    ClickOnDelete();
+  void                    onActorItemChanged( QListWidgetItem* );
+  void                    onSelectAll( int );
   void                    onSelectOrientation( int );
   void                    SetCurrentPlaneParam();
-  void                    onSelectionChanged();
   void                    OnPreviewToggle( bool );
   void                    ClickOnOk();
   void                    ClickOnCancel();
index 72ce1e852964e41b4f20fc343c98c3852a99f16c..c663c74da3ff9bedb28fbc0e97251ee23ee3bcb1 100644 (file)
@@ -65,6 +65,7 @@
 #include CORBA_CLIENT_HEADER(SMESH_Group)
 
 // VTK includes
+#include <vtkMath.h>
 #include <vtkRenderer.h>
 #include <vtkActorCollection.h>
 #include <vtkUnstructuredGrid.h>
@@ -605,6 +606,9 @@ namespace SMESH
         }
       }
     }
+    if( anActor )
+      if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
+        aSMESHGUI->addActorAsObserver( anActor );
     return anActor;
   }
 
@@ -1167,4 +1171,108 @@ namespace SMESH
 
     }
   }
+
+  //----------------------------------------------------------------------------
+  // internal function
+  void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theMinPnt[3],
+                           vtkFloatingPointType& theMaxBoundPrj,
+                           vtkFloatingPointType& theMinBoundPrj )
+  {
+    //Enlarge bounds in order to avoid conflicts of precision
+    for(int i = 0; i < 6; i += 2){
+      static double EPS = 1.0E-3;
+      vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
+      theBounds[i] -= aDelta;
+      theBounds[i+1] += aDelta;
+    }
+
+    vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
+                                                {theBounds[1],theBounds[2],theBounds[4]},
+                                                {theBounds[0],theBounds[3],theBounds[4]},
+                                                {theBounds[1],theBounds[3],theBounds[4]},
+                                                {theBounds[0],theBounds[2],theBounds[5]},
+                                                {theBounds[1],theBounds[2],theBounds[5]}, 
+                                                {theBounds[0],theBounds[3],theBounds[5]}, 
+                                                {theBounds[1],theBounds[3],theBounds[5]}};
+
+    int aMaxId = 0, aMinId = aMaxId;
+    theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
+    theMinBoundPrj = theMaxBoundPrj;
+    for(int i = 1; i < 8; i++){
+      vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
+      if(theMaxBoundPrj < aTmp){
+        theMaxBoundPrj = aTmp;
+        aMaxId = i;
+      }
+      if(theMinBoundPrj > aTmp){
+        theMinBoundPrj = aTmp;
+        aMinId = i;
+      }
+    }
+    vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
+    theMinPnt[0] = aMinPnt[0];
+    theMinPnt[1] = aMinPnt[1];
+    theMinPnt[2] = aMinPnt[2];
+  }
+
+  // internal function
+  void DistanceToPosition( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType theDist,
+                           vtkFloatingPointType thePos[3] )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
+    thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
+    thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
+    thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
+  }
+
+  // internal function (currently unused, left just in case)
+  void PositionToDistance( vtkFloatingPointType theBounds[6],
+                           vtkFloatingPointType theDirection[3],
+                           vtkFloatingPointType thePos[3],
+                           vtkFloatingPointType& theDist )
+  {
+    vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+    ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+    vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
+    theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
+  }
+
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] )
+  {
+    bool anIsOk = false;
+    theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
+    theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
+    std::list<vtkActor*>::iterator anIter = theActorList.begin();
+    for( ; anIter != theActorList.end(); anIter++ ) {
+      if( vtkActor* aVTKActor = *anIter ) {
+        if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
+          vtkFloatingPointType aBounds[6];
+          anActor->GetUnstructuredGrid()->GetBounds( aBounds );
+          theBounds[0] = std::min( theBounds[0], aBounds[0] );
+          theBounds[1] = std::max( theBounds[1], aBounds[1] );
+          theBounds[2] = std::min( theBounds[2], aBounds[2] );
+          theBounds[3] = std::max( theBounds[3], aBounds[3] );
+          theBounds[4] = std::min( theBounds[4], aBounds[4] );
+          theBounds[5] = std::max( theBounds[5], aBounds[5] );
+          anIsOk = true;
+        }
+      }
+    }
+
+    if( !anIsOk )
+      return false;
+
+    DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
+    return true;
+  }
 } // end of namespace SMESH
index 508ce767e881cc83dada67234b83ba5d746cdd99..5a9b09c25eccb9a48040e389f2a991a22032d0ad 100644 (file)
@@ -57,6 +57,8 @@ class SMESHGUI;
 class SMESH_Actor;
 class SALOME_Actor;
 
+class vtkActor;
+
 namespace SMESH
 {
   //----------------------------------------------------------------------------
@@ -185,6 +187,14 @@ SMESHGUI_EXPORT
 
 SMESHGUI_EXPORT
   void SetControlsPrecision( const long );
+
+  //----------------------------------------------------------------------------
+SMESHGUI_EXPORT
+  bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
+                                       vtkFloatingPointType theNormal[3],
+                                       vtkFloatingPointType theDist,
+                                       vtkFloatingPointType theBounds[6],
+                                       vtkFloatingPointType theOrigin[3] );
 };
 
 #endif // SMESHGUI_VTKUTILS_H
index efa0f7aa45300bd9368eb835fc63b15eae1b1ad2..4a1810b317b375745d6db8b77371caf3bb5a21c1 100644 (file)
@@ -5264,6 +5264,14 @@ It is impossible to read point coordinates from file</translation>
         <source>CLIP_PLANES</source>
         <translation>Clipping planes</translation>
     </message>
+    <message>
+        <source>MESHES_SUBMESHES_GROUPS</source>
+        <translation>Meshes, sub-meshes and groups</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Select all</translation>
+    </message>
     <message>
         <source>ROTATION_AROUND_X_Y2Z</source>
         <translation>Rotation around X (Y to Z):</translation>