From 684081068ebbcf36c5b698661ab4a7fb9f9b78ea Mon Sep 17 00:00:00 2001 From: apo Date: Fri, 13 Jan 2006 14:38:46 +0000 Subject: [PATCH] To redesign the rectangle picker Fix for Bug GVIEW11214 - Incorrect selection by area --- src/SVTK/Makefile.in | 2 + src/SVTK/SVTK_RectPicker.cxx | 255 +++++++++++++++++++++++++++++++++++ src/SVTK/SVTK_RectPicker.h | 72 ++++++++++ src/SVTK/SVTK_ViewWindow.cxx | 1 - 4 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 src/SVTK/SVTK_RectPicker.cxx create mode 100644 src/SVTK/SVTK_RectPicker.h diff --git a/src/SVTK/Makefile.in b/src/SVTK/Makefile.in index 0d7920eee..58c7e6fdb 100755 --- a/src/SVTK/Makefile.in +++ b/src/SVTK/Makefile.in @@ -17,6 +17,7 @@ EXPORT_HEADERS= \ SVTK_Prs.h \ SVTK_Actor.h \ SALOME_Actor.h \ + SVTK_RectPicker.h \ SVTK_DeviceActor.h \ SVTK_FontWidget.h \ SVTK_CubeAxesActor2D.h \ @@ -46,6 +47,7 @@ LIB_SRC= \ SVTK_Prs.cxx \ SVTK_Actor.cxx \ SALOME_Actor.cxx \ + SVTK_RectPicker.cxx \ SVTK_DeviceActor.cxx \ SVTK_CubeAxesActor2D.cxx \ SVTK_NonIsometricDlg.cxx \ diff --git a/src/SVTK/SVTK_RectPicker.cxx b/src/SVTK/SVTK_RectPicker.cxx new file mode 100644 index 000000000..2095a67d2 --- /dev/null +++ b/src/SVTK/SVTK_RectPicker.cxx @@ -0,0 +1,255 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// 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 +// +// +// +// File : SVTK_RectPicker.cxx +// Author : +// Module : SALOME + +#include "SVTK_RectPicker.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +namespace +{ + typedef std::vector TVectorIds; + + //---------------------------------------------------------------------------- + void + SelectVisiblePoints(int theSelection[4], + vtkRenderer *theRenderer, + vtkDataSet *theInput, + TVectorIds& theVectorIds, + float theTolerance = 0.001) + { + theVectorIds.clear(); + + vtkIdType aNumPts = theInput->GetNumberOfPoints(); + if(aNumPts < 1) + return; + + theVectorIds.reserve(aNumPts/2 + 1); + + // 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 + // WorldToView() is called. This is expensive, so we get the matrix once + // and handle the transformation ourselves. + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + 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]); + } + + float aX[4] = {1.0, 1.0, 1.0, 1.0}; + for(vtkIdType aPntId = 0; aPntId < aNumPts; aPntId++){ + // perform conversion + 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); + 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] ) + { + 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; + } + + if(anIsVisible) + theVectorIds.push_back(aPntId); + }//for all points + + aMatrix->Delete(); + + if(aZPtr) + delete [] aZPtr; + } + + + //---------------------------------------------------------------------------- + void + SelectVisibleCells(int theSelection[4], + vtkRenderer *theRenderer, + vtkDataSet *theInput, + TVectorIds& theVectorIds, + float theTolerance = 0.001) + { + theVectorIds.clear(); + + vtkIdType aNumCells = theInput->GetNumberOfCells(); + if(aNumCells < 1) + return; + + theVectorIds.reserve(aNumCells/2 + 1); + + // 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 + // WorldToView() is called. This is expensive, so we get the matrix once + // and handle the transformation ourselves. + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + 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; + vtkCell* aCell = theInput->GetCell(aCellId); + vtkIdType aNumPts = aCell->GetNumberOfPoints(); + 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; + } + } + } + if(anIsVisible) + theVectorIds.push_back(aCellId); + }//for all parts + + aMatrix->Delete(); + + if(aZPtr) + delete [] aZPtr; + } +} + +//---------------------------------------------------------------------------- +vtkStandardNewMacro(SVTK_RectPicker); + +//---------------------------------------------------------------------------- +SVTK_RectPicker +::SVTK_RectPicker() +{} + +SVTK_RectPicker +::~SVTK_RectPicker() +{} + +int +SVTK_RectPicker +::Pick(float, float, float, vtkRenderer*) +{ + return 0; +} + +//---------------------------------------------------------------------------- +int +SVTK_RectPicker +::Pick(float selectionPt1[3], float selectionPt2[3], vtkRenderer *ren) +{ + return Pick(selectionPt1[0], selectionPt1[1], selectionPt1[2], + selectionPt2[0], selectionPt2[1], selectionPt2[2], + ren); +} + +//---------------------------------------------------------------------------- +int +SVTK_RectPicker +::Pick(float selectionX1, float selectionY1, float selectionZ1, + float selectionX2, float selectionY2, float selectionZ2, + vtkRenderer *renderer) +{ + return 0; +} diff --git a/src/SVTK/SVTK_RectPicker.h b/src/SVTK/SVTK_RectPicker.h new file mode 100644 index 000000000..f48949ec1 --- /dev/null +++ b/src/SVTK/SVTK_RectPicker.h @@ -0,0 +1,72 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// 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 +// +// +// +// File : SVTK_RectPicker.h +// Author : +// Module : SALOME + +#ifndef __SVTK_RectPicker_h +#define __SVTK_RectPicker_h + +#include "SVTK.h" + +#include + +class vtkRenderer; + +/*! \class vtkAbstractPropPicker + * \brief For more information see VTK documentation + */ +/*! \class VTKViewer_RectPicker + * \brief Rectangular picker class. + */ +class SVTK_EXPORT SVTK_RectPicker : public vtkAbstractPropPicker +{ + public: + static + SVTK_RectPicker *New(); + + vtkTypeMacro(SVTK_RectPicker,vtkAbstractPropPicker); + + virtual + int + Pick(float selectionX1, float selectionY1, float selectionZ1, + float selectionX2, float selectionY2, float selectionZ2, + vtkRenderer *renderer); + + int + Pick(float selectionPt1[3], float selectionPt2[3], vtkRenderer *ren); + + protected: + SVTK_RectPicker(); + ~SVTK_RectPicker(); + + private: + virtual + int + Pick(float, float, float, vtkRenderer*); +}; + +#endif + + diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index f3dd67bb9..b95a23d20 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -41,7 +41,6 @@ #include "SUIT_Accel.h" #include "VTKViewer_Utilities.h" -#include "VTKViewer_CellRectPicker.h" #include "SVTK_View.h" #include "SVTK_MainWindow.h" -- 2.39.2