Salome HOME
Redesign SALOME documentation
[modules/gui.git] / src / OCCViewer / OCCViewer_ClippingDlg.cxx
index 065ef91f2ff21b1b165ca059d9929fc37893079f..59ea3461e8a91e7d5807138e789afc36cda59b9d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include "OCCViewer_ClippingDlg.h"
 
 #include <QtxDoubleSpinBox.h>
+#include <QtxDoubleSpinSlider.h>
+#include <QtxIntSpinSlider.h>
 #include <QtxAction.h>
 
 #include "SUIT_Session.h"
 #include "SUIT_ViewWindow.h"
 #include "SUIT_ViewManager.h"
+#include "OCCViewer_ClipPlane.h"
 #include "OCCViewer_ViewWindow.h"
 #include "OCCViewer_ViewPort3d.h"
 #include "OCCViewer_ViewModel.h"
+#include "OCCViewer_ViewManager.h"
+#include "OCCViewer_ClipPlaneInteractor.h"
 
 #include <V3d_View.hxx>
-#include <Visual3d_View.hxx>
 #include <Geom_Plane.hxx>
 #include <Prs3d_Presentation.hxx>
+#include <Prs3d_PlaneAspect.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_InteractiveObject.hxx>
 #include <AIS_InteractiveContext.hxx>
+#include <Prs3d_Drawer.hxx>
 #include <IntAna_IntConicQuad.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Pln.hxx>
 #include <QSlider>
 #include <QMenu>
 
-/*!
-  Constructor of class ClipPlane
- */
-ClipPlane::ClipPlane():
-  RelativeMode(),
-  X(0.0), Y(0.0), Z(0.0),
-  Dx(1.0), Dy(1.0), Dz(1.0),
-  Orientation(0),
-  IsActive( true ),
-  IsInvert( false ),
-  PlaneMode( Absolute )
-{
-}
-
-/*!
-  Constructor of class OrientedPlane
- */
-OrientedPlane::OrientedPlane():
-  Orientation(0),
-  Distance(0.5),
-  Rotation1(0),
-  Rotation2(0)
-{
-}
-
 /**********************************************************************************
  ************************        Internal functions        ************************
  *********************************************************************************/
 
+void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,
+                          double  theDefaultSize,
+                          double& theXMin,
+                          double& theYMin,
+                          double& theZMin,
+                          double& theXMax,
+                          double& theYMax,
+                          double& theZMax) {
+
+  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
+  aXMin = aYMin = aZMin = DBL_MAX;
+  aXMax = aYMax = aZMax = -DBL_MAX;
+  
+  bool isFound = false;
+  AIS_ListOfInteractive aList;
+  ic->DisplayedObjects( aList );
+  for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {
+    Handle(AIS_InteractiveObject) anObj = it.Value();
+    if ( !anObj.IsNull() && anObj->HasPresentation() &&
+         !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
+      Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
+      if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
+        isFound = true;
+        double xmin, ymin, zmin, xmax, ymax, zmax;
+       Bnd_Box aBox = aPrs->MinMaxValues();
+       xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X();
+       ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y();
+       zmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z();
+       xmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().X();
+       ymax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Y();
+       zmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Z();
+        aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );
+        aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );
+        aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );
+      }
+    }
+  }
+
+  if(!isFound) {
+    if(theDefaultSize == 0.0)
+      theDefaultSize = 100.;
+    aXMin = aYMin = aZMin = -theDefaultSize;
+    aXMax = aYMax = aZMax = theDefaultSize;
+  }
+  theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;
+  theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;
+}
+
 /*!
   Compute the point of bounding box and current clipping plane
  */
-void ComputeBoundsParam( double theBounds[6],
-                         double theDirection[3],
+void ComputeBoundsParam( const double theBounds[6],
+                         const double theDirection[3],
                          double theMinPnt[3],
                          double& theMaxBoundPrj,
                          double& theMinBoundPrj )
 {
-  //Enlarge bounds in order to avoid conflicts of precision
-  for(int i = 0; i < 6; i += 2) {
+  double aEnlargeBounds[6];
+
+  // Enlarge bounds in order to avoid conflicts of precision
+  for(int i = 0; i < 6; i += 2)
+  {
     static double EPS = 1.0E-3;
     double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
-    theBounds[i] -= aDelta;
-    theBounds[i+1] += aDelta;
+    aEnlargeBounds[i  ] = theBounds[i  ] - aDelta;
+    aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;
   }
 
-  double 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] } };
+  double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] },
+                                { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] },
+                                { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] },
+                                { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] },
+                                { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] },
+                                { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] },
+                                { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] },
+                                { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } };
 
   int aMaxId = 0;
   theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
@@ -138,131 +170,161 @@ void ComputeBoundsParam( double theBounds[6],
 /*!
   Compute the position of current plane by distance
  */
-void DistanceToPosition( double theBounds[6],
-                         double theDirection[3],
-                         double theDist,
+void DistanceToPosition( const double theBounds[6],
+                         const double theDirection[3],
+                         const double theDist,
                          double thePos[3] )
 {
   double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
-  ComputeBoundsParam( theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj );
-  double 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;
+  ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj );
+  double 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;
 }
 
 /*!
   Compute the parameters of clipping plane
  */
-bool ComputeClippingPlaneParameters( double theNormal[3],
-                                     double theDist,
-                                     double theBounds[6],
-                                     double theOrigin[3],
-                                     Handle(V3d_View) theView3d )
+bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,
+                                     const double theDefaultSize,
+                                     const double theNormal[3],
+                                     const double theDist,
+                                     double theOrigin[3] )
 {
-  bool anIsOk = false;
-  theBounds[0] = theBounds[2] = theBounds[4] = 999.99;
-  theBounds[1] = theBounds[3] = theBounds[5] = -999.99;
   double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
 
-  theView3d->View()->MinMaxValues( aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5]);
-  if ( !theView3d->View()->ContainsFacet() ) {
-    aBounds[0] = aBounds[2] = aBounds[4] = 0.0;
-    aBounds[1] = aBounds[3] = aBounds[5] = 100.0;
-  }
-  anIsOk = true;
-
-  if( !anIsOk )
-    return false;
+  getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );
 
   DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
   return true;
 }
 
 /*!
-  Cross product of two 3-vectors. Result vector in result[3].
+  \brief Converts relative plane parameters to absolute.
+  \param theIC [in] the interactive context.
+  \param theDefaultSize [in] the default trihedron size.
+  \param theDistance [in] the plane distance relative to minimum corner of model boundaries.
+  \param theDX [in] x component of plane direction.
+  \param theDY [in] y component of plane direction.
+  \param theDZ [in] z component of plane direction.
+  \param theX [out] x coordinate of plane origin.
+  \param theY [out] y coordinate of plane origin.
+  \param theZ [out] z coordinate of plane origin.
  */
-void Cross(const double first[3], const double second[3], double result[3])
+bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC,
+                     const double theDefaultSize,
+                     const double theDistance,
+                     const double theDX,
+                     const double theDY,
+                     const double theDZ,
+                     double& theX,
+                     double& theY,
+                     double& theZ )
 {
-  result[0] = first[1]*second[2] - first[2]*second[1];
-  result[1] = first[2]*second[0] - first[0]*second[2];
-  result[2] = first[0]*second[1] - first[1]*second[0];
+  double aNormal[3] = { theDX, theDY, theDZ };
+  double anOrigin[3] = { 0.0, 0.0, 0.0 };
+
+  bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin );
+
+  if( !anIsOk )
+  {
+    return false;
+  }
+
+  theX = anOrigin[0];
+  theY = anOrigin[1];
+  theZ = anOrigin[2];
+
+  return true;
 }
 
 /*!
-  Compute relative clipping plane in absolute coordinates
+  \brief Converts absolute position and direction to bounding box distance.
+  \param theIC [in] the interactive context.
+  \param theDefaultSize [in] the default trihedron size.
+  \param theX [in] x coordinate of plane origin.
+  \param theY [in] y coordinate of plane origin.
+  \param theZ [in] z coordinate of plane origin.
+  \param theDX [in] x component of plane direction.
+  \param theDY [in] y component of plane direction.
+  \param theDZ [in] z component of plane direction.
+  \param theDistance [out] the plane distance relative to minimum corner of model boundaries.
  */
-void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d )
+void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC,
+                     const double theDefaultSize,
+                     const double theX,
+                     const double theY,
+                     const double theZ,
+                     const double theDX,
+                     const double theDY,
+                     const double theDZ,
+                     double& theDistance )
 {
-  double aNormal[3];
-  double aDir[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } };
-  {
-    static double aCoeff = M_PI/180.0;
-
-    double anU[2] = { cos( aCoeff * thePlane->RelativeMode.Rotation1 ), cos( aCoeff * thePlane->RelativeMode.Rotation2 ) };
-    double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) };
-    aV[0] = thePlane->RelativeMode.Rotation1 > 0? aV[0]: -aV[0];
-    aV[1] = thePlane->RelativeMode.Rotation2 > 0? aV[1]: -aV[1];
-
-    switch ( thePlane->RelativeMode.Orientation ) {
-    case 0:
-      aDir[0][1] = anU[0];
-      aDir[0][2] = aV[0];
-      aDir[1][0] = anU[1];
-      aDir[1][2] = aV[1];
-      break;
-    case 1:
-      aDir[0][2] = anU[0];
-      aDir[0][0] = aV[0];
-      aDir[1][1] = anU[1];
-      aDir[1][0] = aV[1];
-      break;
-    case 2:
-      aDir[0][0] = anU[0];
-      aDir[0][1] = aV[0];
-      aDir[1][2] = anU[1];
-      aDir[1][1] = aV[1];
-      break;
-    }
+  gp_Pnt aPlaneP( theX, theY, theZ );
+  gp_Dir aPlaneN( theDX, theDY, theDZ );
 
-    Cross( aDir[1], aDir[0], aNormal );
-    // Normalize
-    double den;
-    den = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] );
-    if ( den != 0.0 ) {
-      for (int i=0; i < 3; i++) {
-        aNormal[i] /= den;
-      }
-    }
-    Cross( aNormal, aDir[1], aDir[0] );
-  }
+  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
 
-  double aBounds[6];
-  double anOrigin[3];
+  getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
 
-  bool anIsOk = false;
+  Bnd_Box aMinMax;
+  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
 
-  anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
-  aBounds[0] = aBounds[2] = aBounds[4] = 0;
-  aBounds[1] = aBounds[3] = aBounds[5] = 0;
-  anIsOk = true;
+  gp_Trsf aRelativeTransform;
+  aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );
+  Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );
 
-  anIsOk = ComputeClippingPlaneParameters( aNormal,
-                                           thePlane->RelativeMode.Distance,
-                                           aBounds,
-                                           anOrigin,
-                                           theView3d );
-  if( !anIsOk )
-         return;
-
-  thePlane->Dx = aNormal[0];
-  thePlane->Dy = aNormal[1];
-  thePlane->Dz = aNormal[2];
-  thePlane->X = anOrigin[0];
-  thePlane->Y = anOrigin[1];
-  thePlane->Z = anOrigin[2];
+  aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+  double aLength   = aZmax - aZmin;
+  double aDistance = aZmax;
+
+  double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;
+  aRelativeDistance = qMin( aRelativeDistance, aLength );
+  aRelativeDistance = qMax( aRelativeDistance, 0.0 );
+  theDistance = aRelativeDistance;
 }
 
+/*!
+  Compute clipping plane size base point and normal
+ */
+
+void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,
+                     double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {
+  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
+  aXMin = aYMin = aZMin = DBL_MAX;
+  aXMax = aYMax = aZMax = -DBL_MAX;
+  
+  getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+  double aSize = 50;
+
+  double aNormalX = 0.0;
+  double aNormalY = 0.0;
+  double aNormalZ = 0.0;
+  theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ );
+  gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z );
+  gp_Dir aNormal( aNormalX, aNormalY, aNormalZ );
+
+  // compute clipping plane size
+  gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
+  double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
+  aSize = aDiag * 1.1;
+  
+  // compute clipping plane center ( redefine the base point )
+  IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
+  
+  intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
+
+  if ( intersector.IsDone() && intersector.NbPoints() == 1 )
+    aBasePnt = intersector.Point( 1 );
+  
+  theSize = aSize;
+  theBasePnt = aBasePnt;
+  theNormal = aNormal;
+}
+
+
 /*********************************************************************************
  *********************      class OCCViewer_ClippingDlg      *********************
  *********************************************************************************/
@@ -270,18 +332,16 @@ void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d )
   Constructor
   \param view - view window
   \param parent - parent widget
-  \param name - dialog name
-  \param modal - is this dialog modal
-  \param fl - flags
 */
-OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const char* name, bool modal, Qt::WindowFlags fl )
-: QDialog( view, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
-  myView( view )
+OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
+  : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )
 {
   setObjectName( "OCCViewer_ClippingDlg" );
-  setModal( modal );
+  setModal( false );
 
   setWindowTitle( tr( "Clipping" ) );
+
+  setAttribute (Qt::WA_DeleteOnClose, true);
   
   QVBoxLayout* topLayout = new QVBoxLayout( this );
   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
@@ -299,7 +359,6 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
   MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
   buttonNew->setMenu( MenuMode );
-  CurrentMode = Absolute;
 
   GroupPlanesLayout->addWidget( ComboBoxPlanes );
   GroupPlanesLayout->addWidget( isActivePlane );
@@ -445,72 +504,38 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   CBRelativeOrientation->addItem( tr("ALONG_ZX") );
   GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
 
-  TLValueDistance = new QLabel( GroupParameters );
-  TLValueDistance->setObjectName( "TLValueDistance" );
-  TLValueDistance->setAlignment( Qt::AlignCenter );
-  TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt );
-  GroupParametersLayout->addWidget( TLValueDistance, 1, 1 );
-
   TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
   TextLabelDistance->setObjectName( "TextLabelDistance" );
-  GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 );
-
-  SliderDistance = new QSlider( Qt::Horizontal, GroupParameters );
-  SliderDistance->setObjectName( "SliderDistance" );
-  SliderDistance->setFocusPolicy( Qt::NoFocus );
-  SliderDistance->setMinimumSize( 300, 0 );
-  SliderDistance->setMinimum( 0 );
-  SliderDistance->setMaximum( 100 );
-  SliderDistance->setSingleStep( 1 );
-  SliderDistance->setPageStep( 10 );
-  SliderDistance->setTracking( false );
-  GroupParametersLayout->addWidget( SliderDistance, 2, 1 );
-
-  TLValueRotation1 = new QLabel( GroupParameters );
-  TLValueRotation1->setObjectName( "TLValueRotation1" );
-  TLValueRotation1->setAlignment( Qt::AlignCenter );
-  TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  TLValueRotation1->setFont( fnt );
-  GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 );
+  GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
+  
+  SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );
+  SpinSliderDistance->setObjectName( "SpinSliderDistance" );
+  SpinSliderDistance->setPrecision( precision );
+  QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );
+  GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );
+
+  QString aUnitRot = QString(QChar(0xB0));
 
   TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
   TextLabelRotation1->setObjectName( "TextLabelRotation1" );
-  GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 );
-
-  SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters );
-  SliderRotation1->setObjectName( "SliderRotation1" );
-  SliderRotation1->setFocusPolicy( Qt::NoFocus );
-  SliderRotation1->setMinimumSize( 300, 0 );
-  SliderRotation1->setMinimum( -180 );
-  SliderRotation1->setMaximum( 180 );
-  SliderRotation1->setSingleStep( 1 );
-  SliderRotation1->setPageStep( 10 );
-  SliderRotation1->setTracking(false);
-  GroupParametersLayout->addWidget( SliderRotation1, 4, 1 );
-
-  TLValueRotation2 = new QLabel( GroupParameters );
-  TLValueRotation2->setObjectName( "TLValueRotation2" );
-  TLValueRotation2->setAlignment( Qt::AlignCenter );
-  TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  TLValueRotation2->setFont( fnt );
-  GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 );
+  GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );
+  
+  SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
+  SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );
+  SpinSliderRotation1->setUnit( aUnitRot );
+  SpinSliderRotation1->setFont( fnt );
+  GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );
 
   TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
   TextLabelRotation2->setObjectName( "TextLabelRotation2" );
   TextLabelRotation2->setObjectName( "TextLabelRotation2" );
-  GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 );
-
-  SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters );
-  SliderRotation2->setObjectName( "SliderRotation2" );
-  SliderRotation2->setFocusPolicy( Qt::NoFocus );
-  SliderRotation2->setMinimumSize( 300, 0 );
-  SliderRotation2->setMinimum( -180 );
-  SliderRotation2->setMaximum( 180 );
-  SliderRotation2->setSingleStep( 1 );
-  SliderRotation2->setPageStep( 10 );
-  SliderRotation2->setTracking(false);
-  GroupParametersLayout->addWidget( SliderRotation2, 6, 1 );
+  GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );
+
+  SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
+  SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );
+  SpinSliderRotation2->setUnit( aUnitRot );
+  SpinSliderRotation2->setFont( fnt );
+  GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );
 
   /***************************************************************/
   QGroupBox* CheckBoxWidget = new QGroupBox( this );
@@ -534,15 +559,15 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   buttonOk = new QPushButton( GroupButtons );
   buttonOk->setObjectName( "buttonOk" );
   buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE"  ) );
-  buttonOk->setAutoDefault( TRUE );
-  buttonOk->setDefault( TRUE );
+  buttonOk->setAutoDefault( true );
+  buttonOk->setDefault( true );
   GroupButtonsLayout->addWidget( buttonOk );
 
   buttonApply = new QPushButton( GroupButtons );
   buttonApply->setObjectName( "buttonApply" );
   buttonApply->setText( tr( "BUT_APPLY"  ) );
-  buttonApply->setAutoDefault( TRUE );
-  buttonApply->setDefault( TRUE );
+  buttonApply->setAutoDefault( true );
+  buttonApply->setDefault( true );
   GroupButtonsLayout->addWidget( buttonApply );
 
   GroupButtonsLayout->addStretch();
@@ -550,11 +575,11 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   buttonClose = new QPushButton( GroupButtons );
   buttonClose->setObjectName( "buttonClose" );
   buttonClose->setText( tr( "BUT_CLOSE"  ) );
-  buttonClose->setAutoDefault( TRUE );
+  buttonClose->setAutoDefault( true );
   GroupButtonsLayout->addWidget( buttonClose );
 
-  QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
-  buttonHelp->setAutoDefault( TRUE );
+  QPushButton* buttonHelp = new QPushButton( tr( "HELP" ), GroupButtons );
+  buttonHelp->setAutoDefault( true );
   GroupButtonsLayout->addWidget( buttonHelp );
 
   /***************************************************************/
@@ -589,12 +614,9 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
 
   connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
-  connect( SliderDistance,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderDistanceHasMoved( int ) ) );
-  connect( SliderDistance,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderDistanceHasMoved( int ) ) );
-  connect( SliderRotation1,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderRotation1HasMoved( int ) ) );
-  connect( SliderRotation1,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderRotation1HasMoved( int ) ) );
-  connect( SliderRotation2,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderRotation2HasMoved( int ) ) );
-  connect( SliderRotation2,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderRotation2HasMoved( int ) ) );
+  connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
+  connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
 
   connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
   connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
@@ -603,14 +625,23 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
   connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
   connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
-  
-  connect(view, SIGNAL(Show( QShowEvent* ) ), this, SLOT( onViewShow() ) );
-  connect(view, SIGNAL(Hide( QHideEvent* ) ), this, SLOT( onViewHide() ) );
 
   myBusy = false;
   myIsSelectPlane = false;
-  myView3d = myView->getViewPort()->getView();
+  myIsPlaneCreation = false;
+  myIsUpdatingControls = false;
+  myModel = model;
 
+  myModel->getViewer3d()->InitActiveViews();
+
+  OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();
+  myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );
+  connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ),
+          SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );
+  connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ),
+          SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );
+
+  myLocalPlanes = myModel->getClipPlanes();
   synchronize();
 }
 
@@ -618,11 +649,9 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const
   Destructor
   Destroys the object and frees any allocated resources
 */
-OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
+OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
 {
-  // no need to delete child widgets, Qt does it all for us
-  foreach( ClipPlane* aPlane, myClippingPlanes )
-    delete aPlane;
+  myLocalPlanes.clear();
 }
 
 /*!
@@ -631,8 +660,10 @@ OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
 {
   erasePreview();
-  myAction->setChecked( false );
   QDialog::closeEvent( e );
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
 }
 
 /*!
@@ -651,6 +682,10 @@ void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
 {
   erasePreview();
   QDialog::hideEvent( e );
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
+
 }
 
 /*!
@@ -668,13 +703,86 @@ void OCCViewer_ClippingDlg::initParam()
 
   CBAbsoluteOrientation->setCurrentIndex(0);
 
-  TLValueDistance->setText( "0" );
-  TLValueRotation1->setText( "0\xB0" );
-  TLValueRotation2->setText( "0\xB0" );
+  SpinSliderDistance->setValue( 0.5 );
+  SpinSliderRotation1->setValue( 0 );
+  SpinSliderRotation2->setValue( 0 );
   CBRelativeOrientation->setCurrentIndex( 0 );
-  SliderDistance->setValue( 50 );
-  SliderRotation1->setValue( 0 );
-  SliderRotation2->setValue( 0 );
+
+  isActivePlane->setChecked( true );
+}
+
+/*!
+  Set plane parameters from widgets.
+*/
+void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane )
+{
+  OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode();
+
+  thePlane.Mode = aMode;
+
+  if ( aMode == OCCViewer_ClipPlane::Absolute )
+  {
+    if( qFuzzyIsNull( SpinBox_Dx->value() ) && 
+        qFuzzyIsNull( SpinBox_Dy->value() ) && 
+        qFuzzyIsNull( SpinBox_Dz->value() ) ) {
+      return;
+    }
+  }
+
+  thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute)
+    ? CBAbsoluteOrientation->currentIndex()
+    : CBRelativeOrientation->currentIndex();
+
+  // Get XYZ, DXYZ
+  if ( aMode == OCCViewer_ClipPlane::Absolute )
+  {
+    if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
+    {
+      thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value();
+      thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value();
+      thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value();
+      thePlane.AbsoluteOrientation.IsInvert = false;
+    }
+    else
+    {
+      thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0
+                                           || SpinBox_Dy->value() < 0.0
+                                           || SpinBox_Dz->value() < 0.0;
+    }
+
+    thePlane.X = SpinBox_X->value();
+    thePlane.Y = SpinBox_Y->value();
+    thePlane.Z = SpinBox_Z->value();
+  }
+  else
+  {
+    thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value();
+    thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value();
+
+    double aPlaneDx = 0.0;
+    double aPlaneDy = 0.0;
+    double aPlaneDz = 0.0;
+    double aX = 0.0;
+    double aY = 0.0;
+    double aZ = 0.0;
+
+    OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType,
+                                         thePlane.RelativeOrientation.Rotation1,
+                                         thePlane.RelativeOrientation.Rotation2,
+                                         aPlaneDx, aPlaneDy, aPlaneDz );
+
+    DistanceToXYZ( myModel->getAISContext(),
+                   myModel->trihedronSize(),
+                   SpinSliderDistance->value(),
+                   aPlaneDx, aPlaneDy, aPlaneDz,
+                   aX, aY, aZ );
+
+    thePlane.X = aX;
+    thePlane.Y = aY;
+    thePlane.Z = aZ;
+  }
+
+  thePlane.IsOn = isActivePlane->isChecked();
 }
 
 /*!
@@ -683,7 +791,7 @@ void OCCViewer_ClippingDlg::initParam()
 void OCCViewer_ClippingDlg::synchronize()
 {
   ComboBoxPlanes->clear();
-  int aNbPlanesAbsolute = myClippingPlanes.size();
+  int aNbPlanesAbsolute = myLocalPlanes.size();
 
   QString aName;
   for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
@@ -701,9 +809,9 @@ void OCCViewer_ClippingDlg::synchronize()
   else {
     ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
     initParam();
-    ClickOnDisableAll();
   }
-  if ( CurrentMode == Absolute ) {
+  if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )
+  {
     SpinBox_X->setEnabled( anIsControlsEnable );
     SpinBox_Y->setEnabled( anIsControlsEnable );
     SpinBox_Z->setEnabled( anIsControlsEnable );
@@ -714,11 +822,12 @@ void OCCViewer_ClippingDlg::synchronize()
     invertButton->setEnabled( anIsControlsEnable );
     resetButton->setEnabled( anIsControlsEnable );
   }
-  else if( CurrentMode == Relative ) {
+  else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )
+  {
     CBRelativeOrientation->setEnabled( anIsControlsEnable );
-    SliderDistance->setEnabled( anIsControlsEnable );
-    SliderRotation1->setEnabled( anIsControlsEnable );
-    SliderRotation2->setEnabled( anIsControlsEnable );
+    SpinSliderDistance->setEnabled( anIsControlsEnable );
+    SpinSliderRotation1->setEnabled( anIsControlsEnable );
+    SpinSliderRotation2->setEnabled( anIsControlsEnable );
     isActivePlane->setEnabled( anIsControlsEnable );
   }
   isActivePlane->setEnabled( anIsControlsEnable );
@@ -729,85 +838,125 @@ void OCCViewer_ClippingDlg::synchronize()
 */
 void OCCViewer_ClippingDlg::displayPreview()
 {
-  if ( myBusy || !isValid() )
+  if ( myBusy || !isValid() || !myModel)
     return;
 
-  OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
-  if ( !anOCCViewer )
-    return;
-
-  Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
-
-  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
-  aXMin = aYMin = aZMin = DBL_MAX;
-  aXMax = aYMax = aZMax = -DBL_MAX;
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+  
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  bool isFound = false;
-  AIS_ListOfInteractive aList;
-  ic->DisplayedObjects( aList );
-  for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
-  {
-    Handle(AIS_InteractiveObject) anObj = it.Value();
-    if ( !anObj.IsNull() && anObj->HasPresentation() &&
-         !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
-      Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
-      if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
-        isFound = true;
-        double xmin, ymin, zmin, xmax, ymax, zmax;
-        aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
-        aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );
-        aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );
-        aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );
-      }
+  for ( int i=0; i < clipPlanesCount(); i++ ) {
+    OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);
+    if ( aClipPlane.IsOn ) {
+      Handle(AIS_Plane) myPreviewPlane;
+      double aSize;
+      gp_Pnt aBasePnt;
+      gp_Dir aNormal;
+      clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
+      myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
+      myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
+      Handle(Prs3d_PlaneAspect) aPlaneAspect = new Prs3d_PlaneAspect();
+      aPlaneAspect->SetPlaneLength( aSize, aSize );
+      myPreviewPlane->Attributes()->SetPlaneAspect( aPlaneAspect );
+      ic->SetWidth( myPreviewPlane, 10, false );
+      ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
+      ic->SetTransparency( myPreviewPlane, 0.5, false );
+      Quantity_Color c = (aCurPlaneIndex == i) ? Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ) : Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB );
+      ic->SetColor( myPreviewPlane, c , false );
+      ic->Display( myPreviewPlane, 1, 0, false );
+      myPreviewPlaneVector.push_back( myPreviewPlane );
     }
   }
+  myModel->update();
+
+  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+  getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+  gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
+                          (aYmax + aYmin) * 0.5,
+                          (aZmax + aZmin) * 0.5 );
+  Bnd_Box aMinMax;
+  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+  myInteractor->setPlanes( myPreviewPlaneVector );
+  myInteractor->setRotationCenter( aRotationCenter );
+  myInteractor->setMinMax( aMinMax );
+  myInteractor->setEnabled( true );
+}
 
-  double aSize = 50;
-
-  ClipPlane* aClipPlane;
-  for ( int i=0; i < myClippingPlanes.size(); i++ ) {
-  Pnt_ClipPlane aPlane = myClippingPlanes[i];
-  aClipPlane = aPlane;
-
-  double Epsilon = 0.0001;
-  double Epsilon_Dx = ( aClipPlane->Dx > 0 ) ? Epsilon: -Epsilon;
-  double Epsilon_Dy = ( aClipPlane->Dy > 0 ) ? Epsilon: -Epsilon;
-  double Epsilon_Dz = ( aClipPlane->Dz > 0 ) ? Epsilon: -Epsilon;
-
-  gp_Pnt aBasePnt( aClipPlane->X + Epsilon_Dx,  aClipPlane->Y + Epsilon_Dy,  aClipPlane->Z + Epsilon_Dz );
-  gp_Dir aNormal( aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz );
-  gp_Pnt aCenter = aBasePnt;
-
-  if ( isFound )
-  {
-    // compute clipping plane size
-    aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
-    double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
-    aSize = aDiag * 1.1;
-
-    // compute clipping plane center ( redefine the base point )
-    IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
-
-    intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
-    if ( intersector.IsDone() && intersector.NbPoints() == 1 )
-      aBasePnt = intersector.Point( 1 );
+void OCCViewer_ClippingDlg::updatePreview() {
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  int count = clipPlanesCount();
+  if ( myBusy || 
+       !isValid() || 
+       myIsPlaneCreation ||
+       !myModel || 
+       count == 0 || 
+       (aCurPlaneIndex +1 > count) ||
+       !PreviewCheckBox->isChecked())
+    return;
+  
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+  
+  OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);
+  Handle(AIS_Plane) myPreviewPlane;
+
+  if (aClipPlane.IsOn) {
+    double aSize;
+    gp_Pnt aBasePnt;
+    gp_Dir aNormal;
+    clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
+    if(myPreviewPlaneVector.size() < clipPlanesCount()) {
+      myPreviewPlaneVector.resize(clipPlanesCount());
     }
-
-    if ( aClipPlane->IsActive == true ) {
-      Handle(AIS_Plane) myPreviewPlane;
-      myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) );
-      myPreviewPlane->SetSize( aSize, aSize );
-
-      ic->Display( myPreviewPlane, 1, -1, false );
+    myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
+    if(myPreviewPlane.IsNull()) {
+      //Plane was not created
+      myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
+      myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
+      Handle(Prs3d_PlaneAspect) aPlaneAspect = new Prs3d_PlaneAspect();
+      aPlaneAspect->SetPlaneLength( aSize, aSize );
+      myPreviewPlane->Attributes()->SetPlaneAspect( aPlaneAspect );
+      ic->Display( myPreviewPlane, 1, 0, false );
       ic->SetWidth( myPreviewPlane, 10, false );
       ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
       ic->SetTransparency( myPreviewPlane, 0.5, false );
-      ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
+      myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
+    } else {      
+      myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
+      myPreviewPlane->SetCenter( aBasePnt );
+      myPreviewPlane->SetSize( aSize, aSize ); 
+    }
 
-      myPreviewPlaneVector.push_back( myPreviewPlane );
+    ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
+    ic->Update( myPreviewPlane, Standard_False );
+  } else {
+    if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {
+      myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
+      if(ic->IsDisplayed(myPreviewPlane)) {
+       ic->Erase( myPreviewPlane, false );
+       ic->Remove( myPreviewPlane, false );
+      }
+      myPreviewPlaneVector[aCurPlaneIndex].Nullify();
     }
   }
-  anOCCViewer->update();
+  for(int i = 0; i < myPreviewPlaneVector.size(); i++) {
+    if( i == aCurPlaneIndex ) continue;
+    if(!myPreviewPlaneVector[i].IsNull())
+      ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
+  }
+  myModel->update();
+
+  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+  getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+  gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
+                          (aYmax + aYmin) * 0.5,
+                          (aZmax + aZmin) * 0.5 );
+  Bnd_Box aMinMax;
+  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+  myInteractor->setPlanes( myPreviewPlaneVector );
+  myInteractor->setRotationCenter( aRotationCenter );
+  myInteractor->setMinMax( aMinMax );
 }
 
 /*!
@@ -815,12 +964,11 @@ void OCCViewer_ClippingDlg::displayPreview()
 */
 void OCCViewer_ClippingDlg::erasePreview()
 {
-  OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
-  if ( !anOCCViewer )
+  if ( !myModel )
     return;
-  
-  Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
-  
+
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+
   for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
   Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
     if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
@@ -829,7 +977,9 @@ void OCCViewer_ClippingDlg::erasePreview()
       myPreviewPlane.Nullify();
     }
   }
-  anOCCViewer->update();
+  myPreviewPlaneVector.clear();
+  myModel->update();
+  myInteractor->setEnabled( false );
 }
 
 /*!
@@ -843,25 +993,96 @@ bool OCCViewer_ClippingDlg::isValid()
 /*!
   Update view after changes
 */
-void OCCViewer_ClippingDlg::updateView()
+void OCCViewer_ClippingDlg::updateClipping()
 {
-  if ( PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked() ) {
-    erasePreview();
-    if ( AutoApplyCheckBox->isChecked() )
+  if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
+  {
+    if (AutoApplyCheckBox->isChecked()) {
       onApply();
-    if ( PreviewCheckBox->isChecked() && !isRestore )
-      displayPreview();
+    }
+    
+    if (!PreviewCheckBox->isChecked())
+      myModel->update();
+    else 
+      updatePreview();
   }
 }
 
+/*!
+  Updates state of user controls.
+*/
+void OCCViewer_ClippingDlg::updateControls()
+{
+  if ( clipPlanesCount() == 0 )
+  {
+    initParam();
+    return;
+  }
+
+  int aPlaneIdx = ComboBoxPlanes->currentIndex();
+
+  OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );
+
+  double aPlaneDx  = 0.0;
+  double aPlaneDy  = 0.0;
+  double aPlaneDz  = 0.0;
+  double aDistance = 0.0;
+  aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz );
+
+  if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute )
+  {
+    ModeStackedLayout->setCurrentIndex( 0 );
+
+    // Set plane parameters in the dialog
+    SpinBox_X->setValue( aPlane.X );
+    SpinBox_Y->setValue( aPlane.Y );
+    SpinBox_Z->setValue( aPlane.Z );
+    SpinBox_Dx->setValue( aPlaneDx );
+    SpinBox_Dy->setValue( aPlaneDy );
+    SpinBox_Dz->setValue( aPlaneDz );
+    CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType );
+    onOrientationAbsoluteChanged( aPlane.OrientationType );
+  }
+  else if( aPlane.Mode == OCCViewer_ClipPlane::Relative )
+  {
+    ModeStackedLayout->setCurrentIndex( 1 );
+
+    // Set plane parameters in the dialog
+    SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) );
+    SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) );
+
+    XYZToDistance( myModel->getAISContext(),
+                   myModel->trihedronSize(),
+                   aPlane.X, aPlane.Y, aPlane.Z,
+                   aPlaneDx, aPlaneDy, aPlaneDz,
+                   aDistance );
+
+    SpinSliderDistance->setValue( aDistance );
+
+    CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType );
+    onOrientationRelativeChanged( aPlane.OrientationType );
+  }
+
+  isActivePlane->setChecked( aPlane.IsOn );
+}
+
 /*!
   SLOT on new button click: create a new clipping plane
 */
 void OCCViewer_ClippingDlg::ClickOnNew()
 {
-  ClipPlane* aPlane = new ClipPlane();
-  aPlane->PlaneMode = CurrentMode;
-  myClippingPlanes.push_back( aPlane );
+  OCCViewer_ClipPlane aClipPlane;
+
+  // init controls state
+  myIsUpdatingControls = true;
+  initParam();
+  myIsUpdatingControls = false;
+
+  // init plane according to the state of controls
+  setPlaneParam( aClipPlane );
+
+  // add plane
+  myLocalPlanes.push_back( aClipPlane );
   synchronize();
 }
 
@@ -870,15 +1091,27 @@ void OCCViewer_ClippingDlg::ClickOnNew()
 */
 void OCCViewer_ClippingDlg::ClickOnDelete()
 {
-  if ( myClippingPlanes.empty() )
+  int aPlaneIndex = ComboBoxPlanes->currentIndex();
+  if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
     return;
 
-  int aPlaneIndex = ComboBoxPlanes->currentIndex();
+  myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
+
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
 
-  ClipPlaneVector::iterator anIter = myClippingPlanes.begin() + aPlaneIndex;
-  myClippingPlanes.erase( anIter );
-  updateView();
+  if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {
+    Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];
+    if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
+      ic->Erase( myPreviewPlane, false );
+      ic->Remove( myPreviewPlane, false );
+    }
+    myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);
+  }
   synchronize();
+  if (AutoApplyCheckBox->isChecked()) {
+    onApply();
+  }
+  myModel->update();
 }
 
 /*!
@@ -887,15 +1120,17 @@ void OCCViewer_ClippingDlg::ClickOnDelete()
 */
 void OCCViewer_ClippingDlg::ClickOnDisableAll()
 {
-  AutoApplyCheckBox->setChecked( false );
-  Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes();
-  Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes);
-  for( ;anIter.More();anIter.Next() ){
-    Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
-    aClipPlane->SetOn(Standard_False);
+  AutoApplyCheckBox->setChecked (false);
+  int aClipPlanesCount = clipPlanesCount();
+  for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
+  {
+    OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
+    aPlane.IsOn = false;
   }
-  myView3d->Update();
-  myView3d->Redraw();
+  erasePreview();
+  isActivePlane->setChecked(false);
+  myModel->setClipPlanes(myLocalPlanes);
+  myModel->update();
 }
 
 /*!
@@ -904,8 +1139,7 @@ void OCCViewer_ClippingDlg::ClickOnDisableAll()
 void OCCViewer_ClippingDlg::ClickOnOk()
 {
   onApply();
-  erasePreview();
-  myAction->setChecked( false );
+  ClickOnClose();
 }
 
 /*!
@@ -914,8 +1148,7 @@ void OCCViewer_ClippingDlg::ClickOnOk()
 void OCCViewer_ClippingDlg::ClickOnApply()
 {
   onApply();
-  myView3d->Update();
-  myView3d->Redraw();
+  myModel->update();
 }
 
 /*!
@@ -924,7 +1157,9 @@ void OCCViewer_ClippingDlg::ClickOnApply()
 void OCCViewer_ClippingDlg::ClickOnClose()
 {
   erasePreview();
-  myAction->setChecked( false );
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
 }
 
 /*!
@@ -934,7 +1169,7 @@ void OCCViewer_ClippingDlg::ClickOnHelp()
 {
   SUIT_Application* app = SUIT_Session::session()->activeApplication();
   if ( app )
-    app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
+    app->onHelpContextModule( "GUI", "occ_3d_viewer.html", "clipping-planes" );
 }
 
 /*!
@@ -942,10 +1177,11 @@ void OCCViewer_ClippingDlg::ClickOnHelp()
 */
 void OCCViewer_ClippingDlg::onModeAbsolute()
 {
+  myIsPlaneCreation = true;
   ModeStackedLayout->setCurrentIndex(0);
-  CurrentMode = Absolute;
   ClickOnNew();
-  onValueChanged();
+  myIsPlaneCreation = false;
+  updateClipping();
 }
 
 /*!
@@ -953,10 +1189,12 @@ void OCCViewer_ClippingDlg::onModeAbsolute()
 */
 void OCCViewer_ClippingDlg::onModeRelative()
 {
+  myIsPlaneCreation = true;
   ModeStackedLayout->setCurrentIndex(1);
-  CurrentMode = Relative;
   ClickOnNew();
-  onValueChanged();
+  myIsPlaneCreation = false;
+  SetCurrentPlaneParam();
+  updateClipping();
 }
 
 /*!
@@ -964,10 +1202,19 @@ void OCCViewer_ClippingDlg::onModeRelative()
 */
 void OCCViewer_ClippingDlg::onValueChanged()
 {
+  if ( myIsUpdatingControls )
+  {
+    return;
+  }
+
   SetCurrentPlaneParam();
+
   if ( myIsSelectPlane )
+  {
     return;
-  updateView();
+  }
+
+  updateClipping();
 }
 
 /*!
@@ -975,44 +1222,16 @@ void OCCViewer_ClippingDlg::onValueChanged()
 */
 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
 {
-  if ( myClippingPlanes.empty() )
+  if ( clipPlanesCount() == 0 )
+  {
     return;
+  }
 
-  Pnt_ClipPlane aPlane = myClippingPlanes[theIndex];
-  ClipPlane* aClipPlane = aPlane;
+  OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );
 
   myIsSelectPlane = true;
-  if ( aClipPlane->PlaneMode == Absolute ) {
-    ModeStackedLayout->setCurrentIndex( 0 );
-    CurrentMode = Absolute;
-    int anOrientation = aClipPlane->Orientation;
-    // Set plane parameters in the dialog
-    SpinBox_X->setValue( aClipPlane->X );
-    SpinBox_Y->setValue( aClipPlane->Y );
-    SpinBox_Z->setValue( aClipPlane->Z );
-    SpinBox_Dx->setValue( aClipPlane->Dx );
-    SpinBox_Dy->setValue( aClipPlane->Dy );
-    SpinBox_Dz->setValue( aClipPlane->Dz );
-    CBAbsoluteOrientation->setCurrentIndex( anOrientation );
-    onOrientationAbsoluteChanged( anOrientation );
-  }
-  else if( aClipPlane->PlaneMode == Relative ) {
-    ModeStackedLayout->setCurrentIndex( 1 );
-    CurrentMode = Relative;
-    int anOrientation = aClipPlane->RelativeMode.Orientation;
-    // Set plane parameters in the dialog
-    SliderDistance->setValue( aClipPlane->RelativeMode.Distance*100 );
-    TLValueDistance->setText( QString::number(aClipPlane->RelativeMode.Distance ) );
-    SliderRotation1->setValue( aClipPlane->RelativeMode.Rotation1 );
-    TLValueRotation1->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation1 ) );
-    SliderRotation2->setValue( aClipPlane->RelativeMode.Rotation2 );
-    TLValueRotation2->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation2 ) );
-    CBRelativeOrientation->setCurrentIndex( anOrientation );
-    onOrientationRelativeChanged( anOrientation );
-  }
-  isActivePlane->setChecked( aClipPlane->IsActive );
+  updateControls();
   ComboBoxPlanes->setCurrentIndex( theIndex );
-
   myIsSelectPlane = false;
 }
 
@@ -1021,32 +1240,16 @@ void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
 */
 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
 {
-  if ( myClippingPlanes.empty() || myIsSelectPlane )
+  if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )
+  {
     return;
+  }
 
   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
 
-  Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
-  ClipPlane* aPlaneData = aPlane;
-
-  if ( aPlaneData->PlaneMode == Absolute ) {
-    aPlaneData->Orientation = CBAbsoluteOrientation->currentIndex();
-    aPlaneData->X = SpinBox_X->value();
-    aPlaneData->Y = SpinBox_Y->value();
-    aPlaneData->Z = SpinBox_Z->value();
-    aPlaneData->Dx = SpinBox_Dx->value();
-    aPlaneData->Dy = SpinBox_Dy->value();
-    aPlaneData->Dz = SpinBox_Dz->value();
-  }
-  else if( aPlaneData->PlaneMode == Relative ) {
-    aPlaneData->RelativeMode.Orientation = CBRelativeOrientation->currentIndex();
-    aPlaneData->RelativeMode.Distance = TLValueDistance->text().toDouble();
-    aPlaneData->RelativeMode.Rotation1 = TLValueRotation1->text().remove("\xB0").toInt();
-    aPlaneData->RelativeMode.Rotation2 = TLValueRotation2->text().remove("\xB0").toInt();
-    erasePreview();
-    RelativePlaneToAbsolute( aPlane, myView3d );
-  }
-  aPlaneData->IsActive = isActivePlane->isChecked();
+  OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
+
+  setPlaneParam( aPlane );
 }
 
 /*!
@@ -1060,7 +1263,8 @@ void OCCViewer_ClippingDlg::onReset()
   SpinBox_Z->setValue(0);
   myBusy = false;
 
-  updateView();
+  SetCurrentPlaneParam();
+  updateClipping();
 }
 
 /*!
@@ -1078,13 +1282,13 @@ void OCCViewer_ClippingDlg::onInvert()
   SpinBox_Dz->setValue( -Dz );
   myBusy = false;
 
-  if ( !myClippingPlanes.empty() ) {
+  if ( clipPlanesCount() != 0 )
+  {
     int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
-    Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
-    ClipPlane* aPlaneData = aPlane;
-    aPlaneData->IsInvert = !aPlaneData->IsInvert;
+    OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
+    aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;
   }
-  updateView();
+  updateClipping();
 }
 
 /*!
@@ -1110,12 +1314,17 @@ void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
   SpinBox_Dy->setEnabled( isUserMode );
   SpinBox_Dz->setEnabled( isUserMode );
 
-  if ( isUserMode )
-    return;
-
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
   double aDx = 0, aDy = 0, aDz = 0;
 
-  if ( mode == 1 )
+  if ( mode == 0 )
+  {
+    aDx = aPlane.AbsoluteOrientation.Dx;
+    aDy = aPlane.AbsoluteOrientation.Dy;
+    aDz = aPlane.AbsoluteOrientation.Dz;
+  }
+  else if ( mode == 1 )
   {
     aDz = 1;
     TextLabelZ->setEnabled( true );
@@ -1136,22 +1345,25 @@ void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
     SpinBox_Y->setEnabled( true );
     SpinBox_Y->setFocus();
   }
-
-  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
-  Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
-  ClipPlane* aPlaneData = aPlane;
-  if ( aPlaneData->IsInvert == true ) {
-    aDx = -aDx; aDy = -aDy; aDz = -aDz;
+    
+  if ( aPlane.AbsoluteOrientation.IsInvert == true )
+  {
+    aDx = -aDx;
+    aDy = -aDy;
+    aDz = -aDz;
   }
-
+    
   myBusy = true;
   SpinBox_Dx->setValue( aDx );
   SpinBox_Dy->setValue( aDy );
   SpinBox_Dz->setValue( aDz );
   myBusy = false;
 
-  SetCurrentPlaneParam();
-  updateView();
+  if ( !myIsUpdatingControls )
+  {
+    SetCurrentPlaneParam();
+    updateClipping();
+  }
 }
 
 /*!
@@ -1159,9 +1371,9 @@ void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
 */
 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
 {
-  if ( myClippingPlanes.empty() )
+  if ( clipPlanesCount() == 0 )
     return;
-
+  
   if ( theItem == 0 ) {
     TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
     TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
@@ -1175,9 +1387,15 @@ void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
     TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
   }
 
-  if( (QComboBox*)sender() == CBRelativeOrientation )
-    SetCurrentPlaneParam();
-  updateView();
+  if ( !myIsUpdatingControls )
+  {
+    if( (QComboBox*)sender() == CBRelativeOrientation )
+    {
+      SetCurrentPlaneParam();
+    }
+
+    updateClipping();
+  }
 }
 
 /*!
@@ -1195,9 +1413,10 @@ void OCCViewer_ClippingDlg::onPreview( bool on )
 */
 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
 {
-  if ( toggled ) onApply();
-  myView3d->Update();
-  myView3d->Redraw();
+  if ( toggled ) {
+    onApply();
+    myModel->update();
+  }  
 }
 
 /*!
@@ -1208,66 +1427,103 @@ void OCCViewer_ClippingDlg::onApply()
   if ( myBusy )
     return;
   myIsSelectPlane = true;
-  Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes();
-  Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes);
-  for( ;anIter.More();anIter.Next() ){
-    Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
-    aClipPlane->SetOn(Standard_False);
-  }
 
   qApp->processEvents();
   QApplication::setOverrideCursor( Qt::WaitCursor );
   qApp->processEvents();
 
-  for ( int i=0;i<myClippingPlanes.size();i++ ) {
-    Pnt_ClipPlane aPlane = myClippingPlanes[i];
-    ClipPlane* aClipPlane = aPlane;
-    if ( aClipPlane->IsActive == true )
-      myView->setCuttingPlane( true, aClipPlane->X , aClipPlane->Y , aClipPlane->Z,
-                               aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz );
-  }
+  myModel->setClipPlanes(myLocalPlanes);
 
   QApplication::restoreOverrideCursor();
   myIsSelectPlane = false;
 }
 
-void OCCViewer_ClippingDlg::onViewShow()
+/*!
+  SLOT: Called when clip plane is clicked in viewer.
+*/
+void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )
 {
-  if(myAction->isChecked())
-    show();
-  else
-    hide();
-}
+  for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
+  {
+    Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
+    if ( aPlane != thePlane )
+    {
+      continue;
+    }
 
-void OCCViewer_ClippingDlg::onViewHide()
-{
-  hide();
+    ComboBoxPlanes->setCurrentIndex( aPlaneIt );
+
+    break;
+  }
 }
 
 /*!
-  SLOT: Called when value of slider distance change
+  SLOT: Called when clip plane is changed by dragging in viewer.
 */
-void OCCViewer_ClippingDlg::SliderDistanceHasMoved( int value )
+void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )
 {
-  double new_value = value/100.;
-  TLValueDistance->setText( QString("%1").arg( new_value ) );
-  onValueChanged();
+  for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
+  {
+    Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
+    if ( aPlane != thePlane )
+    {
+      continue;
+    }
+
+    OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );
+
+    gp_Pln aPln = thePlane->Component()->Pln();
+    const gp_Pnt& aPlaneP = aPln.Location();
+    const gp_Dir& aPlaneN = aPln.Axis().Direction();
+
+    aClipPlane.X  = aPlaneP.X();
+    aClipPlane.Y  = aPlaneP.Y();
+    aClipPlane.Z  = aPlaneP.Z();
+
+    if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute )
+    {
+      if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
+      {
+        int anInvertCoeff = aClipPlane.AbsoluteOrientation.IsInvert ? 1 : -1;
+        aClipPlane.AbsoluteOrientation.Dx = anInvertCoeff * aPlaneN.X();
+        aClipPlane.AbsoluteOrientation.Dy = anInvertCoeff * aPlaneN.Y();
+        aClipPlane.AbsoluteOrientation.Dz = anInvertCoeff * aPlaneN.Z();
+      }
+    }
+    else
+    {
+      OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(),
+                                           aClipPlane.OrientationType,
+                                           aClipPlane.RelativeOrientation.Rotation1,
+                                           aClipPlane.RelativeOrientation.Rotation2 );
+    }
+
+    myIsUpdatingControls = true;
+    updateControls();
+    myIsUpdatingControls = false;
+
+    if ( AutoApplyCheckBox->isChecked() )
+    {
+      onApply();
+    }
+
+    break;
+  }
 }
 
-/*!
-  SLOT: Called when value of slider rotation1 change
-*/
-void OCCViewer_ClippingDlg::SliderRotation1HasMoved( int value )
+OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
 {
-  TLValueRotation1->setText( QString("%1\xB0").arg( value ) );
-  onValueChanged();
+  return myLocalPlanes[theIdx];
 }
 
-/*!
-  SLOT: Called when value of slider rotation2 change
-*/
-void OCCViewer_ClippingDlg::SliderRotation2HasMoved( int value )
+int OCCViewer_ClippingDlg::clipPlanesCount()
+{
+  return myLocalPlanes.size();
+}
+
+OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const
 {
-  TLValueRotation2->setText( QString("%1\xB0").arg( value ) );
-  onValueChanged();
+  return ModeStackedLayout->currentIndex() == 0
+    ? OCCViewer_ClipPlane::Absolute 
+    : OCCViewer_ClipPlane::Relative;
 }