Salome HOME
Copyright update 2022
[modules/gui.git] / src / SVTK / SVTK_Renderer.cxx
index 853ad34ca247067f531c2525e873c6dfaddbf36f..3d8aa0aa4d3c5ca4618d0cdbbcd9801c638c6e0b 100644 (file)
@@ -1,44 +1,43 @@
-//  SALOME VTKViewer : build VTK viewer into Salome desktop
+// Copyright (C) 2007-2022  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
+//
+// 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, or (at your option) any later version.
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  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. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+//  SALOME VTKViewer : build VTK viewer into Salome desktop
 //  File   :
 //  Author :
-//  Module :
-//  $Header$
 
 #include "SVTK_Renderer.h"
 
 #include "SVTK_Trihedron.h"
 #include "SVTK_CubeAxesActor2D.h"
-#include "SVTK_RectPicker.h"
+#include "SVTK_AreaPicker.h"
 
 #include "SALOME_Actor.h"
 #include "VTKViewer_Actor.h"
+#include "VTKViewer_Algorithm.h"
 #include "VTKViewer_Transform.h"
 #include "VTKViewer_Utilities.h"
+#include "VTKViewer_OpenGLRenderer.h"
 
 #include <vtkCamera.h>
-#include <vtkRenderer.h>
 #include <vtkTextProperty.h>
 #include <vtkObjectFactory.h>
 #include <vtkCallbackCommand.h>
@@ -48,6 +47,7 @@
 #include <vtkCellPicker.h>
 
 #include <vtkProperty.h>
+#include <vtkProp3DCollection.h>
 
 // undefining min and max because CASCADE's defines them and
 // it clashes with std::min(), std::max() included in utilities.h
 #undef max
 
 
-vtkStandardNewMacro(SVTK_Renderer);
+vtkStandardNewMacro(SVTK_Renderer)
 
 /*!
   Constructor
 */
 SVTK_Renderer
 ::SVTK_Renderer():
-  myDevice(vtkRenderer::New()),
-  myInteractor(NULL),
   myPriority(0.0),
   myEventCallbackCommand(vtkCallbackCommand::New()),
+  myDevice(VTKViewer_OpenGLRenderer::New()),
+  myInteractor(NULL),
+  myTransform(VTKViewer_Transform::New()),
   myPointPicker(vtkPointPicker::New()),
   myCellPicker(vtkCellPicker::New()),
-  myPointRectPicker(SVTK_RectPicker::New()),
-  myCellRectPicker(SVTK_RectPicker::New()),
+  myPointAreaPicker(SVTK_AreaPicker::New()),
+  myCellAreaPicker(SVTK_AreaPicker::New()),
   myPreHighlightProperty(vtkProperty::New()),
   myHighlightProperty(vtkProperty::New()),
-  myTransform(VTKViewer_Transform::New()),
   myCubeAxes(SVTK_CubeAxesActor2D::New()),
   myTrihedron(SVTK_Trihedron::New()),
   myTrihedronSize(105),
@@ -81,17 +81,15 @@ SVTK_Renderer
   myDevice->Delete();
   myTransform->Delete();
 
-  SetSelectionTolerance();
-
   myPointPicker->Delete();
   myCellPicker->Delete();
 
-  myPointRectPicker->Delete();
-  myPointRectPicker->PickFromListOn();
+  myPointAreaPicker->Delete();
+  myPointAreaPicker->PickFromListOn();
 
-  myCellRectPicker->Delete();
-  myCellRectPicker->PickFromListOn();
-  myCellRectPicker->PickPointsOff();
+  myCellAreaPicker->Delete();
+  myCellAreaPicker->PickFromListOn();
+  myCellAreaPicker->PickPointsOff();
 
   //SetPreselectionProp();
   myPreHighlightProperty->Delete();
@@ -107,12 +105,15 @@ SVTK_Renderer
   myHighlightProperty->SetLineWidth(SALOME_LINE_WIDTH+2);
   myHighlightProperty->SetRepresentationToPoints();
 
+  // Bug 0020123, note 0005217 - Problem with zoom
+  GetDevice()->SetNearClippingPlaneTolerance( 0.00001 );
+
   myTrihedron->Delete();
   myCubeAxes->Delete();
   myEventCallbackCommand->Delete();
 
   myTrihedron->AddToRender(GetDevice());
-  GetDevice()->AddProp(GetCubeAxes());
+  GetDevice()->AddViewProp(GetCubeAxes());
 
   myBndBox[0] = myBndBox[2] = myBndBox[4] = 0;
   myBndBox[1] = myBndBox[3] = myBndBox[5] = myTrihedron->GetSize();
@@ -143,14 +144,14 @@ SVTK_Renderer
   myEventCallbackCommand->SetClientData(this);
   myEventCallbackCommand->SetCallback(SVTK_Renderer::ProcessEvents);
   GetDevice()->AddObserver(vtkCommand::ConfigureEvent,
-                          myEventCallbackCommand.GetPointer(), 
-                          myPriority);
+                           myEventCallbackCommand.GetPointer(), 
+                           myPriority);
   GetDevice()->AddObserver(vtkCommand::ResetCameraEvent,
-                          myEventCallbackCommand.GetPointer(), 
-                          myPriority);
+                           myEventCallbackCommand.GetPointer(), 
+                           myPriority);
   GetDevice()->AddObserver(vtkCommand::ResetCameraClippingRangeEvent,
-                          myEventCallbackCommand.GetPointer(), 
-                          myPriority);
+                           myEventCallbackCommand.GetPointer(), 
+                           myPriority);
 }
 
 /*!
@@ -159,7 +160,8 @@ SVTK_Renderer
 SVTK_Renderer
 ::~SVTK_Renderer()
 {
-  vtkActorCollection* anActors = GetDevice()->GetActors();
+  VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
+  vtkActorCollection* anActors = aCopy.GetActors();
   vtkActorCollection* anActors2 = vtkActorCollection::New();
 
   anActors->InitTraversal();
@@ -186,9 +188,9 @@ SVTK_Renderer
 void 
 SVTK_Renderer
 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
-               unsigned long theEvent,
-               void* theClientData, 
-               void* vtkNotUsed(theCallData))
+                unsigned long theEvent,
+                void* theClientData, 
+                void* vtkNotUsed(theCallData))
 {
   SVTK_Renderer* self = reinterpret_cast<SVTK_Renderer*>(theClientData);
 
@@ -221,10 +223,11 @@ SVTK_Renderer
 void 
 SVTK_Renderer
 ::Initialize(vtkRenderWindowInteractor* theInteractor,
-            SVTK_Selector* theSelector)
+             SVTK_Selector* theSelector)
 {
   myInteractor = theInteractor;
   mySelector = theSelector;
+  SetSelectionTolerance();
 }
 
 /*!
@@ -232,7 +235,7 @@ SVTK_Renderer
 */
 void
 SVTK_Renderer
-::AddActor(VTKViewer_Actor* theActor)
+::AddActor(VTKViewer_Actor* theActor, bool theIsAdjustActors)
 {
   if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
     anActor->SetInteractor(myInteractor);
@@ -242,14 +245,17 @@ SVTK_Renderer
     anActor->SetPointPicker(myPointPicker.GetPointer());
     anActor->SetCellPicker(myCellPicker.GetPointer());
 
-    anActor->SetPointRectPicker(myPointRectPicker.GetPointer());
-    anActor->SetCellRectPicker(myCellRectPicker.GetPointer());
+    anActor->SetPointAreaPicker(myPointAreaPicker.GetPointer());
+    anActor->SetCellAreaPicker(myCellAreaPicker.GetPointer());
 
     anActor->SetPreHighlightProperty(myPreHighlightProperty.GetPointer());
     anActor->SetHighlightProperty(myHighlightProperty.GetPointer());
 
     anActor->AddToRender(GetDevice());
-    AdjustActors();
+    anActor->UpdateNameActors();
+
+    if(theIsAdjustActors)
+      AdjustActors();
   }
 }
 
@@ -258,7 +264,7 @@ SVTK_Renderer
 */
 void
 SVTK_Renderer
-::RemoveActor(VTKViewer_Actor* theActor)
+::RemoveActor(VTKViewer_Actor* theActor, bool theIsAdjustActors)
 {
   if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(theActor)){
     // Order of the calls are important because VTKViewer_Actor::RemoveFromRender
@@ -270,14 +276,26 @@ SVTK_Renderer
     anActor->SetPointPicker(NULL);
     anActor->SetCellPicker(NULL);
 
-    anActor->SetPointRectPicker(NULL);
-    anActor->SetCellRectPicker(NULL);
+    anActor->SetPointAreaPicker(NULL);
+    anActor->SetCellAreaPicker(NULL);
 
     anActor->SetPreHighlightProperty(NULL);
     anActor->SetHighlightProperty(NULL);
 
     anActor->RemoveFromRender(GetDevice());
-    AdjustActors();
+
+    while ( int i = myPointPicker->GetProp3Ds()->IsItemPresent( theActor ))
+      myPointPicker->GetProp3Ds()->RemoveItem( i-1 );
+    while ( int i = myCellPicker->GetProp3Ds()->IsItemPresent( theActor ))
+      myCellPicker->GetProp3Ds()->RemoveItem( i-1 );
+
+    while ( int i = myPointPicker->GetActors()->IsItemPresent( theActor ))
+      myPointPicker->GetActors()->RemoveItem( i-1 );
+    while ( int i = myCellPicker->GetActors()->IsItemPresent( theActor ))
+      myCellPicker->GetActors()->RemoveItem( i-1 );
+
+    if(theIsAdjustActors)
+      AdjustActors();
   }
 }
 
@@ -310,6 +328,14 @@ SVTK_Renderer
 {
   myTransform->SetMatrixScale( theScale[0], theScale[1], theScale[2] );
   AdjustActors();
+
+  VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
+  vtkActorCollection* anActors = aCopy.GetActors();
+  anActors->InitTraversal();
+  while(vtkActor* anAct = anActors->GetNextActor())
+    if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct))
+      if(anActor->isHighlighted() && !anActor->IsInfinitive())
+        anActor->highlight(true);
 }
 
 /*!
@@ -318,9 +344,9 @@ SVTK_Renderer
 void
 SVTK_Renderer
 ::SetSelectionProp(const double& theRed, 
-                  const double& theGreen, 
-                  const double& theBlue, 
-                  const int& theWidth) 
+                   const double& theGreen, 
+                   const double& theBlue, 
+                   const int& theWidth) 
 {
   myHighlightProperty->SetColor( theRed, theGreen, theBlue );
   myHighlightProperty->SetLineWidth( theWidth );
@@ -333,9 +359,9 @@ SVTK_Renderer
 void
 SVTK_Renderer
 ::SetPreselectionProp(const double& theRed, 
-                     const double& theGreen, 
-                     const double& theBlue, 
-                     const int& theWidth) 
+                      const double& theGreen, 
+                      const double& theBlue, 
+                      const int& theWidth) 
 {
   myPreHighlightProperty->SetColor( theRed, theGreen, theBlue );
   myPreHighlightProperty->SetLineWidth( theWidth );
@@ -348,13 +374,16 @@ SVTK_Renderer
 void
 SVTK_Renderer
 ::SetSelectionTolerance(const double& theTolNodes, 
-                       const double& theTolCell)
+                        const double& theTolCell,
+                        const double& theTolObjects)
 {
   myPointPicker->SetTolerance( theTolNodes );
   myCellPicker->SetTolerance( theTolCell );
 
-  myPointRectPicker->SetTolerance( theTolNodes );
-  myCellRectPicker->SetTolerance( theTolCell );
+  myPointAreaPicker->SetTolerance( theTolNodes );
+  myCellAreaPicker->SetTolerance( theTolCell );
+
+  mySelector->SetTolerance( theTolObjects );
 }
 
 
@@ -364,11 +393,11 @@ SVTK_Renderer
 
 inline
 bool
-CheckBndBox(const vtkFloatingPointType theBounds[6])
+CheckBndBox(const double theBounds[6])
 {
-  if(theBounds[0] > -VTK_LARGE_FLOAT && theBounds[1] < VTK_LARGE_FLOAT &&
-     theBounds[2] > -VTK_LARGE_FLOAT && theBounds[3] < VTK_LARGE_FLOAT &&
-     theBounds[4] > -VTK_LARGE_FLOAT && theBounds[5] < VTK_LARGE_FLOAT)
+  if(theBounds[0] > -VTK_FLOAT_MAX && theBounds[1] < VTK_FLOAT_MAX &&
+     theBounds[2] > -VTK_FLOAT_MAX && theBounds[3] < VTK_FLOAT_MAX &&
+     theBounds[4] > -VTK_FLOAT_MAX && theBounds[5] < VTK_FLOAT_MAX)
     return true;
   return false;
 }
@@ -383,9 +412,9 @@ SVTK_Renderer
   bool aTDisplayed = IsTrihedronDisplayed();
   bool aCDisplayed = IsCubeAxesDisplayed();
 
-  vtkFloatingPointType aNewBndBox[6];
-  aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT;
-  aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT;
+  double aNewBndBox[6];
+  aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_FLOAT_MAX;
+  aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_FLOAT_MAX;
 
   int aVisibleNum = myTrihedron->GetVisibleActorCount(GetDevice());
   if(aVisibleNum){
@@ -396,31 +425,32 @@ SVTK_Renderer
       myCubeAxes->VisibilityOff();
 
     // if the new trihedron size have sufficient difference, then apply the value
-    vtkFloatingPointType aSize = myTrihedron->GetSize();
+    double aSize = myTrihedron->GetSize();
     if ( IsTrihedronRelative() )
       {
-       ComputeTrihedronSize(GetDevice(),aSize,aSize,myTrihedronSize);
-       myTrihedron->SetSize(aSize);
+        ComputeTrihedronSize(GetDevice(),aSize,aSize,myTrihedronSize);
+        myTrihedron->SetSize(aSize);
       }
     else
       myTrihedron->SetSize( myTrihedronSize );
 
     // iterate through displayed objects and set size if necessary
-    vtkActorCollection* anActors = GetDevice()->GetActors();
+    VTK::ActorCollectionCopy aCopy(GetDevice()->GetActors());
+    vtkActorCollection* anActors = aCopy.GetActors();
     anActors->InitTraversal();
     while(vtkActor* anAct = anActors->GetNextActor()){
       if(SALOME_Actor* anActor = dynamic_cast<SALOME_Actor*>(anAct)){
-       if(anActor->IsResizable())
-         anActor->SetSize(0.5*aSize);
+        if(anActor->IsResizable())
+          anActor->SetSize(0.5*aSize);
         if(anActor->GetVisibility() && !anActor->IsInfinitive()){
-         vtkFloatingPointType *aBounds = anActor->GetBounds();
+          double *aBounds = anActor->GetBounds();
           if(CheckBndBox(aBounds))
-           for(int i = 0; i < 5; i = i + 2){
-             if(aBounds[i] < aNewBndBox[i]) 
-               aNewBndBox[i] = aBounds[i];
-             if(aBounds[i+1] > aNewBndBox[i+1]) 
-               aNewBndBox[i+1] = aBounds[i+1];
-           }
+            for(int i = 0; i < 5; i = i + 2){
+              if(aBounds[i] < aNewBndBox[i]) 
+                aNewBndBox[i] = aBounds[i];
+              if(aBounds[i+1] > aNewBndBox[i+1]) 
+                aNewBndBox[i+1] = aBounds[i+1];
+            }
         }
       }
     }
@@ -466,7 +496,7 @@ SVTK_Renderer
 */
 void
 SVTK_Renderer
-::SetTrihedronSize(int theSize, const bool theRelative)
+::SetTrihedronSize(double theSize, const bool theRelative)
 {
   if(myTrihedronSize != theSize || myIsTrihedronRelative != theRelative){
     myTrihedronSize = theSize;
@@ -478,7 +508,7 @@ SVTK_Renderer
 /*!
   \return size of the trihedron in percents from bounding box of the scene
 */
-int
+double
 SVTK_Renderer
 ::GetTrihedronSize() const
 {
@@ -528,6 +558,18 @@ SVTK_Renderer
     myTrihedron->VisibilityOn();
 }
 
+/*!
+  Set trihedron visibility
+*/
+void 
+SVTK_Renderer
+::SetTrihedronVisibility( const bool show ) {
+  if(show)
+    myTrihedron->VisibilityOn();
+  else
+    myTrihedron->VisibilityOff();  
+}
+
 /*!
   Adjust size of the trihedron to the bounding box of the scene
 */
@@ -610,7 +652,7 @@ SVTK_Renderer
   else
     myCubeAxes->VisibilityOff();
 
-  static vtkFloatingPointType aCoeff = 3.0;
+  static double aCoeff = 3.0;
   aCamera->SetParallelScale(aCoeff*aCamera->GetParallelScale());
 }
 
@@ -655,6 +697,72 @@ SVTK_Renderer
   ::ResetCameraClippingRange(GetDevice());
 }
 
+/*!
+  Fit all selected presentation in the scene
+*/
+void SVTK_Renderer::onFitSelection()
+{
+  vtkActorCollection* aSelectedCollection = vtkActorCollection::New();
+
+  VTK::ActorCollectionCopy aCopy( GetDevice()->GetActors() );
+  vtkActorCollection* aCollection = aCopy.GetActors();
+  aCollection->InitTraversal();
+  while ( vtkActor* aProp = aCollection->GetNextActor() )
+    if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aProp ) ) {
+      const Handle(SALOME_InteractiveObject)& io = anActor->getIO();
+      if ( !io.IsNull() && mySelector->IsSelected( io ) )
+        aSelectedCollection->AddItem( aProp );
+    }
+  
+  if( aSelectedCollection->GetNumberOfItems() == 0 )
+    return; // if collection is empty
+  
+  double bounds[6];
+  ::ComputeBounds( aSelectedCollection, bounds );
+
+  if ( aSelectedCollection->GetNumberOfItems() && ::isBoundValid( bounds ) ) {
+    GetDevice()->ResetCamera( bounds );
+    GetDevice()->ResetCameraClippingRange( bounds );
+  }
+}
+
+void SVTK_Renderer::OnFitIObjects(const SALOME_ListIO& objects)
+{
+  vtkActorCollection* aSelectedCollection = vtkActorCollection::New();
+
+  VTK::ActorCollectionCopy aCopy( GetDevice()->GetActors() );
+  vtkActorCollection* aCollection = aCopy.GetActors();
+  aCollection->InitTraversal();
+  while ( vtkActor* aProp = aCollection->GetNextActor() )
+  {
+    if ( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aProp ) ) {
+      const Handle(SALOME_InteractiveObject)& io = anActor->getIO();
+      if ( anActor->GetVisibility() && !io.IsNull() ) {
+       SALOME_ListIteratorOfListIO iter( objects );
+       for ( ; iter.More(); iter.Next() ) {
+         if ( iter.Value().IsNull() )
+           continue;
+         if ( io->isSame( iter.Value() ) ) {
+           aSelectedCollection->AddItem( aProp );
+           break;
+         }
+       }
+      }
+    }
+  }
+
+  if( aSelectedCollection->GetNumberOfItems() == 0 )
+    return; // if collection is empty
+  
+  double bounds[6];
+  ::ComputeBounds( aSelectedCollection, bounds );
+
+  if ( aSelectedCollection->GetNumberOfItems() && ::isBoundValid( bounds ) ) {
+    GetDevice()->ResetCamera( bounds );
+    GetDevice()->ResetCameraClippingRange( bounds );
+  }
+}
+
 /*!
   Reset camera clipping range to adjust the range to the bounding box of the scene
 */
@@ -736,6 +844,31 @@ SVTK_Renderer
   this->OnFitAll();
 }
 
+
+/*!
+  To rotate view 90 degrees clockwise
+*/
+void
+SVTK_Renderer
+::onClockWiseView()
+{
+  vtkCamera* aCamera = GetDevice()->GetActiveCamera(); 
+  aCamera->Roll(-90);
+  aCamera->OrthogonalizeViewUp();
+}
+
+/*!
+  To rotate view 90 degrees counterclockwise
+*/
+void
+SVTK_Renderer
+::onAntiClockWiseView()
+{
+  vtkCamera* aCamera = GetDevice()->GetActiveCamera(); 
+  aCamera->Roll(90);
+  aCamera->OrthogonalizeViewUp();
+}
+
 /*!
   To reset direction of the camera to right view
 */