]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Fix for Bug GVIEW11214
authorapo <apo@opencascade.com>
Mon, 16 Jan 2006 10:17:50 +0000 (10:17 +0000)
committerapo <apo@opencascade.com>
Mon, 16 Jan 2006 10:17:50 +0000 (10:17 +0000)
  Incorrect selection by area

src/SVTK/SALOME_Actor.cxx
src/SVTK/SALOME_Actor.h
src/SVTK/SVTK.cxx
src/SVTK/SVTK_RectPicker.cxx
src/SVTK/SVTK_RectPicker.h
src/SVTK/SVTK_Renderer.cxx
src/SVTK/SVTK_Renderer.h

index bf80f1f843a101800ae6ddbb56d2ee05928041c9..44c00fe8b888d94e672f0d6db32ac9c1b56fdca8 100644 (file)
@@ -38,7 +38,7 @@
 #include "VTKViewer_TransformFilter.h"
 #include "VTKViewer_PassThroughFilter.h"
 #include "VTKViewer_GeometryFilter.h"
-#include "VTKViewer_CellRectPicker.h"
+#include "SVTK_RectPicker.h"
 
 #include "SVTK_Actor.h"
 
@@ -1046,46 +1046,34 @@ SALOME_Actor
 
     switch(aSelectionMode){
     case NodeSelection: {
-      if( vtkDataSet* aDataSet = GetInput() ) {
-       TColStd_MapOfInteger anIndices;
-       for( int i = 0; i < aDataSet->GetNumberOfPoints(); i++) {
-         float aPoint[3];
-         aDataSet->GetPoint( i, aPoint );
-
-         float aPnt[3];
-         aRenderer->SetWorldPoint( aPoint[0], aPoint[1], aPoint[2], 1.0 );
-         aRenderer->WorldToDisplay();
-         aRenderer->GetDisplayPoint( aPnt );
-
-         if( aPnt[0] > x1 && aPnt[0] < x2 && aPnt[1] > y1 && aPnt[1] < y2 ) {
-           float aDisp[3];
-           aRenderer->SetWorldPoint( aPoint[0], aPoint[1], aPoint[2], 1.0 );
-           aRenderer->WorldToDisplay();
-           aRenderer->GetDisplayPoint( aDisp );
-
-           if( myPointPicker->Pick( aDisp[0], aDisp[1], 0.0, aRenderer ) ) {
-             if( vtkActorCollection* anActorCollection = myPointPicker->GetActors() ) {
-               if( anActorCollection->IsItemPresent( this ) ) {
-                 float aPickedPoint[3];
-                 myPointPicker->GetMapperPosition( aPickedPoint );
-                 vtkIdType aVtkId = aDataSet->FindPoint( aPickedPoint );
-                 if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) {
-                   int anObjId = GetNodeObjId( aVtkId );
-                   anIndices.Add( anObjId );
-                 }
-               }
-             }
-           }
+      myPointRectPicker->InitializePickList();
+      myPointRectPicker->AddPickList(this);
+      myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
+
+      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap();
+      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
+      TColStd_MapOfInteger anIndexes;
+      if(aMapIter != aVectorIdsMap.end()){
+       const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
+       vtkIdType anEnd = aVectorIds.size();
+       SVTK_RectPicker::TVectorIds::const_iterator anIdIter = aVectorIds.begin();
+       for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
+         int aPointId = aVectorIds[anId];
+         if( aPointId >= 0 && mySelector->IsValid( this, aPointId, true ) ) {
+           int anObjId = GetNodeObjId( aPointId );
+           anIndexes.Add( anObjId );
          }
        }
-       if( !anIndices.IsEmpty() ) {
-         mySelector->AddOrRemoveIndex( myIO, anIndices, true );
-         mySelector->AddIObject( this );
-         anIndices.Clear();
-       }
-       else
-         mySelector->RemoveIObject( this );
       }
+      
+      if( !anIndexes.IsEmpty() ) {
+       mySelector->AddOrRemoveIndex( myIO, anIndexes, true );
+       mySelector->AddIObject( this );
+       anIndexes.Clear();
+      }
+      else
+       mySelector->RemoveIObject( this );
+
       break;
     }
     case ActorSelection :
@@ -1119,15 +1107,19 @@ SALOME_Actor
     case FaceSelection:
     case VolumeSelection: 
     {
-      myCellRectPicker->SetTolerance( 0.001 );
+      myCellRectPicker->InitializePickList();
+      myCellRectPicker->AddPickList(this);
       myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer );
 
-      VTKViewer_CellDataSet aCellList = myCellRectPicker->GetCellData( this );
+      const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap();
+      SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this);
       TColStd_MapOfInteger anIndexes;
-      if( !aCellList.empty() ) {
-       VTKViewer_CellDataSet::iterator anIter = aCellList.begin();
-       for(; anIter != aCellList.end(); ++anIter ) {
-         int aCellId = anIter->cellId;
+      if(aMapIter != aVectorIdsMap.end()){
+       const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second;
+       vtkIdType anEnd = aVectorIds.size();
+       SVTK_RectPicker::TVectorIds::const_iterator anIdIter = aVectorIds.begin();
+       for(vtkIdType anId = 0; anId < anEnd; anId++ ) {
+         int aCellId = aVectorIds[anId];
          if ( !mySelector->IsValid( this, aCellId ) )
            continue;
 
@@ -1168,9 +1160,16 @@ SALOME_Actor
 
 void
 SALOME_Actor
-::SetCellRectPicker(VTKViewer_CellRectPicker* theCellRectPicker) 
+::SetPointRectPicker(SVTK_RectPicker* theRectPicker) 
+{
+  myPointRectPicker = theRectPicker;
+}
+
+void
+SALOME_Actor
+::SetCellRectPicker(SVTK_RectPicker* theRectPicker) 
 {
-  myCellRectPicker = theCellRectPicker;
+  myCellRectPicker = theRectPicker;
 }
 
 //----------------------------------------------------------------------------
index 8ef2f4d53a946cc345006feb7fb3bf7bfc94bcc8..de4b00b25b2f6b993c1201e97ccab5258bca8ece 100644 (file)
@@ -64,9 +64,9 @@ class VTKViewer_Transform;
 class VTKViewer_GeometryFilter;
 class VTKViewer_TransformFilter;
 class VTKViewer_PassThroughFilter;
-class VTKViewer_CellRectPicker;
 
 class SVTK_Actor;
+class SVTK_RectPicker;
 class SVTK_InteractorStyle;
 
 extern int SALOME_POINT_SIZE;
@@ -394,9 +394,13 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor
   void
   SetCellPicker(vtkCellPicker* theCellPicker); 
 
+  //! To set up a picker for point rectangle selection (initialized by #SVTK_Renderer::AddActor)
+  void
+  SetPointRectPicker(SVTK_RectPicker* theRectPicker);
+
   //! To set up a picker for cell rectangle selection (initialized by #SVTK_Renderer::AddActor)
   void
-  SetCellRectPicker(VTKViewer_CellRectPicker* theCellRectPicker);
+  SetCellRectPicker(SVTK_RectPicker* theRectPicker);
 
   //----------------------------------------------------------------------------
   //! To set up a prehighlight property (initialized by #SVTK_Renderer::AddActor)
@@ -450,7 +454,9 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor
   // Highlight/ Prehighlight devices
   vtkSmartPointer<vtkPointPicker> myPointPicker;
   vtkSmartPointer<vtkCellPicker> myCellPicker;
-  vtkSmartPointer<VTKViewer_CellRectPicker> myCellRectPicker;
+
+  vtkSmartPointer<SVTK_RectPicker> myPointRectPicker;
+  vtkSmartPointer<SVTK_RectPicker> myCellRectPicker;
 
   vtkSmartPointer<SVTK_Actor> myPreHighlightActor;
   vtkSmartPointer<SVTK_Actor> myHighlightActor;
index a8f334e138b246c2d0874795d55bcb21fe4ad260..0be0d5cfdfbadccaea9bda865199a57ba084ff1e 100644 (file)
@@ -30,6 +30,8 @@
 #include "SVTK_Prs.h"
 #include "SVTK_Actor.h"
 #include "SALOME_Actor.h"
+#include "SVTK_RectPicker.h"
+#include "SVTK_DeviceActor.h"
 #include "SVTK_CubeAxesActor2D.h"
 #include "SVTK_Functor.h"
 #include "SVTK_View.h"
index 2095a67d2d6101b1498af64ed532236e9be02871..a8d81bb3c58af1ac7e8f1e03cb0fed86fdda2256 100644 (file)
 
 #include "SVTK_RectPicker.h"
 
-#include <vector>
+#include <set>
 
 #include <vtkObjectFactory.h>
+#include <vtkCommand.h>
+
+#include <vtkAbstractMapper3D.h>
+#include <vtkMapper.h>
+#include <vtkProperty.h>
+
+#include <vtkAssemblyPath.h>
+#include <vtkAssemblyNode.h>
+
 #include <vtkRenderWindow.h>
 #include <vtkMatrix4x4.h>
 #include <vtkRenderer.h>
 //----------------------------------------------------------------------------
 namespace
 {
-  typedef std::vector<vtkIdType> TVectorIds;
+  //----------------------------------------------------------------------------
+  inline
+  float
+  GetZ(float* theZPtr,
+       int theSelection[4],
+       int theDX,
+       int theDY)
+  {
+    return theZPtr[theDX - theSelection[0] + (theDY - theSelection[1])*(theSelection[2] - theSelection[0] + 1)];
+  }
+
+
+  //----------------------------------------------------------------------------
+  inline
+  int
+  Check(float* theZPtr,
+       int theSelection[4],
+       float theTolerance,
+       float theDZ,
+       int theDX,
+       int theDY)
+  {
+    int aRet = 0;
+    if(theDX < theSelection[0] || theDX > theSelection[2] ||
+       theDY < theSelection[1] || theDY > theSelection[3])
+      return aRet;
+
+    // Access the value from the captured zbuffer.  Note, we only
+    // captured a portion of the zbuffer, so we need to offset dx by
+    // the selection window.
+    float aZ = GetZ(theZPtr,theSelection,theDX,theDY);
+    
+    if(aZ == 0.0 || aZ == 1.0)
+      return aRet;
+
+    aRet = fabs(aZ - theDZ) <= theTolerance? 1: -1;
+    //cout<<"Check = {"<<theDX<<", "<<theDY<<", "<<theDZ<<", "<<aZ<<"} = "<<aRet<<"\n";
+
+    return aRet;
+  }
+
 
   //----------------------------------------------------------------------------
   void
   SelectVisiblePoints(int theSelection[4],
                      vtkRenderer *theRenderer,
                      vtkDataSet *theInput,
-                     TVectorIds& theVectorIds,
-                     float theTolerance = 0.001)
+                     SVTK_RectPicker::TVectorIds& theVisibleIds,
+                     SVTK_RectPicker::TVectorIds& theInVisibleIds,
+                     float theTolerance)
   {
-    theVectorIds.clear();
+    theVisibleIds.clear();
+    theInVisibleIds.clear();
 
     vtkIdType aNumPts = theInput->GetNumberOfPoints();
     if(aNumPts < 1)
       return;
     
-    theVectorIds.reserve(aNumPts/2 + 1);
+    theVisibleIds.reserve(aNumPts/2 + 1);
+    theInVisibleIds.reserve(aNumPts/2 + 1);
 
     // Grab the composite perspective transform.  This matrix is used to convert
     // each point to view coordinates.  vtkRenderer provides a WorldToView()
@@ -68,20 +120,23 @@ namespace
     aMatrix->DeepCopy(theRenderer->GetActiveCamera()->
                      GetCompositePerspectiveTransformMatrix(1,0,1));
 
-    // If we have more than a few query points, we grab the z-buffer for the
-    // selection region all at once and probe the resulting array.  When we
-    // have just a few points, we perform individual z-buffer queries.
-    const int SimpleQueryLimit = 25;
-    float *aZPtr = NULL;
-    if(aNumPts > SimpleQueryLimit){
-      aZPtr = theRenderer->GetRenderWindow()->
-       GetZbufferData(theSelection[0], theSelection[2], theSelection[1], theSelection[3]);
+    // We grab the z-buffer for the selection region all at once and probe the resulting array.
+    float *aZPtr = theRenderer->GetRenderWindow()->
+      GetZbufferData(theSelection[0], theSelection[1], theSelection[2], theSelection[3]);
+    /*
+    cout<<"theSelection = {"<<theSelection[0]<<", "<<theSelection[1]<<", "<<theSelection[2]<<", "<<theSelection[3]<<"}\n";
+    for(int iY = theSelection[1]; iY <= theSelection[3];  iY++){
+      for(int iX = theSelection[0]; iX <= theSelection[2];  iX++){
+       cout<<GetZ(aZPtr,theSelection,iX,iY)<<" ";
+      }
+      cout<<endl;
     }
-
-    float aX[4] = {1.0, 1.0, 1.0, 1.0};
+    */
     for(vtkIdType aPntId = 0; aPntId < aNumPts; aPntId++){
       // perform conversion
+      float aX[4] = {1.0, 1.0, 1.0, 1.0};
       theInput->GetPoint(aPntId,aX);
+
       float aView[4];
       aMatrix->MultiplyPoint(aX,aView);
       if(aView[3] == 0.0)
@@ -90,33 +145,61 @@ namespace
                                aView[1]/aView[3],
                                aView[2]/aView[3]);
       theRenderer->ViewToDisplay();
+
       float aDX[3];
       theRenderer->GetDisplayPoint(aDX);
-      bool anIsVisible = false;
-
+      
       // check whether visible and in selection window 
-      if(aDX[0] >= theSelection[0] && aDX[0] <= theSelection[1] &&
-         aDX[1] >= theSelection[2] && aDX[1] <= theSelection[3] )
+      if(aDX[0] >= theSelection[0] && aDX[0] <= theSelection[2] &&
+         aDX[1] >= theSelection[1] && aDX[1] <= theSelection[3])
       {
-       float aZ = 0.0;
-       if(aNumPts > SimpleQueryLimit){
-         // Access the value from the captured zbuffer.  Note, we only
-         // captured a portion of the zbuffer, so we need to offset dx by
-         // the selection window.
-         aZ = aZPtr[int(aDX[0]) - theSelection[0]
-                    + (int(aDX[1]) - theSelection[2])
-                    *(theSelection[1] - theSelection[0] + 1)];
-        }else{
-        aZ = theRenderer->GetZ(int(aDX[0]), 
-                              int(aDX[1]));
-        }
-       float aDiff = fabs(aZ-aDX[2]);
-       if(aDiff <= theTolerance)
-         anIsVisible = true;
-      }
+       //cout<<"\naPntId "<<aPntId<<"; aDX = {"<<aDX[0]<<", "<<aDX[1]<<", "<<aDX[2]<<"}\n";
+       int aDX0 = int(aDX[0]);
+       int aDX1 = int(aDX[1]);
+
+       int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aDX0,aDX1);
+       if(aRet > 0)
+         goto ADD_VISIBLE;
+       if(aRet < 0)
+         goto ADD_INVISIBLE;
 
-      if(anIsVisible)
-       theVectorIds.push_back(aPntId);
+       static int aMaxRadius = 5;
+       for(int aRadius = 0; aRadius < aMaxRadius; aRadius++){
+         int aStartDX[2] = {aDX0 - aRadius, aDX1 - aRadius};
+         for(int i = 0; i < aRadius; i++){
+           int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0]++,aStartDX[1]);
+           if(aRet > 0)
+             goto ADD_VISIBLE;
+           if(aRet < 0)
+             goto ADD_INVISIBLE;
+         }
+         for(int i = 0; i < aRadius; i++){
+           int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0],aStartDX[1]++);
+           if(aRet > 0)
+             goto ADD_VISIBLE;
+           if(aRet < 0)
+             goto ADD_INVISIBLE;
+         }
+         for(int i = 0; i < aRadius; i++){
+           int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0]--,aStartDX[1]);
+           if(aRet > 0)
+             goto ADD_VISIBLE;
+           if(aRet < 0)
+             goto ADD_INVISIBLE;
+         }
+         for(int i = 0; i < aRadius; i++){
+           int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0],aStartDX[1]--);
+           if(aRet > 0)
+             goto ADD_VISIBLE;
+           if(aRet < 0)
+             goto ADD_INVISIBLE;
+         }
+       }
+       if(false)
+         ADD_VISIBLE : theVisibleIds.push_back(aPntId);
+       if(false)
+         ADD_INVISIBLE : theInVisibleIds.push_back(aPntId);
+      }
     }//for all points
 
     aMatrix->Delete();
@@ -131,8 +214,8 @@ namespace
   SelectVisibleCells(int theSelection[4],
                     vtkRenderer *theRenderer,
                     vtkDataSet *theInput,
-                    TVectorIds& theVectorIds,
-                    float theTolerance = 0.001)
+                    SVTK_RectPicker::TVectorIds& theVectorIds,
+                    float theTolerance)
   {
     theVectorIds.clear();
 
@@ -142,6 +225,19 @@ namespace
     
     theVectorIds.reserve(aNumCells/2 + 1);
 
+    SVTK_RectPicker::TVectorIds aVisiblePntIds;
+    SVTK_RectPicker::TVectorIds anInVisiblePntIds;
+    SelectVisiblePoints(theSelection,
+                       theRenderer,
+                       theInput,
+                       aVisiblePntIds,
+                       anInVisiblePntIds,
+                       theTolerance);
+
+    typedef std::set<vtkIdType> TIdsSet;
+    TIdsSet aVisibleIds(aVisiblePntIds.begin(),aVisiblePntIds.end());
+    TIdsSet anInVisibleIds(anInVisiblePntIds.begin(),anInVisiblePntIds.end());
+
     // Grab the composite perspective transform.  This matrix is used to convert
     // each point to view coordinates.  vtkRenderer provides a WorldToView()
     // method but it computes the composite perspective transform each time
@@ -151,67 +247,46 @@ namespace
     aMatrix->DeepCopy(theRenderer->GetActiveCamera()->
                      GetCompositePerspectiveTransformMatrix(1,0,1));
 
-    // If we have more than a few query points, we grab the z-buffer for the
-    // selection region all at once and probe the resulting array.  When we
-    // have just a few points, we perform individual z-buffer queries.
-    const int SimpleQueryLimit = 25;
-    float *aZPtr = NULL;
-    if(aNumCells > SimpleQueryLimit){
-      aZPtr = theRenderer->GetRenderWindow()->
-       GetZbufferData(theSelection[0], theSelection[2], theSelection[1], theSelection[3]);
-    }
-
-    float aX[4] = {1.0, 1.0, 1.0, 1.0};
     for(vtkIdType aCellId = 0; aCellId < aNumCells; aCellId++){
-      bool anIsVisible = true;
+      //cout<<"aCellId = "<<aCellId<<"\n";
       vtkCell* aCell = theInput->GetCell(aCellId);
       vtkIdType aNumPts = aCell->GetNumberOfPoints();
+      bool anIsInRectangle = true;
+      bool anIsVisible = false;
       for(vtkIdType anId = 0; anId < aNumPts; anId++){
-       // perform conversion
        vtkIdType aPntId = aCell->GetPointId(anId);
-       theInput->GetPoint(aPntId,aX);
-       float aView[4];
-       aMatrix->MultiplyPoint(aX,aView);
-       if(aView[3] == 0.0)
-         continue;
-       theRenderer->SetViewPoint(aView[0]/aView[3], 
-                                 aView[1]/aView[3],
-                                 aView[2]/aView[3]);
-       theRenderer->ViewToDisplay();
-       float aDX[3];
-       theRenderer->GetDisplayPoint(aDX);
-
-       // check whether visible and in selection window 
-       if(aDX[0] >= theSelection[0] && aDX[0] <= theSelection[1] &&
-          aDX[1] >= theSelection[2] && aDX[1] <= theSelection[3])
-       {
-         float aZ = 0.0;
-         if(aNumPts > SimpleQueryLimit){
-           // Access the value from the captured zbuffer.  Note, we only
-           // captured a portion of the zbuffer, so we need to offset dx by
-           // the selection window.
-           aZ = aZPtr[int(aDX[0]) - theSelection[0]
-                      + (int(aDX[1]) - theSelection[2])
-                      *(theSelection[1] - theSelection[0] + 1)];
-         }else{
-           aZ = theRenderer->GetZ(int(aDX[0]), 
-                                  int(aDX[1]));
-         }
-         float aDiff = fabs(aZ-aDX[2]);
-         if(aDiff > theTolerance){
-           anIsVisible = false;
-           break;
-         }
-       }
+       //cout<<"\taPntId = "<<aPntId<<"; ";
+
+       anIsInRectangle &= 
+         aVisibleIds.find(aPntId) != aVisibleIds.end() ||
+         anInVisibleIds.find(aPntId) != anInVisibleIds.end();
+
+       anIsVisible |= aVisibleIds.find(aPntId) != aVisibleIds.end();
       }
-      if(anIsVisible)
+      //cout<<"\t"<<anIsInRectangle<<"; "<<anIsVisible<<"\n";
+      if(anIsInRectangle && anIsVisible)
        theVectorIds.push_back(aCellId);
     }//for all parts
-    
-    aMatrix->Delete();
-    
-    if(aZPtr)
-      delete [] aZPtr;
+  }
+
+  //----------------------------------------------------------------------------
+  void
+  CalculatePickPosition(vtkRenderer *theRenderer,
+                       float theSelectionX, 
+                       float theSelectionY, 
+                       float theSelectionZ,
+                       float thePickPosition[3])
+  {
+    // Convert the selection point into world coordinates.
+    //
+    theRenderer->SetDisplayPoint(theSelectionX, theSelectionY, theSelectionZ);
+    theRenderer->DisplayToWorld();
+    float* aWorldCoords = theRenderer->GetWorldPoint();
+    if ( aWorldCoords[3] != 0.0 ) {
+      for (int i=0; i < 3; i++) {
+       thePickPosition[i] = aWorldCoords[i] / aWorldCoords[3];
+      }
+    }
   }
 }
 
@@ -221,7 +296,10 @@ vtkStandardNewMacro(SVTK_RectPicker);
 //----------------------------------------------------------------------------
 SVTK_RectPicker
 ::SVTK_RectPicker()
-{}
+{
+  this->Tolerance = 0.025; // 1/40th of the renderer window
+  this->PickPoints = 1;
+}
 
 SVTK_RectPicker
 ::~SVTK_RectPicker()
@@ -237,19 +315,141 @@ SVTK_RectPicker
 //----------------------------------------------------------------------------
 int
 SVTK_RectPicker
-::Pick(float selectionPt1[3], float selectionPt2[3], vtkRenderer *ren)
+::Pick(float theSelection[3], float theSelection2[3], vtkRenderer *theRenderer)
 {
-  return Pick(selectionPt1[0], selectionPt1[1], selectionPt1[2], 
-             selectionPt2[0], selectionPt2[1], selectionPt2[2],
-             ren);
+  return Pick(theSelection[0], theSelection[1], theSelection[2], 
+             theSelection2[0], theSelection2[1], theSelection2[2],
+             theRenderer);
 }
 
 //----------------------------------------------------------------------------
 int 
 SVTK_RectPicker
-::Pick(float selectionX1, float selectionY1, float selectionZ1,
-       float selectionX2, float selectionY2, float selectionZ2,
-       vtkRenderer *renderer)
+::Pick(float theSelectionX, float theSelectionY, float theSelectionZ, 
+       float theSelectionX2, float theSelectionY2, float theSelectionZ2,
+       vtkRenderer *theRenderer)
 {
-  return 0;
+  //  Initialize picking process
+  this->Initialize();
+  myCellIdsMap.clear();
+  myPointIdsMap.clear();
+  this->Renderer = theRenderer;
+
+  // Get camera focal point and position. Convert to display (screen) 
+  // coordinates. We need a depth value for z-buffer.
+  //
+  vtkCamera* aCamera = theRenderer->GetActiveCamera();
+
+  float aCameraFP[4];
+  aCamera->GetFocalPoint(aCameraFP); 
+  aCameraFP[3] = 1.0;
+
+  theRenderer->SetWorldPoint(aCameraFP);
+  theRenderer->WorldToDisplay();
+  float* aDisplayCoords = theRenderer->GetDisplayPoint();
+  float aSelectionZ = aDisplayCoords[2];
+
+  this->SelectionPoint[0] = theSelectionX;
+  this->SelectionPoint[1] = theSelectionY;
+  this->SelectionPoint[2] = theSelectionZ;
+
+  // Convert the selection point into world coordinates.
+  //
+  CalculatePickPosition(theRenderer,
+                       theSelectionX,
+                       theSelectionY,
+                       aSelectionZ,
+                       this->PickPosition);
+
+  this->SelectionPoint2[0] = theSelectionX2;
+  this->SelectionPoint2[1] = theSelectionY2;
+  this->SelectionPoint2[2] = theSelectionZ2;
+
+  // Convert the selection point into world coordinates.
+  //
+  CalculatePickPosition(theRenderer,
+                       theSelectionX2,
+                       theSelectionY2,
+                       aSelectionZ,
+                       this->PickPosition2);
+
+  // Invoke start pick method if defined
+  this->InvokeEvent(vtkCommand::StartPickEvent,NULL);
+
+  vtkPropCollection *aProps;
+  if ( this->PickFromList ) 
+    aProps = this->GetPickList();
+  else 
+    aProps = theRenderer->GetProps();
+
+  aProps->InitTraversal();
+  while ( vtkProp* aProp = aProps->GetNextProp() ) {
+    aProp->InitPathTraversal();
+    while ( vtkAssemblyPath* aPath = aProp->GetNextPath() ) {
+      vtkMapper *aMapper = NULL;
+      bool anIsPickable = false;
+      vtkActor* anActor = NULL;
+      vtkProp *aPropCandidate = aPath->GetLastNode()->GetProp();
+      if ( aPropCandidate->GetPickable() && aPropCandidate->GetVisibility() ) {
+        anIsPickable = true;
+       anActor = vtkActor::SafeDownCast(aPropCandidate);
+       if ( anActor ) {
+          aMapper = anActor->GetMapper();
+          if ( anActor->GetProperty()->GetOpacity() <= 0.0 )
+           anIsPickable = false;
+       }
+      }
+      if ( anIsPickable  &&  aMapper && aMapper->GetInput()) {
+       int aSelectionPoint[4] = {int(theSelectionX),
+                                 int(theSelectionY),
+                                 int(theSelectionX2),
+                                 int(theSelectionY2)};
+       if ( this->PickPoints ) {
+         TVectorIds& aVisibleIds = myPointIdsMap[anActor];
+         TVectorIds anInVisibleIds;
+         SelectVisiblePoints(aSelectionPoint,
+                             theRenderer,
+                             aMapper->GetInput(),
+                             aVisibleIds,
+                             anInVisibleIds,
+                             this->Tolerance);
+         if ( aVisibleIds.empty() ) {
+           myPointIdsMap.erase(myPointIdsMap.find(anActor));
+         }
+       } else {
+         TVectorIds& aVectorIds = myCellIdsMap[anActor];
+         SelectVisibleCells(aSelectionPoint,
+                            theRenderer,
+                            aMapper->GetInput(),
+                            aVectorIds,
+                            this->Tolerance);
+         if ( aVectorIds.empty() ) {
+           myCellIdsMap.erase(myCellIdsMap.find(anActor));
+         }
+       }
+      }
+    }
+  }
+
+  // Invoke end pick method if defined
+  this->InvokeEvent(vtkCommand::EndPickEvent,NULL);
+
+  return myPointIdsMap.empty() || myCellIdsMap.empty();
 }
+
+
+//----------------------------------------------------------------------------
+const SVTK_RectPicker::TVectorIdsMap& 
+SVTK_RectPicker
+::GetPointIdsMap() const
+{
+  return myPointIdsMap;
+}
+
+const SVTK_RectPicker::TVectorIdsMap& 
+SVTK_RectPicker
+::GetCellIdsMap() const
+{
+  return myCellIdsMap;
+}
+
index f48949ec1426ccaaf85df20ba6624a0803b3f419..a9837c2d9cdc647f6a66a29c71dd73b8461d90af 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "SVTK.h"
 
+#include <map>
+#include <vector>
+
 #include <vtkAbstractPropPicker.h>
 
 class vtkRenderer;
@@ -48,19 +51,56 @@ class SVTK_EXPORT SVTK_RectPicker : public vtkAbstractPropPicker
 
   vtkTypeMacro(SVTK_RectPicker,vtkAbstractPropPicker);
   
+  /*! 
+    Specify tolerance for performing pick operation. Tolerance is specified
+    as fraction of rendering window size. (Rendering window size is measured
+    across diagonal.)
+  */
+  vtkSetMacro(Tolerance,float);
+  vtkGetMacro(Tolerance,float);
+
+  //! Use these methods to pick points or points and cells
+  vtkSetMacro(PickPoints,int);
+  vtkGetMacro(PickPoints,int);
+  vtkBooleanMacro(PickPoints,int);
+
   virtual 
   int
-  Pick(float selectionX1, float selectionY1, float selectionZ1
-       float selectionX2, float selectionY2, float selectionZ2,
-       vtkRenderer *renderer);  
+  Pick(float theSelectionX, float theSelectionY, float theSelectionZ
+       float theSelectionX2, float theSelectionY2, float theSelectionZ2,
+       vtkRenderer *theRenderer);  
 
   int
-  Pick(float selectionPt1[3], float selectionPt2[3], vtkRenderer *ren);
+  Pick(float theSelection[3], float theSelection2[3], vtkRenderer *theRenderer);
+
+  typedef std::vector<vtkIdType> TVectorIds;
+  typedef std::map<vtkActor*,TVectorIds> TVectorIdsMap;
+
+  const TVectorIdsMap& 
+  GetPointIdsMap() const;
+
+  const TVectorIdsMap& 
+  GetCellIdsMap() const;
 
  protected:
   SVTK_RectPicker();
   ~SVTK_RectPicker();
 
+  //! tolerance for computation (% of window)
+  float Tolerance;
+
+  //! use the following to control picking mode
+  int PickPoints;
+
+  //! second rectangle selection point in window (pixel) coordinates
+  float SelectionPoint2[3]; 
+
+  //! second rectangle selection point in world coordinates
+  float PickPosition2[3]; 
+
+  TVectorIdsMap myPointIdsMap;
+  TVectorIdsMap myCellIdsMap;
+
  private:
   virtual 
   int
index 3a5b42f84b1fe36afc109e4b9132c75d03d485b3..4ac2fe3e4c08acada454efe54880338024cd5096 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "SVTK_Trihedron.h"
 #include "SVTK_CubeAxesActor2D.h"
-#include "VTKViewer_CellRectPicker.h"
+#include "SVTK_RectPicker.h"
 
 #include "SALOME_Actor.h"
 #include "VTKViewer_Actor.h"
@@ -67,7 +67,8 @@ SVTK_Renderer
   myEventCallbackCommand(vtkCallbackCommand::New()),
   myPointPicker(vtkPointPicker::New()),
   myCellPicker(vtkCellPicker::New()),
-  myCellRectPicker(VTKViewer_CellRectPicker::New()),
+  myPointRectPicker(SVTK_RectPicker::New()),
+  myCellRectPicker(SVTK_RectPicker::New()),
   myPreHighlightProperty(vtkProperty::New()),
   myHighlightProperty(vtkProperty::New()),
   myTransform(VTKViewer_Transform::New()),
@@ -79,9 +80,16 @@ SVTK_Renderer
   myTransform->Delete();
 
   SetSelectionTolerance();
+
   myPointPicker->Delete();
   myCellPicker->Delete();
+
+  myPointRectPicker->Delete();
+  myPointRectPicker->PickFromListOn();
+
   myCellRectPicker->Delete();
+  myCellRectPicker->PickFromListOn();
+  myCellRectPicker->PickPointsOff();
 
   //SetPreselectionProp();
   myPreHighlightProperty->Delete();
@@ -207,6 +215,8 @@ SVTK_Renderer
 
     anActor->SetPointPicker(myPointPicker.GetPointer());
     anActor->SetCellPicker(myCellPicker.GetPointer());
+
+    anActor->SetPointRectPicker(myPointRectPicker.GetPointer());
     anActor->SetCellRectPicker(myCellRectPicker.GetPointer());
 
     anActor->SetPreHighlightProperty(myPreHighlightProperty.GetPointer());
@@ -230,6 +240,8 @@ SVTK_Renderer
 
     anActor->SetPointPicker(NULL);
     anActor->SetCellPicker(NULL);
+
+    anActor->SetPointRectPicker(NULL);
     anActor->SetCellRectPicker(NULL);
 
     anActor->SetPreHighlightProperty(NULL);
index 9770f46145401fcca4f5ad76b138b5fab51dd68c..5f486543ca9c3e9f5f1a7fe1be48cb531619cb73 100644 (file)
@@ -43,7 +43,7 @@ class vtkPointPicker;
 class vtkCellPicker;
 class vtkProperty;
 
-class VTKViewer_CellRectPicker;
+class SVTK_RectPicker;
 
 class VTKViewer_Trihedron;
 class VTKViewer_Transform;
@@ -228,7 +228,9 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject
   // Highlight/ Prehighlight devices
   vtkSmartPointer<vtkPointPicker> myPointPicker;
   vtkSmartPointer<vtkCellPicker> myCellPicker;
-  vtkSmartPointer<VTKViewer_CellRectPicker> myCellRectPicker;
+
+  vtkSmartPointer<SVTK_RectPicker> myPointRectPicker;
+  vtkSmartPointer<SVTK_RectPicker> myCellRectPicker;
 
   vtkSmartPointer<vtkProperty> myPreHighlightProperty;
   vtkSmartPointer<vtkProperty> myHighlightProperty;