Salome HOME
A new point is inserted on existing segment. Line/spline curve type.
authoradv <adv@opencascade.com>
Tue, 19 Nov 2013 08:19:50 +0000 (08:19 +0000)
committeradv <adv@opencascade.com>
Tue, 19 Nov 2013 08:19:50 +0000 (08:19 +0000)
src/HYDROCurveCreator/CurveCreator_Utils.cxx
src/HYDROCurveCreator/CurveCreator_Utils.h
src/HYDROCurveCreator/CurveCreator_Widget.cxx
src/HYDROCurveCreator/CurveCreator_Widget.h

index 30779616cf2d7830e0c04fa8af3256aa9d90f765..ec27ddb04599b9e6b98e1d18155032b308876f3e 100644 (file)
 
 #include "CurveCreator_Utils.h"
 
+#include <GEOMUtils.hxx>
+
 #include <gp_Pln.hxx>
 #include <ProjLib.hxx>
 #include <ElSLib.hxx>
 
+//=======================================================================
+// function : ConvertClickToPoint()
+// purpose  : Returns the point clicked in 3D view
+//=======================================================================
+void CurveCreator_Utils::ConvertPointToClick( const gp_Pnt& thePoint,
+                                              Handle(V3d_View) theView,
+                                              int& x, int& y )
+{
+  theView->Convert(thePoint.X(), thePoint.Y(), thePoint.Z(), x, y );
+}
+
 
 //=======================================================================
 // function : ConvertClickToPoint()
@@ -30,6 +43,8 @@
 //=======================================================================
 gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) aView )
 {
+  return GEOMUtils::ConvertClickToPoint( x, y, aView );
+  /*
   V3d_Coordinate XEye, YEye, ZEye, XAt, YAt, ZAt;
   aView->Eye( XEye, YEye, ZEye );
 
@@ -48,4 +63,5 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a
   gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project( PlaneOfTheView, ConvertedPoint );
   gp_Pnt ResultPoint = ElSLib::Value( ConvertedPointOnPlane.X(), ConvertedPointOnPlane.Y(), PlaneOfTheView );
   return ResultPoint;
+  */
 }
index f727601d588f5e0cf4943466c1ec3a2b8d74efe2..7d901d11574e93d62551a61acb67b6da7b8f0a13 100644 (file)
@@ -29,6 +29,18 @@ class CurveCreator_Utils
 {
 public:
 
+    /*!
+   * \brief Returns the point clicked in 3D view.
+   *
+   * \param x The X coordinate in the view.
+   * \param y The Y coordinate in the view.
+   * \param theView View where the given point takes place.
+   * \retval gp_Pnt Returns the point clicked in 3D view
+   */
+  CURVECREATOR_EXPORT static void ConvertPointToClick( const gp_Pnt& thePoint,
+                                                       Handle(V3d_View) theView,
+                                                       int& x, int& y );
+
   /*!
    * \brief Returns the point clicked in 3D view.
    *
index 441d059ee710fbb37d5281b4993b2c9d96f2d64b..c2f9d69a3bfd2f866d1baa636ac10341d5538e0a 100644 (file)
@@ -26,8 +26,6 @@
 #include "CurveCreator_NewSectionDlg.h"
 #include "CurveCreator_Utils.h"
 
-#include <GEOMUtils.hxx>
-
 #include <SUIT_Session.h>
 #include <SUIT_Desktop.h>
 #include <SUIT_ResourceMgr.h>
 
 #include <BRep_Tool.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Dir.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 
 #include <AIS_ListOfInteractive.hxx>
 #include <AIS_ListIteratorOfListOfInteractive.hxx>
@@ -66,6 +70,8 @@
 const double LOCAL_SELECTION_TOLERANCE = 0.0001;
 const int POINT_INDEX_COLUMN_WIDTH = 50;
 
+const int SCENE_PIXEL_TOLERANCE = 4;
+
 CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
                                          CurveCreator_ICurve *theCurve,
                                          Qt::WindowFlags fl)
@@ -847,7 +853,7 @@ void CurveCreator_Widget::onGetCoordsByClick( QMouseEvent* pe )
     {
       OCCViewer_ViewPort3d* vp =
         ((OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView())->getViewPort();
-      aPnt = GEOMUtils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
+      aPnt = CurveCreator_Utils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
     }
     // set the coordinates into dialog
     CurveCreator::Coordinates aCoords;
@@ -933,9 +939,9 @@ void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
   //setLocalPointContext( false );
   OCCViewer_ViewWindow* aWindow =
            (OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView();
-  gp_Pnt aStartPnt = GEOMUtils::ConvertClickToPoint( myDragStartPosition.x(), myDragStartPosition.y(),
+  gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(), myDragStartPosition.y(),
                                                      aWindow->getViewPort()->getView() );
-  gp_Pnt anEndPnt = GEOMUtils::ConvertClickToPoint( aPos.x(), aPos.y(),
+  gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( aPos.x(), aPos.y(),
                                                     aWindow->getViewPort()->getView() );
   double aXDelta = aStartPnt.X() - anEndPnt.X();
   double anYDelta = aStartPnt.Y() - anEndPnt.Y();
@@ -1153,10 +1159,9 @@ void CurveCreator_Widget::setLocalPointContext( const bool theOpen )
 
   if ( theOpen ) {
     // Open local context if there is no one
-    bool allObjects = true;
     if ( !ic->HasOpenedContext() ) {
       ic->ClearCurrents( false );
-      ic->OpenLocalContext( allObjects, true, true );
+      ic->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ );
     }
     AIS_ListOfInteractive aList;
     ic->DisplayedObjects( aList );
@@ -1164,7 +1169,6 @@ void CurveCreator_Widget::setLocalPointContext( const bool theOpen )
     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
       aLSize++;
 
-    int theMode = TopAbs_VERTEX;
     for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
     {
       Handle(AIS_InteractiveObject) anAIS = it.Value();
@@ -1172,13 +1176,13 @@ void CurveCreator_Widget::setLocalPointContext( const bool theOpen )
       {
         if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
         {
-          ic->Load( anAIS, -1, false );
-          ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)theMode ) );
+          ic->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ );
+          ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) );
         }
         else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) )
         {
-          ic->Load( anAIS, -1, false );
-          ic->Activate( anAIS, theMode );
+          ic->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ );
+          ic->Activate( anAIS, TopAbs_VERTEX );
         }
       }
       continue;
@@ -1330,42 +1334,83 @@ bool CurveCreator_Widget::pointOnObject( Handle(AIS_InteractiveObject) theObject
   if ( theObject.IsNull() || !aViewer )
     return isFound;
 
-  OCCViewer_ViewWindow* aWindow =
-           (OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView();
-  thePoint = GEOMUtils::ConvertClickToPoint( theX, theY,
-                                             aWindow->getViewPort()->getView() );
-
+  gp_Pnt aPoint;
+  gp_Pnt aPnt1, aPnt2;
   Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject );
   if ( !aLine.IsNull() ) {
+    const Handle(Geom_Line) aGLine = aLine->Line();
     Handle(Geom_Point) aPStart;
     Handle(Geom_Point) aPEnd;
     aLine->Points( aPStart, aPEnd );
-
-    Standard_Real aStartX = aPStart->X(),
-                  aStartY = aPStart->Y(),
-                  aStartZ = aPStart->Z();
-    Standard_Real anEndX = aPEnd->X(),
-                  anEndY = aPEnd->Y(),
-                  anEndZ = aPEnd->Z();
-    // TODO: check whether the point belong to the selected line
-    gp_Lin aLin( gp_Pnt( aPStart->X(), aPStart->Y(), aPStart->Z() ),
-                gp_Dir( gp_Vec( gp_Pnt( aPStart->X(), aPStart->Y(), aPStart->Z() ),
-                                gp_Pnt( aPEnd->X(), aPEnd->Y(), aPEnd->Z() ) ) ) );
-    double aDistance = aLin.Distance( thePoint );
-
-
-    if ( aLin.Contains( thePoint, LOCAL_SELECTION_TOLERANCE ) ) {
-      // find the neighbour points
-      thePoint1 = findLocalPointIndex( 0, aPStart->X(), aPStart->Y() );
-      thePoint2 = findLocalPointIndex( 0, aPEnd->X(),   aPEnd->Y() );
-
-      isFound = thePoint1 >= 0 && thePoint2 >= 0;
-    }
+    aPnt1 = aPStart->Pnt();
+    aPnt2 = aPEnd->Pnt();
+    isFound = hasProjectPointOnCurve( theX, theY, aGLine, aPoint );
   }
   else {
     Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject );
     if ( !aShape.IsNull() ) {
-      // find the neighbour points
+      const TopoDS_Wire& aWire = TopoDS::Wire( aShape->Shape() );
+      if ( !aWire.IsNull() ) {
+        TopExp_Explorer anExp( aWire, TopAbs_EDGE );
+        for ( ; anExp.More(); anExp.Next())
+        {
+          const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
+          if ( !anEdge.IsNull() ) {
+            Standard_Real aFirst, aLast;
+            Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst, aLast );
+            aCurve->D0(aFirst,aPnt1);
+            aCurve->D0(aLast,aPnt2);
+            isFound = hasProjectPointOnCurve( theX, theY, aCurve, aPoint );
+          }
+        }
+      }
+    }
+  }
+  if ( isFound ) {
+    thePoint = aPoint;
+    thePoint1 = findLocalPointIndex( 0, aPnt1.X(), aPnt1.Y() );
+    thePoint2 = findLocalPointIndex( 0, aPnt2.X(), aPnt2.Y() );
+    isFound = thePoint1 >= 0 && thePoint2 >= 0;
+  }
+  return isFound;
+}
+
+/**
+ * Returns whether the clicked point belong to the curve or has a very near projection
+ * \param theX the X coordinate of a point clicked in the OCC viewer
+ * \param theY the Y coordinate of a point clicked in the OCC viewer
+ * \param theCurve a geometry curve
+ * \param theOutPoint a found projected point on the curve
+ */
+bool CurveCreator_Widget::hasProjectPointOnCurve( const int theX, const int theY,
+                                                  const Handle(Geom_Curve)& theCurve,
+                                                  gp_Pnt& theOutPoint )
+{
+  bool isFound = false;
+  OCCViewer_Viewer* aViewer = getOCCViewer();
+  if ( !aViewer )
+    return isFound;
+
+  OCCViewer_ViewWindow* aWindow =
+           (OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView();
+  Handle(V3d_View) aView = aWindow->getViewPort()->getView();
+  gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, aView );
+
+  GeomAPI_ProjectPointOnCurve aProj( aPoint, theCurve );
+  Standard_Integer aNbPoint = aProj.NbPoints();
+  if (aNbPoint > 0) {
+    for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) {
+      gp_Pnt aNewPoint = aProj.Point(j);
+
+      int aX, anY;
+      CurveCreator_Utils::ConvertPointToClick( aNewPoint, aView, aX, anY );
+
+      int aXDelta = abs( aX - theX );
+      int anYDelta = abs( anY - theY );
+      isFound = aXDelta < SCENE_PIXEL_TOLERANCE && anYDelta < SCENE_PIXEL_TOLERANCE;
+      if ( isFound ) {
+        theOutPoint = aNewPoint;
+      }
     }
   }
   return isFound;
index bbc58f69476e2420b5c202a6229ef57848b1ae59..0129da991c4d7b19e4bae08cac6ea254da9e9148 100644 (file)
 #include <SUIT_ViewWindow.h>
 #include <AIS_InteractiveObject.hxx>
 
+#include <Geom_Curve.hxx>
+#include <V3d_View.hxx>
+#include <gp_Pnt.hxx>
+
 class OCCViewer_Viewer;
 
 class QAction;
@@ -155,6 +159,9 @@ private:
   bool pointOnObject( Handle(AIS_InteractiveObject) theObject,
                       const int theX, const int theY,
                       gp_Pnt& thePoint, int& thePoint1, int& thePoint2 );
+  bool hasProjectPointOnCurve( const int theX, const int theY,
+                               const Handle(Geom_Curve)& theCurve,
+                               gp_Pnt& theOutPoint );
 
 private:
   QMap<ActionId, QAction*>    myActionMap;