From f5d741e54ea475315ee8f7ca822d1ecba030fc21 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 3 Dec 2013 08:03:28 +0000 Subject: [PATCH] OCC functionality moving out from the widget --- src/HYDROCurveCreator/CurveCreator_Utils.cxx | 176 ++++++++++++++++++ src/HYDROCurveCreator/CurveCreator_Utils.h | 43 ++++- src/HYDROCurveCreator/CurveCreator_Widget.cxx | 176 ++---------------- src/HYDROCurveCreator/CurveCreator_Widget.h | 8 - 4 files changed, 230 insertions(+), 173 deletions(-) diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.cxx b/src/HYDROCurveCreator/CurveCreator_Utils.cxx index ec27ddb0..15396cdc 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Utils.cxx @@ -22,9 +22,33 @@ #include #include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + #include #include +const double LOCAL_SELECTION_TOLERANCE = 0.0001; +const int SCENE_PIXEL_TOLERANCE = 10; + //======================================================================= // function : ConvertClickToPoint() // purpose : Returns the point clicked in 3D view @@ -65,3 +89,155 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a return ResultPoint; */ } + +//======================================================================= +// function : setLocalPointContext +// purpose : Open/close the viewer local context +//======================================================================= +void CurveCreator_Utils::setLocalPointContext( + Handle(AIS_InteractiveContext) theContext, + const bool theOpen ) +{ + if ( !theContext ) + return; + + if ( theOpen ) { + // Open local context if there is no one + if ( !theContext->HasOpenedContext() ) { + theContext->ClearCurrents( false ); + theContext->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ ); + } + AIS_ListOfInteractive aList; + theContext->DisplayedObjects( aList ); + int aLSize = 0; + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) + aLSize++; + + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) + { + Handle(AIS_InteractiveObject) anAIS = it.Value(); + if ( !anAIS.IsNull() ) + { + if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) + { + theContext->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ ); + theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) ); + //theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_VERTEX ) ); + } + else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) ) + { + theContext->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ ); + theContext->Activate( anAIS, TopAbs_VERTEX ); + } + } + continue; + } + } + else { + if ( theContext->HasOpenedContext() ) + theContext->CloseAllContexts(); + } +} + +bool CurveCreator_Utils::pointOnObject( Handle(V3d_View) theView, + Handle(AIS_InteractiveObject) theObject, + const int theX, const int theY, + gp_Pnt& thePoint, + gp_Pnt& thePoint1, gp_Pnt& thePoint2 ) +{ + bool isFound = false; + + if ( theObject.IsNull() || theView.IsNull() ) + return isFound; + + gp_Pnt aPoint; + Standard_Real aParameter; + gp_Pnt aPnt1, aPnt2; + Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject ); + if ( !aLine.IsNull() ) { + const Handle(Geom_Line) aGLine = aLine->Line(); + isFound = hasProjectPointOnCurve( theView, theX, theY, aGLine, aParameter ); + if ( isFound ) { + aPoint = aGLine->Value( aParameter ); + + Handle(Geom_Point) aPStart; + Handle(Geom_Point) aPEnd; + aLine->Points( aPStart, aPEnd ); + aPnt1 = aPStart->Pnt(); + aPnt2 = aPEnd->Pnt(); + + // in case of Geom line a projection is performed to the infinite line, + // so it is necessary to bound it by the line size + Bnd_Box aLineBox; + aLineBox.Set( aPnt1, gp_Vec( aPnt1, aPnt2 ) ); + isFound = !aLineBox.IsOut( aPoint ); + } + } + else { + Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject ); + if ( !aShape.IsNull() ) { + 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 ); + + if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) { + Handle(Geom_BSplineCurve) aBSplineCurve = Handle(Geom_BSplineCurve)::DownCast( aCurve ); + if ( !aBSplineCurve.IsNull() ) { + isFound = hasProjectPointOnCurve( theView, theX, theY, aCurve, aParameter ); + if ( isFound ) { + aPoint = aBSplineCurve->Value( aParameter ); + Standard_Integer anI1, anI2; + aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 ); + + aPnt1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) ); + aPnt2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) ); + } + } + } + } + } + } + } + } + if ( isFound ) { + thePoint = aPoint; + thePoint1 = aPnt1; + thePoint2 = aPnt2; + } + return isFound; +} + +bool CurveCreator_Utils::hasProjectPointOnCurve( Handle(V3d_View) theView, + const int theX, const int theY, + const Handle(Geom_Curve)& theCurve, + Standard_Real& theParameter ) +{ + bool isFound = false; + if ( theView.IsNull() ) + return isFound; + + gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, theView ); + + 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 ); + theParameter = aProj.Parameter( j ); + + int aX, anY; + CurveCreator_Utils::ConvertPointToClick( aNewPoint, theView, aX, anY ); + + int aXDelta = abs( aX - theX ); + int anYDelta = abs( anY - theY ); + isFound = aXDelta < SCENE_PIXEL_TOLERANCE && anYDelta < SCENE_PIXEL_TOLERANCE; + } + } + return isFound; +} diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.h b/src/HYDROCurveCreator/CurveCreator_Utils.h index 7d901d11..52d34e63 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.h +++ b/src/HYDROCurveCreator/CurveCreator_Utils.h @@ -22,8 +22,10 @@ #include "CurveCreator_Macro.hxx" -#include +#include #include +#include +#include class CurveCreator_Utils { @@ -49,7 +51,44 @@ public: * \param theView View where the given point takes place. * \retval gp_Pnt Returns the point clicked in 3D view */ - CURVECREATOR_EXPORT static gp_Pnt ConvertClickToPoint( int x, int y, Handle(V3d_View) theView ); + CURVECREATOR_EXPORT static gp_Pnt ConvertClickToPoint( int x, int y, + Handle(V3d_View) theView ); + + /*! + * \brief Sets the local point context for the 3D viewer. + * \param theOpen The flag to open or close the local context. + */ + CURVECREATOR_EXPORT static void setLocalPointContext( + Handle(AIS_InteractiveContext) theContext, + const bool theOpen ); + + /** + * Checks whether the point belongs to the OCC object + * \param theObject a line or shape with a bspline inside + * \param theX the X coordinate in the view. + * \param theY the Y coordinate in the view. + * \param thePoint the output point to be append to the model curve + * \param thePoint1 the output point to bound the line where a new point should be inserted + * \param thePoint2 the output point to bound the line where a new point should be inserted + */ + CURVECREATOR_EXPORT static bool pointOnObject( Handle(V3d_View) theView, + Handle(AIS_InteractiveObject) theObject, + const int theX, const int theY, + gp_Pnt& thePoint, gp_Pnt& thePoint1, + gp_Pnt& thePoint2 ); + + /* + * 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 + */ + CURVECREATOR_EXPORT static bool hasProjectPointOnCurve( + Handle(V3d_View) theView, + const int theX, const int theY, + const Handle(Geom_Curve)& theCurve, + Standard_Real& theParameter ); }; diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.cxx b/src/HYDROCurveCreator/CurveCreator_Widget.cxx index 37169ef5..a19fbead 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Widget.cxx @@ -1134,6 +1134,13 @@ void CurveCreator_Widget::insertPointToSelectedSegment( const int theX, gp_Pnt aPoint1, aPoint2; bool isFoundPoint = false; + OCCViewer_ViewPort3d* aViewPort = getViewPort(); + Handle(V3d_View) aView; + if ( aViewPort ) + aView = aViewPort->getView(); + if ( aView.IsNull() ) + return; + for ( aContext->InitSelected(); aContext->MoreSelected() && !isFoundPoint; aContext->NextSelected() ) { TopoDS_Shape aTShape = aContext->SelectedShape(); @@ -1145,7 +1152,9 @@ void CurveCreator_Widget::insertPointToSelectedSegment( const int theX, continue; const TopLoc_Location& aLocation = anOwner->Location(); Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() ); - isFoundPoint = pointOnObject( anAIS, theX, theY, aPoint, aPoint1, aPoint2 ); + + isFoundPoint = CurveCreator_Utils::pointOnObject( aView, anAIS, theX, theY, aPoint, + aPoint1, aPoint2 ); } } if ( !isFoundPoint ) @@ -1287,48 +1296,9 @@ void CurveCreator_Widget::updateLocalPointView() */ void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable ) { - Handle(AIS_InteractiveContext) ic = getAISContext(); - if ( !ic ) - return; - - if ( theOpen ) { - // Open local context if there is no one - if ( !ic->HasOpenedContext() ) { - ic->ClearCurrents( false ); - ic->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ ); - } - AIS_ListOfInteractive aList; - ic->DisplayedObjects( aList ); - int aLSize = 0; - for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) - aLSize++; - - for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) - { - Handle(AIS_InteractiveObject) anAIS = it.Value(); - if ( !anAIS.IsNull() ) - { - if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) - { - ic->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ ); - ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_WIRE ) ); - //ic->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_VERTEX ) ); - } - else if ( anAIS->DynamicType() != STANDARD_TYPE(AIS_Trihedron) ) - { - ic->Load( anAIS, -1/*selection mode*/, false/*allow decomposition*/ ); - ic->Activate( anAIS, TopAbs_VERTEX ); - } - } - continue; - } - } - else { - if ( ic->HasOpenedContext() ) - ic->CloseAllContexts(); - if ( isUpdateTable ) - updateLocalPointView(); - } + CurveCreator_Utils::setLocalPointContext( getAISContext(), theOpen ); + if ( !theOpen && isUpdateTable ) + updateLocalPointView(); } void CurveCreator_Widget::addLocalPointToTable( const double theX, const double theY ) @@ -1562,126 +1532,6 @@ void CurveCreator_Widget::convert( const SectionToPointList& thePoints, } } -/** - * Checks whether the point belongs to the OCC object - * \param theObject a line or shape with a bspline inside - * \param theX the X coordinate in the view. - * \param theY the Y coordinate in the view. - * \param thePoint the output point to be append to the model curve - * \param thePoint1 the output point to bound the line where a new point should be inserted - * \param thePoint2 the output point to bound the line where a new point should be inserted - */ -bool CurveCreator_Widget::pointOnObject( Handle(AIS_InteractiveObject) theObject, - const int theX, const int theY, - gp_Pnt& thePoint, - gp_Pnt& thePoint1, gp_Pnt& thePoint2 ) -{ - bool isFound = false; - - Handle(AIS_InteractiveContext) aContext = getAISContext(); - if ( theObject.IsNull() || !aContext ) - return isFound; - - gp_Pnt aPoint; - Standard_Real aParameter; - gp_Pnt aPnt1, aPnt2; - Handle(AIS_Line) aLine = Handle(AIS_Line)::DownCast( theObject ); - if ( !aLine.IsNull() ) { - const Handle(Geom_Line) aGLine = aLine->Line(); - isFound = hasProjectPointOnCurve( theX, theY, aGLine, aParameter ); - if ( isFound ) { - aPoint = aGLine->Value( aParameter ); - - Handle(Geom_Point) aPStart; - Handle(Geom_Point) aPEnd; - aLine->Points( aPStart, aPEnd ); - aPnt1 = aPStart->Pnt(); - aPnt2 = aPEnd->Pnt(); - - // in case of Geom line a projection is performed to the infinite line, - // so it is necessary to bound it by the line size - Bnd_Box aLineBox; - aLineBox.Set( aPnt1, gp_Vec( aPnt1, aPnt2 ) ); - isFound = !aLineBox.IsOut( aPoint ); - } - } - else { - Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject ); - if ( !aShape.IsNull() ) { - 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 ); - - if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) { - Handle(Geom_BSplineCurve) aBSplineCurve = Handle(Geom_BSplineCurve)::DownCast( aCurve ); - if ( !aBSplineCurve.IsNull() ) { - isFound = hasProjectPointOnCurve( theX, theY, aCurve, aParameter ); - if ( isFound ) { - aPoint = aBSplineCurve->Value( aParameter ); - Standard_Integer anI1, anI2; - aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 ); - - aPnt1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) ); - aPnt2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) ); - } - } - } - } - } - } - } - } - if ( isFound ) { - thePoint = aPoint; - thePoint1 = aPnt1; - thePoint2 = aPnt2; - } - 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, - Standard_Real& theParameter ) -{ - bool isFound = false; - OCCViewer_ViewPort3d* aViewPort = getViewPort(); - if ( !aViewPort ) - return isFound; - - Handle(V3d_View) aView = aViewPort->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 ); - theParameter = aProj.Parameter( 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; - } - } - return isFound; -} - /** * Returns a section index from the table * \param theRowId a table row diff --git a/src/HYDROCurveCreator/CurveCreator_Widget.h b/src/HYDROCurveCreator/CurveCreator_Widget.h index 0e6e51e8..0afa8ea2 100644 --- a/src/HYDROCurveCreator/CurveCreator_Widget.h +++ b/src/HYDROCurveCreator/CurveCreator_Widget.h @@ -185,14 +185,6 @@ private: void convert( const SectionToPointList& thePoints, QMap >& theConvPoints ); - // OCC algorithm - bool pointOnObject( Handle(AIS_InteractiveObject) theObject, - const int theX, const int theY, - gp_Pnt& thePoint, gp_Pnt& thePoint1, gp_Pnt& thePoint2 ); - bool hasProjectPointOnCurve( const int theX, const int theY, - const Handle(Geom_Curve)& theCurve, - Standard_Real& theParameter ); - // local point view table methods int getSectionId( const int theRowId ) const; int getPointId( const int theRowId ) const; -- 2.39.2