Salome HOME
0052660: Plot2D Viewer: Plot2d_Curve can't be selected
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
index 2b2d6d866b4f9d28e58667cb31635c2739676dad..98ae2107b3d762f9126aefb8a6cfdf96aaf6061a 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include "OCCViewer_ViewManager.h"
 #include "OCCViewer_ViewSketcher.h"
 #include "OCCViewer_CreateRestoreViewDlg.h"
-#include "OCCViewer_ClippingDlg.h"
+#include "OCCViewer_ClipPlane.h"
 #include "OCCViewer_SetRotationPointDlg.h"
 #include "OCCViewer_AxialScaleDlg.h"
 #include "OCCViewer_CubeAxesDlg.h"
+#include "OCCViewer_ClippingDlg.h"
 
 #include <Basics_OCCTVersion.hxx>
 
@@ -64,6 +65,8 @@
 
 #include <BRep_Tool.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
 #include <TopoDS.hxx>
 
 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
 
 #include <gp_Dir.hxx>
 #include <gp_Pln.hxx>
+#include <gp_GTrsf.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
 
+#include <Graphic3d_SequenceOfHClipPlane.hxx>
+#include <Graphic3d_ClipPlane.hxx>
+
+#include <Image_PixMap.hxx>
+
 #include <Standard_Version.hxx>
 
 #include "utilities.h"
@@ -224,18 +233,21 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop*     theDesktop,
   myEnableDrawMode = false;
   myDrawRect=false;
   updateEnabledDrawMode();
-  myClippingDlg = 0;
   myScalingDlg = 0;
   mySetRotationPointDlg = 0;
   myRectBand = 0;
   
   IsSketcherStyle = false;
+  myIsKeyFree = false;
 
   mypSketcher = 0;
   myCurSketch = -1;
   my2dMode = No2dMode;
 
   myInteractionStyle = SUIT_ViewModel::STANDARD;
+  myPreselectionEnabled = true;
+  mySelectionEnabled = true;
+
 
   clearViewAspects();
   
@@ -351,13 +363,26 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
     case QEvent::Wheel:
       {
         QWheelEvent* aEvent = (QWheelEvent*) e;
-       myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
-       double delta = (double)( aEvent->delta() ) / ( 15 * 8 );
-       int x  = aEvent->x();
-       int y  = aEvent->y();
-       int x1 = (int)( aEvent->x() + width()*delta/100 );
-       int y1 = (int)( aEvent->y() + height()*delta/100 );
-       myViewPort->zoom( x, y, x1, y1 );
+     
+        if ( aEvent->modifiers().testFlag(Qt::ControlModifier) ) {
+          Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
+          if ( isPreselectionEnabled() && ic->HasOpenedContext() ) {
+            if ( aEvent->delta() > 0 ) {
+              ic->HilightNextDetected( myViewPort->getView() );
+            } else {
+              ic->HilightPreviousDetected( myViewPort->getView() );
+            }
+          }
+        } else {
+          myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
+          double delta = (double)( aEvent->delta() ) / ( 15 * 8 );
+          int x  = aEvent->x();
+          int y  = aEvent->y();
+          int x1 = (int)( aEvent->x() + width()*delta/100 );
+          int y1 = (int)( aEvent->y() + height()*delta/100 );
+          myViewPort->zoom( x, y, x1, y1 );
+          myViewPort->getView()->ZFitAll();
+        }
       }
       return true;
 
@@ -448,17 +473,24 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent )
 
   default:
   /*  Try to activate a transformation */
-    switch ( getButtonState(theEvent, anInteractionStyle) ) {
+    OperationType aState;
+    if ( interactionStyle() == SUIT_ViewModel::STANDARD )
+      aState = getButtonState(theEvent, anInteractionStyle);
+    else {
+      aState = OCCViewer_ViewWindow::NOTHING;
+      myIsKeyFree = true;
+    }
+    switch ( aState ) {
     case ZOOMVIEW:
       myViewPort->startZoomAtPoint( myStartX, myStartY );
       activateZoom();
       break;
     case PANVIEW:
-            activatePanning();
+      activatePanning();
       break;
     case ROTATE:
-            activateRotation();
-            myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
+      activateRotation();
+      myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
       break;
     default:
       if ( myRotationPointSelection )
@@ -470,20 +502,38 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent )
           for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
           {
             TopoDS_Shape aShape = ic->SelectedShape();
+            GProp_GProps aSystem;
+            gp_Pnt aPnt;
             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
             {
-              gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
-              if ( mySetRotationPointDlg )
-              {
-                myRotationPointSelection = false;
-                mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
-              }
+              aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
+            }
+            else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE )
+            {
+              BRepGProp::LinearProperties( aShape, aSystem );
+              aPnt = aSystem.CentreOfMass();
+            }
+            else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_FACE )
+            {
+              BRepGProp::SurfaceProperties( aShape, aSystem );
+              aPnt = aSystem.CentreOfMass();
+            }
+            else if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_SOLID )
+            {
+              BRepGProp::VolumeProperties( aShape, aSystem );
+              aPnt = aSystem.CentreOfMass();
             }
             else
             {
               myCurrPointType = myPrevPointType;
               break;
             }
+
+            if ( mySetRotationPointDlg )
+            {
+              myRotationPointSelection = false;
+              mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
+            }
           }
           if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType;
           if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
@@ -575,65 +625,102 @@ void OCCViewer_ViewWindow::activateRotation()
 */
 bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ )
 {
-  Handle(Visual3d_View) aView = myViewPort->getView()->View();
+  Handle(V3d_View) aView3d = myViewPort->getView();
 
-  Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ;
-  Standard_Real Umin,Vmin,Umax,Vmax ;
-  Standard_Integer Nstruct,Npoint ;
-  Graphic3d_MapOfStructure MySetOfStructures;
+  // Project boundaries points and add to avergae gravity
+  // the ones which lie within the screen limits
+  Standard_Real aScreenLimits[4] = { 0.0, 0.0, 0.0, 0.0 };
 
-  aView->DisplayedStructures (MySetOfStructures);
-  Nstruct = MySetOfStructures.Extent() ;
+#if OCC_VERSION_LARGE > 0x06070100
+  // NDC space screen limits
+  aScreenLimits[0] = -1.0;
+  aScreenLimits[1] =  1.0;
+  aScreenLimits[2] = -1.0;
+  aScreenLimits[3] =  1.0;
+#else
+  aView3d->View()->ViewMapping().WindowLimit( aScreenLimits[0],
+                                              aScreenLimits[1],
+                                              aScreenLimits[2],
+                                              aScreenLimits[3] );
+#endif
 
-  Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
-  aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ;
-  Npoint = 0 ; theX = theY = theZ = 0. ;
-  for( ; MyIterator.More(); MyIterator.Next()) {
-    if (!(MyIterator.Key())->IsEmpty()) {
-      (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin,
-                                         Xmax,Ymax,Zmax) ;
+  Standard_Integer aPointsNb = 0;
 
-      Standard_Real LIM = ShortRealLast() -1.;
-      if (!    (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM
-                ||  fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) {
+  Standard_Real aXmin = 0.0;
+  Standard_Real aYmin = 0.0;
+  Standard_Real aZmin = 0.0;
+  Standard_Real aXmax = 0.0;
+  Standard_Real aYmax = 0.0;
+  Standard_Real aZmax = 0.0;
 
-        aView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ;
-        }
-        aView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ;
-        }
-        aView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ;
-        }
-        aView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ;
-        }
-        aView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ;
-        }
-        aView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ;
-        }
-        aView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ;
-        }
-        aView->Projects(Xmax,Ymax,Zmax,U,V,W) ;
-        if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
-          Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ;
-        }
+  Graphic3d_MapOfStructure aSetOfStructures;
+  aView3d->View()->DisplayedStructures( aSetOfStructures );
+  Graphic3d_MapIteratorOfMapOfStructure aStructureIt( aSetOfStructures );
+
+  for( ; aStructureIt.More(); aStructureIt.Next() ) {
+    const Handle(Graphic3d_Structure)& aStructure = aStructureIt.Key();
+    if ( aStructure->IsEmpty() ) {
+      continue;
+    }
+
+#if OCC_VERSION_LARGE > 0x06070100
+    Bnd_Box aBox = aStructure->MinMaxValues();
+    aXmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X();
+    aYmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y();
+    aZmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z();
+    aXmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().X();
+    aYmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Y();
+    aZmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Z();
+#else
+    aStructure->MinMaxValues( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
+#endif
+
+    // Infinite structures are skipped
+    Standard_Real aLIM = ShortRealLast() - 1.0;
+    if ( Abs( aXmin ) > aLIM || Abs( aYmin ) > aLIM || Abs( aZmin ) > aLIM
+      || Abs( aXmax ) > aLIM || Abs( aYmax ) > aLIM || Abs( aZmax ) > aLIM ) {
+      continue;
+    }
+
+    gp_Pnt aPoints[8] = {
+      gp_Pnt( aXmin, aYmin, aZmin ), gp_Pnt( aXmin, aYmin, aZmax ),
+      gp_Pnt( aXmin, aYmax, aZmin ), gp_Pnt( aXmin, aYmax, aZmax ),
+      gp_Pnt( aXmax, aYmin, aZmin ), gp_Pnt( aXmax, aYmin, aZmax ),
+      gp_Pnt( aXmax, aYmax, aZmin ), gp_Pnt( aXmax, aYmax, aZmax )
+    };
+
+    for ( Standard_Integer aPointIt = 0; aPointIt < 8; ++aPointIt ) {
+      const gp_Pnt& aBBPoint = aPoints[aPointIt];
+
+#if OCC_VERSION_LARGE > 0x06070100
+      gp_Pnt aProjected = aView3d->Camera()->Project( aBBPoint );
+      const Standard_Real& U = aProjected.X();
+      const Standard_Real& V = aProjected.Y();
+#else
+      Standard_Real U = 0.0;
+      Standard_Real V = 0.0;
+      Standard_Real W = 0.0;
+      aView3d->View()->Projects( aBBPoint.X(), aBBPoint.Y(), aBBPoint.Z(), U, V, W );
+#endif
+
+      if (U >= aScreenLimits[0]
+       && U <= aScreenLimits[1]
+       && V >= aScreenLimits[2]
+       && V <= aScreenLimits[3])
+      {
+        aPointsNb++;
+        theX += aBBPoint.X();
+        theY += aBBPoint.Y();
+        theZ += aBBPoint.Z();
       }
     }
   }
-  if( Npoint > 0 ) {
-    theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ;
+
+  if ( aPointsNb > 0 )
+  {
+    theX /= aPointsNb;
+    theY /= aPointsNb;
+    theZ /= aPointsNb;
   }
   return true;
 }
@@ -699,9 +786,9 @@ void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY
 }
 
 /*!
-  \brief Start the point selection process.
+  \brief Start the shape selection process.
 */
-void OCCViewer_ViewWindow::activateStartPointSelection()
+void OCCViewer_ViewWindow::activateStartPointSelection( TopAbs_ShapeEnum theShapeType )
 {
   myPrevPointType = myCurrPointType;
   myCurrPointType = SELECTED;
@@ -720,7 +807,7 @@ void OCCViewer_ViewWindow::activateStartPointSelection()
          anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) )
     {
       ic->Load(anObj,-1);
-      ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX));
+      ic->Activate(anObj,AIS_Shape::SelectionMode(theShapeType));
      }
   }
   // activate selection <------
@@ -792,6 +879,25 @@ bool OCCViewer_ViewWindow::setTransformRequested( OperationType op )
 */
 void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent )
 {
+  if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) {
+    myIsKeyFree = false;
+    switch ( getButtonState( theEvent, interactionStyle() ) ) {
+    case ZOOMVIEW:
+      myViewPort->startZoomAtPoint( myStartX, myStartY );
+      activateZoom();
+      break;
+    case PANVIEW:
+      activatePanning();
+      break;
+    case ROTATE:
+      activateRotation();
+      myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
+      break;
+    default:
+      break;
+    }
+  }
+
   myCurrX = theEvent->x();
   myCurrY = theEvent->y();
   switch (myOperation) {
@@ -829,8 +935,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent )
       int aState = theEvent->modifiers();
       int aButton = theEvent->buttons();
       int anInteractionStyle = interactionStyle();
-      if ( anInteractionStyle == SUIT_ViewModel::STANDARD && 
-           aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) {
+      if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD &&
+           aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
+         ( anInteractionStyle == SUIT_ViewModel::KEY_FREE &&
+         aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
         myDrawRect = myEnableDrawMode;
         if ( myDrawRect ) {
           drawRect();
@@ -843,8 +951,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent )
         }
         emit mouseMoving( this, theEvent );
       }
-      else if ( anInteractionStyle == SUIT_ViewModel::STANDARD && 
-                aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) {
+      else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD &&
+                aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) ||
+                ( anInteractionStyle == SUIT_ViewModel::KEY_FREE &&
+                aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) {
         OCCViewer_ViewSketcher* sketcher = 0;
         QList<OCCViewer_ViewSketcher*>::Iterator it;
         for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
@@ -913,6 +1023,7 @@ void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
 
   case PANVIEW:
   case ZOOMVIEW:
+    myViewPort->getView()->ZFitAll();
     resetState();
     break;
 
@@ -1171,12 +1282,12 @@ void OCCViewer_ViewWindow::createActions()
   connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView()));
   toolMgr()->registerAction( aAction, CloneId );
 
-  myClippingAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ),
-                           tr( "MNU_CLIPPING" ), 0, this);
-  myClippingAction->setStatusTip(tr("DSC_CLIPPING"));
-  myClippingAction->setCheckable( true );
-  connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool )));
-  toolMgr()->registerAction( myClippingAction, ClippingId );
+  aAction = new QtxAction (tr("MNU_CLIPPING"), aResMgr->loadPixmap ("OCCViewer", tr("ICON_OCCVIEWER_CLIPPING")),
+                                      tr("MNU_CLIPPING"), 0, this);
+  aAction->setStatusTip (tr("DSC_CLIPPING"));
+  aAction->setCheckable (true);
+  connect (aAction, SIGNAL (toggled (bool)), this, SLOT (onClipping (bool)));
+  toolMgr()->registerAction (aAction, ClippingId);
 
   aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
                            tr( "MNU_SHOOT_VIEW" ), 0, this);
@@ -1193,8 +1304,10 @@ void OCCViewer_ViewWindow::createActions()
   if (myModel->trihedronActivated()) {
     aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ),
                              tr( "MNU_SHOW_TRIHEDRE" ), 0, this);
+    aAction->setCheckable( true );
+    aAction->setChecked( true );
     aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
-    connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow()));
+    connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onTrihedronShow(bool)));
     toolMgr()->registerAction( aAction, TrihedronShowId );
   }
 
@@ -1205,6 +1318,22 @@ void OCCViewer_ViewWindow::createActions()
   connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale()));
   toolMgr()->registerAction( aAction, AxialScaleId );
 
+  // Enable/disable preselection
+  aAction = new QtxAction(tr("MNU_ENABLE_PRESELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESELECTION" ) ),
+                          tr( "MNU_ENABLE_PRESELECTION" ), 0, this);
+  aAction->setStatusTip(tr("DSC_ENABLE_PRESELECTION"));
+  aAction->setCheckable(true);
+  connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchPreselection(bool)));
+  toolMgr()->registerAction( aAction, SwitchPreselectionId );
+
+  // Enable/disable selection
+  aAction = new QtxAction(tr("MNU_ENABLE_SELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SELECTION" ) ),
+                          tr( "MNU_ENABLE_SELECTION" ), 0, this);
+  aAction->setStatusTip(tr("DSC_ENABLE_SELECTION"));
+  aAction->setCheckable(true);
+  connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchSelection(bool)));
+  toolMgr()->registerAction( aAction, SwitchSelectionId );
+
   // Graduated axes 
   aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ),
                            tr( "MNU_GRADUATED_AXES" ), 0, this);
@@ -1242,6 +1371,15 @@ void OCCViewer_ViewWindow::createActions()
   connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView()));
   toolMgr()->registerAction( aAction, MaximizedId );
 
+  // Return to 3d view
+  if (my2dMode!=No2dMode){
+    aAction = new QtxAction(tr("MNU_RETURN_3D_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RETURN_3D_VIEW" ) ),
+                            tr( "MNU_RETURN_3D_VIEW" ), 0, this );
+    aAction->setStatusTip(tr("DSC_RETURN_3D_VIEW"));
+    connect(aAction, SIGNAL(triggered()), this, SLOT(returnTo3dView()));
+    toolMgr()->registerAction( aAction, ReturnTo3dViewId );
+  }
+
   // Synchronize View 
   toolMgr()->registerAction( synchronizeAction(), SynchronizeId );
 }
@@ -1251,28 +1389,30 @@ void OCCViewer_ViewWindow::createActions()
 */
 void OCCViewer_ViewWindow::createToolBar()
 {
-  QString aToolbarName;
-  switch (my2dMode) {
-  case XYPlane:
-    aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" );
-    break;
-  case XZPlane:
-    aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" );
-    break;
-  case YZPlane:
-    aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" );
-    break;
-  default:
-    aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" );
+  static const char* titles[] = {
+    "LBL_3DTOOLBAR_LABEL",
+    "LBL_XYTOOLBAR_LABEL",
+    "LBL_XZTOOLBAR_LABEL",
+    "LBL_YZTOOLBAR_LABEL",
+  };
+  static const char* names[] = {
+    "OCCViewer3DViewOperations",
+    "OCCViewerXYViewOperations",
+    "OCCViewerXZViewOperations",
+    "OCCViewerYZViewOperations",
+  };
+  int tid = toolMgr()->createToolBar( tr( titles[my2dMode] ),        // title (language-dependant)
+                                     QString( names[my2dMode] ),    // name (language-independant)
+                                     false );                       // disable floatable toolbar
+  if ( my2dMode != No2dMode ){
+    toolMgr()->append( ReturnTo3dViewId, tid );
+    toolMgr()->append( toolMgr()->separator(), tid );
   }
-  
-  int tid = toolMgr()->createToolBar( aToolbarName, false );
-
   toolMgr()->append( DumpId, tid );
   toolMgr()->append( SwitchInteractionStyleId, tid );
-#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
   toolMgr()->append( SwitchZoomingStyleId, tid );
-#endif
+  toolMgr()->append( SwitchPreselectionId, tid );
+  toolMgr()->append( SwitchSelectionId, tid );
   if( myModel->trihedronActivated() )
     toolMgr()->append( TrihedronShowId, tid );
 
@@ -1317,9 +1457,7 @@ void OCCViewer_ViewWindow::createToolBar()
   toolMgr()->append( toolMgr()->separator(), tid );
   toolMgr()->append( ClippingId, tid );
   toolMgr()->append( AxialScaleId, tid );
-#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
   toolMgr()->append( GraduatedAxesId, tid );
-#endif
   toolMgr()->append( AmbientId, tid );
 
   toolMgr()->append( MaximizedId, tid );
@@ -1495,44 +1633,6 @@ void OCCViewer_ViewWindow::onCloneView()
   emit viewCloned( vw );
 }
 
-/*!
-  \brief called if clipping operation is activated.
-
-  Enables/disables clipping plane displaying.
-
-  \parma on action state
-*/
-void OCCViewer_ViewWindow::onClipping( bool on )
-{
-  /*
-  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
-  if ( on )
-    myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" )));
-  else
-    myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" )));
-  */
-  OCCViewer_ViewWindow* aParent = dynamic_cast<OCCViewer_ViewWindow*>(parent()->parent());
-  if (!aParent)
-    aParent = this;
-  if ( on )
-    {
-      if ( !myClippingDlg )
-        {
-          myClippingDlg = new OCCViewer_ClippingDlg( aParent );
-          myClippingDlg->SetAction( myClippingAction );
-        }
-    
-      if ( !myClippingDlg->isVisible() )
-        myClippingDlg->show();
-    }
-  else
-    {
-      if ( myClippingDlg->isVisible() )
-        myClippingDlg->hide();
-      aParent->setCuttingPlane(false);
-    }
-}
-
 /*!
   Creates one more window with same content
 */
@@ -1606,7 +1706,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base
 
   Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
   aView3d->SetScale( anItem.scale );
-  aView3d->SetCenter( anItem.centerX, anItem.centerY );
   aView3d->SetTwist( anItem.twist );
   aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
   aView3d->SetImmediateUpdate( prev );
@@ -1614,12 +1713,37 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base
   aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
   aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ );
 
+#if OCC_VERSION_LARGE > 0x06070100
+  if ( anItem.centerX != 0.0 || anItem.centerY != 0.0 )
+  {
+    double anUpX = 0.0, anUpY = 0.0, anUpZ = 0.0;
+
+    // "eye" and "at" require conversion to represent center panning
+    // up direction is only available after setting angle of twist and
+    // other view parameters
+    aView3d->Up( anUpX, anUpY, anUpZ );
+
+    gp_Dir aProj( -anItem.projX, -anItem.projY, -anItem.projZ );
+    gp_Dir anUp( anUpX, anUpY, anUpZ );
+    gp_Pnt anAt( anItem.atX, anItem.atY, anItem.atZ );
+    gp_Pnt anEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
+    gp_Dir aSide = aProj ^ anUp;
+
+    anAt.Translate( gp_Vec( aSide ) * anItem.centerX );
+    anAt.Translate( gp_Vec( anUp  ) * anItem.centerY );
+
+    aView3d->SetAt( anAt.X(), anAt.Y(), anAt.Z() );
+    aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
+  }
+#else
+  aView3d->SetCenter( anItem.centerX, anItem.centerY );
+#endif
+
   if ( !baseParamsOnly ) {
 
     myModel->setTrihedronShown( anItem.isVisible );
     myModel->setTrihedronSize( anItem.size );
         
-#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
     // graduated trihedron
     bool anIsVisible = anItem.gtIsVisible;
     OCCViewer_AxisWidget::AxisData anAxisData[3];
@@ -1630,14 +1754,14 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base
     anAxisData[1].Name = anItem.gtNameZ;
     anAxisData[2].Name = anItem.gtNameZ;
     anAxisData[0].NameColor = QColor( anItem.gtNameColorRX,
-                                     anItem.gtNameColorGX,
-                                     anItem.gtNameColorBX );
+              anItem.gtNameColorGX,
+              anItem.gtNameColorBX );
     anAxisData[1].NameColor = QColor( anItem.gtNameColorRY,
-                                     anItem.gtNameColorGY,
-                                     anItem.gtNameColorBY );
+              anItem.gtNameColorGY,
+              anItem.gtNameColorBY );
     anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ,
-                                     anItem.gtNameColorGZ,
-                                     anItem.gtNameColorBZ );
+              anItem.gtNameColorGZ,
+              anItem.gtNameColorBZ );
     anAxisData[0].DrawValues = anItem.gtDrawValuesX;
     anAxisData[1].DrawValues = anItem.gtDrawValuesY;
     anAxisData[2].DrawValues = anItem.gtDrawValuesZ;
@@ -1648,14 +1772,14 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base
     anAxisData[1].Offset = anItem.gtOffsetY;
     anAxisData[2].Offset = anItem.gtOffsetZ;
     anAxisData[0].Color = QColor( anItem.gtColorRX,
-                                 anItem.gtColorGX,
-                                 anItem.gtColorBX );
+          anItem.gtColorGX,
+          anItem.gtColorBX );
     anAxisData[1].Color = QColor( anItem.gtColorRY,
-                                 anItem.gtColorGY,
-                                 anItem.gtColorBY );
+          anItem.gtColorGY,
+          anItem.gtColorBY );
     anAxisData[2].Color = QColor( anItem.gtColorRZ,
-                                 anItem.gtColorGZ,
-                                 anItem.gtColorBZ );
+          anItem.gtColorGZ,
+          anItem.gtColorBZ );
     anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX;
     anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY;
     anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ;
@@ -1665,7 +1789,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base
 
     myCubeAxesDlg->SetData( anIsVisible, anAxisData );
     myCubeAxesDlg->ApplyData( aView3d );
-#endif
 
   } // if ( !baseParamsOnly )
 
@@ -1683,9 +1806,52 @@ void OCCViewer_ViewWindow::setRestoreFlag()
 /*!
   \brief Called when action "show/hide trihedron" is activated.
 */
-void OCCViewer_ViewWindow::onTrihedronShow()
+void OCCViewer_ViewWindow::onTrihedronShow(bool show)
 {
-  myModel->toggleTrihedron();
+  myModel->setTrihedronShown(show);
+}
+
+/*!
+  \brief Toggles preselection (highlighting) on/off
+*/
+void OCCViewer_ViewWindow::onSwitchPreselection( bool on )
+{
+  myPreselectionEnabled = on;
+  myModel->setSelectionOptions( isPreselectionEnabled(), myModel->isSelectionEnabled() );
+
+  // unhighlight all highlighted objects
+  /*if ( !on ) {
+    myModel->unHighlightAll( true, false );
+  }*/
+
+  // update action state if method is called outside
+  QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchPreselectionId ) );
+  if ( a && a->isChecked() != on ) {
+    a->setChecked( on );
+  }
+}
+
+/*!
+  \brief Toggles selection on/off
+*/
+void OCCViewer_ViewWindow::onSwitchSelection( bool on )
+{
+  mySelectionEnabled = on;
+  myModel->setSelectionOptions( myModel->isPreselectionEnabled(), isSelectionEnabled() );
+  
+  // update action state if method is called outside
+
+  // preselection
+  QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchPreselectionId ) );
+  if ( a ) {
+    a->setEnabled( on );
+  }
+
+  // selection
+  a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchSelectionId ) );
+  if ( a && a->isChecked() != on ) {
+    a->setChecked( on );
+  }
 }
 
 /*!
@@ -1762,6 +1928,10 @@ QImage OCCViewer_ViewWindow::dumpView()
   
   int aWidth = myViewPort->width();
   int aHeight = myViewPort->height();
+
+  // rnv: An old approach to dump the OCCViewer content
+  //      Now used OCCT built-in procedure.
+  /*     
   QApplication::syncX();
   view->Redraw(); // In order to reactivate GL context
   //view->Update();
@@ -1798,10 +1968,13 @@ QImage OCCViewer_ViewWindow::dumpView()
 
   glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                 data);
+  */
+  
+  Image_PixMap aPix;
+  view->ToPixMap(aPix,aWidth, aHeight,Graphic3d_BT_RGBA);
 
-  QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 );
+  QImage anImage( aPix.Data(), aWidth, aHeight, QImage::Format_ARGB32 );
   anImage = anImage.mirrored();
-  anImage = anImage.rgbSwapped();
   return anImage;
 }
 
@@ -1851,33 +2024,30 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x,  const doub
 
     // try to use already existing plane or create a new one
     Handle(V3d_Plane) clipPlane;
-    view->InitActivePlanes();
 
     // calculate new a,b,c,d values for the plane
     gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz));
     double a, b, c, d;
     pln.Coefficients(a, b, c, d);
-
-#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
-    if (view->MoreActivePlanes()) {
-      clipPlane = view->ActivePlane();
-      clipPlane->SetPlane(a, b, c, d);
+    
+    Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes();
+    if(aPlanes.Size() > 0 ) {
+      Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes);
+      Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
+      aClipPlane->SetEquation(pln);
+      aClipPlane->SetOn(Standard_True);
+    } else {
+      view->AddClipPlane( myModel->createClipPlane( pln, Standard_True ) );
+    }
+  }
+  else {
+    Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes();
+    Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes);
+    for( ;anIter.More();anIter.Next() ){
+      Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
+      aClipPlane->SetOn(Standard_False);
     }
-    else
-      clipPlane = new V3d_Plane (a, b, c, d);
-#else
-    if (view->MoreActivePlanes())
-      clipPlane = view->ActivePlane();
-    else
-      clipPlane = new V3d_Plane (viewer);
-
-    clipPlane->SetPlane(a, b, c, d);
-#endif
-
-    view->SetPlaneOn(clipPlane);
   }
-  else
-    view->SetPlaneOff();
 
   view->Update();
   view->Redraw();
@@ -1898,8 +2068,17 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln )
 bool OCCViewer_ViewWindow::isCuttingPlane()
 {
   Handle(V3d_View) view = myViewPort->getView();
-  view->InitActivePlanes();
-  return (view->MoreActivePlanes());
+  bool res = false;
+  Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes();
+  Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes);
+  for( ;anIter.More();anIter.Next() ) {
+    Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
+    if(aClipPlane->IsOn()) {
+      res = true;
+      break;
+    }
+  }
+  return res;
 }
 
 /*!
@@ -1908,13 +2087,12 @@ bool OCCViewer_ViewWindow::isCuttingPlane()
 */
 viewAspect OCCViewer_ViewWindow::getViewParams() const
 {
-  double centerX, centerY, projX, projY, projZ, twist;
+  double projX, projY, projZ, twist;
   double atX, atY, atZ, eyeX, eyeY, eyeZ;
   double aScaleX, aScaleY, aScaleZ;
 
   Handle(V3d_View) aView3d = myViewPort->getView();
 
-  aView3d->Center( centerX, centerY );
   aView3d->Proj( projX, projY, projZ );
   aView3d->At( atX, atY, atZ );
   aView3d->Eye( eyeX, eyeY, eyeZ );
@@ -1929,8 +2107,6 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const
 
   viewAspect params;
   params.scale    = aView3d->Scale();
-  params.centerX  = centerX;
-  params.centerY  = centerY;
   params.projX    = projX;
   params.projY    = projY;
   params.projZ    = projZ;
@@ -1948,7 +2124,10 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const
   params.isVisible= isShown;
   params.size     = size;
 
-#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
+#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1
+  aView3d->Center( params.centerX, params.centerY );
+#endif
+
   // graduated trihedron
   bool anIsVisible = false;
   OCCViewer_AxisWidget::AxisData anAxisData[3];
@@ -1994,12 +2173,10 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const
   params.gtTickmarkLengthX = anAxisData[0].TickmarkLength;
   params.gtTickmarkLengthY = anAxisData[1].TickmarkLength;
   params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength;
-#endif
 
   return params;
 }
 
-
 /*!
   \brief Get visual parameters of this view window.
   \return visual parameters of view window
@@ -2011,8 +2188,10 @@ QString OCCViewer_ViewWindow::getVisualParameters()
   QStringList data;
 
   data << QString( "scale=%1" )    .arg( params.scale,   0, 'e', 12 );
+#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1
   data << QString( "centerX=%1" )  .arg( params.centerX, 0, 'e', 12 );
   data << QString( "centerY=%1" )  .arg( params.centerY, 0, 'e', 12 );
+#endif
   data << QString( "projX=%1" )    .arg( params.projX,   0, 'e', 12 );
   data << QString( "projY=%1" )    .arg( params.projY,   0, 'e', 12 );
   data << QString( "projZ=%1" )    .arg( params.projZ,   0, 'e', 12 );
@@ -2029,7 +2208,47 @@ QString OCCViewer_ViewWindow::getVisualParameters()
   data << QString( "isVisible=%1" ).arg( params.isVisible );
   data << QString( "size=%1" )     .arg( params.size,    0, 'f',  2 );
 
-#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 or newer version
+  ClipPlanesList aPlanes =  myModel->getClipPlanes();
+  for ( int i=0; i < aPlanes.size(); i++ )
+  {
+    OCCViewer_ClipPlane& aPlane = aPlanes[i];
+    QString ClippingPlane = QString( "ClippingPlane%1=").arg( i+1 );
+    ClippingPlane +=  QString( "Mode~%1;").arg( (int)aPlane.Mode );
+    ClippingPlane +=  QString( "IsActive~%1;").arg( aPlane.IsOn );
+    switch ( aPlane.Mode )
+    {
+      case OCCViewer_ClipPlane::Absolute :
+      {
+        ClippingPlane += QString( "AbsoluteOrientation~%1;" ).arg( aPlane.OrientationType );
+
+        if ( aPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
+        {
+          ClippingPlane += QString( "Dx~%1;" ).arg( aPlane.AbsoluteOrientation.Dx );
+          ClippingPlane += QString( "Dy~%1;" ).arg( aPlane.AbsoluteOrientation.Dy );
+          ClippingPlane += QString( "Dz~%1;" ).arg( aPlane.AbsoluteOrientation.Dz );
+        }
+        else
+        {
+          ClippingPlane += QString( "IsInvert~%1;" ).arg( aPlane.AbsoluteOrientation.IsInvert );
+        }
+      }
+      break;
+
+      case OCCViewer_ClipPlane::Relative :
+      {
+        ClippingPlane += QString( "RelativeOrientation~%1;" ).arg( aPlane.OrientationType );
+        ClippingPlane += QString( "Rotation1~%1;" ).arg( aPlane.RelativeOrientation.Rotation1 );
+        ClippingPlane += QString( "Rotation2~%1" ).arg( aPlane.RelativeOrientation.Rotation2 );
+      }
+      break;
+    }
+
+    ClippingPlane +=  QString( "X~%1;" ).arg( aPlane.X );
+    ClippingPlane +=  QString( "Y~%1;" ).arg( aPlane.Y );
+    ClippingPlane +=  QString( "Z~%1;" ).arg( aPlane.Z );
+    data << ClippingPlane;
+  }
+
   // graduated trihedron
   data << QString( "gtIsVisible=%1" )      .arg( params.gtIsVisible );
   data << QString( "gtDrawNameX=%1" )      .arg( params.gtDrawNameX );
@@ -2071,7 +2290,6 @@ QString OCCViewer_ViewWindow::getVisualParameters()
   data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX );
   data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY );
   data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ );
-#endif
   QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" );
   data << QString( "background=%1" ).arg( bg );
 
@@ -2085,7 +2303,7 @@ QString OCCViewer_ViewWindow::getVisualParameters()
 void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
 {
   viewAspect params;
-
+  ClipPlanesList aClipPlanes;
   QStringList data = parameters.split( '*' );
   Qtx::BackgroundData bgData;
   if ( parameters.contains( '=' )  ) // new format - "scale=1.000e+00*centerX=0.000e+00..."
@@ -2111,6 +2329,44 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
       else if ( paramName == "scaleZ" )            params.scaleZ            = paramValue.toDouble();
       else if ( paramName == "isVisible" )         params.isVisible         = paramValue.toInt();
       else if ( paramName == "size" )              params.size              = paramValue.toDouble();
+      else if ( paramName.contains( "ClippingPlane" ) )
+      {
+        QStringList ClipPlaneData = paramValue.split( ';' );
+        OCCViewer_ClipPlane aPlane;
+        foreach( QString ClipPlaneParam, ClipPlaneData )
+        {
+          QString ClipPlane_paramName  = ClipPlaneParam.section( '~', 0, 0 ).trimmed();
+          QString ClipPlane_paramValue = ClipPlaneParam.section( '~', 1, 1 ).trimmed();
+          if ( ClipPlane_paramName == "Mode" )
+          {
+            aPlane.Mode = ( OCCViewer_ClipPlane::PlaneMode ) ClipPlane_paramValue.toInt();
+          }
+          else if ( ClipPlane_paramName == "IsActive" ) aPlane.IsOn = ClipPlane_paramValue.toInt();
+          else if ( ClipPlane_paramName == "X" )        aPlane.X    = ClipPlane_paramValue.toDouble();
+          else if ( ClipPlane_paramName == "Y" )        aPlane.Y    = ClipPlane_paramValue.toDouble();
+          else if ( ClipPlane_paramName == "Z" )        aPlane.Z    = ClipPlane_paramValue.toDouble();
+          else
+          {
+            switch ( aPlane.Mode )
+            {
+              case OCCViewer_ClipPlane::Absolute :
+                if      ( ClipPlane_paramName == "Dx" ) aPlane.AbsoluteOrientation.Dx = ClipPlane_paramValue.toDouble();
+                else if ( ClipPlane_paramName == "Dy" ) aPlane.AbsoluteOrientation.Dy = ClipPlane_paramValue.toDouble();
+                else if ( ClipPlane_paramName == "Dz" ) aPlane.AbsoluteOrientation.Dz = ClipPlane_paramValue.toDouble();
+                else if ( ClipPlane_paramName == "IsInvert" ) aPlane.AbsoluteOrientation.IsInvert = ClipPlane_paramValue.toInt();
+                else if ( ClipPlane_paramName == "AbsoluteOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt();
+                break;
+
+              case OCCViewer_ClipPlane::Relative :
+                if      ( ClipPlane_paramName == "RelativeOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt();
+                else if ( ClipPlane_paramName == "Rotation1" )           aPlane.RelativeOrientation.Rotation1 = ClipPlane_paramValue.toDouble();
+                else if ( ClipPlane_paramName == "Rotation2" )           aPlane.RelativeOrientation.Rotation2 = ClipPlane_paramValue.toDouble();
+                break;
+            }
+          }
+        }
+        aClipPlanes.push_back(aPlane);
+      }
       // graduated trihedron
       else if ( paramName == "gtIsVisible" )       params.gtIsVisible       = paramValue.toInt();
       else if ( paramName == "gtDrawNameX" )       params.gtDrawNameX       = paramValue.toInt();
@@ -2153,8 +2409,8 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
       else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt();
       else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt();
       else if ( paramName == "background" )        {
-       QString bg = paramValue.replace( "$", "=" );
-       bgData = Qtx::stringToBackground( bg );
+  QString bg = paramValue.replace( "$", "=" );
+  bgData = Qtx::stringToBackground( bg );
       }
     }
   }
@@ -2180,8 +2436,9 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
     params.isVisible = data.count() > idx ? data[idx++].toInt()    : 1;
     params.size      = data.count() > idx ? data[idx++].toDouble() : 100.0;
   }
-  performRestoring( params );
+  performRestoring( params );  
   setBackground( bgData );
+  myModel->setClipPlanes(aClipPlanes);
 }
 
 /*!
@@ -2294,7 +2551,7 @@ void OCCViewer_ViewWindow::onSketchingFinished()
   if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept )
   {
     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
-    bool append = bool( mypSketcher->buttonState() & Qt::ShiftModifier );
+    bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() );
     switch( mypSketcher->type() )
     {
     case Rect:
@@ -2388,16 +2645,34 @@ void OCCViewer_ViewWindow::onMaximizedView()
   setMaximized(!isMaximized());
 }
 
+void OCCViewer_ViewWindow::returnTo3dView()
+{
+  setReturnedTo3dView( true );
+}
+
+void OCCViewer_ViewWindow::setReturnedTo3dView(bool isVisible3dView)
+{
+  if ( !toolMgr()->action( ReturnTo3dViewId ) ||
+    toolMgr()->isShown(ReturnTo3dViewId) != isVisible3dView ) return;
+  if ( !isVisible3dView )
+    toolMgr()->show( ReturnTo3dViewId );
+  else
+    toolMgr()->hide( ReturnTo3dViewId );
+  if ( isVisible3dView ) emit returnedTo3d( );
+}
+
 
 void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal)
 {
   QAction* anAction =  toolMgr()->action( MaximizedId );
+  QAction* anAction2 =  toolMgr()->action( ReturnTo3dViewId );
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
   if ( toMaximize ) {
     anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) );  
     anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) );  
     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) );
     anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) );
+    if ( anAction2 && my2dMode != No2dMode ) toolMgr()->show( ReturnTo3dViewId );
     if (toSendSignal) {
       emit maximized( this, true );
     }
@@ -2407,13 +2682,13 @@ void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal)
     anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) );  
     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) );
     anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) );
+    if ( anAction2 && my2dMode != No2dMode ) toolMgr()->hide( ReturnTo3dViewId );
     if (toSendSignal) {
       emit maximized( this, false );
     }
   }
 }
 
-
 bool OCCViewer_ViewWindow::isMaximized() const
 {
   return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" ));
@@ -2457,6 +2732,11 @@ void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackgrou
   if ( myViewPort ) myViewPort->setBackground( theBackground );
 }
 
+void OCCViewer_ViewWindow::showStaticTrihedron( bool on )
+{
+  if ( myViewPort ) myViewPort->showStaticTrihedron( on );
+}
+
 /*!
   Clears view aspects
 */
@@ -2510,59 +2790,85 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
     aProps.setDimension( SUIT_CameraProperties::Dim2D );
     aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() );
   }
-  
+
   // read common properites of the view
-  Standard_Real anUpDir[3];
-  Standard_Real aPrjDir[3];
-  Standard_Real aMapScale[2];
-  Standard_Real aTranslation[3];
+  Standard_Real anUp[3];
+  Standard_Real anAt[3];
+  Standard_Real anEye[3];
+  Standard_Real aProj[3];
   Standard_Real anAxialScale[3];
-  
-  aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]);
-  aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]);
-  aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
-  aSourceView->Size(aMapScale[0], aMapScale[1]);
 
-  getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  aSourceView->Up( anUp[0], anUp[1], anUp[2] );
+  aSourceView->At( anAt[0], anAt[1], anAt[2] );
+  aSourceView->Proj( aProj[0], aProj[1], aProj[2] );
+  getViewPort()->getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
+
+  aProps.setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
+  aProps.setViewUp( anUp[0], anUp[1], anUp[2] );
 
-  // we use similar depth to the one used in perspective projection 
-  // to proivde a convinience synchronization with other camera views that
-  // can switch between orthogonal & perspective projection. otherwise,
-  // the camera will get to close when switching from orthogonal to perspective.
+#if OCC_VERSION_LARGE > 0x06070100
+  aSourceView->Eye( anEye[0], anEye[1], anEye[2] );
+
+  // store camera properties "as is": it is up to synchronized
+  // view classes to provide necessary property conversion.
+  aProps.setPosition( anEye[0], anEye[1], anEye[2] );
+  aProps.setFocalPoint( anAt[0], anAt[1], anAt[2] );
+
+  if ( aSourceView->Camera()->IsOrthographic() )
+  {
+    aProps.setProjection( SUIT_CameraProperties::PrjOrthogonal );
+    aProps.setViewAngle( 0.0 );
+  }
+  else
+  {
+    aProps.setProjection( SUIT_CameraProperties::PrjPerspective );
+    aProps.setViewAngle( aSourceView->Camera()->FOVy() );
+  }
+  aProps.setMappingScale( aSourceView->Camera()->Scale() );
+#else
   Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5;
 
-  // store common props
-  aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
-  aProps.setMappingScale(aMapScale[1] / 2.0);
-  aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
-  
   // generate view orientation matrix for transforming OCC projection reference point
   // into a camera (eye) position.
-  gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
-    gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2]));
+  gp_Dir aLeftDir = gp_Dir( anUp[0], anUp[1], anUp[2] ) ^ gp_Dir( aProj[0], aProj[1], aProj[2] );
 
-  gp_Trsf aTrsf;
-  aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0],
-                   aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1],
-                   aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2],
-                   Precision::Confusion(),
-                   Precision::Confusion() );
+  gp_GTrsf aTrsf;
+  aTrsf.SetValue( 1, 1, aLeftDir.X() );
+  aTrsf.SetValue( 2, 1, aLeftDir.Y() );
+  aTrsf.SetValue( 3, 1, aLeftDir.Z() );
+
+  aTrsf.SetValue( 1, 2, anUp[0] );
+  aTrsf.SetValue( 2, 2, anUp[1] );
+  aTrsf.SetValue( 3, 2, anUp[2] );
+
+  aTrsf.SetValue( 1, 3, aProj[0] );
+  aTrsf.SetValue( 2, 3, aProj[1] );
+  aTrsf.SetValue( 3, 3, aProj[2] );
+
+  aTrsf.SetValue( 1, 4, anAt[0] );
+  aTrsf.SetValue( 2, 4, anAt[1] );
+  aTrsf.SetValue( 3, 4, anAt[2] );
 
-  // get projection reference point in view coordinates
   Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint();
-  
+
   // transform to world-space coordinate system
-  gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf);
-  
+  gp_XYZ aPosition( aProjRef.X(), aProjRef.Y(), aCameraDepth );
+  aTrsf.Transforms( aPosition );
+
   // compute focal point
   double aFocalPoint[3];
 
-  aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth;
-  aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth;
-  aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth;
+  aFocalPoint[0] = aPosition.X() - aProj[0] * aCameraDepth;
+  aFocalPoint[1] = aPosition.Y() - aProj[1] * aCameraDepth;
+  aFocalPoint[2] = aPosition.Z() - aProj[2] * aCameraDepth;
+
+  aProps.setFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] );
+  aProps.setPosition( aPosition.X(), aPosition.Y(), aPosition.Z() );
 
-  aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
-  aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z());
+  Standard_Real aViewScale[2];
+  aSourceView->Size( aViewScale[0], aViewScale[1] );
+  aProps.setMappingScale( aViewScale[1] );
+#endif
 
   return aProps;
 }
@@ -2590,39 +2896,52 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   double anUpDir[3];
   double aPosition[3];
   double aFocalPoint[3];
-  double aMapScaling;
   double anAxialScale[3];
 
   // get common properties
-  aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
-  aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
-  aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
-  aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
-  aMapScaling = aProps.getMappingScale() * 2.0;
-
-  gp_Dir aProjDir(aPosition[0] - aFocalPoint[0],
-                  aPosition[1] - aFocalPoint[1],
-                  aPosition[2] - aFocalPoint[2]);
-  
+  aProps.getFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] );
+  aProps.getPosition( aPosition[0], aPosition[1], aPosition[2] );
+  aProps.getViewUp( anUpDir[0], anUpDir[1], anUpDir[2] );
+  aProps.getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
+
+#if OCC_VERSION_LARGE > 0x06070100
+  aDestView->SetAt( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] );
+  aDestView->SetEye( aPosition[0], aPosition[1], aPosition[2] );
+  aDestView->SetUp( anUpDir[0], anUpDir[1], anUpDir[2] );
+  aDestView->Camera()->SetScale( aProps.getMappingScale() );
+#else
+  gp_Dir aProjDir( aPosition[0] - aFocalPoint[0],
+                   aPosition[1] - aFocalPoint[1],
+                   aPosition[2] - aFocalPoint[2] );
+
   // get custom view translation
   Standard_Real aTranslation[3];
-  aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
-
-  gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
-    gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z()));
-
-  // convert camera position into a view reference point
-  gp_Trsf aTrsf;
-  aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0],
-                   aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1],
-                   aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], 
-                   Precision::Confusion(),
-                   Precision::Confusion() );
+  aDestView->At( aTranslation[0], aTranslation[1], aTranslation[2] );
+
+  gp_Dir aLeftDir = gp_Dir( anUpDir[0], anUpDir[1], anUpDir[2] )
+                  ^ gp_Dir( aProjDir.X(), aProjDir.Y(), aProjDir.Z() );
+
+  gp_GTrsf aTrsf;
+  aTrsf.SetValue( 1, 1, aLeftDir.X() );
+  aTrsf.SetValue( 2, 1, aLeftDir.Y() );
+  aTrsf.SetValue( 3, 1, aLeftDir.Z() );
+
+  aTrsf.SetValue( 1, 2, anUpDir[0] );
+  aTrsf.SetValue( 2, 2, anUpDir[1] );
+  aTrsf.SetValue( 3, 2, anUpDir[2] );
+
+  aTrsf.SetValue( 1, 3, aProjDir.X() );
+  aTrsf.SetValue( 2, 3, aProjDir.Y() );
+  aTrsf.SetValue( 3, 3, aProjDir.Z() );
+
+  aTrsf.SetValue( 1, 4, aTranslation[0] );
+  aTrsf.SetValue( 2, 4, aTranslation[1] );
+  aTrsf.SetValue( 3, 4, aTranslation[2] );
   aTrsf.Invert();
 
   // transform to view-space coordinate system
-  gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
-  aProjRef.Transform(aTrsf);
+  gp_XYZ aProjRef( aPosition[0], aPosition[1], aPosition[2] );
+  aTrsf.Transforms( aProjRef );
 
   // set view camera properties using low-level approach. this is done
   // in order to avoid interference with static variables in v3d view used
@@ -2630,31 +2949,29 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
   Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping();
   Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation();
 
-  Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z());
-  Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]);
+  Graphic3d_Vector aMappingProj( aProjDir.X(), aProjDir.Y(), aProjDir.Z() );
+  Graphic3d_Vector aMappingUp( anUpDir[0], anUpDir[1], anUpDir[2] );
 
   aMappingProj.Normalize();
   aMappingUp.Normalize();
 
-  anOrientation.SetViewReferencePlane(aMappingProj);
-  anOrientation.SetViewReferenceUp(aMappingUp);
+  anOrientation.SetViewReferencePlane( aMappingProj );
+  anOrientation.SetViewReferenceUp( aMappingUp );
 
-  aDestView->SetViewMapping(aMapping);
-  aDestView->SetViewOrientation(anOrientation);
+  aDestView->SetViewMapping( aMapping );
+  aDestView->SetViewOrientation( anOrientation );
 
   // set panning
-  aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
+  aDestView->SetCenter( aProjRef.X(), aProjRef.Y() );
 
   // set mapping scale
+  double aMapScaling = aProps.getMappingScale();
   Standard_Real aWidth, aHeight;
-  aDestView->Size(aWidth, aHeight);
-  
-  if ( aWidth > aHeight )
-    aDestView->SetSize (aMapScaling * (aWidth / aHeight));
-  else
-    aDestView->SetSize (aMapScaling);
+  aDestView->Size( aWidth, aHeight );
+  aDestView->SetSize ( aWidth > aHeight ? aMapScaling * (aWidth / aHeight) : aMapScaling );
+#endif
 
-  getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
+  getViewPort()->setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] );
 
   aDestView->ZFitAll();
   aDestView->SetImmediateUpdate( Standard_True );
@@ -2662,3 +2979,85 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
 
   blockSignals( blocked );
 }
+
+/*!
+  \brief Indicates whether preselection is enabled
+  \return true if preselection is enabled
+*/
+bool OCCViewer_ViewWindow::isPreselectionEnabled() const
+{
+  return myPreselectionEnabled;
+}
+
+/*!
+  \brief Enables/disables preselection
+  \param theIsToEnable if true - preselection will be enabled
+*/
+void OCCViewer_ViewWindow::enablePreselection( bool theIsToEnable )
+{
+  onSwitchPreselection( theIsToEnable );
+}
+
+/*!
+  \brief Indicates whether selection is enabled
+  \return true if selection is enabled
+*/
+bool OCCViewer_ViewWindow::isSelectionEnabled() const
+{
+  return mySelectionEnabled;
+}
+
+/*!
+  \brief Enables/disables selection
+  \param theIsToEnable if true - selection will be enabled
+*/
+void OCCViewer_ViewWindow::enableSelection( bool theIsToEnable )
+{
+  onSwitchSelection( theIsToEnable );
+}
+
+
+/*!
+  \brief called if clipping operation is activated / deactivated.
+
+  Enables/disables clipping plane displaying.
+
+  \parma on action state
+*/
+void OCCViewer_ViewWindow::onClipping (bool theIsOn)
+{
+  if(!myModel) return;
+  OCCViewer_ClippingDlg* aClippingDlg = myModel->getClippingDlg();
+  
+  if (theIsOn) {
+    if (!aClippingDlg) {
+      aClippingDlg = new OCCViewer_ClippingDlg (this, myModel);
+      myModel->setClippingDlg(aClippingDlg);
+    }
+    if (!aClippingDlg->isVisible())
+      aClippingDlg->show();
+  } else {
+    if ( aClippingDlg ) {
+      aClippingDlg->close();
+      myModel->setClippingDlg(0);
+    }
+  }
+
+  SUIT_ViewManager* mgr = getViewManager();
+  if( mgr ) {
+    QVector<SUIT_ViewWindow*> aViews = mgr->getViews();
+    for(int i = 0, iEnd = aViews.size(); i < iEnd; i++) {
+      if(SUIT_ViewWindow* aViewWindow = aViews.at(i)) {
+       QtxActionToolMgr* mgr = aViewWindow->toolMgr();
+       if(!mgr) continue;
+       QAction* a = toolMgr()->action( ClippingId );
+       if(!a) continue;
+       if(theIsOn != a->isChecked()){
+         disconnect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool)));
+         a->setChecked(theIsOn);
+         connect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool)));
+       }
+      }
+    }
+  }
+}