Salome HOME
updated copyright message
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 3f546a8..322c869
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -28,6 +28,8 @@
 
 #include <SUIT_ViewManager.h>
 #include <SUIT_ViewModel.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
 
 #include <QColor>
 #include <QFileInfo>
 #include <QPaintEvent>
 #include <QResizeEvent>
 #include <QApplication>
+#include <QTimer>
 
-#include <Visual3d_View.hxx>
-#include <V3d_Viewer.hxx>
-
-#if OCC_VERSION_LARGE > 0x06070100
 #include <V3d_View.hxx>
-#else
-#include <V3d_PerspectiveView.hxx>
-#include <V3d_OrthographicView.hxx>
-#endif
 
 #include "utilities.h"
 
 #if defined WIN32
 #include <WNT_Window.hxx>
 #else
-#include <Xw_Window.hxx>
+//#include <Xw_Window.hxx>
 #endif
 
 static double rx = 0.;
@@ -68,27 +63,18 @@ static Standard_Boolean zRotation = Standard_False;
 */
 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView  type )
   : OCCViewer_ViewPort( parent ),
-    myScale( 1.0 ),
     myBusy( true ),
+    myScale( 1.0 ),
     myIsAdvancedZoomingEnabled( false )
 {
   // VSR: 01/07/2010 commented to avoid SIGSEGV at SALOME exit
   //selectVisualId();
 
-#if OCC_VERSION_LARGE > 0x06070100
   myActiveView = new V3d_View( viewer, type );
-#else
-  if ( type == V3d_ORTHOGRAPHIC ) {
-    myOrthoView = new V3d_OrthographicView( viewer );
-    myActiveView = myOrthoView;
-    myPerspView = 0;
-  } else {
-    myPerspView = new V3d_PerspectiveView( viewer );
-    myActiveView = myPerspView;
-  }
-#endif
 
-  setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
+  setDefaultParams();
+
+  myCursor = NULL;
 }
 
 /*!
@@ -96,7 +82,13 @@ OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_V
 */
 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
 {
-  emit vpClosed();
+  if ( myCursor )
+  {
+    delete myCursor;
+    myCursor = NULL;
+  }
+
+  emit vpClosed(this);
   Handle(V3d_View) aView = activeView();
   if (!aView.IsNull())
     aView->Remove();
@@ -134,17 +126,7 @@ bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
       view->View()->Deactivate();
   }
 
-  /* create static trihedron (16551: EDF PAL 501) */
-  OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
-  if ( aVW ) {
-    OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
-    if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){
-      view->ZBufferTriedronSetup();
-      view->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
-    }
-  }
-
-  emit( vpMapped() );
+  emit( vpMapped(this) );
 
   return true;
 }
@@ -234,40 +216,16 @@ bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
   refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
   refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
   refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
-#if OCC_VERSION_LARGE <= 0x06070100
-  refView->Center( x, y ); tgtView->SetCenter( x, y );
-#endif
   tgtView->SetScale( refView->Scale() );
   tgtView->SetTwist( refView->Twist() );
 
   /* update */
   tgtView->Update();
   tgtView->SetImmediateUpdate( Standard_True );
-  tgtView->ZFitAll();
-  return true;
-}
 
-/*!
-  Returns Z-size of this view. [ public ]
-*/
-double OCCViewer_ViewPort3d::getZSize() const
-{
-  if ( !activeView().IsNull() )
-    return activeView()->ZSize();
-  return 0;
+  return true;
 }
 
-/*!
-  Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
-*/
-void OCCViewer_ViewPort3d::setZSize( double zsize )
-{
-  myActiveView->SetZSize( zsize );
-  /*    if ( !myOrthoView.IsNull() )
-        myOrthoView->SetZSize( zsize );
-        if ( !myPerspView.IsNull() )
-        myPerspView->SetZSize( zsize );*/
-}
 
 /*!
   Get axial scale to the view
@@ -323,22 +281,6 @@ void OCCViewer_ViewPort3d::updateBackground()
   if ( activeView().IsNull() ) return;
   if ( !myBackground.isValid() ) return;
 
-  // VSR: Important note on below code.
-  // In OCCT (in version 6.5.2), things about the background drawing
-  // are not straightforward and not clearly understandable:
-  // - Horizontal gradient is drawn vertically (!), well ok, from top side to bottom one.
-  // - Vertical gradient is drawn horizontally (!), from right side to left one (!!!).
-  // - First and second diagonal gradients are confused.
-  // - Image texture, once set, can not be removed (!).
-  // - Texture image fill mode Aspect_FM_NONE is not taken into account (and means the same
-  //   as Aspect_FM_CENTERED).
-  // - The only way to cancel gradient background (and get back to single colored) is to
-  //   set gradient background style to Aspect_GFM_NONE while passing two colors is also needed
-  //   (see V3d_View::SetBgGradientColors() function).
-  // - Also, it is impossible to draw texture image above the gradiented background (only above
-  //   single-colored).
-  // In OCCT 6.5.3 all above mentioned problems are fixed; so, above comment should be removed as soon
-  // as SALOME is migrated to OCCT 6.5.3. The same concerns #ifdef statements in the below code
   switch ( myBackground.mode() ) {
   case Qtx::ColorBackground:
     {
@@ -347,13 +289,8 @@ void OCCViewer_ViewPort3d::updateBackground()
        // Unset texture should be done here
        // ...
        Quantity_Color qCol( c.red()/255., c.green()/255., c.blue()/255., Quantity_TOC_RGB );
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
        activeView()->SetBgGradientStyle( Aspect_GFM_NONE ); // cancel gradient background
        activeView()->SetBgImageStyle( Aspect_FM_NONE );     // cancel texture background
-#else
-       // cancel gradient background (in OCC before v6.5.3 the only way to do this is to set it to NONE type passing arbitrary colors as parameters)
-       activeView()->SetBgGradientColors( qCol, qCol, Aspect_GFM_NONE );
-#endif
        // then change background color
        activeView()->SetBackgroundColor( qCol );
        // update viewer
@@ -375,38 +312,16 @@ void OCCViewer_ViewPort3d::updateBackground()
        activeView()->SetBgImageStyle( Aspect_FM_NONE );    // cancel texture background
        switch ( type ) {
        case OCCViewer_Viewer::HorizontalGradient:
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
          activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
-#else
-         // in OCCT before v6.5.3, to draw horizontal gradient it's necessary to use Aspect_GFM_VER type
-         // and interchange the colors
-         activeView()->SetBgGradientColors( qCol2, qCol1, Aspect_GFM_VER, Standard_True );
-#endif
          break;
        case OCCViewer_Viewer::VerticalGradient:
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
          activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_VER, Standard_True );
-#else
-         // in OCCT before v6.5.3, to draw vertical gradient it's necessary to use Aspect_GFM_HOR type
-         activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
-#endif
          break;
        case OCCViewer_Viewer::Diagonal1Gradient:
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
          activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
-#else
-         // in OCCT before v6.5.3, to draw 1st dialognal gradient it's necessary to use Aspect_GFM_DIAG2 type
-         // and interchange the colors
-         activeView()->SetBgGradientColors( qCol2, qCol1, Aspect_GFM_DIAG2, Standard_True );
-#endif
          break;
        case OCCViewer_Viewer::Diagonal2Gradient:
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
          activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG2, Standard_True );
-#else
-         // in OCCT before v6.5.3, to draw 2nd dialognal gradient it's necessary to use Aspect_GFM_DIAG1 type
-         activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
-#endif
          break;
        case OCCViewer_Viewer::Corner1Gradient:
          activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER1, Standard_True );
@@ -434,9 +349,6 @@ void OCCViewer_ViewPort3d::updateBackground()
   default:
     break;
   }
-#if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
-  // VSR: In OCCT before v6.5.3 below code can't be used because of very ugly bug - it has been impossible to
-  // clear the background texture image as soon as it was once set to the viewer.
   if ( myBackground.isTextureShown() ) {
     QString fileName;
     int textureMode = myBackground.texture( fileName );
@@ -445,13 +357,13 @@ void OCCViewer_ViewPort3d::updateBackground()
       // set texture image: file name and fill mode
       switch ( textureMode ) {
       case Qtx::CenterTexture:
-       activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_CENTERED );
+       activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_CENTERED );
        break;
       case Qtx::TileTexture:
-       activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_TILED );
+       activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_TILED );
        break;
       case Qtx::StretchTexture:
-       activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_STRETCH );
+       activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_STRETCH );
        break;
       default:
        break;
@@ -459,7 +371,6 @@ void OCCViewer_ViewPort3d::updateBackground()
       activeView()->Update();
     }
   }
-#endif
 }
 
 /*!
@@ -487,10 +398,8 @@ void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
 */
 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
 {
-#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
   if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
     activeView()->StartZoomAtPoint( x, y );
-#endif
 }
 
 /*!
@@ -502,11 +411,9 @@ void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
     // as OCCT respects a sign of only dx,
     // but we want both signes to be taken into account
     //activeView()->Zoom( x0, y0, x, y );
-#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
     if ( isAdvancedZoomingEnabled() )
       activeView()->ZoomAtPoint( x0, y0, x, y );
     else
-#endif
       activeView()->Zoom( x0 + y0, 0, x + y, 0 );
     emit vpTransformed( this );
   }
@@ -547,7 +454,7 @@ void OCCViewer_ViewPort3d::startRotation( int x, int y,
     //activeView()->Gravity(gx,gy,gz);
 
     switch ( theRotationPointType ) {
-    case OCCViewer_ViewWindow::GRAVITY:
+    case OCCViewer_ViewWindow::BBCENTER:
       activeView()->StartRotation( x, y, 0.45 );
       break;
     case OCCViewer_ViewWindow::SELECTED:
@@ -562,7 +469,7 @@ void OCCViewer_ViewPort3d::startRotation( int x, int y,
                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
                             Standard_True );
 
-      Quantity_Ratio zRotationThreshold;
+      Standard_Real zRotationThreshold;
       zRotation = Standard_False;
       zRotationThreshold = 0.45;
       if( zRotationThreshold > 0. ) {
@@ -575,7 +482,8 @@ void OCCViewer_ViewPort3d::startRotation( int x, int y,
     default:
       break;
     }
-    activeView()->DepthFitAll();
+    // VSR: 10.06.2015: next line commented out - causes ugly blinking on starting rotation with Perspective projection mode
+    //activeView()->DepthFitAll();
   }
 }
 
@@ -588,7 +496,7 @@ void OCCViewer_ViewPort3d::rotate( int x, int y,
 {
   if ( !activeView().IsNull() ) {
     switch ( theRotationPointType ) {
-    case OCCViewer_ViewWindow::GRAVITY:
+    case OCCViewer_ViewWindow::BBCENTER:
       activeView()->Rotation( x, y );
       break;
     case OCCViewer_ViewWindow::SELECTED:
@@ -622,10 +530,6 @@ void OCCViewer_ViewPort3d::rotate( int x, int y,
 void OCCViewer_ViewPort3d::endRotation()
 {
   if ( !activeView().IsNull() ) {
-    activeView()->ZFitAll( 1.0 );
-#if OCC_VERSION_LARGE <= 0x06070100
-    activeView()->SetZSize( 0.0 );
-#endif
     activeView()->Update();
     emit vpTransformed( this );
   }
@@ -642,10 +546,9 @@ void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
     mapView( activeView() );
 #endif
   if ( !myWindow.IsNull() ) {
-    QApplication::syncX();
-    QRect rc = e->rect();
-    if ( !myPaintersRedrawing )
-      activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
+    if ( !myPaintersRedrawing ) {
+      activeView()->Redraw();
+    }
   }
   OCCViewer_ViewPort::paintEvent( e );
   myBusy = false;
@@ -656,20 +559,27 @@ void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
 */
 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
 {
-#ifdef WIN32
-  /* Win32 : map before first show to avoid flicker */
+  /* Map before first show to avoid flicker */
   if ( !mapped( activeView() ) )
     mapView( activeView() );
-#endif
-  QApplication::syncX();
-  if ( !activeView().IsNull() )
+  QTimer::singleShot( 0, this, SLOT( repaintViewAfterMove() ) );
+  emit vpResizeEvent( e );
+}
+
+/*!
+  Moved the viewport
+*/
+void OCCViewer_ViewPort3d::repaintViewAfterMove( )
+{
+  if ( !activeView().IsNull() ){
     activeView()->MustBeResized();
+  }
 }
 
 /*!
   Fits all objects in view. [ virtual protected ]
 */
-void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
+void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool /*withZ*/, bool upd )
 {
   if ( activeView().IsNull() )
     return;
@@ -679,14 +589,8 @@ void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
 
   Standard_Real margin = 0.01;
   
-#if OCC_VERSION_LARGE > 0x06070100
   activeView()->FitAll( margin, upd );
-  if(withZ)
-    activeView()->ZFitAll();
-#else 
-  activeView()->FitAll( margin, withZ, upd );
-#endif
-  activeView()->SetZSize(0.);
+
   emit vpTransformed( this );
 }
 
@@ -794,13 +698,7 @@ bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
     Handle(V3d_View) aView3d = getView();
     Handle(V3d_View) aRefView3d = vp3d->getView();
     aView3d->SetImmediateUpdate( Standard_False );
-#if OCC_VERSION_LARGE > 0x06070100
     aView3d->Camera()->Copy( aRefView3d->Camera() );
-#else
-    aView3d->SetViewMapping( aRefView3d->ViewMapping() );
-    aView3d->SetViewOrientation( aRefView3d->ViewOrientation() );
-#endif
-    aView3d->ZFitAll();
     aView3d->SetImmediateUpdate( Standard_True );
     aView3d->Update();
     blockSignals( blocked );
@@ -812,18 +710,58 @@ bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
 /*
  * Show/Hide static triedron
  */
-void OCCViewer_ViewPort3d::updateStaticTriedronVisibility() {
-  OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
-  if ( aVW ) {
-    OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
-    Handle(V3d_View) aView = activeView();
-    if ( aViewModel ){
-      if(aViewModel->isStaticTrihedronDisplayed()) {
-       aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
-      } else {
-       aView->TriedronErase();
-      }
-      aView->Update();
-    }
+void OCCViewer_ViewPort3d::showStaticTrihedron( bool on )
+{
+  Handle(V3d_View) aView = activeView();
+  if ( !aView ) return;
+  
+  if ( on ) {
+    aView->ZBufferTriedronSetup();
+    aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
+  } else {
+    aView->TriedronErase();
   }
+  aView->Update();
+}
+
+/*
+ * Create default cursor with a specific shape
+ */
+void OCCViewer_ViewPort3d::setDefaultCursor( Qt::CursorShape theCursorShape )
+{
+  if ( !myCursor )
+    myCursor = new QCursor();
+
+  myCursor->setShape( theCursorShape );
+}
+
+/*
+ * Get default cursor with a specific shape
+ */
+QCursor* OCCViewer_ViewPort3d::getDefaultCursor() const
+{
+  return myCursor;
+}
+
+/*
+ * Set default parameters from preferences
+ */
+void OCCViewer_ViewPort3d::setDefaultParams()
+{
+  setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
+
+  // get ray tracing parameters from preferences
+  int aDepth = SUIT_Session::session()->resourceMgr()->integerValue( "OCCViewer", "rt_depth", 3 );
+  bool aReflection = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_reflection", true );
+  bool anAntialiasing = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_antialiasing", false );
+  bool aShadow = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_shadow", true );
+  bool aTransparentShadow = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_trans_shadow", true );
+
+  Graphic3d_RenderingParams& aParams = myActiveView->ChangeRenderingParams();
+  aParams.RaytracingDepth = aDepth;
+  aParams.IsReflectionEnabled = aReflection;
+  aParams.IsAntialiasingEnabled = anAntialiasing;
+  aParams.IsShadowEnabled = aShadow;
+  aParams.IsTransparentShadowEnabled = aTransparentShadow;
+  myActiveView->Redraw();
 }