#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()
if ( theObject.IsNull() || theView.IsNull() )
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 aPoint, aFoundPoint;
+ gp_Pnt aCurPoint, aCurPoint1, aCurPoint2;
+ gp_Pnt aFoundPoint, aFoundPnt1, aFoundPnt2;
Standard_Real aParameter;
- gp_Pnt aPnt1, aPnt2, aFoundPnt1, aFoundPnt2;
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())
{
- int aDelta, aMinDelta = 2*SCENE_PIXEL_TOLERANCE*SCENE_PIXEL_TOLERANCE;
- Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject );
- if ( !aShape.IsNull() ) {
- const TopoDS_Compound& aCompound = TopoDS::Compound( aShape->Shape() );
- if ( !aCompound.IsNull() ) {
- 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 ) {
- 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 ) );
- }
- }
- }
- else { // usual curve
- Handle(Geom_Line) aGLine = Handle(Geom_Line)::DownCast( aCurve );
- if ( !aGLine.IsNull() ) {
- isFound = hasProjectPointOnCurve( theView, theX, theY, aGLine, aParameter,
- aDelta );
- if ( isFound ) {
- aPoint = aGLine->Value( aParameter );
-
- TopoDS_Vertex V1, V2;
- TopExp::Vertices(anEdge, V1, V2, Standard_True);
- if (!V1.IsNull() && !V2.IsNull())
- {
- aPnt1 = BRep_Tool::Pnt(V1);
- aPnt2 = BRep_Tool::Pnt(V2);
- }
- gp_Vec aVec1( aPnt1, aPoint );
- gp_Vec aVec2( aPnt2, aPoint );
- double anAngle = aVec1.Angle( aVec2 );
- isFound = fabs( anAngle - M_PI ) < LOCAL_SELECTION_TOLERANCE;
- }
- }
- }
- if ( isFound && aMinDelta >= aDelta ) {
- isFullFound = true;
- aMinDelta = aDelta;
- aFoundPnt1 = aPnt1;
- aFoundPnt2 = aPnt2;
- aFoundPoint = aPoint;
- }
+ 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 ( isFullFound ) {
- thePoint = aPoint;
- thePoint = aFoundPoint;
- thePoint1 = aFoundPnt1;
- thePoint2 = aFoundPnt2;
+ 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 isFullFound;
}
int aX, anY;
CurveCreator_Utils::ConvertPointToClick( aNewPoint, theView, aX, anY );
- int aXDelta = abs( aX - theX );
- int anYDelta = abs( anY - theY );
- theDelta = aXDelta*aXDelta + anYDelta*anYDelta;
- 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;
+}