Salome HOME
Updated copyright comment
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
old mode 100755 (executable)
new mode 100644 (file)
index c61d8eb..23cf8b4
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  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
 #include <QPaintEvent>
 #include <QResizeEvent>
 #include <QApplication>
+#include <QTimer>
+#include <QDateTime>
 
-#include <Visual3d_View.hxx>
-#include <V3d_Viewer.hxx>
-
-#if OCC_VERSION_LARGE > 0x06070100
+#include <gp_Quaternion.hxx>
 #include <V3d_View.hxx>
-#else
-#include <V3d_PerspectiveView.hxx>
-#include <V3d_OrthographicView.hxx>
-#endif
 
 #include "utilities.h"
 
@@ -70,29 +65,21 @@ 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 ),
-    myIsAdvancedZoomingEnabled( false )
+    myScale( 1.0 ),
+    myIsAdvancedZoomingEnabled( false ),
+    myRotAngle( 0.0 ),
+    myIsRotating( 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
 
   setDefaultParams();
 
   myCursor = NULL;
+  myRotTimer = NULL;
 }
 
 /*!
@@ -100,6 +87,13 @@ OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_V
 */
 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
 {
+  if ( myRotTimer )
+  {
+    myRotTimer->stop();
+    delete myRotTimer;
+    myRotTimer = NULL;
+  }
+
   if ( myCursor )
   {
     delete myCursor;
@@ -234,40 +228,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
@@ -399,13 +369,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;
@@ -440,6 +410,9 @@ void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
 */
 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
 {
+  // if (myIsRotating)
+  //   stopRotation();
+
   if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
     activeView()->StartZoomAtPoint( x, y );
 }
@@ -449,6 +422,9 @@ void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
 */
 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
 {
+  // if (myIsRotating)
+  //   stopRotation();
+
   if ( !activeView().IsNull() ) {
     // as OCCT respects a sign of only dx,
     // but we want both signes to be taken into account
@@ -466,6 +442,9 @@ void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
 */
 void OCCViewer_ViewPort3d::setCenter( int x, int y )
 {
+  if (myIsRotating)
+    stopRotation();
+
   if ( !activeView().IsNull() ) {
     activeView()->Place( x, y, myScale );
     emit vpTransformed( this );
@@ -477,6 +456,9 @@ void OCCViewer_ViewPort3d::setCenter( int x, int y )
 */
 void OCCViewer_ViewPort3d::pan( int dx, int dy )
 {
+  if (myIsRotating)
+    stopRotation();
+
   if ( !activeView().IsNull() ) {
     activeView()->Pan( dx, dy, 1.0 );
     emit vpTransformed( this );
@@ -490,28 +472,36 @@ void OCCViewer_ViewPort3d::startRotation( int x, int y,
                                           int theRotationPointType,
                                           const gp_Pnt& theSelectedPoint )
 {
+  if (myIsRotating)
+    stopRotation();
+
   if ( !activeView().IsNull() ) {
-    //double gx, gy, gz;
-    //double gx = activeView()->gx;
-    //activeView()->Gravity(gx,gy,gz);
+
+    Standard_Real zRotationThreshold, X, Y;
+    sx = x; sy = y;
+    activeView()->Size(X,Y);
+    rx = Standard_Real(activeView()->Convert(X));
+    ry = Standard_Real(activeView()->Convert(Y));
+    gp_Pnt centerPnt;
 
     switch ( theRotationPointType ) {
-    case OCCViewer_ViewWindow::GRAVITY:
+    case OCCViewer_ViewWindow::BBCENTER:
+      centerPnt = activeView()->GravityPoint();
+      zRotation = Standard_False;
+      zRotationThreshold = 0.45;
+      if( zRotationThreshold > 0. ) {
+        Standard_Real dx = Abs(sx - rx/2.);
+        Standard_Real dy = Abs(sy - ry/2.);
+        Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
+        if( dx > dd || dy > dd ) zRotation = Standard_True;
+      }
       activeView()->StartRotation( x, y, 0.45 );
       break;
     case OCCViewer_ViewWindow::SELECTED:
-      sx = x; sy = y;
-
-      double X,Y;
-      activeView()->Size(X,Y);
-      rx = Standard_Real(activeView()->Convert(X));
-      ry = Standard_Real(activeView()->Convert(Y));
-
       activeView()->Rotate( 0., 0., 0.,
                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
                             Standard_True );
 
-      Quantity_Ratio zRotationThreshold;
       zRotation = Standard_False;
       zRotationThreshold = 0.45;
       if( zRotationThreshold > 0. ) {
@@ -538,7 +528,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:
@@ -572,15 +562,75 @@ 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 );
   }
 }
 
+/*!
+  Set the rotation axis and start automatic rotation
+*/
+void OCCViewer_ViewPort3d::setRotationAxis(const gp_Vec& theAxis, double theAngle, double theZAngle)
+{
+  myRotAxis.SetLocation(activeView()->GravityPoint());
+  if (zRotation) {
+    gp_Dir anAxisDir = activeView()->Camera()->Direction();
+    myRotAxis.SetDirection(anAxisDir.Reversed());
+    myRotAngle = theZAngle;
+  }
+  else {
+    myRotAxis.SetDirection(gp_Dir(theAxis));
+    myRotAngle = theAngle;
+  }
+  if (!myRotTimer) {
+    myRotTimer = new QTimer(this);
+    myRotTimer->setSingleShot(true);
+    connect(myRotTimer, SIGNAL(timeout()), this, SLOT(updateRotation()));
+  }
+  else
+    myRotTimer->stop();
+
+  myIsRotating = true;
+  myLastRender = QDateTime::currentMSecsSinceEpoch();
+  Handle(Graphic3d_Camera) aCamera = activeView()->Camera();
+  gp_Trsf trsfRot;
+  trsfRot.SetRotation (myRotAxis, myRotAngle);
+  aCamera->Transform(trsfRot);
+  activeView()->SetCamera(aCamera);
+  myRotTimer->start(20);
+}
+
+/*!
+  Stop the automatic rotation
+*/
+void OCCViewer_ViewPort3d::stopRotation()
+{
+  myIsRotating = false;
+  if (myRotTimer)
+    myRotTimer->stop();
+}
+
+/*!
+  Update the automatic rotation animation
+*/
+void OCCViewer_ViewPort3d::updateRotation()
+{
+  if (!myIsRotating)
+    return;
+
+  qint64 curTime = QDateTime::currentMSecsSinceEpoch();
+  double angle = myRotAngle * (curTime - myLastRender) / 100.;
+  Handle(Graphic3d_Camera) aCamera = activeView()->Camera();
+  gp_Trsf trsfRot;
+  trsfRot.SetRotation(myRotAxis, angle);
+  aCamera->Transform(trsfRot);
+  activeView()->SetCamera(aCamera);
+
+  myLastRender = curTime;
+  if (myRotTimer)
+    myRotTimer->start(20);
+}
+
 /*!
   Repaints the viewport. [ virtual protected ]
 */
@@ -592,12 +642,9 @@ void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
     mapView( activeView() );
 #endif
   if ( !myWindow.IsNull() ) {
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-    QApplication::syncX();
-#endif
-    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;
@@ -608,50 +655,41 @@ void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
 */
 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
 {
-#if defined WIN32 || QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
-  /* Win32 : map before first show to avoid flicker */
+  /* Map before first show to avoid flicker */
   if ( !mapped( activeView() ) )
     mapView( activeView() );
-#endif
-#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
-    QApplication::syncX();
-#endif
-  if ( !activeView().IsNull() )
-    activeView()->MustBeResized();
+  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;
 
+  if (myIsRotating)
+    stopRotation();
+
   if ( keepScale )
     myScale = activeView()->Scale();
 
   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 );
 }
 
@@ -660,6 +698,9 @@ void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
 */
 void OCCViewer_ViewPort3d::reset()
 {
+  if (myIsRotating)
+    stopRotation();
+
   //  double zsize = getZSize();
   if ( !activeView().IsNull() ) {
     activeView()->Reset();
@@ -676,6 +717,9 @@ void OCCViewer_ViewPort3d::rotateXY( double degrees )
   if ( activeView().IsNull() )
     return;
 
+  if (myIsRotating)
+    stopRotation();
+
   int x = width()/2, y = height()/2;
   double X, Y, Z;
   activeView()->Convert( x, y, X, Y, Z );
@@ -759,13 +803,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 );