From 4e407fa77d75351d1dee259a8c41cd7ebe2c9c90 Mon Sep 17 00:00:00 2001 From: ouv Date: Thu, 8 Nov 2007 11:19:02 +0000 Subject: [PATCH] Bug NPAL16761 - EDF 550 GEOM : Polyline to select objects --- src/OCCViewer/Makefile.am | 3 + src/OCCViewer/OCCViewer_ViewModel.cxx | 1 + src/OCCViewer/OCCViewer_ViewPort.cxx | 2 +- src/OCCViewer/OCCViewer_ViewSketcher.cxx | 536 +++++++++++++++++++++++ src/OCCViewer/OCCViewer_ViewSketcher.h | 137 ++++++ src/OCCViewer/OCCViewer_ViewWindow.cxx | 203 ++++++++- src/OCCViewer/OCCViewer_ViewWindow.h | 18 + 7 files changed, 892 insertions(+), 8 deletions(-) create mode 100755 src/OCCViewer/OCCViewer_ViewSketcher.cxx create mode 100755 src/OCCViewer/OCCViewer_ViewSketcher.h diff --git a/src/OCCViewer/Makefile.am b/src/OCCViewer/Makefile.am index c244074a1..2bfc88875 100755 --- a/src/OCCViewer/Makefile.am +++ b/src/OCCViewer/Makefile.am @@ -31,6 +31,7 @@ salomeinclude_HEADERS= \ OCCViewer_ViewModel.h \ OCCViewer_ViewPort3d.h \ OCCViewer_ViewPort.h \ + OCCViewer_ViewSketcher.h \ OCCViewer_ViewWindow.h \ OCCViewer_VService.h \ OCCViewer_CreateRestoreViewDlg.h \ @@ -44,6 +45,7 @@ dist_libOCCViewer_la_SOURCES= \ OCCViewer_ViewModel.cxx \ OCCViewer_ViewPort3d.cxx \ OCCViewer_ViewPort.cxx \ + OCCViewer_ViewSketcher.cxx \ OCCViewer_ViewWindow.cxx \ OCCViewer_VService.cxx \ OCCViewer_CreateRestoreViewDlg.cxx \ @@ -55,6 +57,7 @@ MOC_FILES= \ OCCViewer_ViewModel_moc.cxx \ OCCViewer_ViewPort3d_moc.cxx \ OCCViewer_ViewPort_moc.cxx \ + OCCViewer_ViewSketcher_moc.cxx \ OCCViewer_ViewWindow_moc.cxx \ OCCViewer_ViewManager_moc.cxx \ OCCViewer_CreateRestoreViewDlg_moc.cxx \ diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index a58e95624..5e64aafb3 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -129,6 +129,7 @@ void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view ) { if ( view ) { view->initLayout(); + view->initSketchers(); OCCViewer_ViewPort3d* vp3d = view->getViewPort(); if ( vp3d ) diff --git a/src/OCCViewer/OCCViewer_ViewPort.cxx b/src/OCCViewer/OCCViewer_ViewPort.cxx index ff4ef0551..b0c6e617e 100755 --- a/src/OCCViewer/OCCViewer_ViewPort.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort.cxx @@ -196,7 +196,7 @@ void OCCViewer_ViewPort::initialize() { myPopupActions.setAutoDelete( true ); myPaintersRedrawing = false; - myEnableSketching = false; + myEnableSketching = true; myEnableTransform = true; setMouseTracking( true ); diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.cxx b/src/OCCViewer/OCCViewer_ViewSketcher.cxx new file mode 100755 index 000000000..a6e8d8e30 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewSketcher.cxx @@ -0,0 +1,536 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "OCCViewer_ViewSketcher.h" +#include "OCCViewer_ViewWindow.h" +#include "OCCViewer_ViewPort3d.h" + +#include +#include +#include + +/**************************************************************** +** Class: OCCViewer_ViewSketcher +** Level: Public +*****************************************************************/ + +OCCViewer_ViewSketcher::OCCViewer_ViewSketcher( OCCViewer_ViewWindow* vw, int type ) +: QObject( vw ), +mySketchButton( Qt::LeftButton ), +mypViewWindow( vw ), +myType( type ), +mypData( 0 ), +myResult( Neutral ), +myButtonState( 0 ) +{ +} + +OCCViewer_ViewSketcher::~OCCViewer_ViewSketcher() +{ +} + +void OCCViewer_ViewSketcher::activate() +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + mySavedCursor = avp->cursor(); + avp->setCursor( Qt::PointingHandCursor ); + avp->installEventFilter( this ); + qApp->installEventFilter( this ); + + connect( avp, SIGNAL( vpDrawExternal( QPainter* ) ), this, SLOT( onDrawViewPort() ) ); + + myStart = QPoint(); + myResult = Neutral; + + onActivate(); +} + +void OCCViewer_ViewSketcher::deactivate() +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + disconnect( avp, SIGNAL( vpDrawExternal( QPainter* ) ), this, SLOT( onDrawViewPort() ) ); + + qApp->removeEventFilter( this ); + avp->removeEventFilter( this ); + avp->setCursor( mySavedCursor ); + + onDeactivate(); +} + +int OCCViewer_ViewSketcher::type() const +{ + return myType; +} + +void* OCCViewer_ViewSketcher::data() const +{ + return mypData; +} + +int OCCViewer_ViewSketcher::result() const +{ + return myResult; +} + +int OCCViewer_ViewSketcher::buttonState() const +{ + return myButtonState; +} + +void OCCViewer_ViewSketcher::onActivate() +{ +} + +void OCCViewer_ViewSketcher::onDeactivate() +{ +} + +bool OCCViewer_ViewSketcher::isDefault() const +{ + return true; +} + +bool OCCViewer_ViewSketcher::eventFilter( QObject* o, QEvent* e ) +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + SketchState state = EnTrain; + bool ignore = false; + if ( o == avp ) + { + switch ( e->type() ) + { + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + { + QMouseEvent* me = (QMouseEvent*)e; + + myButtonState = me->state(); + if ( e->type() == QEvent::MouseButtonPress ) + myButtonState |= me->button(); + + if ( myStart.isNull() && ( myButtonState & sketchButton() ) ) + { + state = Debut; + myStart = me->pos(); + } + + myCurr = me->pos(); + + onMouse( me ); + + if ( myResult != Neutral ) + state = Fin; + + ignore = true; + break; + } + case QEvent::Hide: + case QEvent::HideToParent: + myResult = Reject; + onSketch( Fin ); + break; + default: + break; + } + } + if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) + { + ignore = onKey( (QKeyEvent*)e ); + if ( myResult != Neutral ) + state = Fin; + } + + if ( ignore ) + { + onSketch( state ); + return true; + } + return QObject::eventFilter( o, e ); +} + +void OCCViewer_ViewSketcher::onDrawViewPort() +{ + onSketch( Debut ); +} + +bool OCCViewer_ViewSketcher::onKey( QKeyEvent* ) +{ + return false; +} + +void OCCViewer_ViewSketcher::onMouse( QMouseEvent* ) +{ +} + +int OCCViewer_ViewSketcher::sketchButton() +{ + return mySketchButton; +} + +void OCCViewer_ViewSketcher::setSketchButton( int b ) +{ + mySketchButton = b; +} + +/**************************************************************** +** Class: OCCViewer_RectSketcher +** Level: Public +*****************************************************************/ + +OCCViewer_RectSketcher::OCCViewer_RectSketcher( OCCViewer_ViewWindow* vw, int typ ) +: OCCViewer_ViewSketcher( vw, typ ) +{ +} + +OCCViewer_RectSketcher::~OCCViewer_RectSketcher() +{ + delete mypData; +} + +void OCCViewer_RectSketcher::onActivate() +{ + mypData = new QRect(); +} + +void OCCViewer_RectSketcher::onDeactivate() +{ + delete mypData; + mypData = 0; +} + +bool OCCViewer_RectSketcher::onKey( QKeyEvent* e ) +{ + if ( e->key() == Qt::Key_Escape ) + myResult = Reject; + else if ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return ) + myResult = Accept; + + return true; +} + +void OCCViewer_RectSketcher::onMouse( QMouseEvent* e ) +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + if ( avp->rect().contains( myCurr ) ) + avp->setCursor( Qt::PointingHandCursor ); + else + avp->setCursor( Qt::ForbiddenCursor ); + + if ( e->type() == QEvent::MouseButtonRelease && e->button() == sketchButton() ) + { + myResult = Accept; + QApplication::postEvent( avp, new QMouseEvent( e->type(), e->pos(), + e->globalPos(), e->state(), e->button() ) ); + } +} + +void OCCViewer_RectSketcher::onSketch( SketchState state ) +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + QRect* sketchRect = (QRect*)data(); + if ( myButtonState & sketchButton() ) + { + QRect rect( QMIN( myStart.x(), myCurr.x() ), QMIN( myStart.y(), myCurr.y() ), + QABS( myStart.x() - myCurr.x() ), QABS( myStart.y() - myCurr.y() ) ); + QPainter p( avp ); + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + if ( state != Debut && !sketchRect->isEmpty() ) + p.drawRect( *sketchRect ); + *sketchRect = rect; + if ( !rect.isEmpty() && state != Fin ) + p.drawRect( *sketchRect ); + } + + if ( state == Fin ) + { + QApplication::syncX(); /* force rectangle redrawing */ + mypViewWindow->activateSketching( OCCViewer_ViewWindow::NoSketching ); + } +} + +/**************************************************************** +** Class: OCCViewer_PolygonSketcher +** Level: Public +*****************************************************************/ + +OCCViewer_PolygonSketcher::OCCViewer_PolygonSketcher( OCCViewer_ViewWindow* vw, int typ ) +: OCCViewer_ViewSketcher( vw, typ ), + myDbl ( false ), + myToler ( 5, 5 ), + mypPoints ( 0L ), + myAddButton ( 0 ), + myDelButton ( 0 ) +{ + mySketchButton = Qt::RightButton; +} + +OCCViewer_PolygonSketcher::~OCCViewer_PolygonSketcher() +{ + delete mypPoints; + delete mypData; +} + +void OCCViewer_PolygonSketcher::onActivate() +{ + myDbl = false; + mypData = new QPointArray( 0 ); + mypPoints = new QPointArray( 0 ); + + switch ( sketchButton() ) + { + case Qt::LeftButton: + myAddButton = Qt::RightButton; + myDelButton = Qt::MidButton; + break; + case Qt::MidButton: + myAddButton = Qt::LeftButton; + myDelButton = Qt::RightButton; + break; + case Qt::RightButton: + default: + myAddButton = Qt::LeftButton; + myDelButton = Qt::MidButton; + break; + }; +} + +void OCCViewer_PolygonSketcher::onDeactivate() +{ + delete mypPoints; + mypPoints = 0; + delete mypData; + mypData = 0; +} + +bool OCCViewer_PolygonSketcher::onKey( QKeyEvent* e ) +{ + if ( e->key() == Qt::Key_Escape ) + { + myResult = Reject; + return true; + } + else if ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return ) + { + QPointArray* points = (QPointArray*)data(); + if ( points->count() ) + { + QPoint last = points->point( points->count() - 1 ); + if ( last != myCurr ) + { + points->resize( points->count() + 1 ); + points->setPoint( points->count() - 1, myCurr ); + } + } + myResult = Accept; + return true; + } + else if ( e->key() == Qt::Key_Backspace && e->type() == QEvent::KeyRelease ) + { + QPointArray* points = (QPointArray*)data(); + if ( points->count() > 1 ) + points->resize( points->count() - 1 ); + onMouse( 0 ); + return true; + } + + return true; +} + +void OCCViewer_PolygonSketcher::onMouse( QMouseEvent* e ) +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + QPointArray* points = (QPointArray*)data(); + if ( !points->count() && !myStart.isNull() ) + { + points->resize( points->count() + 1 ); + points->setPoint( points->count() - 1, myStart ); + } + + bool closed = false; + bool valid = avp->rect().contains( myCurr ); + if ( !myStart.isNull() ) + { + QRect aRect( myStart.x() - myToler.width(), myStart.y() - myToler.height(), + 2 * myToler.width(), 2 * myToler.height() ); + closed = aRect.contains( myCurr ); + } + valid = valid && isValid( points, myCurr ); + if ( closed && !valid ) + closed = false; + + if ( closed ) + avp->setCursor( Qt::CrossCursor ); + else if ( valid ) + avp->setCursor( Qt::PointingHandCursor ); + else + avp->setCursor( Qt::ForbiddenCursor ); + + if ( !e ) + return; + + if ( e->type() == QEvent::MouseButtonRelease && ( e->button() & sketchButton() ) ) + { + myResult = Reject; + QApplication::postEvent( avp, new QMouseEvent( e->type(), e->pos(), + e->globalPos(), e->state(), e->button() ) ); + } + else if ( e->type() == QEvent::MouseButtonRelease && ( e->button() & myAddButton ) ) + { + if ( closed ) + myResult = Accept; + else + { + if ( myStart.isNull() ) + myStart = myCurr; + else + { + QPoint last = points->point( points->count() - 1 ); + if ( last != myCurr && valid ) + { + points->resize( points->count() + 1 ); + points->setPoint( points->count() - 1, myCurr ); + } + if ( valid && myDbl ) + myResult = Accept; + } + } + } + else if ( ( e->type() == QEvent::MouseButtonRelease && ( e->button() & myDelButton ) ) || + ( e->type() == QEvent::MouseButtonDblClick && ( e->button() & myDelButton ) ) ) + { + if ( points->count() > 1 ) + points->resize( points->count() - 1 ); + onMouse( 0 ); + } + myDbl = e->type() == QEvent::MouseButtonDblClick && ( e->button() & myAddButton ); +} + +void OCCViewer_PolygonSketcher::onSketch( SketchState state ) +{ + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + + QPointArray* points = (QPointArray*)data(); + QPainter p( avp ); + p.setPen( Qt::white ); + p.setRasterOp( Qt::XorROP ); + if ( state != Debut ) + p.drawPolyline( *mypPoints ); + + if ( points->count() ) + { + mypPoints->resize( points->count() + 1 ); + for ( uint i = 0; i < points->count(); i++ ) + mypPoints->setPoint( i, points->point( i ) ); + mypPoints->setPoint( points->count(), myCurr ); + if ( state != Fin ) + p.drawPolyline( *mypPoints ); + } + + if ( state == Fin ) + { + QApplication::syncX(); + mypViewWindow->activateSketching( OCCViewer_ViewWindow::NoSketching ); + } +} + +bool OCCViewer_PolygonSketcher::isValid( const QPointArray* aPoints, const QPoint& aCur ) const +{ + if ( !aPoints->count() ) + return true; + + if ( aPoints->count() == 1 && aPoints->point( 0 ) == aCur ) + return false; + + const QPoint& aLast = aPoints->point( aPoints->count() - 1 ); + + if ( aLast == aCur ) + return true; + + bool res = true; + for ( uint i = 0; i < aPoints->count() - 1 && res; i++ ) + { + const QPoint& aStart = aPoints->point( i ); + const QPoint& anEnd = aPoints->point( i + 1 ); + res = !isIntersect( aStart, anEnd, aCur, aLast ); + } + + return res; +} + +bool OCCViewer_PolygonSketcher::isIntersect( const QPoint& aStart1, const QPoint& anEnd1, + const QPoint& aStart2, const QPoint& anEnd2 ) const +{ + if ( ( aStart1 == aStart2 && anEnd1 == anEnd2 ) || + ( aStart1 == anEnd2 && anEnd1 == aStart2 ) ) + return true; + + if ( aStart1 == aStart2 || aStart2 == anEnd1 || + aStart1 == anEnd2 || anEnd1 == anEnd2 ) + return false; + + double x11 = aStart1.x() * 1.0; + double x12 = anEnd1.x() * 1.0; + double y11 = aStart1.y() * 1.0; + double y12 = anEnd1.y() * 1.0; + + double x21 = aStart2.x() * 1.0; + double x22 = anEnd2.x() * 1.0; + double y21 = aStart2.y() * 1.0; + double y22 = anEnd2.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; +} + + diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.h b/src/OCCViewer/OCCViewer_ViewSketcher.h new file mode 100755 index 000000000..367ece104 --- /dev/null +++ b/src/OCCViewer/OCCViewer_ViewSketcher.h @@ -0,0 +1,137 @@ +// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef OCCVIEWER_VIEWSKETCHER_H +#define OCCVIEWER_VIEWSKETCHER_H + +#include "OCCViewer.h" + +#include +#include + +class OCCViewer_ViewWindow; + +#ifdef WNT +#pragma warning ( disable:4251 ) +#endif + +/*! + \class OCCViewer_ViewSketcher +*/ + +class OCCVIEWER_EXPORT OCCViewer_ViewSketcher : public QObject +{ + Q_OBJECT + +public: + enum { Neutral, Accept, Reject }; + +public: + OCCViewer_ViewSketcher( OCCViewer_ViewWindow*, int ); + virtual ~OCCViewer_ViewSketcher(); + +public: + int type() const; + int result() const; + int buttonState() const; + void* data() const; + + void activate(); + void deactivate(); + + int sketchButton(); + void setSketchButton( int ); + + virtual bool isDefault() const; + virtual bool eventFilter( QObject*, QEvent* ); + +private slots: + void onDrawViewPort(); + +protected: + enum SketchState { Debut, EnTrain, Fin }; + virtual bool onKey( QKeyEvent* ); + virtual void onMouse( QMouseEvent* ); + virtual void onSketch( SketchState ) = 0; + virtual void onActivate(); + virtual void onDeactivate(); + +protected: + int mySketchButton; + OCCViewer_ViewWindow* mypViewWindow; + int myType; + void* mypData; + int myResult; + QCursor mySavedCursor; + QPoint myStart, myCurr; + int myButtonState; +}; + +/*! + \class OCCViewer_RectSketcher +*/ + +class OCCVIEWER_EXPORT OCCViewer_RectSketcher : public OCCViewer_ViewSketcher +{ +public: + OCCViewer_RectSketcher( OCCViewer_ViewWindow*, int ); + virtual ~OCCViewer_RectSketcher(); + +protected: + virtual bool onKey( QKeyEvent* ); + virtual void onMouse( QMouseEvent* ); + virtual void onSketch( SketchState ); + virtual void onActivate(); + virtual void onDeactivate(); +}; + +/*! + \class OCCViewer_PolygonSketcher +*/ + +class OCCVIEWER_EXPORT OCCViewer_PolygonSketcher : public OCCViewer_ViewSketcher +{ +public: + OCCViewer_PolygonSketcher( OCCViewer_ViewWindow*, int ); + virtual ~OCCViewer_PolygonSketcher(); + +protected: + virtual bool onKey( QKeyEvent* ); + virtual void onMouse( QMouseEvent* ); + virtual void onSketch( SketchState ); + virtual void onActivate(); + virtual void onDeactivate(); + +private: + bool isValid( const QPointArray*, const QPoint& ) const; + bool isIntersect( const QPoint&, const QPoint&, + const QPoint&, const QPoint& ) const; + +private: + bool myDbl; + QSize myToler; + QPointArray* mypPoints; + int myAddButton; + int myDelButton; +}; + +#ifdef WNT +#pragma warning( default:4251 ) +#endif + +#endif diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 0ec1a641d..78bd7147e 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -22,6 +22,8 @@ #include "OCCViewer_ViewWindow.h" #include "OCCViewer_ViewModel.h" #include "OCCViewer_ViewPort3d.h" +#include "OCCViewer_ViewManager.h" +#include "OCCViewer_ViewSketcher.h" #include "OCCViewer_CreateRestoreViewDlg.h" #include "OCCViewer_ClippingDlg.h" #include "OCCViewer_SetRotationPointDlg.h" @@ -46,6 +48,7 @@ #include #include #include +#include #include #include @@ -59,6 +62,7 @@ #include #include +static QEvent* l_mbPressEvent = 0; const char* imageZoomCursor[] = { "32 32 3 1", @@ -189,6 +193,9 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_V updateEnabledDrawMode(); myClippingDlg = 0; mySetRotationPointDlg = 0; + + mypSketcher = 0; + myCurSketch = -1; } /*! @@ -387,6 +394,11 @@ void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent) } if ( transformRequested() ) setTransformInProcess( true ); + + /* we may need it for sketching... */ + if ( l_mbPressEvent ) + delete l_mbPressEvent; + l_mbPressEvent = new QMouseEvent( *theEvent ); } @@ -681,9 +693,8 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent) else { int aState = theEvent->state(); - //int aButton = theEvent->button(); if ( aState == Qt::LeftButton || - aState == ( Qt::LeftButton | Qt::ShiftButton) ) { + aState == ( Qt::LeftButton | Qt::ShiftButton) ) { myDrawRect = myEnableDrawMode; if ( myDrawRect ) { drawRect(); @@ -695,6 +706,32 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent) } } } + else if ( aState == Qt::RightButton || + aState == ( Qt::RightButton | Qt::ShiftButton ) ) { + OCCViewer_ViewSketcher* sketcher = 0; + for ( OCCViewer_ViewSketcher* sk = mySketchers.first(); + sk && !sketcher; sk = mySketchers.next() ) + { + if( sk->isDefault() && sk->sketchButton() & ( aState & Qt::MouseButtonMask ) ) + sketcher = sk; + } + if ( sketcher && myCurSketch == -1 ) + { + activateSketching( sketcher->type() ); + if ( mypSketcher ) + { + myCurSketch = mypSketcher->sketchButton(); + + if ( l_mbPressEvent ) + { + QApplication::sendEvent( getViewPort(), l_mbPressEvent ); + delete l_mbPressEvent; + l_mbPressEvent = 0; + } + QApplication::sendEvent( getViewPort(), theEvent ); + } + } + } else { emit mouseMoving( this, theEvent ); } @@ -710,13 +747,24 @@ void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) switch ( myOperation ) { case NOTHING: { + int prevState = myCurSketch; + if(theEvent->state() == RightButton) + { + for ( OCCViewer_ViewSketcher* sk = mySketchers.first(); + sk && myCurSketch != -1; sk = mySketchers.next() ) + { + if( ( sk->sketchButton() & theEvent->state() ) && sk->sketchButton() == myCurSketch ) + myCurSketch = -1; + } + } + emit mouseReleased(this, theEvent); - if(theEvent->button() == RightButton) + if(theEvent->button() == RightButton && prevState == -1) { - QContextMenuEvent aEvent( QContextMenuEvent::Mouse, - theEvent->pos(), theEvent->globalPos(), - theEvent->state() ); - emit contextMenuRequested( &aEvent ); + QContextMenuEvent aEvent( QContextMenuEvent::Mouse, + theEvent->pos(), theEvent->globalPos(), + theEvent->state() ); + emit contextMenuRequested( &aEvent ); } } break; @@ -758,6 +806,12 @@ void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) resetState(); myViewPort->update(); } + + if ( l_mbPressEvent ) + { + delete l_mbPressEvent; + l_mbPressEvent = 0; + } } /*! @@ -1374,3 +1428,138 @@ void OCCViewer_ViewWindow::hideEvent( QHideEvent * theEvent ) emit Hide( theEvent ); } + +/*! + Creates default sketcher. [ virtual protected ] +*/ +OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type ) +{ + if ( type == Rect ) + return new OCCViewer_RectSketcher( this, type ); + if ( type == Polygon ) + return new OCCViewer_PolygonSketcher( this, type ); + return 0; +} + +void OCCViewer_ViewWindow::initSketchers() +{ + if ( mySketchers.isEmpty() ) + { + mySketchers.append( createSketcher( Rect ) ); + mySketchers.append( createSketcher( Polygon ) ); + } +} + +OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) +{ + OCCViewer_ViewSketcher* sketcher = 0; + for ( OCCViewer_ViewSketcher* sk = mySketchers.first(); + sk && !sketcher; sk = mySketchers.next() ) + { + if ( sk->type() == typ ) + sketcher = sk; + } + return sketcher; +} + +/*! + Handles requests for sketching in the active view. [ virtual public ] +*/ +void OCCViewer_ViewWindow::activateSketching( int type ) +{ + OCCViewer_ViewPort3d* vp = getViewPort(); + if ( !vp ) + return; + + if ( !vp->isSketchingEnabled() ) + return; + + /* Finish current sketching */ + if ( type == NoSketching ) + { + if ( mypSketcher ) + { + onSketchingFinished(); + mypSketcher->deactivate(); + mypSketcher = 0; + } + } + /* Activate new sketching */ + else + { + activateSketching( NoSketching ); /* concurrency not suported */ + mypSketcher = getSketcher( type ); + if ( mypSketcher ) + { + mypSketcher->activate(); + onSketchingStarted(); + } + } +} + +/*! + Unhilights detected entities. [ virtual protected ] +*/ +void OCCViewer_ViewWindow::onSketchingStarted() +{ +} + +/*! + Selection by rectangle or polygon. [ virtual protected ] +*/ +void OCCViewer_ViewWindow::onSketchingFinished() +{ + if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + bool append = bool( mypSketcher->buttonState() & Qt::ShiftButton ); + switch( mypSketcher->type() ) + { + case Rect: + { + QRect* aRect = (QRect*)mypSketcher->data(); + if( aRect ) + { + int aLeft = aRect->left(); + int aRight = aRect->right(); + int aTop = aRect->top(); + int aBottom = aRect->bottom(); + + if( append ) + ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); + else + ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); + } + } + break; + case Polygon: + { + QPointArray* aPolygon = (QPointArray*)mypSketcher->data(); + if( aPolygon ) + { + int size = aPolygon->size(); + TColgp_Array1OfPnt2d anArray( 1, size ); + + QPointArray::Iterator it = aPolygon->begin(); + QPointArray::Iterator itEnd = aPolygon->end(); + for( int index = 1; it != itEnd; ++it, index++ ) + { + QPoint aPoint = *it; + anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) ); + } + + if( append ) + ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False ); + else + ic->Select( anArray, getViewPort()->getView(), Standard_False ); + } + } + break; + default: + break; + } + + OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager(); + aViewMgr->getOCCViewer()->performSelectionChanged(); + } +} diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index 9c3841412..698a9f095 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -30,6 +30,7 @@ class SUIT_Desktop; class OCCViewer_ViewPort3d; +class OCCViewer_ViewSketcher; class OCCViewer_ClippingDlg; class OCCViewer_SetRotationPointDlg; @@ -49,6 +50,8 @@ public: enum RotationPointType{ GRAVITY, SELECTED }; + enum SketchingType { NoSketching, Rect, Polygon }; + OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel); virtual ~OCCViewer_ViewWindow() {}; @@ -71,6 +74,11 @@ public: virtual QString getVisualParameters(); virtual void setVisualParameters( const QString& parameters ); + + virtual void initSketchers(); + OCCViewer_ViewSketcher* getSketcher( const int ); + + void activateSketching( int ); public slots: void onFrontView(); @@ -145,6 +153,16 @@ protected: bool computeGravityCenter( double& theX, double& theY, double& theZ ); + virtual void onSketchingStarted(); + virtual void onSketchingFinished(); + + virtual OCCViewer_ViewSketcher* createSketcher( int ); + + OCCViewer_ViewSketcher* mypSketcher; + QList mySketchers; + + int myCurSketch; + OperationType myOperation; OCCViewer_Viewer* myModel; OCCViewer_ViewPort3d* myViewPort; -- 2.39.2