Salome HOME
17063 [EDF] Selection by a circle in the OCC Viewer
authorrnv <rnv@opencascade.com>
Wed, 19 Jun 2019 15:01:00 +0000 (18:01 +0300)
committerrnv <rnv@opencascade.com>
Fri, 21 Jun 2019 08:49:31 +0000 (11:49 +0300)
24 files changed:
doc/salome/gui/input/occ_3d_viewer.rst
doc/salome/gui/input/setting_preferences.rst
src/LightApp/LightApp_Application.cxx
src/LightApp/resources/LightApp.xml
src/LightApp/resources/LightApp_msg_en.ts
src/LightApp/resources/LightApp_msg_fr.ts
src/LightApp/resources/LightApp_msg_ja.ts
src/OCCViewer/CMakeLists.txt
src/OCCViewer/OCCViewer_ViewFrame.cxx
src/OCCViewer/OCCViewer_ViewFrame.h
src/OCCViewer/OCCViewer_ViewModel.cxx
src/OCCViewer/OCCViewer_ViewModel.h
src/OCCViewer/OCCViewer_ViewSketcher.cxx
src/OCCViewer/OCCViewer_ViewSketcher.h
src/OCCViewer/OCCViewer_ViewWindow.cxx
src/OCCViewer/OCCViewer_ViewWindow.h
src/OCCViewer/resources/OCCViewer_images.ts
src/OCCViewer/resources/OCCViewer_msg_en.ts
src/OCCViewer/resources/OCCViewer_msg_fr.ts
src/OCCViewer/resources/OCCViewer_msg_ja.ts
src/OCCViewer/resources/occ_view_circle_style.png [new file with mode: 0644]
src/OCCViewer/resources/occ_view_rect_style.png [new file with mode: 0644]
src/Qtx/QtxRubberBand.cxx
src/Qtx/QtxRubberBand.h

index 002dbffc2725b908d1dd78d7a93e38780dabe360..d5a2f2997938438c79129f7102d041c1f6273821 100644 (file)
@@ -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
 
index 53cd002ac66b3a1ea4f4b026f19a12a1339eb04a..306b7a1725d7b51ec6e21bb57dd16d2c9636e2d4 100644 (file)
@@ -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.
 
index 83909627cef83370745c4700248c3b183d58a2f0..fb14f540ce122d0f956afb6c59c8c490b83f35f2 100644 (file)
@@ -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 <<start>>
   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 <<end>>
 
   // ... "Clipping" group <<start>>
@@ -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<SUIT_ViewManager*> lst;
+    viewManagers(OCCViewer_Viewer::Type(), lst);
+    QListIterator<SUIT_ViewManager*> 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" ) )
   {
index fd64450eec99cacb9d32a033e895db3acdec50a2..ae448ffb22f1a1f4b15ed0324cdd26e7699ee9cc 100644 (file)
     <!-- OCC viewer preferences -->
     <parameter name="projection_mode"     value="0"/>
     <parameter name="stereo_type"         value="0"/>
+    <parameter name="adv_selection_mode"  value="0"/>
     <parameter name="anaglyph_filter"     value="0"/>
     <parameter name="focus_type"          value="1"/>
     <parameter name="focus_value"         value="1.0"/>
index dc4a13b331aee8a59c07e5b840758dde1c42580d..fe57830fedc1a6f2a72aa0388b20c26ea94e0393 100644 (file)
@@ -212,6 +212,18 @@ The changes will be applied on the next application session.</translation>
         <source>PREF_PERSPECTIVE</source>
         <translation>Perspective</translation>
     </message>
+    <message>
+        <source>PREF_POLYGON_SELECTION</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>PREF_CIRCLE_SELECTION</source>
+        <translation>Circle</translation>
+    </message>
+    <message>
+        <source>PREF_SELECTION_STYLE</source>
+        <translation>Advanced selection</translation>
+    </message>
     <message>
         <source>PREF_NAVIGATION</source>
         <translation>Navigation style</translation>
index ca7a04786d9aa551ab1c173e1b14fb3adedcba44..266cc6cb15271b07108adf46c853d55720f65f39 100644 (file)
@@ -212,6 +212,18 @@ Les modifications seront appliquées à la prochaine session.</translation>
         <source>PREF_PERSPECTIVE</source>
         <translation>Perspective</translation>
     </message>
+    <message>
+        <source>PREF_POLYGON_SELECTION</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>PREF_CIRCLE_SELECTION</source>
+        <translation>Circle</translation>
+    </message>
+    <message>
+        <source>PREF_SELECTION_STYLE</source>
+        <translation>Advanced selection</translation>
+    </message>
     <message>
         <source>PREF_NAVIGATION</source>
         <translation>Navigation:</translation>
index 8ba2a56fa8466b604646b7cd0268c09893652f17..513e5d2702786aaa5d4f4fb7dc54e147315a6aa4 100644 (file)
@@ -211,6 +211,18 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて
       <source>PREF_PERSPECTIVE</source>
       <translation>遠近法</translation>
     </message>
+    <message>
+        <source>PREF_POLYGON_SELECTION</source>
+        <translation>Polygon</translation>
+    </message>
+    <message>
+        <source>PREF_CIRCLE_SELECTION</source>
+        <translation>Circle</translation>
+    </message>
+    <message>
+        <source>PREF_SELECTION_STYLE</source>
+        <translation>Advanced selection</translation>
+    </message>
     <message>
       <source>PREF_NAVIGATION</source>
       <translation>ナビゲーション スタイル</translation>
index 6f2aa585d855d0ae12685c086e87446c4d5e6382..5590a5c29ebb6f19a42717423bac909256928cc6 100644 (file)
@@ -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 ---
index c74e5375610e85152623f68a89592f9076d5717f..91e39769e8a6951ca1b8a54e32e24a3dbaa01b41 100644 (file)
@@ -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
 {
index 1df7d964a23241e4885e6e8de84628ab88ac4a8c..755afb5ea83b5057b05e20fa9e9d1ce656163738 100644 (file)
@@ -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 );
 
index 0e3e37f7368d5139a9cf690bb5c30db2bf05ffbc..87370f17d8c1f6f6a2d2beb36fbf331adbd1e216 100644 (file)
@@ -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<SUIT_ViewWindow*> wins = myViewManager->getViews();
+    for (int i = 0; i < (int)wins.count(); i++)
+    {
+      OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>(wins.at(i));
+      if (win)
+        win->setSelectionStyle(theMode);
+    }
+  }
+}
+
+
+
 /*!
   \return stereo type
 */
index 22b8059ed1bf03641de21ef64c76abb215a07a2b..8d91518e92fcfd2c525fa8e34751978b02fdfe81 100644 (file)
@@ -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;
index e70aa8c2bd519fb0e6e8f681445739e7a509187f..676a13e7e49fd90357fc5657d98ad2e5baef7286 100644 (file)
@@ -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;
+}
index 912865499b4745e42c9b1c1143e5101ae5511677..48d79cac990f3f4c930f6f2a240961be89b626a0 100644 (file)
@@ -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
index f8abc653d0ef012c3e7d8ec1a87fe2751e78ee5e..f866ca29c2ed381227eb1ef87c3123c598783449 100644 (file)
@@ -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<OCCViewer_ViewSketcher*>::Iterator it;
-  for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
+  QList<OCCViewer_ViewSketcher*>::ConstIterator it;
+  for ( it = mySketchers.cbegin(); it != mySketchers.cend() && !sketcher; ++it )
   {
     OCCViewer_ViewSketcher* sk = (*it);
     if ( sk->type() == typ )
index 6375da086929097ab374234792fd1a86364dc243..ac3967995d4df28481492ac188fae6cef84e49ff 100644 (file)
@@ -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();
index d91f20aafdab0fb4057d19dc1727a8572d8a2933..a9fc35485bd0472d1e3e44269405255f6214cf0d 100644 (file)
         <source>ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH</source>
         <translation>occ_view_zooming_style_switch.png</translation>
     </message>
+    <message>
+        <source>ICON_OCCVIEWER_RECT_STYLE</source>
+        <translation>occ_view_rect_style.png</translation>
+    </message>
+    <message>
+        <source>ICON_OCCVIEWER_CIRCLE_STYLE</source>
+        <translation>occ_view_circle_style.png</translation>
+    </message>
     <message>
         <source>ICON_OCCVIEWER_MAXIMIZE</source>
         <translation>occ_view_maximized.png</translation>
index 5b0a55a019ac8263a0f5defd0d9b3b5a43445116..2f7fd70fec5fc8d611f921d83b442b8ba69c860f 100644 (file)
         <source>DSC_ZOOMING_STYLE_SWITCH</source>
         <translation>Zooming style switch</translation>
     </message>
+    <message>
+        <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>MNU_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
+    <message>
+        <source>DSC_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
     <message>
         <source>MNU_ENABLE_PRESELECTION</source>
         <translation>Enable/disable preselection</translation>
index 1aaa3ec68bf263b8abdecec0127f3932cedac2aa..76c7e57b7eeb0459ba66b288f2f1ef0a0fdbedd9 100644 (file)
         <source>DSC_ZOOMING_STYLE_SWITCH</source>
         <translation>Changer le style de zoom</translation>
     </message>
+    <message>
+        <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>MNU_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
+    <message>
+        <source>DSC_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
     <message>
         <source>MNU_ENABLE_PRESELECTION</source>
         <translation>Activer/Désactiver préselection</translation>
index 5613620c44da407ceb11e7883fbe972f83d03224..0ac1e9e2120e8f3bd2ae0c5c3290127fc7266d63 100644 (file)
       <source>DSC_ZOOMING_STYLE_SWITCH</source>
       <translation>ズームのスタイルを変更します。</translation>
     </message>
+    <message>
+        <source>MNU_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>DSC_RECTANGLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by polygon</translation>
+    </message>
+    <message>
+        <source>MNU_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
+    <message>
+        <source>DSC_CIRCLE_SELECTION_STYLE</source>
+        <translation>Advanced selection by circle</translation>
+    </message>
     <message>
       <source>MNU_ENABLE_PRESELECTION</source>
       <translation>予選の有効/無効にします。</translation>
diff --git a/src/OCCViewer/resources/occ_view_circle_style.png b/src/OCCViewer/resources/occ_view_circle_style.png
new file mode 100644 (file)
index 0000000..f63b6f9
Binary files /dev/null and b/src/OCCViewer/resources/occ_view_circle_style.png differ
diff --git a/src/OCCViewer/resources/occ_view_rect_style.png b/src/OCCViewer/resources/occ_view_rect_style.png
new file mode 100644 (file)
index 0000000..acc3bc0
Binary files /dev/null and b/src/OCCViewer/resources/occ_view_rect_style.png differ
index 83889d7c5d4747c826959b2f9568baeb5d5f5bf1..fe4bbd6a7db313d229b10b4d85053171601baf64 100644 (file)
@@ -30,6 +30,8 @@
 #include <QShowEvent>
 #include <QVectorIterator>
 
+#include <math.h>
+
 /*!
   \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
index 7d6b10831b316b8f93f54817a7125c268fe0e8ac..4e8b1d9397c54245ad8c8229b41e961267248b68 100644 (file)
@@ -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