From 981fd0666e1bb259eba688c0f35e48cfcd34c6df Mon Sep 17 00:00:00 2001 From: ouv Date: Tue, 24 Apr 2012 10:52:33 +0000 Subject: [PATCH] GUITHARE issue 0001070: External 20578: Probe C3 (on overlapped presentations) --- src/SVTK/SALOME_Actor.cxx | 13 ++++ src/SVTK/SALOME_Actor.h | 7 +++ src/SVTK/SVTK_Renderer.cxx | 124 ++++++++++++++++++++++++++++++++++--- src/SVTK/SVTK_Renderer.h | 32 +++++++++- 4 files changed, 165 insertions(+), 11 deletions(-) diff --git a/src/SVTK/SALOME_Actor.cxx b/src/SVTK/SALOME_Actor.cxx index 589dee0aa..9583cc3f2 100644 --- a/src/SVTK/SALOME_Actor.cxx +++ b/src/SVTK/SALOME_Actor.cxx @@ -163,6 +163,7 @@ SALOME_Actor ::SALOME_Actor(): myRenderer(NULL), myInteractor(NULL), + myPrehighlightedCellId(-1), mySelectionMode(ActorSelection), myPreHighlightActor(SVTK_Actor::New()), myHighlightActor(SVTK_Actor::New()), @@ -448,6 +449,7 @@ SALOME_Actor SVTK_SelectionEvent* theSelectionEvent, bool theIsHighlight) { + myPrehighlightedCellId = -1; if ( !GetPickable() ) return false; @@ -517,6 +519,7 @@ SALOME_Actor if ( anObjId >= 0 ) { myIsPreselected = CheckDimensionId(aSelectionMode,this,anObjId); if(myIsPreselected){ + myPrehighlightedCellId = anObjId; const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex(); int anExtent = aMapIndex.Extent(); anIsChanged |= (anExtent == 0 || anExtent > 0 && anObjId != aMapIndex(1)); @@ -594,6 +597,16 @@ SALOME_Actor return anIsChanged; } +/*! + Returns id of the prehighlighted cell (-1 if no cell is highlighted) +*/ +int +SALOME_Actor +::GetPrehighlightedCellId() const +{ + return myPrehighlightedCellId; +} + /*! To process highlight (called from SVTK_InteractorStyle) */ diff --git a/src/SVTK/SALOME_Actor.h b/src/SVTK/SALOME_Actor.h index e51d4eb43..8c635f5f4 100644 --- a/src/SVTK/SALOME_Actor.h +++ b/src/SVTK/SALOME_Actor.h @@ -171,6 +171,11 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor SVTK_SelectionEvent* theSelectionEvent, bool theIsHighlight); + //! Returns id of the prehighlighted cell (-1 if no cell is highlighted) + virtual + int + GetPrehighlightedCellId() const; + //! To process highlight (called from #SVTK_InteractorStyle) virtual bool @@ -214,6 +219,8 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor Handle(SALOME_InteractiveObject) myIO; + int myPrehighlightedCellId; + SALOME_Actor(); ~SALOME_Actor(); diff --git a/src/SVTK/SVTK_Renderer.cxx b/src/SVTK/SVTK_Renderer.cxx index cab5ca695..c2fd4ea62 100644 --- a/src/SVTK/SVTK_Renderer.cxx +++ b/src/SVTK/SVTK_Renderer.cxx @@ -37,25 +37,26 @@ #include "VTKViewer_Transform.h" #include "VTKViewer_Utilities.h" -#include -#include -#include -#include +#include #include - +#include +#include +#include +#include #include #include -#include - #include +#include +#include +#include // undefining min and max because CASCADE's defines them and // it clashes with std::min(), std::max() included in utilities.h #undef min #undef max - vtkStandardNewMacro(SVTK_Renderer); +vtkStandardNewMacro(SVTK_CellPicker); /*! Constructor @@ -67,7 +68,7 @@ SVTK_Renderer myPriority(0.0), myEventCallbackCommand(vtkCallbackCommand::New()), myPointPicker(vtkPointPicker::New()), - myCellPicker(vtkCellPicker::New()), + myCellPicker(SVTK_CellPicker::New()), myPointRectPicker(SVTK_RectPicker::New()), myCellRectPicker(SVTK_RectPicker::New()), myPreHighlightProperty(vtkProperty::New()), @@ -751,3 +752,108 @@ SVTK_Renderer aCamera->SetFocalPoint(0,0,0); this->OnFitAll(); } + +/*! + SVTK_CellPicker constructor +*/ +SVTK_CellPicker::SVTK_CellPicker() +{ + this->Cell = vtkGenericCell::New(); +} + +/*! + SVTK_CellPicker destructor +*/ +SVTK_CellPicker::~SVTK_CellPicker() +{ + this->Cell->Delete(); +} + +/*! + Redefined virtual method of the vtkCellPicker class +*/ +double SVTK_CellPicker::IntersectWithLine(double p1[3], double p2[3], double tol, + vtkAssemblyPath *path, + vtkProp3D *prop3D, + vtkAbstractMapper3D *m) +{ + vtkIdType numCells, cellId, minCellId; + int i, minSubId, subId; + double x[3], tMin, t, pcoords[3], minXYZ[3], minPcoords[3]; + vtkDataSet *input; + vtkMapper *mapper; + vtkAbstractVolumeMapper *volumeMapper; + + // Get the underlying dataset + if ( (mapper=vtkMapper::SafeDownCast(m)) != NULL ) + { + input = mapper->GetInput(); + } + else if ( (volumeMapper=vtkAbstractVolumeMapper::SafeDownCast(m)) != NULL ) + { + input = volumeMapper->GetDataSetInput(); + } + else + { + return VTK_DOUBLE_MAX; + } + + if ( (numCells = input->GetNumberOfCells()) < 1 ) + { + return 2.0; + } + + // Intersect each cell with ray. Keep track of one closest to + // the eye (within the tolerance tol) and within the clipping range). + // Note that we fudge the "closest to" (tMin+this->Tolerance) a little and + // keep track of the cell with the best pick based on parametric + // coordinate (pick the minimum, maximum parametric distance). This + // breaks ties in a reasonable way when cells are the same distance + // from the eye (like cells lying on a 2D plane). + // + minCellId = -1; + minSubId = -1; + pcoords[0] = pcoords[1] = pcoords[2] = 0; + double pDistMin=VTK_DOUBLE_MAX, pDist; + for (tMin=VTK_DOUBLE_MAX,cellId=0; cellIdGetCell(cellId, this->Cell); + + if ( this->Cell->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId) + && t <= (tMin+this->Tolerance) ) + { + pDist = this->Cell->GetParametricDistance(pcoords); + // This is the only difference of this method from the vtkCellPicker's one + static double aTolerance = 1E-7; + //if ( pDist < pDistMin || (pDist == pDistMin && t < tMin ) ) + if ( pDist < pDistMin || (pDist == pDistMin && t < tMin + aTolerance ) ) + { + minCellId = cellId; + minSubId = subId; + for (i=0; i<3; i++) + { + minXYZ[i] = x[i]; + minPcoords[i] = pcoords[i]; + } + tMin = t; + pDistMin = pDist; +// cout << "cell id: " << minCellId << "\n"; + }//if minimum, maximum + }//if a close cell + }//for all cells + + // Now compare this against other actors. + // + if ( minCellId>(-1) && tMin < this->GlobalTMin ) + { + this->MarkPicked(path, prop3D, m, tMin, minXYZ); + this->CellId = minCellId; + this->SubId = minSubId; + for (i=0; i<3; i++) + { + this->PCoords[i] = minPcoords[i]; + } + vtkDebugMacro("Picked cell id= " << minCellId); + } + return tMin; +} diff --git a/src/SVTK/SVTK_Renderer.h b/src/SVTK/SVTK_Renderer.h index 8dbd981b2..1b08d5965 100644 --- a/src/SVTK/SVTK_Renderer.h +++ b/src/SVTK/SVTK_Renderer.h @@ -34,6 +34,7 @@ #include #include +#include class vtkRenderer; class vtkCallbackCommand; @@ -41,7 +42,6 @@ class vtkRenderWindowInteractor; class vtkPicker; class vtkPointPicker; -class vtkCellPicker; class vtkProperty; class SVTK_RectPicker; @@ -51,6 +51,7 @@ class VTKViewer_Transform; class SVTK_CubeAxesActor2D; class VTKViewer_Actor; class SVTK_Selector; +class SVTK_CellPicker; #ifdef WIN32 #pragma warning ( disable:4251 ) @@ -236,7 +237,7 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject //---------------------------------------------------------------------------- // Highlight/ Prehighlight devices vtkSmartPointer myPointPicker; - vtkSmartPointer myCellPicker; + vtkSmartPointer myCellPicker; vtkSmartPointer myPointRectPicker; vtkSmartPointer myCellRectPicker; @@ -252,6 +253,33 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject vtkFloatingPointType myBndBox[6]; }; +/*! + \class SVTK_CellPicker + The class is intended to redefine the IntersectWithLine() + to correct the mechanism of picking coincident cells +*/ +class SVTK_CellPicker : public vtkCellPicker +{ +public: + static SVTK_CellPicker* New(); + vtkTypeMacro(SVTK_CellPicker,vtkCellPicker); + +protected: + SVTK_CellPicker(); + ~SVTK_CellPicker(); + + virtual double IntersectWithLine(double p1[3], double p2[3], double tol, + vtkAssemblyPath *path, vtkProp3D *p, + vtkAbstractMapper3D *m); + +private: + vtkGenericCell *Cell; //used to accelerate picking + +private: + SVTK_CellPicker(const SVTK_CellPicker&); // Not implemented. + void operator=(const SVTK_CellPicker&); // Not implemented. +}; + #ifdef WIN32 //#pragma warning ( default:4251 ) #endif -- 2.39.2