Salome HOME
refs #550: fix crash when myObject is NULL
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_Displayer.cxx
index 39cb1f54f1e2758e6a3bb9d96a477c8a6e4a8c20..c91247a5a55f7b8eb3c4b52e61c2504ab3bc863e 100644 (file)
@@ -1,12 +1,8 @@
-// Copyright (C) 2007-2013  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
-//
+// Copyright (C) 2014-2015  EDF-R&D
 // 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 "HYDROGUI_PrsZoneDriver.h"
 #include "HYDROGUI_Tool.h"
 
-#include <CurveCreator_Utils.h>
+#include <CurveCreator_Utils.hxx>
 
+#include <LightApp_Application.h>
 #include <SVTK_ViewWindow.h>
 #include <OCCViewer_ViewWindow.h>
 #include <OCCViewer_ViewPort3d.h>
+#include <SUIT_ViewManager.h>
 
 #include <vtkRenderWindowInteractor.h>
 #include <vtkRenderer.h>
@@ -47,7 +45,8 @@
 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
 
 HYDROGUI_Displayer::HYDROGUI_Displayer( HYDROGUI_Module* theModule )
-: HYDROGUI_AbstractDisplayer( theModule )
+: HYDROGUI_AbstractDisplayer( theModule ),
+  myXPosition( -1 ), myYPosition( -1 ), myIsPositionSaved( false )
 {
 }
 
@@ -236,9 +235,55 @@ QString HYDROGUI_Displayer::GetType() const
   return GraphicsView_Viewer::Type();
 }
 
-#include <iostream>
+void HYDROGUI_Displayer::SaveCursorViewPosition( SUIT_ViewWindow* theViewWindow )
+{
+  myIsPositionSaved = false;
+  myXPosition = 0;
+  myYPosition = 0;
+
+  SUIT_ViewWindow* aViewWindow = theViewWindow;
+  if ( !theViewWindow ) {
+    SUIT_ViewManager* aViewMgr = module()->getApp()->activeViewManager();
+    aViewWindow = aViewMgr ? aViewMgr->getActiveView() : 0;
+    if ( !aViewWindow )
+      return;
+  }
+  
+  OCCViewer_ViewWindow* anOCCViewWindow = 
+    dynamic_cast<OCCViewer_ViewWindow*>( aViewWindow );
+  if ( anOCCViewWindow ) {
+    // Get the selected point coordinates
+    OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
+    if ( aViewPort ) {
+      QPoint aViewPos = aViewPort->mapFromGlobal( QCursor::pos() );
+      myXPosition = aViewPos.x();
+      myYPosition = aViewPos.y();
+      myIsPositionSaved = true;
+    }
+  }
+  else {
+    SVTK_ViewWindow* aVTKViewWindow = 
+      dynamic_cast<SVTK_ViewWindow*>(aViewWindow);
+    if ( aVTKViewWindow ) {
+      vtkRenderer* aRen = aVTKViewWindow->getRenderer();
+      if ( aRen )
+      {
+        vtkCamera* aCamera = aRen->GetActiveCamera();
+        double* aNormal = aCamera->GetViewPlaneNormal();
+        vtkRenderWindowInteractor* anInteractor = aVTKViewWindow->getInteractor();
+        if ( anInteractor )
+        {
+          anInteractor->GetLastEventPosition( myXPosition, myYPosition );
+          myIsPositionSaved = true;
+        }
+      }
+    }
+  }
+  if (!myIsPositionSaved)
+    int aValue = 0;
+}
+
 bool HYDROGUI_Displayer::GetCursorViewCoordinates( SUIT_ViewWindow* theViewWindow,
-                                                   const QPoint& theCursorPos,
                                                    double& theXCoordinate,
                                                    double& theYCoordinate,
                                                    double& theZCoordinate )
@@ -246,9 +291,8 @@ bool HYDROGUI_Displayer::GetCursorViewCoordinates( SUIT_ViewWindow* theViewWindo
   theXCoordinate = 0;
   theYCoordinate = 0;
   theZCoordinate = 0;
-  
   bool doShow = false;
-  if ( !theViewWindow )
+  if ( !theViewWindow || !myIsPositionSaved )
     return doShow;
   
   OCCViewer_ViewWindow* anOCCViewWindow = 
@@ -259,64 +303,52 @@ bool HYDROGUI_Displayer::GetCursorViewCoordinates( SUIT_ViewWindow* theViewWindo
     if ( !aViewPort ) {
       return doShow;
     }
-    QPoint aViewPos = aViewPort->mapFromGlobal( theCursorPos );
-    gp_Pnt aPnt = CurveCreator_Utils::ConvertClickToPoint( aViewPos.x(), aViewPos.y(),
+    gp_Pnt aPnt = CurveCreator_Utils::ConvertClickToPoint( myXPosition, myYPosition,
                                                            aViewPort->getView() );
     theXCoordinate = aPnt.X();
     theYCoordinate = aPnt.Y();
-    //std::cout << "Coordinates: " << theCursorPos.x() << ", " << theCursorPos.y() << std::endl;
     doShow = true;
   } 
   else
   {
-    SVTK_ViewWindow* aViewWindow = 
+    SVTK_ViewWindow* aVTKViewWindow = 
       dynamic_cast<SVTK_ViewWindow*>(theViewWindow);
-    if ( aViewWindow ) {
-      vtkRenderer* aRen = aViewWindow->getRenderer();
+    if ( aVTKViewWindow ) {
+      vtkRenderer* aRen = aVTKViewWindow->getRenderer();
       if ( aRen )
       {
         vtkCamera* aCamera = aRen->GetActiveCamera();
         double* aNormal = aCamera->GetViewPlaneNormal();
-        int event_x, event_y;
-        vtkRenderWindowInteractor* anInteractor = aViewWindow->getInteractor();
-        if ( anInteractor )
-        {
-          anInteractor->GetLastEventPosition(event_x, event_y);
-          // Use a WorldPicker to get current coords
-          //std::cout << "Coordinates: " << theCursorPos.x() << ", " << theCursorPos.y() << std::endl;
-          //SVTK_RenderWindowInteractor* anInteractor = 
-          //std::cout << "VTK Coordinates: " << event_x << ", " << event_y << std::endl;
-          myPicker->Pick( event_x, event_y, 0, aRen );
-          double* aCoords = myPicker->GetPickPosition();
-          /////////////////////// Use the same algorithm as for OCC
-          double X, Y, Z;
-          double aXp, aYp, aZp;
-          double Vx, Vy, Vz;
-          X = aCoords[0];
-          Y = aCoords[1];
-          Z = aCoords[2];
-          Vx = aNormal[0];
-          Vy = aNormal[1];
-          Vz = aNormal[2];
-          Standard_Real aPrec = LOCAL_SELECTION_TOLERANCE;
-          if ( fabs( Vz ) > aPrec ) {
-            double aT = -Z/Vz;
-            aXp = X + aT*Vx;
-            aYp = Y + aT*Vy;
-            aZp = Z + aT*Vz;
-          }
-          else { // Vz = 0 - the eyed plane is orthogonal to Z plane - XOZ, or YOZ
-            aXp = aYp = aZp = 0;
-            if ( fabs( Vy ) < aPrec ) // Vy = 0 - the YOZ plane
-              aYp = Y;
-            else if ( fabs( Vx ) < aPrec ) // Vx = 0 - the XOZ plane
-              aXp = X;
-          }
-          /////////////////////////
-          theXCoordinate = aXp;
-          theYCoordinate = aYp;
-          doShow = true;
+        myPicker->Pick( myXPosition, myYPosition, 0, aRen );
+        double* aCoords = myPicker->GetPickPosition();
+        /////////////////////// Use the same algorithm as for OCC
+        double X, Y, Z;
+        double aXp, aYp, aZp;
+        double Vx, Vy, Vz;
+        X = aCoords[0];
+        Y = aCoords[1];
+        Z = aCoords[2];
+        Vx = aNormal[0];
+        Vy = aNormal[1];
+        Vz = aNormal[2];
+        Standard_Real aPrec = LOCAL_SELECTION_TOLERANCE;
+        if ( fabs( Vz ) > aPrec ) {
+          double aT = -Z/Vz;
+          aXp = X + aT*Vx;
+          aYp = Y + aT*Vy;
+          aZp = Z + aT*Vz;
+        }
+        else { // Vz = 0 - the eyed plane is orthogonal to Z plane - XOZ, or YOZ
+          aXp = aYp = aZp = 0;
+          if ( fabs( Vy ) < aPrec ) // Vy = 0 - the YOZ plane
+            aYp = Y;
+          else if ( fabs( Vx ) < aPrec ) // Vx = 0 - the XOZ plane
+            aXp = X;
         }
+        /////////////////////////
+        theXCoordinate = aXp;
+        theYCoordinate = aYp;
+        doShow = true;
       }
     } 
   }