-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
//
// Copyright (C) 2003-2007 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.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "SUIT_Tools.h"
#include "SALOME_Actor.h"
+#include "ViewerTools_ScreenScaling.h"
#include <vtkObjectFactory.h>
#include <vtkMath.h>
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include <vtkPointPicker.h>
+#include <vtkCellPicker.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCallbackCommand.h>
#include <vtkPerspectiveTransform.h>
#include <vtkMatrix4x4.h>
+#include <QtxRubberBand.h>
+
#include <QPixmap>
#include <QWidget>
-#include <QRubberBand>
+#include <QPolygon>
#include <algorithm>
#include <iostream>
}
-vtkStandardNewMacro(SVTK_InteractorStyle);
+vtkStandardNewMacro(SVTK_InteractorStyle)
/*!
Constructor
*/
SVTK_InteractorStyle::SVTK_InteractorStyle():
- mySelectionEvent(new SVTK_SelectionEvent()),
- myPointPicker(vtkPointPicker::New()),
myLastHighlitedActor(NULL),
myLastPreHighlitedActor(NULL),
myControllerIncrement(SVTK_ControllerIncrement::New()),
myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()),
+ mySelectionEvent(new SVTK_SelectionEvent()),
myHighlightSelectionPointActor(SVTK_Actor::New()),
+ myPointPicker(vtkPointPicker::New()),
myRectBand(0),
- myIsAdvancedZoomingEnabled(false)
+ myPolygonBand(0),
+ myPoligonState(Disable),
+ myIsAdvancedZoomingEnabled(false),
+ myInteractivePoint{0.0, 0.0, 0.0}
{
myPointPicker->Delete();
SVTK_InteractorStyle::~SVTK_InteractorStyle()
{
endDrawRect();
+ endDrawPolygon();
}
/*!
return myInteractor->GetSelector();
}
+/*!
+ Realeaze actors
+*/
+void SVTK_InteractorStyle::FreeActors()
+{
+ myLastHighlitedActor = NULL;
+ myLastPreHighlitedActor = NULL;
+}
+
/*!
Generate special SVTK_SelectionEvent
*/
myOtherPoint = QPoint(x, y);
}
+/*!
+ To handle mouse double click event
+*/
+void SVTK_InteractorStyle::OnMouseButtonDoubleClick()
+{
+ if( myPoligonState == InProcess ) {
+ onFinishOperation();
+ myPoligonState = Finished;
+ }
+}
+
/*!
To handle mouse move event
*/
int shift,
int x, int y)
{
+ if ( myPoligonState == Start ) {
+ // if right button was pressed and mouse is moved
+ // we can to draw a polygon for polygonal selection
+ myPoligonState = InProcess;
+ startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT );
+ }
myShiftState = shift;
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
onOperation(QPoint(x, y));
if(GetCurrentRenderer() == NULL)
return;
+ if ( myPoligonState != Disable )
+ return;
+
myShiftState = shift;
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
{
if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
{
- SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
- myPointPicker->Pick( aSelectionEvent->myX,
- aSelectionEvent->myY,
- 0.0,
+ Selection_Mode aSelectionMode = GetSelector()->SelectionMode();
+ double* aCoords = NULL;
+ vtkIdType aVtkId;
+ bool isTrueType = false;
+
+ if( myCurrFocalPointType == SVTK::StartFocalPointSelection ||
+ ( myCurrRotationPointType == SVTK::StartPointSelection && aSelectionMode == NodeSelection ) )
+ {
+ SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
+ myPointPicker->Pick( aSelectionEvent->myX,
+ aSelectionEvent->myY,
+ 0.0,
+ GetCurrentRenderer() );
+ aVtkId = myPointPicker->GetPointId();
+ if ( aVtkId >= 0 )
+ {
+ vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
+ aCoords = anActor->GetNodeCoord(anObjId);
+ isTrueType = true;
+ }
+ }
+
+ if( aSelectionMode == EdgeSelection || aSelectionMode == FaceSelection || aSelectionMode == VolumeSelection )
+ {
+ vtkSmartPointer<vtkCellPicker> aCellPicker = vtkCellPicker::New();
+ aCellPicker->SetTolerance( 0.005 );
+ SVTK::TPickLimiter aPickLimiter( aCellPicker, anActor );
+ aCellPicker->Pick( aSelectionEvent->myX,
+ aSelectionEvent->myY,
+ 0.0,
GetCurrentRenderer() );
- int aVtkId = myPointPicker->GetPointId();
- if ( aVtkId >= 0 )
- {
- int anObjId = anActor->GetNodeObjId( aVtkId );
- double* aCoords = anActor->GetNodeCoord(anObjId);
-
+ aVtkId = aCellPicker->GetCellId();
+ vtkIdType aCellId = anActor->GetElemObjId( aVtkId );
+
+ if( aSelectionMode == EdgeSelection )
+ isTrueType = anActor->GetObjDimension( aCellId ) == 1;
+ else if( aSelectionMode == FaceSelection )
+ isTrueType = anActor->GetObjDimension( aCellId ) == 2;
+ else if( aSelectionMode == VolumeSelection )
+ isTrueType = anActor->GetObjDimension( aCellId ) == 3;
+
+ if ( aVtkId >= 0 && isTrueType )
+ aCoords = anActor->GetGravityCenter( aCellId );
+ }
+
+ if( aVtkId >= 0 )
+ {
if (myCurrRotationPointType == SVTK::StartPointSelection) {
myCurrRotationPointType = SVTK::SetRotateSelected;
-
// invoke event for update coordinates in SVTK_SetRotationPointDlg
- InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
+ if( isTrueType )
+ InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords);
+ else
+ InvokeEvent(SVTK::RotationPointChanged);
+ GetSelector()->SetSelectionMode(ActorSelection);
}
else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
myCurrFocalPointType = SVTK::SetFocalPointSelected;
// invoke event with no data (for SVTK_SetRotationPointDlg)
InvokeEvent(SVTK::RotationPointChanged,0);
myCurrRotationPointType = myPrevRotationPointType;
+ GetSelector()->SetSelectionMode(ActorSelection);
}
else if (myCurrFocalPointType == SVTK::StartFocalPointSelection) {
// invoke event with no data (for SVTK_ViewParameterDlg)
*/
void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl),
int shift,
- int vtkNotUsed(x),
- int vtkNotUsed(y))
+ int x,
+ int y)
{
myShiftState = shift;
+ if( myPoligonState == InProcess ) { // add a new point of polygon
+ // The mouse events were already scaled up with a pixel ratio for a proper selection,
+ // but rubber band's implemented with QPainter scales them on its own.
+ // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
+ const double pixelRatio = ViewerTools_ScreenScaling::getPR();
+
+ myPolygonPoints.append(QPoint(x / pixelRatio, y / pixelRatio));
+ this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY );
+ mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) );
+ return;
+ }
+ else if ( myPoligonState == Closed ) { // close polygon and apply a selection
+ onFinishOperation();
+ myPoligonState = Finished;
+ return;
+ }
+ else if( myPoligonState == Finished || myPoligonState == NotValid )
+ return;
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
onFinishOperation();
+ int lastOperation = State;
startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
+ if (lastOperation == VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
+ InvokeEvent(SVTK::InteractiveSelectionFinished, nullptr);
+ }
}
}
if(GetCurrentRenderer() == NULL)
return;
+ if ( myPoligonState != Disable )
+ return;
+
myShiftState = shift;
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
}
myOtherPoint = myPoint = QPoint(x, y);
- if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
+ if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
+ ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
startOperation(ForcedState);
}
else {
int vtkNotUsed(x),
int vtkNotUsed(y))
{
+ if( myPoligonState == InProcess ) { // delete a point of polygon
+ if ( myPolygonPoints.size() > 2 ) {
+ myPolygonPoints.remove( myPolygonPoints.size() - 1 );
+ mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 );
+ }
+ return;
+ }
myShiftState = shift;
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
return;
myShiftState = shift;
+
+ if ( !ctrl ) {
+ myPoligonState = Start;
+ this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY);
+ mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) );
+ }
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
onFinishOperation();
startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
}
myOtherPoint = myPoint = QPoint(x, y);
- if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
+ if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE &&
+ ForcedState != VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION) {
startOperation(ForcedState);
}
else {
int vtkNotUsed(x),
int vtkNotUsed(y))
{
+ if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved
+ myPoligonState = Disable;
+ mySelectionEvent->myPolygonPoints.clear();
+ }
+
+ if( myPoligonState != Disable ) {
+ endDrawPolygon();
+ myPoligonState = Finished;
+ startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
+ return;
+ }
+
myShiftState = shift;
// finishing current viewer operation
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) {
ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE;
}
+/*!
+ Starts Interactive Selection operation
+*/
+void SVTK_InteractorStyle::startInteractiveSelection()
+{
+ if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
+ {
+ onFinishOperation();
+ startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
+ }
+ ForcedState = VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION;
+}
+
+
/*!
Set rotation point selected by user
*/
case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
case VTK_INTERACTOR_STYLE_CAMERA_FIT:
case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
+ case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE)
startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
State = operation;
case VTK_INTERACTOR_STYLE_CAMERA_SELECT:
case VTK_INTERACTOR_STYLE_CAMERA_FIT:
{
- drawRect();
+ if ( myPoligonState == InProcess )
+ drawPolygon();
+ else
+ drawRect();
+ break;
+ }
+ case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
+ {
+ InteractiveSelection();
break;
}
case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
}
else {
if (myPoint == myOtherPoint)
- {
- // process point selection
- this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
- Interactor->StartPickCallback();
+ {
+ // process point selection
+ this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY);
+ Interactor->StartPickCallback();
- SALOME_Actor* aHighlightedActor = NULL;
- vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
-
- aSelectionEvent->myIsRectangle = false;
+ SALOME_Actor* aHighlightedActor = NULL;
+ vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
- if(!myShiftState)
- GetSelector()->ClearIObjects();
+ aSelectionEvent->myIsRectangle = false;
+ aSelectionEvent->myIsPolygon = false;
+ if(!myShiftState)
+ GetSelector()->ClearIObjects();
- if( anActorCollection )
+ if( anActorCollection )
+ {
+ if( !myShiftState &&
+ anActorCollection->GetNumberOfItems () > 1 &&
+ myLastHighlitedActor.GetPointer() ) {
+ anActorCollection->RemoveItem ( myLastHighlitedActor.GetPointer() );
+ }
+ anActorCollection->InitTraversal();
+ while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
{
- anActorCollection->InitTraversal();
- while( vtkActor* aVTKActor = anActorCollection->GetNextActor() )
+ if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
{
- if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) )
+ if( anActor->Highlight( this, aSelectionEvent, true ) )
{
- if( anActor->Highlight( this, aSelectionEvent, true ) )
- {
- aHighlightedActor = anActor;
- break;
- }
+ aHighlightedActor = anActor;
+ break;
}
}
}
+ }
- if( !aHighlightedActor )
- {
- if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
- myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
- }
- myLastHighlitedActor = aHighlightedActor;
- }
- else
+ if( !aHighlightedActor )
{
- //processing rectangle selection
- Interactor->StartPickCallback();
- GetSelector()->StartPickCallback();
+ if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor)
+ myLastHighlitedActor->Highlight( this, aSelectionEvent, false );
+ }
+ myLastHighlitedActor = aHighlightedActor;
+ }
+ else
+ {
+ if ( myPoligonState == InProcess || myPoligonState == Closed )
+ aSelectionEvent->myIsPolygon = true;
+ else
aSelectionEvent->myIsRectangle = true;
- if(!myShiftState)
- GetSelector()->ClearIObjects();
+ //processing polygonal selection
+ Interactor->StartPickCallback();
+ GetSelector()->StartPickCallback();
+
+ if(!myShiftState)
+ GetSelector()->ClearIObjects();
- VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
- vtkActorCollection* aListActors = aCopy.GetActors();
- aListActors->InitTraversal();
- while(vtkActor* aActor = aListActors->GetNextActor())
+ VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors());
+ vtkActorCollection* aListActors = aCopy.GetActors();
+ aListActors->InitTraversal();
+ while(vtkActor* aActor = aListActors->GetNextActor())
+ {
+ if(aActor->GetVisibility())
+ {
+ if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
{
- if(aActor->GetVisibility())
- {
- if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor))
- {
- if(aSActor->hasIO())
- aSActor->Highlight( this, aSelectionEvent, true );
- }
- }
+ if(aSActor->hasIO())
+ aSActor->Highlight( this, aSelectionEvent, true );
}
+ }
}
+ }
+ aSelectionEvent->myIsRectangle = false;
+ aSelectionEvent->myIsPolygon = false;
+ aSelectionEvent->myPolygonPoints.clear();
+ endDrawPolygon();
Interactor->EndPickCallback();
GetSelector()->EndPickCallback();
}
- }
- break;
- case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
- case VTK_INTERACTOR_STYLE_CAMERA_PAN:
- case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
- case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
- break;
- case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
+ break;
+ }
+ case VTK_INTERACTOR_STYLE_CAMERA_ZOOM:
+ case VTK_INTERACTOR_STYLE_CAMERA_PAN:
+ case VTK_INTERACTOR_STYLE_CAMERA_ROTATE:
+ case VTK_INTERACTOR_STYLE_CAMERA_SPIN:
+ break;
+ case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN:
{
int w, h, x, y;
Interactor->GetSize(w, h);
{
if (!myCursorState)
setCursor(VTK_INTERACTOR_STYLE_CAMERA_SELECT);
- }
+ } // fall through!
case VTK_INTERACTOR_STYLE_CAMERA_FIT:
{
myOtherPoint = mousePos;
- drawRect();
+ if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid )
+ drawPolygon();
+ else if ( myPoligonState != Finished )
+ drawRect();
break;
}
+ case VTK_INTERACTOR_STYLE_CAMERA_INTERACTIVE_SELECTION:
+ this->InteractiveSelection();
}
}
Called when user moves mouse inside viewer window and there is no active viewer operation
(!put necessary processing here!)
*/
-void SVTK_InteractorStyle::onCursorMove(QPoint mousePos)
+void SVTK_InteractorStyle::onCursorMove(QPoint /*mousePos*/)
{
+ if ( !GetSelector()->IsPreSelectionEnabled() )
+ return;
+
// processing highlighting
SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY();
this->FindPokedRenderer(aSelectionEvent->myX,aSelectionEvent->myY);
SALOME_Actor* aPreHighlightedActor = NULL;
vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer());
- if ( myCurrRotationPointType == SVTK::StartPointSelection ||
- myCurrFocalPointType == SVTK::StartFocalPointSelection )
+ if ( myCurrFocalPointType == SVTK::StartFocalPointSelection )
{
myHighlightSelectionPointActor->SetVisibility( false );
{
SVTK::TPickLimiter aPickLimiter( myPointPicker, anActor );
myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() );
- int aVtkId = myPointPicker->GetPointId();
+ vtkIdType aVtkId = myPointPicker->GetPointId();
if ( aVtkId >= 0 ) {
- int anObjId = anActor->GetNodeObjId( aVtkId );
+ vtkIdType anObjId = anActor->GetNodeObjId( aVtkId );
- TColStd_IndexedMapOfInteger aMapIndex;
+ SVTK_TIndexedMapOfVtkId aMapIndex;
aMapIndex.Add( anObjId );
myHighlightSelectionPointActor->MapPoints( anActor, aMapIndex );
this->RotateXY( incrX, -incrY );
}
+void SVTK_InteractorStyle::InteractiveSelection()
+{
+ if (vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera()) {
+ int posX, posY;
+ this->Interactor->GetEventPosition(posX, posY);
+ double viewFocus[3], z;
+ double* focalPointWorld = cam->GetFocalPoint();
+ this->ComputeWorldToDisplay(focalPointWorld[0], focalPointWorld[1],
+ focalPointWorld[2], viewFocus);
+ z = viewFocus[2];
+
+ this->ComputeDisplayToWorld(double(posX), double(posY),
+ z, this->myInteractivePoint);
+ InvokeEvent(SVTK::InteractiveSelectionChanged, (void*)this->myInteractivePoint);
+ }
+}
+
/*!
Redefined in order to add an observer (callback) for custorm event (space mouse event)
*/
theInteractor->AddObserver( SVTK::SetFocalPointGravity, EventCallbackCommand, Priority );
theInteractor->AddObserver( SVTK::StartFocalPointSelection, EventCallbackCommand, Priority );
theInteractor->AddObserver( SVTK::SetFocalPointSelected, EventCallbackCommand, Priority );
+ theInteractor->AddObserver( SVTK::StartInteractiveSelection, EventCallbackCommand, Priority);
+ theInteractor->AddObserver( SVTK::StopCurrentOperation, EventCallbackCommand, Priority);
}
}
// check if bounding box was changed
if ( GetCurrentRenderer() )
{
+#ifdef VGL_WORKAROUND
+ GetCurrentRenderer()->Render();
+#endif
double aCurrBBCenter[3];
if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) )
{
*/
void SVTK_InteractorStyle::drawRect()
{
- if ( !myRectBand ) {
- myRectBand = new QRubberBand( QRubberBand::Rectangle, GetRenderWidget() );
+ if ( !myRectBand )
+ myRectBand = new QtxRectRubberBand( GetRenderWidget() );
+
+ myRectBand->setUpdatesEnabled ( false );
+
+ // The mouse events were already scaled up with a pixel ratio for a proper selection,
+ // but rubber band's implemented with QPainter scales them on its own.
+ // So, we need to pass unscaled coordinates to get a rectangle painted in a right place.
+ const double pixelRatio = ViewerTools_ScreenScaling::getPR();
+ QRect aRect = SUIT_Tools::makeRect(
+ myPoint.x() / pixelRatio,
+ myPoint.y() / pixelRatio,
+ myOtherPoint.x() / pixelRatio,
+ myOtherPoint.y() / pixelRatio);
+
+ myRectBand->initGeometry( aRect );
+
+ if ( !myRectBand->isVisible() )
+ myRectBand->show();
+
+ myRectBand->setUpdatesEnabled ( true );
+}
+
+/*!
+ \brief Delete rubber band on the end on the dragging operation.
+*/
+void SVTK_InteractorStyle::endDrawRect()
+{
+ if ( myRectBand ) {
+ myRectBand->clearGeometry();
+ myRectBand->hide();
+ }
+}
+
+bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1,
+ const QPoint& theStart2, const QPoint& theEnd2 )
+{
+ if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) ||
+ ( theStart1 == theEnd2 && theEnd1 == theStart2 ) )
+ return true;
+
+ if ( theStart1 == theStart2 || theStart2 == theEnd1 ||
+ theStart1 == theEnd2 || theEnd1 == theEnd2 )
+ return false;
+
+ double x11 = theStart1.x() * 1.0;
+ double x12 = theEnd1.x() * 1.0;
+ double y11 = theStart1.y() * 1.0;
+ double y12 = theEnd1.y() * 1.0;
+
+ double x21 = theStart2.x() * 1.0;
+ double x22 = theEnd2.x() * 1.0;
+ double y21 = theStart2.y() * 1.0;
+ double y22 = theEnd2.y() * 1.0;
+
+ double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 );
+ double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 );
+
+ double b1 = y11 - k1 * x11;
+ double b2 = y21 - k2 * x21;
+
+ if ( k1 == k2 )
+ {
+ if ( b1 != b2 )
+ return false;
+ else
+ return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) ||
+ qMin( x11, x12 ) >= qMax( x21, x22 ) ) &&
+ ( qMax( y11, y12 ) <= qMin( y21, y22 ) ||
+ qMin( y11, y12 ) >= qMax( y21, y22 ) ) );
+ }
+ else
+ {
+ double x0 = ( b2 - b1 ) / ( k1 - k2 );
+ double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 );
+
+ if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) &&
+ qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) &&
+ qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) &&
+ qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) )
+ return true;
+ }
+ return false;
+}
+
+bool isValid( const QPolygon* thePoints, const QPoint& theCurrent )
+{
+ if ( !thePoints->count() )
+ return true;
+
+ if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent )
+ return false;
+
+ const QPoint& aLast = thePoints->point( thePoints->count() - 1 );
+
+ if ( aLast == theCurrent )
+ return true;
+
+ bool res = true;
+ for ( int i = 0; i < thePoints->count() - 1 && res; i++ )
+ {
+ const QPoint& aStart = thePoints->point( i );
+ const QPoint& anEnd = thePoints->point( i + 1 );
+ res = !isIntersect( aStart, anEnd, theCurrent, aLast );
+ }
+ return res;
+}
+
+/*!
+ Draws polygon
+*/
+void SVTK_InteractorStyle::drawPolygon()
+{
+ // The mouse events were already scaled up with a pixel ratio for a proper selection,
+ // but rubber band's implemented with QPainter scales them on its own.
+ // So, we need to pass unscaled coordinates to get a polygon painted in a right place.
+ const double pixelRatio = ViewerTools_ScreenScaling::getPR();
+ const QPoint myPointCopy(myPoint.x() / pixelRatio, myPoint.y() / pixelRatio);
+ const QPoint myOtherPointCopy(myOtherPoint.x() / pixelRatio, myOtherPoint.y() / pixelRatio);
+
+ QSize aToler( 5, 5 );
+ if ( !myPolygonBand ) {
+ myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() );
QPalette palette;
- palette.setColor(myRectBand->foregroundRole(), Qt::white);
- myRectBand->setPalette(palette);
+ palette.setColor( myPolygonBand->foregroundRole(), Qt::white );
+ myPolygonBand->setPalette( palette );
+ myPolygonPoints.append(myPointCopy);
+ }
+ myPolygonBand->hide();
+
+ bool closed = false;
+ bool valid = GetRenderWidget()->rect().contains(myOtherPointCopy);
+ if ( !myPolygonPoints.at(0).isNull() )
+ {
+ QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(),
+ 2 * aToler.width(), 2 * aToler.height() );
+ closed = aRect.contains(myOtherPointCopy);
+ }
+
+ QPolygon* points = new QPolygon( myPolygonPoints );
+ valid = valid && isValid(points, myOtherPointCopy);
+ myPoligonState = valid ? InProcess : NotValid;
+ delete points;
+ if ( closed && !valid )
+ closed = false;
+
+ if ( closed && myPolygonPoints.size() > 2 ) {
+ GetRenderWidget()->setCursor( Qt::CrossCursor );
+ myPoligonState = Closed;
}
- myRectBand->hide();
+ else if ( valid )
+ GetRenderWidget()->setCursor( Qt::PointingHandCursor );
+ else
+ GetRenderWidget()->setCursor( Qt::ForbiddenCursor );
+
+ myPolygonPoints.append(myOtherPointCopy);
- QRect aRect = SUIT_Tools::makeRect(myPoint.x(), myPoint.y(), myOtherPoint.x(), myOtherPoint.y());
- myRectBand->setGeometry( aRect );
- myRectBand->setVisible( aRect.isValid() );
+ QPolygon aPolygon( myPolygonPoints );
+ myPolygonBand->initGeometry( aPolygon );
+ myPolygonBand->setVisible( true );
+
+ if ( myPolygonPoints.size() > 1 ) {
+ myPolygonPoints.remove( myPolygonPoints.size() - 1 );
+ }
}
/*!
\brief Delete rubber band on the end on the dragging operation.
*/
-void SVTK_InteractorStyle::endDrawRect()
+void SVTK_InteractorStyle::endDrawPolygon()
{
- if ( myRectBand ) myRectBand->hide();
+ if ( myPolygonBand ) myPolygonBand->hide();
+
+ // RNV fix for : #19204 [CEA][Windows] VTK Viewer - Access violation while right clicking
+ //delete myPolygonBand;
+ myPolygonBand->deleteLater();
+ myPolygonBand = 0;
- delete myRectBand;
- myRectBand = 0;
+ myPolygonPoints.clear();
}
/*!
case SVTK::StartFocalPointSelection:
self->startFocalPointSelection();
return;
-
+ case SVTK::StartInteractiveSelection:
+ self->startInteractiveSelection();
+ return;
case SVTK::SetFocalPointSelected:
if ( self->myCurrFocalPointType == SVTK::StartFocalPointSelection )
{
self->myPrevFocalPointType = self->myCurrFocalPointType;
self->myCurrFocalPointType = SVTK::SetFocalPointSelected;
return;
+ case SVTK::StopCurrentOperation:
+ self->onFinishOperation();
+ self->startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE);
}
}
}
return myControllerIncrement.GetPointer();
}
-vtkStandardNewMacro(SVTK_ControllerIncrement);
+vtkStandardNewMacro(SVTK_ControllerIncrement)
SVTK_ControllerIncrement::SVTK_ControllerIncrement()
{
myIncrement=10;
return myIncrement;
}
-vtkStandardNewMacro(SVTK_GeomControllerIncrement);
+vtkStandardNewMacro(SVTK_GeomControllerIncrement)
SVTK_GeomControllerIncrement::SVTK_GeomControllerIncrement()
{
}
return myIncrement;
}
-vtkStandardNewMacro(SVTK_ControllerOnKeyDown);
+vtkStandardNewMacro(SVTK_ControllerOnKeyDown)
/*!
Constructor
{
}
-bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* theIS)
+bool SVTK_ControllerOnKeyDown::OnKeyDown(vtkInteractorStyle* /*theIS*/)
{
return true;
}