From: adv Date: Tue, 19 Nov 2013 08:19:50 +0000 (+0000) Subject: A new point is inserted on existing segment. Line/spline curve type. X-Git-Tag: BR_hydro_v_0_3_1~66 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=5ab983d4b8b4d9d77dd3da5069659afc8c338b80;p=modules%2Fhydro.git A new point is inserted on existing segment. Line/spline curve type. --- diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.cxx b/src/HYDROCurveCreator/CurveCreator_Utils.cxx index 30779616..ec27ddb0 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Utils.cxx @@ -19,10 +19,23 @@ #include "CurveCreator_Utils.h" +#include + #include #include #include +//======================================================================= +// 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; + */ } diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.h b/src/HYDROCurveCreator/CurveCreator_Utils.h index f727601d..7d901d11 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.h +++ b/src/HYDROCurveCreator/CurveCreator_Utils.h @@ -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. * diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.cxx b/src/HYDROCurveCreator/CurveCreator_Widget.cxx index 441d059e..c2f9d69a 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Widget.cxx @@ -26,8 +26,6 @@ #include "CurveCreator_NewSectionDlg.h" #include "CurveCreator_Utils.h" -#include - #include #include #include @@ -39,8 +37,14 @@ #include #include +#include +#include +#include #include #include +#include + +#include #include #include @@ -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; diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.h b/src/HYDROCurveCreator/CurveCreator_Widget.h index bbc58f69..0129da99 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.h +++ b/src/HYDROCurveCreator/CurveCreator_Widget.h @@ -30,6 +30,10 @@ #include #include +#include +#include +#include + 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 myActionMap;