#include "SVTK_Event.h"
#include "SVTK_Selector.h"
#include "SVTK_Functor.h"
+#include "SVTK_Actor.h"
#include "VTKViewer_Algorithm.h"
#include "SVTK_Functor.h"
#include <vtkCommand.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
-#include <vtkPicker.h>
+#include <vtkPointPicker.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCallbackCommand.h>
#include <vtkRendererCollection.h>
+#include <vtkDataSet.h>
+#include <vtkPerspectiveTransform.h>
+#include <vtkMatrix4x4.h>
#include <qapplication.h>
#include <qpixmap.h>
//VRV: porting on Qt 3.0.5
#include <algorithm>
+//#include <iostream.h>
+
using namespace std;
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;
//
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;
}
/*!
SVTK_InteractorStyle
::RotateXY(int dx, int dy)
{
- if(GetCurrentRenderer() == NULL)
+ /* if(GetCurrentRenderer() == NULL)
return;
int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize();
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();
}
} 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;
}
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)
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;
}
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)
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;
}
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)
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 );
}
}
{
//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;
+ }
+ }
+ }
}
/*!
vtkObject* anObject = reinterpret_cast<vtkObject*>( clientData );
SVTK_InteractorStyle* self = dynamic_cast<SVTK_InteractorStyle*>( anObject );
int aSpeedIncrement=self->ControllerIncrement()->Current();
+ vtkFloatingPointType aCenter[3];
+ vtkFloatingPointType* aSelectedPoint;
if ( self ) {
switch ( event ) {
case SVTK::SpaceMouseMoveEvent :
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;
}
}
}
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<SALOME_Actor*>(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<SALOME_Actor*>(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