From b2fe6e10501e8f38ca1858dbcfa03d47c8223c6c Mon Sep 17 00:00:00 2001 From: rnv Date: Wed, 19 Jun 2019 18:01:00 +0300 Subject: [PATCH] 17063 [EDF] Selection by a circle in the OCC Viewer --- doc/salome/gui/input/occ_3d_viewer.rst | 14 +++ doc/salome/gui/input/setting_preferences.rst | 1 + src/LightApp/LightApp_Application.cxx | 33 +++++- src/LightApp/resources/LightApp.xml | 1 + src/LightApp/resources/LightApp_msg_en.ts | 12 ++ src/LightApp/resources/LightApp_msg_fr.ts | 12 ++ src/LightApp/resources/LightApp_msg_ja.ts | 12 ++ src/OCCViewer/CMakeLists.txt | 2 + src/OCCViewer/OCCViewer_ViewFrame.cxx | 14 +++ src/OCCViewer/OCCViewer_ViewFrame.h | 3 + src/OCCViewer/OCCViewer_ViewModel.cxx | 27 +++++ src/OCCViewer/OCCViewer_ViewModel.h | 4 + src/OCCViewer/OCCViewer_ViewSketcher.cxx | 108 ++++++++++-------- src/OCCViewer/OCCViewer_ViewSketcher.h | 14 +++ src/OCCViewer/OCCViewer_ViewWindow.cxx | 73 +++++++++++- src/OCCViewer/OCCViewer_ViewWindow.h | 7 +- src/OCCViewer/resources/OCCViewer_images.ts | 8 ++ src/OCCViewer/resources/OCCViewer_msg_en.ts | 16 +++ src/OCCViewer/resources/OCCViewer_msg_fr.ts | 16 +++ src/OCCViewer/resources/OCCViewer_msg_ja.ts | 16 +++ .../resources/occ_view_circle_style.png | Bin 0 -> 501 bytes .../resources/occ_view_rect_style.png | Bin 0 -> 630 bytes src/Qtx/QtxRubberBand.cxx | 96 +++++++++++++++- src/Qtx/QtxRubberBand.h | 29 +++++ 24 files changed, 464 insertions(+), 54 deletions(-) create mode 100644 src/OCCViewer/resources/occ_view_circle_style.png create mode 100644 src/OCCViewer/resources/occ_view_rect_style.png diff --git a/doc/salome/gui/input/occ_3d_viewer.rst b/doc/salome/gui/input/occ_3d_viewer.rst index 002dbffc2..d5a2f2997 100644 --- a/doc/salome/gui/input/occ_3d_viewer.rst +++ b/doc/salome/gui/input/occ_3d_viewer.rst @@ -67,6 +67,20 @@ ____ ____ +.. image:: ../../../../src/OCCViewer/resources/occ_view_rect_style.png + :align: center + +**Advanced selection by polygon** - enables advanced selection by polygon. + +____ + +.. image:: ../../../../src/OCCViewer/resources/occ_view_circle_style.png + :align: center + +**Advanced selection by polygon** - enables advanced selection by circle. + +____ + .. image:: ../../../../src/OCCViewer/resources/occ_view_fitall.png :align: center diff --git a/doc/salome/gui/input/setting_preferences.rst b/doc/salome/gui/input/setting_preferences.rst index 53cd002ac..306b7a172 100644 --- a/doc/salome/gui/input/setting_preferences.rst +++ b/doc/salome/gui/input/setting_preferences.rst @@ -152,6 +152,7 @@ OCC 3D Viewer Preferences - **Enable preselection** - switches preselection on/off. - **Enable selection** - switches selection on/off. + - **Advanced selection** - switches default advanced selection style by Polygon or by Circle. - **Clipping parameters** - specifies the default clipping plane parameters. diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 83909627c..fb14f540c 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -1633,6 +1633,7 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType resMgr->doubleValue( "OCCViewer", "focus_value", vm->stereographicFocusValue() )); vm->setInterocularDistance( resMgr->integerValue( "OCCViewer", "iod_type", vm->interocularDistanceType() ), resMgr->doubleValue( "OCCViewer", "iod_value", vm->interocularDistanceValue() )); + vm->setSelectionStyle( resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) ); vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) ); vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) ); @@ -2596,13 +2597,22 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) // ... "Selection" group <> int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup ); - pref->setItemProperty( "columns", 2, occSelectionGroup ); + pref->setItemProperty( "columns", 3, occSelectionGroup ); // .... -> enable preselection pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup, LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" ); // .... -> enable selection pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup, LightApp_Preferences::Bool, "OCCViewer", "enable_selection" ); + // .... -> selection style + int aSeleStyle = pref->addPreference( tr( "PREF_SELECTION_STYLE" ), occSelectionGroup, + LightApp_Preferences::Selector, "OCCViewer", "adv_selection_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_POLYGON_SELECTION") << tr("PREF_CIRCLE_SELECTION"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, aSeleStyle); + pref->setItemProperty( "indexes", anIndicesList, aSeleStyle); // ... "Selection" group <> // ... "Clipping" group <> @@ -3313,6 +3323,27 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString } #endif + +#ifndef DISABLE_OCCVIEWER + if (sec == QString("OCCViewer") && param == QString("adv_selection_mode")) + { + int mode = resMgr->integerValue("OCCViewer", "adv_selection_mode", 0); + QList lst; + viewManagers(OCCViewer_Viewer::Type(), lst); + QListIterator it(lst); + while (it.hasNext()) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if (!vm || !vm->inherits("OCCViewer_Viewer")) + continue; + + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->setSelectionStyle(mode); + } + } +#endif + + #ifndef DISABLE_OCCVIEWER if ( sec == QString( "OCCViewer" ) && param == QString( "stereo_type" ) ) { diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index fd64450ee..ae448ffb2 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -125,6 +125,7 @@ + diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index dc4a13b33..fe57830fe 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -212,6 +212,18 @@ The changes will be applied on the next application session. PREF_PERSPECTIVE Perspective + + PREF_POLYGON_SELECTION + Polygon + + + PREF_CIRCLE_SELECTION + Circle + + + PREF_SELECTION_STYLE + Advanced selection + PREF_NAVIGATION Navigation style diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index ca7a04786..266cc6cb1 100644 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -212,6 +212,18 @@ Les modifications seront appliquées à la prochaine session. PREF_PERSPECTIVE Perspective + + PREF_POLYGON_SELECTION + Polygon + + + PREF_CIRCLE_SELECTION + Circle + + + PREF_SELECTION_STYLE + Advanced selection + PREF_NAVIGATION Navigation: diff --git a/src/LightApp/resources/LightApp_msg_ja.ts b/src/LightApp/resources/LightApp_msg_ja.ts index 8ba2a56fa..513e5d270 100644 --- a/src/LightApp/resources/LightApp_msg_ja.ts +++ b/src/LightApp/resources/LightApp_msg_ja.ts @@ -211,6 +211,18 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて PREF_PERSPECTIVE 遠近法 + + PREF_POLYGON_SELECTION + Polygon + + + PREF_CIRCLE_SELECTION + Circle + + + PREF_SELECTION_STYLE + Advanced selection + PREF_NAVIGATION ナビゲーション スタイル diff --git a/src/OCCViewer/CMakeLists.txt b/src/OCCViewer/CMakeLists.txt index 6f2aa585d..5590a5c29 100644 --- a/src/OCCViewer/CMakeLists.txt +++ b/src/OCCViewer/CMakeLists.txt @@ -149,6 +149,8 @@ SET(_other_RESOURCES resources/occ_view_ray_tracing.png resources/occ_view_env_texture.png resources/occ_view_light_source.png + resources/occ_view_circle_style.png + resources/occ_view_rect_style.png ) # --- sources --- diff --git a/src/OCCViewer/OCCViewer_ViewFrame.cxx b/src/OCCViewer/OCCViewer_ViewFrame.cxx index c74e53756..91e39769e 100644 --- a/src/OCCViewer/OCCViewer_ViewFrame.cxx +++ b/src/OCCViewer/OCCViewer_ViewFrame.cxx @@ -354,6 +354,20 @@ void OCCViewer_ViewFrame::setProjectionType( int t) } } +//************************************************************************************** +int OCCViewer_ViewFrame::selectionStyle() const +{ + return getView(MAIN_VIEW)->selectionStyle(); +} + +//************************************************************************************** +void OCCViewer_ViewFrame::setSelectionStyle(int t) +{ + foreach(OCCViewer_ViewWindow* aView, myViews) { + aView->setSelectionStyle(t); + } +} + //************************************************************************************** int OCCViewer_ViewFrame::stereoType() const { diff --git a/src/OCCViewer/OCCViewer_ViewFrame.h b/src/OCCViewer/OCCViewer_ViewFrame.h index 1df7d964a..755afb5ea 100644 --- a/src/OCCViewer/OCCViewer_ViewFrame.h +++ b/src/OCCViewer/OCCViewer_ViewFrame.h @@ -75,6 +75,9 @@ public: virtual int projectionType() const; virtual void setProjectionType( int ); + virtual int selectionStyle() const; + virtual void setSelectionStyle(int); + virtual int stereoType() const; virtual void setStereoType( const int ); diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index 0e3e37f73..87370f17d 100644 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -170,6 +170,7 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) // set projection type to orthographic myProjectionType = 0; + mySelectionStyle = 0; // set stereo parameters myStereoType = 0; myAnaglyphFilter = 0; @@ -244,6 +245,7 @@ void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view ) view->initSketchers(); view->setInteractionStyle( interactionStyle() ); view->setProjectionType( projectionType() ); + view->setSelectionStyle( selectionStyle() ); view->setStereoType( stereoType() ); view->setAnaglyphFilter( anaglyphFilter() ); view->setStereographicFocus( stereographicFocusType(), stereographicFocusValue() ); @@ -545,6 +547,31 @@ void OCCViewer_Viewer::setProjectionType( const int theType ) } } + +int OCCViewer_Viewer::selectionStyle() const +{ + return mySelectionStyle; +} + +void OCCViewer_Viewer::setSelectionStyle(const int theMode) +{ + if (mySelectionStyle != theMode) { + mySelectionStyle = theMode; + if (!myViewManager) + return; + + QVector wins = myViewManager->getViews(); + for (int i = 0; i < (int)wins.count(); i++) + { + OCCViewer_ViewWindow* win = ::qobject_cast(wins.at(i)); + if (win) + win->setSelectionStyle(theMode); + } + } +} + + + /*! \return stereo type */ diff --git a/src/OCCViewer/OCCViewer_ViewModel.h b/src/OCCViewer/OCCViewer_ViewModel.h index 22b8059ed..8d91518e9 100644 --- a/src/OCCViewer/OCCViewer_ViewModel.h +++ b/src/OCCViewer/OCCViewer_ViewModel.h @@ -159,6 +159,9 @@ public: int stereoType() const; void setStereoType( const int ); + int selectionStyle() const; + void setSelectionStyle(const int); + int anaglyphFilter() const; void setAnaglyphFilter( const int ); @@ -260,6 +263,7 @@ protected: int myAnaglyphFilter; int myStereographicFocusType; int myInterocularDistanceType; + int mySelectionStyle; double myStereographicFocusValue; double myInterocularDistanceValue; diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.cxx b/src/OCCViewer/OCCViewer_ViewSketcher.cxx index e70aa8c2b..676a13e7e 100644 --- a/src/OCCViewer/OCCViewer_ViewSketcher.cxx +++ b/src/OCCViewer/OCCViewer_ViewSketcher.cxx @@ -313,14 +313,17 @@ OCCViewer_PolygonSketcher::OCCViewer_PolygonSketcher( OCCViewer_ViewWindow* vw, myToler ( 5, 5 ), //mypPoints ( 0L ), myAddButton ( 0 ), - myDelButton ( 0 ) + myDelButton ( 0 ), + myMode ( Poligone ) { mySketchButton = Qt::RightButton; if ( vw ) - { - OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); - mypPolyRB = new QtxPolyRubberBand( avp ); - } + { + OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + mypPolyRB = new QtxPolyRubberBand( avp ); + mypCircleRB = new QtxCircleRubberBand( avp ); + } + mypData = new QPolygon( 0 ); } OCCViewer_PolygonSketcher::~OCCViewer_PolygonSketcher() @@ -332,7 +335,6 @@ OCCViewer_PolygonSketcher::~OCCViewer_PolygonSketcher() void OCCViewer_PolygonSketcher::onActivate() { myDbl = false; - mypData = new QPolygon( 0 ); //mypPoints = new QPolygon( 0 ); switch ( sketchButton() ) @@ -355,13 +357,11 @@ void OCCViewer_PolygonSketcher::onActivate() void OCCViewer_PolygonSketcher::onDeactivate() { - //delete mypPoints; - //mypPoints = 0; - delete (QPolygon*)mypData; - mypData = 0; - if ( mypPolyRB ) mypPolyRB->clearGeometry(); + if (mypCircleRB) + mypCircleRB->clearGeometry(); + ((QPolygon*)mypData)->clear(); } bool OCCViewer_PolygonSketcher::onKey( QKeyEvent* e ) @@ -471,45 +471,53 @@ void OCCViewer_PolygonSketcher::onMouse( QMouseEvent* e ) void OCCViewer_PolygonSketcher::onSketch( SketchState state ) { - //OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); - QPolygon* points = (QPolygon*)data(); - /*QPainter p( avp ); - p.setPen( Qt::white ); - p.setCompositionMode( QPainter::CompositionMode_Xor ); - 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 ( mypPolyRB ) { - if ( state == Fin ) { - mypPolyRB->clearGeometry(); - mypPolyRB->hide(); - mypViewWindow->activateSketching( OCCViewer_ViewWindow::NoSketching ); - } else { - mypPolyRB->setUpdatesEnabled ( false ); - if ( !mypPolyRB->isVisible() ) - mypPolyRB->show(); - //if ( state != Debut ) - // mypPolyRB->repaint(); - - if ( state != Fin && points->count() ) - mypPolyRB->initGeometry( QPolygon(*points) << myCurr ); - //mypPolyRB->addNode( myCurr ); - - //if ( state != Fin ) - // mypPolyRB->repaint(); - mypPolyRB->setUpdatesEnabled ( true ); - //mypPolyRB->repaint(); + switch (myMode) { + case Poligone: + if (mypPolyRB) { + if (state == Fin) { + mypPolyRB->clearGeometry(); + mypPolyRB->hide(); + mypViewWindow->activateSketching(OCCViewer_ViewWindow::NoSketching); + } + else { + mypPolyRB->setUpdatesEnabled(false); + if (!mypPolyRB->isVisible()) + mypPolyRB->show(); + + if (state != Fin && points->count()) + mypPolyRB->initGeometry(QPolygon(*points) << myCurr); + mypPolyRB->setUpdatesEnabled(true); + } } + break; + case Circle: + if (mypCircleRB) { + if (state == Fin) { + mypCircleRB->getPoligon(points); + mypCircleRB->clearGeometry(); + mypCircleRB->hide(); + if (points->size() == CIRCLE_NB_POINTS) + myResult = Accept; + mypViewWindow->activateSketching(OCCViewer_ViewWindow::NoSketching); + } + else { + mypCircleRB->setUpdatesEnabled(false); + + if (state != Fin) { + if (mypCircleRB->isCenterDefined()) { + mypCircleRB->setRadius(myCurr); + if ((mypCircleRB->radius() > MIN_RADIUS) && (!mypCircleRB->isVisible())) + mypCircleRB->show(); + } + else { + mypCircleRB->initGeometry(myCurr); + } + } + mypCircleRB->setUpdatesEnabled(true); + } + } + break; } } @@ -589,3 +597,7 @@ bool OCCViewer_PolygonSketcher::isIntersect( const QPoint& aStart1, const QPoint } +void OCCViewer_PolygonSketcher::setSketcherMode(int theMode) +{ + myMode = (SketchMode)theMode; +} diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.h b/src/OCCViewer/OCCViewer_ViewSketcher.h index 912865499..48d79cac9 100644 --- a/src/OCCViewer/OCCViewer_ViewSketcher.h +++ b/src/OCCViewer/OCCViewer_ViewSketcher.h @@ -33,6 +33,7 @@ class QPolygon; class QtxRectRubberBand; class QtxPolyRubberBand; +class QtxCircleRubberBand; #ifdef WIN32 #pragma warning ( disable:4251 ) @@ -69,6 +70,9 @@ public: virtual bool isDefault() const; virtual bool eventFilter( QObject*, QEvent* ); + virtual void setSketcherMode(int theMode) {} + virtual int sketcherMode() const { return 0; } + private slots: void onDrawViewPort(); @@ -119,9 +123,16 @@ protected: class OCCVIEWER_EXPORT OCCViewer_PolygonSketcher : public OCCViewer_ViewSketcher { public: + enum SketchMode { Poligone, Circle }; + OCCViewer_PolygonSketcher( OCCViewer_ViewWindow*, int ); virtual ~OCCViewer_PolygonSketcher(); + virtual void setSketcherMode(int theMode); + virtual int sketcherMode() const { + return myMode; + } + protected: virtual bool onKey( QKeyEvent* ); virtual void onMouse( QMouseEvent* ); @@ -142,6 +153,9 @@ private: int myDelButton; QtxPolyRubberBand* mypPolyRB; + QtxCircleRubberBand* mypCircleRB; + + SketchMode myMode; }; #ifdef WIN32 diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index f8abc653d..f866ca29c 100644 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -428,6 +428,10 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) emit keyPressed(this, (QKeyEvent*) e); return true; + case QEvent::KeyRelease: + emit keyReleased(this, (QKeyEvent*) e); + return true; + default: break; } @@ -1472,6 +1476,25 @@ void OCCViewer_ViewWindow::createActions() connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool))); toolMgr()->registerAction( aAction, SwitchZoomingStyleId ); + // Switch advanced selection style (poligone/circle) + aAction = new QtxAction(tr("MNU_RECTANGLE_SELECTION_STYLE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RECT_STYLE" ) ), + tr( "MNU_RECTANGLE_SELECTION_STYLE" ), 0, this); + aAction->setStatusTip(tr("DSC_RECTANGLE_SELECTION_STYLE")); + aAction->setCheckable(true); + toolMgr()->registerAction( aAction, RectangleSelectionStyleId); + + aAction = new QtxAction(tr("MNU_CIRCLE_SELECTION_STYLE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CIRCLE_STYLE" ) ), + tr( "MNU_CIRCLE_SELECTION_STYLE" ), 0, this); + aAction->setStatusTip(tr("DSC_CIRCLE_SELECTION_STYLE")); + aAction->setCheckable(true); + toolMgr()->registerAction( aAction, CircleSelectionStyleId); + + // - add exclusive action group + QActionGroup* aSelectionGroup = new QActionGroup(this); + aSelectionGroup->addAction(toolMgr()->action(RectangleSelectionStyleId)); + aSelectionGroup->addAction(toolMgr()->action(CircleSelectionStyleId)); + connect(aSelectionGroup, SIGNAL(triggered(QAction*)), this, SLOT(onSwitchSelectionStyle(QAction*))); + // Maximized view aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ), tr( "MNU_MINIMIZE_VIEW" ), 0, this ); @@ -1543,6 +1566,8 @@ void OCCViewer_ViewWindow::createToolBar() toolMgr()->append( SwitchZoomingStyleId, tid ); toolMgr()->append( SwitchPreselectionId, tid ); toolMgr()->append( SwitchSelectionId, tid ); + toolMgr()->append(RectangleSelectionStyleId, tid ); + toolMgr()->append(CircleSelectionStyleId, tid ); if( myModel->trihedronActivated() ) toolMgr()->append( TrihedronShowId, tid ); @@ -2189,6 +2214,48 @@ void OCCViewer_ViewWindow::onSwitchSelection( bool on ) } } +/*! + \brief Switches style of advanced multiple selection by Poligon/Circle +*/ +void OCCViewer_ViewWindow::onSwitchSelectionStyle(QAction* theAction) +{ + // selection + OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon); + if (aSkecher) { + if (theAction == toolMgr()->action(RectangleSelectionStyleId)) { + aSkecher->setSketcherMode(OCCViewer_PolygonSketcher::Poligone); + } + else if (theAction == toolMgr()->action(CircleSelectionStyleId)) { + aSkecher->setSketcherMode(OCCViewer_PolygonSketcher::Circle); + } + } +} + +int OCCViewer_ViewWindow::selectionStyle() const +{ + OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon); + if (aSkecher) { + return aSkecher->sketcherMode(); + } + return 0; +} + +void OCCViewer_ViewWindow::setSelectionStyle(int theMode) +{ + OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon); + if (aSkecher) { + aSkecher->setSketcherMode(theMode); + if (theMode == 0) { + toolMgr()->action(RectangleSelectionStyleId)->setChecked(true); + toolMgr()->action(CircleSelectionStyleId)->setChecked(false); + } + else { + toolMgr()->action(RectangleSelectionStyleId)->setChecked(false); + toolMgr()->action(CircleSelectionStyleId)->setChecked(true); + } + } +} + /*! \brief Switches "keyboard free" interaction style on/off */ @@ -3001,11 +3068,11 @@ void OCCViewer_ViewWindow::initSketchers() } } -OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) +OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) const { OCCViewer_ViewSketcher* sketcher = 0; - QList::Iterator it; - for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) + QList::ConstIterator it; + for ( it = mySketchers.cbegin(); it != mySketchers.cend() && !sketcher; ++it ) { OCCViewer_ViewSketcher* sk = (*it); if ( sk->type() == typ ) diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index 6375da086..ac3967995 100644 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -152,6 +152,7 @@ public: SwitchPreselectionId, SwitchSelectionId, MaximizedId, SynchronizeId, ReturnTo3dViewId, OrthographicId, PerspectiveId, StereoId, RayTracingId, EnvTextureId, LightSourceId, + RectangleSelectionStyleId, CircleSelectionStyleId, UserId }; enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, @@ -201,7 +202,7 @@ public: virtual void setVisualParameters( const QString& parameters ); virtual void initSketchers(); - virtual OCCViewer_ViewSketcher* getSketcher( const int ); + virtual OCCViewer_ViewSketcher* getSketcher( const int ) const; virtual void activateSketching( int ); @@ -219,6 +220,9 @@ public: virtual int projectionType() const; virtual void setProjectionType( int ); + virtual int selectionStyle() const; + virtual void setSelectionStyle(int); + virtual int stereoType() const; virtual void setStereoType( const int ); @@ -313,6 +317,7 @@ public slots: virtual void onSwitchZoomingStyle( bool on ); virtual void onSwitchPreselection( bool on ); virtual void onSwitchSelection( bool on ); + virtual void onSwitchSelectionStyle(QAction* theAction); virtual void onRayTracing(); virtual void onEnvTexture(); virtual void onLightSource(); diff --git a/src/OCCViewer/resources/OCCViewer_images.ts b/src/OCCViewer/resources/OCCViewer_images.ts index d91f20aaf..a9fc35485 100644 --- a/src/OCCViewer/resources/OCCViewer_images.ts +++ b/src/OCCViewer/resources/OCCViewer_images.ts @@ -119,6 +119,14 @@ ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH occ_view_zooming_style_switch.png + + ICON_OCCVIEWER_RECT_STYLE + occ_view_rect_style.png + + + ICON_OCCVIEWER_CIRCLE_STYLE + occ_view_circle_style.png + ICON_OCCVIEWER_MAXIMIZE occ_view_maximized.png diff --git a/src/OCCViewer/resources/OCCViewer_msg_en.ts b/src/OCCViewer/resources/OCCViewer_msg_en.ts index 5b0a55a01..2f7fd70fe 100644 --- a/src/OCCViewer/resources/OCCViewer_msg_en.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_en.ts @@ -236,6 +236,22 @@ DSC_ZOOMING_STYLE_SWITCH Zooming style switch + + MNU_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + DSC_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + MNU_CIRCLE_SELECTION_STYLE + Advanced selection by circle + + + DSC_CIRCLE_SELECTION_STYLE + Advanced selection by circle + MNU_ENABLE_PRESELECTION Enable/disable preselection diff --git a/src/OCCViewer/resources/OCCViewer_msg_fr.ts b/src/OCCViewer/resources/OCCViewer_msg_fr.ts index 1aaa3ec68..76c7e57b7 100644 --- a/src/OCCViewer/resources/OCCViewer_msg_fr.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_fr.ts @@ -235,6 +235,22 @@ DSC_ZOOMING_STYLE_SWITCH Changer le style de zoom + + MNU_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + DSC_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + MNU_CIRCLE_SELECTION_STYLE + Advanced selection by circle + + + DSC_CIRCLE_SELECTION_STYLE + Advanced selection by circle + MNU_ENABLE_PRESELECTION Activer/Désactiver préselection diff --git a/src/OCCViewer/resources/OCCViewer_msg_ja.ts b/src/OCCViewer/resources/OCCViewer_msg_ja.ts index 5613620c4..0ac1e9e21 100644 --- a/src/OCCViewer/resources/OCCViewer_msg_ja.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_ja.ts @@ -236,6 +236,22 @@ DSC_ZOOMING_STYLE_SWITCH ズームのスタイルを変更します。 + + MNU_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + DSC_RECTANGLE_SELECTION_STYLE + Advanced selection by polygon + + + MNU_CIRCLE_SELECTION_STYLE + Advanced selection by circle + + + DSC_CIRCLE_SELECTION_STYLE + Advanced selection by circle + MNU_ENABLE_PRESELECTION 予選の有効/無効にします。 diff --git a/src/OCCViewer/resources/occ_view_circle_style.png b/src/OCCViewer/resources/occ_view_circle_style.png new file mode 100644 index 0000000000000000000000000000000000000000..f63b6f9d944d20cafe6d53487da9a6fa44f2e235 GIT binary patch literal 501 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VOS+@4BLl<6e(pbstUx|zfk$L9 z0|U1p2s75F#7_hYvX^-Jy0Ty8km3}O;u=xnoS&PUnpeW$T$GwvlA5AW zo>`Ki5R#Fq;O^-g@IFN~52#QAq%b%?t)x7$D3zfgF*C13FE6!3!9>qc&+M-s=L-e~ zMsrUW#}EtuFVe*0)9kW`6o>Pel34$V1X0BY7^;yYg&+7eqYVy^r*gBh^u(B?F z&UE#&!fW=~jb|7o)3T(BOzi8E8O;tSNT~3aeATS0>wJ3Rm!rfvhDzZSW5vS>7Ut!# z6T7;uW|zD_EV;no@KfIy3yU48QW`#nJSRC#lxI1(q=E%?V&!o2dG)2lW`j>*EO6~0C!OJ*hLXucF!!nZ^&-HIhK zpiIeZxr8+P+yk?N56C3kW6@Mn({H}gctsiHRy~G83i%C(L_{7eh)~(R#qqdJP)N2bZe?^JG%hhNHvLWs=l}o#xJg7oR5(v#`2YVuRWVjU7zP3kY~uJZRzVO30u3Pk z4a9qZxB$e*rVbrr7i3_NU}xvPYhn^I!O1DJRzt&njijW;J)qcApxk^QjsRj2ta>p7 z7#MgsIQUMPnue|@FW;MqjFXb)lvr3q_9!cx?-CVN{KUb*dk(0+9f%!(7#utp26Ax; zZqU+l-iK}&HXIt-Uazn3J%^K%?+DPqzd$U2Vi*u~%gE@SFD%@Whs^+7*vqS|7^wFs z*bF4YGT7O9ZlHSR;_ QcK`qY07*qoM6N<$f|0K7U;qFB literal 0 HcmV?d00001 diff --git a/src/Qtx/QtxRubberBand.cxx b/src/Qtx/QtxRubberBand.cxx index 83889d7c5..fe4bbd6a7 100644 --- a/src/Qtx/QtxRubberBand.cxx +++ b/src/Qtx/QtxRubberBand.cxx @@ -30,6 +30,8 @@ #include #include +#include + /*! \class QtxAbstractRubberBand \brief Analog of class QRubberBand with possibility of creation non-rectangular contour for selection. @@ -95,7 +97,7 @@ void QtxAbstractRubberBand::paintEvent( QPaintEvent* theEvent ) QPainter aPainter( this ); aPainter.setRenderHint( QPainter::Antialiasing ); QRect r = myPoints.boundingRect(); - aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) ); + //aPainter.setClipRegion( r.normalized().adjusted( -1, -1, 2, 2 ) ); aPainter.drawTiledPixmap( 0, 0, width(), height(), tiledPixmap); aPainter.end(); @@ -311,3 +313,95 @@ void QtxPolyRubberBand::setClosed( bool theFlag ) updateMask(); } } + +QtxCircleRubberBand::QtxCircleRubberBand(QWidget* parent) + :QtxAbstractRubberBand(parent), myHasCenter(false) +{ + myPoints.resize(2); + myIsClosed = true; +} + +QtxCircleRubberBand::~QtxCircleRubberBand() +{ +} + +void QtxCircleRubberBand::initGeometry(const QPoint& thePoint) +{ + myIsClosed = false; + myHasCenter = true; + myPoints.clear(); + myPoints << thePoint; + updateMask(); +} + +void QtxCircleRubberBand::setRadius(const QPoint& thePoint) +{ + if (myPoints.size() == 1) + myPoints << thePoint; + else + myPoints.setPoint(1, thePoint); + myIsClosed = true; + updateMask(); +} + +void QtxCircleRubberBand::updateMask() +{ + int aLen = radius(); + if (aLen > MIN_RADIUS) { + QRegion aReg1(myPoints[0].x() - aLen, + myPoints[0].y() - aLen, aLen * 2, aLen * 2, QRegion::Ellipse); + QRegion aReg2(myPoints[0].x() - aLen + 2, + myPoints[0].y() - aLen + 2, aLen * 2 - 4, aLen * 2 - 4, QRegion::Ellipse); + setMask(aReg1 - aReg2); + } +} + +bool QtxCircleRubberBand::isCenterDefined() const +{ + return myHasCenter; +} + +void QtxCircleRubberBand::clearGeometry() +{ + QtxAbstractRubberBand::clearGeometry(); + myHasCenter = false; + myIsClosed = false; +} + +QPoint rotatePoint(const QPoint& theStart, const QPoint& theCenter, double theAngle) +{ + double cosTheta = cos(theAngle); + double sinTheta = sin(theAngle); + int aX = (int)(cosTheta * (theStart.x() - theCenter.x()) - + sinTheta * (theStart.y() - theCenter.y()) + theCenter.x()); + int aY = (int)(sinTheta * (theStart.x() - theCenter.x()) + + cosTheta * (theStart.y() - theCenter.y()) + theCenter.y()); + return QPoint(aX, aY); +} + +static double m_pi = 4 * atan(1); +static double angle_deg = 360. / CIRCLE_NB_POINTS; +static double angle_rad = angle_deg * (m_pi / 180.); + + +void QtxCircleRubberBand::getPoligon(QPolygon* thePoints) const +{ + int aLen = radius(); + if (aLen > MIN_RADIUS) { + thePoints->clear(); + QPoint aCenter = myPoints[0]; + QPoint aStart = myPoints[1]; + for (int i = 0; i < CIRCLE_NB_POINTS; i++) { + thePoints->append(aStart); + aStart = rotatePoint(aStart, aCenter, angle_rad); + } + } +} + +int QtxCircleRubberBand::radius() const +{ + if (myPoints.size() < 2) + return -1; + QPoint aDist = myPoints[1] - myPoints[0]; + return (int)std::sqrt(std::pow(aDist.x(), 2) + std::pow(aDist.y(), 2)); +} \ No newline at end of file diff --git a/src/Qtx/QtxRubberBand.h b/src/Qtx/QtxRubberBand.h index 7d6b10831..4e8b1d939 100644 --- a/src/Qtx/QtxRubberBand.h +++ b/src/Qtx/QtxRubberBand.h @@ -90,4 +90,33 @@ public: void setClosed( bool ); }; + +#define CIRCLE_NB_POINTS 30 +#define MIN_RADIUS 5 + +class QTX_EXPORT QtxCircleRubberBand : public QtxAbstractRubberBand +{ + Q_OBJECT + +public: + QtxCircleRubberBand(QWidget*); + virtual ~QtxCircleRubberBand(); + + void initGeometry(const QPoint&); + + void setRadius(const QPoint&); + + bool isCenterDefined() const; + + virtual void clearGeometry(); + + void getPoligon(QPolygon* thePoints) const; + + int radius() const; + +protected: + virtual void updateMask(); + bool myHasCenter; +}; + #endif //QTXRUBBERBAND_H -- 2.39.2