]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
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>
Wed, 19 Jun 2019 15:01:00 +0000 (18:01 +0300)
13 files changed:
src/OCCViewer/CMakeLists.txt
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 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 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..a1ec747cccaced39d9b3459ef62fe35f9d6607c0 100644 (file)
@@ -33,6 +33,7 @@ class QPolygon;
 
 class QtxRectRubberBand;
 class QtxPolyRubberBand;
+class QtxCircleRubberBand;
 
 #ifdef WIN32
 #pragma warning ( disable:4251 )
@@ -69,6 +70,8 @@ public:
   virtual bool                 isDefault() const;
   virtual bool                 eventFilter( QObject*, QEvent* );
 
+  virtual void                 setSketcherMode(int theMode) {}
+
 private slots:
   void                         onDrawViewPort();
 
@@ -119,9 +122,13 @@ 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);
+
 protected:
   virtual bool                 onKey( QKeyEvent* );
   virtual void                 onMouse( QMouseEvent* );
@@ -142,6 +149,9 @@ private:
   int                          myDelButton;
   
   QtxPolyRubberBand*           mypPolyRB;
+  QtxCircleRubberBand*         mypCircleRB;
+
+  SketchMode myMode;
 };
 
 #ifdef WIN32
index f8abc653d0ef012c3e7d8ec1a87fe2751e78ee5e..2d8b48f5012bdf72ad9e0e86dff3ba7047c38ede 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,14 @@ 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_SELECTION_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RECT_STYLE" ) ),
+                          tr( "MNU_SELECTION_STYLE_SWITCH" ), 0, this);
+  aAction->setStatusTip(tr("DSC_SELECTION_STYLE_SWITCH"));
+  aAction->setCheckable(true);
+  connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchSelectionStyle(bool)));
+  toolMgr()->registerAction( aAction, SwitchSelectionStyleId);
+
   // Maximized view
   aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ),
                           tr( "MNU_MINIMIZE_VIEW" ), 0, this );
@@ -1543,6 +1555,7 @@ void OCCViewer_ViewWindow::createToolBar()
   toolMgr()->append( SwitchZoomingStyleId, tid );
   toolMgr()->append( SwitchPreselectionId, tid );
   toolMgr()->append( SwitchSelectionId, tid );
+  toolMgr()->append(SwitchSelectionStyleId, tid );
   if( myModel->trihedronActivated() )
     toolMgr()->append( TrihedronShowId, tid );
 
@@ -2189,6 +2202,26 @@ void OCCViewer_ViewWindow::onSwitchSelection( bool on )
   }
 }
 
+void OCCViewer_ViewWindow::onSwitchSelectionStyle(bool on)
+{
+  // selection
+  QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action(SwitchSelectionStyleId) );
+  if (a) {
+    if (a->isChecked() != on) {
+      a->setChecked(on);
+    }
+    SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+    QPixmap aIcon = on ? aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_CIRCLE_STYLE")) :
+      aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_RECT_STYLE"));
+    a->setIcon(aIcon);
+  }
+  OCCViewer_ViewSketcher* aSkecher = getSketcher(Polygon);
+  if (aSkecher) {
+    aSkecher->setSketcherMode(on ? OCCViewer_PolygonSketcher::Circle :
+      OCCViewer_PolygonSketcher::Poligone);
+  }
+}
+
 /*!
   \brief Switches "keyboard free" interaction style on/off
 */
index 6375da086929097ab374234792fd1a86364dc243..056d4c5a1f07a3d7b0ab90d41e70f43d22cb6e08 100644 (file)
@@ -152,6 +152,7 @@ public:
         SwitchPreselectionId, SwitchSelectionId,
         MaximizedId, SynchronizeId, ReturnTo3dViewId,
         OrthographicId, PerspectiveId, StereoId, RayTracingId, EnvTextureId, LightSourceId,
+   SwitchSelectionStyleId,
         UserId };
 
   enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, 
@@ -313,6 +314,7 @@ public slots:
   virtual void onSwitchZoomingStyle( bool on );
   virtual void onSwitchPreselection( bool on );
   virtual void onSwitchSelection( bool on );
+  virtual void onSwitchSelectionStyle( bool on );
   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..6d3ad7bf8529eb72813b081295af0f8805d8d38f 100644 (file)
         <source>MNU_ZOOMING_STYLE_SWITCH</source>
         <translation>Zooming style switch</translation>
     </message>
+    <message>
+        <source>MNU_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</translation>
+    </message>
     <message>
         <source>DSC_ZOOMING_STYLE_SWITCH</source>
         <translation>Zooming style switch</translation>
     </message>
+    <message>
+        <source>DSC_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</translation>
+    </message>
     <message>
         <source>MNU_ENABLE_PRESELECTION</source>
         <translation>Enable/disable preselection</translation>
index 1aaa3ec68bf263b8abdecec0127f3932cedac2aa..7e08574046b35998c1dcdaa46c65c5857fe908e1 100644 (file)
         <source>MNU_ZOOMING_STYLE_SWITCH</source>
         <translation>Changer le style de zoom</translation>
     </message>
+    <message>
+        <source>MNU_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</translation>
+    </message>
     <message>
         <source>DSC_ZOOMING_STYLE_SWITCH</source>
         <translation>Changer le style de zoom</translation>
     </message>
+    <message>
+        <source>DSC_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</translation>
+    </message>
     <message>
         <source>MNU_ENABLE_PRESELECTION</source>
         <translation>Activer/Désactiver préselection</translation>
index 5613620c44da407ceb11e7883fbe972f83d03224..0820836f4a94a12b176f8ee417d2a2c26fc7c76b 100644 (file)
       <source>MNU_ZOOMING_STYLE_SWITCH</source>
       <translation>ズームのスタイルを変更します。</translation>
     </message>
+    <message>
+        <source>MNU_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</translation>
+    </message>
     <message>
       <source>DSC_ZOOMING_STYLE_SWITCH</source>
       <translation>ズームのスタイルを変更します。</translation>
     </message>
+    <message>
+        <source>DSC_SELECTION_STYLE_SWITCH</source>
+        <translation>Advanced selection style switch</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..ee8bb50
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..18b4f09
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