Salome HOME
Merge branch 'master' of ssh://git.salome-platform.org/modules/gui
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewModel.cxx
index 3735978ed10f18adaa8899e5933ac8fd4ce26172..c11d24ca0c9f0cfd56dd6c561d83157afaf1b19f 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  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
@@ -26,6 +26,7 @@
 #include "OCCViewer_VService.h"
 #include "OCCViewer_ViewPort3d.h"
 #include "OCCViewer_ClippingDlg.h"
+#include "OCCViewer_Utilities.h"
 
 #include "SUIT_ViewWindow.h"
 #include "SUIT_ViewManager.h"
@@ -35,6 +36,8 @@
 
 #include "ViewerData_AISShape.hxx"
 
+#include <Basics_OCCTVersion.hxx>
+
 #include "QtxActionToolMgr.h"
 #include "QtxBackgroundTool.h"
 
@@ -54,6 +57,9 @@
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
 
+#include <Graphic3d_Texture2Dmanual.hxx>
+#include <Graphic3d_TextureParams.hxx>
+
 #include <Geom_Axis2Placement.hxx>
 #include <Prs3d_Drawer.hxx>
 #include <Prs3d_DatumAspect.hxx>
 
 #include <Visual3d_View.hxx>
 
-
-// VSR: Uncomment below line to allow texture background support in OCC viewer
-#define OCC_ENABLE_TEXTURED_BACKGROUND
-
 /*!
   Get data for supported background modes: gradient types, identifiers and supported image formats
 */
@@ -79,11 +81,7 @@ QString OCCViewer_Viewer::backgroundData( QStringList& gradList, QIntList& idLis
               Diagonal1Gradient              << Diagonal2Gradient <<
               Corner1Gradient                << Corner2Gradient   <<
               Corner3Gradient                << Corner4Gradient;
-#if OCC_VERSION_LARGE > 0x06050200 // enabled since OCCT 6.5.3, since in previous version this functionality is buggy
-#ifdef OCC_ENABLE_TEXTURED_BACKGROUND
   txtList  << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture;
-#endif
-#endif
   return tr("BG_IMAGE_FILES");
 }
 
@@ -104,18 +102,8 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron)
   //myV3dViewer->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267)
   myV3dViewer->SetDefaultLights();
 
-#if OCC_VERSION_LARGE <= 0x06060000 // Porting to OCCT higher 6.6.0 version
-  myV3dCollector = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Collector3d").ToExtString() );
-  //myV3dCollector->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267)
-  myV3dCollector->SetDefaultLights();
-#endif
-
   // init selector
-#if OCC_VERSION_LARGE <= 0x06060000 
-  myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector );
-#else
   myAISContext = new AIS_InteractiveContext( myV3dViewer );
-#endif
   myAISContext->SelectionColor( Quantity_NOC_WHITE );
   
   // display isoline on planar faces (box for ex.)
@@ -153,11 +141,6 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron)
   // selection
   mySelectionEnabled = true;
   myMultiSelectionEnabled = true;
-  
-  
-  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-  if(resMgr)
-    myShowStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
 }
 
 /*!
@@ -167,9 +150,6 @@ OCCViewer_Viewer::~OCCViewer_Viewer()
 {
   myAISContext.Nullify();
   myV3dViewer.Nullify();
-#if OCC_VERSION_LARGE <= 0x06060000
-  myV3dCollector.Nullify();
-#endif
 }
 
 /*!
@@ -225,6 +205,9 @@ void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view )
     if ( vp3d )
     {
       vp3d->getView()->SetSurfaceDetail(V3d_TEX_ALL);
+      // connect signal from viewport
+      connect(vp3d, SIGNAL(vpClosed(OCCViewer_ViewPort3d*)), this, SLOT(onViewClosed(OCCViewer_ViewPort3d*)));
+      connect(vp3d, SIGNAL(vpMapped(OCCViewer_ViewPort3d*)), this, SLOT(onViewMapped(OCCViewer_ViewPort3d*)));
     }
   }
 }
@@ -243,9 +226,7 @@ SUIT_ViewWindow* OCCViewer_Viewer::createView( SUIT_Desktop* theDesktop )
   initView( vw );
   // set default background for view window
   vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
-  // connect signal from viewport
-  connect(view->getViewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
-  connect(view->getViewPort(), SIGNAL(vpMapped()), this, SLOT(onViewMapped()));
+
   return view;
 }
 
@@ -393,7 +374,7 @@ void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEven
   emit selectionChanged();
 }
 
-void OCCViewer_Viewer::onViewClosed()
+void OCCViewer_Viewer::onViewClosed(OCCViewer_ViewPort3d*)
 {
   Standard_Integer aViewsNb = 0;
   for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
@@ -404,17 +385,19 @@ void OCCViewer_Viewer::onViewClosed()
   }
 }
 
-void OCCViewer_Viewer::onViewMapped()
+void OCCViewer_Viewer::onViewMapped(OCCViewer_ViewPort3d* viewPort)
 {
   setTrihedronShown( true );
+  bool showStaticTrihedron = true;
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  if ( resMgr ) showStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
+  viewPort->showStaticTrihedron( showStaticTrihedron );
 }
 
 int OCCViewer_Viewer::getTopLayerId()
 {
-#if OCC_VERSION_LARGE > 0x06050200
   if ( myTopLayerId == 0 && !myAISContext->CurrentViewer().IsNull() )    
     myAISContext->CurrentViewer()->AddZLayer( myTopLayerId );
-#endif
 
   return myTopLayerId;
 }
@@ -533,6 +516,13 @@ void OCCViewer_Viewer::enableSelection(bool isEnabled)
       win->enableSelection( isEnabled );
     }
   }
+
+  
+  //clear current selection in the viewer
+  if(!isEnabled) {
+    myAISContext->ClearSelected( Standard_True );
+  }
+
 }
 
 /*!
@@ -720,15 +710,6 @@ bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj,
   AIS_ListOfInteractive List;
   myAISContext->DisplayedObjects(List);
 
-#if OCC_VERSION_LARGE <= 0x06060000
-  if( !onlyInViewer )
-  {
-    AIS_ListOfInteractive List1;
-    myAISContext->ObjectsInCollector(List1);
-    List.Append(List1);
-  }
-#endif
-
   AIS_ListIteratorOfListOfInteractive ite(List);
   for ( ; ite.More(); ite.Next() )
     if( ite.Value()==obj )
@@ -892,7 +873,7 @@ void OCCViewer_Viewer::isos( int& u, int& v ) const
  */
 OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow()
 {
-  return new OCCViewer_ViewWindow( 0,  this);
+  return new OCCViewer_ViewWindow(0,  this);
 }
 
 // obsolete  
@@ -926,18 +907,10 @@ void OCCViewer_Viewer::setBackground( int theViewId, const Qtx::BackgroundData&
 /*!
   Set the show static trihedron flag
 */
-void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on) {
-  if(myShowStaticTrihedron != on) {
-    OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
-    if(!aView)
-      return;
-
-    OCCViewer_ViewPort3d* vp3d = aView->getViewPort();
-    if(vp3d) {
-      myShowStaticTrihedron = on;
-      vp3d->updateStaticTriedronVisibility();
-    }
-  }
+void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on)
+{
+  OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
+  if ( aView ) aView->showStaticTrihedron( on );
 }
 
 /*!
@@ -959,18 +932,7 @@ bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize
   if ( view3d.IsNull() )
     return false;
 
-  double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
-  double aMaxSide;
-
-  view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
-
-  if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() ||
-       Xmax == RealLast()  || Ymax == RealLast()  || Zmax == RealLast() )
-    return false;
-
-  aMaxSide = Xmax - Xmin;
-  if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
-  if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
+  double aMaxSide = computeSceneSize( view3d );
 
   // IPAL21687
   // The boundary box of the view may be initialized but nullified
@@ -984,8 +946,39 @@ bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize
   theSize = getTrihedron()->Size();
   theNewSize = aMaxSide*aSizeInPercents / 100.0;
 
-  return fabs( theNewSize - theSize ) > theSize * EPS ||
-         fabs( theNewSize - theSize) > theNewSize * EPS;
+  return fabs( theNewSize - theSize ) > theSize    * EPS ||
+         fabs( theNewSize - theSize ) > theNewSize * EPS;
+}
+
+/*!
+ * Compute scene size
+ */
+double OCCViewer_Viewer::computeSceneSize(const Handle(V3d_View)& view3d) const
+{
+  double aMaxSide = 0;
+  double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
+
+#if OCC_VERSION_LARGE > 0x06070100
+  Bnd_Box aBox = view3d->View()->MinMaxValues();
+  Xmin = aBox.CornerMin().X();
+  Ymin = aBox.CornerMin().Y();
+  Zmin = aBox.CornerMin().Z();
+  Xmax = aBox.CornerMax().X();
+  Ymax = aBox.CornerMax().Y();
+  Zmax = aBox.CornerMax().Z();
+#else
+  view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
+#endif
+
+  if ( Xmin != RealFirst() && Ymin != RealFirst() && Zmin != RealFirst() &&
+       Xmax != RealLast()  && Ymax != RealLast()  && Zmax != RealLast() )
+  {
+    aMaxSide = Xmax - Xmin;
+    if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
+    if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
+  }
+
+  return aMaxSide;
 }
 
 /*! 
@@ -1015,9 +1008,36 @@ void OCCViewer_Viewer::setSelectionOptions( bool isPreselectionEnabled, bool isS
 {
   myPreselectionEnabled = isPreselectionEnabled;
   mySelectionEnabled = isSelectionEnabled;
+  //clear current selection in the viewer
+  
+  if(!mySelectionEnabled) {
+    myAISContext->ClearSelected( Standard_True );
+  }
 }
 
-
+/*!
+  Creates clipping plane based on the incoming plane
+*/
+Handle(Graphic3d_ClipPlane) OCCViewer_Viewer::createClipPlane(const gp_Pln& thePlane, const Standard_Boolean theIsOn)
+{
+  Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane( thePlane );
+  aGraphic3dPlane->SetOn( theIsOn );
+  aGraphic3dPlane->SetCapping( Standard_True );
+
+  // load capping texture
+  QPixmap px( ":images/hatch.png" );
+  if( !px.isNull() ) {
+    const Handle(Image_PixMap) aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage() );
+    Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual( aPixmap );
+    if( aTexture->IsDone() ) {
+      aTexture->EnableModulate();
+      aTexture->EnableRepeat();
+      aTexture->GetParams()->SetScale( Graphic3d_Vec2( 0.01, 0.01 ) );
+      aGraphic3dPlane->SetCappingTexture( aTexture );
+    }
+  }
+  return aGraphic3dPlane;
+}
 /*!
   Applies clipping planes to clippable objects
 */
@@ -1029,16 +1049,18 @@ void OCCViewer_Viewer::setClipPlanes(ClipPlanesList theList)
 
   // 2. Create new clipping planes
   ClipPlanesList::iterator inIt = theList.begin();
-  for (;inIt != theList.end(); inIt++ ) {
-    OCCViewer_ClipPlane plane;
-    plane = (*inIt);
-    myClipPlanes.push_back(plane);
-    gp_Pln aPln (gp_Pnt (plane.X, plane.Y, plane.Z),
-                gp_Dir (plane.Dx, plane.Dy, plane.Dz));
-    Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane();
-    aGraphic3dPlane->SetEquation (aPln);   
-    aGraphic3dPlane->SetOn(plane.IsOn);
-    myInternalClipPlanes.Add(aGraphic3dPlane);
+  for (;inIt != theList.end(); inIt++ )
+  {
+    OCCViewer_ClipPlane aPlane = *inIt;
+
+    double aDx = 0.0, aDy = 0.0, aDz = 0.0;
+    aPlane.OrientationToXYZ( aDx, aDy, aDz );
+
+    gp_Pnt anOrigin( aPlane.X, aPlane.Y, aPlane.Z );
+    gp_Dir aDirection( aDx, aDy, aDz );
+
+    myInternalClipPlanes.Append( createClipPlane( gp_Pln( anOrigin, aDirection ), aPlane.IsOn ) );
+    myClipPlanes.push_back( aPlane );
   }
 
   // 3. Apply clipping planes