]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
0021018: EDF 1592 GEOM: Problems with the radius input field in the Fillet 1D dialog box
authorvsr <vsr@opencascade.com>
Wed, 20 Oct 2010 08:12:33 +0000 (08:12 +0000)
committervsr <vsr@opencascade.com>
Wed, 20 Oct 2010 08:12:33 +0000 (08:12 +0000)
src/GEOMImpl/GEOMImpl_Fillet1d.cxx
src/GEOMImpl/GEOMImpl_Fillet1d.hxx

index cafc9bd78422a5fa842d985cd9118e6e08b30be1..24123d0b7106c3b98a1a999441a0a49acc1c92ac 100644 (file)
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  File   : GEOMImpl_Fillet1d.cxx
-//  Module : GEOMImpl
-//
-#include "GEOMImpl_Fillet1d.hxx"
-
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepBuilderAPI_MakeEdge.hxx>
-#include <ElCLib.hxx>
-#include <ElSLib.hxx>
-#include <gp_Circ.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2dAPI_ProjectPointOnCurve.hxx>
-#include <Geom2dAPI_InterCurveCurve.hxx>
-#include <GeomAPI_ProjectPointOnCurve.hxx>
-#include <GeomProjLib.hxx>
-#include <Geom_Circle.hxx>
-#include <Precision.hxx>
-#include <TColStd_ListIteratorOfListOfReal.hxx>
-
-/**
- * class GEOMImpl_Fillet1d
- */
-
-
-//=======================================================================
-//function : Constructor
-//purpose  : 
-//=======================================================================
-GEOMImpl_Fillet1d::GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
-                                     const TopoDS_Edge& theEdge2,
-                                     const gp_Pln& thePlane)
-: myEdgesExchnged( Standard_False )
-{
-  myPlane = new Geom_Plane(thePlane);
-
-  BRepAdaptor_Curve aBAC1(theEdge1);
-  BRepAdaptor_Curve aBAC2(theEdge2);
-  if (aBAC1.GetType() < aBAC2.GetType()) 
-  { // first curve must be more complicated
-    myEdge1 = theEdge2;
-    myEdge2 = theEdge1;
-    myEdgesExchnged = Standard_True;
-  }   
-  else
-  {
-    myEdge1 = theEdge1;
-    myEdge2 = theEdge2;
-  }
-
-  Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(myEdge1, myStart1, myEnd1);
-  Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(myEdge2, myStart2, myEnd2);
-
-  myCurve1 = GeomProjLib::Curve2d(aCurve1, myStart1, myEnd1, myPlane);
-  myCurve2 = GeomProjLib::Curve2d(aCurve2, myStart2, myEnd2, myPlane);
-
-  while (myCurve1->IsPeriodic() && myStart1 >= myEnd1)
-    myEnd1 += myCurve1->Period();
-  while (myCurve2->IsPeriodic() && myStart2 >= myEnd2)
-    myEnd2 += myCurve2->Period();
-  if (aBAC1.GetType() == aBAC2.GetType()) 
-  {
-    if (myEnd2 - myStart2 < myEnd1 - myStart1) 
-    { // first curve must be parametrically shorter
-      TopoDS_Edge anEdge = myEdge1;
-      myEdge1 = myEdge2;
-      myEdge2 = anEdge;
-      Handle(Geom2d_Curve) aCurve = myCurve1;
-      myCurve1 = myCurve2;
-      myCurve2 = aCurve;
-      Standard_Real a = myStart1;
-      myStart1 = myStart2;
-      myStart2 = a;
-      a = myEnd1;
-      myEnd1 = myEnd2;
-      myEnd2 = a;
-      myEdgesExchnged = Standard_True;
-    }
-  }
-}
-
-//=======================================================================
-//function : isRadiusIntersected
-//purpose  : local function
-//=======================================================================
-static Standard_Boolean isRadiusIntersected(const Handle(Geom2d_Curve)& theCurve,
-                                            const gp_Pnt2d theStart,
-                                            const gp_Pnt2d theEnd,
-                                            const Standard_Boolean theStartConnected) 
-{
-  const Standard_Real aTol = Precision::Confusion();
-  const Standard_Real anAngTol = Precision::Angular();
-  Geom2dAPI_InterCurveCurve anInter(theCurve, new Geom2d_Line(theStart,
-    gp_Dir2d(gp_Vec2d(theStart, theEnd))), aTol);
-  Standard_Integer a;
-  gp_Pnt2d aPoint;
-  for(a = anInter.NbPoints(); a > 0; a--) 
-  {
-    aPoint = anInter.Point(a);
-    if ( aPoint.Distance(theStart) < aTol && !theStartConnected )
-      return Standard_True;
-    if (aPoint.Distance(theEnd) < aTol * 200)
-      return Standard_True;
-    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) 
-      return Standard_True;
-  }
-  Handle(Geom2d_Curve) aCurve;
-  for(a = anInter.NbSegments(); a > 0; a--) 
-  {
-    anInter.Segment(a, aCurve);
-    aPoint = aCurve->Value(aCurve->FirstParameter());
-    if (aPoint.Distance(theStart) < aTol) 
-      if (!theStartConnected) 
-        return Standard_True;
-    if (aPoint.Distance(theEnd) < aTol) 
-      return Standard_True;
-    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) 
-      return Standard_True;
-    aPoint = aCurve->Value(aCurve->LastParameter());
-    if (aPoint.Distance(theStart) < aTol) 
-      if (!theStartConnected) 
-        return Standard_True;
-    if (aPoint.Distance(theEnd) < aTol) 
-      return Standard_True;
-    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) 
-      return Standard_True;
-  }
-  return Standard_False;
-}
-
-
-//=======================================================================
-//function : fillPoint
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1d::fillPoint(GEOMImpl_Fillet1dPoint* thePoint) 
-{
-  gp_Pnt2d aPoint;
-  gp_Vec2d aVec;
-  const Standard_Real aTol = Precision::Confusion();
-  myCurve1->D1(thePoint->GetParam(), aPoint, aVec);
-  if (aVec.SquareMagnitude() < aTol) 
-    return;
-  
-  gp_Vec2d aPerp(((myStartSide)?-1:1) * aVec.Y(), ((myStartSide)?1:-1) * aVec.X());
-  aPerp.Normalize();
-  aPerp.Multiply(myRadius);
-  gp_Pnt2d aCenter = aPoint.Translated(aPerp);
-  thePoint->SetCenter(aCenter);
-
-  // on the intersection point
-  Standard_Boolean aValid = Standard_True;
-  Geom2dAPI_ProjectPointOnCurve aProjInt(aPoint, myCurve2);
-  if (aProjInt.NbPoints() && aPoint.Distance(aProjInt.NearestPoint()) < aTol) 
-    aValid = Standard_False;
-  else 
-    aValid = !isRadiusIntersected(myCurve2, aPoint, aCenter, Standard_True);
-  
-  Geom2dAPI_ProjectPointOnCurve aProj(aCenter, myCurve2);
-  Standard_Integer a, aNB = aProj.NbPoints();
-  for(a = aNB; a > 0; a--) 
-  {
-    if (aPoint.Distance(aProj.Point(a)) < aTol) 
-      continue;
-    
-    Standard_Boolean aValid2 = aValid;
-    if (aValid2) 
-      aValid2 = !isRadiusIntersected(myCurve1, aCenter, aProj.Point(a), Standard_False);
-
-    // checking the right parameter
-    Standard_Real aParam = aProj.Parameter(a);
-    while(myCurve2->IsPeriodic() && aParam < myStart2)
-      aParam += myCurve2->Period();
-
-    thePoint->AddValue(aProj.Distance(a) * aProj.Distance(a) - myRadius * myRadius,
-                       (aParam >= myStart2 && aParam <= myEnd2 && aValid2));
-    if (fabs(fabs(aProj.Distance(a)) - myRadius) < aTol)
-      thePoint->SetParam2(aParam);
-  }
-}
-
-//=======================================================================
-//function : fillDiff
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1d::fillDiff(GEOMImpl_Fillet1dPoint* thePoint, Standard_Real theDiffStep, Standard_Boolean theFront) 
-{
-  GEOMImpl_Fillet1dPoint* aDiff =
-    new GEOMImpl_Fillet1dPoint(thePoint->GetParam() + (theFront?(theDiffStep):(-theDiffStep)));
-  fillPoint(aDiff);
-  if (!thePoint->ComputeDifference(aDiff))
-  {
-    aDiff->SetParam(thePoint->GetParam() + (theFront?(-theDiffStep):(theDiffStep)));
-    fillPoint(aDiff);
-    thePoint->ComputeDifference(aDiff);
-  }
-  delete aDiff;
-}
-
-//=======================================================================
-//function : Perform
-//purpose  : 
-//=======================================================================
-Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius) 
-{
-  myResultParams.Clear();
-  myResultOrientation.Clear();
-
-  Standard_Real aNBSteps = 100;
-  Geom2dAdaptor_Curve aGAC(myCurve1);
-  switch (aGAC.GetType()) 
-  {
-    case GeomAbs_Line:
-      aNBSteps = 2;
-      break;
-    case GeomAbs_Circle:
-      aNBSteps = 4;
-      break;
-    case GeomAbs_Ellipse:
-      aNBSteps = 5;
-      break;
-    case GeomAbs_BezierCurve:
-    case GeomAbs_BSplineCurve:
-      aNBSteps = 2 + aGAC.Degree() * aGAC.NbPoles();
-      break;
-    default: // unknown: maximum
-      aNBSteps = 100;
-  }
-
-  myRadius = theRadius;
-  Standard_Real aParam, aStep, aDStep;
-  aStep = (myEnd1 - myStart1) / aNBSteps;
-  aDStep = aStep/1000.;
-
-  Standard_Integer aCycle;
-  for(aCycle = 2, myStartSide = Standard_False; aCycle; myStartSide = !myStartSide, aCycle--) 
-  {
-    GEOMImpl_Fillet1dPoint *aLeft = NULL, *aRight = NULL;
-    
-    for(aParam = myStart1 + aStep; aParam < myEnd1 || fabs(myEnd1 - aParam) < Precision::Confusion(); aParam += aStep) 
-    {
-      if (!aLeft) 
-      {
-        aLeft = new GEOMImpl_Fillet1dPoint(aParam - aStep);
-        fillPoint(aLeft);
-        fillDiff(aLeft, aDStep, Standard_True);
-      }
-      
-      aRight = new GEOMImpl_Fillet1dPoint(aParam);
-      fillPoint(aRight);
-      fillDiff(aRight, aDStep, Standard_False);
-      
-      aLeft->FilterPoints(aRight);
-      performNewton(aLeft, aRight);
-      
-      delete aLeft;
-      aLeft = aRight;
-    }
-    delete aLeft;
-  }
-
-  if (myResultParams.Extent()) 
-    return Standard_True;
-  
-  return Standard_False;
-}
-
-//=======================================================================
-//function : processPoint
-//purpose  : 
-//=======================================================================
-Standard_Boolean GEOMImpl_Fillet1d::processPoint(GEOMImpl_Fillet1dPoint* theLeft,
-                                                 GEOMImpl_Fillet1dPoint* theRight,
-                                                 Standard_Real           theParameter) 
-{
-  if (theParameter >= theLeft->GetParam() && theParameter < theRight->GetParam()) 
-  {
-    Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
-    if (theParameter - theLeft->GetParam() < aDX / 100.) 
-    {
-      theParameter = theLeft->GetParam() + aDX / 100.;
-    }
-    if (theRight->GetParam() - theParameter < aDX / 100.)
-    {
-      theParameter = theRight->GetParam() - aDX / 100.;
-    }
-
-    GEOMImpl_Fillet1dPoint* aPoint1 = theLeft->Copy();
-    GEOMImpl_Fillet1dPoint* aPoint2 = new GEOMImpl_Fillet1dPoint(theParameter);
-    fillPoint(aPoint2);
-    fillDiff(aPoint2, aDX / 10., Standard_True);
-    
-    aPoint1->FilterPoints(aPoint2);
-    performNewton(aPoint1, aPoint2);
-    aPoint2->FilterPoints(theRight);
-    performNewton(aPoint2, theRight);
-
-    delete aPoint1;
-    delete aPoint2;
-    return Standard_True;
-  }
-
-  return Standard_False;
-}
-
-//=======================================================================
-//function : performNewton
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1d::performNewton(GEOMImpl_Fillet1dPoint* theLeft,
-                                      GEOMImpl_Fillet1dPoint* theRight)
-{
-  Standard_Integer a;
-  // check the left: if this is solution store it and remove it from the list of researching points of theLeft
-  a = theLeft->HasSolution(myRadius);
-  if (a) 
-  {
-    if (theLeft->IsValid(a)) 
-    {
-      myResultParams.Append(theLeft->GetParam());
-      myResultOrientation.Append(myStartSide);
-    }
-    return;
-  }
-
-  Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
-  if ( aDX < Precision::Confusion() / 1000000.) 
-  {
-    a = theRight->HasSolution(myRadius);
-    if (a)
-      if (theRight->IsValid(a)) 
-      {
-        myResultParams.Append(theRight->GetParam());
-        myResultOrientation.Append(myStartSide);
-      }
-    return;
-  }
-
-  for(a = 1; a <= theLeft->GetNBValues(); a++) 
-  {
-    Standard_Integer aNear = theLeft->GetNear(a);
-    
-    Standard_Real aA = (theRight->GetDiff(aNear) - theLeft->GetDiff(a)) / aDX;
-    Standard_Real aB = theLeft->GetDiff(a) - aA * theLeft->GetParam();
-    Standard_Real aC = theLeft->GetValue(a) - theLeft->GetDiff(a) * theLeft->GetParam() + 
-                       aA * theLeft->GetParam() * theLeft->GetParam() / 2.0;
-    Standard_Real aDet = aB * aB - 2.0 * aA * aC;
-
-    if ( fabs(aDet) < gp::Resolution() )
-      continue;
-    
-    if (fabs(aA) < Precision::Confusion()) 
-    { // linear case
-      if (fabs(aB) > 10e-20) 
-      {
-        Standard_Real aX0 = - aC / aB; // use extremum
-        if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
-          processPoint(theLeft, theRight, aX0);
-      }
-      else 
-      {
-        processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
-      }
-    } 
-    else
-    {
-      if (fabs(aB) > fabs(aDet * 1000000.)) 
-      {  // possible floating point operations accurancy errors
-        processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
-      } 
-      else
-      {
-        if (aDet > 0) 
-        { // two solutions
-          aDet = sqrt(aDet);
-          Standard_Boolean aRes = processPoint(theLeft, theRight, (- aB + aDet) / aA);
-          if (!aRes) 
-            aRes = processPoint(theLeft, theRight, (- aB - aDet) / aA);
-          if (!aRes) 
-            processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
-        } 
-        else 
-        {
-          Standard_Real aX0 = - aB / aA; // use extremum
-          if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
-            processPoint(theLeft, theRight, aX0);
-          else 
-            processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
-        }
-      }
-    }
-  }
-}
-
-//=======================================================================
-//function : Result
-//purpose  : 
-//=======================================================================
-TopoDS_Edge GEOMImpl_Fillet1d::Result(const gp_Pnt& thePoint,
-                                      TopoDS_Edge& theEdge1,
-                                      TopoDS_Edge& theEdge2) 
-{
-  TopoDS_Edge aResult;
-  gp_Pnt2d aTargetPoint2d;
-  Standard_Real aX, aY;
-  ElSLib::PlaneParameters(myPlane->Pln().Position(), thePoint, aX, aY);
-  aTargetPoint2d.SetCoord(aX, aY);
-   
-  // choose the nearest circle
-  Standard_Real aDistance, aP;
-  GEOMImpl_Fillet1dPoint *aNearest;
-  Standard_Integer a;
-  TColStd_ListIteratorOfListOfReal anIter(myResultParams);
-  for(aNearest = NULL, a = 1; anIter.More(); anIter.Next(), a++) 
-  {
-    myStartSide = (myResultOrientation.Value(a)) ? Standard_True : Standard_False;
-    GEOMImpl_Fillet1dPoint *aPoint = new GEOMImpl_Fillet1dPoint(anIter.Value());
-    fillPoint(aPoint);
-    if (!aPoint->HasSolution(myRadius)) 
-      continue;
-    aP = fabs(aPoint->GetCenter().Distance(aTargetPoint2d) - myRadius);
-    if (!aNearest || aP < aDistance) 
-    {
-      aNearest = aPoint;
-      aDistance = aP;
-    } 
-    else 
-    {
-      delete aPoint;
-    }
-   }
-   
-  if (!aNearest) 
-     return aResult;
-   
-  // create circle edge
-  gp_Pnt aCenter = ElSLib::PlaneValue(aNearest->GetCenter().X(),
-                                      aNearest->GetCenter().Y(),
-                                      myPlane->Pln().Position());
-  Handle(Geom_Circle) aCircle =
-    new Geom_Circle(gp_Ax2(aCenter, myPlane->Pln().Axis().Direction()), myRadius);
-  gp_Pnt2d aPoint2d1, aPoint2d2;
-  myCurve1->D0(aNearest->GetParam(), aPoint2d1);
-  myCurve2->D0(aNearest->GetParam2(), aPoint2d2);
-  gp_Pnt aPoint1 = ElSLib::PlaneValue(aPoint2d1.X(), aPoint2d1.Y(), myPlane->Pln().Position());
-  gp_Pnt aPoint2 = ElSLib::PlaneValue(aPoint2d2.X(), aPoint2d2.Y(), myPlane->Pln().Position());
-
-  GeomAPI_ProjectPointOnCurve aProj(thePoint, aCircle);
-  Standard_Real aTarGetParam = aProj.LowerDistanceParameter();
-  gp_Pnt aPointOnCircle = aProj.NearestPoint();
-
-  // Check extrema point manually, because there is a bug in Open CASCADE
-  //  in calculation of nearest point to a circle near the parameter 0.0
-  gp_Pnt p0 = ElCLib::Value(0.0, aCircle->Circ());
-  if (p0.Distance(thePoint) < aPointOnCircle.Distance(thePoint))
-  {
-     aTarGetParam = 0.0;
-     aPointOnCircle = p0;
-  }
-
-  aProj.Perform(aPoint1);
-  Standard_Real aParam1 = aProj.LowerDistanceParameter();
-    aProj.Perform(aPoint2);
-  Standard_Real aParam2 = aProj.LowerDistanceParameter();
-  Standard_Boolean aIsOut = ((aParam1 < aTarGetParam && aParam2 < aTarGetParam) || 
-                             (aParam1 > aTarGetParam && aParam2 > aTarGetParam));
-  if (aParam1 > aParam2) 
-    aIsOut = !aIsOut;
-  BRepBuilderAPI_MakeEdge aBuilder(aCircle->Circ(),
-                                   aIsOut ? aParam2 : aParam1,
-                                   aIsOut? aParam1 : aParam2);
-  aResult = aBuilder.Edge();
-
-  // divide edges
-  Standard_Real aStart, anEnd;
-  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge1, aStart, anEnd);
-  gp_Vec aDir;
-  aCurve->D1(aNearest->GetParam(), aPoint1, aDir);
-
-  gp_Vec aCircleDir;
-  aCircle->D1(aParam1, aPoint1, aCircleDir);
-  if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ aIsOut)
-    aStart = aNearest->GetParam();
-  else
-    anEnd = aNearest->GetParam();
-
-  if (fabs(aStart - anEnd) > Precision::Confusion())
-  {
-      //Divide edge
-      BRepBuilderAPI_MakeEdge aDivider1(aCurve, aStart, anEnd);
-      if (myEdgesExchnged) 
-        theEdge2 = aDivider1.Edge();
-      else 
-        theEdge1 = aDivider1.Edge();
-  }
-
-  aCurve = BRep_Tool::Curve(myEdge2, aStart, anEnd);
-  aCurve->D1(aNearest->GetParam2(), aPoint2, aDir);
-   
-  aCircle->D1(aParam2, aPoint2, aCircleDir);
-  if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ (!aIsOut))
-    aStart = aNearest->GetParam2();
-  else
-    anEnd = aNearest->GetParam2();
-
-  if (fabs(aStart - anEnd) > Precision::Confusion())
-  {
-      BRepBuilderAPI_MakeEdge aDivider2(aCurve, aStart, anEnd);
-      if (myEdgesExchnged) 
-        theEdge1 = aDivider2.Edge();
-      else 
-        theEdge2 = aDivider2.Edge();
-  }
-
-  delete aNearest;
-  return aResult;
-}
-
-//=======================================================================
-//function : AddValue
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1dPoint::AddValue(Standard_Real theValue, Standard_Boolean theValid) 
-{
-  Standard_Integer a;
-  for(a = 1; a <= myV.Length(); a++) 
-  {
-    if (theValue < myV.Value(a)) 
-    {
-      myV.InsertBefore(a, theValue);
-      myValid.InsertBefore(a, (Standard_Integer)theValid);
-      return;
-    }
-  }
-  myV.Append(theValue);
-  myValid.Append((Standard_Integer)theValid);
-}
-
-//=======================================================================
-//function : ComputeDifference
-//purpose  : 
-//=======================================================================
-Standard_Boolean GEOMImpl_Fillet1dPoint::ComputeDifference(GEOMImpl_Fillet1dPoint* thePoint) 
-{
-  Standard_Integer a;
-  Standard_Boolean aDiffsSet = (myD.Length() != 0);
-  Standard_Real aDX = thePoint->GetParam() - myParam, aDY;
-  if (thePoint->myV.Length() == myV.Length()) 
-  { // absolutely the same points
-    for(a = 1; a <= myV.Length(); a++) 
-    {
-      aDY = thePoint->myV.Value(a) - myV.Value(a);
-      if ( aDiffsSet ) 
-        myD.SetValue(a, fabs(aDX) > gp::Resolution() ? (aDY/aDX) : 0);
-      else
-        myD.Append( fabs(aDX) > gp::Resolution() ? (aDY/aDX) : 0);
-    }
-    return Standard_True;
-  }
-  // between the diffeerent points searching for nearest analogs
-  Standard_Integer b;
-  for(a = 1; a <= myV.Length(); a++) 
-  {
-    for(b = 1; b <= thePoint->myV.Length(); b++) 
-    {
-      if (b == 1 || fabs(thePoint->myV.Value(b) - myV.Value(a)) < fabs(aDY))
-        aDY = thePoint->myV.Value(b) - myV.Value(a);
-    }
-    if (aDiffsSet) 
-    {
-      if ( fabs(aDX) > gp::Resolution() && fabs(aDY / aDX) < fabs(myD.Value(a)))
-        myD.SetValue(a, aDY / aDX);
-      else
-        myD.SetValue(a, 0);
-    } 
-    else 
-    {
-      myD.Append( fabs(aDX) > gp::Resolution() ? aDY/aDX : 0);
-    }
-  }
-  
-  return Standard_False;
-}
-
-//=======================================================================
-//function : FilterPoints
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1dPoint::FilterPoints(GEOMImpl_Fillet1dPoint* thePoint) 
-{
-  Standard_Integer a, b;
-  TColStd_SequenceOfReal aDiffs;
-  Standard_Real aY, aY2, aDX = thePoint->GetParam() - myParam;
-  for(a = 1; a <= myV.Length(); a++) 
-  {
-    // searching for near point from thePoint
-    Standard_Integer aNear = 0;
-    Standard_Real aDiff = aDX * 10000.;
-    aY = myV.Value(a) + myD.Value(a) * aDX;
-    for(b = 1; b <= thePoint->myV.Length(); b++) 
-    {
-      // calculate hypothesis value of the Y2 with the constant first and second derivative
-      aY2 = aY + aDX * (thePoint->myD.Value(b) - myD.Value(a)) / 2.0;
-      if (aNear == 0 || fabs(aY2 - thePoint->myV.Value(b)) < fabs(aDiff)) 
-      {
-        aNear = b;
-        aDiff = aY2 - thePoint->myV.Value(b);
-      }
-    }//for b...
-
-    if (aNear) 
-    {
-      if (myV.Value(a) * thePoint->myV.Value(aNear) > 0) 
-      {// the same sign at the same sides of the interval
-        if (myV.Value(a) * myD.Value(a) > 0) 
-        {
-          if (fabs(myD.Value(a)) > Precision::Confusion()) 
-            aNear = 0;
-        } 
-        else 
-        {
-          if (fabs(myV.Value(a)) > fabs(thePoint->myV.Value(aNear)))
-            if (thePoint->myV.Value(aNear) * thePoint->myD.Value(aNear) < 0 &&
-                fabs(thePoint->myD.Value(aNear)) > Precision::Confusion())
-            {
-              aNear = 0;
-            }
-        }
-      }
-    }
-
-    if (aNear) 
-    {
-      if (myV.Value(a) * thePoint->myV.Value(aNear) > 0) 
-      {
-        if ((myV.Value(a) + myD.Value(a) * aDX) * myV.Value(a) > Precision::Confusion() &&
-        (thePoint->myV.Value(aNear) + thePoint->myD.Value(aNear) * aDX) * thePoint->myV.Value(aNear) > Precision::Confusion())
-        {
-          aNear = 0;
-        }
-      }
-    }
-    
-    if (aNear)
-    {
-      if (  fabs(aDX) < gp::Resolution() || fabs(aDiff / aDX) > 1.e+7) 
-      {
-        aNear = 0;
-      }
-    }
-
-    if (aNear == 0) 
-    {  // there is no near: remove it from the list
-      myV.Remove(a);
-      myD.Remove(a);
-      myValid.Remove(a);
-      a--;
-    } 
-    else 
-    {
-      Standard_Boolean aFound = Standard_False;
-      for(b = 1; b <= myNear.Length(); b++) 
-      {
-        if (myNear.Value(b) == aNear) 
-        {
-          if (fabs(aDiffs.Value(b)) < fabs(aDiff)) 
-          { // return this 'near'
-            aFound = Standard_True;
-            myV.Remove(a);
-            myD.Remove(a);
-            myValid.Remove(a);
-            a--;
-            break;
-          } 
-          else 
-          { // remove the old 'near'
-            myV.Remove(b);
-            myD.Remove(b);
-            myValid.Remove(b);
-            myNear.Remove(b);
-            aDiffs.Remove(b);
-            a--;
-            break;
-          }
-        }
-      }//for b...
-      if (!aFound) 
-      {
-        myNear.Append(aNear);
-        aDiffs.Append(aDiff);
-      }
-    }
-  }//for a...
-}
-
-//=======================================================================
-//function : Copy
-//purpose  : 
-//=======================================================================
-GEOMImpl_Fillet1dPoint* GEOMImpl_Fillet1dPoint::Copy() 
-{
-  GEOMImpl_Fillet1dPoint* aCopy = new GEOMImpl_Fillet1dPoint(myParam);
-  Standard_Integer a;
-  for(a = 1; a <= myV.Length(); a++) 
-  {
-    aCopy->myV.Append(myV.Value(a));
-    aCopy->myD.Append(myD.Value(a));
-    aCopy->myValid.Append(myValid.Value(a));
-  }
-  return aCopy;
-}
-
-//=======================================================================
-//function : HasSolution
-//purpose  : 
-//=======================================================================
-Standard_Integer GEOMImpl_Fillet1dPoint::HasSolution(const Standard_Real theRadius) 
-{
-  Standard_Integer a;
-  for(a = 1; a <= myV.Length(); a++) 
-  {
-    if (fabs(sqrt(fabs(fabs(myV.Value(a)) + theRadius * theRadius)) - theRadius) < Precision::Confusion() / 10.) 
-      return a;
-  }
-  return 0;
-}
-
-//=======================================================================
-//function : RemoveSolution
-//purpose  : 
-//=======================================================================
-void GEOMImpl_Fillet1dPoint::RemoveSolution(Standard_Integer theIndex)
-{
-  myV.Remove(theIndex);
-  myD.Remove(theIndex);
-  myValid.Remove(theIndex);
-  myNear.Remove(theIndex);
-}
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE\r
+//\r
+//  This library is free software; you can redistribute it and/or\r
+//  modify it under the terms of the GNU Lesser General Public\r
+//  License as published by the Free Software Foundation; either\r
+//  version 2.1 of the License.\r
+//\r
+//  This library is distributed in the hope that it will be useful,\r
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+//  Lesser General Public License for more details.\r
+//\r
+//  You should have received a copy of the GNU Lesser General Public\r
+//  License along with this library; if not, write to the Free Software\r
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
+//\r
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+//\r
+\r
+//  File   : GEOMImpl_Fillet1d.cxx\r
+//  Module : GEOMImpl\r
+//\r
+#include "GEOMImpl_Fillet1d.hxx"\r
+\r
+#include <BRep_Tool.hxx>\r
+#include <BRepAdaptor_Curve.hxx>\r
+#include <BRepBuilderAPI_MakeEdge.hxx>\r
+#include <ElCLib.hxx>\r
+#include <ElSLib.hxx>\r
+#include <gp_Circ.hxx>\r
+#include <Geom2d_Line.hxx>\r
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>\r
+#include <Geom2dAPI_InterCurveCurve.hxx>\r
+#include <GeomAPI_ProjectPointOnCurve.hxx>\r
+#include <GeomProjLib.hxx>\r
+#include <Geom_Circle.hxx>\r
+#include <Precision.hxx>\r
+#include <TColStd_ListIteratorOfListOfReal.hxx>\r
+\r
+/**\r
+ * class GEOMImpl_Fillet1d\r
+ */\r
+\r
+\r
+//=======================================================================\r
+//function : Constructor\r
+//purpose  : \r
+//=======================================================================\r
+GEOMImpl_Fillet1d::GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,\r
+                                     const TopoDS_Edge& theEdge2,\r
+                                     const gp_Pln& thePlane)\r
+: myEdgesExchnged( Standard_False )\r
+{\r
+  myPlane = new Geom_Plane(thePlane);\r
+\r
+  BRepAdaptor_Curve aBAC1(theEdge1);\r
+  BRepAdaptor_Curve aBAC2(theEdge2);\r
+  if (aBAC1.GetType() < aBAC2.GetType()) \r
+  { // first curve must be more complicated\r
+    myEdge1 = theEdge2;\r
+    myEdge2 = theEdge1;\r
+    myEdgesExchnged = Standard_True;\r
+  }   \r
+  else\r
+  {\r
+    myEdge1 = theEdge1;\r
+    myEdge2 = theEdge2;\r
+  }\r
+\r
+  Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(myEdge1, myStart1, myEnd1);\r
+  Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(myEdge2, myStart2, myEnd2);\r
+\r
+  myCurve1 = GeomProjLib::Curve2d(aCurve1, myStart1, myEnd1, myPlane);\r
+  myCurve2 = GeomProjLib::Curve2d(aCurve2, myStart2, myEnd2, myPlane);\r
+\r
+  while (myCurve1->IsPeriodic() && myStart1 >= myEnd1)\r
+    myEnd1 += myCurve1->Period();\r
+  while (myCurve2->IsPeriodic() && myStart2 >= myEnd2)\r
+    myEnd2 += myCurve2->Period();\r
\r
+  if (aBAC1.GetType() == aBAC2.GetType()) \r
+  {\r
+    if (myEnd2 - myStart2 < myEnd1 - myStart1) \r
+    { // first curve must be parametrically shorter\r
+      TopoDS_Edge anEdge = myEdge1;\r
+      myEdge1 = myEdge2;\r
+      myEdge2 = anEdge;\r
+      Handle(Geom2d_Curve) aCurve = myCurve1;\r
+      myCurve1 = myCurve2;\r
+      myCurve2 = aCurve;\r
+      Standard_Real a = myStart1;\r
+      myStart1 = myStart2;\r
+      myStart2 = a;\r
+      a = myEnd1;\r
+      myEnd1 = myEnd2;\r
+      myEnd2 = a;\r
+      myEdgesExchnged = Standard_True;\r
+    }\r
+  }\r
+}\r
+\r
+//=======================================================================\r
+//function : isRadiusIntersected\r
+//purpose  : local function\r
+//=======================================================================\r
+static Standard_Boolean isRadiusIntersected(const Handle(Geom2d_Curve)& theCurve,\r
+                                            const gp_Pnt2d theStart,\r
+                                            const gp_Pnt2d theEnd,\r
+                                            const Standard_Boolean theStartConnected) \r
+{\r
+  const Standard_Real aTol = Precision::Confusion();\r
+  const Standard_Real anAngTol = Precision::Angular();\r
+  Geom2dAPI_InterCurveCurve anInter(theCurve, new Geom2d_Line(theStart,\r
+    gp_Dir2d(gp_Vec2d(theStart, theEnd))), aTol);\r
+  Standard_Integer a;\r
+  gp_Pnt2d aPoint;\r
+  for(a = anInter.NbPoints(); a > 0; a--) \r
+  {\r
+    aPoint = anInter.Point(a);\r
+    if ( aPoint.Distance(theStart) < aTol && !theStartConnected )\r
+      return Standard_True;\r
+    if (aPoint.Distance(theEnd) < aTol * 200)\r
+      return Standard_True;\r
+    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) \r
+      return Standard_True;\r
+  }\r
+  Handle(Geom2d_Curve) aCurve;\r
+  for(a = anInter.NbSegments(); a > 0; a--) \r
+  {\r
+    anInter.Segment(a, aCurve);\r
+    aPoint = aCurve->Value(aCurve->FirstParameter());\r
+    if (aPoint.Distance(theStart) < aTol) \r
+      if (!theStartConnected) \r
+        return Standard_True;\r
+    if (aPoint.Distance(theEnd) < aTol) \r
+      return Standard_True;\r
+    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) \r
+      return Standard_True;\r
+    aPoint = aCurve->Value(aCurve->LastParameter());\r
+    if (aPoint.Distance(theStart) < aTol) \r
+      if (!theStartConnected) \r
+        return Standard_True;\r
+    if (aPoint.Distance(theEnd) < aTol) \r
+      return Standard_True;\r
+    if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol)) \r
+      return Standard_True;\r
+  }\r
+  return Standard_False;\r
+}\r
+\r
+\r
+//=======================================================================\r
+//function : fillPoint\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1d::fillPoint(GEOMImpl_Fillet1dPoint* thePoint) \r
+{\r
+  gp_Pnt2d aPoint;\r
+  gp_Vec2d aVec;\r
+  const Standard_Real aTol = Precision::Confusion();\r
+  myCurve1->D1(thePoint->GetParam(), aPoint, aVec);\r
+  if (aVec.SquareMagnitude() < aTol) \r
+    return;\r
+  \r
+  gp_Vec2d aPerp(((myStartSide)?-1:1) * aVec.Y(), ((myStartSide)?1:-1) * aVec.X());\r
+  aPerp.Normalize();\r
+  aPerp.Multiply(myRadius);\r
+  gp_Pnt2d aCenter = aPoint.Translated(aPerp);\r
+  thePoint->SetCenter(aCenter);\r
+\r
+  // on the intersection point\r
+  Standard_Boolean aValid = Standard_True;\r
+  Geom2dAPI_ProjectPointOnCurve aProjInt(aPoint, myCurve2);\r
+  if (aProjInt.NbPoints() && aPoint.Distance(aProjInt.NearestPoint()) < aTol) \r
+    aValid = Standard_False;\r
+  else \r
+    aValid = !isRadiusIntersected(myCurve2, aPoint, aCenter, Standard_True);\r
+  \r
+  Geom2dAPI_ProjectPointOnCurve aProj(aCenter, myCurve2);\r
+  Standard_Integer a, aNB = aProj.NbPoints();\r
+  for(a = aNB; a > 0; a--) \r
+  {\r
+    if (aPoint.Distance(aProj.Point(a)) < aTol) \r
+      continue;\r
+    \r
+    Standard_Boolean aValid2 = aValid;\r
+    if (aValid2) \r
+      aValid2 = !isRadiusIntersected(myCurve1, aCenter, aProj.Point(a), Standard_False);\r
+\r
+    // checking the right parameter\r
+    Standard_Real aParam = aProj.Parameter(a);\r
+    while(myCurve2->IsPeriodic() && aParam < myStart2)\r
+      aParam += myCurve2->Period();\r
+\r
+    thePoint->AddValue(aProj.Distance(a) * aProj.Distance(a) - myRadius * myRadius,\r
+                       (aParam >= myStart2 && aParam <= myEnd2 && aValid2));\r
+    if (fabs(fabs(aProj.Distance(a)) - myRadius) < aTol)\r
+      thePoint->SetParam2(aParam);\r
+  }\r
+}\r
+\r
+//=======================================================================\r
+//function : fillDiff\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1d::fillDiff(GEOMImpl_Fillet1dPoint* thePoint, Standard_Real theDiffStep, Standard_Boolean theFront) \r
+{\r
+  GEOMImpl_Fillet1dPoint* aDiff =\r
+    new GEOMImpl_Fillet1dPoint(thePoint->GetParam() + (theFront?(theDiffStep):(-theDiffStep)));\r
+  fillPoint(aDiff);\r
+  if (!thePoint->ComputeDifference(aDiff))\r
+  {\r
+    aDiff->SetParam(thePoint->GetParam() + (theFront?(-theDiffStep):(theDiffStep)));\r
+    fillPoint(aDiff);\r
+    thePoint->ComputeDifference(aDiff);\r
+  }\r
+  delete aDiff;\r
+}\r
+\r
+//=======================================================================\r
+//function : Perform\r
+//purpose  : \r
+//=======================================================================\r
+Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius) \r
+{\r
+  myDegreeOfRecursion = 0;\r
+  myResultParams.Clear();\r
+  myResultOrientation.Clear();\r
+\r
+  Standard_Real aNBSteps = 100;\r
+  Geom2dAdaptor_Curve aGAC(myCurve1);\r
+  switch (aGAC.GetType()) \r
+  {\r
+    case GeomAbs_Line:\r
+      aNBSteps = 2;\r
+      break;\r
+    case GeomAbs_Circle:\r
+      aNBSteps = 4;\r
+      break;\r
+    case GeomAbs_Ellipse:\r
+      aNBSteps = 5;\r
+      break;\r
+    case GeomAbs_BezierCurve:\r
+    case GeomAbs_BSplineCurve:\r
+      aNBSteps = 2 + aGAC.Degree() * aGAC.NbPoles();\r
+      break;\r
+    default: // unknown: maximum\r
+      aNBSteps = 100;\r
+  }\r
+\r
+  myRadius = theRadius;\r
+  Standard_Real aParam, aStep, aDStep;\r
+  aStep = (myEnd1 - myStart1) / aNBSteps;\r
+  aDStep = aStep/1000.;\r
+\r
+  Standard_Integer aCycle;\r
+  for(aCycle = 2, myStartSide = Standard_False; aCycle; myStartSide = !myStartSide, aCycle--) \r
+  {\r
+    GEOMImpl_Fillet1dPoint *aLeft = NULL, *aRight = NULL;\r
+    \r
+    for(aParam = myStart1 + aStep; aParam < myEnd1 || fabs(myEnd1 - aParam) < Precision::Confusion(); aParam += aStep) \r
+    {\r
+      if (!aLeft) \r
+      {\r
+        aLeft = new GEOMImpl_Fillet1dPoint(aParam - aStep);\r
+        fillPoint(aLeft);\r
+        fillDiff(aLeft, aDStep, Standard_True);\r
+      }\r
+      \r
+      aRight = new GEOMImpl_Fillet1dPoint(aParam);\r
+      fillPoint(aRight);\r
+      fillDiff(aRight, aDStep, Standard_False);\r
+      \r
+      aLeft->FilterPoints(aRight);\r
+      performNewton(aLeft, aRight);\r
+      \r
+      delete aLeft;\r
+      aLeft = aRight;\r
+    }\r
+    delete aLeft;\r
+  }\r
+\r
+  if (myResultParams.Extent()) \r
+    return Standard_True;\r
+  \r
+  return Standard_False;\r
+}\r
+\r
+//=======================================================================\r
+//function : processPoint\r
+//purpose  : \r
+//=======================================================================\r
+Standard_Boolean GEOMImpl_Fillet1d::processPoint(GEOMImpl_Fillet1dPoint* theLeft,\r
+                                                 GEOMImpl_Fillet1dPoint* theRight,\r
+                                                 Standard_Real           theParameter) \r
+{\r
+  if (theParameter >= theLeft->GetParam() && theParameter < theRight->GetParam()) \r
+  {\r
+    Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();\r
+    if (theParameter - theLeft->GetParam() < aDX / 100.) \r
+    {\r
+      theParameter = theLeft->GetParam() + aDX / 100.;\r
+    }\r
+    if (theRight->GetParam() - theParameter < aDX / 100.)\r
+    {\r
+      theParameter = theRight->GetParam() - aDX / 100.;\r
+    }\r
+\r
+    // Protection on infinite loop.\r
+    myDegreeOfRecursion++;\r
+    Standard_Real diffx = 0.001 * aDX;\r
+    if (myDegreeOfRecursion > 1000)\r
+    {\r
+        diffx *= 10.0;\r
+        if (myDegreeOfRecursion > 10000)\r
+        {\r
+            diffx *= 10.0;\r
+            if (myDegreeOfRecursion > 100000)\r
+            {\r
+                return Standard_True;\r
+            }\r
+        }\r
+    }\r
+\r
+    GEOMImpl_Fillet1dPoint* aPoint1 = theLeft->Copy();\r
+    GEOMImpl_Fillet1dPoint* aPoint2 = new GEOMImpl_Fillet1dPoint(theParameter);\r
+    fillPoint(aPoint2);\r
+    fillDiff(aPoint2, diffx, Standard_True);\r
+    \r
+    aPoint1->FilterPoints(aPoint2);\r
+    performNewton(aPoint1, aPoint2);\r
+    aPoint2->FilterPoints(theRight);\r
+    performNewton(aPoint2, theRight);\r
+\r
+    delete aPoint1;\r
+    delete aPoint2;\r
+    return Standard_True;\r
+  }\r
+\r
+  return Standard_False;\r
+}\r
+\r
+//=======================================================================\r
+//function : performNewton\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1d::performNewton(GEOMImpl_Fillet1dPoint* theLeft,\r
+                                      GEOMImpl_Fillet1dPoint* theRight)\r
+{\r
+  Standard_Integer a;\r
+  // check the left: if this is solution store it and remove it from the list of researching points of theLeft\r
+  a = theLeft->HasSolution(myRadius);\r
+  if (a) \r
+  {\r
+    if (theLeft->IsValid(a)) \r
+    {\r
+      myResultParams.Append(theLeft->GetParam());\r
+      myResultOrientation.Append(myStartSide);\r
+    }\r
+    return;\r
+  }\r
+\r
+  Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();\r
+  if ( aDX < Precision::Confusion() / 1000000.) \r
+  {\r
+    a = theRight->HasSolution(myRadius);\r
+    if (a)\r
+      if (theRight->IsValid(a)) \r
+      {\r
+        myResultParams.Append(theRight->GetParam());\r
+        myResultOrientation.Append(myStartSide);\r
+      }\r
+    return;\r
+  }\r
+\r
+  for(a = 1; a <= theLeft->GetNBValues(); a++) \r
+  {\r
+    Standard_Integer aNear = theLeft->GetNear(a);\r
+    \r
+    Standard_Real aA = (theRight->GetDiff(aNear) - theLeft->GetDiff(a)) / aDX;\r
+    Standard_Real aB = theLeft->GetDiff(a) - aA * theLeft->GetParam();\r
+    Standard_Real aC = theLeft->GetValue(a) - theLeft->GetDiff(a) * theLeft->GetParam() + \r
+                       aA * theLeft->GetParam() * theLeft->GetParam() / 2.0;\r
+    Standard_Real aDet = aB * aB - 2.0 * aA * aC;\r
+\r
+    if ( fabs(aDet) < gp::Resolution() )\r
+      continue;\r
+    \r
+    if (fabs(aA) < Precision::Confusion()) \r
+    { // linear case\r
+      if (fabs(aB) > 10e-20) \r
+      {\r
+        Standard_Real aX0 = - aC / aB; // use extremum\r
+        if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())\r
+          processPoint(theLeft, theRight, aX0);\r
+      }\r
+      else \r
+      {\r
+        processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise\r
+      }\r
+    } \r
+    else\r
+    {\r
+      if (fabs(aB) > fabs(aDet * 1000000.)) \r
+      {  // possible floating point operations accurancy errors\r
+        processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise\r
+      } \r
+      else\r
+      {\r
+        if (aDet > 0) \r
+        { // two solutions\r
+          aDet = sqrt(aDet);\r
+          Standard_Boolean aRes = processPoint(theLeft, theRight, (- aB + aDet) / aA);\r
+          if (!aRes) \r
+            aRes = processPoint(theLeft, theRight, (- aB - aDet) / aA);\r
+          if (!aRes) \r
+            processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise\r
+        } \r
+        else \r
+        {\r
+          Standard_Real aX0 = - aB / aA; // use extremum\r
+          if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())\r
+            processPoint(theLeft, theRight, aX0);\r
+          else \r
+            processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+//=======================================================================\r
+//function : Result\r
+//purpose  : \r
+//=======================================================================\r
+TopoDS_Edge GEOMImpl_Fillet1d::Result(const gp_Pnt& thePoint,\r
+                                      TopoDS_Edge& theEdge1,\r
+                                      TopoDS_Edge& theEdge2) \r
+{\r
+  TopoDS_Edge aResult;\r
+  gp_Pnt2d aTargetPoint2d;\r
+  Standard_Real aX, aY;\r
+  ElSLib::PlaneParameters(myPlane->Pln().Position(), thePoint, aX, aY);\r
+  aTargetPoint2d.SetCoord(aX, aY);\r
+   \r
+  // choose the nearest circle\r
+  Standard_Real aDistance, aP;\r
+  GEOMImpl_Fillet1dPoint *aNearest;\r
+  Standard_Integer a;\r
+  TColStd_ListIteratorOfListOfReal anIter(myResultParams);\r
+  for(aNearest = NULL, a = 1; anIter.More(); anIter.Next(), a++) \r
+  {\r
+    myStartSide = (myResultOrientation.Value(a)) ? Standard_True : Standard_False;\r
+    GEOMImpl_Fillet1dPoint *aPoint = new GEOMImpl_Fillet1dPoint(anIter.Value());\r
+    fillPoint(aPoint);\r
+    if (!aPoint->HasSolution(myRadius)) \r
+      continue;\r
+    aP = fabs(aPoint->GetCenter().Distance(aTargetPoint2d) - myRadius);\r
+    if (!aNearest || aP < aDistance) \r
+    {\r
+      aNearest = aPoint;\r
+      aDistance = aP;\r
+    } \r
+    else \r
+    {\r
+      delete aPoint;\r
+    }\r
+   }\r
+   \r
+  if (!aNearest) \r
+     return aResult;\r
+   \r
+  // create circle edge\r
+  gp_Pnt aCenter = ElSLib::PlaneValue(aNearest->GetCenter().X(),\r
+                                      aNearest->GetCenter().Y(),\r
+                                      myPlane->Pln().Position());\r
+  Handle(Geom_Circle) aCircle =\r
+    new Geom_Circle(gp_Ax2(aCenter, myPlane->Pln().Axis().Direction()), myRadius);\r
+  gp_Pnt2d aPoint2d1, aPoint2d2;\r
+  myCurve1->D0(aNearest->GetParam(), aPoint2d1);\r
+  myCurve2->D0(aNearest->GetParam2(), aPoint2d2);\r
+  gp_Pnt aPoint1 = ElSLib::PlaneValue(aPoint2d1.X(), aPoint2d1.Y(), myPlane->Pln().Position());\r
+  gp_Pnt aPoint2 = ElSLib::PlaneValue(aPoint2d2.X(), aPoint2d2.Y(), myPlane->Pln().Position());\r
+\r
+  GeomAPI_ProjectPointOnCurve aProj(thePoint, aCircle);\r
+  Standard_Real aTarGetParam = aProj.LowerDistanceParameter();\r
+  gp_Pnt aPointOnCircle = aProj.NearestPoint();\r
+\r
+  // Check extrema point manually, because there is a bug in Open CASCADE\r
+  //  in calculation of nearest point to a circle near the parameter 0.0\r
+  gp_Pnt p0 = ElCLib::Value(0.0, aCircle->Circ());\r
+  if (p0.Distance(thePoint) < aPointOnCircle.Distance(thePoint))\r
+  {\r
+     aTarGetParam = 0.0;\r
+     aPointOnCircle = p0;\r
+  }\r
+\r
+  aProj.Perform(aPoint1);\r
+  Standard_Real aParam1 = aProj.LowerDistanceParameter();\r
+    aProj.Perform(aPoint2);\r
+  Standard_Real aParam2 = aProj.LowerDistanceParameter();\r
+  Standard_Boolean aIsOut = ((aParam1 < aTarGetParam && aParam2 < aTarGetParam) || \r
+                             (aParam1 > aTarGetParam && aParam2 > aTarGetParam));\r
+  if (aParam1 > aParam2) \r
+    aIsOut = !aIsOut;\r
+  BRepBuilderAPI_MakeEdge aBuilder(aCircle->Circ(),\r
+                                   aIsOut ? aParam2 : aParam1,\r
+                                   aIsOut? aParam1 : aParam2);\r
+  aResult = aBuilder.Edge();\r
+\r
+  // divide edges\r
+  Standard_Real aStart, anEnd;\r
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge1, aStart, anEnd);\r
+  gp_Vec aDir;\r
+  aCurve->D1(aNearest->GetParam(), aPoint1, aDir);\r
+\r
+  gp_Vec aCircleDir;\r
+  aCircle->D1(aParam1, aPoint1, aCircleDir);\r
+  if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ aIsOut)\r
+    aStart = aNearest->GetParam();\r
+  else\r
+    anEnd = aNearest->GetParam();\r
+\r
+  if (fabs(aStart - anEnd) > Precision::Confusion())\r
+  {\r
+      //Divide edge\r
+      BRepBuilderAPI_MakeEdge aDivider1(aCurve, aStart, anEnd);\r
+      if (myEdgesExchnged) \r
+        theEdge2 = aDivider1.Edge();\r
+      else \r
+        theEdge1 = aDivider1.Edge();\r
+  }\r
+\r
+  aCurve = BRep_Tool::Curve(myEdge2, aStart, anEnd);\r
+  aCurve->D1(aNearest->GetParam2(), aPoint2, aDir);\r
+   \r
+  aCircle->D1(aParam2, aPoint2, aCircleDir);\r
+  if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ (!aIsOut))\r
+    aStart = aNearest->GetParam2();\r
+  else\r
+    anEnd = aNearest->GetParam2();\r
+\r
+  if (fabs(aStart - anEnd) > Precision::Confusion())\r
+  {\r
+      BRepBuilderAPI_MakeEdge aDivider2(aCurve, aStart, anEnd);\r
+      if (myEdgesExchnged) \r
+        theEdge1 = aDivider2.Edge();\r
+      else \r
+        theEdge2 = aDivider2.Edge();\r
+  }\r
+\r
+  delete aNearest;\r
+  return aResult;\r
+}\r
+\r
+//=======================================================================\r
+//function : AddValue\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1dPoint::AddValue(Standard_Real theValue, Standard_Boolean theValid) \r
+{\r
+  Standard_Integer a;\r
+  for(a = 1; a <= myV.Length(); a++) \r
+  {\r
+    if (theValue < myV.Value(a)) \r
+    {\r
+      myV.InsertBefore(a, theValue);\r
+      myValid.InsertBefore(a, (Standard_Integer)theValid);\r
+      return;\r
+    }\r
+  }\r
+  myV.Append(theValue);\r
+  myValid.Append((Standard_Integer)theValid);\r
+}\r
+\r
+//=======================================================================\r
+//function : ComputeDifference\r
+//purpose  : \r
+//=======================================================================\r
+Standard_Boolean GEOMImpl_Fillet1dPoint::ComputeDifference(GEOMImpl_Fillet1dPoint* thePoint) \r
+{\r
+  Standard_Integer a;\r
+  Standard_Boolean aDiffsSet = (myD.Length() != 0);\r
+  Standard_Real aDX = thePoint->GetParam() - myParam, aDY;\r
+  if (thePoint->myV.Length() == myV.Length()) \r
+  { // absolutely the same points\r
+    for(a = 1; a <= myV.Length(); a++) \r
+    {\r
+      aDY = thePoint->myV.Value(a) - myV.Value(a);\r
+      if ( aDiffsSet ) \r
+        myD.SetValue(a, fabs(aDX) > gp::Resolution() ? (aDY/aDX) : 0);\r
+      else\r
+        myD.Append( fabs(aDX) > gp::Resolution() ? (aDY/aDX) : 0);\r
+    }\r
+    return Standard_True;\r
+  }\r
+  // between the diffeerent points searching for nearest analogs\r
+  Standard_Integer b;\r
+  for(a = 1; a <= myV.Length(); a++) \r
+  {\r
+    for(b = 1; b <= thePoint->myV.Length(); b++) \r
+    {\r
+      if (b == 1 || fabs(thePoint->myV.Value(b) - myV.Value(a)) < fabs(aDY))\r
+        aDY = thePoint->myV.Value(b) - myV.Value(a);\r
+    }\r
+    if (aDiffsSet) \r
+    {\r
+      if ( fabs(aDX) > gp::Resolution() && fabs(aDY / aDX) < fabs(myD.Value(a)))\r
+        myD.SetValue(a, aDY / aDX);\r
+      else\r
+        myD.SetValue(a, 0);\r
+    } \r
+    else \r
+    {\r
+      myD.Append( fabs(aDX) > gp::Resolution() ? aDY/aDX : 0);\r
+    }\r
+  }\r
+  \r
+  return Standard_False;\r
+}\r
+\r
+//=======================================================================\r
+//function : FilterPoints\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1dPoint::FilterPoints(GEOMImpl_Fillet1dPoint* thePoint) \r
+{\r
+  Standard_Integer a, b;\r
+  TColStd_SequenceOfReal aDiffs;\r
+  Standard_Real aY, aY2, aDX = thePoint->GetParam() - myParam;\r
+  for(a = 1; a <= myV.Length(); a++) \r
+  {\r
+    // searching for near point from thePoint\r
+    Standard_Integer aNear = 0;\r
+    Standard_Real aDiff = aDX * 10000.;\r
+    aY = myV.Value(a) + myD.Value(a) * aDX;\r
+    for(b = 1; b <= thePoint->myV.Length(); b++) \r
+    {\r
+      // calculate hypothesis value of the Y2 with the constant first and second derivative\r
+      aY2 = aY + aDX * (thePoint->myD.Value(b) - myD.Value(a)) / 2.0;\r
+      if (aNear == 0 || fabs(aY2 - thePoint->myV.Value(b)) < fabs(aDiff)) \r
+      {\r
+        aNear = b;\r
+        aDiff = aY2 - thePoint->myV.Value(b);\r
+      }\r
+    }//for b...\r
+\r
+    if (aNear) \r
+    {\r
+      if (myV.Value(a) * thePoint->myV.Value(aNear) > 0) \r
+      {// the same sign at the same sides of the interval\r
+        if (myV.Value(a) * myD.Value(a) > 0) \r
+        {\r
+          if (fabs(myD.Value(a)) > Precision::Confusion()) \r
+            aNear = 0;\r
+        } \r
+        else \r
+        {\r
+          if (fabs(myV.Value(a)) > fabs(thePoint->myV.Value(aNear)))\r
+            if (thePoint->myV.Value(aNear) * thePoint->myD.Value(aNear) < 0 &&\r
+                fabs(thePoint->myD.Value(aNear)) > Precision::Confusion())\r
+            {\r
+              aNear = 0;\r
+            }\r
+        }\r
+      }\r
+    }\r
+\r
+    if (aNear) \r
+    {\r
+      if (myV.Value(a) * thePoint->myV.Value(aNear) > 0) \r
+      {\r
+        if ((myV.Value(a) + myD.Value(a) * aDX) * myV.Value(a) > Precision::Confusion() &&\r
+        (thePoint->myV.Value(aNear) + thePoint->myD.Value(aNear) * aDX) * thePoint->myV.Value(aNear) > Precision::Confusion())\r
+        {\r
+          aNear = 0;\r
+        }\r
+      }\r
+    }\r
+    \r
+    if (aNear)\r
+    {\r
+      if (  fabs(aDX) < gp::Resolution() || fabs(aDiff / aDX) > 1.e+7) \r
+      {\r
+        aNear = 0;\r
+      }\r
+    }\r
+\r
+    if (aNear == 0) \r
+    {  // there is no near: remove it from the list\r
+      myV.Remove(a);\r
+      myD.Remove(a);\r
+      myValid.Remove(a);\r
+      a--;\r
+    } \r
+    else \r
+    {\r
+      Standard_Boolean aFound = Standard_False;\r
+      for(b = 1; b <= myNear.Length(); b++) \r
+      {\r
+        if (myNear.Value(b) == aNear) \r
+        {\r
+          if (fabs(aDiffs.Value(b)) < fabs(aDiff)) \r
+          { // return this 'near'\r
+            aFound = Standard_True;\r
+            myV.Remove(a);\r
+            myD.Remove(a);\r
+            myValid.Remove(a);\r
+            a--;\r
+            break;\r
+          } \r
+          else \r
+          { // remove the old 'near'\r
+            myV.Remove(b);\r
+            myD.Remove(b);\r
+            myValid.Remove(b);\r
+            myNear.Remove(b);\r
+            aDiffs.Remove(b);\r
+            a--;\r
+            break;\r
+          }\r
+        }\r
+      }//for b...\r
+      if (!aFound) \r
+      {\r
+        myNear.Append(aNear);\r
+        aDiffs.Append(aDiff);\r
+      }\r
+    }\r
+  }//for a...\r
+}\r
+\r
+//=======================================================================\r
+//function : Copy\r
+//purpose  : \r
+//=======================================================================\r
+GEOMImpl_Fillet1dPoint* GEOMImpl_Fillet1dPoint::Copy() \r
+{\r
+  GEOMImpl_Fillet1dPoint* aCopy = new GEOMImpl_Fillet1dPoint(myParam);\r
+  Standard_Integer a;\r
+  for(a = 1; a <= myV.Length(); a++) \r
+  {\r
+    aCopy->myV.Append(myV.Value(a));\r
+    aCopy->myD.Append(myD.Value(a));\r
+    aCopy->myValid.Append(myValid.Value(a));\r
+  }\r
+  return aCopy;\r
+}\r
+\r
+//=======================================================================\r
+//function : HasSolution\r
+//purpose  : \r
+//=======================================================================\r
+Standard_Integer GEOMImpl_Fillet1dPoint::HasSolution(const Standard_Real theRadius) \r
+{\r
+  Standard_Integer a;\r
+  for(a = 1; a <= myV.Length(); a++) \r
+  {\r
+    if (fabs(sqrt(fabs(fabs(myV.Value(a)) + theRadius * theRadius)) - theRadius) < Precision::Confusion() / 10.) \r
+      return a;\r
+  }\r
+  return 0;\r
+}\r
+\r
+//=======================================================================\r
+//function : RemoveSolution\r
+//purpose  : \r
+//=======================================================================\r
+void GEOMImpl_Fillet1dPoint::RemoveSolution(Standard_Integer theIndex)\r
+{\r
+  myV.Remove(theIndex);\r
+  myD.Remove(theIndex);\r
+  myValid.Remove(theIndex);\r
+  myNear.Remove(theIndex);\r
+}\r
index 80df11a1edb4e98bddf0c1da5ecd5ac40aff71dd..c12ee156781761ddaa28ae3b616211807f8a2d0d 100644 (file)
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  File   : GEOMImpl_Fillet1d.hxx
-//  Module : GEOMImpl
-//
-#ifndef _GEOMImpl_Fillet1d_HeaderFile
-#define _GEOMImpl_Fillet1d_HeaderFile
-
-#include <gp_Pnt.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom2d_Curve.hxx>
-
-#include <TopoDS_Edge.hxx>
-#include <TColStd_ListOfReal.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <TColStd_SequenceOfInteger.hxx>
-
-class GEOMImpl_Fillet1dPoint;
-
-/**
-* GEOMImpl_Fillet1d is 1D fillet algorithm on two planar edges with given radius
-*/
-
-class GEOMImpl_Fillet1d 
-{
-public:
-  //! Constructor
-  //! The fillet 1D algorithm initialise by two edges and plane
-  Standard_EXPORT GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
-                                    const TopoDS_Edge& theEdge2,
-                                    const gp_Pln&      thePlane);
-  //! Makes fillet with given radius
-  //! @returns Standard_True, if at least one result computed
-  Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);
-  //! Returns result fillet edge and modified edges as out parameters
-  Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2);
-
-private:
-  //! private methods
-  void fillPoint(GEOMImpl_Fillet1dPoint*);
-  void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean);
-  void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);
-  Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);
-
-
-private:
-  //! private fields
-  TopoDS_Edge myEdge1, myEdge2;
-  Handle(Geom_Plane) myPlane;
-  Handle(Geom2d_Curve) myCurve1, myCurve2;
-  Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;
-  TColStd_ListOfReal myResultParams;
-  TColStd_SequenceOfInteger myResultOrientation;
-  Standard_Boolean myStartSide, myEdgesExchnged;
-};
-
-
-/**
-* GEOMImpl_Fillet1dPoint is an internal class for 1D fillet algorithm
-*   to store and compare computed solutions on edges
-*/
-
-class GEOMImpl_Fillet1dPoint
-{
-public:
-  //! Puiblic methods
-
-  //! Constructor
-  Standard_EXPORT GEOMImpl_Fillet1dPoint(Standard_Real theParam)
-  {myParam = theParam;}
-  
-  //! Make copy of point
-  //!WARNING: Copies only field values: myParam, myV, myD, myValid
-  Standard_EXPORT GEOMImpl_Fillet1dPoint* Copy(); // warning: this is not the full copy! 
-
-  //! Set/Get parameter
-  Standard_EXPORT inline void SetParam(Standard_Real theParam)
-    {myParam = theParam;}
-  Standard_EXPORT inline Standard_Real GetParam() const
-    {return myParam;}
-  Standard_EXPORT inline void SetParam2(const Standard_Real theParam2)
-    {myParam2 = theParam2;}
-  Standard_EXPORT inline Standard_Real GetParam2()
-    { return myParam2 ; }
-
-  //! Returns validity  
-  Standard_EXPORT inline Standard_Boolean IsValid(int theIndex)
-    {return (Standard_Boolean)myValid.Value(theIndex);}
-
-  //! Get values
-  Standard_EXPORT inline Standard_Integer GetNBValues() {return myV.Length();}
-  Standard_EXPORT inline Standard_Real GetValue(Standard_Integer theIndex)
-    {return myV.Value(theIndex);}
-  Standard_EXPORT inline Standard_Real GetDiff(Standard_Integer theIndex)
-    {return myD.Value(theIndex);}
-  Standard_EXPORT inline Standard_Integer GetNear(Standard_Integer theIndex)
-    {return myNear.Value(theIndex);}
-
-  //! Set/Get center point
-  Standard_EXPORT inline void SetCenter(const gp_Pnt2d thePoint)
-    {myCenter = thePoint;}
-  Standard_EXPORT inline const gp_Pnt2d GetCenter()
-    {return myCenter;}
-
-  Standard_EXPORT void AddValue(Standard_Real theValue, Standard_Boolean theIsValid);
-
-  //! compute difference between this and given point
-  Standard_EXPORT Standard_Boolean ComputeDifference(GEOMImpl_Fillet1dPoint*);
-  Standard_EXPORT void FilterPoints(GEOMImpl_Fillet1dPoint*);
-  
-  //! Check is point contains solution and  returns the index of them if any
-  Standard_EXPORT Standard_Integer HasSolution(Standard_Real theRadius); 
-  //! Remove solution by index
-  void RemoveSolution(Standard_Integer theIndex);
-
-private:
-  //! Private fields
-  gp_Pnt2d myCenter;
-  Standard_Real myParam, myParam2;
-  TColStd_SequenceOfReal myV, myD;
-  TColStd_SequenceOfInteger myValid, myNear;
-};
-
-#endif
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE\r
+//\r
+//  This library is free software; you can redistribute it and/or\r
+//  modify it under the terms of the GNU Lesser General Public\r
+//  License as published by the Free Software Foundation; either\r
+//  version 2.1 of the License.\r
+//\r
+//  This library is distributed in the hope that it will be useful,\r
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+//  Lesser General Public License for more details.\r
+//\r
+//  You should have received a copy of the GNU Lesser General Public\r
+//  License along with this library; if not, write to the Free Software\r
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
+//\r
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+//\r
+\r
+//  File   : GEOMImpl_Fillet1d.hxx\r
+//  Module : GEOMImpl\r
+//\r
+#ifndef _GEOMImpl_Fillet1d_HeaderFile\r
+#define _GEOMImpl_Fillet1d_HeaderFile\r
+\r
+#include <gp_Pnt.hxx>\r
+#include <Geom_Plane.hxx>\r
+#include <Geom2d_Curve.hxx>\r
+\r
+#include <TopoDS_Edge.hxx>\r
+#include <TColStd_ListOfReal.hxx>\r
+#include <TColStd_SequenceOfReal.hxx>\r
+#include <TColStd_SequenceOfInteger.hxx>\r
+\r
+class GEOMImpl_Fillet1dPoint;\r
+\r
+/**\r
+* GEOMImpl_Fillet1d is 1D fillet algorithm on two planar edges with given radius\r
+*/\r
+\r
+class GEOMImpl_Fillet1d \r
+{\r
+public:\r
+  //! Constructor\r
+  //! The fillet 1D algorithm initialise by two edges and plane\r
+  Standard_EXPORT GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,\r
+                                    const TopoDS_Edge& theEdge2,\r
+                                    const gp_Pln&      thePlane);\r
+  //! Makes fillet with given radius\r
+  //! @returns Standard_True, if at least one result computed\r
+  Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);\r
+  //! Returns result fillet edge and modified edges as out parameters\r
+  Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2);\r
+\r
+private:\r
+  //! private methods\r
+  void fillPoint(GEOMImpl_Fillet1dPoint*);\r
+  void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean);\r
+  void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);\r
+  Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);\r
+\r
+\r
+private:\r
+  //! private fields\r
+  TopoDS_Edge myEdge1, myEdge2;\r
+  Handle(Geom_Plane) myPlane;\r
+  Handle(Geom2d_Curve) myCurve1, myCurve2;\r
+  Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;\r
+  TColStd_ListOfReal myResultParams;\r
+  TColStd_SequenceOfInteger myResultOrientation;\r
+  Standard_Boolean myStartSide, myEdgesExchnged;\r
+  Standard_Integer myDegreeOfRecursion;\r
+};\r
+\r
+\r
+/**\r
+* GEOMImpl_Fillet1dPoint is an internal class for 1D fillet algorithm\r
+*   to store and compare computed solutions on edges\r
+*/\r
+\r
+class GEOMImpl_Fillet1dPoint\r
+{\r
+public:\r
+  //! Puiblic methods\r
+\r
+  //! Constructor\r
+  Standard_EXPORT GEOMImpl_Fillet1dPoint(Standard_Real theParam)\r
+  {myParam = theParam;}\r
+  \r
+  //! Make copy of point\r
+  //!WARNING: Copies only field values: myParam, myV, myD, myValid\r
+  Standard_EXPORT GEOMImpl_Fillet1dPoint* Copy(); // warning: this is not the full copy! \r
+\r
+  //! Set/Get parameter\r
+  Standard_EXPORT inline void SetParam(Standard_Real theParam)\r
+    {myParam = theParam;}\r
+  Standard_EXPORT inline Standard_Real GetParam() const\r
+    {return myParam;}\r
+  Standard_EXPORT inline void SetParam2(const Standard_Real theParam2)\r
+    {myParam2 = theParam2;}\r
+  Standard_EXPORT inline Standard_Real GetParam2()\r
+    { return myParam2 ; }\r
+\r
+  //! Returns validity  \r
+  Standard_EXPORT inline Standard_Boolean IsValid(int theIndex)\r
+    {return (Standard_Boolean)myValid.Value(theIndex);}\r
+\r
+  //! Get values\r
+  Standard_EXPORT inline Standard_Integer GetNBValues() {return myV.Length();}\r
+  Standard_EXPORT inline Standard_Real GetValue(Standard_Integer theIndex)\r
+    {return myV.Value(theIndex);}\r
+  Standard_EXPORT inline Standard_Real GetDiff(Standard_Integer theIndex)\r
+    {return myD.Value(theIndex);}\r
+  Standard_EXPORT inline Standard_Integer GetNear(Standard_Integer theIndex)\r
+    {return myNear.Value(theIndex);}\r
+\r
+  //! Set/Get center point\r
+  Standard_EXPORT inline void SetCenter(const gp_Pnt2d thePoint)\r
+    {myCenter = thePoint;}\r
+  Standard_EXPORT inline const gp_Pnt2d GetCenter()\r
+    {return myCenter;}\r
+\r
+  Standard_EXPORT void AddValue(Standard_Real theValue, Standard_Boolean theIsValid);\r
+\r
+  //! compute difference between this and given point\r
+  Standard_EXPORT Standard_Boolean ComputeDifference(GEOMImpl_Fillet1dPoint*);\r
+  Standard_EXPORT void FilterPoints(GEOMImpl_Fillet1dPoint*);\r
+  \r
+  //! Check is point contains solution and  returns the index of them if any\r
+  Standard_EXPORT Standard_Integer HasSolution(Standard_Real theRadius); \r
+  //! Remove solution by index\r
+  void RemoveSolution(Standard_Integer theIndex);\r
+\r
+private:\r
+  //! Private fields\r
+  gp_Pnt2d myCenter;\r
+  Standard_Real myParam, myParam2;\r
+  TColStd_SequenceOfReal myV, myD;\r
+  TColStd_SequenceOfInteger myValid, myNear;\r
+};\r
+\r
+#endif\r