X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROCurveCreator%2FCurveCreator_Utils.cxx;h=1fcc4084030de42aba451f7fe357f77c117470e8;hb=c363fc5c3541669e07cf4d991cc1e94253147ac1;hp=39084ac6a42c06e6fb376bb1601fc7184c73cffd;hpb=c3e4d5bddd44c587d45f0e1d908d58c7ade3d094;p=modules%2Fhydro.git diff --git a/src/HYDROCurveCreator/CurveCreator_Utils.cxx b/src/HYDROCurveCreator/CurveCreator_Utils.cxx index 39084ac6..1fcc4084 100644 --- a/src/HYDROCurveCreator/CurveCreator_Utils.cxx +++ b/src/HYDROCurveCreator/CurveCreator_Utils.cxx @@ -34,17 +34,20 @@ #include #include #include -#include #include #include +#include #include #include #include +#include #include #include #include +#include +#include #include #include @@ -58,10 +61,13 @@ #include #include +#include + #include "CurveCreator_ICurve.hxx" const double LOCAL_SELECTION_TOLERANCE = 0.0001; -const int SCENE_PIXEL_TOLERANCE = 10; +const int SCENE_PIXEL_PROJECTION_TOLERANCE = 10; +const int SCENE_PIXEL_POINT_TOLERANCE = 5; //======================================================================= // function : ConvertClickToPoint() @@ -84,197 +90,198 @@ gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) a return GEOMUtils::ConvertClickToPoint( x, y, aView ); } - -//#define USE_COMPOUND -#include "CurveCreator_Curve.hxx" // TODO - remove void CurveCreator_Utils::constructShape( const CurveCreator_ICurve* theCurve, - const int theISection, TopoDS_Shape& theShape, - std::vector& aSectionRepresentation ) + TopoDS_Shape& theShape ) { - CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection ); - - - int aPointSize = theCurve->getNbPoints( theISection ); - bool aSectIsClosed = theCurve->isClosed( theISection ); - if( aSectType == CurveCreator::Polyline ) + BRep_Builder aBuilder; + TopoDS_Compound aComp; + aBuilder.MakeCompound( aComp ); + for( int iSection = 0 ; iSection < theCurve->getNbSections() ; iSection++ ) { -#ifdef USE_COMPOUND - BRep_Builder aBuilder; - TopoDS_Compound aComp; - aBuilder.MakeCompound(aComp); + int theISection = iSection; + CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection ); + int aPointSize = theCurve->getNbPoints( theISection ); + bool aSectIsClosed = theCurve->isClosed( theISection ); + bool isPolyline = aSectType == CurveCreator::Polyline; int iPoint = 0; gp_Pnt aPrevPoint, aPoint; if ( aPointSize == 1 ) { - CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPrevPoint ); - TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPrevPoint ).Vertex(); + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); + TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); aBuilder.Add( aComp, aVertex ); } else if ( aPointSize > 1 ) { + Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aPointSize); + int aHIndex = 1; + TopoDS_Edge aPointEdge; TopoDS_Vertex aVertex; - CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPrevPoint ); - aVertex = BRepBuilderAPI_MakeVertex( aPrevPoint ).Vertex(); + CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); + aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); aBuilder.Add( aComp, aVertex ); + aHCurvePoints->SetValue(aHIndex++, aPoint); + aPrevPoint = aPoint; iPoint++; for( ; iPoint < aPointSize; iPoint++ ) { CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint ); aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); aBuilder.Add( aComp, aVertex ); - aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); - aBuilder.Add( aComp, aPointEdge ); + aHCurvePoints->SetValue(aHIndex++, aPoint); + if ( isPolyline ) { + aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); + aBuilder.Add( aComp, aPointEdge ); + } aPrevPoint = aPoint; } if( aSectIsClosed && ( aPointSize > 2 ) ) { CurveCreator_UtilsICurve::getPoint( theCurve, theISection, 0, aPoint ); aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex(); aBuilder.Add( aComp, aVertex ); - aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); - aBuilder.Add( aComp, aPointEdge ); - } - theShape = aComp; - } -#endif - } - else if( aSectType == CurveCreator::Spline ) - { -#ifdef USE_COMPOUND -#else - std::vector aPoints; - for( int iPoint = 0; iPoint < aPointSize; iPoint++ ) - { - //Handle_AIS_Point anAISPnt = theCurve->getAISPoint( theISection, iPoint ); - //aSectionRepresentation.push_back( anAISPnt ); - - CurveCreator::Coordinates aCoords = theCurve->getPoint( theISection, iPoint ); - double aX = aCoords[0]; - double aY = aCoords[1]; - double aZ = aCoords[2]; - aPoints.push_back( aX ); - aPoints.push_back( aY ); - } - - if( aPointSize > 1 ) - { - Handle(Geom_BSplineCurve) aBSplineCurve; - // fill array for algorithm by the received coordinates - int aLen = aPoints.size() / 2; - Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt (1, aLen); - std::vector::const_iterator aListIter = aPoints.begin(); - for (int ind = 1; ind <= aLen; ind++) { - gp_Pnt aPnt(gp::Origin()); - aPnt.SetX(*aListIter); - aListIter++; - aPnt.SetY(*aListIter); - aListIter++; - aPnt.SetZ(0); - aHCurvePoints->SetValue(ind, aPnt); + if ( isPolyline ) { + aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge(); + aBuilder.Add( aComp, aPointEdge ); + } } - // compute BSpline - GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution()); - aGBC.Perform(); - if (aGBC.IsDone()) { - aBSplineCurve = aGBC.Curve(); + if( !isPolyline ) { + // compute BSpline + Handle(Geom_BSplineCurve) aBSplineCurve; + GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution()); + aGBC.Perform(); + if ( aGBC.IsDone() ) + aBSplineCurve = aGBC.Curve(); + TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge(); + TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire(); + aBuilder.Add( aComp, aWire ); } - TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge(); - - TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire(); - theShape = aWire; } -#endif } + theShape = aComp; +} -#ifndef USE_COMPOUND - const CurveCreator_Curve* aCurve = dynamic_cast( theCurve ); - if ( !aCurve ) - return; +class ComparePnt +{ +public: + ComparePnt( const gp_Pnt& thePoint ) : myPoint( thePoint) {}; + ~ComparePnt() {} - if( aSectType == CurveCreator::Polyline ) - { - int iPoint = 0; - for( ; iPoint < ( aPointSize - 1 ) ; iPoint++ ){ - Handle_AIS_Point anAISPnt = aCurve->getAISPoint(theISection, iPoint); - aSectionRepresentation.push_back( anAISPnt ); - Handle_AIS_Line aLine = aCurve->getAISLine( theISection, iPoint, iPoint+1 ); - aSectionRepresentation.push_back( aLine ); - } - if( aPointSize != 0 ){ - Handle_AIS_Point anAISPnt = aCurve->getAISPoint(theISection, iPoint); - aSectionRepresentation.push_back( anAISPnt ); - if( aSectIsClosed && ( aPointSize > 1 ) ){ - Handle_AIS_Line aLine = aCurve->getAISLine( theISection, iPoint, 0 ); - aSectionRepresentation.push_back( aLine ); - } - } - } - else if( aSectType == CurveCreator::Spline ) + bool operator < ( const ComparePnt& theOtherPoint ) const { - std::vector aPoints; - for( int iPoint = 0; iPoint < aPointSize; iPoint++ ) - { - Handle_AIS_Point anAISPnt = aCurve->getAISPoint( theISection, iPoint ); - aSectionRepresentation.push_back( anAISPnt ); + bool isLess = myPoint.X() < theOtherPoint.myPoint.X(); + if ( !isLess && myPoint.X() == theOtherPoint.myPoint.X() ) { + isLess = myPoint.Y() < theOtherPoint.myPoint.Y(); + if ( !isLess && myPoint.Y() == theOtherPoint.myPoint.Y() ) + isLess = myPoint.Z() < theOtherPoint.myPoint.Z(); } + return isLess; } -#endif -} +private: + gp_Pnt myPoint; +}; -std::list CurveCreator_Utils::getSelectedPoints( Handle(AIS_InteractiveContext) theContext ) +void CurveCreator_Utils::getSelectedPoints( Handle(AIS_InteractiveContext) theContext, + const CurveCreator_ICurve* theCurve, + CurveCreator_ICurve::SectionToPointList& thePoints ) { - std::list aSelectedPoints; + thePoints.clear(); + std::list aSelectedPoints; gp_Pnt aPnt; + std::map aPntMap; + + CurveCreator_ICurve::SectionToPointList aPoints; for ( theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected() ) { TopoDS_Vertex aVertex; TopoDS_Shape aShape = theContext->SelectedShape(); if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) aVertex = TopoDS::Vertex( theContext->SelectedShape() ); - else { - Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner(); - if ( !anOwner.IsNull() ) { - Handle(AIS_InteractiveObject) anAIS = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() ); - if ( !anAIS.IsNull() ) { - Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast( anAIS); - if ( !aPoint.IsNull() ) - aVertex = TopoDS::Vertex( aPoint->Vertex() ); - } - if ( aVertex.IsNull() ) { - // the following happens if there are no points in the current curve, there is only a shape - /*Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast(anOwner); - if ( aBrepOwner.IsNull() ) - continue; - if ( aBrepOwner->HasShape() ) { - const TopoDS_Shape& aShape = aBrepOwner->Shape(); - if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) - { - aVertex = TopoDS::Vertex( aShape ); - } - }*/ - } - } - } + if ( aVertex.IsNull() ) continue; aPnt = BRep_Tool::Pnt( aVertex ); - aSelectedPoints.push_back( aPnt.X() ); - aSelectedPoints.push_back( aPnt.Y() ); - aSelectedPoints.push_back( aPnt.Z() ); + if ( aPntMap.find( aPnt ) != aPntMap.end() ) + continue; + aPntMap[aPnt] = 0; + + CurveCreator_UtilsICurve::findSectionsToPoints( theCurve, aPnt.X(), aPnt.Y(), aPoints ); + CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aPoints.begin(), + aLast = aPoints.end(); + for ( ; anIt != aLast; anIt++ ) + thePoints.push_back( *anIt ); } +} + +void CurveCreator_Utils::setSelectedPoints( Handle(AIS_InteractiveContext) theContext, + const CurveCreator_ICurve* theCurve, + const CurveCreator_ICurve::SectionToPointList& thePoints ) +{ + if ( !theCurve ) + return; - return aSelectedPoints; + Handle(AIS_InteractiveObject) anAIS = theCurve->getAISObject(); + if ( anAIS.IsNull() ) + return; + Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast( anAIS ); + if ( anAISShape.IsNull() ) + return; + + //ASL: we convert list of point indices to list of points coordinates + int aSize = thePoints.size(); + std::vector aPntsToSelect( aSize ); + + CurveCreator_ICurve::SectionToPointList::const_iterator + aPIt = thePoints.begin(), aPLast = thePoints.end(); + CurveCreator_ICurve::SectionToPoint aSToPoint; + for( int i=0; aPIt != aPLast; aPIt++, i++ ) + { + gp_Pnt aPntToSelect; + CurveCreator_UtilsICurve::getPoint( theCurve, aPIt->first, aPIt->second, aPntToSelect ); + aPntsToSelect[i] = aPntToSelect; + } + + theContext->ClearSelected( Standard_False ); + //ASL: we switch off automatic highlight to improve performance of selection + theContext->SetAutomaticHilight( Standard_False ); + + Handle_SelectMgr_Selection aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) ); + for( aSelection->Init(); aSelection->More(); aSelection->Next() ) + { + Handle_SelectBasics_SensitiveEntity aSenEntity = aSelection->Sensitive(); + Handle_Select3D_SensitivePoint aSenPnt = Handle_Select3D_SensitivePoint::DownCast( aSenEntity ); + + gp_Pnt anOwnerPnt = aSenPnt->Point(); + Handle_SelectMgr_EntityOwner anOwner = Handle_SelectMgr_EntityOwner::DownCast( aSenPnt->OwnerId() ); + + + CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(), + aLast = thePoints.end(); + bool isFound = false; + for( int i=0; iAddOrRemoveSelected( anOwner, Standard_False ); + break; + } + } + } + + //ASL: we switch on again automatic highlight (otherwise selection will not be shown) + // and call HilightPicked to draw selected owners + theContext->SetAutomaticHilight( Standard_True ); + theContext->LocalContext()->HilightPicked( Standard_True ); } + //======================================================================= // function : setLocalPointContext // purpose : Open/close the viewer local context //======================================================================= -//#define USE_COMPOUND -void CurveCreator_Utils::setLocalPointContext( - Handle(AIS_InteractiveContext) theContext, - const bool theOpen ) +void CurveCreator_Utils::setLocalPointContext( const CurveCreator_ICurve* theCurve, + Handle(AIS_InteractiveContext) theContext, + const bool theOpen ) { -#ifdef USE_COMPOUND - return; -#endif if ( !theContext ) return; @@ -284,30 +291,15 @@ void CurveCreator_Utils::setLocalPointContext( 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() ) + // load the curve AIS object to the local context with the point selection + Handle(AIS_InteractiveObject) anAIS = theCurve->getAISObject(); + if ( !anAIS.IsNull() ) { - Handle(AIS_InteractiveObject) anAIS = it.Value(); - if ( !anAIS.IsNull() ) + if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) ) { - 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 ); - } + theContext->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ ); + theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_VERTEX ) ); } - continue; } } else { @@ -316,113 +308,104 @@ void CurveCreator_Utils::setLocalPointContext( } } -bool CurveCreator_Utils::getNeighbourPoints( Handle(AIS_InteractiveContext) theContext, - Handle(V3d_View) theView, - const int theX, const int theY, - gp_Pnt& thePoint, gp_Pnt& thePoint1, - gp_Pnt& thePoint2 ) -{ - bool isFoundPoint = false; - if ( theContext.IsNull() ) - return isFoundPoint; - - for ( theContext->InitSelected(); theContext->MoreSelected() && !isFoundPoint; - theContext->NextSelected() ) { - TopoDS_Shape aTShape = theContext->SelectedShape(); - if ( !aTShape.IsNull() && aTShape.ShapeType() == TopAbs_VERTEX ) - continue; - else { - Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner(); - if ( anOwner.IsNull() ) - continue; - const TopLoc_Location& aLocation = anOwner->Location(); - Handle(AIS_InteractiveObject) anAIS = - Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() ); - isFoundPoint = CurveCreator_Utils::pointOnObject( theView, anAIS, theX, theY, thePoint, - thePoint1, thePoint2 ); - } - } - return isFoundPoint; -} - 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; + bool isFullFound = false; if ( theObject.IsNull() || theView.IsNull() ) - return isFound; - - gp_Pnt aPoint; + return isFullFound; + Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject ); + if ( aShape.IsNull() ) + return isFullFound; + const TopoDS_Compound& aCompound = TopoDS::Compound( aShape->Shape() ); + if ( aCompound.IsNull() ) + return isFullFound; + + gp_Pnt aCurPoint, aCurPoint1, aCurPoint2; + gp_Pnt aFoundPoint, aFoundPnt1, aFoundPnt2; 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 ) ); - } - } - } - } + bool isFound = false; + int aDelta, aMinDelta = 2*SCENE_PIXEL_PROJECTION_TOLERANCE*SCENE_PIXEL_PROJECTION_TOLERANCE; + TopExp_Explorer anExp( aCompound, TopAbs_EDGE ); + for ( ; anExp.More(); anExp.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current()); + if ( anEdge.IsNull() ) + continue; + 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, aBSplineCurve, + aParameter, aDelta ); + if ( isFound ) { + aCurPoint = aBSplineCurve->Value( aParameter ); + Standard_Integer anI1, anI2; + aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 ); + aCurPoint1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) ); + aCurPoint2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) ); } } } + else { // a curve built on a polyline edge + Handle(Geom_Line) aGLine = Handle(Geom_Line)::DownCast( aCurve ); + if ( aGLine.IsNull() ) + continue; + isFound = hasProjectPointOnCurve( theView, theX, theY, aGLine, aParameter, + aDelta ); + if ( isFound ) { + aCurPoint = aGLine->Value( aParameter ); + TopoDS_Vertex V1, V2; + TopExp::Vertices( anEdge, V1, V2, Standard_True ); + if ( V1.IsNull() || V2.IsNull() ) + continue; + aCurPoint1 = BRep_Tool::Pnt(V1); + aCurPoint2 = BRep_Tool::Pnt(V2); + + // check that the projected point is on the bounded curve + gp_Vec aVec1( aCurPoint1, aCurPoint ); + gp_Vec aVec2( aCurPoint2, aCurPoint ); + isFound = fabs( aVec1.Angle( aVec2 ) - M_PI ) < LOCAL_SELECTION_TOLERANCE; + } + } + if ( isFound && aMinDelta >= aDelta ) { + aMinDelta = aDelta; + + isFullFound = true; + aFoundPnt1 = aCurPoint1; + aFoundPnt2 = aCurPoint2; + aFoundPoint = aCurPoint; + } } - if ( isFound ) { - thePoint = aPoint; - thePoint1 = aPnt1; - thePoint2 = aPnt2; + if ( isFullFound ) { + int aX, anY, aX1, anY1, aX2, anY2; + int aDelta; + CurveCreator_Utils::ConvertPointToClick( aFoundPoint, theView, aX, anY ); + CurveCreator_Utils::ConvertPointToClick( aFoundPnt1, theView, aX1, anY1 ); + CurveCreator_Utils::ConvertPointToClick( aFoundPnt2, theView, aX2, anY2 ); + + isFullFound = !isEqualPixels( aX, anY, aX1, anY1, SCENE_PIXEL_POINT_TOLERANCE, aDelta ) && + !isEqualPixels( aX, anY, aX2, anY2, SCENE_PIXEL_POINT_TOLERANCE, aDelta ); + if ( isFullFound ) { + thePoint = aFoundPoint; + thePoint1 = aFoundPnt1; + thePoint2 = aFoundPnt2; + } } - return isFound; + return isFullFound; } bool CurveCreator_Utils::hasProjectPointOnCurve( Handle(V3d_View) theView, const int theX, const int theY, const Handle(Geom_Curve)& theCurve, - Standard_Real& theParameter ) + Standard_Real& theParameter, + int& theDelta ) { bool isFound = false; if ( theView.IsNull() ) @@ -440,10 +423,19 @@ bool CurveCreator_Utils::hasProjectPointOnCurve( Handle(V3d_View) theView, 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; + isFound = isEqualPixels( aX, anY, theX, theY, SCENE_PIXEL_PROJECTION_TOLERANCE, theDelta ); } } return isFound; } + +bool CurveCreator_Utils::isEqualPixels( const int theX, const int theY, const int theOtherX, + const int theOtherY, const double theTolerance, int& theDelta ) +{ + int aXDelta = abs( theX - theOtherX ); + int anYDelta = abs( theY - theOtherY ); + + theDelta = aXDelta*aXDelta + anYDelta*anYDelta; + + return aXDelta < theTolerance && anYDelta < theTolerance; +}