Salome HOME
Merge remote branch 'origin/V7_dev' into V8_0_0_BR
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
index 19203799f55cf7100573ffd2f560d2e9837d8abf..8ad6be95c8e4e742427b3ab5a6523c3c6fc3dca8 100755 (executable)
 #include "OCCViewer_AxialScaleDlg.h"
 #include "OCCViewer_CubeAxesDlg.h"
 #include "OCCViewer_ClippingDlg.h"
+#include "OCCViewer_RayTracingDlg.h"
+#include "OCCViewer_EnvTextureDlg.h"
+#include "OCCViewer_LightSourceDlg.h"
+#include "OCCViewer_Utilities.h"
 
 #include <SUIT_Desktop.h>
 #include <SUIT_Session.h>
@@ -116,6 +120,9 @@ static QEvent* l_mbPressEvent = 0;
 #undef KeyPress
 #endif
 
+// Enable ray tracing features
+#define ENABLE_RAY_TRACING
+
 const char* imageZoomCursor[] = {
 "32 32 3 1",
 ". c None",
@@ -243,6 +250,7 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop*     theDesktop,
   myModel = theModel;
   myRestoreFlag = 0;
   myEnableDrawMode = false;
+  myDrawRectEnabled = true;
   myDrawRect=false;
   updateEnabledDrawMode();
   myScalingDlg = 0;
@@ -385,7 +393,9 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
               ic->HilightPreviousDetected( myViewPort->getView() );
             }
           }
-        } else {
+        }
+        else {
+          emit vpTransformationStarted ( ZOOMVIEW );
           myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
           double delta = (double)( aEvent->delta() ) / ( 15 * 8 );
           int x  = aEvent->x();
@@ -394,6 +404,7 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
           int y1 = (int)( aEvent->y() + height()*delta/100 );
           myViewPort->zoom( x, y, x1, y1 );
           myViewPort->getView()->ZFitAll();
+          emit vpTransformationFinished ( ZOOMVIEW );
         }
       }
       return true;
@@ -417,13 +428,25 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
   return SUIT_ViewWindow::eventFilter(watched, e);
 }
 
+/*!
+  \brief Enable / disable draw rect (rubber band) mode
+*/
+bool OCCViewer_ViewWindow::enableDrawMode( bool on )
+{
+  bool prev = myDrawRectEnabled;
+  myDrawRectEnabled = on;
+  updateEnabledDrawMode();
+  return prev;
+}
+
 /*!
   \brief Update state of enable draw mode state.
 */
 void OCCViewer_ViewWindow::updateEnabledDrawMode()
 {
+  myEnableDrawMode = myDrawRectEnabled;
   if ( myModel )
-    myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
+    myEnableDrawMode = myEnableDrawMode && myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
 }
 
 /*!
@@ -562,7 +585,7 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent )
     }
     /* notify that we start a transformation */
     if ( transformRequested() )
-            emit vpTransformationStarted ( myOperation );
+      emit vpTransformationStarted ( myOperation );
   }
   if ( transformRequested() )
     setTransformInProcess( true );
@@ -671,9 +694,8 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou
 
   for( ; aStructureIt.More(); aStructureIt.Next() ) {
     const Handle(Graphic3d_Structure)& aStructure = aStructureIt.Key();
-    if ( aStructure->IsEmpty() ) {
+    if ( aStructure->IsEmpty() || !aStructure->IsVisible() || aStructure->CStructure()->IsForHighlight )
       continue;
-    }
 
 #if OCC_VERSION_LARGE > 0x06070100
     Bnd_Box aBox = aStructure->MinMaxValues();
@@ -1159,6 +1181,8 @@ void OCCViewer_ViewWindow::createActions()
     return;
 
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  if( !aResMgr )
+    return;
 
   QtxAction* aAction;
 
@@ -1431,6 +1455,28 @@ void OCCViewer_ViewWindow::createActions()
 
   // Synchronize View
   toolMgr()->registerAction( synchronizeAction(), SynchronizeId );
+#ifdef ENABLE_RAY_TRACING
+  // Ray tracing
+  aAction = new QtxAction( tr("MNU_RAY_TRACING"), aResMgr->loadPixmap( "OCCViewer", tr("ICON_OCCVIEWER_RAY_TRACING") ),
+                           tr("MNU_RAY_TRACING"), 0, this );
+  aAction->setStatusTip( tr("DSC_RAY_TRACING") );
+  connect( aAction, SIGNAL( triggered() ), this, SLOT( onRayTracing() ) );
+  toolMgr()->registerAction( aAction, RayTracingId );
+
+  // Environment texture
+  aAction = new QtxAction( tr("MNU_ENV_TEXTURE"), aResMgr->loadPixmap( "OCCViewer", tr("ICON_OCCVIEWER_ENV_TEXTURE") ),
+                           tr("MNU_ENV_TEXTURE"), 0, this );
+  aAction->setStatusTip( tr("DSC_ENV_TEXTURE") );
+  connect( aAction, SIGNAL( triggered() ), this, SLOT( onEnvTexture() ) );
+  toolMgr()->registerAction( aAction, EnvTextureId );
+
+  // Light source
+  aAction = new QtxAction( tr("MNU_LIGHT_SOURCE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_LIGHT_SOURCE" ) ),
+                           tr( "MNU_LIGHT_SOURCE" ), 0, this );
+  aAction->setStatusTip( tr("DSC_LIGHT_SOURCE") );
+  connect( aAction, SIGNAL( triggered() ), this, SLOT( onLightSource() ) );
+  toolMgr()->registerAction( aAction, LightSourceId );
+#endif
 }
 
 /*!
@@ -1520,6 +1566,11 @@ void OCCViewer_ViewWindow::createToolBar()
 
   toolMgr()->append( MaximizedId, tid );
   toolMgr()->append( SynchronizeId, tid );
+#ifdef ENABLE_RAY_TRACING
+  toolMgr()->append( RayTracingId, tid );
+  toolMgr()->append( EnvTextureId, tid );
+  toolMgr()->append( LightSourceId, tid );
+#endif
 }
 
 /*!
@@ -2096,7 +2147,7 @@ void OCCViewer_ViewWindow::onSwitchInteractionStyle( bool on )
 
   // update action state if method is called outside
   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchInteractionStyleId ) );
-  if ( a->isChecked() != on )
+  if ( a && a->isChecked() != on )
     a->setChecked( on );
 }
 
@@ -2109,7 +2160,7 @@ void OCCViewer_ViewWindow::onSwitchZoomingStyle( bool on )
 
   // update action state if method is called outside
   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchZoomingStyleId ) );
-  if ( a->isChecked() != on )
+  if ( a && a->isChecked() != on )
     a->setChecked( on );
 }
 
@@ -2217,17 +2268,20 @@ bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img,
                                              const QString& fileName,
                                              const QString& format )
 {
+  bool res = false;
+  QApplication::setOverrideCursor( Qt::WaitCursor );
   if ( format != "PS" && format != "EPS")
-    return SUIT_ViewWindow::dumpViewToFormat( img, fileName, format );
+   res = myViewPort->getView()->Dump( fileName.toStdString().c_str() );
 
   Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
 
   if (format == "PS")
-    a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript);
+    res = a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript);
   else if (format == "EPS")
-    a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript);
+    res = a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript);
 
-  return true;
+  QApplication::restoreOverrideCursor();
+  return res;
 }
 
 
@@ -2525,6 +2579,58 @@ 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 );
+
+  // ray tracing parameters
+  Graphic3d_RenderingParams rendParams = this->getViewPort()->getView()->RenderingParams();
+  if ( rendParams.Method == Graphic3d_RM_RAYTRACING ) {
+    QString RayTracing = "rayTracing=";
+    RayTracing += QString( "rtDepth~%1;" ).arg( rendParams.RaytracingDepth );
+    RayTracing += QString( "rtReflection~%1;" ).arg( rendParams.IsReflectionEnabled );
+    RayTracing += QString( "rtAntialiasing~%1;" ).arg( rendParams.IsAntialiasingEnabled );
+    RayTracing += QString( "rtShadow~%1;" ).arg( rendParams.IsShadowEnabled );
+    RayTracing += QString( "rtTransShadow~%1;" ).arg( rendParams.IsTransparentShadowEnabled );
+    data << RayTracing;
+  }
+
+  // environment texture parameters
+  Handle(Graphic3d_TextureEnv) aTexture = this->getViewPort()->getView()->TextureEnv();
+  if ( !aTexture.IsNull() ) {
+    QString EnvTexture = "envTexture=";
+    if ( aTexture->Name() == Graphic3d_NOT_ENV_UNKNOWN ) {
+      TCollection_AsciiString aFileName;
+      aTexture->Path().SystemName( aFileName );
+      EnvTexture += QString( "etFile~%1;" ).arg( aFileName.ToCString() );
+    }
+    else
+      EnvTexture += QString( "etNumber~%1;" ).arg( aTexture->Name() );
+    data << EnvTexture;
+  }
+
+  // light source parameters
+  myModel->getViewer3d()->InitDefinedLights();
+  while ( myModel->getViewer3d()->MoreDefinedLights() )
+  {
+    Handle(V3d_Light) aLight = myModel->getViewer3d()->DefinedLight();
+    if ( aLight->Type() != V3d_AMBIENT ) {
+      QString LightSource = QString( "lightSource=" );
+      LightSource += QString( "lightType~%1;" ).arg( aLight->Type() );
+      double aX, aY, aZ;
+      if ( aLight->Type() == V3d_DIRECTIONAL )
+        Handle(V3d_DirectionalLight)::DownCast( aLight )->Direction( aX, aY, aZ );
+      else if ( aLight->Type() == V3d_POSITIONAL )
+        Handle(V3d_PositionalLight)::DownCast( aLight )->Position( aX, aY, aZ );
+      LightSource += QString( "lightX~%1;" ).arg( aX );
+      LightSource += QString( "lightY~%1;" ).arg( aY );
+      LightSource += QString( "lightZ~%1;" ).arg( aZ );
+      LightSource += QString( "lightColorR~%1;" ).arg( aLight->Color().Red() );
+      LightSource += QString( "lightColorG~%1;" ).arg( aLight->Color().Green() );
+      LightSource += QString( "lightColorB~%1;" ).arg( aLight->Color().Blue() );
+      LightSource += QString( "lightHeadlight~%1;" ).arg( aLight->Headlight() );
+      data << LightSource;
+    }
+    myModel->getViewer3d()->NextDefinedLights();
+  }
+
   QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" );
   data << QString( "background=%1" ).arg( bg );
 
@@ -2643,6 +2749,81 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
       else if ( paramName == "gtTickmarkLengthX" ) params.gtTickmarkLengthX = paramValue.toInt();
       else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt();
       else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt();
+      else if ( paramName == "rayTracing" )
+      {
+        Graphic3d_RenderingParams& rendParams = this->getViewPort()->getView()->ChangeRenderingParams();
+        rendParams.Method = Graphic3d_RM_RAYTRACING;
+        QStringList rtData = paramValue.split( ';' );
+        foreach( QString rtParam, rtData )
+        {
+          QString rt_paramName  = rtParam.section( '~', 0, 0 ).trimmed();
+          QString rt_paramValue = rtParam.section( '~', 1, 1 ).trimmed();
+          if ( rt_paramName == "rtDepth" ) rendParams.RaytracingDepth = rt_paramValue.toInt();
+          else if ( rt_paramName == "rtReflection" ) rendParams.IsReflectionEnabled = rt_paramValue.toInt();
+          else if ( rt_paramName == "rtAntialiasing" ) rendParams.IsAntialiasingEnabled = rt_paramValue.toInt();
+          else if ( rt_paramName == "rtShadow" ) rendParams.IsShadowEnabled = rt_paramValue.toInt();
+          else if ( rt_paramName == "rtTransShadow" ) rendParams.IsTransparentShadowEnabled = rt_paramValue.toInt();
+        }
+      }
+      else if ( paramName == "envTexture" )
+      {
+        Handle(Graphic3d_TextureEnv) aTexture;
+        QStringList etData = paramValue.split( ';' );
+        foreach( QString etParam, etData )
+        {
+          QString et_paramName  = etParam.section( '~', 0, 0 ).trimmed();
+          QString et_paramValue = etParam.section( '~', 1, 1 ).trimmed();
+          if ( et_paramName == "etNumber" )
+            aTexture = new Graphic3d_TextureEnv( Graphic3d_NameOfTextureEnv( et_paramValue.toInt() ) );
+          else if ( et_paramName == "etFile" )
+            aTexture = new Graphic3d_TextureEnv( TCollection_AsciiString( et_paramValue.toStdString().c_str() ) );
+          Handle(V3d_View) aView = this->getViewPort()->getView();
+          aView->SetTextureEnv( aTexture );
+          aView->SetSurfaceDetail( V3d_TEX_ENVIRONMENT );
+        }
+      }
+      else if ( paramName == "lightSource" )
+      {
+        myModel->getViewer3d()->InitDefinedLights();
+        while ( myModel->getViewer3d()->MoreDefinedLights() )
+        {
+          Handle(V3d_Light) aLight = myModel->getViewer3d()->DefinedLight();
+          if( aLight->Type() != V3d_AMBIENT )
+            myModel->getViewer3d()->DelLight( aLight );
+          myModel->getViewer3d()->NextDefinedLights();
+        }
+        double aX, aY, aZ;
+        double cR, cG, cB;
+        V3d_TypeOfLight aType;
+        bool isHeadlight;
+        QStringList lsData = paramValue.split( ';' );
+        foreach( QString lsParam, lsData )
+        {
+          QString ls_paramName  = lsParam.section( '~', 0, 0 ).trimmed();
+          QString ls_paramValue = lsParam.section( '~', 1, 1 ).trimmed();
+          if ( ls_paramName == "lightType" ) aType = V3d_TypeOfLight( ls_paramValue.toInt() );
+          else if ( ls_paramName == "lightX" ) aX = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightY" ) aY = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightZ" ) aZ = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightColorR" ) cR = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightColorG" ) cG = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightColorB" ) cB = ls_paramValue.toDouble();
+          else if ( ls_paramName == "lightHeadlight" ) isHeadlight = ls_paramValue.toInt();
+        }
+        Quantity_Color aColor = Quantity_Color( cR, cG, cB, Quantity_TOC_RGB );
+        if( aType == V3d_DIRECTIONAL ) {
+          Handle(V3d_DirectionalLight) aLight = new V3d_DirectionalLight( myModel->getViewer3d() );
+          aLight->SetDirection( aX, aY, aZ );
+          aLight->SetColor( aColor );
+          aLight->SetHeadlight( isHeadlight );
+          myModel->getViewer3d()->SetLightOn( aLight );
+        }
+        else if( aType == V3d_POSITIONAL ) {
+          Handle(V3d_PositionalLight) aLight = new V3d_PositionalLight( myModel->getViewer3d(), aX, aY, aZ, aColor.Name() );
+          aLight->SetHeadlight( isHeadlight );
+          myModel->getViewer3d()->SetLightOn( aLight );
+        }
+      }
       else if ( paramName == "background" )        {
   QString bg = paramValue.replace( "$", "=" );
   bgData = Qtx::stringToBackground( bg );
@@ -3544,3 +3725,30 @@ void OCCViewer_ViewWindow::onClipping (bool theIsOn)
     }
   }
 }
+
+void OCCViewer_ViewWindow::onRayTracing()
+{
+  if( !OCCViewer_Utilities::isDialogOpened( this, OCCViewer_RayTracingDlg::getName() ) ) {
+    QDialog* aDlg = new OCCViewer_RayTracingDlg( this );
+    if ( aDlg != NULL )
+      aDlg->show();
+  }
+}
+
+void OCCViewer_ViewWindow::onEnvTexture()
+{
+  if( !OCCViewer_Utilities::isDialogOpened( this, OCCViewer_EnvTextureDlg::getName() ) ) {
+    QDialog* aDlg = new OCCViewer_EnvTextureDlg( this );
+    if ( aDlg != NULL )
+      aDlg->show();
+  }
+}
+
+void OCCViewer_ViewWindow::onLightSource()
+{
+  if( !OCCViewer_Utilities::isDialogOpened( this, OCCViewer_LightSourceDlg::getName() ) ) {
+    QDialog* aDlg = new OCCViewer_LightSourceDlg( this, myModel );
+    if ( aDlg != NULL )
+      aDlg->show();
+  }
+}