Salome HOME
updated copyright message
[modules/gui.git] / src / OCCViewer / OCCViewer_ClippingDlg.cxx
index 23b53653a1aa39c97d7a1ec1535e7daa93c9eff0..44ae4a70684223ee2983f4763adc56acaa804462 100644 (file)
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE\r
-//\r
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS\r
-//\r
-// This library is free software; you can redistribute it and/or\r
-// modify it under the terms of the GNU Lesser General Public\r
-// License as published by the Free Software Foundation; either\r
-// version 2.1 of the License, or (at your option) any later version.\r
-//\r
-// This library is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-// Lesser General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU Lesser General Public\r
-// License along with this library; if not, write to the Free Software\r
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
-//\r
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
-//\r
-\r
-#include "OCCViewer_ClippingDlg.h"\r
-\r
-#include <QtxDoubleSpinBox.h>\r
-#include <QtxDoubleSpinSlider.h>\r
-#include <QtxIntSpinSlider.h>\r
-#include <QtxAction.h>\r
-\r
-#include "SUIT_Session.h"\r
-#include "SUIT_ViewWindow.h"\r
-#include "SUIT_ViewManager.h"\r
-#include "OCCViewer_ClipPlane.h"\r
-#include "OCCViewer_ViewWindow.h"\r
-#include "OCCViewer_ViewPort3d.h"\r
-#include "OCCViewer_ViewModel.h"\r
-#include "OCCViewer_ViewManager.h"\r
-#include "OCCViewer_ClipPlaneInteractor.h"\r
-\r
-#include <V3d_View.hxx>\r
-#include <Visual3d_View.hxx>\r
-#include <Geom_Plane.hxx>\r
-#include <Prs3d_Presentation.hxx>\r
-#include <AIS_ListIteratorOfListOfInteractive.hxx>\r
-#include <AIS_ListOfInteractive.hxx>\r
-#include <AIS_InteractiveObject.hxx>\r
-#include <AIS_InteractiveContext.hxx>\r
-#include <IntAna_IntConicQuad.hxx>\r
-#include <gp_Lin.hxx>\r
-#include <gp_Pln.hxx>\r
-#include <math.h>\r
-\r
-// QT Includes\r
-#include <QApplication>\r
-#include <QGroupBox>\r
-#include <QHBoxLayout>\r
-#include <QVBoxLayout>\r
-#include <QGridLayout>\r
-#include <QLabel>\r
-#include <QPushButton>\r
-#include <QComboBox>\r
-#include <QCheckBox>\r
-#include <QStackedLayout>\r
-#include <QSlider>\r
-#include <QMenu>\r
-\r
-/**********************************************************************************\r
- ************************        Internal functions        ************************\r
- *********************************************************************************/\r
-\r
-void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,\r
-                          double  theDefaultSize,\r
-                          double& theXMin,\r
-                          double& theYMin,\r
-                          double& theZMin,\r
-                          double& theXMax,\r
-                          double& theYMax,\r
-                          double& theZMax) {\r
-\r
-  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;\r
-  aXMin = aYMin = aZMin = DBL_MAX;\r
-  aXMax = aYMax = aZMax = -DBL_MAX;\r
-  \r
-  bool isFound = false;\r
-  AIS_ListOfInteractive aList;\r
-  ic->DisplayedObjects( aList );\r
-  for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {\r
-    Handle(AIS_InteractiveObject) anObj = it.Value();\r
-    if ( !anObj.IsNull() && anObj->HasPresentation() &&\r
-         !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {\r
-      Handle(Prs3d_Presentation) aPrs = anObj->Presentation();\r
-      if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {\r
-        isFound = true;\r
-        double xmin, ymin, zmin, xmax, ymax, zmax;\r
-        aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );\r
-        aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );\r
-        aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );\r
-        aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );\r
-      }\r
-    }\r
-  }\r
-\r
-  if(!isFound) {\r
-    if(theDefaultSize == 0.0)\r
-      theDefaultSize = 100.;\r
-    aXMin = aYMin = aZMin = -theDefaultSize;\r
-    aXMax = aYMax = aZMax = theDefaultSize;\r
-  }\r
-  theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;\r
-  theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;\r
-}\r
-\r
-/*!\r
-  Compute the point of bounding box and current clipping plane\r
- */\r
-void ComputeBoundsParam( const double theBounds[6],\r
-                         const double theDirection[3],\r
-                         double theMinPnt[3],\r
-                         double& theMaxBoundPrj,\r
-                         double& theMinBoundPrj )\r
-{\r
-  double aEnlargeBounds[6];\r
-\r
-  // Enlarge bounds in order to avoid conflicts of precision\r
-  for(int i = 0; i < 6; i += 2)\r
-  {\r
-    static double EPS = 1.0E-3;\r
-    double aDelta = (theBounds[i+1] - theBounds[i])*EPS;\r
-    aEnlargeBounds[i  ] = theBounds[i  ] - aDelta;\r
-    aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;\r
-  }\r
-\r
-  double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] },\r
-                                { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] },\r
-                                { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] },\r
-                                { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] },\r
-                                { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] },\r
-                                { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] },\r
-                                { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] },\r
-                                { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } };\r
-\r
-  int aMaxId = 0;\r
-  theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]\r
-                   + theDirection[2] * aBoundPoints[aMaxId][2];\r
-  theMinBoundPrj = theMaxBoundPrj;\r
-  for(int i = 1; i < 8; i++) {\r
-    double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]\r
-                  + theDirection[2] * aBoundPoints[i][2];\r
-    if(theMaxBoundPrj < aTmp) {\r
-      theMaxBoundPrj = aTmp;\r
-      aMaxId = i;\r
-    }\r
-    if(theMinBoundPrj > aTmp) {\r
-      theMinBoundPrj = aTmp;\r
-    }\r
-  }\r
-  double *aMinPnt = aBoundPoints[aMaxId];\r
-  theMinPnt[0] = aMinPnt[0];\r
-  theMinPnt[1] = aMinPnt[1];\r
-  theMinPnt[2] = aMinPnt[2];\r
-}\r
-\r
-/*!\r
-  Compute the position of current plane by distance\r
- */\r
-void DistanceToPosition( const double theBounds[6],\r
-                         const double theDirection[3],\r
-                         const double theDist,\r
-                         double thePos[3] )\r
-{\r
-  double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];\r
-  ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj );\r
-  double aLength = (aMaxBoundPrj - aMinBoundPrj) * theDist;\r
-  thePos[0] = aMinPnt[0] - theDirection[0] * aLength;\r
-  thePos[1] = aMinPnt[1] - theDirection[1] * aLength;\r
-  thePos[2] = aMinPnt[2] - theDirection[2] * aLength;\r
-}\r
-\r
-/*!\r
-  Compute the parameters of clipping plane\r
- */\r
-bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,\r
-                                     const double theDefaultSize,\r
-                                     const double theNormal[3],\r
-                                     const double theDist,\r
-                                     double theOrigin[3] )\r
-{\r
-  double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };\r
-\r
-  getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );\r
-\r
-  DistanceToPosition( aBounds, theNormal, theDist, theOrigin );\r
-  return true;\r
-}\r
-\r
-/*!\r
-  \brief Converts relative plane parameters to absolute.\r
-  \param theIC [in] the interactive context.\r
-  \param theDefaultSize [in] the default trihedron size.\r
-  \param theDistance [in] the plane distance relative to minimum corner of model boundaries.\r
-  \param theDX [in] x component of plane direction.\r
-  \param theDY [in] y component of plane direction.\r
-  \param theDZ [in] z component of plane direction.\r
-  \param theX [out] x coordinate of plane origin.\r
-  \param theY [out] y coordinate of plane origin.\r
-  \param theZ [out] z coordinate of plane origin.\r
- */\r
-bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC,\r
-                     const double theDefaultSize,\r
-                     const double theDistance,\r
-                     const double theDX,\r
-                     const double theDY,\r
-                     const double theDZ,\r
-                     double& theX,\r
-                     double& theY,\r
-                     double& theZ )\r
-{\r
-  double aNormal[3] = { theDX, theDY, theDZ };\r
-  double anOrigin[3] = { 0.0, 0.0, 0.0 };\r
-\r
-  bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin );\r
-\r
-  if( !anIsOk )\r
-  {\r
-    return false;\r
-  }\r
-\r
-  theX = anOrigin[0];\r
-  theY = anOrigin[1];\r
-  theZ = anOrigin[2];\r
-\r
-  return true;\r
-}\r
-\r
-/*!\r
-  \brief Converts absolute position and direction to bounding box distance.\r
-  \param theIC [in] the interactive context.\r
-  \param theDefaultSize [in] the default trihedron size.\r
-  \param theX [in] x coordinate of plane origin.\r
-  \param theY [in] y coordinate of plane origin.\r
-  \param theZ [in] z coordinate of plane origin.\r
-  \param theDX [in] x component of plane direction.\r
-  \param theDY [in] y component of plane direction.\r
-  \param theDZ [in] z component of plane direction.\r
-  \param theDistance [out] the plane distance relative to minimum corner of model boundaries.\r
- */\r
-void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC,\r
-                     const double theDefaultSize,\r
-                     const double theX,\r
-                     const double theY,\r
-                     const double theZ,\r
-                     const double theDX,\r
-                     const double theDY,\r
-                     const double theDZ,\r
-                     double& theDistance )\r
-{\r
-  gp_Pnt aPlaneP( theX, theY, theZ );\r
-  gp_Dir aPlaneN( theDX, theDY, theDZ );\r
-\r
-  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
-\r
-  getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
-\r
-  Bnd_Box aMinMax;\r
-  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
-\r
-  gp_Trsf aRelativeTransform;\r
-  aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );\r
-  Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );\r
-\r
-  aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
-\r
-  double aLength   = aZmax - aZmin;\r
-  double aDistance = aZmax;\r
-\r
-  double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;\r
-  aRelativeDistance = qMin( aRelativeDistance, aLength );\r
-  aRelativeDistance = qMax( aRelativeDistance, 0.0 );\r
-  theDistance = aRelativeDistance;\r
-}\r
-\r
-/*!\r
-  Compute clipping plane size base point and normal\r
- */\r
-\r
-void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,\r
-                     double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {\r
-  double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;\r
-  aXMin = aYMin = aZMin = DBL_MAX;\r
-  aXMax = aYMax = aZMax = -DBL_MAX;\r
-  \r
-  getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);\r
-  double aSize = 50;\r
-\r
-  double aNormalX = 0.0;\r
-  double aNormalY = 0.0;\r
-  double aNormalZ = 0.0;\r
-  theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ );\r
-  gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z );\r
-  gp_Dir aNormal( aNormalX, aNormalY, aNormalZ );\r
-\r
-  // compute clipping plane size\r
-  gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );\r
-  double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;\r
-  aSize = aDiag * 1.1;\r
-  \r
-  // compute clipping plane center ( redefine the base point )\r
-  IntAna_IntConicQuad intersector = IntAna_IntConicQuad();\r
-  \r
-  intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );\r
-\r
-  if ( intersector.IsDone() && intersector.NbPoints() == 1 )\r
-    aBasePnt = intersector.Point( 1 );\r
-  \r
-  theSize = aSize;\r
-  theBasePnt = aBasePnt;\r
-  theNormal = aNormal;\r
-}\r
-\r
-\r
-/*********************************************************************************\r
- *********************      class OCCViewer_ClippingDlg      *********************\r
- *********************************************************************************/\r
-/*!\r
-  Constructor\r
-  \param view - view window\r
-  \param parent - parent widget\r
-*/\r
-OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)\r
-  : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )\r
-{\r
-  setObjectName( "OCCViewer_ClippingDlg" );\r
-  setModal( false );\r
-\r
-  setWindowTitle( tr( "Clipping" ) );\r
-\r
-  setAttribute (Qt::WA_DeleteOnClose, true);\r
-  \r
-  QVBoxLayout* topLayout = new QVBoxLayout( this );\r
-  topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );\r
-\r
-  /***************************************************************/\r
-  // Controls for selecting, creating, deleting planes\r
-  QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );\r
-  QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );\r
-  ComboBoxPlanes = new QComboBox( GroupPlanes );\r
-  isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );\r
-  buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );\r
-  buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );\r
-  buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );\r
-  MenuMode = new QMenu( "MenuMode", buttonNew );\r
-  MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );\r
-  MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );\r
-  buttonNew->setMenu( MenuMode );\r
-\r
-  GroupPlanesLayout->addWidget( ComboBoxPlanes );\r
-  GroupPlanesLayout->addWidget( isActivePlane );\r
-  GroupPlanesLayout->addWidget( buttonNew );\r
-  GroupPlanesLayout->addWidget( buttonDelete );\r
-  GroupPlanesLayout->addWidget( buttonDisableAll );\r
-\r
-  ModeStackedLayout = new QStackedLayout();\r
-\r
-  /**********************   Mode Absolute   **********************/\r
-  /* Controls for absolute mode of clipping plane:\r
-     X, Y, Z - coordinates of the intersection of cutting plane and the three axes\r
-     Dx, Dy, Dz - components of normal to the cutting plane\r
-     Orientation - direction of cutting plane\r
-   */\r
-  const double min = -1e+7;\r
-  const double max =  1e+7;\r
-  const double step = 5;\r
-  const int precision = -7;\r
-\r
-  // Croup Point\r
-  QGroupBox* GroupAbsolutePoint = new QGroupBox( this );\r
-  GroupAbsolutePoint->setObjectName( "GroupPoint" );\r
-  GroupAbsolutePoint->setTitle( tr("BASE_POINT") );\r
-  QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );\r
-  GroupPointLayout->setAlignment( Qt::AlignTop );\r
-  GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );\r
-\r
-  TextLabelX = new QLabel( GroupAbsolutePoint );\r
-  TextLabelX->setObjectName( "TextLabelX" );\r
-  TextLabelX->setText( tr("X:") );\r
-  GroupPointLayout->addWidget( TextLabelX, 0, 0 );\r
-  \r
-  SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
-  SpinBox_X->setObjectName("SpinBox_X" );\r
-  SpinBox_X->setPrecision( precision );\r
-  GroupPointLayout->addWidget( SpinBox_X, 0, 1 );\r
-\r
-  TextLabelY = new QLabel( GroupAbsolutePoint );\r
-  TextLabelY->setObjectName( "TextLabelY" );\r
-  TextLabelY->setText( tr("Y:") );\r
-  GroupPointLayout->addWidget( TextLabelY, 0, 2 );\r
-\r
-  SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
-  SpinBox_Y->setObjectName("SpinBox_Y" );\r
-  SpinBox_Y->setPrecision( precision );\r
-  GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );\r
-\r
-  TextLabelZ = new QLabel( GroupAbsolutePoint );\r
-  TextLabelZ->setObjectName( "TextLabelZ" );\r
-  TextLabelZ->setText( tr("Z:") );\r
-  GroupPointLayout->addWidget( TextLabelZ, 0, 4 );\r
-\r
-  SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
-  SpinBox_Z->setObjectName("SpinBox_Z" );\r
-  SpinBox_Z->setPrecision( precision );\r
-  GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );\r
-\r
-  resetButton  = new QPushButton( GroupAbsolutePoint );\r
-  resetButton->setObjectName( "resetButton" );\r
-  resetButton->setText( tr( "RESET"  ) );\r
-  GroupPointLayout->addWidget( resetButton, 0, 6 );\r
-\r
-  // Group Direction\r
-  GroupAbsoluteDirection = new QGroupBox( this );\r
-  GroupAbsoluteDirection->setObjectName( "GroupDirection" );\r
-  GroupAbsoluteDirection->setTitle( tr("DIRECTION") );\r
-  QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );\r
-  GroupDirectionLayout->setAlignment( Qt::AlignTop );\r
-  GroupDirectionLayout->setSpacing( 6 );\r
-  GroupDirectionLayout->setMargin( 11 );\r
-  \r
-  TextLabelDx = new QLabel( GroupAbsoluteDirection );\r
-  TextLabelDx->setObjectName( "TextLabelDx" );\r
-  TextLabelDx->setText( tr("Dx:") );\r
-  GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );\r
-  \r
-  SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
-  SpinBox_Dx->setObjectName("SpinBox_Dx" );\r
-  SpinBox_Dx->setPrecision( precision );\r
-  GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );\r
-\r
-  TextLabelDy = new QLabel( GroupAbsoluteDirection );\r
-  TextLabelDy->setObjectName( "TextLabelDy" );\r
-  TextLabelDy->setText( tr("Dy:") );\r
-  GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );\r
-  \r
-  SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
-  SpinBox_Dy->setObjectName("SpinBox_Dy" );\r
-  SpinBox_Dy->setPrecision( precision );\r
-  GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );\r
-\r
-  TextLabelDz = new QLabel( GroupAbsoluteDirection );\r
-  TextLabelDz->setObjectName( "TextLabelDz" );\r
-  TextLabelDz->setText( tr("Dz:") );\r
-  GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );\r
-  \r
-  SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
-  SpinBox_Dz->setObjectName("SpinBox_Dz" );\r
-  SpinBox_Dz->setPrecision( precision );\r
-  GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );\r
-\r
-  invertButton  = new QPushButton( GroupAbsoluteDirection );\r
-  invertButton->setObjectName( "invertButton" );\r
-  invertButton->setText( tr( "INVERT"  ) );\r
-  GroupDirectionLayout->addWidget( invertButton, 0, 6 );\r
\r
-  CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );\r
-  CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );\r
-  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );\r
-  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );\r
-  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );\r
-  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );\r
-  GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );\r
-\r
-  QVBoxLayout* ModeActiveLayout = new QVBoxLayout();\r
-  ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );\r
-  ModeActiveLayout->addWidget( GroupAbsolutePoint );\r
-  ModeActiveLayout->addWidget( GroupAbsoluteDirection );\r
-\r
-  QWidget* ModeActiveWidget = new QWidget( this );\r
-  ModeActiveWidget->setLayout( ModeActiveLayout );\r
-\r
-  /**********************   Mode Relative   **********************/\r
-  /* Controls for relative mode of clipping plane:\r
-     Distance - Value from 0 to 1.\r
-     Specifies the distance from the minimum value in a given direction of bounding box to the current position\r
-     Rotation1, Rotation2 - turn angles of cutting plane in given directions\r
-     Orientation - direction of cutting plane\r
-   */\r
-  QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );\r
-  QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );\r
-  GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );\r
-\r
-  TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);\r
-  TextLabelOrientation->setObjectName( "TextLabelOrientation" );\r
-  GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );\r
-\r
-  CBRelativeOrientation = new QComboBox(GroupParameters);\r
-  CBRelativeOrientation->setObjectName( "RelativeOrientation" );\r
-  CBRelativeOrientation->addItem( tr("ALONG_XY") );\r
-  CBRelativeOrientation->addItem( tr("ALONG_YZ") );\r
-  CBRelativeOrientation->addItem( tr("ALONG_ZX") );\r
-  GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );\r
-\r
-  TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );\r
-  TextLabelDistance->setObjectName( "TextLabelDistance" );\r
-  GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );\r
-  \r
-  SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );\r
-  SpinSliderDistance->setObjectName( "SpinSliderDistance" );\r
-  SpinSliderDistance->setPrecision( precision );\r
-  QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );\r
-  GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );\r
-\r
-  QString aUnitRot = "\xB0";\r
-\r
-  TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );\r
-  TextLabelRotation1->setObjectName( "TextLabelRotation1" );\r
-  GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );\r
-  \r
-  SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );\r
-  SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );\r
-  SpinSliderRotation1->setUnit( aUnitRot );\r
-  SpinSliderRotation1->setFont( fnt );\r
-  GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );\r
-\r
-  TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);\r
-  TextLabelRotation2->setObjectName( "TextLabelRotation2" );\r
-  TextLabelRotation2->setObjectName( "TextLabelRotation2" );\r
-  GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );\r
-\r
-  SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );\r
-  SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );\r
-  SpinSliderRotation2->setUnit( aUnitRot );\r
-  SpinSliderRotation2->setFont( fnt );\r
-  GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );\r
-\r
-  /***************************************************************/\r
-  QGroupBox* CheckBoxWidget = new QGroupBox( this );\r
-  QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );\r
-  \r
-  PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );\r
-  PreviewCheckBox->setObjectName( "PreviewCheckBox" );\r
-  PreviewCheckBox->setChecked( true );\r
-  CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );\r
-  \r
-  AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );\r
-  AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );\r
-  CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );\r
-\r
-  /***************************************************************/\r
-  QGroupBox* GroupButtons = new QGroupBox( this );\r
-  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );\r
-  GroupButtonsLayout->setAlignment( Qt::AlignTop );\r
-  GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );\r
-  \r
-  buttonOk = new QPushButton( GroupButtons );\r
-  buttonOk->setObjectName( "buttonOk" );\r
-  buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE"  ) );\r
-  buttonOk->setAutoDefault( TRUE );\r
-  buttonOk->setDefault( TRUE );\r
-  GroupButtonsLayout->addWidget( buttonOk );\r
-\r
-  buttonApply = new QPushButton( GroupButtons );\r
-  buttonApply->setObjectName( "buttonApply" );\r
-  buttonApply->setText( tr( "BUT_APPLY"  ) );\r
-  buttonApply->setAutoDefault( TRUE );\r
-  buttonApply->setDefault( TRUE );\r
-  GroupButtonsLayout->addWidget( buttonApply );\r
-\r
-  GroupButtonsLayout->addStretch();\r
-  \r
-  buttonClose = new QPushButton( GroupButtons );\r
-  buttonClose->setObjectName( "buttonClose" );\r
-  buttonClose->setText( tr( "BUT_CLOSE"  ) );\r
-  buttonClose->setAutoDefault( TRUE );\r
-  GroupButtonsLayout->addWidget( buttonClose );\r
-\r
-  QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );\r
-  buttonHelp->setAutoDefault( TRUE );\r
-  GroupButtonsLayout->addWidget( buttonHelp );\r
-\r
-  /***************************************************************/\r
-  ModeStackedLayout->addWidget( ModeActiveWidget );\r
-  ModeStackedLayout->addWidget( GroupParameters );\r
-\r
-  topLayout->addWidget( GroupPlanes );\r
-  topLayout->addLayout( ModeStackedLayout );\r
-  topLayout->addWidget( CheckBoxWidget );\r
-  topLayout->addWidget( GroupButtons );\r
-\r
-  this->setLayout( topLayout );\r
-\r
-  // Initializations\r
-  initParam();\r
-\r
-  // Signals and slots connections\r
-  connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );\r
-  connect( isActivePlane,  SIGNAL ( toggled ( bool ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );\r
-  connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );\r
-  connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );\r
-\r
-  connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );\r
-  connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;\r
-  connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;\r
-\r
-  connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );\r
-  connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
-  connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );\r
-  connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );\r
-\r
-  connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;\r
-  connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );\r
-  \r
-  connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;\r
-  connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );\r
-  connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );\r
-  connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );\r
-\r
-  myBusy = false;\r
-  myIsSelectPlane = false;\r
-  myIsPlaneCreation = false;\r
-  myIsUpdatingControls = false;\r
-  myModel = model;\r
-\r
-  myModel->getViewer3d()->InitActiveViews();\r
-\r
-  OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();\r
-  myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );\r
-  connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );\r
-  connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );\r
-\r
-  myLocalPlanes = myModel->getClipPlanes();\r
-  synchronize();\r
-}\r
-\r
-/*!\r
-  Destructor\r
-  Destroys the object and frees any allocated resources\r
-*/\r
-OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()\r
-{\r
-  myLocalPlanes.clear();\r
-}\r
-\r
-/*!\r
-  Custom handling of close event: erases preview\r
-*/\r
-void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )\r
-{\r
-  erasePreview();\r
-  QDialog::closeEvent( e );\r
-  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
-  if(v)\r
-    v->onClipping(false);\r
-}\r
-\r
-/*!\r
-  Custom handling of show event: displays preview\r
-*/\r
-void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )\r
-{\r
-  QDialog::showEvent( e );\r
-  onPreview( PreviewCheckBox->isChecked() );\r
-}\r
-\r
-/*!\r
-  Custom handling of hide event: erases preview\r
-*/\r
-void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )\r
-{\r
-  erasePreview();\r
-  QDialog::hideEvent( e );\r
-  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
-  if(v)\r
-    v->onClipping(false);\r
-\r
-}\r
-\r
-/*!\r
-  Initialization of initial values of widgets\r
-*/\r
-void OCCViewer_ClippingDlg::initParam()\r
-{\r
-  SpinBox_X->setValue( 0.0 );\r
-  SpinBox_Y->setValue( 0.0 );\r
-  SpinBox_Z->setValue( 0.0 );\r
-\r
-  SpinBox_Dx->setValue( 1.0 );\r
-  SpinBox_Dy->setValue( 1.0 );\r
-  SpinBox_Dz->setValue( 1.0 );\r
-\r
-  CBAbsoluteOrientation->setCurrentIndex(0);\r
-\r
-  SpinSliderDistance->setValue( 0.5 );\r
-  SpinSliderRotation1->setValue( 0 );\r
-  SpinSliderRotation2->setValue( 0 );\r
-  CBRelativeOrientation->setCurrentIndex( 0 );\r
-\r
-  isActivePlane->setChecked( true );\r
-}\r
-\r
-/*!\r
-  Set plane parameters from widgets.\r
-*/\r
-void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane )\r
-{\r
-  OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode();\r
-\r
-  thePlane.Mode = aMode;\r
-\r
-  if ( aMode == OCCViewer_ClipPlane::Absolute )\r
-  {\r
-    if( qFuzzyIsNull( SpinBox_Dx->value() ) && \r
-        qFuzzyIsNull( SpinBox_Dy->value() ) && \r
-        qFuzzyIsNull( SpinBox_Dz->value() ) ) {\r
-      return;\r
-    }\r
-  }\r
-\r
-  thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute)\r
-    ? CBAbsoluteOrientation->currentIndex()\r
-    : CBRelativeOrientation->currentIndex();\r
-\r
-  // Get XYZ, DXYZ\r
-  if ( aMode == OCCViewer_ClipPlane::Absolute )\r
-  {\r
-    if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )\r
-    {\r
-      thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value();\r
-      thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value();\r
-      thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value();\r
-    }\r
-    else\r
-    {\r
-      thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0\r
-                                           || SpinBox_Dy->value() < 0.0\r
-                                           || SpinBox_Dz->value() < 0.0;\r
-    }\r
-\r
-    thePlane.X = SpinBox_X->value();\r
-    thePlane.Y = SpinBox_Y->value();\r
-    thePlane.Z = SpinBox_Z->value();\r
-  }\r
-  else\r
-  {\r
-    thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value();\r
-    thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value();\r
-\r
-    double aPlaneDx = 0.0;\r
-    double aPlaneDy = 0.0;\r
-    double aPlaneDz = 0.0;\r
-    double aX = 0.0;\r
-    double aY = 0.0;\r
-    double aZ = 0.0;\r
-\r
-    OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType,\r
-                                         thePlane.RelativeOrientation.Rotation1,\r
-                                         thePlane.RelativeOrientation.Rotation2,\r
-                                         aPlaneDx, aPlaneDy, aPlaneDz );\r
-\r
-    DistanceToXYZ( myModel->getAISContext(),\r
-                   myModel->trihedronSize(),\r
-                   SpinSliderDistance->value(),\r
-                   aPlaneDx, aPlaneDy, aPlaneDz,\r
-                   aX, aY, aZ );\r
-\r
-    thePlane.X = aX;\r
-    thePlane.Y = aY;\r
-    thePlane.Z = aZ;\r
-  }\r
-\r
-  thePlane.IsOn = isActivePlane->isChecked();\r
-}\r
-\r
-/*!\r
-  Synchronize dialog's widgets with data\r
-*/\r
-void OCCViewer_ClippingDlg::synchronize()\r
-{\r
-  ComboBoxPlanes->clear();\r
-  int aNbPlanesAbsolute = myLocalPlanes.size();\r
-\r
-  QString aName;\r
-  for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {\r
-    aName = QString("Plane %1").arg(i);\r
-    ComboBoxPlanes->addItem( aName );\r
-  }\r
-\r
-  int aPos = ComboBoxPlanes->count() - 1;\r
-  ComboBoxPlanes->setCurrentIndex( aPos );\r
-\r
-  bool anIsControlsEnable = ( aPos >= 0 );\r
-  if ( anIsControlsEnable ) {\r
-    onSelectPlane( aPos );\r
-  }\r
-  else {\r
-    ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );\r
-    initParam();\r
-  }\r
-  if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )\r
-  {\r
-    SpinBox_X->setEnabled( anIsControlsEnable );\r
-    SpinBox_Y->setEnabled( anIsControlsEnable );\r
-    SpinBox_Z->setEnabled( anIsControlsEnable );\r
-    SpinBox_Dx->setEnabled( anIsControlsEnable );\r
-    SpinBox_Dy->setEnabled( anIsControlsEnable );\r
-    SpinBox_Dz->setEnabled( anIsControlsEnable );\r
-    CBAbsoluteOrientation->setEnabled( anIsControlsEnable );\r
-    invertButton->setEnabled( anIsControlsEnable );\r
-    resetButton->setEnabled( anIsControlsEnable );\r
-  }\r
-  else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )\r
-  {\r
-    CBRelativeOrientation->setEnabled( anIsControlsEnable );\r
-    SpinSliderDistance->setEnabled( anIsControlsEnable );\r
-    SpinSliderRotation1->setEnabled( anIsControlsEnable );\r
-    SpinSliderRotation2->setEnabled( anIsControlsEnable );\r
-    isActivePlane->setEnabled( anIsControlsEnable );\r
-  }\r
-  isActivePlane->setEnabled( anIsControlsEnable );\r
-}\r
-\r
-/*!\r
-  Displays preview of clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::displayPreview()\r
-{\r
-  if ( myBusy || !isValid() || !myModel)\r
-    return;\r
-\r
-  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
-  \r
-  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
-\r
-  for ( int i=0; i < clipPlanesCount(); i++ ) {\r
-    OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);\r
-    if ( aClipPlane.IsOn ) {\r
-      Handle(AIS_Plane) myPreviewPlane;\r
-      double aSize;\r
-      gp_Pnt aBasePnt;\r
-      gp_Dir aNormal;\r
-      clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());\r
-      myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );\r
-      myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );\r
-      myPreviewPlane->SetSize( aSize, aSize );\r
-      ic->SetWidth( myPreviewPlane, 10, false );\r
-      ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );\r
-      ic->SetTransparency( myPreviewPlane, 0.5, false );\r
-      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 );\r
-      ic->SetColor( myPreviewPlane, c , false );\r
-      ic->Display( myPreviewPlane, 1, 0, false );\r
-      myPreviewPlaneVector.push_back( myPreviewPlane );\r
-    }\r
-  }\r
-  myModel->update();\r
-\r
-  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
-  getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);\r
-  gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,\r
-                          (aYmax + aYmin) * 0.5,\r
-                          (aZmax + aZmin) * 0.5 );\r
-  Bnd_Box aMinMax;\r
-  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
-\r
-  myInteractor->setPlanes( myPreviewPlaneVector );\r
-  myInteractor->setRotationCenter( aRotationCenter );\r
-  myInteractor->setMinMax( aMinMax );\r
-  myInteractor->setEnabled( true );\r
-}\r
-\r
-void OCCViewer_ClippingDlg::updatePreview() {\r
-  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
-  int count = clipPlanesCount();\r
-  if ( myBusy || \r
-       !isValid() || \r
-       myIsPlaneCreation ||\r
-       !myModel || \r
-       count == 0 || \r
-       (aCurPlaneIndex +1 > count) ||\r
-       !PreviewCheckBox->isChecked())\r
-    return;\r
-  \r
-  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
-  \r
-  OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);\r
-  Handle(AIS_Plane) myPreviewPlane;\r
-\r
-  if (aClipPlane.IsOn) {\r
-    double aSize;\r
-    gp_Pnt aBasePnt;\r
-    gp_Dir aNormal;\r
-    clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());\r
-    if(myPreviewPlaneVector.size() < clipPlanesCount()) {\r
-      myPreviewPlaneVector.resize(clipPlanesCount());\r
-    }\r
-    myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];\r
-    if(myPreviewPlane.IsNull()) {\r
-      //Plane was not created\r
-      myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );\r
-      myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );\r
-      myPreviewPlane->SetSize( aSize, aSize );\r
-      ic->Display( myPreviewPlane, 1, 0, false );\r
-      ic->SetWidth( myPreviewPlane, 10, false );\r
-      ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );\r
-      ic->SetTransparency( myPreviewPlane, 0.5, false );\r
-      myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;\r
-    } else {      \r
-      myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );\r
-      myPreviewPlane->SetCenter( aBasePnt );\r
-      myPreviewPlane->SetSize( aSize, aSize ); \r
-    }\r
-\r
-    ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );\r
-    ic->Update( myPreviewPlane, Standard_False );\r
-  } else {\r
-    if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {\r
-      myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];\r
-      if(ic->IsDisplayed(myPreviewPlane)) {\r
-       ic->Erase( myPreviewPlane, false );\r
-       ic->Remove( myPreviewPlane, false );\r
-      }\r
-      myPreviewPlaneVector[aCurPlaneIndex].Nullify();\r
-    }\r
-  }\r
-  for(int i = 0; i < myPreviewPlaneVector.size(); i++) {\r
-    if( i == aCurPlaneIndex ) continue;\r
-    if(!myPreviewPlaneVector[i].IsNull())\r
-      ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );\r
-  }\r
-  myModel->update();\r
-\r
-  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
-  getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);\r
-  gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,\r
-                          (aYmax + aYmin) * 0.5,\r
-                          (aZmax + aZmin) * 0.5 );\r
-  Bnd_Box aMinMax;\r
-  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
-\r
-  myInteractor->setPlanes( myPreviewPlaneVector );\r
-  myInteractor->setRotationCenter( aRotationCenter );\r
-  myInteractor->setMinMax( aMinMax );\r
-}\r
-\r
-/*!\r
-  Erases preview of clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::erasePreview()\r
-{\r
-  if ( !myModel )\r
-    return;\r
-\r
-  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
-\r
-  for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {\r
-  Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];\r
-    if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {\r
-      ic->Erase( myPreviewPlane, false );\r
-      ic->Remove( myPreviewPlane, false );\r
-      myPreviewPlane.Nullify();\r
-    }\r
-  }\r
-  myPreviewPlaneVector.clear();\r
-  myModel->update();\r
-  myInteractor->setEnabled( false );\r
-}\r
-\r
-/*!\r
-  Return true if plane parameters are valid\r
-*/\r
-bool OCCViewer_ClippingDlg::isValid()\r
-{\r
-  return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );\r
-}\r
-\r
-/*!\r
-  Update view after changes\r
-*/\r
-void OCCViewer_ClippingDlg::updateClipping()\r
-{\r
-  if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())\r
-  {\r
-    if (AutoApplyCheckBox->isChecked()) {\r
-      onApply();\r
-    }\r
-    \r
-    if (!PreviewCheckBox->isChecked())\r
-      myModel->update();\r
-    else \r
-      updatePreview();\r
-  }\r
-}\r
-\r
-/*!\r
-  Updates state of user controls.\r
-*/\r
-void OCCViewer_ClippingDlg::updateControls()\r
-{\r
-  if ( clipPlanesCount() == 0 )\r
-  {\r
-    initParam();\r
-    return;\r
-  }\r
-\r
-  int aPlaneIdx = ComboBoxPlanes->currentIndex();\r
-\r
-  OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );\r
-\r
-  double aPlaneDx  = 0.0;\r
-  double aPlaneDy  = 0.0;\r
-  double aPlaneDz  = 0.0;\r
-  double aDistance = 0.0;\r
-  aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz );\r
-\r
-  if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute )\r
-  {\r
-    ModeStackedLayout->setCurrentIndex( 0 );\r
-\r
-    // Set plane parameters in the dialog\r
-    SpinBox_X->setValue( aPlane.X );\r
-    SpinBox_Y->setValue( aPlane.Y );\r
-    SpinBox_Z->setValue( aPlane.Z );\r
-    SpinBox_Dx->setValue( aPlaneDx );\r
-    SpinBox_Dy->setValue( aPlaneDy );\r
-    SpinBox_Dz->setValue( aPlaneDz );\r
-    CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType );\r
-    onOrientationAbsoluteChanged( aPlane.OrientationType );\r
-  }\r
-  else if( aPlane.Mode == OCCViewer_ClipPlane::Relative )\r
-  {\r
-    ModeStackedLayout->setCurrentIndex( 1 );\r
-\r
-    // Set plane parameters in the dialog\r
-    SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) );\r
-    SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) );\r
-\r
-    XYZToDistance( myModel->getAISContext(),\r
-                   myModel->trihedronSize(),\r
-                   aPlane.X, aPlane.Y, aPlane.Z,\r
-                   aPlaneDx, aPlaneDy, aPlaneDz,\r
-                   aDistance );\r
-\r
-    SpinSliderDistance->setValue( aDistance );\r
-\r
-    CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType );\r
-    onOrientationRelativeChanged( aPlane.OrientationType );\r
-  }\r
-\r
-  isActivePlane->setChecked( aPlane.IsOn );\r
-}\r
-\r
-/*!\r
-  SLOT on new button click: create a new clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnNew()\r
-{\r
-  OCCViewer_ClipPlane aClipPlane;\r
-\r
-  // init controls state\r
-  myIsUpdatingControls = true;\r
-  initParam();\r
-  myIsUpdatingControls = false;\r
-\r
-  // init plane according to the state of controls\r
-  setPlaneParam( aClipPlane );\r
-\r
-  // add plane\r
-  myLocalPlanes.push_back( aClipPlane );\r
-  synchronize();\r
-}\r
-\r
-/*!\r
-  SLOT on delete button click: Delete selected clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnDelete()\r
-{\r
-  int aPlaneIndex = ComboBoxPlanes->currentIndex();\r
-  if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))\r
-    return;\r
-\r
-  myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);\r
-\r
-  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
-\r
-  if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {\r
-    Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];\r
-    if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {\r
-      ic->Erase( myPreviewPlane, false );\r
-      ic->Remove( myPreviewPlane, false );\r
-    }\r
-    myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);\r
-  }\r
-  synchronize();\r
-  if (AutoApplyCheckBox->isChecked()) {\r
-    onApply();\r
-  }\r
-  myModel->update();\r
-}\r
-\r
-/*!\r
-  SLOT on disable all button click: Restore initial state of viewer,\r
-  erase all clipping planes\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnDisableAll()\r
-{\r
-  AutoApplyCheckBox->setChecked (false);\r
-  int aClipPlanesCount = clipPlanesCount();\r
-  for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)\r
-  {\r
-    OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);\r
-    aPlane.IsOn = false;\r
-  }\r
-  erasePreview();\r
-  isActivePlane->setChecked(false);\r
-  myModel->setClipPlanes(myLocalPlanes);\r
-  myModel->update();\r
-}\r
-\r
-/*!\r
-  SLOT on ok button click: sets cutting plane and closes dialog\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnOk()\r
-{\r
-  onApply();\r
-  ClickOnClose();\r
-}\r
-\r
-/*!\r
-  SLOT on Apply button click: sets cutting plane and update viewer\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnApply()\r
-{\r
-  onApply();\r
-  myModel->update();\r
-}\r
-\r
-/*!\r
-  SLOT on close button click: erases preview and rejects dialog\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnClose()\r
-{\r
-  erasePreview();\r
-  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
-  if(v)\r
-    v->onClipping(false);\r
-}\r
-\r
-/*!\r
-  SLOT on help button click: opens a help page\r
-*/\r
-void OCCViewer_ClippingDlg::ClickOnHelp()\r
-{\r
-  SUIT_Application* app = SUIT_Session::session()->activeApplication();\r
-  if ( app )\r
-    app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );\r
-}\r
-\r
-/*!\r
-  Set absolute mode of clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::onModeAbsolute()\r
-{\r
-  myIsPlaneCreation = true;\r
-  ModeStackedLayout->setCurrentIndex(0);\r
-  ClickOnNew();\r
-  myIsPlaneCreation = false;\r
-  updateClipping();\r
-}\r
-\r
-/*!\r
-  Set relative mode of clipping plane\r
-*/\r
-void OCCViewer_ClippingDlg::onModeRelative()\r
-{\r
-  myIsPlaneCreation = true;\r
-  ModeStackedLayout->setCurrentIndex(1);\r
-  ClickOnNew();\r
-  myIsPlaneCreation = false;\r
-  SetCurrentPlaneParam();\r
-  updateClipping();\r
-}\r
-\r
-/*!\r
-  SLOT: called on value of clipping plane changed\r
-*/\r
-void OCCViewer_ClippingDlg::onValueChanged()\r
-{\r
-  if ( myIsUpdatingControls )\r
-  {\r
-    return;\r
-  }\r
-\r
-  SetCurrentPlaneParam();\r
-\r
-  if ( myIsSelectPlane )\r
-  {\r
-    return;\r
-  }\r
-\r
-  updateClipping();\r
-}\r
-\r
-/*!\r
-  Set current parameters of selected plane\r
-*/\r
-void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )\r
-{\r
-  if ( clipPlanesCount() == 0 )\r
-  {\r
-    return;\r
-  }\r
-\r
-  OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );\r
-\r
-  myIsSelectPlane = true;\r
-  updateControls();\r
-  ComboBoxPlanes->setCurrentIndex( theIndex );\r
-  myIsSelectPlane = false;\r
-}\r
-\r
-/*!\r
-  Restore parameters of selected plane\r
-*/\r
-void OCCViewer_ClippingDlg::SetCurrentPlaneParam()\r
-{\r
-  if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )\r
-  {\r
-    return;\r
-  }\r
-\r
-  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
-\r
-  OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
-\r
-  setPlaneParam( aPlane );\r
-}\r
-\r
-/*!\r
-  SLOT on reset button click: sets default values\r
-*/\r
-void OCCViewer_ClippingDlg::onReset()\r
-{\r
-  myBusy = true;\r
-  SpinBox_X->setValue(0);\r
-  SpinBox_Y->setValue(0);\r
-  SpinBox_Z->setValue(0);\r
-  myBusy = false;\r
-\r
-  updateClipping();\r
-}\r
-\r
-/*!\r
-  SLOT on invert button click: inverts normal of cutting plane\r
-*/\r
-void OCCViewer_ClippingDlg::onInvert()\r
-{\r
-  double Dx = SpinBox_Dx->value();\r
-  double Dy = SpinBox_Dy->value();\r
-  double Dz = SpinBox_Dz->value();\r
-\r
-  myBusy = true;\r
-  SpinBox_Dx->setValue( -Dx );\r
-  SpinBox_Dy->setValue( -Dy );\r
-  SpinBox_Dz->setValue( -Dz );\r
-  myBusy = false;\r
-\r
-  if ( clipPlanesCount() != 0 )\r
-  {\r
-    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
-    OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
-    aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;\r
-  }\r
-  updateClipping();\r
-}\r
-\r
-/*!\r
-  SLOT: called on orientation of clipping plane in absolute mode changed\r
-*/\r
-void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )\r
-{\r
-  bool isUserMode = (mode==0);\r
-\r
-  TextLabelX->setEnabled( isUserMode );\r
-  TextLabelY->setEnabled( isUserMode );\r
-  TextLabelZ->setEnabled( isUserMode );\r
-\r
-  SpinBox_X->setEnabled( isUserMode );\r
-  SpinBox_Y->setEnabled( isUserMode );\r
-  SpinBox_Z->setEnabled( isUserMode );\r
-\r
-  TextLabelDx->setEnabled( isUserMode );\r
-  TextLabelDy->setEnabled( isUserMode );\r
-  TextLabelDz->setEnabled( isUserMode );\r
-\r
-  SpinBox_Dx->setEnabled( isUserMode );\r
-  SpinBox_Dy->setEnabled( isUserMode );\r
-  SpinBox_Dz->setEnabled( isUserMode );\r
-\r
-  if ( !isUserMode ) {\r
-\r
-    double aDx = 0, aDy = 0, aDz = 0;\r
-\r
-    if ( mode == 1 )\r
-    {\r
-      aDz = 1;\r
-      TextLabelZ->setEnabled( true );\r
-      SpinBox_Z->setEnabled( true );\r
-      SpinBox_Z->setFocus();\r
-    }\r
-    else if ( mode == 2 )\r
-    {\r
-      aDx = 1;\r
-      TextLabelX->setEnabled( true );\r
-      SpinBox_X->setEnabled( true );\r
-      SpinBox_X->setFocus();\r
-    }\r
-    else if ( mode == 3 )\r
-    {\r
-      aDy = 1;\r
-      TextLabelY->setEnabled( true );\r
-      SpinBox_Y->setEnabled( true );\r
-      SpinBox_Y->setFocus();\r
-    }\r
-    \r
-    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
-    OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
-    if ( aPlane.AbsoluteOrientation.IsInvert == true )\r
-    {\r
-      aDx = -aDx;\r
-      aDy = -aDy;\r
-      aDz = -aDz;\r
-    }\r
-    \r
-    myBusy = true;\r
-    SpinBox_Dx->setValue( aDx );\r
-    SpinBox_Dy->setValue( aDy );\r
-    SpinBox_Dz->setValue( aDz );\r
-    myBusy = false;\r
-  }\r
-\r
-  if ( !myIsUpdatingControls )\r
-  {\r
-    SetCurrentPlaneParam();\r
-    updateClipping();\r
-  }\r
-}\r
-\r
-/*!\r
-  SLOT: called on orientation of clipping plane in relative mode changed\r
-*/\r
-void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)\r
-{\r
-  if ( clipPlanesCount() == 0 )\r
-    return;\r
-  \r
-  if ( theItem == 0 ) {\r
-    TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );\r
-    TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );\r
-  }\r
-  else if ( theItem == 1 ) {\r
-    TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );\r
-    TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );\r
-  }\r
-  else if ( theItem == 2 ) {\r
-    TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );\r
-    TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );\r
-  }\r
-\r
-  if ( !myIsUpdatingControls )\r
-  {\r
-    if( (QComboBox*)sender() == CBRelativeOrientation )\r
-    {\r
-      SetCurrentPlaneParam();\r
-    }\r
-\r
-    updateClipping();\r
-  }\r
-}\r
-\r
-/*!\r
-  SLOT: called on preview check box toggled\r
-*/\r
-void OCCViewer_ClippingDlg::onPreview( bool on )\r
-{\r
-  erasePreview();\r
-  if ( on ) \r
-    displayPreview();\r
-}\r
-\r
-/*!\r
-  SLOT: called on Auto Apply check box toggled\r
-*/\r
-void OCCViewer_ClippingDlg::onAutoApply( bool toggled )\r
-{\r
-  if ( toggled ) {\r
-    onApply();\r
-    myModel->update();\r
-  }  \r
-}\r
-\r
-/*!\r
-  SLOT on Apply button click: sets cutting plane\r
-*/\r
-void OCCViewer_ClippingDlg::onApply()\r
-{\r
-  if ( myBusy )\r
-    return;\r
-  myIsSelectPlane = true;\r
-\r
-  qApp->processEvents();\r
-  QApplication::setOverrideCursor( Qt::WaitCursor );\r
-  qApp->processEvents();\r
-\r
-  myModel->setClipPlanes(myLocalPlanes);\r
-\r
-  QApplication::restoreOverrideCursor();\r
-  myIsSelectPlane = false;\r
-}\r
-\r
-/*!\r
-  SLOT: Called when clip plane is clicked in viewer.\r
-*/\r
-void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )\r
-{\r
-  for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )\r
-  {\r
-    Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );\r
-    if ( aPlane != thePlane )\r
-    {\r
-      continue;\r
-    }\r
-\r
-    ComboBoxPlanes->setCurrentIndex( aPlaneIt );\r
-\r
-    break;\r
-  }\r
-}\r
-\r
-/*!\r
-  SLOT: Called when clip plane is changed by dragging in viewer.\r
-*/\r
-void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )\r
-{\r
-  for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )\r
-  {\r
-    Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );\r
-    if ( aPlane != thePlane )\r
-    {\r
-      continue;\r
-    }\r
-\r
-    OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );\r
-\r
-    gp_Pln aPln = thePlane->Component()->Pln();\r
-    const gp_Pnt& aPlaneP = aPln.Location();\r
-    const gp_Dir& aPlaneN = aPln.Axis().Direction();\r
-\r
-    aClipPlane.X  = aPlaneP.X();\r
-    aClipPlane.Y  = aPlaneP.Y();\r
-    aClipPlane.Z  = aPlaneP.Z();\r
-\r
-    if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute )\r
-    {\r
-      if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )\r
-      {\r
-        aClipPlane.AbsoluteOrientation.Dx = aPlaneN.X();\r
-        aClipPlane.AbsoluteOrientation.Dy = aPlaneN.Y();\r
-        aClipPlane.AbsoluteOrientation.Dz = aPlaneN.Z();\r
-      }\r
-    }\r
-    else\r
-    {\r
-      OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(),\r
-                                           aClipPlane.OrientationType,\r
-                                           aClipPlane.RelativeOrientation.Rotation1,\r
-                                           aClipPlane.RelativeOrientation.Rotation2 );\r
-    }\r
-\r
-    myIsUpdatingControls = true;\r
-    updateControls();\r
-    myIsUpdatingControls = false;\r
-\r
-    if ( AutoApplyCheckBox->isChecked() )\r
-    {\r
-      onApply();\r
-    }\r
-\r
-    break;\r
-  }\r
-}\r
-\r
-OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )\r
-{\r
-  return myLocalPlanes[theIdx];\r
-}\r
-\r
-int OCCViewer_ClippingDlg::clipPlanesCount()\r
-{\r
-  return myLocalPlanes.size();\r
-}\r
-\r
+// Copyright (C) 2007-2023  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
+//
+// 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, 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#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 <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 <math.h>
+
+// QT Includes
+#include <QApplication>
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QLabel>
+#include <QPushButton>
+#include <QComboBox>
+#include <QCheckBox>
+#include <QStackedLayout>
+#include <QSlider>
+#include <QMenu>
+
+/**********************************************************************************
+ ************************        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( const double theBounds[6],
+                         const double theDirection[3],
+                         double theMinPnt[3],
+                         double& theMaxBoundPrj,
+                         double& theMinBoundPrj )
+{
+  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;
+    aEnlargeBounds[i  ] = theBounds[i  ] - aDelta;
+    aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;
+  }
+
+  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]
+                   + theDirection[2] * aBoundPoints[aMaxId][2];
+  theMinBoundPrj = theMaxBoundPrj;
+  for(int i = 1; i < 8; i++) {
+    double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
+                  + theDirection[2] * aBoundPoints[i][2];
+    if(theMaxBoundPrj < aTmp) {
+      theMaxBoundPrj = aTmp;
+      aMaxId = i;
+    }
+    if(theMinBoundPrj > aTmp) {
+      theMinBoundPrj = aTmp;
+    }
+  }
+  double *aMinPnt = aBoundPoints[aMaxId];
+  theMinPnt[0] = aMinPnt[0];
+  theMinPnt[1] = aMinPnt[1];
+  theMinPnt[2] = aMinPnt[2];
+}
+
+/*!
+  Compute the position of current plane by distance
+ */
+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;
+}
+
+/*!
+  Compute the parameters of clipping plane
+ */
+bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,
+                                     const double theDefaultSize,
+                                     const double theNormal[3],
+                                     const double theDist,
+                                     double theOrigin[3] )
+{
+  double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+
+  getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );
+
+  DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
+  return true;
+}
+
+/*!
+  \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.
+ */
+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 )
+{
+  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;
+}
+
+/*!
+  \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 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 )
+{
+  gp_Pnt aPlaneP( theX, theY, theZ );
+  gp_Dir aPlaneN( theDX, theDY, theDZ );
+
+  double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+
+  getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+  Bnd_Box aMinMax;
+  aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+
+  gp_Trsf aRelativeTransform;
+  aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );
+  Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );
+
+  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      *********************
+ *********************************************************************************/
+/*!
+  Constructor
+  \param view - view window
+  \param parent - parent widget
+*/
+OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
+  : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )
+{
+  setObjectName( "OCCViewer_ClippingDlg" );
+  setModal( false );
+
+  setWindowTitle( tr( "Clipping" ) );
+
+  setAttribute (Qt::WA_DeleteOnClose, true);
+  
+  QVBoxLayout* topLayout = new QVBoxLayout( this );
+  topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
+
+  /***************************************************************/
+  // Controls for selecting, creating, deleting planes
+  QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
+  QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
+  ComboBoxPlanes = new QComboBox( GroupPlanes );
+  isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
+  buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
+  buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
+  buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
+  MenuMode = new QMenu( "MenuMode", buttonNew );
+  MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
+  MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
+  buttonNew->setMenu( MenuMode );
+
+  GroupPlanesLayout->addWidget( ComboBoxPlanes );
+  GroupPlanesLayout->addWidget( isActivePlane );
+  GroupPlanesLayout->addWidget( buttonNew );
+  GroupPlanesLayout->addWidget( buttonDelete );
+  GroupPlanesLayout->addWidget( buttonDisableAll );
+
+  ModeStackedLayout = new QStackedLayout();
+
+  /**********************   Mode Absolute   **********************/
+  /* Controls for absolute mode of clipping plane:
+     X, Y, Z - coordinates of the intersection of cutting plane and the three axes
+     Dx, Dy, Dz - components of normal to the cutting plane
+     Orientation - direction of cutting plane
+   */
+  const double min = -1e+7;
+  const double max =  1e+7;
+  const double step = 5;
+  const int precision = -7;
+
+  // Croup Point
+  QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
+  GroupAbsolutePoint->setObjectName( "GroupPoint" );
+  GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
+  QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
+  GroupPointLayout->setAlignment( Qt::AlignTop );
+  GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
+
+  TextLabelX = new QLabel( GroupAbsolutePoint );
+  TextLabelX->setObjectName( "TextLabelX" );
+  TextLabelX->setText( tr("X:") );
+  GroupPointLayout->addWidget( TextLabelX, 0, 0 );
+  
+  SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
+  SpinBox_X->setObjectName("SpinBox_X" );
+  SpinBox_X->setPrecision( precision );
+  GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
+
+  TextLabelY = new QLabel( GroupAbsolutePoint );
+  TextLabelY->setObjectName( "TextLabelY" );
+  TextLabelY->setText( tr("Y:") );
+  GroupPointLayout->addWidget( TextLabelY, 0, 2 );
+
+  SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
+  SpinBox_Y->setObjectName("SpinBox_Y" );
+  SpinBox_Y->setPrecision( precision );
+  GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
+
+  TextLabelZ = new QLabel( GroupAbsolutePoint );
+  TextLabelZ->setObjectName( "TextLabelZ" );
+  TextLabelZ->setText( tr("Z:") );
+  GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
+
+  SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
+  SpinBox_Z->setObjectName("SpinBox_Z" );
+  SpinBox_Z->setPrecision( precision );
+  GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
+
+  resetButton  = new QPushButton( GroupAbsolutePoint );
+  resetButton->setObjectName( "resetButton" );
+  resetButton->setText( tr( "RESET"  ) );
+  GroupPointLayout->addWidget( resetButton, 0, 6 );
+
+  // Group Direction
+  GroupAbsoluteDirection = new QGroupBox( this );
+  GroupAbsoluteDirection->setObjectName( "GroupDirection" );
+  GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
+  QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
+  GroupDirectionLayout->setAlignment( Qt::AlignTop );
+  GroupDirectionLayout->setSpacing( 6 );
+  GroupDirectionLayout->setMargin( 11 );
+  
+  TextLabelDx = new QLabel( GroupAbsoluteDirection );
+  TextLabelDx->setObjectName( "TextLabelDx" );
+  TextLabelDx->setText( tr("Dx:") );
+  GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
+  
+  SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
+  SpinBox_Dx->setObjectName("SpinBox_Dx" );
+  SpinBox_Dx->setPrecision( precision );
+  GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
+
+  TextLabelDy = new QLabel( GroupAbsoluteDirection );
+  TextLabelDy->setObjectName( "TextLabelDy" );
+  TextLabelDy->setText( tr("Dy:") );
+  GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
+  
+  SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
+  SpinBox_Dy->setObjectName("SpinBox_Dy" );
+  SpinBox_Dy->setPrecision( precision );
+  GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
+
+  TextLabelDz = new QLabel( GroupAbsoluteDirection );
+  TextLabelDz->setObjectName( "TextLabelDz" );
+  TextLabelDz->setText( tr("Dz:") );
+  GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
+  
+  SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
+  SpinBox_Dz->setObjectName("SpinBox_Dz" );
+  SpinBox_Dz->setPrecision( precision );
+  GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
+
+  invertButton  = new QPushButton( GroupAbsoluteDirection );
+  invertButton->setObjectName( "invertButton" );
+  invertButton->setText( tr( "INVERT"  ) );
+  GroupDirectionLayout->addWidget( invertButton, 0, 6 );
+  CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
+  CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
+  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
+  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
+  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
+  CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
+  GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
+
+  QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
+  ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
+  ModeActiveLayout->addWidget( GroupAbsolutePoint );
+  ModeActiveLayout->addWidget( GroupAbsoluteDirection );
+
+  QWidget* ModeActiveWidget = new QWidget( this );
+  ModeActiveWidget->setLayout( ModeActiveLayout );
+
+  /**********************   Mode Relative   **********************/
+  /* Controls for relative mode of clipping plane:
+     Distance - Value from 0 to 1.
+     Specifies the distance from the minimum value in a given direction of bounding box to the current position
+     Rotation1, Rotation2 - turn angles of cutting plane in given directions
+     Orientation - direction of cutting plane
+   */
+  QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
+  QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
+  GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
+
+  TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
+  TextLabelOrientation->setObjectName( "TextLabelOrientation" );
+  GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
+
+  CBRelativeOrientation = new QComboBox(GroupParameters);
+  CBRelativeOrientation->setObjectName( "RelativeOrientation" );
+  CBRelativeOrientation->addItem( tr("ALONG_XY") );
+  CBRelativeOrientation->addItem( tr("ALONG_YZ") );
+  CBRelativeOrientation->addItem( tr("ALONG_ZX") );
+  GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
+
+  TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
+  TextLabelDistance->setObjectName( "TextLabelDistance" );
+  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, 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, 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 );
+  QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
+  
+  PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
+  PreviewCheckBox->setObjectName( "PreviewCheckBox" );
+  PreviewCheckBox->setChecked( true );
+  CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
+  
+  AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
+  AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
+  CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
+
+  /***************************************************************/
+  QGroupBox* GroupButtons = new QGroupBox( this );
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
+  GroupButtonsLayout->setAlignment( Qt::AlignTop );
+  GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
+  
+  buttonOk = new QPushButton( GroupButtons );
+  buttonOk->setObjectName( "buttonOk" );
+  buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE"  ) );
+  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 );
+  GroupButtonsLayout->addWidget( buttonApply );
+
+  GroupButtonsLayout->addStretch();
+  
+  buttonClose = new QPushButton( GroupButtons );
+  buttonClose->setObjectName( "buttonClose" );
+  buttonClose->setText( tr( "BUT_CLOSE"  ) );
+  buttonClose->setAutoDefault( true );
+  GroupButtonsLayout->addWidget( buttonClose );
+
+  QPushButton* buttonHelp = new QPushButton( tr( "HELP" ), GroupButtons );
+  buttonHelp->setAutoDefault( true );
+  GroupButtonsLayout->addWidget( buttonHelp );
+
+  /***************************************************************/
+  ModeStackedLayout->addWidget( ModeActiveWidget );
+  ModeStackedLayout->addWidget( GroupParameters );
+
+  topLayout->addWidget( GroupPlanes );
+  topLayout->addLayout( ModeStackedLayout );
+  topLayout->addWidget( CheckBoxWidget );
+  topLayout->addWidget( GroupButtons );
+
+  this->setLayout( topLayout );
+
+  // Initializations
+  initParam();
+
+  // Signals and slots connections
+  connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
+  connect( isActivePlane,  SIGNAL ( toggled ( bool ) ),  this, SLOT( onValueChanged() ) );
+  connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
+  connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
+  connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
+
+  connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );
+  connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
+  connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
+  connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
+
+  connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( 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 ) ) );
+  
+  connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
+  connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
+  connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
+  connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
+
+  myBusy = false;
+  myIsSelectPlane = false;
+  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();
+}
+
+/*!
+  Destructor
+  Destroys the object and frees any allocated resources
+*/
+OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
+{
+  myLocalPlanes.clear();
+}
+
+/*!
+  Custom handling of close event: erases preview
+*/
+void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
+{
+  erasePreview();
+  QDialog::closeEvent( e );
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
+}
+
+/*!
+  Custom handling of show event: displays preview
+*/
+void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
+{
+  QDialog::showEvent( e );
+  onPreview( PreviewCheckBox->isChecked() );
+}
+
+/*!
+  Custom handling of hide event: erases preview
+*/
+void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
+{
+  erasePreview();
+  QDialog::hideEvent( e );
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
+
+}
+
+/*!
+  Initialization of initial values of widgets
+*/
+void OCCViewer_ClippingDlg::initParam()
+{
+  SpinBox_X->setValue( 0.0 );
+  SpinBox_Y->setValue( 0.0 );
+  SpinBox_Z->setValue( 0.0 );
+
+  SpinBox_Dx->setValue( 1.0 );
+  SpinBox_Dy->setValue( 1.0 );
+  SpinBox_Dz->setValue( 1.0 );
+
+  CBAbsoluteOrientation->setCurrentIndex(0);
+
+  SpinSliderDistance->setValue( 0.5 );
+  SpinSliderRotation1->setValue( 0 );
+  SpinSliderRotation2->setValue( 0 );
+  CBRelativeOrientation->setCurrentIndex( 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();
+}
+
+/*!
+  Synchronize dialog's widgets with data
+*/
+void OCCViewer_ClippingDlg::synchronize()
+{
+  ComboBoxPlanes->clear();
+  int aNbPlanesAbsolute = (int)myLocalPlanes.size();
+
+  QString aName;
+  for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
+    aName = QString("Plane %1").arg(i);
+    ComboBoxPlanes->addItem( aName );
+  }
+
+  int aPos = ComboBoxPlanes->count() - 1;
+  ComboBoxPlanes->setCurrentIndex( aPos );
+
+  bool anIsControlsEnable = ( aPos >= 0 );
+  if ( anIsControlsEnable ) {
+    onSelectPlane( aPos );
+  }
+  else {
+    ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
+    initParam();
+  }
+  if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )
+  {
+    SpinBox_X->setEnabled( anIsControlsEnable );
+    SpinBox_Y->setEnabled( anIsControlsEnable );
+    SpinBox_Z->setEnabled( anIsControlsEnable );
+    SpinBox_Dx->setEnabled( anIsControlsEnable );
+    SpinBox_Dy->setEnabled( anIsControlsEnable );
+    SpinBox_Dz->setEnabled( anIsControlsEnable );
+    CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
+    invertButton->setEnabled( anIsControlsEnable );
+    resetButton->setEnabled( anIsControlsEnable );
+  }
+  else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )
+  {
+    CBRelativeOrientation->setEnabled( anIsControlsEnable );
+    SpinSliderDistance->setEnabled( anIsControlsEnable );
+    SpinSliderRotation1->setEnabled( anIsControlsEnable );
+    SpinSliderRotation2->setEnabled( anIsControlsEnable );
+    isActivePlane->setEnabled( anIsControlsEnable );
+  }
+  isActivePlane->setEnabled( anIsControlsEnable );
+}
+
+/*!
+  Displays preview of clipping plane
+*/
+void OCCViewer_ClippingDlg::displayPreview()
+{
+  if ( myBusy || !isValid() || !myModel)
+    return;
+
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+  
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+
+  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 );
+}
+
+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((int)myPreviewPlaneVector.size() < clipPlanesCount()) { //TODO: mismatch signed/unsigned
+      myPreviewPlaneVector.resize(clipPlanesCount());
+    }
+    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 );
+      myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
+    } else {      
+      myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
+      myPreviewPlane->SetCenter( aBasePnt );
+      myPreviewPlane->SetSize( aSize, aSize ); 
+    }
+
+    ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
+    ic->Update( myPreviewPlane, Standard_False );
+  } else {
+    if((int)myPreviewPlaneVector.size() > aCurPlaneIndex ) {
+      myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
+      if(ic->IsDisplayed(myPreviewPlane)) {
+       ic->Erase( myPreviewPlane, false );
+       ic->Remove( myPreviewPlane, false );
+      }
+      myPreviewPlaneVector[aCurPlaneIndex].Nullify();
+    }
+  }
+  for(int i = 0; i < (int)myPreviewPlaneVector.size(); i++) {//TODO: mismatch signed/unsigned
+    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 );
+}
+
+/*!
+  Erases preview of clipping plane
+*/
+void OCCViewer_ClippingDlg::erasePreview()
+{
+  if ( !myModel )
+    return;
+
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+
+  for ( int i=0; i < (int)myPreviewPlaneVector.size(); i++ ) {//TODO: mismatch signed/unsigned
+  Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
+    if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
+      ic->Erase( myPreviewPlane, false );
+      ic->Remove( myPreviewPlane, false );
+      myPreviewPlane.Nullify();
+    }
+  }
+  myPreviewPlaneVector.clear();
+  myModel->update();
+  myInteractor->setEnabled( false );
+}
+
+/*!
+  Return true if plane parameters are valid
+*/
+bool OCCViewer_ClippingDlg::isValid()
+{
+  return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
+}
+
+/*!
+  Update view after changes
+*/
+void OCCViewer_ClippingDlg::updateClipping()
+{
+  if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
+  {
+    if (AutoApplyCheckBox->isChecked()) {
+      onApply();
+    }
+    
+    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()
+{
+  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();
+}
+
+/*!
+  SLOT on delete button click: Delete selected clipping plane
+*/
+void OCCViewer_ClippingDlg::ClickOnDelete()
+{
+  int aPlaneIndex = ComboBoxPlanes->currentIndex();
+  if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
+    return;
+
+  myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
+
+  Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+
+  if(aPlaneIndex+1 <= (int)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();
+}
+
+/*!
+  SLOT on disable all button click: Restore initial state of viewer,
+  erase all clipping planes
+*/
+void OCCViewer_ClippingDlg::ClickOnDisableAll()
+{
+  AutoApplyCheckBox->setChecked (false);
+  int aClipPlanesCount = clipPlanesCount();
+  for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
+  {
+    OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
+    aPlane.IsOn = false;
+  }
+  erasePreview();
+  isActivePlane->setChecked(false);
+  myModel->setClipPlanes(myLocalPlanes);
+  myModel->update();
+}
+
+/*!
+  SLOT on ok button click: sets cutting plane and closes dialog
+*/
+void OCCViewer_ClippingDlg::ClickOnOk()
+{
+  onApply();
+  ClickOnClose();
+}
+
+/*!
+  SLOT on Apply button click: sets cutting plane and update viewer
+*/
+void OCCViewer_ClippingDlg::ClickOnApply()
+{
+  onApply();
+  myModel->update();
+}
+
+/*!
+  SLOT on close button click: erases preview and rejects dialog
+*/
+void OCCViewer_ClippingDlg::ClickOnClose()
+{
+  erasePreview();
+  OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
+  if(v)
+    v->onClipping(false);
+}
+
+/*!
+  SLOT on help button click: opens a help page
+*/
+void OCCViewer_ClippingDlg::ClickOnHelp()
+{
+  SUIT_Application* app = SUIT_Session::session()->activeApplication();
+  if ( app )
+    app->onHelpContextModule( "GUI", "occ_3d_viewer.html", "clipping-planes" );
+}
+
+/*!
+  Set absolute mode of clipping plane
+*/
+void OCCViewer_ClippingDlg::onModeAbsolute()
+{
+  myIsPlaneCreation = true;
+  ModeStackedLayout->setCurrentIndex(0);
+  ClickOnNew();
+  myIsPlaneCreation = false;
+  updateClipping();
+}
+
+/*!
+  Set relative mode of clipping plane
+*/
+void OCCViewer_ClippingDlg::onModeRelative()
+{
+  myIsPlaneCreation = true;
+  ModeStackedLayout->setCurrentIndex(1);
+  ClickOnNew();
+  myIsPlaneCreation = false;
+  SetCurrentPlaneParam();
+  updateClipping();
+}
+
+/*!
+  SLOT: called on value of clipping plane changed
+*/
+void OCCViewer_ClippingDlg::onValueChanged()
+{
+  if ( myIsUpdatingControls )
+  {
+    return;
+  }
+
+  SetCurrentPlaneParam();
+
+  if ( myIsSelectPlane )
+  {
+    return;
+  }
+
+  updateClipping();
+}
+
+/*!
+  Set current parameters of selected plane
+*/
+void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
+{
+  if ( clipPlanesCount() == 0 )
+  {
+    return;
+  }
+
+  //OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex ); // unused
+
+  myIsSelectPlane = true;
+  updateControls();
+  ComboBoxPlanes->setCurrentIndex( theIndex );
+  myIsSelectPlane = false;
+}
+
+/*!
+  Restore parameters of selected plane
+*/
+void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
+{
+  if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )
+  {
+    return;
+  }
+
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+
+  OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
+
+  setPlaneParam( aPlane );
+}
+
+/*!
+  SLOT on reset button click: sets default values
+*/
+void OCCViewer_ClippingDlg::onReset()
+{
+  myBusy = true;
+  SpinBox_X->setValue(0);
+  SpinBox_Y->setValue(0);
+  SpinBox_Z->setValue(0);
+  myBusy = false;
+
+  SetCurrentPlaneParam();
+  updateClipping();
+}
+
+/*!
+  SLOT on invert button click: inverts normal of cutting plane
+*/
+void OCCViewer_ClippingDlg::onInvert()
+{
+  double Dx = SpinBox_Dx->value();
+  double Dy = SpinBox_Dy->value();
+  double Dz = SpinBox_Dz->value();
+
+  myBusy = true;
+  SpinBox_Dx->setValue( -Dx );
+  SpinBox_Dy->setValue( -Dy );
+  SpinBox_Dz->setValue( -Dz );
+  myBusy = false;
+
+  if ( clipPlanesCount() != 0 )
+  {
+    int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+    OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
+    aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;
+  }
+  updateClipping();
+}
+
+/*!
+  SLOT: called on orientation of clipping plane in absolute mode changed
+*/
+void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
+{
+  bool isUserMode = (mode==0);
+
+  TextLabelX->setEnabled( isUserMode );
+  TextLabelY->setEnabled( isUserMode );
+  TextLabelZ->setEnabled( isUserMode );
+
+  SpinBox_X->setEnabled( isUserMode );
+  SpinBox_Y->setEnabled( isUserMode );
+  SpinBox_Z->setEnabled( isUserMode );
+
+  TextLabelDx->setEnabled( isUserMode );
+  TextLabelDy->setEnabled( isUserMode );
+  TextLabelDz->setEnabled( isUserMode );
+
+  SpinBox_Dx->setEnabled( isUserMode );
+  SpinBox_Dy->setEnabled( isUserMode );
+  SpinBox_Dz->setEnabled( isUserMode );
+
+  int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
+  OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
+  double aDx = 0, aDy = 0, aDz = 0;
+
+  if ( mode == 0 )
+  {
+    aDx = aPlane.AbsoluteOrientation.Dx;
+    aDy = aPlane.AbsoluteOrientation.Dy;
+    aDz = aPlane.AbsoluteOrientation.Dz;
+  }
+  else if ( mode == 1 )
+  {
+    aDz = 1;
+    TextLabelZ->setEnabled( true );
+    SpinBox_Z->setEnabled( true );
+    SpinBox_Z->setFocus();
+  }
+  else if ( mode == 2 )
+  {
+    aDx = 1;
+    TextLabelX->setEnabled( true );
+    SpinBox_X->setEnabled( true );
+    SpinBox_X->setFocus();
+  }
+  else if ( mode == 3 )
+  {
+    aDy = 1;
+    TextLabelY->setEnabled( true );
+    SpinBox_Y->setEnabled( true );
+    SpinBox_Y->setFocus();
+  }
+    
+  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;
+
+  if ( !myIsUpdatingControls )
+  {
+    SetCurrentPlaneParam();
+    updateClipping();
+  }
+}
+
+/*!
+  SLOT: called on orientation of clipping plane in relative mode changed
+*/
+void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
+{
+  if ( clipPlanesCount() == 0 )
+    return;
+  
+  if ( theItem == 0 ) {
+    TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
+    TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
+  }
+  else if ( theItem == 1 ) {
+    TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
+    TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
+  }
+  else if ( theItem == 2 ) {
+    TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
+    TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
+  }
+
+  if ( !myIsUpdatingControls )
+  {
+    if( (QComboBox*)sender() == CBRelativeOrientation )
+    {
+      SetCurrentPlaneParam();
+    }
+
+    updateClipping();
+  }
+}
+
+/*!
+  SLOT: called on preview check box toggled
+*/
+void OCCViewer_ClippingDlg::onPreview( bool on )
+{
+  erasePreview();
+  if ( on ) 
+    displayPreview();
+}
+
+/*!
+  SLOT: called on Auto Apply check box toggled
+*/
+void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
+{
+  if ( toggled ) {
+    onApply();
+    myModel->update();
+  }  
+}
+
+/*!
+  SLOT on Apply button click: sets cutting plane
+*/
+void OCCViewer_ClippingDlg::onApply()
+{
+  if ( myBusy )
+    return;
+  myIsSelectPlane = true;
+
+  qApp->processEvents();
+  QApplication::setOverrideCursor( Qt::WaitCursor );
+  qApp->processEvents();
+
+  myModel->setClipPlanes(myLocalPlanes);
+
+  QApplication::restoreOverrideCursor();
+  myIsSelectPlane = false;
+}
+
+/*!
+  SLOT: Called when clip plane is clicked in viewer.
+*/
+void OCCViewer_ClippingDlg::onPlaneClicked( const Handle_AIS_Plane& thePlane )
+{
+  for ( int aPlaneIt = 0; aPlaneIt < (int)myPreviewPlaneVector.size(); aPlaneIt++ )
+  {
+    Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
+    if ( aPlane != thePlane )
+    {
+      continue;
+    }
+
+    ComboBoxPlanes->setCurrentIndex( aPlaneIt );
+
+    break;
+  }
+}
+
+/*!
+  SLOT: Called when clip plane is changed by dragging in viewer.
+*/
+void OCCViewer_ClippingDlg::onPlaneDragged( const Handle_AIS_Plane& thePlane )
+{
+  for ( int aPlaneIt = 0; aPlaneIt < (int)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;
+  }
+}
+
+OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
+{
+  return myLocalPlanes[theIdx];
+}
+
+int OCCViewer_ClippingDlg::clipPlanesCount()
+{
+  return myLocalPlanes.size();
+}
+
 OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const
 {
   return ModeStackedLayout->currentIndex() == 0