From c511d17aaa71086e204b3b63f3199702fbe7fb77 Mon Sep 17 00:00:00 2001 From: enk Date: Wed, 31 Oct 2007 13:38:21 +0000 Subject: [PATCH] Selection improvement Added changes from current version of SALOME --- src/SVTK/SVTK_Event.h | 8 + src/SVTK/SVTK_InteractorStyle.cxx | 277 ++++++++++++++++++++++++-- src/SVTK/SVTK_InteractorStyle.h | 19 +- src/SVTK/SVTK_Renderer.cxx | 8 +- src/SVTK/SVTK_Renderer.h | 3 +- src/SVTK/SVTK_Selector.cxx | 82 +++++++- src/SVTK/SVTK_Selector.h | 17 +- src/SVTK/SVTK_SelectorDef.h | 15 ++ src/SVTK/SVTK_View.cxx | 5 +- src/SVTK/SVTK_View.h | 3 +- src/SVTK/SVTK_ViewWindow.cxx | 10 +- src/SVTK/SVTK_ViewWindow.h | 3 +- src/VTKViewer/VTKViewer_Utilities.cxx | 103 ++++++++++ src/VTKViewer/VTKViewer_Utilities.h | 8 + 14 files changed, 509 insertions(+), 52 deletions(-) diff --git a/src/SVTK/SVTK_Event.h b/src/SVTK/SVTK_Event.h index fa415ab83..8b2d1bdb0 100644 --- a/src/SVTK/SVTK_Event.h +++ b/src/SVTK/SVTK_Event.h @@ -61,6 +61,14 @@ namespace SVTK StartGlobalPan, StartFitArea, + SetRotateGravity, + StartPointSelection, + SetRotateSelected, + + BBCenterChanged, + RotationPointChanged, + ChangeRotationPoint, + LastEvent }; } diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index 4f8dfaa60..7ba576467 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -36,6 +36,7 @@ #include "SVTK_Event.h" #include "SVTK_Selector.h" #include "SVTK_Functor.h" +#include "SVTK_Actor.h" #include "VTKViewer_Algorithm.h" #include "SVTK_Functor.h" @@ -47,11 +48,14 @@ #include #include #include -#include +#include #include #include #include #include +#include +#include +#include #include #include @@ -62,6 +66,8 @@ //VRV: porting on Qt 3.0.5 #include +//#include + using namespace std; namespace @@ -100,19 +106,23 @@ namespace vtkStandardNewMacro(SVTK_InteractorStyle); + /*! Constructor */ SVTK_InteractorStyle ::SVTK_InteractorStyle(): mySelectionEvent(new SVTK_SelectionEvent()), - myPicker(vtkPicker::New()), + myPointPicker(vtkPointPicker::New()), myLastHighlitedActor(NULL), myLastPreHighlitedActor(NULL), myControllerIncrement(SVTK_ControllerIncrement::New()), - myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()) + myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()), + myHighlightRotationPointActor(SVTK_Actor::New()) { - myPicker->Delete(); + myPointPicker->Delete(); + + myPointPicker->SetTolerance(0.025); this->MotionFactor = 10.0; this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE; @@ -131,6 +141,20 @@ SVTK_InteractorStyle // myControllerIncrement->Delete(); myControllerOnKeyDown->Delete(); + + myCurrRotationPointType = SVTK::SetRotateGravity; + myPrevRotationPointType = myCurrRotationPointType; + + myHighlightRotationPointActor->Delete(); + myHighlightRotationPointActor->Initialize(); + myHighlightRotationPointActor->PickableOff(); + myHighlightRotationPointActor->SetVisibility( false ); + + myHighlightRotationPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2); + myHighlightRotationPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2); + myHighlightRotationPointActor->GetProperty()->SetRepresentationToPoints(); + + myBBFirstCheck = true; } /*! @@ -205,7 +229,7 @@ void SVTK_InteractorStyle ::RotateXY(int dx, int dy) { - if(GetCurrentRenderer() == NULL) + /* if(GetCurrentRenderer() == NULL) return; int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize(); @@ -222,6 +246,61 @@ SVTK_InteractorStyle GetCurrentRenderer()->ResetCameraClippingRange(); + this->Render();*/ + + if(GetCurrentRenderer() == NULL) + return; + + vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera(); + + double viewFP[3], viewPos[3]; + cam->GetFocalPoint(viewFP); + cam->GetPosition(viewPos); + + if ( myCurrRotationPointType == SVTK::SetRotateGravity ) + { + vtkFloatingPointType aCenter[3]; + if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) ) + { + myRotationPointX = aCenter[0]; + myRotationPointY = aCenter[1]; + myRotationPointZ = aCenter[2]; + } + } + + // Calculate corresponding transformation + vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New(); + aTransform->Identity(); + aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ); + + // Azimuth transformation + int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize(); + double aDeltaAzimuth = -20.0 / size[0]; + + double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor; + aTransform->RotateWXYZ(rxf, cam->GetViewUp()); + + // Elevation transformation + double aDeltaElevation = -20.0 / size[1]; + + double ryf = double(dy) * aDeltaElevation * this->MotionFactor; + vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix(); + const double anAxis[3] = {-aMatrix->GetElement(0,0), // mkr : 27.11.2006 : PAL14011 - Strange behaviour in rotation in VTK Viewer. + -aMatrix->GetElement(0,1), + -aMatrix->GetElement(0,2)}; + + aTransform->RotateWXYZ(ryf, anAxis); + + aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ); + + // To apply the transformation + cam->SetPosition(aTransform->TransformPoint(viewPos)); + cam->SetFocalPoint(aTransform->TransformPoint(viewFP)); + + cam->OrthogonalizeViewUp(); + + GetCurrentRenderer()->ResetCameraClippingRange(); + this->Render(); } @@ -431,9 +510,53 @@ SVTK_InteractorStyle } else { if (ctrl) startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); + else if ( myCurrRotationPointType == SVTK::StartPointSelection ) + { + SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY(); + + SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + + if ( anActor ) + { + myPointPicker->Pick( aSelectionEvent->myX, + aSelectionEvent->myY, + 0.0, + GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) + { + int anObjId = anActor->GetNodeObjId( aVtkId ); + vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId); + + myCurrRotationPointType = SVTK::SetRotateSelected; + + // invoke event for update coordinates in SVTK_SetRotationPointDlg + InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords); + } + else + { + // invoke event with no data (for SVTK_SetRotationPointDlg) + InvokeEvent(SVTK::RotationPointChanged,0); + myCurrRotationPointType = myPrevRotationPointType; + } + } + else + { + // invoke event with no data (for SVTK_SetRotationPointDlg) + InvokeEvent(SVTK::RotationPointChanged,0); + myCurrRotationPointType = myPrevRotationPointType; + } + + myHighlightRotationPointActor->SetVisibility( false ); + if(GetCurrentRenderer() != NULL) + GetCurrentRenderer()->RemoveActor( myHighlightRotationPointActor.GetPointer() ); + + GetRenderWidget()->setCursor(myDefCursor); + } else startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT); } + return; } @@ -696,6 +819,26 @@ SVTK_InteractorStyle ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE; } +/*! + Set rotation point selected by user +*/ +void +SVTK_InteractorStyle +::startPointSelection() +{ + myCurrRotationPointType = SVTK::StartPointSelection; + + if(GetCurrentRenderer() != NULL) { + GetCurrentRenderer()->AddActor( myHighlightRotationPointActor.GetPointer() ); + vtkFloatingPointType aColor[3]; + GetCurrentRenderer()->GetBackground( aColor ); + myHighlightRotationPointActor->GetProperty()->SetColor(1. - aColor[0], + 1. - aColor[1], + 1. - aColor[2]); + } + + setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE); +} /*! Starts Spin operation (e.g. through menu command) @@ -863,7 +1006,10 @@ SVTK_InteractorStyle break; case VTK_INTERACTOR_STYLE_CAMERA_NONE: default: - GetRenderWidget()->setCursor(myDefCursor); + if ( myCurrRotationPointType == SVTK::StartPointSelection ) + GetRenderWidget()->setCursor(myHandCursor); + else + GetRenderWidget()->setCursor(myDefCursor); myCursorState = false; break; } @@ -947,12 +1093,8 @@ SVTK_InteractorStyle this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY); Interactor->StartPickCallback(); - myPicker->Pick(aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer()); - // - SALOME_Actor* anActor = GetFirstSALOMEActor(myPicker.GetPointer()); + SALOME_Actor* anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); + aSelectionEvent->myIsRectangle = false; if(!myShiftState) @@ -961,8 +1103,9 @@ SVTK_InteractorStyle if(anActor){ anActor->Highlight( this, aSelectionEvent, true ); }else{ - if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor) + if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor) { myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); + } } myLastHighlitedActor = anActor; } @@ -1083,19 +1226,44 @@ SVTK_InteractorStyle bool anIsChanged = false; - myPicker->Pick(aSelectionEvent->myX, - aSelectionEvent->myY, - 0.0, - GetCurrentRenderer()); + SALOME_Actor *anActor = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); - SALOME_Actor *anActor = GetFirstSALOMEActor(myPicker.GetPointer()); - if (anActor){ - anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true ); + if ( myCurrRotationPointType == SVTK::StartPointSelection ) + { + myHighlightRotationPointActor->SetVisibility( false ); + + SALOME_Actor *anCurrActor; + if ( anActor ) anCurrActor = anActor; + else if ( myLastPreHighlitedActor.GetPointer() + && + myLastPreHighlitedActor.GetPointer() != anActor ) + anCurrActor = myLastPreHighlitedActor.GetPointer(); + if ( anCurrActor ) + { + myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) { + int anObjId = anActor->GetNodeObjId( aVtkId ); + + TColStd_IndexedMapOfInteger aMapIndex; + aMapIndex.Add( anObjId ); + myHighlightRotationPointActor->MapPoints( anActor, aMapIndex ); + + myHighlightRotationPointActor->SetVisibility( true ); + anIsChanged = true; + } + } } + else { + if (anActor){ + anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true ); + } - if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor) - anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false ); + if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor) + anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false ); + } + myLastPreHighlitedActor = anActor; if(anIsChanged) @@ -1225,6 +1393,11 @@ SVTK_InteractorStyle theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority ); theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority ); theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority ); + + theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority ); + theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority ); + + theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority ); } } @@ -1237,6 +1410,30 @@ SVTK_InteractorStyle { //vtkInteractorStyle::OnTimer(); this->Interactor->Render(); + // check if bounding box was changed + if ( GetCurrentRenderer() ) + { + vtkFloatingPointType aCurrBBCenter[3]; + if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) ) + { + if ( !myBBFirstCheck ) + { + if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 || + fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 || + fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) { + // bounding box was changed => send SVTK::RotationPointChanged event + // invoke event for update coordinates in SVTK_SetRotationPointDlg + InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter); + for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i]; + } + } + else + { + for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i]; + myBBFirstCheck = false; + } + } + } } /*! @@ -1299,6 +1496,8 @@ SVTK_InteractorStyle vtkObject* anObject = reinterpret_cast( clientData ); SVTK_InteractorStyle* self = dynamic_cast( anObject ); int aSpeedIncrement=self->ControllerIncrement()->Current(); + vtkFloatingPointType aCenter[3]; + vtkFloatingPointType* aSelectedPoint; if ( self ) { switch ( event ) { case SVTK::SpaceMouseMoveEvent : @@ -1372,6 +1571,40 @@ SVTK_InteractorStyle case SVTK::StartFitArea: self->startFitArea(); return; + + case SVTK::SetRotateGravity: + if ( self->myCurrRotationPointType == SVTK::StartPointSelection ) + { + self->myHighlightRotationPointActor->SetVisibility( false ); + if( self->GetCurrentRenderer() != NULL ) + self->GetCurrentRenderer()->RemoveActor( self->myHighlightRotationPointActor.GetPointer() ); + self->GetRenderWidget()->setCursor(self->myDefCursor); + } + self->myPrevRotationPointType = self->myCurrRotationPointType; + self->myCurrRotationPointType = SVTK::SetRotateGravity; + if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) + // invoke event for update coordinates in SVTK_SetRotationPointDlg + self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter); + return; + case SVTK::StartPointSelection: + self->startPointSelection(); + return; + + case SVTK::ChangeRotationPoint: + if ( self->myCurrRotationPointType == SVTK::StartPointSelection ) + { + self->myHighlightRotationPointActor->SetVisibility( false ); + if( self->GetCurrentRenderer() != NULL ) + self->GetCurrentRenderer()->RemoveActor( self->myHighlightRotationPointActor.GetPointer() ); + self->GetRenderWidget()->setCursor(self->myDefCursor); + } + self->myPrevRotationPointType = self->myCurrRotationPointType; + self->myCurrRotationPointType = SVTK::SetRotateSelected; + aSelectedPoint = (vtkFloatingPointType*)callData; + self->myRotationPointX = aSelectedPoint[0]; + self->myRotationPointY = aSelectedPoint[1]; + self->myRotationPointZ = aSelectedPoint[2]; + return; } } } diff --git a/src/SVTK/SVTK_InteractorStyle.h b/src/SVTK/SVTK_InteractorStyle.h index 90057f5a8..712f5c3fd 100644 --- a/src/SVTK/SVTK_InteractorStyle.h +++ b/src/SVTK/SVTK_InteractorStyle.h @@ -104,12 +104,13 @@ class SVTK_EXPORT SVTK_ControllerOnKeyDown : public vtkObject{ }; class vtkCell; -class vtkPicker; +class vtkPointPicker; class SALOME_Actor; class SVTK_Selector; class SVTK_GenericRenderWindowInteractor; +class SVTK_Actor; #define VTK_INTERACTOR_STYLE_CAMERA_NONE 0 #define VTK_INTERACTOR_STYLE_CAMERA_ROTATE 1 @@ -119,6 +120,7 @@ class SVTK_GenericRenderWindowInteractor; #define VTK_INTERACTOR_STYLE_CAMERA_FIT 5 #define VTK_INTERACTOR_STYLE_CAMERA_SELECT 6 #define VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN 7 +#define VTK_INTERACTOR_STYLE_CAMERA_SELECT_ROTATION_POINT 8 //! Introduce SALOME way of user interaction /*! @@ -278,6 +280,8 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle void startFitArea(); void startSpin(); + void startPointSelection(); + protected: void loadCursors(); void startOperation(int operation); @@ -324,7 +328,18 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle PSelectionEvent mySelectionEvent; - vtkSmartPointer myPicker; + unsigned long myCurrRotationPointType; + unsigned long myPrevRotationPointType; + + double myRotationPointX; + double myRotationPointY; + double myRotationPointZ; + + vtkSmartPointer myHighlightRotationPointActor; + vtkSmartPointer myPointPicker; + + vtkFloatingPointType myBBCenter[3]; + bool myBBFirstCheck; }; #ifdef WIN32 diff --git a/src/SVTK/SVTK_Renderer.cxx b/src/SVTK/SVTK_Renderer.cxx index d3020f1c1..155e419ca 100644 --- a/src/SVTK/SVTK_Renderer.cxx +++ b/src/SVTK/SVTK_Renderer.cxx @@ -81,8 +81,6 @@ SVTK_Renderer myDevice->Delete(); myTransform->Delete(); - SetSelectionTolerance(); - myPointPicker->Delete(); myCellPicker->Delete(); @@ -225,6 +223,7 @@ SVTK_Renderer { myInteractor = theInteractor; mySelector = theSelector; + SetSelectionTolerance(); } /*! @@ -348,13 +347,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 ); + + mySelector->SetTolerance( theTolObjects ); } diff --git a/src/SVTK/SVTK_Renderer.h b/src/SVTK/SVTK_Renderer.h index 3e44d5fe4..5c24cefa1 100644 --- a/src/SVTK/SVTK_Renderer.h +++ b/src/SVTK/SVTK_Renderer.h @@ -122,7 +122,8 @@ class SVTK_EXPORT SVTK_Renderer : public vtkObject //! Setup requested tolerance for the picking void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); //---------------------------------------------------------------------------- //! Adjust all intenal actors (trihedron and graduated rules) to the scene diff --git a/src/SVTK/SVTK_Selector.cxx b/src/SVTK/SVTK_Selector.cxx index d93bd4b44..ead47cbbc 100644 --- a/src/SVTK/SVTK_Selector.cxx +++ b/src/SVTK/SVTK_Selector.cxx @@ -35,6 +35,27 @@ #include #include +#include +#include + + +/*! + Find first SALOME_Actor from the end of actors collection +*/ +inline +SALOME_Actor* +GetLastSALOMEActor(vtkActorCollection* theCollection) +{ + if (theCollection) { + for (int i = theCollection->GetNumberOfItems() - 1; i >= 0; i--) { + if (SALOME_Actor* anActor = dynamic_cast(theCollection->GetItemAsObject(i))) + if (anActor->hasIO()) + return anActor; + } + } + return NULL; +} + /*! \return new SVTK_Selector @@ -50,9 +71,14 @@ SVTK_Selector Default constructor */ SVTK_SelectorDef -::SVTK_SelectorDef() +::SVTK_SelectorDef(): + myPicker(vtkPicker::New()), + myCellPicker(vtkCellPicker::New()) { mySelectionMode = ActorSelection; + + myPicker->Delete(); + myCellPicker->Delete(); } /*! @@ -280,13 +306,16 @@ SVTK_SelectorDef TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO); if(anIter != myMapIOSubIndex.end()){ const TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap; - return aMapIndex.Contains( theIndex ) == Standard_True; + return aMapIndex.Contains(theIndex); } return false; } -static bool removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, const int theIndex) +static +bool +removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, + const int theIndex) { int anId = theMapIndex.FindIndex(theIndex); // i==0 if Index is not in the MapIndex if(anId){ @@ -305,7 +334,7 @@ static bool removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, const int theI theMapIndex = aNewMap; } } - return anId != 0; + return anId; } /*! @@ -399,18 +428,18 @@ SVTK_SelectorDef } TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap; - bool anIsConatains = aMapIndex.Contains( theIndex ) == Standard_True; - if ( anIsConatains ) - removeIndex( aMapIndex, theIndex ); + bool anIsConatains = aMapIndex.Contains(theIndex); + if(anIsConatains) + removeIndex(aMapIndex,theIndex); - if ( !theIsModeShift ) + if(!theIsModeShift) aMapIndex.Clear(); - if ( !anIsConatains ) + if(!anIsConatains) aMapIndex.Add( theIndex ); - if ( aMapIndex.IsEmpty() ) - myMapIOSubIndex.erase( theIO ); + if( aMapIndex.IsEmpty()) + myMapIOSubIndex.erase(theIO); return false; } @@ -515,3 +544,34 @@ SVTK_SelectorDef return Handle(VTKViewer_Filter)(); } +SALOME_Actor* +SVTK_SelectorDef +::Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const +{ + myCellPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + + vtkActorCollection* aListActors = myCellPicker->GetActors(); + SALOME_Actor* anActor = GetLastSALOMEActor(aListActors); + + if (! anActor) { + myPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + aListActors = myPicker->GetActors(); + anActor = GetLastSALOMEActor(aListActors); + } + + return anActor; +} + +void +SVTK_SelectorDef +::SetTolerance(const double& theTolerance) +{ + myPicker->SetTolerance(theTolerance); + myCellPicker->SetTolerance(theTolerance); +} diff --git a/src/SVTK/SVTK_Selector.h b/src/SVTK/SVTK_Selector.h index 380e28b31..ae11f7710 100644 --- a/src/SVTK/SVTK_Selector.h +++ b/src/SVTK/SVTK_Selector.h @@ -29,7 +29,6 @@ #ifndef SVTK_SELECTOR_H #define SVTK_SELECTOR_H -#include "SVTK.h" #include "SVTK_Selection.h" #include "SALOME_ListIO.hxx" #include "VTKViewer_Filter.h" @@ -42,6 +41,11 @@ class SALOME_Actor; +struct SVTK_SelectionEvent; + +class vtkRenderer; + + //! Define an abstract interface for selection in SVTK package /*! The class implements selection functionality through storing corresponding @@ -50,7 +54,7 @@ class SALOME_Actor; \note Also, for each #SALOME_InteractiveObject it tries to keep corresponding refenrence to #SALOME_Actor */ -class SVTK_EXPORT SVTK_Selector: public vtkObject +class SVTK_Selector: public vtkObject { public: static SVTK_Selector* New(); @@ -205,6 +209,15 @@ public: virtual void EndPickCallback() = 0; + + //---------------------------------------------------------------------------- + virtual + SALOME_Actor* + Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const =0; + + virtual + void + SetTolerance(const double& theTolerance) = 0; }; diff --git a/src/SVTK/SVTK_SelectorDef.h b/src/SVTK/SVTK_SelectorDef.h index e20d764ec..634d7297b 100644 --- a/src/SVTK/SVTK_SelectorDef.h +++ b/src/SVTK/SVTK_SelectorDef.h @@ -43,6 +43,9 @@ class SALOME_Actor; class SVTK_Viewer; class SVTK_ViewWindow; +class vtkPicker; +class vtkCellPicker; + class SVTK_SelectorDef: public SVTK_Selector { public: @@ -165,6 +168,15 @@ public: void EndPickCallback(); + //---------------------------------------------------------------------------- + virtual + SALOME_Actor* + Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const; + + virtual + void + SetTolerance(const double& theTolerance); + private: int mySelectionMode; @@ -206,6 +218,9 @@ private: typedef std::map TFilters; TFilters myFilters; + + vtkSmartPointer myPicker; + vtkSmartPointer myCellPicker; }; #endif diff --git a/src/SVTK/SVTK_View.cxx b/src/SVTK/SVTK_View.cxx index 882728b3a..34ea47300 100644 --- a/src/SVTK/SVTK_View.cxx +++ b/src/SVTK/SVTK_View.cxx @@ -259,9 +259,10 @@ SVTK_View void SVTK_View ::SetSelectionTolerance(const double& theTolNodes, - const double& theTolCell) + const double& theTolCell, + const double& theTolObjects) { - GetRenderer()->SetSelectionTolerance(theTolNodes,theTolCell); + GetRenderer()->SetSelectionTolerance(theTolNodes,theTolCell, theTolObjects); } /*! diff --git a/src/SVTK/SVTK_View.h b/src/SVTK/SVTK_View.h index 4c25de9bc..c7cc984b9 100644 --- a/src/SVTK/SVTK_View.h +++ b/src/SVTK/SVTK_View.h @@ -251,7 +251,8 @@ public: //! Redirect the request to #SVTK_Renderer::SetPreselectionProp void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); protected: int myDisplayMode; diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 667f406c3..8fbb70053 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -61,7 +61,6 @@ #include "VTKViewer_Algorithm.h" #include "SVTK_Functor.h" - namespace SVTK { int convertAction( const int accelAction ) @@ -82,10 +81,6 @@ namespace SVTK } } - - - - /*! Constructor */ @@ -758,9 +753,10 @@ SVTK_ViewWindow void SVTK_ViewWindow ::SetSelectionTolerance(const double& theTolNodes, - const double& theTolItems) + const double& theTolItems, + const double& theTolObjects) { - myView->SetSelectionTolerance(theTolNodes,theTolItems); + myView->SetSelectionTolerance(theTolNodes,theTolItems, theTolObjects); } /*! diff --git a/src/SVTK/SVTK_ViewWindow.h b/src/SVTK/SVTK_ViewWindow.h index 809168505..14b79945b 100755 --- a/src/SVTK/SVTK_ViewWindow.h +++ b/src/SVTK/SVTK_ViewWindow.h @@ -249,7 +249,8 @@ class SVTK_EXPORT SVTK_ViewWindow : public SUIT_ViewWindow virtual void SetSelectionTolerance(const double& theTolNodes = 0.025, - const double& theTolCell = 0.001); + const double& theTolCell = 0.001, + const double& theTolObjects = 0.025); //! Methods to save/restore visual parameters of a view (pan, zoom, etc.) virtual diff --git a/src/VTKViewer/VTKViewer_Utilities.cxx b/src/VTKViewer/VTKViewer_Utilities.cxx index 5f061a64b..51ae53568 100755 --- a/src/VTKViewer/VTKViewer_Utilities.cxx +++ b/src/VTKViewer/VTKViewer_Utilities.cxx @@ -214,3 +214,106 @@ ComputeTrihedronSize( vtkRenderer* theRenderer, return fabs( theNewSize - theSize) > theSize * EPS_SIZE || fabs( theNewSize-theSize ) > theNewSize * EPS_SIZE; } + +bool IsBBEmpty(vtkRenderer* theRenderer) +{ + if(!theRenderer) + return false; + + vtkFloatingPointType aNewBndBox[6]; + aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT; + aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT; + + // iterate through displayed objects and set size if necessary + vtkActorCollection* anActors = theRenderer->GetActors(); + anActors->InitTraversal(); + bool isAny = false; + while(vtkActor* anAct = anActors->GetNextActor()) + //if(SALOME_Actor* anActor = dynamic_cast(anAct)) + if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(anAct)) + if(anActor->GetVisibility() && !anActor->IsInfinitive()) + { + vtkFloatingPointType *aBounds = anActor->GetBounds(); + if(aBounds[0] > -VTK_LARGE_FLOAT && aBounds[1] < VTK_LARGE_FLOAT && + aBounds[2] > -VTK_LARGE_FLOAT && aBounds[3] < VTK_LARGE_FLOAT && + aBounds[4] > -VTK_LARGE_FLOAT && aBounds[5] < VTK_LARGE_FLOAT) + isAny = true; + } + + return !isAny; +} + +bool ComputeBBCenter(vtkRenderer* theRenderer, vtkFloatingPointType theCenter[3]) +{ + theCenter[0] = theCenter[1] = theCenter[2] = 0.0; + + if(!theRenderer) + return false; + + vtkFloatingPointType aNewBndBox[6]; + aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT; + aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT; + + // iterate through displayed objects and set size if necessary + vtkActorCollection* anActors = theRenderer->GetActors(); + anActors->InitTraversal(); + bool isAny = false; + while(vtkActor* anAct = anActors->GetNextActor()) + { + //if(SALOME_Actor* anActor = dynamic_cast(anAct)) + if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(anAct)) + { + if(anActor->GetVisibility() && !anActor->IsInfinitive()) + { + vtkFloatingPointType *aBounds = anActor->GetBounds(); + if(aBounds[0] > -VTK_LARGE_FLOAT && aBounds[1] < VTK_LARGE_FLOAT && + aBounds[2] > -VTK_LARGE_FLOAT && aBounds[3] < VTK_LARGE_FLOAT && + aBounds[4] > -VTK_LARGE_FLOAT && aBounds[5] < VTK_LARGE_FLOAT) + { + 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]; + } + isAny = true; + } + } + } + } + + if ( !isAny ) + { + // null bounding box => the center is (0,0,0) + return true; + } + + if(aNewBndBox[0] > -VTK_LARGE_FLOAT && aNewBndBox[1] < VTK_LARGE_FLOAT && + aNewBndBox[2] > -VTK_LARGE_FLOAT && aNewBndBox[3] < VTK_LARGE_FLOAT && + aNewBndBox[4] > -VTK_LARGE_FLOAT && aNewBndBox[5] < VTK_LARGE_FLOAT) + { + static vtkFloatingPointType MIN_DISTANCE = 1.0 / VTK_LARGE_FLOAT; + + vtkFloatingPointType aLength = aNewBndBox[1]-aNewBndBox[0]; + aLength = max((aNewBndBox[3]-aNewBndBox[2]),aLength); + aLength = max((aNewBndBox[5]-aNewBndBox[4]),aLength); + + if(aLength < MIN_DISTANCE) + return false; + + vtkFloatingPointType aWidth = + sqrt((aNewBndBox[1]-aNewBndBox[0])*(aNewBndBox[1]-aNewBndBox[0]) + + (aNewBndBox[3]-aNewBndBox[2])*(aNewBndBox[3]-aNewBndBox[2]) + + (aNewBndBox[5]-aNewBndBox[4])*(aNewBndBox[5]-aNewBndBox[4])); + + if(aWidth < MIN_DISTANCE) + return false; + + theCenter[0] = (aNewBndBox[0] + aNewBndBox[1])/2.0; + theCenter[1] = (aNewBndBox[2] + aNewBndBox[3])/2.0; + theCenter[2] = (aNewBndBox[4] + aNewBndBox[5])/2.0; + return true; + } + + return false; +} \ No newline at end of file diff --git a/src/VTKViewer/VTKViewer_Utilities.h b/src/VTKViewer/VTKViewer_Utilities.h index 7ef9cc550..785d14fbd 100755 --- a/src/VTKViewer/VTKViewer_Utilities.h +++ b/src/VTKViewer/VTKViewer_Utilities.h @@ -47,4 +47,12 @@ ComputeTrihedronSize(vtkRenderer* theRenderer, const vtkFloatingPointType theSize, const vtkFloatingPointType theSizeInPercents); +VTKVIEWER_EXPORT +extern +bool IsBBEmpty(vtkRenderer* theRenderer); +VTKVIEWER_EXPORT +extern +bool ComputeBBCenter(vtkRenderer* theRenderer, + vtkFloatingPointType theCenter[3]); + #endif -- 2.39.2