0026431: Can't cut a sphere from a cylinder
authornbv <nbv@opencascade.com>
Tue, 10 Nov 2015 07:31:19 +0000 (10:31 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 4 Dec 2015 10:15:04 +0000 (13:15 +0300)
This branch contains fixes for 26675 and 26431 bugs.

1. Normalization has been eliminated.
2. Interfaces of AppDef_Compute::Parametrization(...) and BRepAlgo_BooleanOperations::SetApproxParameters() methods have been changed.
3. Overloaded methods for ApproxInt_Approx::SetParameters(...), TopOpeBRepTool_GeomTool::GetTolerances(...) and TopOpeBRepTool_GeomTool::SetTolerances(...) have been removed (because some fields of these classes are not used more).
4. Comments for some methods have been changed in BRepApprox_TheMultiLineOfApprox.hxx and GeomInt_TheMultiLineOfWLApprox.hxx files.
5. Some fields have been deleted from ApproxInt_MultiLine class. Kept members have become constant.
6. Interface of ksection DRAW-command has been changed.
7. Now, 2dintersect DRAW-command prints information about found segments.
8. Some code fragments have been rewritten to make them easier.
9. Algorithm of splitting WLine, which goes through pole of sphere has been improved.
10. Improve approximation algorithm in order to it will compute correct 2D- and 3D-tangent at the end of bezier constraints (including case when curve goes through or finishes on singular points).
11. Interface of IntPatch_WLine::Dump(...) method has been corrected.
12. Some methods for working with Walking-line are made more universal (available for both GeomInt and IntTools packages).
13. Problem in BRepLib::SameParameter(...) method has been fixed (see corresponding comment).
14. Small correction in Draft package.
15. Any outputs in IntPatch_Intersection::Dump(...) method have become disabled because they are useless. If anybody need in this outputs he/she will correct this method himself/herself.

Adjusting some test cases according to their new behavior.
Creation of new test cases.

----------------------------------------------------------------------------------------------------------------------------

Some explanation of new behavior of some test cases:

 1. Regressions:

a) blend simple X4
The problem is described in the issue #0026740. According to this description,  the result on the current MASTER seems to be wrong indeed.

b) boolean bcommon_complex C7 and boolean bcut_complex Q1
These test case use same shapes with different Boolean operation (COMMON and CUT). They are already BAD (on the MASTER). Now, some sub-shapes have become not-shared, simply. In my opinion, we shall apply new behavior of these tests.

c) boolean bsection M3
The problem described in the issue #0026777 exists even on the current MASTER.

d) boolean bsection M9
The problem is described in the message http://tracker.dev.opencascade.org/view.php?id=26815#c47546. Here, we have really regression in the picture.

e) boolean bsection N2

The problem is described in issue #0026814.

f) boolean volumemaker G1

The problem is described in issue #26020.

g) bugs modalg_1 bug1255 (and bug1255_1)

The problem is described in issue #26815.

h) bugs modalg_2 bug5805_18, bugs modalg_2 bug5805_42, bugs modalg_2 bug5805_46

The problem is described in issue #25925.

i) bugs modalg_3 bug602

The problem is describes in issue #602.

j) bugs modalg_5 bug24915

The problem is described in the message http://tracker.dev.opencascade.org/view.php?id=25929#c48565. It is not fixed by this issue.

k) bugs modalg_5 bug25838

The main reason is described in issue #0026816.

----------------------------------------------------------------------------
2. Improvements:

a) boolean volumemaker F9
b) bugs modalg_1 bug10160_3
c) bugs modalg_2 bug22557
d) bugs modalg_5 bug25319_1 (_2)
e) draft angle G2
f) offset shape A1
g) offset with_intersect_80 N7

81 files changed:
src/AppDef/AppDef_Compute.hxx
src/AppParCurves/AppParCurves_LeastSquare.gxx
src/Approx/Approx_ComputeLine.gxx
src/ApproxInt/ApproxInt_Approx.gxx
src/ApproxInt/ApproxInt_ImpPrmSvSurfaces.gxx
src/ApproxInt/ApproxInt_KnotTools.cxx
src/ApproxInt/ApproxInt_MultiLine.gxx
src/BRepAlgo/BRepAlgo_BooleanOperations.cxx
src/BRepAlgo/BRepAlgo_BooleanOperations.hxx
src/BRepApprox/BRepApprox_Approx.hxx
src/BRepApprox/BRepApprox_TheComputeLineBezierOfApprox.hxx
src/BRepApprox/BRepApprox_TheMultiLineOfApprox.hxx
src/BRepLib/BRepLib.cxx
src/BSplCLib/BSplCLib_2.cxx
src/ChFi3d/ChFi3d_Builder_0.cxx
src/Draft/Draft_Modification_1.cxx
src/GeomInt/GeomInt_IntSS.hxx
src/GeomInt/GeomInt_IntSS.lxx
src/GeomInt/GeomInt_IntSS_1.cxx
src/GeomInt/GeomInt_LineTool.cxx
src/GeomInt/GeomInt_LineTool.hxx
src/GeomInt/GeomInt_TheComputeLineBezierOfWLApprox.hxx
src/GeomInt/GeomInt_TheMultiLineOfWLApprox.hxx
src/GeomInt/GeomInt_WLApprox.hxx
src/GeomliteTest/GeomliteTest_API2dCommands.cxx
src/HLRTopoBRep/HLRTopoBRep_DSFiller.cxx
src/IntPatch/FILES
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_Intersection.hxx
src/IntPatch/IntPatch_WLineTool.cxx [new file with mode: 0644]
src/IntPatch/IntPatch_WLineTool.hxx [new file with mode: 0644]
src/IntTools/IntTools_Context.cxx
src/IntTools/IntTools_FaceFace.cxx
src/IntTools/IntTools_WLineTool.cxx
src/IntTools/IntTools_WLineTool.hxx
src/ProjLib/ProjLib_ComputeApprox.cxx
src/QABugs/FILES
src/QABugs/QABugs.cxx
src/QABugs/QABugs.hxx
src/QABugs/QABugs_20.cxx [new file with mode: 0644]
src/QABugs/QABugs_3.cxx
src/ShapeAlgo/ShapeAlgo_AlgoContainer.cxx
src/TopOpeBRep/TopOpeBRep_FacesIntersector.cxx
src/TopOpeBRepTool/TopOpeBRepTool_CurveTool.cxx
src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.cxx
src/TopOpeBRepTool/TopOpeBRepTool_GeomTool.hxx
tests/blend/buildevol/B3
tests/blend/simple/G6
tests/blend/simple/X4
tests/boolean/bcommon_complex/C7
tests/boolean/bsection/M3
tests/boolean/bsection/N2
tests/boolean/volumemaker/C5
tests/boolean/volumemaker/C6
tests/boolean/volumemaker/F9
tests/boolean/volumemaker/G1
tests/bugs/modalg_1/buc60533
tests/bugs/modalg_1/buc60555_1
tests/bugs/modalg_1/buc60555_2
tests/bugs/modalg_1/buc60555_3
tests/bugs/modalg_1/bug10160_3
tests/bugs/modalg_1/bug1255
tests/bugs/modalg_1/bug1255_1
tests/bugs/modalg_2/bug22557
tests/bugs/modalg_2/bug5805_18
tests/bugs/modalg_2/bug5805_42
tests/bugs/modalg_2/bug5805_46
tests/bugs/modalg_3/bug602
tests/bugs/modalg_5/bug24585_1
tests/bugs/modalg_5/bug24915
tests/bugs/modalg_5/bug25319_1
tests/bugs/modalg_5/bug25319_2
tests/bugs/modalg_5/bug25838
tests/bugs/modalg_6/bug26431_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug26431_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug26431_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug26675 [new file with mode: 0644]
tests/draft/angle/G2
tests/offset/shape/A1
tests/offset/with_intersect_80/L6

index c387e88..a65bbd3 100644 (file)
@@ -116,7 +116,7 @@ public:
   Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue();
   
   //! returns the type  of  parametrization
-  Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const;
+  Standard_EXPORT Approx_ParametrizationType Parametrization () const;
   
   //! returns the new parameters of the approximation
   //! corresponding to the points of the multicurve <Index>.
index d21e276..0915499 100644 (file)
@@ -56,6 +56,92 @@ static int FlatLength(const TColStd_Array1OfInteger& Mults) {
   return sum;
 }
 
+//=======================================================================
+//function : CheckTangents
+//purpose  : Checks if theArrTg3d and theArrTg2d have direction
+//            corresponded to the direction between theArrPt1 and theArrPt2.
+//            If it is not then reverses tangent vectors.
+//              theArrPt1 (as same as theArrPt2) is sub-set of all 3D-points in
+//            one multy-point (multy-point is union of sets of 2D- and 3D-points).
+//
+//ATTENTION!!!
+//              The property of correlation between Tg3d and Tg2d is used here.
+//            Therefore, only 3D-coinciding is checked.
+//=======================================================================
+static void CheckTangents(const TColgp_Array1OfPnt& theArrPt1,
+                          const TColgp_Array1OfPnt& theArrPt2,
+                          TColgp_Array1OfVec& theArrTg3d,
+                          TColgp_Array1OfVec2d& theArrTg2d)
+{
+  if(theArrPt1.Lower() != theArrPt2.Lower())
+    return;
+
+  if(theArrPt1.Upper() != theArrPt2.Upper())
+    return;
+
+  if(theArrTg3d.Length() != theArrPt1.Length())
+    return;
+
+  Standard_Boolean isToChangeDir = Standard_False;
+
+  for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++)
+  {
+    const gp_Vec aV1(theArrPt1(i), theArrPt2(i));
+    const gp_Vec& aV2 = theArrTg3d(i);
+
+    if(aV1.Dot(aV2) < 0.0)
+    {
+      isToChangeDir = Standard_True;
+      break;
+    }
+  }
+
+  if(!isToChangeDir)
+    return;
+
+  //Change directions for every 2D- and 3D-tangents
+
+  for(Standard_Integer i = theArrTg3d.Lower(); i <= theArrTg3d.Upper(); i++)
+  {
+    theArrTg3d(i).Reverse();
+  }
+
+  for(Standard_Integer i = theArrTg2d.Lower(); i <= theArrTg2d.Upper(); i++)
+  {
+    theArrTg2d(i).Reverse();
+  }
+}
+
+//=======================================================================
+//function : CheckTangents
+//purpose  : Checks if theArrTg2d have direction
+//            corresponded to the direction between theArrPt1 and theArrPt2.
+//            If it is not then reverses tangent vector.
+//              theArrPt1 (as same as theArrPt2) is sub-set of all 2D-points in
+//            one multy-point (multy-point is union of sets of 2D- and 3D-points).
+//=======================================================================
+static void CheckTangents(const TColgp_Array1OfPnt2d& theArrPt1,
+                          const TColgp_Array1OfPnt2d& theArrPt2,
+                          TColgp_Array1OfVec2d& theArrTg2d)
+{
+  if(theArrPt1.Lower() != theArrPt2.Lower())
+    return;
+
+  if(theArrPt1.Upper() != theArrPt2.Upper())
+    return;
+
+  for(Standard_Integer i = theArrPt1.Lower(); i <= theArrPt1.Upper(); i++)
+  {
+    const gp_Vec2d  aV1(theArrPt1(i), theArrPt2(i));
+    const gp_Vec2d& aV2 = theArrTg2d(i);
+
+    if(aV1.Dot(aV2) < 0.0)
+    {
+      theArrTg2d(i).Reverse();
+    }
+  }
+}
+
 
 AppParCurves_LeastSquare::
   AppParCurves_LeastSquare(const MultiLine&    SSP,
@@ -893,14 +979,20 @@ void AppParCurves_LeastSquare::Perform(const math_Vector&  Parameters,
 
 
 
-
+//=======================================================================
+//function : Affect
+//purpose  :    Index is an ID of the point in MultiLine. Every point is set of
+//            several 3D- and 2D-points. E.g. every points of Walking-line,
+//            obtained in intersection algorithm, is set of one 3D points
+//            (nbP == 1) and two 2D-points (nbP2d == 2).
+//=======================================================================
 void AppParCurves_LeastSquare::Affect(const MultiLine& SSP,
                                      const Standard_Integer Index,
                                      AppParCurves_Constraint& Cons,
                                      math_Vector& Vt,
                                      math_Vector& Vc)
 {
-  // Vt: vecteur tangent, Vc: vecteur courbure.
+  // Vt: vector of tangent, Vc: vector of curvature.
 
   if (Cons >= AppParCurves_TangencyPoint) {
     Standard_Integer i, i2 = 1;
@@ -908,59 +1000,99 @@ void AppParCurves_LeastSquare::Affect(const MultiLine& SSP,
     Standard_Integer mynbP2d = nbP2d, mynbP = nbP;
     if (nbP2d == 0) mynbP2d = 1;
     if (nbP == 0) mynbP = 1;
-    TColgp_Array1OfPnt TabP(1, mynbP);
-    TColgp_Array1OfPnt2d TabP2d(1, mynbP2d);
     TColgp_Array1OfVec TabV(1, mynbP);
     TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
     
-    if (Cons == AppParCurves_CurvaturePoint) {
-      if (nbP != 0 && nbP2d != 0) {
-       Ok = ToolLine::Curvature(SSP, Index,TabV,TabV2d);
-       if (!Ok) { Cons = AppParCurves_TangencyPoint;}
+    if (Cons == AppParCurves_CurvaturePoint)
+    {
+      if (nbP != 0 && nbP2d != 0)
+      {
+        Ok = ToolLine::Curvature(SSP, Index,TabV,TabV2d);
+        if (!Ok) { Cons = AppParCurves_TangencyPoint;}
       }
-      else if (nbP2d != 0) {
-       Ok = ToolLine::Curvature(SSP, Index, TabV2d);
-       if (!Ok) { Cons = AppParCurves_TangencyPoint;}
+      else if (nbP2d != 0)
+      {
+        Ok = ToolLine::Curvature(SSP, Index, TabV2d);
+        if (!Ok) { Cons = AppParCurves_TangencyPoint;}
       }
       else {
-       Ok = ToolLine::Curvature(SSP, Index, TabV);
-       if (!Ok) { Cons = AppParCurves_TangencyPoint;}
+        Ok = ToolLine::Curvature(SSP, Index, TabV);
+        if (!Ok) { Cons = AppParCurves_TangencyPoint;}
       }
       if (Ok) {
-       for (i = 1; i <= nbP; i++) {
-         (TabV(i)).Coord(Vc(i2), Vc(i2+1), Vc(i2+2));
-         i2 += 3;
-       }
-       for (i = 1; i <= nbP2d; i++) {
-         (TabV2d(i)).Coord(Vc(i2), Vc(i2+1));
-         i2 += 2;
-       }
+        for (i = 1; i <= nbP; i++) {
+          (TabV(i)).Coord(Vc(i2), Vc(i2+1), Vc(i2+2));
+          i2 += 3;
+        }
+
+        for (i = 1; i <= nbP2d; i++) {
+          (TabV2d(i)).Coord(Vc(i2), Vc(i2+1));
+          i2 += 2;
+        }
       }
     }
 
     i2 = 1;
     if (Cons >= AppParCurves_TangencyPoint) {
       if (nbP != 0 && nbP2d != 0) {
-       Ok = ToolLine::Tangency(SSP, Index, TabV, TabV2d);
-       if (!Ok) { Cons = AppParCurves_PassPoint;}
+        Ok = ToolLine::Tangency(SSP, Index, TabV, TabV2d);
+        if (!Ok) { Cons = AppParCurves_PassPoint;}
       }
       else if (nbP2d != 0) {
-       Ok = ToolLine::Tangency(SSP, Index, TabV2d);
-       if (!Ok) { Cons = AppParCurves_PassPoint;}
+        Ok = ToolLine::Tangency(SSP, Index, TabV2d);
+        if (!Ok) { Cons = AppParCurves_PassPoint;}
       }
       else {
-       Ok = ToolLine::Tangency(SSP, Index, TabV);
-       if (!Ok) { Cons = AppParCurves_PassPoint;}
+        Ok = ToolLine::Tangency(SSP, Index, TabV);
+        if (!Ok) { Cons = AppParCurves_PassPoint;}
       }
-      if (Ok) {
-       for (i = 1; i <= nbP; i++) {
-         (TabV(i)).Coord(Vt(i2), Vt(i2+1), Vt(i2+2));
-         i2 += 3;
-       }
-       for (i = 1; i <= nbP2d; i++) {
-         (TabV2d(i)).Coord(Vt(i2), Vt(i2+1));
-         i2 += 2;
-       }
+
+      if (Ok)
+      {
+        TColgp_Array1OfPnt anArrPts3d1(1, mynbP), anArrPts3d2(1, mynbP);
+
+        if(nbP != 0)
+        {
+          if(Index < ToolLine::LastPoint(SSP))
+          {
+            ToolLine::Value(SSP, Index, anArrPts3d1);
+            ToolLine::Value(SSP, Index+1, anArrPts3d2);
+          }
+          else
+          {// (Index == ToolLine::LastPoint(theML))
+            ToolLine::Value(SSP, Index-1, anArrPts3d1);
+            ToolLine::Value(SSP, Index, anArrPts3d2);
+          }
+
+          CheckTangents(anArrPts3d1, anArrPts3d2, TabV, TabV2d);
+        }
+        else if(nbP2d != 0)
+        {
+          TColgp_Array1OfPnt2d anArrPts2d1(1, mynbP2d), anArrPts2d2(1, mynbP2d);
+
+          if(Index < ToolLine::LastPoint(SSP))
+          {
+            ToolLine::Value(SSP, Index, anArrPts3d1, anArrPts2d1);
+            ToolLine::Value(SSP, Index+1, anArrPts3d2, anArrPts2d2);
+          }
+          else
+          {// (Index == ToolLine::LastPoint(theML))
+            ToolLine::Value(SSP, Index-1, anArrPts3d1, anArrPts2d1);
+            ToolLine::Value(SSP, Index, anArrPts3d2, anArrPts2d2);
+          }
+
+          CheckTangents(anArrPts2d1, anArrPts2d2, TabV2d);
+        }
+
+        for (i = 1; i <= nbP; i++) {
+          (TabV(i)).Coord(Vt(i2), Vt(i2+1), Vt(i2+2));
+          i2 += 3;
+        }
+
+        for (i = 1; i <= nbP2d; i++) {
+          (TabV2d(i)).Coord(Vt(i2), Vt(i2+1));
+          i2 += 2;
+        }
       }
     }
   }
index 94aabba..edc6086 100644 (file)
@@ -1274,7 +1274,7 @@ void Approx_ComputeLine::Error(const Standard_Integer Index,
   tol2d = Tolers2d.Value(Index);
 }
 
-void Approx_ComputeLine::Parametrization(Approx_ParametrizationType& partype) const
+Approx_ParametrizationType Approx_ComputeLine::Parametrization() const
 {
-  partype = Par;
+  return Par;
 }
index 911e90f..a59c2cf 100644 (file)
 #include <Precision.hxx>
 #include <ApproxInt_KnotTools.hxx>
 
-const Standard_Integer LimRajout = 5;
-const Standard_Integer NbPntMaxDecoupage = 30;
-const Standard_Real RatioTol = 1.5;
+// If quantity of points is less than aMinNbPointsForApprox
+// then interpolation is used.
+const Standard_Integer aMinNbPointsForApprox = 5;
 
-//=======================================================================
-//function : MINABS3
-//purpose  : Compute minimal absolute distance to 0 from 3 values.
-//=======================================================================
-static Standard_Real MINABS3(Standard_Real a, Standard_Real b,Standard_Real c)
-{
-  if(a<0.0) a=-a;
-  if(b<0.0) b=-b;
-  if(c<0.0) c=-c;
-  if(a>c) a=c;
-  if(a>b) a=b;
-  return(a);
-}
-
-//=======================================================================
-//function : MINABS4
-//purpose  : Compute minimal absolute distance to 0 from 4 values.
-//=======================================================================
-static Standard_Real MINABS4(Standard_Real a, Standard_Real b,Standard_Real c,Standard_Real d)
-{
-  if(a<0.0) a=-a;
-  if(b<0.0) b=-b;
-  if(c<0.0) c=-c;
-  if(d<0.0) d=-d;
-  if(a>c) a=c;
-  if(a>b) a=b;
-  if(a>d) a=d;
-  return(a);
-}
+// This constant should be removed in the future.
+const Standard_Real RatioTol = 1.5 ;
 
 //=======================================================================
 //function : ComputeTrsf3d
 //purpose  : 
 //=======================================================================
 static void ComputeTrsf3d(const Handle(TheWLine)& theline,
-                          Standard_Real& Xo, Standard_Real& Ax,
-                          Standard_Real& Yo, Standard_Real& Ay,
-                          Standard_Real& Zo, Standard_Real& Az)
+                          Standard_Real& theXo,
+                          Standard_Real& theYo,
+                          Standard_Real& theZo)
 {
-    Standard_Integer nbp = theline->NbPnts();
-    Standard_Real z0,z1,x0,x1,y0,y1;
-    z0=y0=x0=RealLast();
-    z1=y1=x1=RealFirst();
-    for(Standard_Integer i=1;i<=nbp;i++) { 
-      const gp_Pnt& P = theline->Point(i).Value();
-      Standard_Real  X = P.X();
-      Standard_Real  Y = P.Y();
-      Standard_Real  Z = P.Z();
-      if(X<x0) x0=X;
-      if(X>x1) x1=X;
-      if(Y<y0) y0=Y;
-      if(Y>y1) y1=Y;
-      if(Z<z0) z0=Z;
-      if(Z>z1) z1=Z;
-    }
-    Standard_Real dx = x1-x0;
-    Standard_Real dy = y1-y0;
-    Standard_Real dz = z1-z0;
-    Standard_Real MaxD = dx; 
-    if(MaxD < dy) MaxD=dy;
-    if(MaxD < dz) MaxD=dz;
-    Standard_Real MaxDF = 0.01*MaxD;
-
-    if(MaxDF<1e-12) 
-      MaxDF=1.0;
-
-    if(dx > MaxDF) { Ax = 1.0 / dx;    Xo = -Ax * x0;  }
-    else {     Ax = 1.0/( MaxDF) ; Xo = -Ax*x0;   }
-    if(dy > MaxDF) { Ay = 1.0 / dy;    Yo = -Ay * y0;  }
-    else {     Ay = 1.0/( MaxDF); Yo = -Ay*y0;   }
-    if(dz > MaxDF) { Az = 1.0 / dz;    Zo = -Az * z0;  }
-    else {     Az = 1.0/(MaxDF); Zo = -Az*z0;   } 
+  const Standard_Integer aNbPnts = theline->NbPnts();
+  Standard_Real aXmin = RealLast(), aYmin = RealLast(), aZmin = RealLast();
+  for(Standard_Integer i=1;i<=aNbPnts;i++)
+  { 
+    const gp_Pnt& P = theline->Point(i).Value();
+    aXmin = Min(P.X(), aXmin);
+    aYmin = Min(P.Y(), aYmin);
+    aZmin = Min(P.Z(), aZmin);
+  }
+
+  theXo = -aXmin;
+  theYo = -aYmin;
+  theZo = -aZmin;
 }
 
 //=======================================================================
 //function : ComputeTrsf2d
-//purpose  :
+//purpose  : 
 //=======================================================================
 static void ComputeTrsf2d(const Handle(TheWLine)& theline,
-                          Standard_Real& Uo, Standard_Real& Au,
-                          Standard_Real& Vo, Standard_Real& Av,
                           const Standard_Boolean onFirst,
-                          const Standard_Real UVResRatio = 1.0)
-{
-    Standard_Integer nbp = theline->NbPnts();
-    Standard_Real u0,u1,v0,v1;
-    u0 = v0 = RealLast();
-    u1 = v1 = RealFirst();
-    // pointer to a member-function
-    void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
-    if (onFirst)
-      pfunc = &IntSurf_PntOn2S::ParametersOnS1;
-    else
-      pfunc = &IntSurf_PntOn2S::ParametersOnS2;
-    for(Standard_Integer i=1;i<=nbp;i++) { 
-      const IntSurf_PntOn2S&  POn2S = theline->Point(i);
-      Standard_Real  U,V;
-      (POn2S.*pfunc)(U,V);
-      if(U<u0) u0=U;
-      if(U>u1) u1=U;
-      if(V<v0) v0=V;
-      if(V>v1) v1=V;
-    }
-
-    Standard_Real du = (u1-u0);
-    Standard_Real dv = (v1-v0);
-
-    if (UVResRatio > 1.)
-      du *= UVResRatio;
-    else if (UVResRatio < 1.)
-      dv /= UVResRatio;
+                          Standard_Real& theUo,
+                          Standard_Real& theVo)
+{ 
+  const Standard_Integer aNbPnts = theline->NbPnts();
+  Standard_Real aUmin = RealLast(), aVmin = RealLast();
 
-    Standard_Real MaxUV=du;
-    if(MaxUV<dv) MaxUV=dv;
+  // pointer to a member-function
+  void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
 
-    Standard_Real MaxUVF=0.01*MaxUV;
-
-    //-- lbr le 22 fev 99 (FPE) 
-    if(MaxUVF<1e-12) 
-      MaxUVF=1.0;
+  if (onFirst)
+    pfunc = &IntSurf_PntOn2S::ParametersOnS1;
+  else
+    pfunc = &IntSurf_PntOn2S::ParametersOnS2;
+  
+  for(Standard_Integer i=1; i<=aNbPnts; i++)
+  { 
+    const IntSurf_PntOn2S&  POn2S = theline->Point(i);
+    Standard_Real  U,V;
+    (POn2S.*pfunc)(U,V);
+    aUmin = Min(U, aUmin);
+    aVmin = Min(V, aVmin);
+  }
 
-    if(du > MaxUVF) { Au = 1.0 / du;    Uo = -Au * u0;  }
-    else {     Au = 1.0/(MaxUVF); Uo = -Au*u0;  }
-    if(dv > MaxUVF) { Av = 1.0 / dv;    Vo = -Av * v0;  }
-    else {     Av = 1.0/(MaxUVF); Vo = -Av*v0;  }
+  theUo = -aUmin;
+  theVo = -aVmin;
 }
 
 //=======================================================================
@@ -219,22 +152,23 @@ static void Parameters(const ApproxInt_TheMultiLine& Line,
 }
 
 //=======================================================================
-//function : ApproxInt_Approx
-//purpose  : Constructor.
+//function : Default constructor
+//purpose  : 
 //=======================================================================
-ApproxInt_Approx::ApproxInt_Approx()
-: myComputeLine(4, 8, 0.001, 0.001, 5, Standard_True),
-  myComputeLineBezier(4, 8, 0.001, 0.001, 5, Standard_True)
+ApproxInt_Approx::ApproxInt_Approx():
+                      myComputeLine(4, 8, 0.001, 0.001, 5),
+                      myComputeLineBezier(4, 8, 0.001, 0.001, 5),
+                      myWithTangency(Standard_True),
+                      myTol3d(0.001),
+                      myTol2d(0.001),
+                      myDegMin(4),
+                      myDegMax(8),
+                      myNbIterMax(5),
+                      myTolReached3d(0.0),
+                      myTolReached2d(0.0)
 {
   myComputeLine.SetContinuity(2);
-  myData.myBezierApprox = Standard_True;
-
-  myRelativeTol = Standard_True;
-  myNbPntMax = NbPntMaxDecoupage;
-  myData.myMinFactorXYZ = 0.0;
-  myData.myMinFactorUV  = 0.0;
-  myTolReached3d = myTolReached2d = 0.0;
-  myUVRes1 = myUVRes2 = 1.0;
+  //myComputeLineBezier.SetContinuity(2);
 }
 
 //=======================================================================
@@ -251,43 +185,35 @@ void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
   // Prepare DS.
   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
 
-  Standard_Integer nbpntbez = indicemax-indicemin;
-  if(nbpntbez < LimRajout) 
+  const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin;
+  if(nbpntbez < aMinNbPointsForApprox) 
     myData.myBezierApprox = Standard_False;
   else 
     myData.myBezierApprox = Standard_True;
 
   // Fill data structure.
-  fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2);
+  fillData(theline);
 
   // Build knots.
   buildKnots(theline, NULL);
-
-  Standard_Boolean cut = Standard_True;
-  if(myRelativeTol==Standard_False)
+  if (myKnots.Length() == 2 &&
+      indicemax - indicemin > 2 * myData.myNbPntMax)
   {
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
+    // At least 3 knots for BrepApprox.
+    myKnots.ChangeLast() = (indicemax - indicemin) / 2;
+    myKnots.Append(indicemax);
   }
 
+  myComputeLine.Init      (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
+  myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
+
   buildCurve(theline, NULL);
 }
 
 //=======================================================================
 //function : Perform
-//purpose  : Param-Param perform.
+//purpose  : Definition of next steps according to surface types
+//            (i.e. coordination algorithm).
 //=======================================================================
 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
                                const ThePSurface& Surf2,
@@ -299,95 +225,26 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
                                const Standard_Integer indicemax) 
 {
 
-  GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
-  GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
-  if ((typeS1 != GeomAbs_Plane    &&
-       typeS1 != GeomAbs_Cylinder &&
-       typeS1 != GeomAbs_Sphere   &&
-       typeS1 != GeomAbs_Cone)    &&
-      (typeS2 != GeomAbs_Plane    &&
-       typeS2 != GeomAbs_Cylinder &&
-       typeS2 != GeomAbs_Sphere   &&
-       typeS2 != GeomAbs_Cone))
-  {
-    // Prepare DS.
-    prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
-
-    // Non-analytical case: Param-Param perform.
-    ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
+  myTolReached3d = myTolReached2d = 0.;
 
-    Standard_Integer nbpntbez = indicemax-indicemin;
-    if(nbpntbez < LimRajout) 
-      myData.myBezierApprox = Standard_False;
-    else 
-      myData.myBezierApprox = Standard_True;
+  const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
+  const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
 
-    Standard_Boolean cut = Standard_True;
-    if(nbpntbez < LimRajout)
-    {
-      cut = Standard_False;
-    }
-
-    Standard_Real aS1URes = ThePSurfaceTool::UResolution(Surf1, 1.0),
-                  aS1VRes = ThePSurfaceTool::VResolution(Surf1, 1.0),
-                  aS2URes = ThePSurfaceTool::UResolution(Surf2, 1.0),
-                  aS2VRes = ThePSurfaceTool::VResolution(Surf2, 1.0);
-    if(ApproxU1V1)
-      myUVRes1 = aS1URes / aS1VRes;
-    if(ApproxU2V2)
-      myUVRes2 = aS2URes / aS2VRes;
-
-    // Fill data structure.
-    fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2);
-
-    // Build knots.
-    Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces;
-    buildKnots(theline, ptrsvsurf);
-
-    if(myRelativeTol==Standard_False)
-    {
-      myComputeLine.Init(myDegMin,
-        myDegMax,
-        myTol3d*myData.myMinFactorXYZ,
-        myTol2d*myData.myMinFactorUV,
-        myNbIterMax,
-        cut,
-        myData.parametrization);
-      myComputeLineBezier.Init(myDegMin,
-        myDegMax,
-        myTol3d*myData.myMinFactorXYZ,
-        myTol2d*myData.myMinFactorUV,
-        myNbIterMax,
-        cut,
-        myData.parametrization);
-    }
-    else
-    {
-      myComputeLine.Init(myDegMin,
-        myDegMax,
-        myTol3d,
-        myTol2d,
-        myNbIterMax,
-        cut,
-        myData.parametrization);
-      myComputeLineBezier.Init(myDegMin,
-        myDegMax,
-        myTol3d,
-        myTol2d,
-        myNbIterMax,
-        cut,
-        myData.parametrization);
-    }
+  const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) ||
+                                      (typeS1 == GeomAbs_Cylinder) ||
+                                      (typeS1 == GeomAbs_Sphere) ||
+                                      (typeS1 == GeomAbs_Cone) ||
+                                      (typeS2 == GeomAbs_Plane) ||
+                                      (typeS2 == GeomAbs_Cylinder) ||
+                                      (typeS2 == GeomAbs_Sphere) ||
+                                      (typeS2 == GeomAbs_Cone));
 
-    buildCurve(theline, ptrsvsurf);
-  }
-  else
+  if(isQuadric)
   {
     IntSurf_Quadric Quad;
     Standard_Boolean SecondIsImplicit=Standard_False;
     switch (typeS1)
     {
-
     case GeomAbs_Plane:
       Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
       break;
@@ -427,160 +284,51 @@ void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
 
         default:
           break;
-        }
+        }//switch (typeS2)
       }
+
       break;
-    } 
-    if(SecondIsImplicit)
-    {
-      Perform(Surf1,Quad,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
-    }
-    else
-    {
-      Perform(Quad,Surf2,theline,ApproxXYZ,ApproxU1V1,ApproxU2V2,indicemin,indicemax);
-    }
-  }
-}
+    }//switch (typeS1)
 
-//=======================================================================
-//function : SetParameters
-//purpose  :
-//=======================================================================
-void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
-                                     const Standard_Real     Tol2d,
-                                     const Standard_Integer  DegMin,
-                                     const Standard_Integer  DegMax,
-                                     const Standard_Integer  NbIterMax,
-                                     const Standard_Boolean  ApproxWithTangency,
-                                     const Approx_ParametrizationType Parametrization)
-{
-    myWithTangency = ApproxWithTangency;
-    myTol3d        = Tol3d / RatioTol;
-    myTol2d        = Tol2d / RatioTol;
-    myDegMin       = DegMin;
-    myDegMax       = DegMax;
-    myNbIterMax    = NbIterMax;
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      Standard_True,
-      Parametrization);
-
-    if(!ApproxWithTangency) { 
-      myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
-    }
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      Standard_True,
-      Parametrization);
-    if(!ApproxWithTangency)
-    {
-      myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
-    }
-    myData.myBezierApprox = Standard_True;
-}
+    Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline,
+            ApproxXYZ, ApproxU1V1, ApproxU2V2,
+            indicemin, indicemax, !SecondIsImplicit);
 
-//=======================================================================
-//function : SetParameters
-//purpose  : Set parameters with RelativeTol flag and NbPntMax value.
-//=======================================================================
-void ApproxInt_Approx::SetParameters(const Standard_Real     Tol3d,
-                                     const Standard_Real     Tol2d,
-                                     const Standard_Boolean  RelativeTol,
-                                     const Standard_Integer  DegMin,
-                                     const Standard_Integer  DegMax,
-                                     const Standard_Integer  NbIterMax,
-                                     const Standard_Integer  NbPntMax,
-                                     const Standard_Boolean  ApproxWithTangency,
-                                     const Approx_ParametrizationType Parametrization) 
-{
-  myNbPntMax = NbPntMax ;
-  myRelativeTol = RelativeTol ;
-  SetParameters (Tol3d, Tol2d, DegMin, DegMax, NbIterMax, ApproxWithTangency, Parametrization) ;
-}
+    return;
+  }
+
+  // Here, isQuadric == FALSE.
 
-//=======================================================================
-//function : Perform
-//purpose  : Param-Analytic perform.
-//=======================================================================
-void ApproxInt_Approx::Perform(const ThePSurface& PSurf,
-                               const TheISurface& ISurf,
-                               const Handle(TheWLine)& theline,
-                               const Standard_Boolean ApproxXYZ,
-                               const Standard_Boolean ApproxU1V1,
-                               const Standard_Boolean ApproxU2V2,
-                               const Standard_Integer indicemin,
-                               const Standard_Integer indicemax)
-{
   // Prepare DS.
   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
 
-  // Non-analytical case: Param-Analytic perform.
-  ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(PSurf,ISurf);
+  // Non-analytical case: Param-Param perform.
+  ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
 
   Standard_Integer nbpntbez = indicemax-indicemin;
-  if(nbpntbez < LimRajout) 
+
+  if(nbpntbez < aMinNbPointsForApprox)
+  {
     myData.myBezierApprox = Standard_False;
+  }
   else 
-    myData.myBezierApprox = Standard_True;
-
-  Standard_Boolean cut = Standard_True;
-  if(nbpntbez < LimRajout)
   {
-    cut = Standard_False;
+    myData.myBezierApprox = Standard_True;
   }
 
-  Standard_Real aS1URes = ThePSurfaceTool::UResolution(PSurf, 1.0),
-                aS1VRes = ThePSurfaceTool::VResolution(PSurf, 1.0);
-  if(ApproxU1V1)
-    myUVRes1 = aS1URes / aS1VRes;
-
   // Fill data structure.
-  fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2);
+  fillData(theline);
+
+  const Standard_Boolean cut = myData.myBezierApprox;
+  const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces;
 
   // Build knots.
-  Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
   buildKnots(theline, ptrsvsurf);
 
-  if(myRelativeTol==Standard_False)
-  {
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-  }
-  else
-  {
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-  }
+  myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, cut, myData.parametrization);
+  myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, cut, myData.parametrization);
 
   buildCurve(theline, ptrsvsurf);
 }
@@ -596,77 +344,80 @@ void ApproxInt_Approx::Perform(const TheISurface& ISurf,
                                const Standard_Boolean ApproxU1V1,
                                const Standard_Boolean ApproxU2V2,
                                const Standard_Integer indicemin,
-                               const Standard_Integer indicemax)
+                               const Standard_Integer indicemax,
+                               const Standard_Boolean isTheQuadFirst)
 {
   // Prepare DS.
   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
 
   // Non-analytical case: Analytic-Param perform.
-  ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces(ISurf, PSurf);
+  ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces = 
+                          isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf):
+                                          ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf);
 
-  Standard_Integer nbpntbez = indicemax-indicemin;
-  if(nbpntbez < LimRajout) 
+  const Standard_Integer nbpntbez = indicemax-indicemin;
+  if(nbpntbez < aMinNbPointsForApprox)
+  {
     myData.myBezierApprox = Standard_False;
+  }
   else 
-    myData.myBezierApprox = Standard_True;
-
-  Standard_Boolean cut = Standard_True;
-  if(nbpntbez < LimRajout)
   {
-    cut = Standard_False;
+    myData.myBezierApprox = Standard_True;
   }
 
-  Standard_Real aS2URes = ThePSurfaceTool::UResolution(PSurf, 1.0),
-                aS2VRes = ThePSurfaceTool::VResolution(PSurf, 1.0);
-  if(ApproxU2V2)
-    myUVRes2 = aS2URes / aS2VRes;
+  const Standard_Boolean cut = myData.myBezierApprox;
+  const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
 
   // Fill data structure.
-  fillData(theline, ApproxXYZ, ApproxU1V1, ApproxU2V2);
+  fillData(theline);
 
   // Build knots.
-  Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
   buildKnots(theline, ptrsvsurf);
 
-  if(myRelativeTol==Standard_False)
-  {
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d*myData.myMinFactorXYZ,
-      myTol2d*myData.myMinFactorUV,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-  }
-  else
-  {
-    myComputeLine.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-    myComputeLineBezier.Init(myDegMin,
-      myDegMax,
-      myTol3d,
-      myTol2d,
-      myNbIterMax,
-      cut,
-      myData.parametrization);
-  }
+  myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, cut, myData.parametrization);
+  myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, cut, myData.parametrization);
 
   buildCurve(theline, ptrsvsurf);
 }
 
 //=======================================================================
+//function : SetParameters
+//purpose  : 
+//=======================================================================
+void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d,
+                                      const Standard_Real Tol2d,
+                                      const Standard_Integer DegMin,
+                                      const Standard_Integer DegMax,
+                                      const Standard_Integer NbIterMax,
+                                      const Standard_Integer NbPntMax,
+                                      const Standard_Boolean ApproxWithTangency,
+                                      const Approx_ParametrizationType Parametrization)
+{
+  myData.myNbPntMax = NbPntMax;
+  myWithTangency = ApproxWithTangency;
+  myTol3d        = Tol3d/RatioTol;
+  myTol2d        = Tol2d/RatioTol;
+  myDegMin       = DegMin;
+  myDegMax       = DegMax;
+  myNbIterMax    = NbIterMax;
+
+  myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, Standard_True, Parametrization);
+  myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
+                            myNbIterMax, Standard_True, Parametrization);
+
+  if(!ApproxWithTangency)
+  { 
+    myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
+    myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
+  }
+  
+  myData.myBezierApprox = Standard_True;
+}
+
+//=======================================================================
 //function : NbMultiCurves
 //purpose  :
 //=======================================================================
@@ -683,9 +434,8 @@ void ApproxInt_Approx::UpdateTolReached()
 {
   if (myData.myBezierApprox)
   {
-    Standard_Integer ICur;
-    Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves();
-    for (ICur = 1 ; ICur <= NbCurves ; ICur++)
+    const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
+    for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++)
     {
       Standard_Real Tol3D, Tol2D ;
       myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
@@ -705,13 +455,7 @@ void ApproxInt_Approx::UpdateTolReached()
 //=======================================================================
 Standard_Real ApproxInt_Approx::TolReached3d() const
 {
-  Standard_Real TheTol3D = RatioTol * myTolReached3d ;
-
-  if (myData.myMinFactorXYZ>1.5e-7)
-    TheTol3D = TheTol3D / myData.myMinFactorXYZ;
-
-  //cout << "Tol 3D: " << TheTol3D << endl;
-  return TheTol3D ;
+  return myTolReached3d * RatioTol;
 }
 
 //=======================================================================
@@ -720,13 +464,7 @@ Standard_Real ApproxInt_Approx::TolReached3d() const
 //=======================================================================
 Standard_Real ApproxInt_Approx::TolReached2d() const
 {
-  Standard_Real TheTol2D = RatioTol * myTolReached2d ;
-
-  if (myData.myMinFactorUV>1.5e-7)
-    TheTol2D = TheTol2D / myData.myMinFactorUV;
-
-  //cout << "Tol 2D: " << TheTol2D << endl;
-  return TheTol2D ;
+  return myTolReached2d * RatioTol;
 }
 
 //=======================================================================
@@ -738,11 +476,6 @@ Standard_Boolean ApproxInt_Approx::IsDone() const
   if(myData.myBezierApprox)
   { 
     return(myComputeLineBezier.NbMultiCurves() > 0);
-    //-- Lorsque la tolerance n est pas atteinte et qu il 
-    //-- faudrait rajouter des points sur la ligne
-    //-- les approx sortent avec la meilleure tolerance
-    //-- atteinte.  ( Pas de rajout de points ds cette version)
-    //-- return(myTolReached);
   }
   else
   {
@@ -757,11 +490,11 @@ Standard_Boolean ApproxInt_Approx::IsDone() const
 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const
 {
   if(myData.myBezierApprox)
-  {
+  { 
     return(myBezToBSpl.Value());
   }
   else
-  {
+  { 
     return(myComputeLine.Value());
   }
 }
@@ -770,52 +503,22 @@ const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer
 //function : fillData
 //purpose  : Fill ApproxInt data structure.
 //=======================================================================
-void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline,
-                                const Standard_Boolean ApproxXYZ,
-                                const Standard_Boolean ApproxU1V1,
-                                const Standard_Boolean ApproxU2V2)
+void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline)
 {
-  if(ApproxXYZ)
-  {
-    ComputeTrsf3d(theline, myData.Xo, myData.Ax, myData.Yo, myData.Ay, myData.Zo, myData.Az);
-  }
+  if(myData.ApproxXYZ)
+    ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo);
   else
-  {
     myData.Xo = myData.Yo = myData.Zo = 0.0;
-    myData.Ax = myData.Ay = myData.Az = 1.0;
-  }
 
-  if(ApproxU1V1)
-  {
-    ComputeTrsf2d(theline, myData.U1o, myData.A1u, myData.V1o, myData.A1v,Standard_True, myUVRes1);
-  }
+  if(myData.ApproxU1V1)
+    ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o);
   else
-  {
     myData.U1o = myData.V1o = 0.0;
-    myData.A1u = myData.A1v = 1.0;
-  }
 
-  if(ApproxU2V2)
-  {
-    ComputeTrsf2d(theline, myData.U2o, myData.A2u, myData.V2o, myData.A2v, Standard_False, myUVRes2);
-  }
+  if(myData.ApproxU2V2)
+    ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o);
   else
-  {
     myData.U2o = myData.V2o = 0.0;
-    myData.A2u = myData.A2v = 1.0;
-  }
-
-  Standard_Real A3d = MINABS3(myData.Ax, myData.Ay, myData.Az);
-  if((A3d < myData.myMinFactorXYZ) || (myData.myMinFactorXYZ == 0.0))
-  {
-    myData.myMinFactorXYZ = A3d;
-  }
-
-  Standard_Real A2d = MINABS4(myData.A1u, myData.A1v, myData.A2u, myData.A2v);
-  if((A2d < myData.myMinFactorUV) || (myData.myMinFactorUV == 0.0))
-  {
-    myData.myMinFactorUV = A2d;
-  }
 }
 
 //=======================================================================
@@ -828,20 +531,13 @@ void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ,
                                  const Standard_Integer theIndicemin,
                                  const Standard_Integer theIndicemax)
 {
-  myData.myMinFactorXYZ = 0.0;
-  myData.myMinFactorUV  = 0.0;
   myTolReached3d = myTolReached2d = 0.0;
-  myUVRes1 = myUVRes2 = 1.0;
   myData.ApproxU1V1 = theApproxU1V1;
   myData.ApproxU2V2 = theApproxU2V2;
   myData.ApproxXYZ = theApproxXYZ;
   myData.indicemin = theIndicemin;
   myData.indicemax = theIndicemax;
-  myData.nbpntmax = myNbPntMax;
-
-  Approx_ParametrizationType parametrization;
-  myComputeLineBezier.Parametrization(parametrization);
-  myData.parametrization = parametrization;
+  myData.parametrization = myComputeLineBezier.Parametrization();
 }
 
 //=======================================================================
@@ -852,71 +548,66 @@ void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline,
                                   const Standard_Address thePtrSVSurf)
 {
   myKnots.Clear();
-  if(myData.myBezierApprox)
+  if(!myData.myBezierApprox)
   {
-    ApproxInt_TheMultiLine aTestLine(theline,
-      thePtrSVSurf,
-      ((myData.ApproxXYZ)? 1 : 0),
-      ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
-      myData.Xo, myData.Ax, myData.Yo, myData.Ay, myData.Zo, myData.Az,
-      myData.U1o, myData.A1u, 
-      myData.V1o, myData.A1v,
-      myData.U2o, myData.A2u,
-      myData.V2o ,myData.A2v,
-      myData.ApproxU1V1,
-      myData.indicemin,
-      myData.indicemax);
-
-    Standard_Integer nbp3d = aTestLine.NbP3d();
-    Standard_Integer nbp2d = aTestLine.NbP2d();
-    TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d));
-    TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d));
-    TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax);
-    TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax);
-    TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax);
-    Standard_Integer i;
-    for(i = myData.indicemin; i <= myData.indicemax; ++i)
+    myKnots.Append(myData.indicemin);
+    myKnots.Append(myData.indicemax);
+    return;
+  }
+
+  const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf,
+                                          ((myData.ApproxXYZ)? 1 : 0),
+                                          ((myData.ApproxU1V1)? 1: 0) +
+                                                ((myData.ApproxU2V2)? 1: 0),
+                                          myData.Xo, myData.Yo, myData.Zo,
+                                          myData.U1o, myData.V1o, myData.U2o, myData.V2o,
+                                          myData.ApproxU1V1,
+                                          myData.indicemin, myData.indicemax);
+
+  const Standard_Integer  nbp3d = aTestLine.NbP3d(),
+                          nbp2d = aTestLine.NbP2d();
+  TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d));
+  TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d));
+  TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax);
+  TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax);
+  TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax);
+
+  for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i)
+  {
+    if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d);
+    else if (nbp2d != 0)          aTestLine.Value(i, aTabPnt2d);
+    else if (nbp3d != 0)          aTestLine.Value(i, aTabPnt3d);
+    //
+    if(nbp3d > 0)
     {
-      if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d);
-      else if (nbp2d != 0)          aTestLine.Value(i, aTabPnt2d);
-      else if (nbp3d != 0)          aTestLine.Value(i, aTabPnt3d);
-      //
-      if(nbp3d > 0)
-      {
-        aPntXYZ(i) = aTabPnt3d(1);
-      }
-      if(nbp2d > 1)
+      aPntXYZ(i) = aTabPnt3d(1);
+    }
+    if(nbp2d > 1)
+    {
+      aPntU1V1(i) = aTabPnt2d(1);
+      aPntU2V2(i) = aTabPnt2d(2);
+    }
+    else if(nbp2d > 0)
+    {
+      if(myData.ApproxU1V1)
       {
         aPntU1V1(i) = aTabPnt2d(1);
-        aPntU2V2(i) = aTabPnt2d(2);
       }
-      else if(nbp2d > 0)
+      else
       {
-        if(myData.ApproxU1V1)
-        {
-          aPntU1V1(i) = aTabPnt2d(1);
-        }
-        else
-        {
-          aPntU2V2(i) = aTabPnt2d(1);
-        }
+        aPntU2V2(i) = aTabPnt2d(1);
       }
     }
+  }
 
-    Standard_Integer aMinNbPnts = myData.nbpntmax;
+  Standard_Integer aMinNbPnts = myData.myNbPntMax;
 
-    // Expected parametrization.
-    math_Vector aPars(myData.indicemin, myData.indicemax);
-    Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars);
+  // Expected parametrization.
+  math_Vector aPars(myData.indicemin, myData.indicemax);
+  Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars);
 
-    ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars,
-      myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots);
-  }
-  else
-  {
-    myKnots.Append(myData.indicemin);
-    myKnots.Append(myData.indicemax);
-  }
+  ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars,
+    myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots);
 }
 
 //=======================================================================
@@ -932,93 +623,74 @@ void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline,
   }
 
   Standard_Integer kind = myKnots.Lower();
-  Standard_Integer imin, imax;
-  myTolReached = Standard_True;
+  Standard_Integer imin = 0, imax = 0;
   Standard_Boolean OtherInter = Standard_False;
   do
   {
     // Base cycle: iterate over knots.
     imin = myKnots(kind);
     imax = myKnots(kind+1);
-    ApproxInt_TheMultiLine myMultiLine(theline,
-      thePtrSVSurf,
+    ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf,
       ((myData.ApproxXYZ)? 1 : 0),
       ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
-      myData.Xo, myData.Ax, myData.Yo,myData.Ay, myData.Zo,myData.Az,
-      myData.U1o, myData.A1u, myData.V1o, myData.A1v,
-      myData.U2o, myData.A2u, myData.V2o, myData.A2v,
-      myData.ApproxU1V1,
-      imin,
-      imax);
+      myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
+      myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
 
     if(myData.myBezierApprox)
     {
       myComputeLineBezier.Perform(myMultiLine);
       if (myComputeLineBezier.NbMultiCurves() == 0)
         return;
-      myTolReached&=myComputeLineBezier.IsToleranceReached();
     }
     else
     {
       myComputeLine.Perform(myMultiLine);
     }
+
     UpdateTolReached();
 
-    Standard_Integer indice3d,indice2d1,indice2d2;
-    indice3d = 1; 
-    indice2d1= 2;
-    indice2d2= 3;
+    Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3;
     if(!myData.ApproxXYZ)  { indice2d1--; indice2d2--; } 
     if(!myData.ApproxU1V1) { indice2d2--; } 
     if(myData.ApproxXYZ)
     { 
-      Standard_Real ax,bx,ay,by,az,bz;
-      ax = 1.0/myData.Ax;   bx = -myData.Xo*ax;
-      ay = 1.0/myData.Ay;   by = -myData.Yo*ay;
-      az = 1.0/myData.Az;   bz = -myData.Zo*az;
       if(myData.myBezierApprox)
       {
         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
         {
-          myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d,bx,ax,by,ay,bz,az);
+          myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
         }
       }
       else
       {
-        myComputeLine.ChangeValue().Transform(indice3d,bx,ax,by,ay,bz,az);
+        myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
       }
     }
     if(myData.ApproxU1V1)
     {
-      Standard_Real ax,bx,ay,by;
-      ax = 1.0/myData.A1u;   bx = -myData.U1o*ax;
-      ay = 1.0/myData.A1v;   by = -myData.V1o*ay;
       if(myData.myBezierApprox) {
         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
         {
-          myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1,bx,ax,by,ay);
+          myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
         }
       }
       else
       {
-        myComputeLine.ChangeValue().Transform2d(indice2d1,bx,ax,by,ay);
+        myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
       }
     }
     if(myData.ApproxU2V2)
     {
-      Standard_Real ax,bx,ay,by;
-      ax = 1.0/myData.A2u;   bx = -myData.U2o*ax;
-      ay = 1.0/myData.A2v;   by = -myData.V2o*ay;
       if(myData.myBezierApprox)
       {
         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
         {
-          myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2,bx,ax,by,ay);
+          myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
         }
       }
       else
       {
-        myComputeLine.ChangeValue().Transform2d(indice2d2,bx,ax,by,ay);
+        myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
       }
     }
 
index d7e06fb..74eb09d 100644 (file)
 #include <GeomAbs_SurfaceType.hxx>
 #include <Precision.hxx>
 
-#define       ComputeParametersOnImplicitSurface(MyISurf,P,u,v)  MyISurf.Parameters(P,u,v)
+//=======================================================================
+//function : IsSingular
+//purpose  :    Returns TRUE if vectors theDU || theDV or if at least one
+//            of them has null-magnitude.
+//              theSqLinTol is square of linear tolerance.
+//              theAngTol is angular tolerance.
+//=======================================================================
+static Standard_Boolean IsSingular( const gp_Vec& theDU,
+                                    const gp_Vec& theDV,
+                                    const Standard_Real theSqLinTol,
+                                    const Standard_Real theAngTol)
+{
+  gp_Vec aDU(theDU), aDV(theDV);
 
-#define Debug(expr)  cout<<" expr :"<<expr;
-#define MyISurf MyZerImpFunc.ISurface()
-#define MyPSurf MyZerImpFunc.PSurface()
+  const Standard_Real aSqMagnDU = aDU.SquareMagnitude(),
+                      aSqMagnDV = aDV.SquareMagnitude();
+
+  if(aSqMagnDU < theSqLinTol)
+    return Standard_True;
+
+  aDU.Divide(sqrt(aSqMagnDU));
+
+  if(aSqMagnDV < theSqLinTol)
+    return Standard_True;
+
+  aDV.Divide(sqrt(aSqMagnDV));
+
+  //Here aDU and aDV vectors have magnitude 1.0.
+
+  if(aDU.Crossed(aDV).SquareMagnitude() < theAngTol*theAngTol)
+    return Standard_True;
+
+  return Standard_False;
+}
+
+//=======================================================================
+//function : SingularProcessing
+//purpose  :    Computes 2D-representation (in UV-coordinates) of 
+//            theTg3D vector on the surface in case when
+//            theDU.Crossed(theDV).Magnitude() == 0.0. Stores result in
+//            theTg2D variable.
+//              theDU and theDV are vectors of 1st derivative
+//            (with respect to U and V variables correspondingly).
+//              If theIsTo3DTgCompute == TRUE then theTg3D has not been 
+//            defined yet (it should be computed).
+//              theLinTol is SQUARE of the tolerance.
+//
+//Algorithm:
+//              Condition
+//                  Tg=theDU*theTg2D.X()+theDV*theTg2D.Y()  
+//            has to be satisfied strictly.
+//              More over, vector Tg has to be NORMALYZED
+//            (if theIsTo3DTgCompute == TRUE then new computed vector will
+//            always have magnitude 1.0).
+//=======================================================================
+static Standard_Boolean SingularProcessing( const gp_Vec& theDU,
+                                            const gp_Vec& theDV,
+                                            const Standard_Boolean theIsTo3DTgCompute,
+                                            const Standard_Real theLinTol,
+                                            const Standard_Real theAngTol,
+                                            gp_Vec& theTg3D,
+                                            gp_Vec2d& theTg2D)
+{
+  //Attention: @ \sin theAngTol \approx theAngTol @ (for cross-product)
+
+  //Really, vector theTg3D has to be normalyzed (if theIsTo3DTgCompute == FALSE).
+  const Standard_Real aSQTan = theTg3D.SquareMagnitude();
+
+  const Standard_Real aSqMagnDU = theDU.SquareMagnitude(),
+                      aSqMagnDV = theDV.SquareMagnitude();
+
+  //There are some reasons of singularity
+
+  //1.
+  if((aSqMagnDU < theLinTol) && (aSqMagnDV < theLinTol))
+  {
+    //For future, this case can be processed as same as in case of 
+    //osculating surfaces (expanding in Taylor series). Here,
+    //we return only.
+
+    return Standard_False;
+  }
+
+  //2.
+  if(aSqMagnDU < theLinTol)
+  {
+    //In this case, theTg3D vector will be parallel with theDV.
+    //Its true direction shall be precised later (the algorithm is
+    //based on array of Walking-points).
+    
+    if(theIsTo3DTgCompute)
+    {
+      //theTg3D will be normalyzed. Its magnitude is
+      const Standard_Real aTgMagn = 1.0;
+
+      const Standard_Real aNorm = sqrt(aSqMagnDV);
+      theTg3D = theDV.Divided(aNorm);
+      theTg2D.SetCoord(0.0, aTgMagn/aNorm);
+    }
+    else
+    {
+      //theTg3D is already defined.
+      //Here we check only, if this tangent is parallel to theDV.
+
+      if(theDV.Crossed(theTg3D).SquareMagnitude() < 
+                    theAngTol*theAngTol*aSqMagnDV*aSQTan)
+      {
+        //theTg3D is parallel to theDV
+        
+        //Use sign "+" if theTg3D and theDV are codirectional
+        //and sign "-" if opposite
+        const Standard_Real aDP = theTg3D.Dot(theDV);
+        theTg2D.SetCoord(0.0, Sign(sqrt(aSQTan/aSqMagnDV), aDP));
+      }
+      else
+      {
+        //theTg3D is not parallel to theDV
+        //It is abnormal
+
+        return Standard_False;
+      }
+    }
+
+    return Standard_True;
+  }
+
+  //3.
+  if(aSqMagnDV < theLinTol)
+  {
+    //In this case, theTg3D vector will be parallel with theDU.
+    //Its true direction shall be precised later (the algorithm is
+    //based on array of Walking-points).
+    
+    if(theIsTo3DTgCompute)
+    {
+      //theTg3D will be normalyzed. Its magnitude is
+      const Standard_Real aTgMagn = 1.0;
+
+      const Standard_Real aNorm = sqrt(aSqMagnDU);
+      theTg3D = theDU.Divided(aNorm);
+      theTg2D.SetCoord(aTgMagn/aNorm, 0.0);
+    }
+    else
+    {
+      //theTg3D is already defined.
+      //Here we check only, if this tangent is parallel to theDU.
+
+      if(theDU.Crossed(theTg3D).SquareMagnitude() < 
+                    theAngTol*theAngTol*aSqMagnDU*aSQTan)
+      {
+        //theTg3D is parallel to theDU
+
+        //Use sign "+" if theTg3D and theDU are codirectional
+        //and sign "-" if opposite
+        const Standard_Real aDP = theTg3D.Dot(theDU);
+        theTg2D.SetCoord(Sign(sqrt(aSQTan/aSqMagnDU), aDP), 0.0);
+      }
+      else
+      {
+        //theTg3D is not parallel to theDU
+        //It is abnormal
+
+        return Standard_False;
+      }
+    }
+
+    return Standard_True;
+  }
+
+  //4. If aSqMagnDU > 0.0 && aSqMagnDV > 0.0 but theDV || theDU.
+
+  const Standard_Real aLenU = sqrt(aSqMagnDU),
+                      aLenV = sqrt(aSqMagnDV);
+
+  //aLenSum > 0.0 definitely
+  const Standard_Real aLenSum = aLenU + aLenV;
+
+  if(theDV.Dot(theDU) > 0.0)
+  {
+    //Vectors theDV and theDU are codirectional.
+
+    if(theIsTo3DTgCompute)
+    {
+      theTg2D.SetCoord(1.0/aLenSum, 1.0/aLenSum);
+      theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y();
+    }
+    else
+    {
+      //theTg3D is already defined.
+      //Here we check only, if this tangent is parallel to theDU
+      //(and theDV together).
+
+      if(theDU.Crossed(theTg3D).SquareMagnitude() < 
+                    theAngTol*theAngTol*aSqMagnDU*aSQTan)
+      {
+        //theTg3D is parallel to theDU
+
+        const Standard_Real aDP = theTg3D.Dot(theDU);
+        const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP);
+        theTg2D.SetCoord(aLenTg/aLenSum, aLenTg/aLenSum);
+      }
+      else
+      {
+        //theTg3D is not parallel to theDU
+        //It is abnormal
+
+        return Standard_False;
+      }
+    }
+  }
+  else
+  {
+    //Vectors theDV and theDU are opposite.
+
+    if(theIsTo3DTgCompute)
+    {
+      //Here we chose theDU as direction of theTg3D.
+      //True direction shall be precised later (the algorithm is
+      //based on array of Walking-points).
+
+      theTg2D.SetCoord(1.0/aLenSum, -1.0/aLenSum);
+      theTg3D = theDU*theTg2D.X() + theDV*theTg2D.Y();
+    }
+    else
+    {
+      //theTg3D is already defined.
+      //Here we check only, if this tangent is parallel to theDU
+      //(and theDV together).
+
+      if(theDU.Crossed(theTg3D).SquareMagnitude() < 
+                    theAngTol*theAngTol*aSqMagnDU*aSQTan)
+      {
+        //theTg3D is parallel to theDU
+
+        const Standard_Real aDP = theTg3D.Dot(theDU);
+        const Standard_Real aLenTg = Sign(sqrt(aSQTan), aDP);
+        theTg2D.SetCoord(aLenTg/aLenSum, -aLenTg/aLenSum);
+      }
+      else
+      {
+        //theTg3D is not parallel to theDU
+        //It is abnormal
+
+        return Standard_False;
+      }
+    }
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : NonSingularProcessing
+//purpose  :    Computes 2D-representation (in UV-coordinates) of 
+//            theTg3D vector on the surface in case when
+//            theDU.Crossed(theDV).Magnitude() > 0.0. Stores result in
+//            theTg2D variable.
+//              theDU and theDV are vectors of 1st derivative
+//            (with respect to U and V variables correspondingly).
+//              theLinTol is SQUARE of the tolerance.
+//
+//Algorithm:
+//              Condition
+//                  Tg=theDU*theTg2D.X()+theDV*theTg2D.Y()  
+//            has to be satisfied strictly.
+//              More over, vector Tg has always to be NORMALYZED.
+//=======================================================================
+static Standard_Boolean NonSingularProcessing(const gp_Vec& theDU,
+                                              const gp_Vec& theDV,
+                                              const gp_Vec& theTg3D,
+                                              const Standard_Real theLinTol,
+                                              const Standard_Real theAngTol,
+                                              gp_Vec2d& theTg2D)
+{
+  const gp_Vec aNormal = theDU.Crossed(theDV);
+  const Standard_Real aSQMagn = aNormal.SquareMagnitude();
+
+  if(IsSingular(theDU, theDV, theLinTol, theAngTol))
+  {
+    gp_Vec aTg(theTg3D);
+    return 
+      SingularProcessing(theDU, theDV, Standard_False,
+                          theLinTol, theAngTol, aTg, theTg2D);
+  }
+
+  //If @\vec{T}=\vec{A}*U+\vec{B}*V@ then 
+
+  //  \left\{\begin{matrix}
+  //  \vec{A} \times \vec{T} = (\vec{A} \times \vec{B})*V 
+  //  \vec{B} \times \vec{T} = (\vec{B} \times \vec{A})*U 
+  //  \end{matrix}\right.
+
+  //From here, values of U and V can be found very easily
+  //(if @\left \| \vec{A} \times \vec{B} \right \| > 0.0 @,
+  //else it is singular case). 
+
+  const gp_Vec aTgU(theTg3D.Crossed(theDU)), aTgV(theTg3D.Crossed(theDV));
+  const Standard_Real aDeltaU = aTgV.SquareMagnitude()/aSQMagn;
+  const Standard_Real aDeltaV = aTgU.SquareMagnitude()/aSQMagn;
+
+  theTg2D.SetCoord(Sign(sqrt(aDeltaU), aTgV.Dot(aNormal)), -Sign(sqrt(aDeltaV), aTgU.Dot(aNormal)));
+
+  return Standard_True;
+}
 
 //--------------------------------------------------------------------------------
 ApproxInt_ImpPrmSvSurfaces::ApproxInt_ImpPrmSvSurfaces( const TheISurface& ISurf
@@ -111,16 +410,31 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::TangencyOnSurf2(const Standard_Real
   T=MyTguv2;
   return(t);
 }
-//--------------------------------------------------------------------------------
-Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
-                                                    ,Standard_Real& v1
-                                                    ,Standard_Real& u2
-                                                    ,Standard_Real& v2
-                                                    ,gp_Pnt& P
-                                                    ,gp_Vec& Tg
-                                                    ,gp_Vec2d& Tguv1
-                                                    ,gp_Vec2d& Tguv2) { 
-  
+
+//=======================================================================
+//function : Compute
+//purpose  :    Computes point on curve, 3D and 2D-tangents of a curve and
+//            parameters on the surfaces.
+//=======================================================================
+Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1,
+                                                      Standard_Real& v1,
+                                                      Standard_Real& u2,
+                                                      Standard_Real& v2,
+                                                      gp_Pnt& P,
+                                                      gp_Vec& Tg,
+                                                      gp_Vec2d& Tguv1,
+                                                      gp_Vec2d& Tguv2)
+{ 
+  const IntSurf_Quadric&  aQSurf = MyZerImpFunc.ISurface();
+  const ThePSurface&      aPSurf = MyZerImpFunc.PSurface();
+  gp_Vec2d& aQuadTg = MyImplicitFirst ? Tguv1 : Tguv2;
+  gp_Vec2d& aPrmTg = MyImplicitFirst ? Tguv2 : Tguv1;
+
+  //for square
+  const Standard_Real aNullValue =  Precision::Approximation()*
+                                    Precision::Approximation(),
+                      anAngTol = Precision::Angular();
+
   Standard_Real tu1=u1;
   Standard_Real tu2=u2;
   Standard_Real tv1=v1;
@@ -175,7 +489,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
     }
   }
 
-
   Standard_Real aBornInf[2],aBornSup[2],aF[1],aX[2],aTolerance[2];
   math_Vector BornInf(aBornInf,1,2),BornSup(aBornSup,1,2),F(aF,1,1),
     X(aX,1,2),Tolerance(aTolerance,1,2);
@@ -183,14 +496,14 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
   math_Matrix D(aD,1, 1, 1, 2); 
 
   Standard_Real binfu,bsupu,binfv,bsupv;
-  binfu = ThePSurfaceTool::FirstUParameter(MyPSurf);
-  binfv = ThePSurfaceTool::FirstVParameter(MyPSurf);
-  bsupu = ThePSurfaceTool::LastUParameter(MyPSurf);
-  bsupv = ThePSurfaceTool::LastVParameter(MyPSurf);
+  binfu = ThePSurfaceTool::FirstUParameter(aPSurf);
+  binfv = ThePSurfaceTool::FirstVParameter(aPSurf);
+  bsupu = ThePSurfaceTool::LastUParameter(aPSurf);
+  bsupv = ThePSurfaceTool::LastVParameter(aPSurf);
   BornInf(1) = binfu; BornSup(1) = bsupu; 
   BornInf(2) = binfv; BornSup(2) = bsupv;
 
-  //--- ThePSurfaceTool::GetResolution(MyPSurf,Tolerance(1),Tolerance(2));
+  //--- ThePSurfaceTool::GetResolution(aPSurf,Tolerance(1),Tolerance(2));
   Tolerance(1) = 1.0e-8; Tolerance(2) = 1.0e-8;
 
   Standard_Real TranslationU=0.0;
@@ -200,8 +513,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
   Rsnld.SetTolerance(Tolerance);
   if(MyImplicitFirst) { 
     if(u2<binfu-0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
        do {  TranslationU+=d; } while(u2+TranslationU < binfu);
       }
       else { 
@@ -211,8 +524,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       }
     }
     else if(u2>bsupu+0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
        do { TranslationU-=d; } while(u2+TranslationU > bsupu);
       }
       else { 
@@ -222,8 +535,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       } 
     }
     if(v2<binfv-0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
        do { TranslationV+=d; } while(v2+TranslationV < binfv);
       }
       else { 
@@ -233,8 +546,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       }
     }
     else if(v2>bsupv+0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
        do { TranslationV-=d; } while(v2+TranslationV > bsupv);
       }
       else { 
@@ -248,8 +561,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
   }
   else { 
     if(u1<binfu-0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
        do {  TranslationU+=d;  } while(u1+TranslationU < binfu);
       }
       else { 
@@ -259,8 +572,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       }
     }
     else if(u1>bsupu+0.0000000001) { 
-      if(ThePSurfaceTool::IsUPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::UPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsUPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::UPeriod(aPSurf);
        do { TranslationU-=d; } while(u1+TranslationU > bsupu);
       }
       else { 
@@ -270,8 +583,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       } 
     }
     if(v1<binfv-0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
        do { TranslationV+=d; } while(v1+TranslationV < binfv);
       }
       else { 
@@ -281,8 +594,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
       }
     }
     else if(v1>bsupv+0.0000000001) { 
-      if(ThePSurfaceTool::IsVPeriodic(MyPSurf)) { 
-       Standard_Real d = ThePSurfaceTool::VPeriod(MyPSurf);
+      if(ThePSurfaceTool::IsVPeriodic(aPSurf)) { 
+       Standard_Real d = ThePSurfaceTool::VPeriod(aPSurf);
        do { TranslationV-=d; } while(v1+TranslationV > bsupv);
       }
       else { 
@@ -296,9 +609,8 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
   }
   
   //----------------------------------------------------
-  //-- Pour eviter de coller le point de depart de la 
-  //-- recherche sur une des bornes (Rsnld -> NotDone)
-  //-- 
+  //Make a small step from boundaries in order to avoid
+  //finding "outboundaried" solution (Rsnld -> NotDone).
   if(X(1)-0.0000000001 <= binfu) X(1)=X(1)+0.0000001;
   if(X(1)+0.0000000001 >= bsupu) X(1)=X(1)-0.0000001;
   if(X(2)-0.0000000001 <= binfv) X(2)=X(2)+0.0000001;
@@ -308,15 +620,6 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
   Standard_Real PourTesterU = X(1);
   Standard_Real PourTesterV = X(2);
   
-
-  /* ***************************************************************
-  cout<<" Envoi a Rsnld : "; Debug(X(1)); Debug(X(2)); 
-  Debug(BornInf(1)); Debug(BornInf(2));
-  Debug(BornSup(1)); Debug(BornSup(2)); cout<<endl;
-  Debug(u1); Debug(v1); Debug(u2); Debug(v2); Debug(MyImplicitFirst); 
-  cout<<endl;
-  **************************************************************** */
-
   Rsnld.Perform(MyZerImpFunc,X,BornInf,BornSup);
   if(Rsnld.IsDone()) { 
     MyHasBeenComputed = Standard_True;
@@ -324,120 +627,202 @@ Standard_Boolean ApproxInt_ImpPrmSvSurfaces::Compute( Standard_Real& u1
     
     Standard_Real DistAvantApresU = Abs(PourTesterU-X(1));
     Standard_Real DistAvantApresV = Abs(PourTesterV-X(2));
-    MyPnt = P = ThePSurfaceTool::Value(MyPSurf,X(1),X(2));
     
-    if(   (DistAvantApresV <= 0.001 )
-       && (DistAvantApresU <= 0.001 )) { 
-      
-      gp_Vec PD1U,PD1V;
-      gp_Vec ID1U,ID1V;
-      
-      
-      if(MyImplicitFirst) { 
-       u2 = X(1)-TranslationU; 
-       v2 = X(2)-TranslationV;
-       ComputeParametersOnImplicitSurface(MyISurf,P,u1,v1);
-       if(MyISurf.TypeQuadric() != GeomAbs_Plane) { 
-         while(u1-tu1>M_PI)  u1-=M_PI+M_PI;
-         while(tu1-u1>M_PI)  u1+=M_PI+M_PI;
-       }
-       MyParOnS1.SetCoord(tu1,tv1);
-       MyParOnS2.SetCoord(tu2,tv2);
-       ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
-       MyISurf.D1(u1,v1,P,ID1U,ID1V);
+    MyPnt = P = ThePSurfaceTool::Value(aPSurf, X(1), X(2));
+    
+    if( (DistAvantApresV <= 0.001 ) &&
+        (DistAvantApresU <= 0.001 ))
+    {
+      gp_Vec aD1uPrm,aD1vPrm;
+      gp_Vec aD1uQuad,aD1vQuad;
+
+      if(MyImplicitFirst)
+      { 
+        u2 = X(1)-TranslationU;
+        v2 = X(2)-TranslationV;
+
+        if(aQSurf.TypeQuadric() != GeomAbs_Plane)
+        { 
+          while(u1-tu1>M_PI)  u1-=M_PI+M_PI;
+          while(tu1-u1>M_PI)  u1+=M_PI+M_PI;
+        }
+
+        MyParOnS1.SetCoord(tu1,tv1);
+        MyParOnS2.SetCoord(tu2,tv2);
+
+        gp_Pnt aP2;
+
+        ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm);
+        aQSurf.D1(u1,v1, aP2, aD1uQuad, aD1vQuad);
+
+        //Middle-point of P-P2 segment
+        P.BaryCenter(1.0, aP2, 1.0);
       }
-      else { 
-       u1 = X(1)-TranslationU;
-       v1 = X(2)-TranslationV;
-       ComputeParametersOnImplicitSurface(MyISurf,P,u2,v2);
-       if(MyISurf.TypeQuadric() != GeomAbs_Plane) { 
-         while(u2-tu2>M_PI)  u2-=M_PI+M_PI;
-         while(tu2-u2>M_PI)  u2+=M_PI+M_PI;
-       }
-       MyParOnS1.SetCoord(tu1,tv1);
-       MyParOnS2.SetCoord(tu2,tu2);
-       ThePSurfaceTool::D1(MyPSurf,X(1),X(2),P,PD1U,PD1V);
-       MyISurf.D1(u2,v2,P,ID1U,ID1V);
+      else
+      {
+        u1 = X(1)-TranslationU;
+        v1 = X(2)-TranslationV;
+        //aQSurf.Parameters(P, u2, v2);
+        if(aQSurf.TypeQuadric() != GeomAbs_Plane)
+        {
+          while(u2-tu2>M_PI)  u2-=M_PI+M_PI;
+          while(tu2-u2>M_PI)  u2+=M_PI+M_PI;
+        }
+
+        MyParOnS1.SetCoord(tu1,tv1);
+        MyParOnS2.SetCoord(tu2,tu2);
+
+        gp_Pnt aP2;
+        ThePSurfaceTool::D1(aPSurf, X(1), X(2), P, aD1uPrm, aD1vPrm);
+
+        aQSurf.D1(u2, v2, aP2, aD1uQuad, aD1vQuad);
+
+        //Middle-point of P-P2 segment
+        P.BaryCenter(1.0, aP2, 1.0);
       }
-      
-      
-      gp_Vec VNormaleImp = MyISurf.Normale(MyPnt);
-      gp_Vec VNormalePrm = PD1U.Crossed(PD1V);
-      if(   VNormaleImp.SquareMagnitude() <= gp::Resolution()
-        || VNormalePrm.SquareMagnitude() <= gp::Resolution()) { 
-       MyIsTangent = Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
+
+      MyPnt = P;
+
+      //Normals to the surfaces
+      gp_Vec  aNormalPrm(aD1uPrm.Crossed(aD1vPrm)), 
+              aNormalImp(aQSurf.Normale(MyPnt));
+
+      const Standard_Real aSQMagnPrm = aNormalPrm.SquareMagnitude(),
+                          aSQMagnImp = aNormalImp.SquareMagnitude();
+
+      Standard_Boolean  isPrmSingular = Standard_False,
+                        isImpSingular = Standard_False;
+
+      if(IsSingular(aD1uPrm, aD1vPrm, aNullValue, anAngTol))
+      {
+        isPrmSingular = Standard_True;
+        if(!SingularProcessing(aD1uPrm, aD1vPrm, Standard_True,
+                                aNullValue, anAngTol, Tg, aPrmTg))
+        {
+          MyIsTangent = Standard_False;
+          MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+          return Standard_False;
+        }
+
+        MyTg = Tg;
       }
-      
-      gp_Dir NormaleImp(VNormaleImp);
-      gp_Dir NormalePrm(VNormalePrm);
-      
-      gp_Vec VNImp(NormaleImp);
-      gp_Vec VNPrm(NormalePrm);
-      MyTg = VNImp.Crossed(VNPrm);
-      Standard_Real NmyTg = MyTg.Magnitude();
-      if(NmyTg < 0.000001) { 
-       MyIsTangent = Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
+      else
+      {
+        aNormalPrm.Divide(sqrt(aSQMagnPrm));
       }
-      MyTg.SetCoord(MyTg.X()/NmyTg,MyTg.Y()/NmyTg,MyTg.Z()/NmyTg);
-      
-      
-      MyTg              = NormaleImp.Crossed(NormalePrm);
-      Tg = MyTg;
-      
-      Standard_Real TUTV,TgTU,TgTV,TUTU,TVTV,DIS;
-      Standard_Real DeltaU,DeltaV;
-      TUTU = PD1U.Dot(PD1U);
-      TVTV = PD1V.Dot(PD1V);
-      TUTV = PD1U.Dot(PD1V);
-      TgTU = MyTg.Dot(PD1U);
-      TgTV = MyTg.Dot(PD1V);
-      DIS  = TUTU * TVTV - TUTV * TUTV;
-      
-      if(DIS<1e-10 && DIS>-1e-10) {
-       MyIsTangent = Standard_False;
-       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-       return(Standard_False);
+
+      //Analogicaly for implicit surface
+      if(aSQMagnImp < aNullValue)
+      {
+        isImpSingular = Standard_True;
+
+        if(!SingularProcessing(aD1uQuad, aD1vQuad, !isPrmSingular,
+                                  aNullValue, anAngTol, Tg, aQuadTg))
+        {
+          MyIsTangent = Standard_False;
+          MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+          return Standard_False;
+        }
+
+        MyTg = Tg;
+      }
+      else
+      {
+        aNormalImp.Divide(sqrt(aSQMagnImp));
       }
 
+      if(isImpSingular && isPrmSingular)
+      {
+        //All is OK. All abnormal cases were processed above.
 
-      DeltaU = (TgTU * TVTV - TgTV * TUTV ) / DIS ; 
-      DeltaV = (TgTV * TUTU - TgTU * TUTV ) / DIS ;
-      
-      if(MyImplicitFirst) { 
-       MyTguv1.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
-                        ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
-       MyTguv2.SetCoord(DeltaU,DeltaV);
-       Tguv1 = MyTguv1;
-       Tguv2 = MyTguv2;
+        MyTguv1 = Tguv1;
+        MyTguv2 = Tguv2;
+
+        MyIsTangent=Standard_True;
+        return MyIsTangent;
       }
-      else { 
-       MyTguv1.SetCoord(DeltaU,DeltaV);
-       MyTguv2.SetCoord( MyTg.Dot(ID1U)/(ID1U.Dot(ID1U))
-                        ,MyTg.Dot(ID1V)/(ID1V.Dot(ID1V)));
-       Tguv1 = MyTguv1;
-       Tguv2 = MyTguv2;
+      else if(!(isImpSingular || isPrmSingular))
+      {
+        //Processing pure non-singular case
+        //(3D- and 2D-tangents are still not defined)
+
+        //Ask to pay attention to the fact that here
+        //aNormalImp and aNormalPrm are normalyzed.
+        //Therefore, @ \left \| \vec{Tg} \right \| = 0.0 @
+        //if and only if (aNormalImp || aNormalPrm).
+        Tg = aNormalImp.Crossed(aNormalPrm);
+      }
+
+      const Standard_Real aSQMagnTg = Tg.SquareMagnitude();
+
+      if(aSQMagnTg < aNullValue)
+      {
+        MyIsTangent = Standard_False;
+        MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+        return Standard_False;
+      }
+
+      //Normalyze Tg vector
+      Tg.Divide(sqrt(aSQMagnTg));
+      MyTg = Tg;
+
+      if(!isPrmSingular)
+      {
+        //If isPrmSingular==TRUE then aPrmTg has already been computed.
+
+        if(!NonSingularProcessing(aD1uPrm, aD1vPrm, Tg, aNullValue, anAngTol, aPrmTg))
+        {
+          MyIsTangent = Standard_False;
+          MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+          return Standard_False;
+        }
+      }
+
+      if(!isImpSingular)
+      {
+        //If isImpSingular==TRUE then aQuadTg has already been computed.
+
+        if(!NonSingularProcessing(aD1uQuad, aD1vQuad, Tg, aNullValue, anAngTol, aQuadTg))
+        {
+          MyIsTangent = Standard_False;
+          MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
+          return Standard_False;
+        }
       }
+        
+      MyTguv1 = Tguv1;
+      MyTguv2 = Tguv2;
+
       MyIsTangent=Standard_True;
-      return(Standard_True); 
+
+#ifdef OCCT_DEBUG
+      //cout << "+++++++++++++++++  ApproxInt_ImpPrmSvSurfaces::Compute(...)  ++++++++++" << endl;
+      //printf( "P2d_1(%+10.20f, %+10.20f); P2d_2(%+10.20f, %+10.20f)\n"
+      //        "P(%+10.20f, %+10.20f, %+10.20f);\n"
+      //        "Tg = {%+10.20f, %+10.20f, %+10.20f};\n"
+      //        "Tguv1 = {%+10.20f, %+10.20f};\n"
+      //        "Tguv2 = {%+10.20f, %+10.20f}\n",
+      //        u1, v1, u2, v2,
+      //        P.X(), P.Y(), P.Z(),
+      //        Tg.X(), Tg.Y(), Tg.Z(),
+      //        Tguv1.X(), Tguv1.Y(), Tguv2.X(), Tguv2.Y());
+      //cout << "-----------------------------------------------------------------------" << endl;
+#endif
+
+      return Standard_True; 
     }
     else { 
-      
       //-- cout<<" ApproxInt_ImpImpSvSurfaces.gxx : Distance apres recadrage Trop Grande "<<endl;
     
       MyIsTangent=Standard_False;
       MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-      return(Standard_False);
+      return Standard_False;
     }
   }
   else { 
     MyIsTangent = Standard_False;
     MyHasBeenComputed = MyHasBeenComputedbis = Standard_False;
-    return(Standard_False);
+    return Standard_False;
   }
 }
 
index f5e7b07..93f0059 100644 (file)
@@ -195,25 +195,6 @@ void ApproxInt_KnotTools::ComputeKnotInds(const NCollection_LocalArray<Standard_
         aFeatureInds.Append(i);
       }
     }
-    else if(aCurv(i)*aCurv(i + 1) < 0.0)
-    {
-      if(Abs(aCurv(i)) < Abs(aCurv(i + 1)))
-      {
-        if(i != theInds.Last())
-        {
-          theInds.Append(i);
-          aFeatureInds.Append(i);
-        }
-      }
-      else
-      {
-        if(i+1 != theInds.Last())
-        {
-          theInds.Append(i + 1);
-          aFeatureInds.Append(i + 1);
-        }
-      }
-    }
   }
   if(aCurv.Upper() != theInds.Last())
   {
@@ -369,7 +350,7 @@ void ApproxInt_KnotTools::FilterKnots(NCollection_Sequence<Standard_Integer>& th
         Standard_Integer anIdx = i + 1;
         for( ; anIdx <= theInds.Length(); ++anIdx)
         {
-          if (theInds(anIdx) - anIndsPrev > theMinNbPnts)
+          if (theInds(anIdx) - anIndsPrev >= theMinNbPnts)
             break;
         }
         anIdx--;
@@ -379,10 +360,36 @@ void ApproxInt_KnotTools::FilterKnots(NCollection_Sequence<Standard_Integer>& th
             aMidIdx - theInds(anIdx)    < theMinNbPnts &&
             theInds(anIdx) - anIndsPrev >= aMinNbStep)
         {
-          // Bad distribution points merge into one knot interval.
-          theLKnots.Append(theInds(anIdx));
-          anIndsPrev = theInds(anIdx);
-          i = anIdx;
+          if (theInds(anIdx) - anIndsPrev > 2 * theMinNbPnts)
+          {
+            // Bad distribution points merge into one knot interval.
+            theLKnots.Append(anIndsPrev + theMinNbPnts);
+            anIndsPrev = anIndsPrev + theMinNbPnts;
+            i = anIdx - 1;
+          }
+          else
+          {
+            if (theInds(anIdx - 1) - anIndsPrev >= theMinNbPnts / 2)
+            {
+              // Bad distribution points merge into one knot interval.
+              theLKnots.Append(theInds(anIdx - 1));
+              anIndsPrev = theInds(anIdx - 1);
+              i = anIdx - 1;
+              if (theInds(anIdx) - theInds(anIdx - 1) <= theMinNbPnts / 2)
+              {
+                theLKnots.SetValue(theLKnots.Upper(), theInds(anIdx));
+                anIndsPrev = theInds(anIdx );
+                i = anIdx;
+              }
+            }
+            else
+            {
+              // Bad distribution points merge into one knot interval.
+              theLKnots.Append(theInds(anIdx));
+              anIndsPrev = theInds(anIdx);
+              i = anIdx;
+            }
+          }
         }
         else if (anIdx == theInds.Upper() && // Last point obtained.
                  theLKnots.Length() >= 2) // It is possible to modify last item.
index c6ee083..d6f2e64 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define DEBUG 0
-
-
 #include <TColStd_Array1OfReal.hxx>
-#include <IntSurf_LineOn2S.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Vec2d.hxx>
 #include <gp_Vec.hxx>
+#include <IntSurf_LineOn2S.hxx>
 
-ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine&    line,
-                                        const Standard_Address   svsurf,
-                                        const Standard_Integer   NbP3d,
-                                        const Standard_Integer   NbP2d,
-                                        const Standard_Real      xo,
-                                        const Standard_Real      ax,
-                                        const Standard_Real      yo,
-                                        const Standard_Real      ay,
-                                        const Standard_Real      zo,
-                                        const Standard_Real      az,
-                                        const Standard_Real      u1o,
-                                        const Standard_Real      a1u,
-                                        const Standard_Real      v1o,
-                                        const Standard_Real      a1v,
-                                        const Standard_Real      u2o,
-                                        const Standard_Real      a2u,
-                                        const Standard_Real      v2o,
-                                        const Standard_Real      a2v,
-                                        const Standard_Boolean   P2DOnFirst,
-                                        const Standard_Integer   IndMin,
-                                        const Standard_Integer   IndMax):
-
-       PtrOnmySvSurfaces(svsurf),
-       myLine(line), 
-       indicemin(IndMin),
-       indicemax(IndMax),
-       nbp3d(NbP3d),
-       nbp2d(NbP2d),
-       p2donfirst(P2DOnFirst),
-       Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
-       U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
-       U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
-{
-#if DEBUG 
-  if(indicemin>=indicemax) {
-    cout<<"\n********************************************";
-    cout<<"\n*****       ApproxInt_MultiLine     ********";
-    cout<<"\n***** indicemin = indicemax = "<<indicemin;
-    cout<<"\n********************************************"<<endl;
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+ApproxInt_MultiLine::
+  ApproxInt_MultiLine(const Handle_TheLine& line,
+                      const Standard_Address svsurf,
+                      const Standard_Integer NbP3d,
+                      const Standard_Integer NbP2d,
+                      const Standard_Real xo,
+                      const Standard_Real yo,
+                      const Standard_Real zo,
+                      const Standard_Real u1o,
+                      const Standard_Real v1o,
+                      const Standard_Real u2o,
+                      const Standard_Real v2o,
+                      const Standard_Boolean P2DOnFirst,
+                      const Standard_Integer IndMin,
+                      const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
+                                                      myLine(line),
+                                                      indicemin(Min(IndMin, IndMax)),
+                                                      indicemax(Max(IndMin, IndMax)),
+                                                      nbp3d(NbP3d), nbp2d(NbP2d),
+                                                      p2donfirst(P2DOnFirst),
+                                                      Xo(xo), Yo(yo), Zo(zo),
+                                                      U1o(u1o), V1o(v1o),
+                                                      U2o(u2o), V2o(v2o)
 
-  }
+{
+#if OCCT_DEBUG 
+  //if(indicemin == indicemax)
+  //{
+  //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
+  //}
 #endif
 }
-//--------------------------------------------------------------------------------
-ApproxInt_MultiLine::ApproxInt_MultiLine(const Handle_TheLine&    line,
-                                        const Standard_Integer   NbP3d,
-                                        const Standard_Integer   NbP2d,
-                                        const Standard_Real      xo,
-                                        const Standard_Real      ax,
-                                        const Standard_Real      yo,
-                                        const Standard_Real      ay,
-                                        const Standard_Real      zo,
-                                        const Standard_Real      az,
-                                        const Standard_Real      u1o,
-                                        const Standard_Real      a1u,
-                                        const Standard_Real      v1o,
-                                        const Standard_Real      a1v,
-                                        const Standard_Real      u2o,
-                                        const Standard_Real      a2u,
-                                        const Standard_Real      v2o,
-                                        const Standard_Real      a2v,
-                                        const Standard_Boolean   P2DOnFirst,
-                                        const Standard_Integer   IndMin,
-                                        const Standard_Integer   IndMax):
-
-       PtrOnmySvSurfaces(0),
-       myLine(line), 
-       indicemin(IndMin),
-       indicemax(IndMax),
-       nbp3d(NbP3d),
-       nbp2d(NbP2d),
-       p2donfirst(P2DOnFirst),
-       Xo(xo),Ax(ax),Yo(yo),Ay(ay),Zo(zo),Az(az),
-       U1o(u1o),A1u(a1u),V1o(v1o),A1v(a1v),
-       U2o(u2o),A2u(a2u),V2o(v2o),A2v(a2v)
+
+//=======================================================================
+//function : Constructor
+//purpose  : 
+//=======================================================================
+ApproxInt_MultiLine::
+  ApproxInt_MultiLine(const Handle_TheLine& line,
+                      const Standard_Integer NbP3d,
+                      const Standard_Integer NbP2d,
+                      const Standard_Real xo,
+                      const Standard_Real yo,
+                      const Standard_Real zo,
+                      const Standard_Real u1o,
+                      const Standard_Real v1o,
+                      const Standard_Real u2o,
+                      const Standard_Real v2o,
+                      const Standard_Boolean P2DOnFirst,
+                      const Standard_Integer IndMin,
+                      const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
+                                                      myLine(line),
+                                                      indicemin(Min(IndMin, IndMax)),
+                                                      indicemax(Max(IndMin, IndMax)),
+                                                      nbp3d(NbP3d), nbp2d(NbP2d),
+                                                      p2donfirst(P2DOnFirst),
+                                                      Xo(xo), Yo(yo), Zo(zo),
+                                                      U1o(u1o), V1o(v1o),
+                                                      U2o(u2o), V2o(v2o)
 {
-  if(indicemin>=indicemax) {
-#if DEBUG
-    cout<<"\n********************************************";
-    cout<<"\n*****       ApproxInt_MultiLine     ********";
-    cout<<"\n***** indicemin = indicemax = "<<indicemin;
-    cout<<"\n********************************************"<<endl;
+#if OCCT_DEBUG
+  //if(indicemin == indicemax)
+  //{
+  //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
+  //}
 #endif
-  }
 }
+
 //--------------------------------------------------------------------------------
 Standard_Integer ApproxInt_MultiLine::FirstPoint() const { 
   return(indicemin);
@@ -134,216 +118,152 @@ Standard_Integer ApproxInt_MultiLine::NbP2d() const {
 }
 //================================================================================
 void ApproxInt_MultiLine::Value(const Standard_Integer  Index,
-                               TColgp_Array1OfPnt&     TabPnt)  const 
+                                TColgp_Array1OfPnt&     TabPnt)  const 
 { 
-  IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real X = POn2S.Value().X();
-  Standard_Real Y = POn2S.Value().Y();
-  Standard_Real Z = POn2S.Value().Z();
-  TabPnt(1) = gp_Pnt(X*Ax + Xo, Y*Ay + Yo, Z*Az + Zo);
+  const gp_Pnt& aP = myLine->Point(Index).Value();
+  TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
 }
-//--------------------------------------------------------------------------------
-void ApproxInt_MultiLine::Value( const Standard_Integer Index
-                               ,TColgp_Array1OfPnt2d&  TabPnt2d) const 
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+void ApproxInt_MultiLine::Value(const Standard_Integer Index,
+                                TColgp_Array1OfPnt2d&  TabPnt2d) const 
 {
   IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real u1,u2,v1,v2;
-  POn2S.Parameters(u1,v1,u2,v2);
-  if(nbp2d==1) { 
-    if(p2donfirst) { 
-      TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
+  Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
+  POn2S.Parameters(u1, v1, u2, v2);
+  if(nbp2d==1)
+  { 
+    if(p2donfirst)
+    { 
+      TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
     }
-    else { 
-      TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
+    else
+    {
+      TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
     }
   }
-  else { 
-    TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
-    if(TabPnt2d.Length()>=2) { 
-      TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
+  else
+  {
+    TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
+    if(TabPnt2d.Length() >= 2)
+    { 
+      TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
     } 
   }
 }
-//--------------------------------------------------------------------------------
-void ApproxInt_MultiLine::Value( const Standard_Integer Index
-                               ,TColgp_Array1OfPnt&    TabPnt
-                               ,TColgp_Array1OfPnt2d&  TabPnt2d)  const 
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+void ApproxInt_MultiLine::Value(const Standard_Integer Index,
+                                TColgp_Array1OfPnt&    TabPnt,
+                                TColgp_Array1OfPnt2d&  TabPnt2d)  const 
 { 
-  IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real u1,u2,v1,v2;
-  POn2S.Parameters(u1,v1,u2,v2);
-  if(nbp2d==1) { 
-    if(p2donfirst) { 
-      TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
-    }
-    else { 
-      TabPnt2d(1) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o); 
-    }
-  }
-  else { 
-    TabPnt2d(1) = gp_Pnt2d(u1 * A1u + U1o , v1 * A1v + V1o);
-    if(TabPnt2d.Length()>=2) { 
-      TabPnt2d(2) = gp_Pnt2d(u2 * A2u + U2o , v2 * A2v + V2o);
-    }
-  }
-  Standard_Real X = POn2S.Value().X();
-  Standard_Real Y = POn2S.Value().Y();
-  Standard_Real Z = POn2S.Value().Z();
-  TabPnt(1) = gp_Pnt(X * Ax + Xo, Y * Ay + Yo, Z * Az + Zo);
+    Value(Index, TabPnt);
+    Value(Index, TabPnt2d);
 }
-//--------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------
-Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
-                                              ,TColgp_Array1OfVec&    TabVec) const 
-{ 
+
+//=======================================================================
+//function : Tangency
+//purpose  : 
+//=======================================================================
+Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
+                                                TColgp_Array1OfVec&    TabVec) const 
+{
   if(PtrOnmySvSurfaces==NULL) 
-    return(Standard_False);
+    return Standard_False;
 
-  IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real u1,u2,v1,v2;
-  gp_Vec Tg;
+  const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
+  Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
   POn2S.Parameters(u1,v1,u2,v2);
-  Standard_Boolean ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
-  if(ret) { 
-    Standard_Real X = Tg.X();
-    Standard_Real Y = Tg.Y();
-    Standard_Real Z = Tg.Z();
-    TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
+
+  Standard_Boolean ret=
+            ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
+  if(!ret)
+  {
+    TabVec(1).SetCoord(0.0, 0.0, 0.0);
   }
-  else 
-    TabVec(1) = gp_Vec(0.0,0.0,0.0);
-  return(ret);
+
+  return ret;
 }
-//--------------------------------------------------------------------------------
-Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
-                                              ,TColgp_Array1OfVec2d&  TabVec2d) const 
-{ 
+
+//=======================================================================
+//function : Tangency
+//purpose  : 
+//=======================================================================
+Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
+                                                TColgp_Array1OfVec2d&  TabVec2d) const 
+{
   if(PtrOnmySvSurfaces==NULL) 
-    return(Standard_False);
+    return Standard_False;
 
-  IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real u1,u2,v1,v2,U,V;
-  gp_Vec2d Tg2d;
-  Standard_Boolean ret;
+  const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
+  Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
   POn2S.Parameters(u1,v1,u2,v2);
-  if(nbp2d==1) { 
-    Standard_Real Au = A1u;
-    Standard_Real Av = A1v;
-    if(p2donfirst) { 
-      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
-    }
-    else { 
-      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
-      Au = A2u;
-      Av = A2v;
+
+  Standard_Boolean ret = Standard_False;
+  if(nbp2d==1)
+  { 
+    if(p2donfirst)
+    {
+      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
     }
-    if(ret) { 
-      U = Tg2d.X();
-      V = Tg2d.Y();
-      TabVec2d(1) = gp_Vec2d(U * Au, V * Av);
+    else
+    { 
+      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
     }
-    else {
-     TabVec2d(1) = gp_Vec2d(0.0,0.0);
-   }
   }
-  else { 
-    ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
-    if(ret) { 
-      U = Tg2d.X();
-      V = Tg2d.Y();
-      TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
-    
-      if(TabVec2d.Length()>=2) { 
-       ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
-       U = Tg2d.X();
-       V = Tg2d.Y();
-       TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
-      }
-      else { 
-       TabVec2d(1) = gp_Vec2d(0.0,0.0);
-       if(TabVec2d.Length()>=2) { 
-         TabVec2d(2) = gp_Vec2d(0.0,0.0);
-       }
+  else
+  {
+    ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
+    if(ret)
+    { 
+      if(TabVec2d.Length()>=2)
+      {
+        ret = 
+              (ret && 
+              ((TheSvSurfaces *)PtrOnmySvSurfaces)->
+                                          TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
       }
     }
   }
-  return(ret);
-}
-//--------------------------------------------------------------------------------
-Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index
-                                           ,TColgp_Array1OfVec&       TabVec
-                                           ,TColgp_Array1OfVec2d&     TabVec2d) const 
-{ 
-  if(PtrOnmySvSurfaces==NULL) 
-    return(Standard_False);
 
-  IntSurf_PntOn2S POn2S(myLine->Point(Index));
-  Standard_Real u1,u2,v1,v2,U,V;
-  gp_Vec2d Tg2d;
-  gp_Vec   Tg;
-  Standard_Boolean ret;
-  POn2S.Parameters(u1,v1,u2,v2);
-  if(nbp2d==1) {
-    Standard_Real Au = A1u;
-    Standard_Real Av = A1v;
-    if(p2donfirst) { 
-      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
-    }
-    else { 
-      ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
-      Au = A2u;
-      Av = A2v;
-    }
-    if(ret) { 
-      U = Tg2d.X();
-      V = Tg2d.Y();
-      TabVec2d(1) = gp_Vec2d(U * Au, V * Av);  
-    }
-    else { 
-      TabVec2d(1) = gp_Vec2d(0.0,0.0);
-    }
-  }
-  else { 
-    ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1( u1,v1,u2,v2,Tg2d);
-    if(ret) { 
-      U = Tg2d.X();
-      V = Tg2d.Y();
-      TabVec2d(1) = gp_Vec2d(U * A1u, V * A1v);
-      if(TabVec2d.Length()>=2) { 
-       ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2( u1,v1,u2,v2,Tg2d);
-       U = Tg2d.X();
-       V = Tg2d.Y();
-       TabVec2d(2) = gp_Vec2d(U * A2u, V * A2v);
-      }
-    }
-    else { 
-      TabVec2d(1) = gp_Vec2d(0.0,0.0);
-      if(TabVec2d.Length()>=2) {
-       TabVec2d(2) = gp_Vec2d(0.0,0.0);
-      }
+  if(!ret)
+  {
+    TabVec2d(1) = gp_Vec2d(0.0, 0.0);
+    if(TabVec2d.Length() >= 2)
+    {
+      TabVec2d(2) = gp_Vec2d(0.0,0.0);
     }
   }
-  if(ret) { 
-    ret&=((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency( u1,v1,u2,v2,Tg);
-    Standard_Real X = Tg.X();
-    Standard_Real Y = Tg.Y();
-    Standard_Real Z = Tg.Z();
-    TabVec(1) = gp_Vec(X * Ax, Y * Ay, Z * Az);
-  }
-  else { 
-    TabVec(1) = gp_Vec(0.0,0.0,0.0);
-  }
-  return(ret);
-}
-//--------------------------------------------------------------------------------
 
+  return ret;
+}
 
+//=======================================================================
+//function : Tangency
+//purpose  : 
+//=======================================================================
+Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
+                                                TColgp_Array1OfVec& TabVec,
+                                                TColgp_Array1OfVec2d& TabVec2d) const
+{ 
+  return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
+}
 
-//================================================================================
-ApproxInt_MultiLine  ApproxInt_MultiLine::MakeMLBetween(const Standard_Integer Low,
-                                                       const Standard_Integer High,
-                                                       const Standard_Integer aNbPntsToInsert)
-const { 
+//=======================================================================
+//function : MakeMLBetween
+//purpose  : 
+//=======================================================================
+ApproxInt_MultiLine
+  ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
+                                      const Standard_Integer High,
+                                      const Standard_Integer aNbPntsToInsert) const
+{ 
   if(PtrOnmySvSurfaces==NULL) {
     //-- cout<<"\n Erreur dans : ApproxInt_MultiLine  ApproxInt_MultiLine::MakeMLBetween "<<endl;
     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
@@ -352,13 +272,12 @@ const {
                               NULL,
                               nbp3d,
                               nbp2d,
-                              Xo,Ax,Yo,Ay,Zo,Az,
-                              U1o,A1u,V1o,A1v,
-                              U2o,A2u,V2o,A2v,
+                              Xo,Yo,Zo,U1o,V1o,U2o,V2o,
                               p2donfirst,
                               1,1));
     //-- return(*this);
   }
+
   Standard_Integer NbPntsToInsert=aNbPntsToInsert;
   if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
   Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
@@ -401,7 +320,6 @@ const {
   AC(Low) =0.0;
   
 #if 0 
-  
   for( i=Low+1; i<=High; i++) { 
     myLine->Point(i).Parameters(u1,v1,u2,v2);
     U1(i) = u1;
@@ -422,20 +340,17 @@ const {
     V1(i) = v1;
     U2(i) = u2;
     V2(i) = v2;    
-    AC(i) = AC(i-1) 
-      + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
+    AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
   }
 
 #endif
   //-------------------------------------------------------------
   //-- Creation des structures contenant les resultats
   
-  Handle(IntSurf_LineOn2S) ResultPntOn2SLine
-    = new IntSurf_LineOn2S();
+  Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
   
   IntSurf_PntOn2S StartPOn2S;  
-  TColStd_Array1OfReal StartParams(1,4);
-  
+  TColStd_Array1OfReal StartParams(1,4);  
   
   ds = AC(High) / (NbPnts-1);
   Standard_Integer Indice = Low;
@@ -450,8 +365,11 @@ const {
     //-- s                            s                       --
     //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
     //----------------------------------------------------------
-    while(AC(Indice+1) <= s) { 
-      if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
+    while(AC(Indice+1) <= s)
+    { 
+      if(!HasBeenInserted)
+        ResultPntOn2SLine->Add(myLine->Point(Indice));
+
       HasBeenInserted = Standard_False;
       Indice++;
       if (Indice == High)
@@ -461,10 +379,12 @@ const {
     if (Indice == High)
       break;
     
-    if(!HasBeenInserted  && AC(Indice) <= s) { 
+    if(!HasBeenInserted  && AC(Indice) <= s)
+    { 
       ResultPntOn2SLine->Add(myLine->Point(Indice));
       HasBeenInserted = Standard_True;
     }
+    
     Standard_Real a = s - AC(Indice);
     Standard_Real b = AC(Indice+1) - s;
     Standard_Real nab = 1.0/(a+b);
@@ -474,48 +394,57 @@ const {
     //--                 Si Dist au precedent point < dsmin   --
     //--                                                      --
     //----------------------------------------------------------
-    if((a>dsmin) && (b>dsmin)) {       
-      
+    if((a>dsmin) && (b>dsmin))
+    {
       u1 = (U1(Indice) * b   +  U1(Indice+1) * a) * nab;
       v1 = (V1(Indice) * b   +  V1(Indice+1) * a) * nab;
       u2 = (U2(Indice) * b   +  U2(Indice+1) * a) * nab;
       v2 = (V2(Indice) * b   +  V2(Indice+1) * a) * nab;
-      
-      
-      if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2)) { 
-       StartPOn2S.SetValue(P,u1,v1,u2,v2);
-       //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
-       //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
-       ResultPntOn2SLine->Add(StartPOn2S);
+            
+      if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2))
+      {
+        StartPOn2S.SetValue(P,u1,v1,u2,v2);
+        //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
+        //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
+        ResultPntOn2SLine->Add(StartPOn2S);
       }
-      else { 
-       //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
+      else
+      {
+        //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
       }
     }
-    else { 
+    else
+    {
       //-- Point non situe a distance suffisante de 2 pts existants
       //-- avec le point p[indice] deja insere
       
-      if(b<0.0) {
-       while(AC(Indice+1) <= s) { 
-         if(!HasBeenInserted) ResultPntOn2SLine->Add(myLine->Point(Indice));
-         //-- cout<<" Insertion du point :"<<Indice<<endl;
-         HasBeenInserted = Standard_False;
-         Indice++;
+      if(b<0.0)
+      {
+        while(AC(Indice+1) <= s)
+        {
+          if(!HasBeenInserted)
+            ResultPntOn2SLine->Add(myLine->Point(Indice));
+
+          //-- cout<<" Insertion du point :"<<Indice<<endl;
+          HasBeenInserted = Standard_False;
+          Indice++;
+
           if (Indice == High)
             break;
-       }
-    
-        if (Indice == High)
+        }
+
+        if(Indice == High)
           break;
-    
-       if(!HasBeenInserted  && AC(Indice) <= s) { 
-         ResultPntOn2SLine->Add(myLine->Point(Indice));
-         HasBeenInserted = Standard_True;
-       } 
+
+        if(!HasBeenInserted  && AC(Indice) <= s)
+        {
+          ResultPntOn2SLine->Add(myLine->Point(Indice));
+          HasBeenInserted = Standard_True;
+        }
       }
-      else { 
-       s+=dsmin - ds;
+      else
+      {
+        s+= (dsmin - ds);
       }
     }
   }
@@ -538,7 +467,8 @@ const {
 
   Standard_Integer CodeErreur=0; 
   
-  for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 &&  i<=NbPnts; i++) {
+  for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 &&  i<=NbPnts; i++)
+  {
     Standard_Real d,du,dv,duv2;
     temp->Point(i).Parameters(u1,v1,u2,v2);
     //-- Virage P1A P1B P1C
@@ -551,11 +481,13 @@ const {
     du = P1C.X() - u1;
     dv = P1C.Y() - v1;
     d = du*du+dv*dv;
-    if(d>duv2) { 
+    if(d>duv2)
+    { 
       CodeErreur = 1;
       CodeErreur = 1;
       break;
     }
+    
     //-- Virage P2A P2B P2C
     P2C.SetCoord(u2,v2);
     du  = P2B.X()-P2A.X();
@@ -566,63 +498,80 @@ const {
     du = P2C.X() - u2;
     dv = P2C.Y() - v2;
     d = du*du+dv*dv;
-    if(d>duv2) {
+    if(d>duv2)
+    {
       CodeErreur = 2;
       break;
     }
+    
     P1A=P1B;
     P2A=P2B;
     P1B=P1C;
     P2B=P2C;
   }
-#if DEBUG
-  if (temp->NbPnts() < NbPntsToInsert + High - Low + 1) { 
-    cout<<" *** Pas assez de points entre :"<<Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
-  }
-  if(CodeErreur) { 
-    cout<<" *** CodeErreur : "<<CodeErreur<<endl;
-  }
+
+#if OCCT_DEBUG
+  //if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
+  //{ 
+  //  cout<<" *** Pas assez de points entre :"<<
+  //            Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
+  //}
+
+  //if(CodeErreur)
+  //{ 
+  //  cout<<" *** CodeErreur : "<<CodeErreur<<endl;
+  //}
 #endif
-  if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1)
-     && (CodeErreur==0)) { 
-    return(ApproxInt_MultiLine(temp,
-                              (High-Low>10)? PtrOnmySvSurfaces : NULL,
-                              nbp3d,
-                              nbp2d,
-                              Xo,Ax,Yo,Ay,Zo,Az,
-                              U1o,A1u,V1o,A1v,
-                              U2o,A2u,V2o,A2v,
-                              p2donfirst,
-                              1,ResultPntOn2SLine->NbPoints()));
+
+  if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
+  {
+    return(ApproxInt_MultiLine( temp, 
+                                (High-Low>10)? PtrOnmySvSurfaces : NULL,
+                                nbp3d,
+                                nbp2d,
+                                Xo,Yo,Zo,
+                                U1o,V1o,
+                                U2o,V2o,
+                                p2donfirst,
+                                1,ResultPntOn2SLine->NbPoints()));
   }
-  else { 
+  else
+  {
     //-- cout<<" ApproxInt_MultiLine "<<endl;
     //-- cout<<" Pas de Rajout de points ds1min =  "<<minds1<<" ds2min = "<<minds2<<endl;
     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
-    return(ApproxInt_MultiLine(vide,
-                              NULL,
-                              nbp3d,
-                              nbp2d,
-                              Xo,Ax,Yo,Ay,Zo,Az,
-                              U1o,A1u,V1o,A1v,
-                              U2o,A2u,V2o,A2v,
-                              p2donfirst,
-                              1,1));
+    return(ApproxInt_MultiLine( vide,
+                                NULL,
+                                nbp3d,
+                                nbp2d,
+                                Xo,Yo,Zo,
+                                U1o,V1o,
+                                U2o,V2o,
+                                p2donfirst,
+                                1,1));
   }
 }
-  //======================================================================
 
+//=======================================================================
+//function : Dump
+//purpose  : 
+//=======================================================================
 void ApproxInt_MultiLine::Dump() const
 {
   TColgp_Array1OfPnt anArr1(1, 1);
   TColgp_Array1OfPnt2d anArr2(1, 2);
         
-  for(Standard_Integer ind = FirstPoint(); ind <= LastPoint(); ind++)
+  const Standard_Integer  anIndF = FirstPoint(),
+                          anIndL = LastPoint();
+        
+  for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
   {
     Value(ind, anArr1, anArr2);
-    printf("%4d  [%+10.20f %+10.20f %+10.20f]  [%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
-      ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
+    printf("%4d  [%+10.20f %+10.20f %+10.20f]  "
+            "[%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
+      ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
+      anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
   }
 }
 
index 0cba54c..d0c9f6e 100644 (file)
@@ -42,8 +42,7 @@
 BRepAlgo_BooleanOperations::BRepAlgo_BooleanOperations() :
 myApproxNbPntMax (30) ,
 myApproxTol3D (1.e-7) ,
-myApproxTol2D (1.e-7) ,
-myApproxRelativeTol (Standard_True)
+myApproxTol2D (1.e-7)
 {
 }
 
@@ -109,13 +108,11 @@ myApproxRelativeTol (Standard_True)
 //=======================================================================
   void BRepAlgo_BooleanOperations::SetApproxParameters (const Standard_Integer NbPntMax,
                                                        const Standard_Real Tol3D,
-                                                       const Standard_Real Tol2D,
-                                                       const Standard_Boolean RelativeTol)
+                                                       const Standard_Real Tol2D)
 {
   myApproxNbPntMax = NbPntMax ;
   myApproxTol3D = Tol3D ;
   myApproxTol2D = Tol2D ;
-  myApproxRelativeTol = RelativeTol ;
 }
 
 //=======================================================================
@@ -140,7 +137,7 @@ myApproxRelativeTol (Standard_True)
   TopOpeBRepDS_BuildTool& BTofBuilder = myDSA.myHB->ChangeBuildTool();
   TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
   GTofBTofBuilder.SetNbPntMax(myApproxNbPntMax);
-  GTofBTofBuilder.SetTolerances (myApproxTol3D, myApproxTol2D, myApproxRelativeTol) ;
+  GTofBTofBuilder.SetTolerances (myApproxTol3D, myApproxTol2D) ;
   Handle(TopOpeBRepBuild_HBuilder)& HB = myDSA.myHB;
   Handle(TopOpeBRepDS_HDataStructure)& HDS = myDSA.ChangeDS();
   HB->Perform(HDS,myS1,myS2);
index a00b4f7..6975d3f 100644 (file)
@@ -58,7 +58,7 @@ public:
   //! the same time in one curve.
   //! Tol3D, Tol2D : Tolerances to be reached by the approximation.
   //! RelativeTol : The given tolerances are relative.
-  Standard_EXPORT void SetApproxParameters (const Standard_Integer NbPntMax, const Standard_Real Tol3D, const Standard_Real Tol2D, const Standard_Boolean RelativeTol);
+  Standard_EXPORT void SetApproxParameters (const Standard_Integer NbPntMax, const Standard_Real Tol3D, const Standard_Real Tol2D);
   
   Standard_EXPORT void Define (const TopoDS_Shape& S1, const TopoDS_Shape& S2, Handle(TopOpeBRepDS_HDataStructure)& HDS);
   
@@ -129,9 +129,6 @@ private:
   Standard_Integer myApproxNbPntMax;
   Standard_Real myApproxTol3D;
   Standard_Real myApproxTol2D;
-  Standard_Boolean myApproxRelativeTol;
-
-
 };
 
 
index c00efbe..ed03731 100644 (file)
@@ -51,22 +51,24 @@ class AppParCurves_MultiBSpCurve;
 
 struct Approx_Data 
 {
-  Approx_Data()
+  Approx_Data() : myBezierApprox(Standard_True),
+                  Xo(0.0), Yo(0.0), Zo(0.0),
+                  U1o(0.0), V1o(0.0), U2o(0.0), V2o(0.0),
+                  ApproxXYZ(Standard_True),
+                  ApproxU1V1(Standard_True),
+                  ApproxU2V2(Standard_True),
+                  indicemin(0), indicemax(0),
+                  myNbPntMax(30), parametrization(Approx_ChordLength)
   {
-    myMinFactorXYZ = 0.0;
-    myMinFactorUV  = 0.0;
   }
 
   Standard_Boolean myBezierApprox;
-  Standard_Real  Xo, Ax, Yo, Ay, Zo, Az,
-    U1o, A1u, V1o, A1v, U2o, A2u, V2o, A2v;
+  Standard_Real  Xo, Yo, Zo, U1o, V1o, U2o, V2o;
   Standard_Boolean ApproxXYZ, ApproxU1V1, ApproxU2V2;
-  Standard_Integer indicemin, indicemax, nbpntmax;
+  Standard_Integer indicemin, indicemax, myNbPntMax;
   Approx_ParametrizationType parametrization;
-  Standard_Real myMinFactorXYZ, myMinFactorUV;
 };
 
-
 class BRepApprox_Approx 
 {
 public:
@@ -80,10 +82,16 @@ public:
   
   Standard_EXPORT void Perform (const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ = Standard_True, const Standard_Boolean ApproxU1V1 = Standard_True, const Standard_Boolean ApproxU2V2 = Standard_True, const Standard_Integer indicemin = 0, const Standard_Integer indicemax = 0);
   
-  Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength);
-  
-  Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Boolean RelativeTol, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Integer NbPntMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength);
-  
+  Standard_EXPORT 
+      void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d,
+                          const Standard_Integer DegMin, 
+                          const Standard_Integer DegMax,
+                          const Standard_Integer NbIterMax,
+                          const Standard_Integer NbPntMax = 30,
+                          const Standard_Boolean ApproxWithTangency = Standard_True,
+                          const Approx_ParametrizationType
+                                          Parametrization = Approx_ChordLength);
+
   Standard_EXPORT void Perform();
   
   Standard_EXPORT Standard_Real TolReached3d() const;
@@ -106,22 +114,12 @@ protected:
 
 
 private:
-
-  Standard_EXPORT Standard_Integer CorrectFinishIdx(const Standard_Integer theMinIdx,
-                                                    const Standard_Integer theMaxIdx,
-                                                    const Handle(BRepApprox_ApproxLine)& theline);
-  
-  Standard_EXPORT void Perform (const BRepAdaptor_Surface& Surf1, const IntSurf_Quadric& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax);
-  
-  Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax);
+  Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const BRepAdaptor_Surface& Surf2, const Handle(BRepApprox_ApproxLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax, const Standard_Boolean isTheQuadFirst);
   
   Standard_EXPORT void UpdateTolReached();
 
   //! Fill data structure for intersection approximation.
-  Standard_EXPORT void fillData(const Handle(BRepApprox_ApproxLine)& theLine,
-                                const Standard_Boolean theApproxXYZ,
-                                const Standard_Boolean theApproxU1V1,
-                                const Standard_Boolean theApproxU2V2);
+  Standard_EXPORT void fillData(const Handle(BRepApprox_ApproxLine)& theLine);
 
   //! Prepare data structure for further computations.
   Standard_EXPORT void prepareDS(const Standard_Boolean theApproxXYZ,
@@ -141,19 +139,15 @@ private:
   BRepApprox_TheComputeLineOfApprox myComputeLine;
   BRepApprox_TheComputeLineBezierOfApprox myComputeLineBezier;
   Approx_MCurvesToBSpCurve myBezToBSpl;
-  Standard_Boolean myTolReached;
   Standard_Boolean myWithTangency;
   Standard_Real myTol3d;
   Standard_Real myTol2d;
-  Standard_Boolean myRelativeTol;
   Standard_Integer myDegMin;
   Standard_Integer myDegMax;
-  Standard_Integer myNbPntMax;
   Standard_Integer myNbIterMax;
   Standard_Real myTolReached3d;
   Standard_Real myTolReached2d;
   Approx_Data myData;
-  Standard_Real myUVRes1, myUVRes2;
   NCollection_Vector<Standard_Integer> myKnots;
 
 };
index 331323e..1e7f39c 100644 (file)
@@ -116,15 +116,12 @@ public:
   Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue();
   
   //! returns the type  of  parametrization
-  Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const;
+  Standard_EXPORT Approx_ParametrizationType Parametrization () const;
   
   //! returns the new parameters of the approximation
   //! corresponding to the points of the multicurve <Index>.
   Standard_EXPORT const TColStd_Array1OfReal& Parameters (const Standard_Integer Index = 1) const;
 
-
-
-
 protected:
 
 
index 8df99dd..40d91b0 100644 (file)
@@ -40,56 +40,71 @@ class BRepApprox_TheMultiLineOfApprox
 public:
 
   DEFINE_STANDARD_ALLOC
-
   
-  //! The  class   SvSurfaces     is used   when    the
-  //! approximation algorithm needs some extra points on
-  //! the line <line>. A New line  is then created which
-  //! shares  the    same  surfaces    and    functions.
-  //!
-  //! SvSurfaces is   a  deferred   class  which  allows
-  //! several implementations of  this  algorithm   with
-  //! different surfaces   (bi-parametric     ones,   or
+  //! The class SvSurfaces is used when the approximation algorithm 
+  //! needs some extra points on the line <line>. 
+  //! A New line  is then created which shares the same surfaces and functions.
+  //! SvSurfaces is a deferred class which allows several implementations of
+  //! this  algorithm with different surfaces (bi-parametric ones, or 
   //! implicit and biparametric ones)
-  Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0);
-  
+  Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line,
+                                                  const Standard_Address PtrSvSurfaces,
+                                                  const Standard_Integer NbP3d,
+                                                  const Standard_Integer NbP2d,
+                                                  const Standard_Real xo,
+                                                  const Standard_Real yo,
+                                                  const Standard_Real zo,
+                                                  const Standard_Real u1o,
+                                                  const Standard_Real v1o,
+                                                  const Standard_Real u2o,
+                                                  const Standard_Real v2o,
+                                                  const Standard_Boolean P2DOnFirst,
+                                                  const Standard_Integer IndMin = 0,
+                                                  const Standard_Integer IndMax = 0);
+
   //! No Extra points will be added on the current line
-  Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0);
-  
+  Standard_EXPORT BRepApprox_TheMultiLineOfApprox(const Handle(BRepApprox_ApproxLine)& line,
+                                                  const Standard_Integer NbP3d,
+                                                  const Standard_Integer NbP2d,
+                                                  const Standard_Real xo,
+                                                  const Standard_Real yo,
+                                                  const Standard_Real zo,
+                                                  const Standard_Real u1o,
+                                                  const Standard_Real v1o,
+                                                  const Standard_Real u2o,
+                                                  const Standard_Real v2o,
+                                                  const Standard_Boolean P2DOnFirst,
+                                                  const Standard_Integer IndMin = 0,
+                                                  const Standard_Integer IndMax = 0);
+
   Standard_EXPORT Standard_Integer FirstPoint() const;
   
   Standard_EXPORT Standard_Integer LastPoint() const;
-  
+
   //! Returns the number of 2d points of a TheLine.
   Standard_EXPORT Standard_Integer NbP2d() const;
-  
+
   //! Returns the number of 3d points of a TheLine.
   Standard_EXPORT Standard_Integer NbP3d() const;
-  
+
   Standard_EXPORT Approx_Status WhatStatus() const;
   
-  //! returns the 3d points of the multipoint <MPointIndex>
-  //! when only 3d points exist.
+  //! Returns the 3d points of the multipoint <MPointIndex> when only 3d points exist.
   Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt) const;
-  
-  //! returns the 2d points of the multipoint <MPointIndex>
-  //! when only 2d points exist.
+
+  //! Returns the 2d points of the multipoint <MPointIndex> when only 2d points exist.
   Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt2d& tabPt2d) const;
-  
-  //! returns the 3d and 2d points of the multipoint
-  //! <MPointIndex>.
+
+  //! Returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt, TColgp_Array1OfPnt2d& tabPt2d) const;
-  
-  //! returns the 3d points of the multipoint <MPointIndex>
-  //! when only 3d points exist.
+
+  //! Returns the 3d tangency points of the multipoint <MPointIndex> only when 3d points exist.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV) const;
   
-  //! returns the 2d tangency points of the multipoint
-  //! <MPointIndex> only when 2d points exist.
+  //! Returns the 2d tangency points of the multipoint <MPointIndex> only when 2d points exist.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec2d& tabV2d) const;
   
-  //! returns the 3d and 2d points of the multipoint
-  //! <MPointIndex>.
+  //! Returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const;
   
   Standard_EXPORT BRepApprox_TheMultiLineOfApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const;
@@ -97,48 +112,25 @@ public:
   //! Dump of the current multi-line.
   Standard_EXPORT void Dump() const;
 
-
-
-
 protected:
-
-
-
-
+  BRepApprox_TheMultiLineOfApprox operator=(BRepApprox_TheMultiLineOfApprox&);
 
 private:
-
-
-
-  Standard_Address PtrOnmySvSurfaces;
-  Handle(BRepApprox_ApproxLine) myLine;
-  Standard_Integer indicemin;
-  Standard_Integer indicemax;
-  Standard_Integer nbp3d;
-  Standard_Integer nbp2d;
-  Standard_Boolean p2donfirst;
-  Standard_Real Xo;
-  Standard_Real Ax;
-  Standard_Real Yo;
-  Standard_Real Ay;
-  Standard_Real Zo;
-  Standard_Real Az;
-  Standard_Real U1o;
-  Standard_Real A1u;
-  Standard_Real V1o;
-  Standard_Real A1v;
-  Standard_Real U2o;
-  Standard_Real A2u;
-  Standard_Real V2o;
-  Standard_Real A2v;
-
+  const Standard_Address PtrOnmySvSurfaces;
+  const Handle(BRepApprox_ApproxLine) myLine;
+  const Standard_Integer indicemin;
+  const Standard_Integer indicemax;
+  const Standard_Integer nbp3d;
+  const Standard_Integer nbp2d;
+  const Standard_Boolean p2donfirst;
+  const Standard_Real Xo;
+  const Standard_Real Yo;
+  const Standard_Real Zo;
+  const Standard_Real U1o;
+  const Standard_Real V1o;
+  const Standard_Real U2o;
+  const Standard_Real V2o;
 
 };
 
-
-
-
-
-
-
 #endif // _BRepApprox_TheMultiLineOfApprox_HeaderFile
index 98e3e0c..b60055f 100644 (file)
@@ -1259,7 +1259,20 @@ void BRepLib::SameParameter(const TopoDS_Edge&  AnEdge,
               else GCurve->PCurve2(curPC);
             }
           }
-          else IsSameP = 0;
+          else
+          {
+            //Approx_SameParameter has failed.
+            //Consequently, the situation might be,
+            //when 3D and 2D-curve do not have same-range.
+            GeomLib::SameRange( Tol2d, PC[i], 
+                                GCurve->First(), GCurve->Last(),
+                                f3d,l3d,curPC);
+
+            if (i == 0) GCurve->PCurve(curPC);
+            else GCurve->PCurve2(curPC);
+
+            IsSameP = 0;
+          }
 
         }
         else IsSameP = 0;
index 53f1675..575753d 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <math_Matrix.hxx>
 
+static const Standard_Integer aGlobalMaxDegree = 25;
+
 //=======================================================================
 //struct : BSplCLib_DataContainer 
 //purpose: Auxiliary structure providing buffers for poles and knots used in
@@ -43,7 +45,7 @@ struct BSplCLib_DataContainer
   {
     (void)Degree; // avoid compiler warning
     Standard_OutOfRange_Raise_if (Degree > BSplCLib::MaxDegree() ||
-        BSplCLib::MaxDegree() > 25,
+        BSplCLib::MaxDegree() > aGlobalMaxDegree,
         "BSplCLib: bspline degree is greater than maximum supported");
   }
 
@@ -324,7 +326,7 @@ BSplCLib::BuildBSpMatrix(const  TColStd_Array1OfReal&     Parameters,
   ReturnCode = 0,
   FirstNonZeroBsplineIndex,
   BandWidth,
-  MaxOrder = 21,
+  MaxOrder = aGlobalMaxDegree+1,
   Order ;
   
   math_Matrix   BSplineBasis(1, MaxOrder,
index 9dc4e63..9ba0cf3 100644 (file)
@@ -3039,8 +3039,6 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
   Standard_Real&              tolreached,
   const Standard_Boolean      wholeCurv) 
 {
-  Standard_Real Step = 0.1;
-
   gp_Pnt pdeb1 = S1->Value(Pardeb(1),Pardeb(2));
   gp_Pnt pfin1 = S1->Value(Parfin(1),Parfin(2));
   gp_Pnt pdeb2 = S2->Value(Pardeb(3),Pardeb(4));
@@ -3267,7 +3265,8 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
                 else         Ul = Uok;
               }
               else { // both projected, but where?
-                if (Uf == Ul) continue;
+                if (Abs(Uf - Ul) < Precision::PConfusion())
+                  continue;
               }
               ptestdeb = C3d->Value(Uf);
               ptestfin = C3d->Value(Ul);
@@ -3323,7 +3322,8 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
 
   // At this stage : 
   // classic intersections have failed, the path is approached in vain.
-  //  Standard_Real Step = 0.1;
+
+  Standard_Real Step = 0.1;
   for(;;) {
     //Attention the parameters of arrow for the path and
     //the tolerance for the approximation can't be taken as those of the  
@@ -3451,8 +3451,12 @@ Standard_Boolean ChFi3d_ComputeCurves(const Handle(Adaptor3d_HSurface)&   S1,
       //
       Handle(IntPatch_WLine)   WL = new IntPatch_WLine(L2S,Standard_False);
 
+#ifdef OCCT_DEBUG
+      //WL->Dump(0);
+#endif
+
       GeomInt_WLApprox approx;
-      approx.SetParameters(tolap,tol2d,4,8,0,1);
+      approx.SetParameters(tolap, tol2d, 4, 8, 0, 30, Standard_True);
       // manage here the approximations that are not useful on planes!
       approx.Perform(S1,S2,WL,
         Standard_True,Standard_True,Standard_True,
index 57b0d8e..47c00b5 100644 (file)
@@ -946,13 +946,14 @@ void Draft_Modification::Perform ()
               return;
             }
 
-            Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
+            Standard_Real Glob2Min = RealLast();
             GeomAdaptor_Curve TheCurve;
 
             Standard_Integer i,j; //,jmin;
 
             if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
             {
+              Standard_Real Dist2Min = RealLast();
               imin = 0;
               for (i=1; i<= i2s.NbLines(); i++) {
                 TheCurve.Load(i2s.Line(i));
@@ -1041,7 +1042,7 @@ void Draft_Modification::Perform ()
                     Dist2Min = myExtPC.SquareDistance(1);
                     locpmin = myExtPC.Point(1).Parameter();
                     for (j=2; j<=myExtPC.NbExt(); j++) {
-                      Dist2 = myExtPC.SquareDistance(j);
+                      const Standard_Real Dist2 = myExtPC.SquareDistance(j);
                       if (Dist2 < Dist2Min) {
                         Dist2Min = Dist2;
                         locpmin = myExtPC.Point(j).Parameter();
@@ -1142,15 +1143,15 @@ void Draft_Modification::Perform ()
               Handle( Geom_Curve ) FirstCurve;
               if (Candidates.Length() > 1)
               {
-                Dist2Min = RealLast();
+                Standard_Real DistMin = Precision::Infinite();
                 for (i = 1; i <= Candidates.Length(); i++)
                 {
                   Handle( Geom_Curve ) aCurve = Candidates(i);
                   gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
-                  Dist2 = Pnt.SquareDistance( pfv );
-                  if (Dist2 < Dist2Min)
+                  const Standard_Real Dist = Pnt.Distance( pfv );
+                  if (Dist - DistMin < -Precision::Confusion())
                   {
-                    Dist2Min = Dist2;
+                    DistMin = Dist;
                     FirstCurve = aCurve;
                   }
                 }
@@ -1210,12 +1211,12 @@ void Draft_Modification::Perform ()
 
               TheCurve.Load( newC );
               Extrema_ExtPC myExtPC( pfv, TheCurve );
-              Dist2Min = RealLast();
+              Standard_Real Dist2Min = RealLast();
               for (i = 1; i <= myExtPC.NbExt(); i++)
               {
                 if (myExtPC.IsMin(i))
                 {
-                  Dist2 = myExtPC.SquareDistance(i);
+                  const Standard_Real Dist2 = myExtPC.SquareDistance(i);
                   if (Dist2 < Dist2Min)
                   {
                     Dist2Min = Dist2;
index af99337..40ed653 100644 (file)
@@ -40,6 +40,7 @@ class gp_Pnt2d;
 class IntPatch_RLine;
 class Bnd_Box2d;
 class Adaptor3d_TopolTool;
+class IntPatch_WLine;
 
 
 
@@ -110,7 +111,9 @@ public:
   //! of the source surface.
   Standard_EXPORT static void TrimILineOnSurfBoundaries (const Handle(Geom2d_Curve)& theC2d1, const Handle(Geom2d_Curve)& theC2d2, const Bnd_Box2d& theBound1, const Bnd_Box2d& theBound2, GeomInt_VectorOfReal& theArrayOfParameters);
 
+  Standard_EXPORT static Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL, const Standard_Integer ideb, const Standard_Integer ifin);
 
+  Standard_EXPORT static Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine, const Standard_Integer ideb, const Standard_Integer ifin, const Standard_Boolean onFirst);
 
 
 protected:
index 24ed10c..95455a6 100644 (file)
@@ -15,6 +15,7 @@
 // commercial license or contractual agreement.
 
 #include <IntPatch_Point.hxx>
+#include <Geom_Surface.hxx>
 
 
 //=======================================================================
index 91832c5..76e1e88 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <algorithm>
+#include <GeomInt_IntSS.hxx>
 
-#include <Adaptor2d_HCurve2d.hxx>
 #include <Adaptor3d_TopolTool.hxx>
-#include <AppParCurves_MultiBSpCurve.hxx>
 #include <Approx_CurveOnSurface.hxx>
-#include <Bnd_Box2d.hxx>
 #include <ElSLib.hxx>
 #include <Extrema_ExtPS.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_TrimmedCurve.hxx>
 #include <Geom2dAdaptor.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 #include <Geom2dInt_GInter.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Ellipse.hxx>
-#include <Geom_Hyperbola.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_Parabola.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <GeomAbs_CurveType.hxx>
-#include <GeomAbs_SurfaceType.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
 #include <GeomAdaptor.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomInt.hxx>
-#include <GeomInt_IntSS.hxx>
+#include <GeomInt_LineTool.hxx>
 #include <GeomInt_WLApprox.hxx>
 #include <GeomLib_Check2dBSplineCurve.hxx>
 #include <GeomLib_CheckBSplineCurve.hxx>
 #include <GeomProjLib.hxx>
-#include <gp_Lin2d.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_Hyperbola.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Parabola.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <IntPatch_ALine.hxx>
 #include <IntPatch_ALineToWLine.hxx>
 #include <IntPatch_GLine.hxx>
-#include <IntPatch_IType.hxx>
-#include <IntPatch_Line.hxx>
 #include <IntPatch_RLine.hxx>
 #include <IntPatch_WLine.hxx>
-#include <IntRes2d_IntersectionPoint.hxx>
 #include <IntRes2d_IntersectionSegment.hxx>
-#include <NCollection_IncAllocator.hxx>
-#include <NCollection_List.hxx>
-#include <NCollection_LocalArray.hxx>
-#include <NCollection_StdAllocator.hxx>
-#include <Precision.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <StdFail_NotDone.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_Array1OfListOfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TColStd_ListOfInteger.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-
-#include <algorithm>
-#include <vector>
-static
-  void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
-                 const Handle(GeomAdaptor_HSurface)& HS2,
-                 const gp_Pnt& Ptref,
-                 Standard_Real& U1,
-                 Standard_Real& V1,
-                 Standard_Real& U2,
-                 Standard_Real& V2);
-
-static 
-  Handle(Geom_Curve) MakeBSpline  (const Handle(IntPatch_WLine)& WL,
-                                  const Standard_Integer ideb,
-                                  const Standard_Integer ifin);
-
-static
-  Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
-                                           const Standard_Integer                         ideb,
-                                           const Standard_Integer                         ifin,
-                                           const Standard_Boolean                         onFirst);
-
-static 
-  Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
-
-
-static
-  Standard_Boolean DecompositionOfWLine  (const Handle(IntPatch_WLine)& theWLine,
-                                         const Handle(GeomAdaptor_HSurface)&            theSurface1, 
-                                         const Handle(GeomAdaptor_HSurface)&            theSurface2,
-                                         const Standard_Real aTolSum, 
-                                         const GeomInt_LineConstructor&                 theLConstructor,
-                                         IntPatch_SequenceOfLine&                       theNewLines);
-
-static
-  Standard_Real AdjustPeriodic(const Standard_Real theParameter,
-                              const Standard_Real parmin,
-                              const Standard_Real parmax,
-                              const Standard_Real thePeriod,
-                              Standard_Real&      theOffset) ;
-static 
-  Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
-                                    const Standard_Real theFirstBoundary,
-                                    const Standard_Real theSecondBoundary,
-                                    const Standard_Real theResolution,
-                                    Standard_Boolean&   IsOnFirstBoundary);
-
-static 
-  Standard_Boolean FindPoint(const gp_Pnt2d&     theFirstPoint,
-                            const gp_Pnt2d&     theLastPoint,
-                            const Standard_Real theUmin, 
-                            const Standard_Real theUmax,
-                            const Standard_Real theVmin,
-                            const Standard_Real theVmax,
-                            gp_Pnt2d&           theNewPoint);
-
-
-static
-  void AdjustUPeriodic (const Handle(Geom_Surface)& aS,
-                       const Handle(Geom2d_Curve)& aC2D);
-static
-  void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1,
-                 IntSurf_Quadric& quad1);
-
-class ProjectPointOnSurf
-{
- public:
-  ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {}
-  void Init(const Handle(Geom_Surface)& Surface,
-           const Standard_Real Umin,
-           const Standard_Real Usup,
-           const Standard_Real Vmin,
-           const Standard_Real Vsup);
-  void Init ();
-  void Perform(const gp_Pnt& P);
-  Standard_Boolean IsDone () const { return myIsDone; }
-  void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const;
-  Standard_Real LowerDistance() const;
- protected:
-  Standard_Boolean myIsDone;
-  Standard_Integer myIndex;
-  Extrema_ExtPS myExtPS;
-  GeomAdaptor_Surface myGeomAdaptor;
-};
+#include <IntSurf_Quadric.hxx>
+#include <Geom_Surface.hxx>
 
 //=======================================================================
-//function : Init
+//function : AdjustUPeriodic
 //purpose  : 
 //=======================================================================
-  void ProjectPointOnSurf::Init (const Handle(Geom_Surface)& Surface,
-                                const Standard_Real       Umin,
-                                const Standard_Real       Usup,
-                                const Standard_Real       Vmin,
-                                const Standard_Real       Vsup )
+ static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
 {
-  const Standard_Real Tolerance = Precision::PConfusion();
+  if (aC2D.IsNull() || !aS->IsUPeriodic())
+    return;
   //
-  myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
-  myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
-  myIsDone = Standard_False;
+  const Standard_Real aEps=Precision::PConfusion();//1.e-9
+  const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15 
+  //
+  Standard_Real umin,umax,vmin,vmax;
+  aS->Bounds(umin,umax,vmin,vmax);
+  const Standard_Real aPeriod = aS->UPeriod();
+  
+  const Standard_Real aT1=aC2D->FirstParameter();
+  const Standard_Real aT2=aC2D->LastParameter();
+  const Standard_Real aTx=aT1+0.467*(aT2-aT1);
+  const gp_Pnt2d aPx=aC2D->Value(aTx);
+  //
+  Standard_Real aUx=aPx.X();
+  if (fabs(aUx)<aEpsilon)
+    aUx=0.;
+  if (fabs(aUx-aPeriod)<aEpsilon)
+    aUx=aPeriod;
+  //
+  Standard_Real dU=0.;
+  while(aUx <(umin-aEps)) {
+    aUx+=aPeriod;
+    dU+=aPeriod;
+  }
+  while(aUx>(umax+aEps)) {
+    aUx-=aPeriod;
+    dU-=aPeriod;
+  }
+  // 
+  if (dU!=0.) {
+    gp_Vec2d aV2D(dU, 0.);
+    aC2D->Translate(aV2D);
+  }
 }
-//=======================================================================
-//function : Init
+
+ //=======================================================================
+//function : GetQuadric
 //purpose  : 
 //=======================================================================
-  void ProjectPointOnSurf::Init ()
+ static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
 {
-  myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0);
-  if (myIsDone) {
-    // evaluate the lower distance and its index;
-    Standard_Real Dist2Min = myExtPS.SquareDistance(1);
-    myIndex = 1;
-    for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++)
-    {
-      const Standard_Real Dist2 = myExtPS.SquareDistance(i);
-      if (Dist2 < Dist2Min) {
-        Dist2Min = Dist2;
-        myIndex = i;
-      }
-    }
+  switch (HS1->Surface().GetType())
+  {
+    case GeomAbs_Plane:    quad1.SetValue(HS1->Surface().Plane()); break;
+    case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
+    case GeomAbs_Cone:     quad1.SetValue(HS1->Surface().Cone()); break;
+    case GeomAbs_Sphere:   quad1.SetValue(HS1->Surface().Sphere()); break;
+    case GeomAbs_Torus:    quad1.SetValue(HS1->Surface().Torus()); break;
+    default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
   }
 }
+
+//=======================================================================
+//function : Parameters
+//purpose  : 
+//=======================================================================
+ static void Parameters(  const Handle(GeomAdaptor_HSurface)& HS1,
+                         const Handle(GeomAdaptor_HSurface)& HS2,
+                         const gp_Pnt& Ptref,
+                         Standard_Real& U1,
+                         Standard_Real& V1,
+                         Standard_Real& U2,
+                         Standard_Real& V2)
+{
+  IntSurf_Quadric quad1,quad2;
+  //
+  GetQuadric(HS1, quad1);
+  GetQuadric(HS2, quad2);
+  //
+  quad1.Parameters(Ptref,U1,V1);
+  quad2.Parameters(Ptref,U2,V2);
+}
+
 //=======================================================================
-//function : Perform
+//function : ParametersOfNearestPointOnSurface
 //purpose  : 
 //=======================================================================
-void ProjectPointOnSurf::Perform(const gp_Pnt& P)
+static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
+                                                          Standard_Real& theU,
+                                                          Standard_Real& theV)
 {
-  myExtPS.Perform(P);
-  Init ();
+  if(!theExtr.IsDone() || !theExtr.NbExt())
+    return Standard_False;
+
+  Standard_Integer anIndex = 1;
+  Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
+  for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
+  {
+    Standard_Real aSQD = theExtr.SquareDistance(i);
+    if (aSQD < aMinSQDist)
+    {
+      aMinSQDist = aSQD;
+      anIndex = i;
+    }
+  }
+
+  theExtr.Point(anIndex).Parameter(theU, theV);
+
+  return Standard_True;
 }
+
 //=======================================================================
-//function : LowerDistanceParameters
+//function : GetSegmentBoundary
 //purpose  : 
 //=======================================================================
-void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U,
-                                                  Standard_Real& V ) const
+static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
+                                const Handle(Geom2d_Curve)& theCurve,
+                                GeomInt_VectorOfReal& theArrayOfParameters)
 {
-  StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters");
-  (myExtPS.Point(myIndex)).Parameter(U,V);
+  Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
+
+  if(theSegm.HasFirstPoint())
+  {
+    const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
+    aU1 = anIPF.ParamOnFirst();
+  }
+
+  if(theSegm.HasLastPoint())
+  {
+    const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
+    aU2 = anIPL.ParamOnFirst();
+  }
+
+  theArrayOfParameters.Append(aU1);
+  theArrayOfParameters.Append(aU2);
 }
+
 //=======================================================================
-//function : LowerDistance
+//function : IntersectCurveAndBoundary
 //purpose  : 
 //=======================================================================
-Standard_Real ProjectPointOnSurf::LowerDistance() const
+static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
+                                      const Handle(Geom2d_Curve)* const theArrBounds,
+                                      const Standard_Integer theNumberOfCurves,
+                                      const Standard_Real theTol,
+                                      GeomInt_VectorOfReal& theArrayOfParameters)
 {
-  StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance");
-  return sqrt(myExtPS.SquareDistance(myIndex));
+  if(theC2d.IsNull())
+    return;
+
+  Geom2dAdaptor_Curve anAC1(theC2d);
+  for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
+  {
+    if(theArrBounds[aCurID].IsNull())
+      continue;
+
+    Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
+    Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
+
+    if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
+      continue;
+
+    for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
+    {
+      const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
+      theArrayOfParameters.Append(aParam);
+    }
+
+    for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
+    {
+      GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
+    }
+  }
 }
-//
 
 //=======================================================================
 //function : MakeCurve
 //purpose  : 
 //=======================================================================
 void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
-                             const Handle(Adaptor3d_TopolTool) & dom1,
-                             const Handle(Adaptor3d_TopolTool) & dom2,
-                             const Standard_Real Tol,
-                             const Standard_Boolean Approx,
-                             const Standard_Boolean ApproxS1,
-                             const Standard_Boolean ApproxS2)
+                                               const Handle(Adaptor3d_TopolTool) & dom1,
+                                               const Handle(Adaptor3d_TopolTool) & dom2,
+                                               const Standard_Real Tol,
+                                               const Standard_Boolean Approx,
+                                               const Standard_Boolean ApproxS1,
+                                               const Standard_Boolean ApproxS2)
 
 {
   Standard_Boolean myApprox1, myApprox2, myApprox;
@@ -261,13 +256,11 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
   typl = L->ArcType();
   //
   if(typl==IntPatch_Walking) {
-    Handle(IntPatch_Line) anewL = 
-      ComputePurgedWLine(Handle(IntPatch_WLine)::DownCast(L));
-    //
-    if(anewL.IsNull()) {
+    Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
+    if(aWLine.IsNull()) {
       return;
     }
-    L = anewL;
+    L = aWLine;
   }
   //
   // Line Constructor
@@ -562,7 +555,7 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
       GeomInt_WLApprox theapp3d;
       Standard_Real tol2d = myTolApprox;
       //       
-      theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
+      theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
 
       aNbParts=myLConstruct.NbParts();
       for (i=1; i<=aNbParts; i++) {
@@ -658,12 +651,17 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
   }// case IntPatch_Analytic:
   break;
 
-                          //########################################  
-                          // Walking
-                          //######################################## 
+  //########################################  
+  // Walking
+  //######################################## 
   case IntPatch_Walking:{
     Handle(IntPatch_WLine) WL = 
       Handle(IntPatch_WLine)::DownCast(L);
+
+#ifdef OCCT_DEBUG
+    //WL->Dump(0);
+#endif
+
     //
     Standard_Integer ifprm, ilprm;
     //
@@ -700,15 +698,10 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
       //       
       tol2d = myTolApprox;
       aTolSS=2.e-7;
-      if(myHS1 == myHS2) { 
-        theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False);     
-      }
-      else { 
-        theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
-      }
+      theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, myHS1 != myHS2);
       //
       bIsDecomposited = 
-        DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
+        GeomInt_LineTool::DecompositionOfWLine(WL, myHS1, myHS2, aTolSS, myLConstruct, aSeqOfL);
       //
       aNbParts=myLConstruct.NbParts();
       aNbSeqOfL=aSeqOfL.Length();
@@ -749,7 +742,7 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
             if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
               (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
 
-                theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
+                theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
                 //Standard_Boolean bUseSurfaces;
                 //bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm,  ilprm);
                 //if (bUseSurfaces) {
@@ -1082,1065 +1075,43 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
     break;
   }
 }
-//
+
 //=======================================================================
-//function : AdjustUPeriodic
-//purpose  : 
+//function : TreatRLine
+//purpose  : Approx of Restriction line
 //=======================================================================
- static void AdjustUPeriodic (const Handle(Geom_Surface)& aS, const Handle(Geom2d_Curve)& aC2D)
+void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, 
+                const Handle(GeomAdaptor_HSurface)& theHS1, 
+                const Handle(GeomAdaptor_HSurface)& theHS2, 
+                Handle(Geom_Curve)& theC3d,
+                Handle(Geom2d_Curve)& theC2d1, 
+                Handle(Geom2d_Curve)& theC2d2, 
+                Standard_Real& theTolReached)
 {
-  if (aC2D.IsNull() || !aS->IsUPeriodic())
-    return;
-  //
-  const Standard_Real aEps=Precision::PConfusion();//1.e-9
-  const Standard_Real aEpsilon=Epsilon(10.);//1.77e-15 
-  //
-  Standard_Real umin,umax,vmin,vmax;
-  aS->Bounds(umin,umax,vmin,vmax);
-  const Standard_Real aPeriod = aS->UPeriod();
-  
-  const Standard_Real aT1=aC2D->FirstParameter();
-  const Standard_Real aT2=aC2D->LastParameter();
-  const Standard_Real aTx=aT1+0.467*(aT2-aT1);
-  const gp_Pnt2d aPx=aC2D->Value(aTx);
-  //
-  Standard_Real aUx=aPx.X();
-  if (fabs(aUx)<aEpsilon)
-    aUx=0.;
-  if (fabs(aUx-aPeriod)<aEpsilon)
-    aUx=aPeriod;
-  //
-  Standard_Real dU=0.;
-  while(aUx <(umin-aEps)) {
-    aUx+=aPeriod;
-    dU+=aPeriod;
-  }
-  while(aUx>(umax+aEps)) {
-    aUx-=aPeriod;
-    dU-=aPeriod;
-  }
-  // 
-  if (dU!=0.) {
-    gp_Vec2d aV2D(dU, 0.);
-    aC2D->Translate(aV2D);
+  Handle(GeomAdaptor_HSurface) aGAHS;
+  Handle(Adaptor2d_HCurve2d) anAHC2d;
+  Standard_Real tf, tl;
+  gp_Lin2d aL;
+  // It is assumed that 2d curve is 2d line (rectangular surface domain)
+  if(theRL->IsArcOnS1())
+  {
+    aGAHS = theHS1;
+    anAHC2d = theRL->ArcOnS1();
+    theRL->ParamOnS1(tf, tl);
+    theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
+    tf = Max(tf, theC2d1->FirstParameter());
+    tl = Min(tl, theC2d1->LastParameter());
+    theC2d1 = new Geom2d_TrimmedCurve(theC2d1, tf, tl);
   }
-}
-//
-//
-//=======================================================================
-//function : GetQuadric
-//purpose  : 
-//=======================================================================
- static void GetQuadric(const Handle(GeomAdaptor_HSurface)& HS1, IntSurf_Quadric& quad1)
-{
-  switch (HS1->Surface().GetType())
+  else if (theRL->IsArcOnS2())
   {
-    case GeomAbs_Plane:    quad1.SetValue(HS1->Surface().Plane()); break;
-    case GeomAbs_Cylinder: quad1.SetValue(HS1->Surface().Cylinder()); break;
-    case GeomAbs_Cone:     quad1.SetValue(HS1->Surface().Cone()); break;
-    case GeomAbs_Sphere:   quad1.SetValue(HS1->Surface().Sphere()); break;
-    case GeomAbs_Torus:    quad1.SetValue(HS1->Surface().Torus()); break;
-    default: Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
-  }
-}
-
-//=======================================================================
-//function : Parameters
-//purpose  : 
-//=======================================================================
- void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
-                 const Handle(GeomAdaptor_HSurface)& HS2,
-                 const gp_Pnt& Ptref,
-                 Standard_Real& U1,
-                 Standard_Real& V1,
-                 Standard_Real& U2,
-                 Standard_Real& V2)
-{
-  IntSurf_Quadric quad1,quad2;
-  //
-  GetQuadric(HS1, quad1);
-  GetQuadric(HS2, quad2);
-  //
-  quad1.Parameters(Ptref,U1,V1);
-  quad2.Parameters(Ptref,U2,V2);
-}
-
-//=======================================================================
-//function : MakeBSpline
-//purpose  : 
-//=======================================================================
-Handle(Geom_Curve) MakeBSpline  (const Handle(IntPatch_WLine)& WL,
-                                 const Standard_Integer ideb,
-                                 const Standard_Integer ifin)
-{
-  const Standard_Integer nbpnt = ifin-ideb+1;
-  TColgp_Array1OfPnt poles(1,nbpnt);
-  TColStd_Array1OfReal knots(1,nbpnt);
-  TColStd_Array1OfInteger mults(1,nbpnt);
-  Standard_Integer i = 1, ipidebm1 = ideb;
-  for(; i<=nbpnt; ipidebm1++, i++)
-  {
-    poles(i) = WL->Point(ipidebm1).Value();
-    mults(i) = 1;
-    knots(i) = i-1;
-  }
-  mults(1) = mults(nbpnt) = 2;
-  return new Geom_BSplineCurve(poles,knots,mults,1);
-}
-
-//=======================================================================
-//function : MakeBSpline2d
-//purpose  : 
-//=======================================================================
-Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
-                                          const Standard_Integer ideb,
-                                          const Standard_Integer ifin,
-                                          const Standard_Boolean onFirst)
-{
-  const Standard_Integer nbpnt = ifin-ideb+1;
-  TColgp_Array1OfPnt2d poles(1,nbpnt);
-  TColStd_Array1OfReal knots(1,nbpnt);
-  TColStd_Array1OfInteger mults(1,nbpnt);
-  Standard_Integer i = 1, ipidebm1 = ideb;
-  for(; i <= nbpnt; ipidebm1++, i++)
-  {
-    Standard_Real U, V;
-    if(onFirst)
-         theWLine->Point(ipidebm1).ParametersOnS1(U, V);
-    else
-         theWLine->Point(ipidebm1).ParametersOnS2(U, V);
-    poles(i).SetCoord(U, V);
-    mults(i) = 1;
-    knots(i) = i-1;
-  }
-  mults(1) = mults(nbpnt) = 2;
-  return new Geom2d_BSplineCurve(poles,knots,mults,1);
-}
-
-//=========================================================================
-// static function : ComputePurgedWLine
-// purpose : Removes equal points (leave one of equal points) from theWLine
-//           and recompute vertex parameters.
-//           Returns new WLine or null WLine if the number
-//           of the points is less than 2.
-//=========================================================================
-Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) 
-{
-  Handle(IntPatch_WLine) aResult;
-  Handle(IntPatch_WLine) aLocalWLine;
-  Handle(IntPatch_WLine) aTmpWLine = theWLine;
-
-  Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
-  aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
-  Standard_Integer i, k, v, nb, nbvtx;
-  nbvtx = theWLine->NbVertex();
-  nb = theWLine->NbPnts();
-
-  for(i = 1; i <= nb; i++) {
-    aLineOn2S->Add(theWLine->Point(i));
-  }
-
-  for(v = 1; v <= nbvtx; v++) {
-    aLocalWLine->AddVertex(theWLine->Vertex(v));
-  }
-  
-  for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
-    Standard_Integer aStartIndex = i + 1;
-    Standard_Integer anEndIndex = i + 5;
-    nb = aLineOn2S->NbPoints();
-    anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
-
-    if((aStartIndex >= nb) || (anEndIndex <= 1)) {
-      continue;
-    }
-    k = aStartIndex;
-
-    while(k <= anEndIndex) {
-      
-      if(i != k) {
-       IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
-       IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
-       
-       if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
-         aTmpWLine = aLocalWLine;
-         aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
-
-         for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
-           IntPatch_Point aVertex = aTmpWLine->Vertex(v);
-           Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
-
-           if(avertexindex >= k) {
-             aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
-           }
-           aLocalWLine->AddVertex(aVertex);
-         }
-         aLineOn2S->RemovePoint(k);
-         anEndIndex--;
-         continue;
-       }
-      }
-      k++;
-    }
-  }
-
-  if(aLineOn2S->NbPoints() > 1) {
-    aResult = aLocalWLine;
-  }
-  return aResult;
-}
-//=======================================================================
-//function : DecompositionOfWLine
-//purpose  : 
-//=======================================================================
-Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
-                                      const Handle(GeomAdaptor_HSurface)&            theSurface1, 
-                                      const Handle(GeomAdaptor_HSurface)&            theSurface2,
-                                      const Standard_Real aTolSum, 
-                                      const GeomInt_LineConstructor&                 theLConstructor,
-                                      IntPatch_SequenceOfLine&                       theNewLines)
-{
-  typedef NCollection_List<Standard_Integer> ListOfInteger;
-  //have to use std::vector, not NCollection_Vector in order to use copy constructor of
-  //ListOfInteger which will be created with specific allocator instance
-  typedef std::vector<ListOfInteger, NCollection_StdAllocator<
-      ListOfInteger> > ArrayOfListOfInteger;
-
-  Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary;
-  Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex;
-  Standard_Real aTol, umin, umax, vmin, vmax;
-
-  //an inc allocator, it will contain wasted space (upon list's Clear()) but it should
-  //still be faster than the standard allocator, and wasted memory should not be
-  //significant and will be limited by time span of this function;
-  //this is a separate allocator from the anIncAlloc below what provides better data
-  //locality in the latter (by avoiding wastes which will only be in anIdxAlloc)
-  Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator();
-  ListOfInteger aListOfPointIndex (anIdxAlloc);
-
-  //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2;
-  ProjectPointOnSurf aPrj1, aPrj2;
-  Handle(Geom_Surface) aSurf1,  aSurf2;
-  //
-  aNbParts=theLConstructor.NbParts();
-  aNbPnts=theWLine->NbPnts();
-  //
-  if((!aNbPnts) || (!aNbParts)){
-    return Standard_False;
-  }
-  //
-  Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
-  NCollection_StdAllocator<ListOfInteger> anAlloc (anIncAlloc);
-  const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from
-  ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc);
-
-  NCollection_LocalArray<Standard_Integer> anArrayOfLineTypeArr (aNbPnts + 1);
-  Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr;
-  //
-  nblines = 0;
-  aTol = Precision::Confusion();
-  //
-  aSurf1 = theSurface1->ChangeSurface().Surface();
-  aSurf1->Bounds(umin, umax, vmin, vmax);
-  aPrj1.Init(aSurf1, umin, umax, vmin, vmax);
-  //
-  aSurf2 = theSurface2->ChangeSurface().Surface();
-  aSurf2->Bounds(umin, umax, vmin, vmax);
-  aPrj2.Init(aSurf2, umin, umax, vmin, vmax);
-  //
-  //
-  bIsPrevPointOnBoundary=Standard_False;
-  for(pit=1; pit<=aNbPnts; pit++) {
-    const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
-    bIsCurrentPointOnBoundary=Standard_False;
-    //
-    // whether aPoint is on boundary or not
-    //
-    for(i=0; i<2; i++) {// exploration Surface 1,2 
-      Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
-      aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
-      //
-      for(j=0; j<2; j++) {// exploration of coordinate U,V
-       Standard_Boolean isperiodic;
-       //
-       isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
-       if(!isperiodic) {
-         continue;
-       }
-       //
-       Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
-       Standard_Real aParameter, anoffset, anAdjustPar;
-       Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary;
-       //
-       aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
-       aPeriod     = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod();
-       alowerboundary = (!j) ? umin : vmin;
-       aupperboundary = (!j) ? umax : vmax;
-       U=0.;V=0.;//?
-       //
-       if(!i){
-         aPoint.ParametersOnS1(U, V);
-       }
-       else{
-         aPoint.ParametersOnS2(U, V);
-       }
-       //
-       aParameter = (!j) ? U : V;
-       anoffset=0.;
-       anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
-       //
-       bIsOnFirstBoundary=Standard_True;
-       //
-       bIsPointOnBoundary=
-         IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
-       
-       if(bIsPointOnBoundary) {
-         bIsCurrentPointOnBoundary = Standard_True;
-         break;
-       }
-      }// for(j=0; j<2; j++)
-      
-      if(bIsCurrentPointOnBoundary){
-       break;
-      }
-    }// for(i=0; i<2; i++) 
-    //
-    if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
-
-      if(!aListOfPointIndex.IsEmpty()) {
-       nblines++;
-       anArrayOfLines[nblines] = aListOfPointIndex;
-       anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
-       aListOfPointIndex.Clear();
-      }
-      bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
-    }
-    aListOfPointIndex.Append(pit);
-  } // for(pit=1; pit<=aNbPnts; pit++)
-  //
-  aNbListOfPointIndex=aListOfPointIndex.Extent();
-  if(aNbListOfPointIndex) {
-    nblines++;
-    anArrayOfLines[nblines].Assign (aListOfPointIndex);
-    anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
-    aListOfPointIndex.Clear();
-  }
-  //
-  if(nblines <= 1){
-    return Standard_False;
-  }
-  //
-  // Correct wlines.begin
-  Standard_Integer aLineType;
-  TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
-  Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator());
-  //
-  for(i = 1; i <= nblines; i++) {
-    aLineType=anArrayOfLineType[i];
-    if(aLineType) {
-      continue;
-    }
-    //
-    const ListOfInteger& aListOfIndex = anArrayOfLines[i];
-    if(aListOfIndex.Extent() < 2) {
-      continue;
-    }
-    //
-    TColStd_ListOfInteger aListOfFLIndex;
-    Standard_Integer aneighbourindex, aLineTypeNeib;
-    //
-    for(j = 0; j < 2; j++) {// neighbour line choice 
-      aneighbourindex = (!j) ? (i-1) : (i+1);
-      if((aneighbourindex < 1) || (aneighbourindex > nblines)){
-       continue;
-      }
-      //
-      aLineTypeNeib=anArrayOfLineType[aneighbourindex];
-      if(!aLineTypeNeib){
-       continue;
-      }
-      //
-      const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex];
-      Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First();
-      const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
-      // check if need use derivative.begin .end [absence]
-      //
-      IntSurf_PntOn2S aNewP = aPoint;
-      Standard_Integer surfit, parit;
-      //
-      for(surfit = 0; surfit < 2; ++surfit) {
-
-       Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2;
-       
-        umin = aGASurface->FirstUParameter();
-        umax = aGASurface->LastUParameter();
-        vmin = aGASurface->FirstVParameter();
-        vmax = aGASurface->LastVParameter();
-       Standard_Real U=0., V=0.;
-
-       if(!surfit) {
-         aNewP.ParametersOnS1(U, V);
-       }
-       else {
-         aNewP.ParametersOnS2(U, V);
-       }
-       //
-       Standard_Integer nbboundaries = 0;
-       Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
-       Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
-       //
-       for(parit = 0; parit < 2; parit++) {
-         Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
-
-         Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
-         Standard_Real alowerboundary = (!parit) ? umin : vmin;
-         Standard_Real aupperboundary = (!parit) ? umax : vmax;
-
-         Standard_Real aParameter = (!parit) ? U : V;
-         Standard_Boolean bIsOnFirstBoundary = Standard_True;
-  
-         if(!isperiodic) {
-           if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
-             bIsUBoundary = (!parit);
-             bIsFirstBoundary = bIsOnFirstBoundary;
-             nbboundaries++;
-           }
-         }
-         else {
-           Standard_Real aPeriod     = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod();
-           Standard_Real anoffset = 0.;
-           Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
-
-           if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
-             bIsUBoundary = (parit == 0);
-             bIsFirstBoundary = bIsOnFirstBoundary;
-             nbboundaries++;
-           }
-         }
-       }
-       //
-       Standard_Boolean bComputeLineEnd = Standard_False;
-       
-       if(nbboundaries == 2) {
-         bComputeLineEnd = Standard_True;
-       }
-       else if(nbboundaries == 1) {
-         Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
-
-         if(isperiodic) {
-           Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
-           Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
-           Standard_Real aPeriod     = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
-           Standard_Real aParameter = (bIsUBoundary) ? U : V;
-           Standard_Real anoffset = 0.;
-           Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
-
-           Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
-           Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
-           anotherPar += anoffset;
-           Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
-           const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
-           Standard_Real nU1, nV1;
-
-           if(surfit == 0)
-             aNeighbourPoint.ParametersOnS1(nU1, nV1);
-           else
-             aNeighbourPoint.ParametersOnS2(nU1, nV1);
-           
-           Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
-           Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
-           bComputeLineEnd = Standard_True;
-           Standard_Boolean bCheckAngle1 = Standard_False;
-           Standard_Boolean bCheckAngle2 = Standard_False;
-           gp_Vec2d aNewVec;
-           Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
-           Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
-           //
-           if(((adist1 - adist2) > Precision::PConfusion()) && 
-              (adist2 < (aPeriod / 4.))) {
-             bCheckAngle1 = Standard_True;
-             aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
-
-             if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
-               aNewP.SetValue((surfit == 0), anewU, anewV);
-               bCheckAngle1 = Standard_False;
-             }
-           }
-           else if(adist1 < (aPeriod / 4.)) {
-             bCheckAngle2 = Standard_True;
-             aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
-
-             if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
-               bCheckAngle2 = Standard_False;
-             }
-           }
-           //
-           if(bCheckAngle1 || bCheckAngle2) {
-             // assume there are at least two points in line (see "if" above)
-             Standard_Integer anindexother = aneighbourpointindex;
-             
-             while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
-               anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
-               const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
-               Standard_Real nU2, nV2;
-               
-               if(surfit == 0)
-                 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
-               else
-                 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
-               gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
-
-               if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
-                 continue;
-               }
-               else {
-                 Standard_Real anAngle = aNewVec.Angle(aVecOld);
-
-                 if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
-
-                   if(bCheckAngle1) {
-                     Standard_Real U1, U2, V1, V2;
-                     IntSurf_PntOn2S atmppoint = aNewP;
-                     atmppoint.SetValue((surfit == 0), anewU, anewV);
-                     atmppoint.Parameters(U1, V1, U2, V2);
-                     gp_Pnt P1 = theSurface1->Value(U1, V1);
-                     gp_Pnt P2 = theSurface2->Value(U2, V2);
-                     gp_Pnt P0 = aPoint.Value();
-
-                     if(P0.IsEqual(P1, aTol) &&
-                        P0.IsEqual(P2, aTol) &&
-                        P1.IsEqual(P2, aTol)) {
-                       bComputeLineEnd = Standard_False;
-                       aNewP.SetValue((surfit == 0), anewU, anewV);
-                     }
-                   }
-                   
-                   if(bCheckAngle2) {
-                     bComputeLineEnd = Standard_False;
-                   }
-                 }
-                 break;
-               }
-             } // end while(anindexother...)
-           }
-         }
-       }
-       //
-       if(bComputeLineEnd) {
-         Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
-         const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
-         Standard_Real nU1, nV1;
-
-         if(surfit == 0)
-           aNeighbourPoint.ParametersOnS1(nU1, nV1);
-         else
-           aNeighbourPoint.ParametersOnS2(nU1, nV1);
-         gp_Pnt2d ap1(nU1, nV1);
-         gp_Pnt2d ap2(nU1, nV1);
-         Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
-
-         while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
-           aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
-           const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
-           Standard_Real nU2, nV2;
-
-           if(surfit == 0)
-             aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
-           else
-             aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
-           ap2.SetX(nU2);
-           ap2.SetY(nV2);
-
-           if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
-             break;
-           }
-         }       
-         gp_Pnt2d anewpoint;
-         Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
-
-         if(found) {
-           // check point
-           Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
-           //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
-           ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
-           Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
-
-           gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
-           aProjector.Perform(aP3d);
-
-           if(aProjector.IsDone()) {
-             if(aProjector.LowerDistance() < aCriteria) {
-               Standard_Real foundU = U, foundV = V;
-               aProjector.LowerDistanceParameters(foundU, foundV);
-
-               if(surfit == 0)
-                 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
-               else
-                 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
-             }
-           }
-         }
-       }
-      }
-      aSeqOfPntOn2S->Add(aNewP);
-      aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
-    }
-    anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
-  }
-  // Correct wlines.end
-
-  // Split wlines.begin
-  for(j = 1; j <= theLConstructor.NbParts(); j++) {
-    Standard_Real fprm = 0., lprm = 0.;
-    theLConstructor.Part(j, fprm, lprm);
-    Standard_Integer ifprm = (Standard_Integer)fprm;
-    Standard_Integer ilprm = (Standard_Integer)lprm;
-    //
-    Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
-    //
-    for(i = 1; i <= nblines; i++) {
-      if(anArrayOfLineType[i] != 0) {
-       continue;
-      }
-      const ListOfInteger& aListOfIndex = anArrayOfLines[i];
-
-      if(aListOfIndex.Extent() < 2) {
-       continue;
-      }
-      const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
-      Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
-      Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
-
-      if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
-       bhasfirstpoint = (i != 1);
-      }
-
-      if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
-       bhaslastpoint = (i != nblines);
-      }
-      Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
-      Standard_Boolean bIsLastInside =  ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
-
-      if(!bIsFirstInside && !bIsLastInside) {
-       if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
-         // append whole line, and boundaries if neccesary
-         if(bhasfirstpoint) {
-           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
-           aLineOn2S->Add(aP);
-         }
-         ListOfInteger::Iterator anIt(aListOfIndex);
-
-         for(; anIt.More(); anIt.Next()) {
-           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
-           aLineOn2S->Add(aP);
-         }
-
-         if(bhaslastpoint) {
-           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
-           aLineOn2S->Add(aP);
-         }
-
-         // check end of split line (end is almost always)
-         Standard_Integer aneighbour = i + 1;
-         Standard_Boolean bIsEndOfLine = Standard_True;
-
-         if(aneighbour <= nblines) {
-           const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
-
-           if((anArrayOfLineType[aneighbour] != 0) &&
-              (aListOfNeighbourIndex.IsEmpty())) {
-             bIsEndOfLine = Standard_False;
-           }
-         }
-
-         if(bIsEndOfLine) {
-           if(aLineOn2S->NbPoints() > 1) {
-             Handle(IntPatch_WLine) aNewWLine = 
-               new IntPatch_WLine(aLineOn2S, Standard_False);
-             theNewLines.Append(aNewWLine);
-           }
-           aLineOn2S = new IntSurf_LineOn2S();
-         }
-       }
-       continue;
-      }
-      // end if(!bIsFirstInside && !bIsLastInside)
-
-      if(bIsFirstInside && bIsLastInside) {
-       // append inside points between ifprm and ilprm
-       ListOfInteger::Iterator anIt(aListOfIndex);
-
-       for(; anIt.More(); anIt.Next()) {
-         if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
-           continue;
-         const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
-         aLineOn2S->Add(aP);
-       }
-      }
-      else {
-
-       if(bIsFirstInside) {
-         // append points from ifprm to last point + boundary point
-         ListOfInteger::Iterator anIt(aListOfIndex);
-
-         for(; anIt.More(); anIt.Next()) {
-           if(anIt.Value() < ifprm)
-             continue;
-           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
-           aLineOn2S->Add(aP);
-         }
-
-         if(bhaslastpoint) {
-           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
-           aLineOn2S->Add(aP);
-         }
-         // check end of split line (end is almost always)
-         Standard_Integer aneighbour = i + 1;
-         Standard_Boolean bIsEndOfLine = Standard_True;
-
-         if(aneighbour <= nblines) {
-           const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
-
-           if((anArrayOfLineType[aneighbour] != 0) &&
-              (aListOfNeighbourIndex.IsEmpty())) {
-             bIsEndOfLine = Standard_False;
-           }
-         }
-
-         if(bIsEndOfLine) {
-           if(aLineOn2S->NbPoints() > 1) {
-             Handle(IntPatch_WLine) aNewWLine = 
-               new IntPatch_WLine(aLineOn2S, Standard_False);
-             theNewLines.Append(aNewWLine);
-           }
-           aLineOn2S = new IntSurf_LineOn2S();
-         }
-       }
-       // end if(bIsFirstInside)
-
-       if(bIsLastInside) {
-         // append points from first boundary point to ilprm
-         if(bhasfirstpoint) {
-           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
-           aLineOn2S->Add(aP);
-         }
-         ListOfInteger::Iterator anIt(aListOfIndex);
-
-         for(; anIt.More(); anIt.Next()) {
-           if(anIt.Value() > ilprm)
-             continue;
-           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
-           aLineOn2S->Add(aP);
-         }
-       }
-       //end if(bIsLastInside)
-      }
-    }
-
-    if(aLineOn2S->NbPoints() > 1) {
-      Handle(IntPatch_WLine) aNewWLine = 
-       new IntPatch_WLine(aLineOn2S, Standard_False);
-      theNewLines.Append(aNewWLine);
-    }
-  }
-  // Split wlines.end
-  //
-  // cda002/I3
-  Standard_Real fprm, lprm;
-  Standard_Integer ifprm, ilprm, aNbPoints, aIndex;
-  //
-  aNbParts=theLConstructor.NbParts();
-  //
-  for(j = 1; j <= aNbParts; j++) {
-    theLConstructor.Part(j, fprm, lprm);
-    ifprm=(Standard_Integer)fprm;
-    ilprm=(Standard_Integer)lprm;
-    //
-    if ((ilprm-ifprm)==1) {
-      for(i = 1; i <= nblines; i++) {
-       aLineType=anArrayOfLineType[i];
-       if(aLineType) {
-         continue;
-       }
-       //
-       const ListOfInteger& aListOfIndex = anArrayOfLines[i];
-       aNbPoints=aListOfIndex.Extent();
-       if(aNbPoints==1) {
-         aIndex=aListOfIndex.First();
-         if (aIndex==ifprm || aIndex==ilprm) {
-           Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
-           const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm);
-           const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm);
-           aLineOn2S->Add(aP1);
-           aLineOn2S->Add(aP2);
-           Handle(IntPatch_WLine) aNewWLine = 
-             new IntPatch_WLine(aLineOn2S, Standard_False);
-           theNewLines.Append(aNewWLine);
-         }
-       }
-      }
-    }
-  }
-  //
-  return Standard_True;
-}
-
-//=======================================================================
-//function : AdjustPeriodic
-//purpose  : 
-//=======================================================================
-Standard_Real AdjustPeriodic(const Standard_Real theParameter,
-                             const Standard_Real parmin,
-                             const Standard_Real parmax,
-                             const Standard_Real thePeriod,
-                             Standard_Real&      theOffset)
-{
-  Standard_Real aresult = theParameter;
-  theOffset = 0.;
-  while(aresult < parmin) {
-    aresult += thePeriod;
-    theOffset += thePeriod;
-  }
-  while(aresult > parmax) {
-    aresult -= thePeriod;
-    theOffset -= thePeriod;
-  }
-  return aresult;
-}
-
-//=======================================================================
-//function : IsPointOnBoundary
-//purpose  : 
-//=======================================================================
-Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
-                                   const Standard_Real theFirstBoundary,
-                                   const Standard_Real theSecondBoundary,
-                                   const Standard_Real theResolution,
-                                   Standard_Boolean&   IsOnFirstBoundary)
-{
-  IsOnFirstBoundary = Standard_True;
-  if(fabs(theParameter - theFirstBoundary) < theResolution)
-    return Standard_True;
-  if(fabs(theParameter - theSecondBoundary) < theResolution)
-  {
-    IsOnFirstBoundary = Standard_False;
-    return Standard_True;
-  }
-  return Standard_False;
-}
-//=======================================================================
-//function : FindPoint
-//purpose  : 
-//=======================================================================
-Standard_Boolean FindPoint(const gp_Pnt2d&     theFirstPoint,
-                           const gp_Pnt2d&     theLastPoint,
-                           const Standard_Real theUmin,
-                           const Standard_Real theUmax,
-                           const Standard_Real theVmin,
-                           const Standard_Real theVmax,
-                           gp_Pnt2d&           theNewPoint)
-{
-  gp_Vec2d aVec(theFirstPoint, theLastPoint);
-  Standard_Integer i = 0, j = 0;
-
-  for(i = 0; i < 4; i++) {
-    gp_Vec2d anOtherVec;
-    gp_Vec2d anOtherVecNormal;
-    gp_Pnt2d aprojpoint = theLastPoint;    
-
-    if((i % 2) == 0) {
-      anOtherVec.SetX(0.);
-      anOtherVec.SetY(1.);
-      anOtherVecNormal.SetX(1.);
-      anOtherVecNormal.SetY(0.);
-
-      if(i < 2)
-       aprojpoint.SetX(theUmin);
-      else
-       aprojpoint.SetX(theUmax);
-    }
-    else {
-      anOtherVec.SetX(1.);
-      anOtherVec.SetY(0.);
-      anOtherVecNormal.SetX(0.);
-      anOtherVecNormal.SetY(1.);
-
-      if(i < 2)
-       aprojpoint.SetY(theVmin);
-      else
-       aprojpoint.SetY(theVmax);
-    }
-    gp_Vec2d anormvec = aVec;
-    anormvec.Normalize();
-    Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
-
-    if(fabs(adot1) < Precision::Angular())
-      continue;
-    Standard_Real adist = 0.;
-
-    if((i % 2) == 0) {
-      adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
-    }
-    else {
-      adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
-    }
-    Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
-
-    for(j = 0; j < 2; j++) {
-      anoffset = (j == 0) ? anoffset : -anoffset;
-      gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
-      gp_Vec2d acurvec(theLastPoint, acurpoint);
-
-      //
-      Standard_Real aDotX, anAngleX, aPC;
-      //
-      aDotX=aVec.Dot(acurvec);
-      anAngleX=aVec.Angle(acurvec);
-      aPC=Precision::PConfusion();
-      //
-      if(aDotX > 0. && fabs(anAngleX) < aPC) {
-      //
-       if((i % 2) == 0) {
-         if((acurpoint.Y() >= theVmin) &&
-            (acurpoint.Y() <= theVmax)) {
-           theNewPoint = acurpoint;
-           return Standard_True;
-         }
-       }
-       else {
-         if((acurpoint.X() >= theUmin) &&
-            (acurpoint.X() <= theUmax)) {
-           theNewPoint = acurpoint;
-           return Standard_True;
-         }
-       }
-      }
-    }
-  }
-  return Standard_False;
-}
-
-//=======================================================================
-//function : ParametersOfNearestPointOnSurface
-//purpose  : 
-//=======================================================================
-static Standard_Boolean ParametersOfNearestPointOnSurface(const Extrema_ExtPS theExtr,
-                                                          Standard_Real& theU,
-                                                          Standard_Real& theV)
-{
-  if(!theExtr.IsDone() || !theExtr.NbExt())
-    return Standard_False;
-
-  Standard_Integer anIndex = 1;
-  Standard_Real aMinSQDist = theExtr.SquareDistance(anIndex);
-  for(Standard_Integer i = 2; i <= theExtr.NbExt(); i++)
-  {
-    Standard_Real aSQD = theExtr.SquareDistance(i);
-    if (aSQD < aMinSQDist)
-    {
-      aMinSQDist = aSQD;
-      anIndex = i;
-    }
-  }
-
-  theExtr.Point(anIndex).Parameter(theU, theV);
-
-  return Standard_True;
-}
-
-//=======================================================================
-//function : GetSegmentBoundary
-//purpose  : 
-//=======================================================================
-static void GetSegmentBoundary( const IntRes2d_IntersectionSegment& theSegm,
-                                const Handle(Geom2d_Curve)& theCurve,
-                                GeomInt_VectorOfReal& theArrayOfParameters)
-{
-  Standard_Real aU1 = theCurve->FirstParameter(), aU2 = theCurve->LastParameter();
-
-  if(theSegm.HasFirstPoint())
-  {
-    const IntRes2d_IntersectionPoint& anIPF = theSegm.FirstPoint();
-    aU1 = anIPF.ParamOnFirst();
-  }
-
-  if(theSegm.HasLastPoint())
-  {
-    const IntRes2d_IntersectionPoint& anIPL = theSegm.LastPoint();
-    aU2 = anIPL.ParamOnFirst();
-  }
-
-  theArrayOfParameters.Append(aU1);
-  theArrayOfParameters.Append(aU2);
-}
-
-//=======================================================================
-//function : IntersectCurveAndBoundary
-//purpose  : 
-//=======================================================================
-static void IntersectCurveAndBoundary(const Handle(Geom2d_Curve)& theC2d,
-                                      const Handle(Geom2d_Curve)* const theArrBounds,
-                                      const Standard_Integer theNumberOfCurves,
-                                      const Standard_Real theTol,
-                                      GeomInt_VectorOfReal& theArrayOfParameters)
-{
-  if(theC2d.IsNull())
-    return;
-
-  Geom2dAdaptor_Curve anAC1(theC2d);
-  for(Standard_Integer aCurID = 0; aCurID < theNumberOfCurves; aCurID++)
-  {
-    if(theArrBounds[aCurID].IsNull())
-      continue;
-
-    Geom2dAdaptor_Curve anAC2(theArrBounds[aCurID]);
-    Geom2dInt_GInter anIntCC2d(anAC1, anAC2, theTol, theTol);
-
-    if(!anIntCC2d.IsDone() || anIntCC2d.IsEmpty())
-      continue;
-
-    for (Standard_Integer aPntID = 1; aPntID <= anIntCC2d.NbPoints(); aPntID++)
-    {
-      const Standard_Real aParam = anIntCC2d.Point(aPntID).ParamOnFirst();
-      theArrayOfParameters.Append(aParam);
-    }
-
-    for (Standard_Integer aSegmID = 1; aSegmID <= anIntCC2d.NbSegments(); aSegmID++)
-    {
-      GetSegmentBoundary(anIntCC2d.Segment(aSegmID), theC2d, theArrayOfParameters);
-    }
-  }
-}
-
-//=======================================================================
-//function : TreatRLine
-//purpose  : Approx of Restriction line
-//=======================================================================
-void GeomInt_IntSS::TreatRLine(const Handle(IntPatch_RLine)& theRL, 
-                const Handle(GeomAdaptor_HSurface)& theHS1, 
-                const Handle(GeomAdaptor_HSurface)& theHS2, 
-                Handle(Geom_Curve)& theC3d,
-                Handle(Geom2d_Curve)& theC2d1, 
-                Handle(Geom2d_Curve)& theC2d2, 
-                Standard_Real& theTolReached)
-{
-  Handle(GeomAdaptor_HSurface) aGAHS;
-  Handle(Adaptor2d_HCurve2d) anAHC2d;
-  Standard_Real tf, tl;
-  gp_Lin2d aL;
-  // It is assumed that 2d curve is 2d line (rectangular surface domain)
-  if(theRL->IsArcOnS1())
-  {
-    aGAHS = theHS1;
-    anAHC2d = theRL->ArcOnS1();
-    theRL->ParamOnS1(tf, tl);
-    theC2d1 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
-  }
-  else if (theRL->IsArcOnS2())
-  {
-    aGAHS = theHS2;
-    anAHC2d = theRL->ArcOnS2();
-    theRL->ParamOnS2(tf, tl);
-    theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
+    aGAHS = theHS2;
+    anAHC2d = theRL->ArcOnS2();
+    theRL->ParamOnS2(tf, tl);
+    theC2d2 = Geom2dAdaptor::MakeCurve(anAHC2d->Curve2d());
+    tf = Max(tf, theC2d2->FirstParameter());
+    tl = Min(tl, theC2d2->LastParameter());
+    theC2d2 = new Geom2d_TrimmedCurve(theC2d2, tf, tl);
   }
   else
   {
@@ -2386,3 +1357,57 @@ void GeomInt_IntSS::TrimILineOnSurfBoundaries(const Handle(Geom2d_Curve)& theC2d
 
   std::sort(theArrayOfParameters.begin(), theArrayOfParameters.end());
 }
+
+//=======================================================================
+//function : MakeBSpline
+//purpose  : 
+//=======================================================================
+Handle(Geom_Curve) GeomInt_IntSS::MakeBSpline  (const Handle(IntPatch_WLine)& WL,
+                                                const Standard_Integer ideb,
+                                                const Standard_Integer ifin)
+{
+  const Standard_Integer nbpnt = ifin-ideb+1;
+  TColgp_Array1OfPnt poles(1,nbpnt);
+  TColStd_Array1OfReal knots(1,nbpnt);
+  TColStd_Array1OfInteger mults(1,nbpnt);
+  Standard_Integer i = 1, ipidebm1 = ideb;
+  for(; i<=nbpnt; ipidebm1++, i++)
+  {
+    poles(i) = WL->Point(ipidebm1).Value();
+    mults(i) = 1;
+    knots(i) = i-1;
+  }
+  mults(1) = mults(nbpnt) = 2;
+  return new Geom_BSplineCurve(poles,knots,mults,1);
+}
+
+//=======================================================================
+//function : MakeBSpline2d
+//purpose  : 
+//=======================================================================
+Handle(Geom2d_BSplineCurve) GeomInt_IntSS::
+      MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
+                    const Standard_Integer ideb,
+                    const Standard_Integer ifin,
+                    const Standard_Boolean onFirst)
+{
+  const Standard_Integer nbpnt = ifin-ideb+1;
+  TColgp_Array1OfPnt2d poles(1,nbpnt);
+  TColStd_Array1OfReal knots(1,nbpnt);
+  TColStd_Array1OfInteger mults(1,nbpnt);
+  Standard_Integer i = 1, ipidebm1 = ideb;
+  for(; i <= nbpnt; ipidebm1++, i++)
+  {
+    Standard_Real U, V;
+    if(onFirst)
+         theWLine->Point(ipidebm1).ParametersOnS1(U, V);
+    else
+         theWLine->Point(ipidebm1).ParametersOnS2(U, V);
+    poles(i).SetCoord(U, V);
+    mults(i) = 1;
+    knots(i) = i-1;
+  }
+
+  mults(1) = mults(nbpnt) = 2;
+  return new Geom2d_BSplineCurve(poles,knots,mults,1);
+}
index 97b5069..5dcf43d 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
+#include <vector>
 #include <GeomInt_LineTool.hxx>
+
+#include <Extrema_ExtPS.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Geom_Surface.hxx>
 #include <IntPatch_ALine.hxx>
 #include <IntPatch_GLine.hxx>
-#include <IntPatch_Line.hxx>
-#include <IntPatch_Point.hxx>
 #include <IntPatch_RLine.hxx>
 #include <IntPatch_WLine.hxx>
-#include <Precision.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <NCollection_List.hxx>
+#include <NCollection_LocalArray.hxx>
+#include <NCollection_StdAllocator.hxx>
+#include <TColStd_Array1OfListOfInteger.hxx>
+
+class ProjectPointOnSurf
+{
+ public:
+  ProjectPointOnSurf() : myIsDone (Standard_False),myIndex(0) {}
+  void Init(const Handle(Geom_Surface)& Surface,
+           const Standard_Real Umin,
+           const Standard_Real Usup,
+           const Standard_Real Vmin,
+           const Standard_Real Vsup);
+  void Init ();
+  void Perform(const gp_Pnt& P);
+  Standard_Boolean IsDone () const { return myIsDone; }
+  void LowerDistanceParameters(Standard_Real& U, Standard_Real& V ) const;
+  Standard_Real LowerDistance() const;
+ protected:
+  Standard_Boolean myIsDone;
+  Standard_Integer myIndex;
+  Extrema_ExtPS myExtPS;
+  GeomAdaptor_Surface myGeomAdaptor;
+};
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void ProjectPointOnSurf::Init ( const Handle(Geom_Surface)& Surface,
+                                const Standard_Real Umin,
+                                const Standard_Real Usup,
+                                const Standard_Real Vmin,
+                                const Standard_Real Vsup )
+{
+  const Standard_Real Tolerance = Precision::PConfusion();
+  //
+  myGeomAdaptor.Load(Surface, Umin,Usup,Vmin,Vsup);
+  myExtPS.Initialize(myGeomAdaptor, Umin, Usup, Vmin, Vsup, Tolerance, Tolerance);
+  myIsDone = Standard_False;
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+void ProjectPointOnSurf::Init ()
+{
+  myIsDone = myExtPS.IsDone() && (myExtPS.NbExt() > 0);
+  if (myIsDone) {
+    // evaluate the lower distance and its index;
+    Standard_Real Dist2Min = myExtPS.SquareDistance(1);
+    myIndex = 1;
+    for (Standard_Integer i = 2; i <= myExtPS.NbExt(); i++)
+    {
+      const Standard_Real Dist2 = myExtPS.SquareDistance(i);
+      if (Dist2 < Dist2Min) {
+        Dist2Min = Dist2;
+        myIndex = i;
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void ProjectPointOnSurf::Perform(const gp_Pnt& P)
+{
+  myExtPS.Perform(P);
+  Init ();
+}
+
+//=======================================================================
+//function : LowerDistanceParameters
+//purpose  : 
+//=======================================================================
+void ProjectPointOnSurf::LowerDistanceParameters (Standard_Real& U,
+                                                  Standard_Real& V ) const
+{
+  StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistanceParameters");
+  (myExtPS.Point(myIndex)).Parameter(U,V);
+}
+
+//=======================================================================
+//function : LowerDistance
+//purpose  : 
+//=======================================================================
+Standard_Real ProjectPointOnSurf::LowerDistance() const
+{
+  StdFail_NotDone_Raise_if(!myIsDone, "GeomInt_IntSS::ProjectPointOnSurf::LowerDistance");
+  return sqrt(myExtPS.SquareDistance(myIndex));
+}
+
+//=======================================================================
+//function : AdjustPeriodic
+//purpose  : 
+//=======================================================================
+static Standard_Real AdjustPeriodic(const Standard_Real theParameter,
+                                    const Standard_Real parmin,
+                                    const Standard_Real parmax,
+                                    const Standard_Real thePeriod,
+                                    Standard_Real&      theOffset)
+{
+  Standard_Real aresult = theParameter;
+  theOffset = 0.;
+  while(aresult < parmin) {
+    aresult += thePeriod;
+    theOffset += thePeriod;
+  }
+  while(aresult > parmax) {
+    aresult -= thePeriod;
+    theOffset -= thePeriod;
+  }
+  return aresult;
+}
+
+//=======================================================================
+//function : IsPointOnBoundary
+//purpose  : 
+//=======================================================================
+static Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
+                                          const Standard_Real theFirstBoundary,
+                                          const Standard_Real theSecondBoundary,
+                                          const Standard_Real theResolution,
+                                          Standard_Boolean&   IsOnFirstBoundary)
+{
+  IsOnFirstBoundary = Standard_True;
+  if(fabs(theParameter - theFirstBoundary) < theResolution)
+    return Standard_True;
+  if(fabs(theParameter - theSecondBoundary) < theResolution)
+  {
+    IsOnFirstBoundary = Standard_False;
+    return Standard_True;
+  }
+  return Standard_False;
+}
+
+//=======================================================================
+//function : FindPoint
+//purpose  : 
+//=======================================================================
+static Standard_Boolean FindPoint(const gp_Pnt2d&     theFirstPoint,
+                                  const gp_Pnt2d&     theLastPoint,
+                                  const Standard_Real theUmin,
+                                  const Standard_Real theUmax,
+                                  const Standard_Real theVmin,
+                                  const Standard_Real theVmax,
+                                  gp_Pnt2d&           theNewPoint)
+{
+  gp_Vec2d aVec(theFirstPoint, theLastPoint);
+  Standard_Integer i = 0, j = 0;
+
+  for(i = 0; i < 4; i++) {
+    gp_Vec2d anOtherVec;
+    gp_Vec2d anOtherVecNormal;
+    gp_Pnt2d aprojpoint = theLastPoint;    
+
+    if((i % 2) == 0) {
+      anOtherVec.SetX(0.);
+      anOtherVec.SetY(1.);
+      anOtherVecNormal.SetX(1.);
+      anOtherVecNormal.SetY(0.);
+
+      if(i < 2)
+       aprojpoint.SetX(theUmin);
+      else
+       aprojpoint.SetX(theUmax);
+    }
+    else {
+      anOtherVec.SetX(1.);
+      anOtherVec.SetY(0.);
+      anOtherVecNormal.SetX(0.);
+      anOtherVecNormal.SetY(1.);
+
+      if(i < 2)
+       aprojpoint.SetY(theVmin);
+      else
+       aprojpoint.SetY(theVmax);
+    }
+    gp_Vec2d anormvec = aVec;
+    anormvec.Normalize();
+    Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
+
+    if(fabs(adot1) < Precision::Angular())
+      continue;
+    Standard_Real adist = 0.;
+
+    if((i % 2) == 0) {
+      adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
+    }
+    else {
+      adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
+    }
+    Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
+
+    for(j = 0; j < 2; j++) {
+      anoffset = (j == 0) ? anoffset : -anoffset;
+      gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
+      gp_Vec2d acurvec(theLastPoint, acurpoint);
+
+      //
+      Standard_Real aDotX, anAngleX, aPC;
+      //
+      aDotX=aVec.Dot(acurvec);
+      anAngleX=aVec.Angle(acurvec);
+      aPC=Precision::PConfusion();
+      //
+      if(aDotX > 0. && fabs(anAngleX) < aPC) {
+      //
+       if((i % 2) == 0) {
+         if((acurpoint.Y() >= theVmin) &&
+            (acurpoint.Y() <= theVmax)) {
+           theNewPoint = acurpoint;
+           return Standard_True;
+         }
+       }
+       else {
+         if((acurpoint.X() >= theUmin) &&
+            (acurpoint.X() <= theUmax)) {
+           theNewPoint = acurpoint;
+           return Standard_True;
+         }
+       }
+      }
+    }
+  }
+  return Standard_False;
+}
+
 
 //=======================================================================
 //function : NbVertex
@@ -164,3 +399,600 @@ Standard_Real GeomInt_LineTool::LastParameter (const Handle(IntPatch_Line)& L)
   }
   return 0.0;
 }
+
+//=======================================================================
+//function : DecompositionOfWLine
+//purpose  : 
+//=======================================================================
+Standard_Boolean GeomInt_LineTool::
+            DecompositionOfWLine( const Handle(IntPatch_WLine)& theWLine,
+                                  const Handle(GeomAdaptor_HSurface)& theSurface1,
+                                  const Handle(GeomAdaptor_HSurface)& theSurface2,
+                                  const Standard_Real aTolSum,
+                                  const GeomInt_LineConstructor& theLConstructor,
+                                  IntPatch_SequenceOfLine& theNewLines)
+{
+  typedef NCollection_List<Standard_Integer> ListOfInteger;
+  //have to use std::vector, not NCollection_Vector in order to use copy constructor of
+  //ListOfInteger which will be created with specific allocator instance
+  typedef std::vector<ListOfInteger, NCollection_StdAllocator<
+      ListOfInteger> > ArrayOfListOfInteger;
+
+  Standard_Boolean bIsPrevPointOnBoundary, bIsCurrentPointOnBoundary;
+  Standard_Integer nblines, aNbPnts, aNbParts, pit, i, j, aNbListOfPointIndex;
+  Standard_Real aTol, umin, umax, vmin, vmax;
+
+  //an inc allocator, it will contain wasted space (upon list's Clear()) but it should
+  //still be faster than the standard allocator, and wasted memory should not be
+  //significant and will be limited by time span of this function;
+  //this is a separate allocator from the anIncAlloc below what provides better data
+  //locality in the latter (by avoiding wastes which will only be in anIdxAlloc)
+  Handle(NCollection_IncAllocator) anIdxAlloc = new NCollection_IncAllocator();
+  ListOfInteger aListOfPointIndex (anIdxAlloc);
+
+  //GeomAPI_ProjectPointOnSurf aPrj1, aPrj2;
+  ProjectPointOnSurf aPrj1, aPrj2;
+  Handle(Geom_Surface) aSurf1,  aSurf2;
+  //
+  aNbParts=theLConstructor.NbParts();
+  aNbPnts=theWLine->NbPnts();
+  //
+  if((!aNbPnts) || (!aNbParts)){
+    return Standard_False;
+  }
+  //
+  Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
+  NCollection_StdAllocator<ListOfInteger> anAlloc (anIncAlloc);
+  const ListOfInteger aDummy (anIncAlloc); //empty list to be copy constructed from
+  ArrayOfListOfInteger anArrayOfLines (aNbPnts + 1, aDummy, anAlloc);
+
+  NCollection_LocalArray<Standard_Integer> anArrayOfLineTypeArr (aNbPnts + 1);
+  Standard_Integer* anArrayOfLineType = anArrayOfLineTypeArr;
+  //
+  nblines = 0;
+  aTol = Precision::Confusion();
+  //
+  aSurf1 = theSurface1->ChangeSurface().Surface();
+  aSurf1->Bounds(umin, umax, vmin, vmax);
+  aPrj1.Init(aSurf1, umin, umax, vmin, vmax);
+  //
+  aSurf2 = theSurface2->ChangeSurface().Surface();
+  aSurf2->Bounds(umin, umax, vmin, vmax);
+  aPrj2.Init(aSurf2, umin, umax, vmin, vmax);
+  //
+  //
+  bIsPrevPointOnBoundary=Standard_False;
+  for(pit=1; pit<=aNbPnts; pit++) {
+    const IntSurf_PntOn2S& aPoint = theWLine->Point(pit);
+    bIsCurrentPointOnBoundary=Standard_False;
+    //
+    // whether aPoint is on boundary or not
+    //
+    for(i=0; i<2; i++) {// exploration Surface 1,2 
+      Handle(GeomAdaptor_HSurface) aGASurface = (!i) ? theSurface1 : theSurface2;
+      aGASurface->ChangeSurface().Surface()->Bounds(umin, umax, vmin, vmax);
+      //
+      for(j=0; j<2; j++) {// exploration of coordinate U,V
+       Standard_Boolean isperiodic;
+       //
+       isperiodic = (!j) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
+       if(!isperiodic) {
+         continue;
+       }
+       //
+       Standard_Real aResolution, aPeriod, alowerboundary, aupperboundary, U, V;
+       Standard_Real aParameter, anoffset, anAdjustPar;
+       Standard_Boolean bIsOnFirstBoundary, bIsPointOnBoundary;
+       //
+       aResolution = (!j) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
+       aPeriod     = (!j) ? aGASurface->UPeriod() : aGASurface->VPeriod();
+       alowerboundary = (!j) ? umin : vmin;
+       aupperboundary = (!j) ? umax : vmax;
+       U=0.;V=0.;//?
+       //
+       if(!i){
+         aPoint.ParametersOnS1(U, V);
+       }
+       else{
+         aPoint.ParametersOnS2(U, V);
+       }
+       //
+       aParameter = (!j) ? U : V;
+       anoffset=0.;
+       anAdjustPar=AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
+       //
+       bIsOnFirstBoundary=Standard_True;
+       //
+       bIsPointOnBoundary=
+         IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary);
+       
+       if(bIsPointOnBoundary) {
+         bIsCurrentPointOnBoundary = Standard_True;
+         break;
+       }
+      }// for(j=0; j<2; j++)
+      
+      if(bIsCurrentPointOnBoundary){
+       break;
+      }
+    }// for(i=0; i<2; i++) 
+    //
+    if((bIsCurrentPointOnBoundary != bIsPrevPointOnBoundary)) {
+
+      if(!aListOfPointIndex.IsEmpty()) {
+       nblines++;
+       anArrayOfLines[nblines] = aListOfPointIndex;
+       anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
+       aListOfPointIndex.Clear();
+      }
+      bIsPrevPointOnBoundary = bIsCurrentPointOnBoundary;
+    }
+    aListOfPointIndex.Append(pit);
+  } // for(pit=1; pit<=aNbPnts; pit++)
+  //
+  aNbListOfPointIndex=aListOfPointIndex.Extent();
+  if(aNbListOfPointIndex) {
+    nblines++;
+    anArrayOfLines[nblines].Assign (aListOfPointIndex);
+    anArrayOfLineType[nblines] = bIsPrevPointOnBoundary;
+    aListOfPointIndex.Clear();
+  }
+  //
+  if(nblines <= 1){
+    return Standard_False;
+  }
+  //
+  // Correct wlines.begin
+  Standard_Integer aLineType;
+  TColStd_Array1OfListOfInteger anArrayOfLineEnds(1, nblines);
+  Handle(IntSurf_LineOn2S) aSeqOfPntOn2S = new IntSurf_LineOn2S (new NCollection_IncAllocator());
+  //
+  for(i = 1; i <= nblines; i++) {
+    aLineType=anArrayOfLineType[i];
+    if(aLineType) {
+      continue;
+    }
+    //
+    const ListOfInteger& aListOfIndex = anArrayOfLines[i];
+    if(aListOfIndex.Extent() < 2) {
+      continue;
+    }
+    //
+    TColStd_ListOfInteger aListOfFLIndex;
+    Standard_Integer aneighbourindex, aLineTypeNeib;
+    //
+    for(j = 0; j < 2; j++) {// neighbour line choice 
+      aneighbourindex = (!j) ? (i-1) : (i+1);
+      if((aneighbourindex < 1) || (aneighbourindex > nblines)){
+       continue;
+      }
+      //
+      aLineTypeNeib=anArrayOfLineType[aneighbourindex];
+      if(!aLineTypeNeib){
+       continue;
+      }
+      //
+      const ListOfInteger& aNeighbour = anArrayOfLines[aneighbourindex];
+      Standard_Integer anIndex = (!j) ? aNeighbour.Last() : aNeighbour.First();
+      const IntSurf_PntOn2S& aPoint = theWLine->Point(anIndex);
+      // check if need use derivative.begin .end [absence]
+      //
+      IntSurf_PntOn2S aNewP = aPoint;
+      Standard_Integer surfit, parit;
+      //
+      for(surfit = 0; surfit < 2; ++surfit) {
+
+       Handle(GeomAdaptor_HSurface) aGASurface = (!surfit) ? theSurface1 : theSurface2;
+       
+        umin = aGASurface->FirstUParameter();
+        umax = aGASurface->LastUParameter();
+        vmin = aGASurface->FirstVParameter();
+        vmax = aGASurface->LastVParameter();
+       Standard_Real U=0., V=0.;
+
+       if(!surfit) {
+         aNewP.ParametersOnS1(U, V);
+       }
+       else {
+         aNewP.ParametersOnS2(U, V);
+       }
+       //
+       Standard_Integer nbboundaries = 0;
+       Standard_Integer bIsUBoundary = Standard_False; // use if nbboundaries == 1
+       Standard_Integer bIsFirstBoundary = Standard_False; // use if nbboundaries == 1
+       //
+       for(parit = 0; parit < 2; parit++) {
+         Standard_Boolean isperiodic = (!parit) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
+
+         Standard_Real aResolution = (!parit) ? aGASurface->UResolution(aTol) : aGASurface->VResolution(aTol);
+         Standard_Real alowerboundary = (!parit) ? umin : vmin;
+         Standard_Real aupperboundary = (!parit) ? umax : vmax;
+
+         Standard_Real aParameter = (!parit) ? U : V;
+         Standard_Boolean bIsOnFirstBoundary = Standard_True;
+  
+         if(!isperiodic) {
+           if(IsPointOnBoundary(aParameter, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
+             bIsUBoundary = (!parit);
+             bIsFirstBoundary = bIsOnFirstBoundary;
+             nbboundaries++;
+           }
+         }
+         else {
+           Standard_Real aPeriod     = (!parit) ? aGASurface->UPeriod() : aGASurface->VPeriod();
+           Standard_Real anoffset = 0.;
+           Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
+
+           if(IsPointOnBoundary(anAdjustPar, alowerboundary, aupperboundary, aResolution, bIsOnFirstBoundary)) {
+             bIsUBoundary = (parit == 0);
+             bIsFirstBoundary = bIsOnFirstBoundary;
+             nbboundaries++;
+           }
+         }
+       }
+       //
+       Standard_Boolean bComputeLineEnd = Standard_False;
+       
+       if(nbboundaries == 2) {
+         bComputeLineEnd = Standard_True;
+       }
+       else if(nbboundaries == 1) {
+         Standard_Boolean isperiodic = (bIsUBoundary) ? aGASurface->IsUPeriodic() : aGASurface->IsVPeriodic();
+
+         if(isperiodic) {
+           Standard_Real alowerboundary = (bIsUBoundary) ? umin : vmin;
+           Standard_Real aupperboundary = (bIsUBoundary) ? umax : vmax;
+           Standard_Real aPeriod     = (bIsUBoundary) ? aGASurface->UPeriod() : aGASurface->VPeriod();
+           Standard_Real aParameter = (bIsUBoundary) ? U : V;
+           Standard_Real anoffset = 0.;
+           Standard_Real anAdjustPar = AdjustPeriodic(aParameter, alowerboundary, aupperboundary, aPeriod, anoffset);
+
+           Standard_Real adist = (bIsFirstBoundary) ? fabs(anAdjustPar - alowerboundary) : fabs(anAdjustPar - aupperboundary);
+           Standard_Real anotherPar = (bIsFirstBoundary) ? (aupperboundary - adist) : (alowerboundary + adist);
+           anotherPar += anoffset;
+           Standard_Integer aneighbourpointindex = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
+           const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex);
+           Standard_Real nU1, nV1;
+
+           if(surfit == 0)
+             aNeighbourPoint.ParametersOnS1(nU1, nV1);
+           else
+             aNeighbourPoint.ParametersOnS2(nU1, nV1);
+           
+           Standard_Real adist1 = (bIsUBoundary) ? fabs(nU1 - U) : fabs(nV1 - V);
+           Standard_Real adist2 = (bIsUBoundary) ? fabs(nU1 - anotherPar) : fabs(nV1 - anotherPar);
+           bComputeLineEnd = Standard_True;
+           Standard_Boolean bCheckAngle1 = Standard_False;
+           Standard_Boolean bCheckAngle2 = Standard_False;
+           gp_Vec2d aNewVec;
+           Standard_Real anewU = (bIsUBoundary) ? anotherPar : U;
+           Standard_Real anewV = (bIsUBoundary) ? V : anotherPar;
+           //
+           if(((adist1 - adist2) > Precision::PConfusion()) && 
+              (adist2 < (aPeriod / 4.))) {
+             bCheckAngle1 = Standard_True;
+             aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(anewU, anewV));
+
+             if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+               aNewP.SetValue((surfit == 0), anewU, anewV);
+               bCheckAngle1 = Standard_False;
+             }
+           }
+           else if(adist1 < (aPeriod / 4.)) {
+             bCheckAngle2 = Standard_True;
+             aNewVec = gp_Vec2d(gp_Pnt2d(nU1, nV1), gp_Pnt2d(U, V));
+
+             if(aNewVec.SquareMagnitude() < (gp::Resolution() * gp::Resolution())) {
+               bCheckAngle2 = Standard_False;
+             }
+           }
+           //
+           if(bCheckAngle1 || bCheckAngle2) {
+             // assume there are at least two points in line (see "if" above)
+             Standard_Integer anindexother = aneighbourpointindex;
+             
+             while((anindexother <= aListOfIndex.Last()) && (anindexother >= aListOfIndex.First())) {
+               anindexother = (j == 0) ? (anindexother + 1) : (anindexother - 1);
+               const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(anindexother);
+               Standard_Real nU2, nV2;
+               
+               if(surfit == 0)
+                 aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
+               else
+                 aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
+               gp_Vec2d aVecOld(gp_Pnt2d(nU2, nV2), gp_Pnt2d(nU1, nV1));
+
+               if(aVecOld.SquareMagnitude() <= (gp::Resolution() * gp::Resolution())) {
+                 continue;
+               }
+               else {
+                 Standard_Real anAngle = aNewVec.Angle(aVecOld);
+
+                 if((fabs(anAngle) < (M_PI * 0.25)) && (aNewVec.Dot(aVecOld) > 0.)) {
+
+                   if(bCheckAngle1) {
+                     Standard_Real U1, U2, V1, V2;
+                     IntSurf_PntOn2S atmppoint = aNewP;
+                     atmppoint.SetValue((surfit == 0), anewU, anewV);
+                     atmppoint.Parameters(U1, V1, U2, V2);
+                     gp_Pnt P1 = theSurface1->Value(U1, V1);
+                     gp_Pnt P2 = theSurface2->Value(U2, V2);
+                     gp_Pnt P0 = aPoint.Value();
+
+                     if(P0.IsEqual(P1, aTol) &&
+                        P0.IsEqual(P2, aTol) &&
+                        P1.IsEqual(P2, aTol)) {
+                       bComputeLineEnd = Standard_False;
+                       aNewP.SetValue((surfit == 0), anewU, anewV);
+                     }
+                   }
+                   
+                   if(bCheckAngle2) {
+                     bComputeLineEnd = Standard_False;
+                   }
+                 }
+                 break;
+               }
+             } // end while(anindexother...)
+           }
+         }
+       }
+       //
+       if(bComputeLineEnd) {
+         Standard_Integer aneighbourpointindex1 = (j == 0) ? aListOfIndex.First() : aListOfIndex.Last();
+         const IntSurf_PntOn2S& aNeighbourPoint = theWLine->Point(aneighbourpointindex1);
+         Standard_Real nU1, nV1;
+
+         if(surfit == 0)
+           aNeighbourPoint.ParametersOnS1(nU1, nV1);
+         else
+           aNeighbourPoint.ParametersOnS2(nU1, nV1);
+         gp_Pnt2d ap1(nU1, nV1);
+         gp_Pnt2d ap2(nU1, nV1);
+         Standard_Integer aneighbourpointindex2 = aneighbourpointindex1;
+
+         while((aneighbourpointindex2 <= aListOfIndex.Last()) && (aneighbourpointindex2 >= aListOfIndex.First())) {
+           aneighbourpointindex2 = (j == 0) ? (aneighbourpointindex2 + 1) : (aneighbourpointindex2 - 1);
+           const IntSurf_PntOn2S& aPrevNeighbourPoint = theWLine->Point(aneighbourpointindex2);
+           Standard_Real nU2, nV2;
+
+           if(surfit == 0)
+             aPrevNeighbourPoint.ParametersOnS1(nU2, nV2);
+           else
+             aPrevNeighbourPoint.ParametersOnS2(nU2, nV2);
+           ap2.SetX(nU2);
+           ap2.SetY(nV2);
+
+           if(ap1.SquareDistance(ap2) > (gp::Resolution() * gp::Resolution())) {
+             break;
+           }
+         }       
+         gp_Pnt2d anewpoint;
+         Standard_Boolean found = FindPoint(ap2, ap1, umin, umax, vmin, vmax, anewpoint);
+
+         if(found) {
+           // check point
+           Standard_Real aCriteria =aTolSum;// BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
+           //GeomAPI_ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
+           ProjectPointOnSurf& aProjector = (surfit == 0) ? aPrj2 : aPrj1;
+           Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
+
+           gp_Pnt aP3d = aSurface->Value(anewpoint.X(), anewpoint.Y());
+           aProjector.Perform(aP3d);
+
+           if(aProjector.IsDone()) {
+             if(aProjector.LowerDistance() < aCriteria) {
+               Standard_Real foundU = U, foundV = V;
+               aProjector.LowerDistanceParameters(foundU, foundV);
+
+               if(surfit == 0)
+                 aNewP.SetValue(aP3d, anewpoint.X(), anewpoint.Y(), foundU, foundV);
+               else
+                 aNewP.SetValue(aP3d, foundU, foundV, anewpoint.X(), anewpoint.Y());
+             }
+           }
+         }
+       }
+      }
+      aSeqOfPntOn2S->Add(aNewP);
+      aListOfFLIndex.Append(aSeqOfPntOn2S->NbPoints());
+    }
+    anArrayOfLineEnds.SetValue(i, aListOfFLIndex);
+  }
+  // Correct wlines.end
+
+  // Split wlines.begin
+  for(j = 1; j <= theLConstructor.NbParts(); j++) {
+    Standard_Real fprm = 0., lprm = 0.;
+    theLConstructor.Part(j, fprm, lprm);
+    Standard_Integer ifprm = (Standard_Integer)fprm;
+    Standard_Integer ilprm = (Standard_Integer)lprm;
+    //
+    Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
+    //
+    for(i = 1; i <= nblines; i++) {
+      if(anArrayOfLineType[i] != 0) {
+       continue;
+      }
+      const ListOfInteger& aListOfIndex = anArrayOfLines[i];
+
+      if(aListOfIndex.Extent() < 2) {
+       continue;
+      }
+      const TColStd_ListOfInteger& aListOfFLIndex = anArrayOfLineEnds.Value(i);
+      Standard_Boolean bhasfirstpoint = (aListOfFLIndex.Extent() == 2);
+      Standard_Boolean bhaslastpoint = (aListOfFLIndex.Extent() == 2);
+
+      if(!bhasfirstpoint && !aListOfFLIndex.IsEmpty()) {
+       bhasfirstpoint = (i != 1);
+      }
+
+      if(!bhaslastpoint && !aListOfFLIndex.IsEmpty()) {
+       bhaslastpoint = (i != nblines);
+      }
+      Standard_Boolean bIsFirstInside = ((ifprm >= aListOfIndex.First()) && (ifprm <= aListOfIndex.Last()));
+      Standard_Boolean bIsLastInside =  ((ilprm >= aListOfIndex.First()) && (ilprm <= aListOfIndex.Last()));
+
+      if(!bIsFirstInside && !bIsLastInside) {
+       if((ifprm < aListOfIndex.First()) && (ilprm > aListOfIndex.Last())) {
+         // append whole line, and boundaries if neccesary
+         if(bhasfirstpoint) {
+           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
+           aLineOn2S->Add(aP);
+         }
+         ListOfInteger::Iterator anIt(aListOfIndex);
+
+         for(; anIt.More(); anIt.Next()) {
+           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
+           aLineOn2S->Add(aP);
+         }
+
+         if(bhaslastpoint) {
+           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
+           aLineOn2S->Add(aP);
+         }
+
+         // check end of split line (end is almost always)
+         Standard_Integer aneighbour = i + 1;
+         Standard_Boolean bIsEndOfLine = Standard_True;
+
+         if(aneighbour <= nblines) {
+           const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
+
+           if((anArrayOfLineType[aneighbour] != 0) &&
+              (aListOfNeighbourIndex.IsEmpty())) {
+             bIsEndOfLine = Standard_False;
+           }
+         }
+
+         if(bIsEndOfLine) {
+           if(aLineOn2S->NbPoints() > 1) {
+             Handle(IntPatch_WLine) aNewWLine = 
+               new IntPatch_WLine(aLineOn2S, Standard_False);
+             theNewLines.Append(aNewWLine);
+           }
+           aLineOn2S = new IntSurf_LineOn2S();
+         }
+       }
+       continue;
+      }
+      // end if(!bIsFirstInside && !bIsLastInside)
+
+      if(bIsFirstInside && bIsLastInside) {
+       // append inside points between ifprm and ilprm
+       ListOfInteger::Iterator anIt(aListOfIndex);
+
+       for(; anIt.More(); anIt.Next()) {
+         if((anIt.Value() < ifprm) || (anIt.Value() > ilprm))
+           continue;
+         const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
+         aLineOn2S->Add(aP);
+       }
+      }
+      else {
+
+       if(bIsFirstInside) {
+         // append points from ifprm to last point + boundary point
+         ListOfInteger::Iterator anIt(aListOfIndex);
+
+         for(; anIt.More(); anIt.Next()) {
+           if(anIt.Value() < ifprm)
+             continue;
+           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
+           aLineOn2S->Add(aP);
+         }
+
+         if(bhaslastpoint) {
+           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.Last());
+           aLineOn2S->Add(aP);
+         }
+         // check end of split line (end is almost always)
+         Standard_Integer aneighbour = i + 1;
+         Standard_Boolean bIsEndOfLine = Standard_True;
+
+         if(aneighbour <= nblines) {
+           const ListOfInteger& aListOfNeighbourIndex = anArrayOfLines[aneighbour];
+
+           if((anArrayOfLineType[aneighbour] != 0) &&
+              (aListOfNeighbourIndex.IsEmpty())) {
+             bIsEndOfLine = Standard_False;
+           }
+         }
+
+         if(bIsEndOfLine) {
+           if(aLineOn2S->NbPoints() > 1) {
+             Handle(IntPatch_WLine) aNewWLine = 
+               new IntPatch_WLine(aLineOn2S, Standard_False);
+             theNewLines.Append(aNewWLine);
+           }
+           aLineOn2S = new IntSurf_LineOn2S();
+         }
+       }
+       // end if(bIsFirstInside)
+
+       if(bIsLastInside) {
+         // append points from first boundary point to ilprm
+         if(bhasfirstpoint) {
+           const IntSurf_PntOn2S& aP = aSeqOfPntOn2S->Value(aListOfFLIndex.First());
+           aLineOn2S->Add(aP);
+         }
+         ListOfInteger::Iterator anIt(aListOfIndex);
+
+         for(; anIt.More(); anIt.Next()) {
+           if(anIt.Value() > ilprm)
+             continue;
+           const IntSurf_PntOn2S& aP = theWLine->Point(anIt.Value());
+           aLineOn2S->Add(aP);
+         }
+       }
+       //end if(bIsLastInside)
+      }
+    }
+
+    if(aLineOn2S->NbPoints() > 1) {
+      Handle(IntPatch_WLine) aNewWLine = 
+       new IntPatch_WLine(aLineOn2S, Standard_False);
+      theNewLines.Append(aNewWLine);
+    }
+  }
+  // Split wlines.end
+  //
+  // cda002/I3
+  Standard_Real fprm, lprm;
+  Standard_Integer ifprm, ilprm, aNbPoints, aIndex;
+  //
+  aNbParts=theLConstructor.NbParts();
+  //
+  for(j = 1; j <= aNbParts; j++) {
+    theLConstructor.Part(j, fprm, lprm);
+    ifprm=(Standard_Integer)fprm;
+    ilprm=(Standard_Integer)lprm;
+    //
+    if ((ilprm-ifprm)==1) {
+      for(i = 1; i <= nblines; i++) {
+       aLineType=anArrayOfLineType[i];
+       if(aLineType) {
+         continue;
+       }
+       //
+       const ListOfInteger& aListOfIndex = anArrayOfLines[i];
+       aNbPoints=aListOfIndex.Extent();
+       if(aNbPoints==1) {
+         aIndex=aListOfIndex.First();
+         if (aIndex==ifprm || aIndex==ilprm) {
+           Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
+           const IntSurf_PntOn2S& aP1 = theWLine->Point(ifprm);
+           const IntSurf_PntOn2S& aP2 = theWLine->Point(ilprm);
+           aLineOn2S->Add(aP1);
+           aLineOn2S->Add(aP2);
+           Handle(IntPatch_WLine) aNewWLine = 
+             new IntPatch_WLine(aLineOn2S, Standard_False);
+           theNewLines.Append(aNewWLine);
+         }
+       }
+      }
+    }
+  }
+  //
+  return Standard_True;
+}
index 00b26c6..e99eb47 100644 (file)
 
 #include <Standard_Integer.hxx>
 #include <Standard_Real.hxx>
+#include <GeomInt_LineConstructor.hxx>
+#include <IntPatch_SequenceOfLine.hxx>
 class IntPatch_Line;
 class IntPatch_Point;
-
+class IntPatch_WLine;
+class GeomAdaptor_HSurface;
 
 
 class GeomInt_LineTool 
@@ -43,7 +46,13 @@ public:
   
   Standard_EXPORT static Standard_Real LastParameter (const Handle(IntPatch_Line)& L);
 
-
+  Standard_EXPORT static Standard_Boolean 
+        DecompositionOfWLine( const Handle(IntPatch_WLine)& theWLine,
+                              const Handle(GeomAdaptor_HSurface)& theSurface1,
+                              const Handle(GeomAdaptor_HSurface)& theSurface2,
+                              const Standard_Real aTolSum,
+                              const GeomInt_LineConstructor& theLConstructor,
+                              IntPatch_SequenceOfLine& theNewLines);
 
 
 protected:
index aa296ca..7de0869 100644 (file)
@@ -116,8 +116,8 @@ public:
   Standard_EXPORT const AppParCurves_MultiBSpCurve& SplineValue();
   
   //! returns the type  of  parametrization
-  Standard_EXPORT void Parametrization (Approx_ParametrizationType& partype) const;
-  
+  Standard_EXPORT Approx_ParametrizationType Parametrization () const;
+
   //! returns the new parameters of the approximation
   //! corresponding to the points of the multicurve <Index>.
   Standard_EXPORT const TColStd_Array1OfReal& Parameters (const Standard_Integer Index = 1) const;
index 3582728..78095b2 100644 (file)
@@ -41,55 +41,75 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  //! The  class   SvSurfaces     is used   when    the
-  //! approximation algorithm needs some extra points on
-  //! the line <line>. A New line  is then created which
-  //! shares  the    same  surfaces    and    functions.
-  //!
-  //! SvSurfaces is   a  deferred   class  which  allows
-  //! several implementations of  this  algorithm   with
-  //! different surfaces   (bi-parametric     ones,   or
+  //! The class SvSurfaces is used when the approximation algorithm 
+  //! needs some extra points on the line <line>. 
+  //! A New line  is then created which shares the same surfaces and functions.
+  //! SvSurfaces is a deferred class which allows several implementations of
+  //! this  algorithm with different surfaces (bi-parametric ones, or 
   //! implicit and biparametric ones)
-  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox(const Handle(IntPatch_WLine)& line, const Standard_Address PtrSvSurfaces, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0);
+  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line,
+                                                  const Standard_Address PtrSvSurfaces,
+                                                  const Standard_Integer NbP3d,
+                                                  const Standard_Integer NbP2d,
+                                                  const Standard_Real xo,
+                                                  const Standard_Real yo,
+                                                  const Standard_Real zo,
+                                                  const Standard_Real u1o,
+                                                  const Standard_Real v1o,
+                                                  const Standard_Real u2o,
+                                                  const Standard_Real v2o,
+                                                  const Standard_Boolean P2DOnFirst,
+                                                  const Standard_Integer IndMin = 0,
+                                                  const Standard_Integer IndMax = 0);
   
   //! No Extra points will be added on the current line
-  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox(const Handle(IntPatch_WLine)& line, const Standard_Integer NbP3d, const Standard_Integer NbP2d, const Standard_Real xo, const Standard_Real ax, const Standard_Real yo, const Standard_Real ay, const Standard_Real zo, const Standard_Real az, const Standard_Real u1o, const Standard_Real a1u, const Standard_Real v1o, const Standard_Real a1v, const Standard_Real u2o, const Standard_Real a2u, const Standard_Real v2o, const Standard_Real a2v, const Standard_Boolean P2DOnFirst, const Standard_Integer IndMin = 0, const Standard_Integer IndMax = 0);
+  Standard_EXPORT GeomInt_TheMultiLineOfWLApprox( const Handle(IntPatch_WLine)& line,
+                                                  const Standard_Integer NbP3d,
+                                                  const Standard_Integer NbP2d,
+                                                  const Standard_Real xo,
+                                                  const Standard_Real yo,
+                                                  const Standard_Real zo,
+                                                  const Standard_Real u1o,
+                                                  const Standard_Real v1o,
+                                                  const Standard_Real u2o,
+                                                  const Standard_Real v2o,
+                                                  const Standard_Boolean P2DOnFirst,
+                                                  const Standard_Integer IndMin = 0,
+                                                  const Standard_Integer IndMax = 0);
   
   Standard_EXPORT Standard_Integer FirstPoint() const;
   
   Standard_EXPORT Standard_Integer LastPoint() const;
-  
+
   //! Returns the number of 2d points of a TheLine.
   Standard_EXPORT Standard_Integer NbP2d() const;
-  
+
   //! Returns the number of 3d points of a TheLine.
   Standard_EXPORT Standard_Integer NbP3d() const;
   
   Standard_EXPORT Approx_Status WhatStatus() const;
   
-  //! returns the 3d points of the multipoint <MPointIndex>
-  //! when only 3d points exist.
+  //! Returns the 3d points of the multipoint <MPointIndex> when only 3d points exist.
   Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt) const;
   
-  //! returns the 2d points of the multipoint <MPointIndex>
-  //! when only 2d points exist.
-  Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt2d& tabPt2d) const;
-  
-  //! returns the 3d and 2d points of the multipoint
-  //! <MPointIndex>.
+  //! Returns the 2d points of the multipoint <MPointIndex> when only 2d points exist.
+  Standard_EXPORT void Value (const Standard_Integer MPointIndex,
+                              TColgp_Array1OfPnt2d& tabPt2d) const;  
+
+  //! returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT void Value (const Standard_Integer MPointIndex, TColgp_Array1OfPnt& tabPt, TColgp_Array1OfPnt2d& tabPt2d) const;
   
-  //! returns the 3d points of the multipoint <MPointIndex>
-  //! when only 3d points exist.
-  Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV) const;
+  //! Returns the 3d tangency points of the multipoint <MPointIndex> only
+  //! when 3d points exist.
+  Standard_EXPORT Standard_Boolean Tangency ( const Standard_Integer MPointIndex,
+                                              TColgp_Array1OfVec& tabV) const;
   
-  //! returns the 2d tangency points of the multipoint
-  //! <MPointIndex> only when 2d points exist.
-  Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec2d& tabV2d) const;
+  //! Returns the 2d tangency points of the multipoint <MPointIndex> only
+  //! when 2d points exist.
+  Standard_EXPORT Standard_Boolean Tangency ( const Standard_Integer MPointIndex,
+                                              TColgp_Array1OfVec2d& tabV2d) const;
   
-  //! returns the 3d and 2d points of the multipoint
-  //! <MPointIndex>.
+  //! Returns the 3d and 2d points of the multipoint <MPointIndex>.
   Standard_EXPORT Standard_Boolean Tangency (const Standard_Integer MPointIndex, TColgp_Array1OfVec& tabV, TColgp_Array1OfVec2d& tabV2d) const;
   
   Standard_EXPORT GeomInt_TheMultiLineOfWLApprox MakeMLBetween (const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPointsToInsert) const;
@@ -101,44 +121,25 @@ public:
 
 
 protected:
-
-
-
-
+  GeomInt_TheMultiLineOfWLApprox operator=(GeomInt_TheMultiLineOfWLApprox&);
 
 private:
-
-
-
-  Standard_Address PtrOnmySvSurfaces;
-  Handle(IntPatch_WLine) myLine;
-  Standard_Integer indicemin;
-  Standard_Integer indicemax;
-  Standard_Integer nbp3d;
-  Standard_Integer nbp2d;
-  Standard_Boolean p2donfirst;
-  Standard_Real Xo;
-  Standard_Real Ax;
-  Standard_Real Yo;
-  Standard_Real Ay;
-  Standard_Real Zo;
-  Standard_Real Az;
-  Standard_Real U1o;
-  Standard_Real A1u;
-  Standard_Real V1o;
-  Standard_Real A1v;
-  Standard_Real U2o;
-  Standard_Real A2u;
-  Standard_Real V2o;
-  Standard_Real A2v;
+  const Standard_Address PtrOnmySvSurfaces;
+  const Handle(IntPatch_WLine) myLine;
+  const Standard_Integer indicemin;
+  const Standard_Integer indicemax;
+  const Standard_Integer nbp3d;
+  const Standard_Integer nbp2d;
+  const Standard_Boolean p2donfirst;
+  const Standard_Real Xo;
+  const Standard_Real Yo;
+  const Standard_Real Zo;
+  const Standard_Real U1o;
+  const Standard_Real V1o;
+  const Standard_Real U2o;
+  const Standard_Real V2o;
 
 
 };
 
-
-
-
-
-
-
 #endif // _GeomInt_TheMultiLineOfWLApprox_HeaderFile
index ba734a4..9e179b8 100644 (file)
@@ -51,19 +51,22 @@ class AppParCurves_MultiBSpCurve;
 
 struct Approx_Data 
 {
-  Approx_Data()
+  Approx_Data() : myBezierApprox(Standard_True),
+                  Xo(0.0), Yo(0.0), Zo(0.0),
+                  U1o(0.0), V1o(0.0), U2o(0.0), V2o(0.0),
+                  ApproxXYZ(Standard_True),
+                  ApproxU1V1(Standard_True),
+                  ApproxU2V2(Standard_True),
+                  indicemin(0), indicemax(0),
+                  myNbPntMax(30), parametrization(Approx_ChordLength)
   {
-    myMinFactorXYZ = 0.0;
-    myMinFactorUV  = 0.0;
   }
 
   Standard_Boolean myBezierApprox;
-  Standard_Real  Xo, Ax, Yo, Ay, Zo, Az,
-    U1o, A1u, V1o, A1v, U2o, A2u, V2o, A2v;
+  Standard_Real  Xo, Yo, Zo, U1o, V1o, U2o, V2o;
   Standard_Boolean ApproxXYZ, ApproxU1V1, ApproxU2V2;
-  Standard_Integer indicemin, indicemax, nbpntmax;
+  Standard_Integer indicemin, indicemax, myNbPntMax;
   Approx_ParametrizationType parametrization;
-  Standard_Real myMinFactorXYZ, myMinFactorUV;
 };
 
 
@@ -80,10 +83,15 @@ public:
   
   Standard_EXPORT void Perform (const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ = Standard_True, const Standard_Boolean ApproxU1V1 = Standard_True, const Standard_Boolean ApproxU2V2 = Standard_True, const Standard_Integer indicemin = 0, const Standard_Integer indicemax = 0);
   
-  Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength);
-  
-  Standard_EXPORT void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d, const Standard_Boolean RelativeTol, const Standard_Integer DegMin, const Standard_Integer DegMax, const Standard_Integer NbIterMax, const Standard_Integer NbPntMax, const Standard_Boolean ApproxWithTangency = Standard_True, const Approx_ParametrizationType Parametrization = Approx_ChordLength);
-  
+  Standard_EXPORT 
+      void SetParameters (const Standard_Real Tol3d, const Standard_Real Tol2d,
+                          const Standard_Integer DegMin, 
+                          const Standard_Integer DegMax,
+                          const Standard_Integer NbIterMax,
+                          const Standard_Integer NbPntMax = 30,
+                          const Standard_Boolean ApproxWithTangency = Standard_True,
+                          const Approx_ParametrizationType
+                                          Parametrization = Approx_ChordLength);  
   Standard_EXPORT void Perform();
   
   Standard_EXPORT Standard_Real TolReached3d() const;
@@ -106,22 +114,12 @@ protected:
 
 
 private:
-
-  Standard_EXPORT Standard_Integer CorrectFinishIdx(const Standard_Integer theMinIdx,
-                                                    const Standard_Integer theMaxIdx,
-                                                    const Handle(IntPatch_WLine)& theline);
-
-  Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Surf1, const IntSurf_Quadric& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax);
-  
-  Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax);
+  Standard_EXPORT void Perform (const IntSurf_Quadric& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(IntPatch_WLine)& aLine, const Standard_Boolean ApproxXYZ, const Standard_Boolean ApproxU1V1, const Standard_Boolean ApproxU2V2, const Standard_Integer indicemin, const Standard_Integer indicemax, const Standard_Boolean isTheQuadFirst);
   
   Standard_EXPORT void UpdateTolReached();
 
   //! Fill data structure for intersection approximation.
-  Standard_EXPORT void fillData(const Handle(IntPatch_WLine)& theLine,
-                                const Standard_Boolean theApproxXYZ,
-                                const Standard_Boolean theApproxU1V1,
-                                const Standard_Boolean theApproxU2V2);
+  Standard_EXPORT void fillData(const Handle(IntPatch_WLine)& theLine);
 
   //! Prepare data structure for further computations.
   Standard_EXPORT void prepareDS(const Standard_Boolean theApproxXYZ,
@@ -141,19 +139,15 @@ private:
   GeomInt_TheComputeLineOfWLApprox myComputeLine;
   GeomInt_TheComputeLineBezierOfWLApprox myComputeLineBezier;
   Approx_MCurvesToBSpCurve myBezToBSpl;
-  Standard_Boolean myTolReached;
   Standard_Boolean myWithTangency;
   Standard_Real myTol3d;
   Standard_Real myTol2d;
-  Standard_Boolean myRelativeTol;
   Standard_Integer myDegMin;
   Standard_Integer myDegMax;
-  Standard_Integer myNbPntMax;
   Standard_Integer myNbIterMax;
   Standard_Real myTolReached3d;
   Standard_Real myTolReached2d;
   Approx_Data myData;
-  Standard_Real myUVRes1, myUVRes2;
   NCollection_Vector<Standard_Integer> myKnots;
 
 };
index 084c495..3effd51 100644 (file)
@@ -280,16 +280,14 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
 //function : intersect
 //purpose  : 
 //=======================================================================
-
 static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
   if( n < 2) 
   {
-#ifdef OCCT_DEBUG
     cout<< "2dintersect curve curve [Tol]"<<endl;
-#endif
     return 1;
   }
+
   Standard_Integer k = 1;
   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[k++]);
   if ( C1.IsNull()) 
@@ -331,6 +329,7 @@ static Standard_Integer intersect(Draw_Interpretor& di, Standard_Integer n, cons
   Handle(Geom2d_Curve) S1,S2;
   Handle(DrawTrSurf_Curve2d) CD;
   for ( i = 1; i <= Intersector.NbSegments(); i++) {
+    di << "Segment #" << i << " found.\n";
     Intersector.Segment(i,S1,S2);
     CD = new DrawTrSurf_Curve2d(S1, Draw_bleu, 30);
     dout << CD;
index a673935..44beb38 100644 (file)
@@ -450,7 +450,7 @@ void  HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
                  
                   //-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<"  Tol3d="<<TOL3d<<"   Tol2d="<<TOL2d<<endl;
 
-                  Approx.SetParameters(TOL3d,TOL2d,dmin,dmax,niter,tg);
+                  Approx.SetParameters(TOL3d, TOL2d, dmin, dmax, niter, 30, tg);
                   Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
                   if (!Approx.IsDone()) {
                     C = AppC;
index 4f4ccc9..49c2766 100755 (executable)
@@ -94,3 +94,5 @@ IntPatch_TheSurfFunction_0.cxx
 IntPatch_WLine.cxx
 IntPatch_WLine.hxx
 IntPatch_WLine.lxx
+IntPatch_WLineTool.cxx
+IntPatch_WLineTool.hxx
index ebc4cbe..b59c0ab 100644 (file)
@@ -39,7 +39,9 @@
 #include <IntSurf_SequenceOfPathPoint.hxx>
 #include <Standard_ConstructionError.hxx>
 #include <Standard_DomainError.hxx>
+#include <Standard_NumericError.hxx>
 #include <Standard_OutOfRange.hxx>
+#include <Standard_TypeMismatch.hxx>
 #include <StdFail_NotDone.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 
 #include <Bnd_Box2d.hxx>
 #include <IntPatch_PointLine.hxx>
 
-static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)&   Line,
-  const Standard_Boolean         IsReversed,
-  const IntSurf_Quadric&         Quad,
-  const Handle(Adaptor3d_TopolTool)&    PDomain,
-  const Handle(Adaptor3d_HSurface)&              QSurf,
-  const Standard_Real            ArcTol,
-  IntPatch_SequenceOfLine& Lines);
+#include <Extrema_GenLocateExtPS.hxx>
+
+static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
+                                        const Standard_Boolean       IsReversed,
+                                        const IntSurf_Quadric&       theQuad,
+                                        const Handle(Adaptor3d_TopolTool)& thePDomain,
+                                        const Handle(Adaptor3d_HSurface)&  theQSurf,
+                                        const Handle(Adaptor3d_HSurface)&  theOtherSurf,
+                                        const Standard_Real                theArcTol,
+                                        IntPatch_SequenceOfLine&           theLines);
 static 
   void ComputeTangency (const IntPatch_TheSOnBounds& solrst,
   IntSurf_SequenceOfPathPoint& seqpdep,
@@ -783,6 +788,10 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
         // <-A
         wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
 
+#ifdef OCCT_DEBUG
+        //wline->Dump(0);
+#endif
+
         if (   iwline->HasFirstPoint() 
           && iwline->IsTangentAtBegining() == Standard_False) 
         {
@@ -1464,12 +1473,13 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 
   const Handle(Adaptor3d_TopolTool)& PDomain = (reversed) ? D1 : D2;
   const Handle(Adaptor3d_HSurface)& aQSurf = (reversed) ? Surf2 : Surf1;
+  const Handle(Adaptor3d_HSurface)& anOtherSurf = (reversed) ? Surf1 : Surf2;
 
   IntPatch_SequenceOfLine dslin;
   Standard_Boolean isDecompose = Standard_False;
   for(Standard_Integer i = 1; i <= slin.Length(); i++ )
   {
-    if(DecomposeResult(slin(i),reversed,Quad,PDomain,aQSurf,TolArc,dslin))
+    if(DecomposeResult(slin(i),reversed,Quad,PDomain,aQSurf, anOtherSurf, TolArc,dslin))
     {
       isDecompose = Standard_True;
     }
@@ -1624,76 +1634,6 @@ static Standard_Boolean AreSamePoints(const IntSurf_PntOn2S& P1,
   return result;
 }
 
-static void ForcedPurgePoints(const Handle(IntSurf_LineOn2S)& Result,
-                              const Standard_Boolean          IsReversed,
-                              const IntSurf_Quadric&          Quad)
-{
-  if(Result->NbPoints() <= 30) return;
-  Standard_Integer Index = 0, IndexLimF = 8, IndexLimL = 8;
-
-  Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
-  if(IsReversed) {
-    Result->Value(1).ParametersOnS2(U1,V1);
-    Result->Value(Result->NbPoints()).ParametersOnS2(U2,V2);
-  }
-  else {
-    Result->Value(1).ParametersOnS1(U1,V1);   
-    Result->Value(Result->NbPoints()).ParametersOnS1(U2,V2);
-  }
-
-  if(Quad.TypeQuadric() == GeomAbs_Cone) {
-    Standard_Real Uapx = 0., Vapx = 0.;
-    Quad.Parameters(Quad.Cone().Apex(),Uapx,Vapx);
-
-    if(fabs(V1-Vapx) <= 1.e-3)
-      IndexLimF = 12;
-    if(fabs(V2-Vapx) <= 1.e-3)
-      IndexLimL = 12;
-  }
-
-  if(Quad.TypeQuadric() == GeomAbs_Sphere) {
-    Standard_Real Vapx1 = M_PI/2., Vapx2 = -M_PI/2.;
-
-    if(fabs(V1-Vapx1) <= 1.e-3 || fabs(V1-Vapx2) <= 1.e-3)
-      IndexLimF = 12;
-    if(fabs(V2-Vapx1) <= 1.e-3 || fabs(V2-Vapx2) <= 1.e-3)
-      IndexLimL = 12;
-  }
-
-  while(Result->NbPoints() > 2 && Index < IndexLimF) {
-    Result->RemovePoint(2);
-    Index++;
-  }
-  Index = 0;
-  while(Result->NbPoints() > 2 && Index < IndexLimL) {
-    Result->RemovePoint(Result->NbPoints()-1);
-    Index++;
-  }
-}
-
-// DEBUG FUNCTION !!!
-#if 0
-static void DumpLine(Handle(IntSurf_LineOn2S)& Line,
-  Standard_Boolean          IsReversed,
-  Standard_Integer          Number)
-{
-  cout << "DUMP LINE" << endl;
-  Standard_Integer i;
-  Standard_Real U,V;
-  for(i = 1; i <= Line->NbPoints(); i++) {
-    if(i <= Number || i >= (Line->NbPoints()-Number)) {
-      if(IsReversed)
-        Line->Value(i).ParametersOnS2(U,V); // S2 - quadric
-      else
-        Line->Value(i).ParametersOnS1(U,V); // S1 - quadric
-      cout << "point p" << i << " " << U << " " << V << endl;
-    }
-  }
-  cout << endl;
-}
-#endif
-// DEBUG FUNCTION !!!
-
 static void SearchVertices(const Handle(IntSurf_LineOn2S)& Line,
   const Handle(IntSurf_LineOn2S)& Vertices,
   TColStd_Array1OfInteger&        PTypes)
@@ -2378,19 +2318,23 @@ static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)&        WLine,
   return result;
 }
 
+//=======================================================================
+//function : DecomposeResult
+//purpose  : Split <theLine> in the places where it passes through seam edge
+//            or singularity (apex of cone or pole of sphere).
+//            This passage is detected by jump of U-parameter
+//            from point to point.
+//=======================================================================
 static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
                                         const Standard_Boolean       IsReversed,
                                         const IntSurf_Quadric&       theQuad,
                                         const Handle(Adaptor3d_TopolTool)& thePDomain,
-                                        const Handle(Adaptor3d_HSurface)&  theQSurf,
+                                        const Handle(Adaptor3d_HSurface)&  theQSurf, //quadric
+                                        const Handle(Adaptor3d_HSurface)&  thePSurf, //parametric
                                         const Standard_Real                theArcTol,
                                         IntPatch_SequenceOfLine&           theLines)
 {
-  // Split <theLine> in the places where it passes through seam edge or singularity
-  // (apex of cone or pole of sphere). This passage is detected by jump of U-parameter
-  // from point to point.
-  
-  const Standard_Real aDeltaUmax = 0.5*M_PI;
+  const Standard_Real aDeltaUmax = M_PI_2;
   const Standard_Real aTOL3D = 1.e-10, 
                       aTOL2D = Precision::PConfusion(),
                       aTOL2DS = Precision::PConfusion();
@@ -2437,7 +2381,13 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
   // build WLine parts (if any)
   Standard_Boolean flNextLine = Standard_True;
   Standard_Boolean hasBeenDecomposed = Standard_False;
-  Standard_Boolean PrePointExist = Standard_False;
+  enum PrePoint_Type
+  {
+    PrePoint_NONE,
+    PrePoint_SEAM,
+    PrePoint_POLE
+  }PrePointExist = PrePoint_NONE;
+
   IntSurf_PntOn2S PrePoint;
   while(flNextLine)
   {
@@ -2449,15 +2399,86 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
     Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
 
     //if((Lindex-Findex+1) <= 2 )
-    if(aLindex <= aFindex)
-      return hasBeenDecomposed;
+    if((aLindex <= aFindex) && (PrePointExist != PrePoint_POLE))
+    {
+      //break of "while(flNextLine)" cycle
+      break;
+    }
 
-    if (PrePointExist)
+    if (PrePointExist == PrePoint_SEAM)
     {
       sline->Add(PrePoint);
-      PrePointExist = Standard_False;
     }
-    
+    else if(PrePointExist == PrePoint_POLE)
+    {
+      //The last point of the line is the pole of the quadric.
+      //Therefore, Walking-line has been broken in this point.
+      //However, new line must start from this point. Here we must
+      //find its 2D-coordinates.
+
+      //For sphere and cone, some intersection point is satisfied to the system
+      //  \cos(U_{q}) = S_{x}(U_{s},V_{s})/F(V_{q}) 
+      //  \sin(U_{q}) = S_{y}(U_{s},V_{s})/F(V_{q}) 
+
+      //where 
+      //  @S_{x}@, @S_{y}@ are X and Y-coordinates of thePSurf;
+      //  @U_{s}@ and @V_{s}@ are UV-parameters on thePSurf;
+      //  @U_{q}@ and @V_{q}@ are UV-parameters on theQSurf;
+      //  @F(V_{q}) @ is some function, which value independs on @U_{q}@
+      //              (form of this function depends on the type of the quadric).
+
+      //When we go through the pole, the function @F(V_{q}) @ changes sign.
+      //Therefore, some cases are possible, when only @\cos(U_{q}) @ or
+      //only @ \sin(U_{q}) @ change sign.
+
+      //Consequently, when the line goes throug the pole, @U_{q}@ can be
+      //changed on @\pi /2 @ (but not less).
+
+      const Standard_Real aPeriod = M_PI_2, aHalfPeriod = M_PI_4;
+      const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aFindex);
+
+      IntSurf_PntOn2S aFirstPoint = PrePoint;
+
+      if(!aFirstPoint.IsSame(aRefPt, Precision::Confusion()))
+      {
+        Standard_Real aURef = 0.0, aVRef = 0.0;
+        Standard_Real aUquad = 0.0, aVquad = 0.0;
+
+        //Take parameters on quadric
+        if(IsReversed)
+        {
+          aFirstPoint.ParametersOnS2(aUquad, aVquad);
+          aRefPt.ParametersOnS2(aURef, aVRef);
+        }
+        else
+        {
+          aFirstPoint.ParametersOnS1(aUquad, aVquad);
+          aRefPt.ParametersOnS1(aURef, aVRef);
+        }
+
+        {
+          Standard_Real aDeltaPar = aURef-aUquad;
+          const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar);
+          while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
+          {
+            aUquad += anIncr;
+            aDeltaPar = aURef-aUquad;
+          }
+        }
+
+        aFirstPoint.SetValue(!IsReversed, aUquad, aVquad);
+
+        sline->Add(aFirstPoint);
+      }
+      else
+      {
+        //break of "while(flNextLine)" cycle
+        break;
+      }
+    }
+
+    PrePointExist = PrePoint_NONE;
+
     // analyze other points
     for(Standard_Integer k = aFindex; k <= aLindex; k++)
     {
@@ -2517,7 +2538,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
                  Abs(AnU1 - 2*M_PI) <= Precision::PConfusion())
         {
           //Modify <PrePoint>
-          PrePointExist = Standard_True;
+          PrePointExist = PrePoint_SEAM;
           Standard_Real theU1, theV1;
           if (!IsReversed)
           {
@@ -2534,6 +2555,240 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
                               theU1, theV1);
           }
         }
+        else
+        {//Check if WLine goes through pole
+          const Standard_Real aTol = Precision::Confusion();
+          const Standard_Real aPeriod = M_PI+M_PI, aHalfPeriod = M_PI;
+          const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aBindex-1);
+          
+          //Not quadric point
+          Standard_Real aU0 = 0.0, aV0 = 0.0;
+          //Quadric point
+          Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
+
+          if(IsReversed)
+          {
+            aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
+          }
+          else
+          {
+            aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
+          }
+
+          //Transforms parametric surface in coordinate-system of the quadric
+          gp_Trsf aTr;
+          aTr.SetTransformation(theQuad.Sphere().Position());
+
+          //aPQuad is Pole
+          gp_Pnt aPQuad;
+          Standard_Real aUquad = 0.0;
+          Standard_Real aVquad = 0.0; 
+          
+          if(theQuad.TypeQuadric() == GeomAbs_Sphere)
+          {
+            aVquad = Sign(M_PI_2, aVQuadRef);
+          }
+          else if(theQuad.TypeQuadric() == GeomAbs_Cone)
+          {
+            const Standard_Real aRadius = theQuad.Cone().RefRadius();
+            const Standard_Real aSemiAngle = theQuad.Cone().SemiAngle();
+            aVquad = -aRadius/sin(aSemiAngle);
+          }
+          else
+          {
+            Standard_TypeMismatch::Raise( "IntPatch_ImpPrmIntersection.cxx,"
+                                          " DecomposeResult(...): "
+                                          "Unsupported quadric with Pole");
+          }
+          
+          theQSurf->D0(aUquad, aVquad, aPQuad);
+
+          Extrema_GenLocateExtPS anExtr(aPQuad, thePSurf->Surface(), aU0, aV0,
+                                        Precision::PConfusion(),
+                                        Precision::PConfusion());
+
+          if(!anExtr.IsDone())
+            break;
+
+          if(anExtr.SquareDistance() < aTol*aTol)
+          { //Pole is an intersection point
+            //(lies in the quadric and the parametric surface)
+
+            anExtr.Point().Parameter(aU0, aV0);
+            gp_Pnt aP0(anExtr.Point().Value());
+
+            IntSurf_PntOn2S aNewPoint;
+            aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), IsReversed, aU0, aV0);
+
+            if(!aNewPoint.IsSame(aRefPt, Precision::Confusion()))
+            { //Found pole does not exist in the Walking-line
+              //It must be added there (with correct 2D-parameters)
+              
+              //2D-parameters of theparametric surface have already been found (aU0, aV0).
+              //Let find 2D-parameters on the quadric.
+
+              //The algorithm depends on the type of the quadric. Here we consider a Sphere only.
+              //Analogical result can be made for another types (e.g. cone, but formulas will
+              //be different) in case of need.
+              
+              //First of all, we need in adjusting thePSurf in the coordinate system of the Sphere
+              //(in order to make the equation of the sphere maximal simple). However, as it will be
+              //shown later, thePSurf is used in algorithm in order to get its derivatives. Therefore,
+              //for improving performance, transformation of these vectors is enough (there is no point
+              //in transformation of full surface).
+              
+              gp_Pnt aPtemp;
+              gp_Vec aVecDu, aVecDv;
+              thePSurf->D1(aU0, aV0, aPtemp, aVecDu, aVecDv);
+
+              //Derivatives of transformed thePSurf
+              aVecDu.Transform(aTr);
+              aVecDv.Transform(aTr);
+
+              if(theQuad.TypeQuadric() == GeomAbs_Sphere)
+              {
+                //The intersection point (including the pole)
+                //must be satisfied to the following system:
+
+                //    \left\{\begin{matrix}
+                //    R*\cos (U_{q})*\cos (V_{q})=S_{x}(U_{s},V_{s})
+                //    R*\sin (U_{q})*\cos (V_{q})=S_{y}(U_{s},V_{s})
+                //    R*\sin (V_{q})=S_{z}(U_{s},V_{s})
+                //    \end{matrix}\right,
+                //where 
+                //  R is the radius of the sphere;
+                //  @S_{x}@, @S_{y}@ and @S_{z}@ are X, Y and Z-coordinates of thePSurf;
+                //  @U_{s}@ and @V_{s}@ are equal to aU0 and aV0 corespondingly;
+                //  @U_{q}@ and @V_{q}@ are equal to aUquad and aVquad corespondingly.
+
+                //Consequently (from first two equations), 
+                //  \left\{\begin{matrix}
+                //  \cos (U_{q}) = \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}
+                //  \sin (U_{q}) = \frac{S_{y}(U_{s},V_{s})}{R*\cos (V_{q})}
+                //  \end{matrix}\right.
+
+                //For pole, 
+                //  V_{q}=\pm \pi /2 \Rightarrow \cos (V_{q}) = 0 (denominator is equal to 0).
+
+                //Therefore, computation U_{q} directly is impossibly.
+                //
+                //Let @V_{q}@ tends to @\pm \pi /2@.
+                //Then (indeterminate form is evaluated in accordance of L'Hospital rule),
+                //  \cos (U_{q}) = \lim_{V_{q} \to (\pi /2-0)} 
+                //  \frac{S_{x}(U_{s},V_{s})}{R*\cos (V_{q})}= 
+                //  -\lim_{V_{q} \to (\pi /2-0)}
+                //  \frac{\frac{\partial S_{x}}
+                //  {\partial U_{s}}*\frac{\mathrm{d} U_{s}} 
+                //  {\mathrm{d} V_{q}}+\frac{\partial S_{x}} 
+                //  {\partial V_{s}}*\frac{\mathrm{d} V_{s}} 
+                //  {\mathrm{d} V_{q}}}{R*\sin (V_{q})} =  
+                //  -\frac{1}{R}*\frac{\mathrm{d} U_{s}}
+                //  {\mathrm{d} V_{q}}*(\frac{\partial S_{x}} 
+                //  {\partial U_{s}}+\frac{\partial S_{x}}
+                //  {\partial V_{s}}*\frac{\mathrm{d} V_{s}}
+                //  {\mathrm{d} U_{s}}) =
+                //  -\frac{1}{R}*\frac{\mathrm{d} V_{s}}
+                //  {\mathrm{d} V_{q}}*(\frac{\partial S_{x}} 
+                //  {\partial U_{s}}*\frac{\mathrm{d} U_{s}}
+                //  {\mathrm{d} V_{s}}+\frac{\partial S_{x}}
+                //  {\partial V_{s}}).
+
+                //Analogicaly for @\sin (U_{q})@ (@S_{x}@ is substituted to @S_{y}@).
+
+                //Let mean, that
+                //  \cos (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \cos (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
+                //  \sin (U_{q}) \left | _{V_{q} \to (-\pi /2+0)} = \sin (U_{q}) \left | _{V_{q} \to (\pi /2-0)}
+
+                //From the 3rd equation of the system, we obtain
+                //  \frac{\mathrm{d} (R*\sin (V_{q}))}{\mathrm{d} V_{q}} =
+                //  \frac{\mathrm{d} S_{z}(U_{s},V_{s})}{\mathrm{d} V_{q}}
+                //or
+                //  R*\cos (V_{q}) = \frac{\partial S_{z}}{\partial U_{s}}*
+                //  \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
+                //  {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}}.
+
+                //If @V_{q}=\pm \pi /2@, then
+                //  \frac{\partial S_{z}}{\partial U_{s}}*
+                //  \frac{\mathrm{d} U_{s}} {\mathrm{d} V_{q}}+\frac{\partial S_{z}}
+                //  {\partial V_{s}}*\frac{\mathrm{d} V_{s}}{\mathrm{d} V_{q}} = 0.
+
+                //Consequently, if @\frac{\partial S_{z}}{\partial U_{s}} \neq 0 @ then
+                //  \frac{\mathrm{d} U_{s}}{\mathrm{d} V_{s}} =
+                //  -\frac{\frac{\partial S_{z}}{\partial V_{s}}}
+                //  {\frac{\partial S_{z}}{\partial U_{s}}}.
+
+                //If @ \frac{\partial S_{z}}{\partial V_{s}} \neq 0 @ then
+                //  \frac{\mathrm{d} V_{s}}{\mathrm{d} U_{s}} =
+                //  -\frac{\frac{\partial S_{z}}{\partial U_{s}}}
+                //  {\frac{\partial S_{z}}{\partial V_{s}}}
+
+                //Cases, when @ \frac{\partial S_{z}}{\partial U_{s}} = 
+                //\frac{\partial S_{z}}{\partial V_{s}} = 0 @ are not consider here.
+                //The reason is written below.
+
+                //Vector with {@ \cos (U_{q}) @, @ \sin (U_{q}) @} coordinates.
+                //Ask to pay attention to the fact that this vector is always normalyzed.
+                gp_Vec2d aV1;
+          
+                if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
+                {
+                  //Example of this exception is intersection a plane with a sphere
+                  //when the plane tangents the sphere in some pole (i.e. only one 
+                  //intersection point, not line). In this case, U-coordinate of the
+                  //sphere is undefined (can be realy anything). On the other hand,
+                  //in this case there are not any Walking-line to be decomposited.
+                  Standard_NumericError_Raise_if(Abs(aVecDu.Z()) < Precision::PConfusion(),
+                    "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
+                                          "Cannot find UV-coordinate for quadric in the pole");
+                  const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
+
+                  aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
+                                aVecDu.Y()*aDusDvs - aVecDv.Y());
+                }
+                else
+                {
+                  //Example of this exception is intersection a plane with a sphere
+                  //when the plane tangents the sphere in some pole (i.e. only one 
+                  //intersection point, not line). In this case, U-coordinate of the
+                  //sphere is undefined (can be realy anything). On the other hand,
+                  //in this case there are not any Walking-line to be decomposited.
+                  Standard_NumericError_Raise_if(Abs(aVecDv.Z()) < Precision::PConfusion(),
+                    "IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
+                                          "Cannot find UV-coordinate for quadric in the pole");
+
+                  const Standard_Real aDvsDus = aVecDu.Z()/aVecDv.Z();
+                  aV1.SetCoord( aVecDv.X()*aDvsDus - aVecDu.X(),
+                                aVecDv.Y()*aDvsDus - aVecDu.Y());
+                }
+
+                aV1.Normalize();
+
+                if(Abs(aV1.X()) > Abs(aV1.Y()))
+                  aUquad = Sign(asin(aV1.Y()), aVquad);
+                else
+                  aUquad = Sign(acos(aV1.X()), aVquad);
+              }
+
+              {
+                //Adjust found U-paramter to previous point of the Walking-line
+                Standard_Real aDeltaPar = aUQuadRef-aUquad;
+                const Standard_Real anIncr = aPeriod*Sign(1.0, aDeltaPar);
+                while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
+                {
+                  aUquad += anIncr;
+                  aDeltaPar = aUQuadRef-aUquad;
+                }
+              }
+              
+              aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
+              
+              sline->Add(aNewPoint);
+              PrePointExist = PrePoint_POLE;
+              PrePoint = aNewPoint;
+            }
+          }
+        }
+
         ////
         break;
       }
@@ -2572,11 +2827,6 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_Line)& theLine,
       }
     }
 
-    if(!hasInternals)
-    {
-      ForcedPurgePoints(sline,IsReversed,theQuad);
-    }
-
     Handle(IntPatch_WLine) wline = 
                         new IntPatch_WLine(sline,Standard_False,
                         theLine->TransitionOnS1(),theLine->TransitionOnS2());
index 3e4c7db..dc234e3 100644 (file)
@@ -12,6 +12,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <IntPatch_Intersection.hxx>
 
 #include <Adaptor3d_HSurface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
 #include <IntPatch_GLine.hxx>
 #include <IntPatch_ImpImpIntersection.hxx>
 #include <IntPatch_ImpPrmIntersection.hxx>
-#include <IntPatch_Intersection.hxx>
 #include <IntPatch_Line.hxx>
 #include <IntPatch_Point.hxx>
 #include <IntPatch_PrmPrmIntersection.hxx>
 #include <IntPatch_RLine.hxx>
 #include <IntPatch_WLine.hxx>
+#include <IntPatch_WLineTool.hxx>
 #include <IntSurf_Quadric.hxx>
 #include <Standard_ConstructionError.hxx>
 #include <Standard_DomainError.hxx>
 #include <Standard_OutOfRange.hxx>
 #include <StdFail_NotDone.hxx>
+#include <IntPatch_LineConstructor.hxx>
 
 #include <stdio.h>
 #define DEBUG 0 
 static const Standard_Integer aNbPointsInALine = 200;
 
-//=======================================================================
-//function : MinMax
-//purpose  : Replaces theParMIN = MIN(theParMIN, theParMAX),
-//                    theParMAX = MAX(theParMIN, theParMAX).
-//=======================================================================
-static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
-{
-  if(theParMIN > theParMAX)
-  {
-    const Standard_Real aTmp = theParMAX;
-    theParMAX = theParMIN;
-    theParMIN = aTmp;
-  }
-}
-
-//=======================================================================
-//function : IsSeam
-//purpose  : Returns:
-//            0 - if interval [theU1, theU2] does not intersect the "seam-edge"
-//                or if "seam-edge" do not exist;
-//            1 - if interval (theU1, theU2) intersect the "seam-edge".
-//            2 - if theU1 or/and theU2 lie ON the "seam-edge"
-//
-//ATTENTION!!!
-//  If (theU1 == theU2) then this function will return only both 0 or 2.
-//=======================================================================
-static Standard_Integer IsSeam( const Standard_Real theU1,
-                                const Standard_Real theU2,
-                                const Standard_Real thePeriod)
-{
-  if(IsEqual(thePeriod, 0.0))
-    return 0;
-
-  //If interval [theU1, theU2] intersect seam-edge then there exists an integer
-  //number N such as 
-  //    (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T),
-  //where T is the period.
-  //I.e. the inerval [theU1/T, theU2/T] must contain at least one
-  //integer number. In this case, Floor(theU1/T) and Floor(theU2/T)
-  //return different values or theU1/T is strictly integer number.
-  //Examples:
-  //  1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3.
-  //  2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2.
-
-  const Standard_Real aVal1 = theU1/thePeriod,
-                      aVal2 = theU2/thePeriod;
-  const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
-  const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
-  if(aPar1 != aPar2)
-  {//Interval (theU1, theU2] intersects seam-edge
-    if(IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
-    {//aVal2 is an integer number => theU2 lies ON the "seam-edge"
-      return 2;
-    }
-
-    return 1;
-  }
-
-  //Here, aPar1 == aPar2. 
-
-  if(IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
-  {//aVal1 is an integer number => theU1 lies ON the "seam-edge"
-    return 2;
-  }
-
-  //If aVal2 is a true integer number then always (aPar1 != aPar2).
-
-  return 0;
-}
-
-//=======================================================================
-//function : IsSeamOrBound
-//purpose  : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge"
-//            (if it exist) or surface boundaries and both thePtf and thePtl do
-//            not match "seam-edge" or boundaries.
-//           Point thePtmid lies in this segment. If thePtmid match
-//            "seam-edge" or boundaries strictly (without any tolerance) then
-//            the function will return TRUE.
-//            See comments in function body for detail information.
-//=======================================================================
-static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
-                                      const IntSurf_PntOn2S& thePtl,
-                                      const IntSurf_PntOn2S& thePtmid,
-                                      const Standard_Real theU1Period,
-                                      const Standard_Real theU2Period,
-                                      const Standard_Real theV1Period,
-                                      const Standard_Real theV2Period,
-                                      const Standard_Real theUfSurf1,
-                                      const Standard_Real theUlSurf1,
-                                      const Standard_Real theVfSurf1,
-                                      const Standard_Real theVlSurf1,
-                                      const Standard_Real theUfSurf2,
-                                      const Standard_Real theUlSurf2,
-                                      const Standard_Real theVfSurf2,
-                                      const Standard_Real theVlSurf2)
-{
-  Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
-  Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
-  thePtf.Parameters(aU11, aV11, aU12, aV12);
-  thePtl.Parameters(aU21, aV21, aU22, aV22);
-
-  MinMax(aU11, aU21);
-  MinMax(aV11, aV21);
-  MinMax(aU12, aU22);
-  MinMax(aV12, aV22);
-
-  if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0)
-  {//Interval [aU11, aU21] intersects theUfSurf1
-    return Standard_True;
-  }
-
-  if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0)
-  {//Interval [aU11, aU21] intersects theUlSurf1
-    return Standard_True;
-  }
-
-  if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0)
-  {//Interval [aV11, aV21] intersects theVfSurf1
-    return Standard_True;
-  }
-
-  if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0)
-  {//Interval [aV11, aV21] intersects theVlSurf1
-    return Standard_True;
-  }
-
-  if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0)
-  {//Interval [aU12, aU22] intersects theUfSurf2
-    return Standard_True;
-  }
-
-  if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0)
-  {//Interval [aU12, aU22] intersects theUlSurf2
-    return Standard_True;
-  }
-
-  if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0)
-  {//Interval [aV12, aV22] intersects theVfSurf2
-    return Standard_True;
-  }
-
-  if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0)
-  {//Interval [aV12, aV22] intersects theVlSurf2
-    return Standard_True;
-  }
-
-  if(IsSeam(aU11, aU21, theU1Period))
-    return Standard_True;
-
-  if(IsSeam(aV11, aV21, theV1Period))
-    return Standard_True;
-
-  if(IsSeam(aU12, aU22, theU2Period))
-    return Standard_True;
-
-  if(IsSeam(aV12, aV22, theV2Period))
-    return Standard_True;
-
-  /*
-    The segment [thePtf, thePtl] does not intersect the boundaries and
-    the seam-edge of the surfaces.
-    Nevertheless, following situation is possible:
-
-                  seam or
-                   bound
-                     |
-        thePtf  *    |
-                     |
-                     * thePtmid
-          thePtl  *  |
-                     |
-
-    This case must be processed, too.
-  */
-
-  Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
-  thePtmid.Parameters(aU1, aV1, aU2, aV2);
-
-  if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1))
-    return Standard_True;
-
-  if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2))
-    return Standard_True;
-
-  if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1))
-    return Standard_True;
-
-  if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2))
-    return Standard_True;
-
-  if(IsSeam(aU1, aU1, theU1Period))
-    return Standard_True;
-
-  if(IsSeam(aU2, aU2, theU2Period))
-    return Standard_True;
-
-  if(IsSeam(aV1, aV1, theV1Period))
-    return Standard_True;
-
-  if(IsSeam(aV2, aV2, theV2Period))
-    return Standard_True;
-
-  return Standard_False;
-}
-
-//=======================================================================
-//function : JoinWLines
-//purpose  : joins all WLines from theSlin to one if it is possible and
-//            records the result into theSlin again.
-//            Lines will be kept to be splitted if:
-//              a) they are separated (has no common points);
-//              b) resulted line (after joining) go through
-//                 seam-edges or surface boundaries.
-//
-//          In addition, if points in theSPnt lies at least in one of 
-//          the line in theSlin, this point will be deleted.
-//=======================================================================
-static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
-                IntPatch_SequenceOfPoint& theSPnt,
-                const Standard_Real theTol3D,
-                const Standard_Real theU1Period,
-                const Standard_Real theU2Period,
-                const Standard_Real theV1Period,
-                const Standard_Real theV2Period,
-                const Standard_Real theUfSurf1,
-                const Standard_Real theUlSurf1,
-                const Standard_Real theVfSurf1,
-                const Standard_Real theVlSurf1,
-                const Standard_Real theUfSurf2,
-                const Standard_Real theUlSurf2,
-                const Standard_Real theVfSurf2,
-                const Standard_Real theVlSurf2)
-{
-  if(theSlin.Length() == 0)
-    return;
-
-  for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
-  {
-    Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1)));
-
-    if(aWLine1.IsNull())
-    {//We must have failed to join not-point-lines
-      return;
-    }
-
-    const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
-    const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1);
-    const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1);
-
-    for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
-    {
-      const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
-
-      if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) ||
-        aPntCur.IsSame(aPntLW1, Precision::Confusion()))
-      {
-        theSPnt.Remove(aNPt);
-        aNPt--;
-      }
-    }
-
-    Standard_Boolean hasBeenRemoved = Standard_False;
-    for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
-    {
-      Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2)));
-
-      const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
-
-      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
-
-      const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
-      const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
-
-      if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
-      {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
-        if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
-      {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
-        if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->InsertBefore(1, aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
-      {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
-        if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-
-      if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
-      {
-        const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
-        const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
-        if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period,
-                          theV1Period, theV2Period, theUfSurf1, theUlSurf1,
-                          theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
-                          theVfSurf2, theVlSurf2))
-        {
-          aWLine1->ClearVertexes();
-          for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
-          {
-            const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
-            aWLine1->Curve()->Add(aPt);
-          }
-
-          aWLine1->ComputeVertexParameters(theTol3D);
-
-          theSlin.Remove(aNumOfLine2);
-          aNumOfLine2--;
-          hasBeenRemoved = Standard_True;
-
-          continue;
-        }
-      }
-    }
-
-    if(hasBeenRemoved)
-      aNumOfLine1--;
-  }
-}
-
 //======================================================================
 // function: SequenceOfLine
 //======================================================================
@@ -1103,7 +721,8 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
                                     const Standard_Real TolArc,
                                     const Standard_Real TolTang,
                                     const Standard_Boolean isGeomInt,
-                                    const Standard_Boolean theIsReqToKeepRLine)
+                                    const Standard_Boolean theIsReqToKeepRLine,
+                                    const Standard_Boolean theIsReqToPostWLProc)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
@@ -1336,6 +955,25 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
                         TolTang, ListOfPnts, RestrictLine, typs1, typs2);
   }
+
+  if(!theIsReqToPostWLProc)
+    return;
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
+  }
 }
 
 //=======================================================================
@@ -1350,7 +988,9 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
                                     const Standard_Real TolTang,
                                     IntSurf_ListOfPntOn2S& ListOfPnts,
                                     const Standard_Boolean RestrictLine,
-                                    const Standard_Boolean isGeomInt)
+                                    const Standard_Boolean isGeomInt,
+                                    const Standard_Boolean theIsReqToKeepRLine,
+                                    const Standard_Boolean theIsReqToPostWLProc)
 {
   myTolArc = TolArc;
   myTolTang = TolTang;
@@ -1547,14 +1187,33 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
     if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
     {
       GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, 
-                      TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+                      TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
     }
     else
     {
       GeomGeomPerfomTrimSurf(theS1, theD1, theS2, theD2,
-              TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+              TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
     }
   }
+
+  if(!theIsReqToPostWLProc)
+    return;
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
+  }
 }
 
 //=======================================================================
@@ -1912,15 +1571,19 @@ void IntPatch_Intersection::
           spnt.Append(aPoint);
         }
 
-        JoinWLines( slin, spnt, theTolTang,
-                    theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
-                    theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
-                    theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
-                    theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
-                    theS1->FirstUParameter(), theS1->LastUParameter(),
-                    theS1->FirstVParameter(), theS1->LastVParameter(),
-                    theS2->FirstUParameter(), theS2->LastUParameter(),
-                    theS2->FirstVParameter(), theS2->LastVParameter());
+        IntPatch_WLineTool::JoinWLines( slin, spnt, theTolTang,
+                                        theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
+                                        theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
+                                        theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
+                                        theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
+                                        theS1->FirstUParameter(),
+                                        theS1->LastUParameter(),
+                                        theS1->FirstVParameter(),
+                                        theS1->LastVParameter(),
+                                        theS2->FirstUParameter(),
+                                        theS2->LastUParameter(),
+                                        theS2->FirstVParameter(),
+                                        theS2->LastVParameter());
       }
     }
   }
@@ -2000,31 +1663,35 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
     }
   }
+
+  for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+  {
+    Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+    if(aWL.IsNull())
+      continue;
+
+    Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
+
+    if(aRW.IsNull())
+      continue;
+
+    slin.InsertAfter(i, aRW);
+    slin.Remove(i);
+  }
 }
-//======================================================================
-#include <IntPatch_IType.hxx>
-#include <IntPatch_LineConstructor.hxx>
-#include <Adaptor2d_HCurve2d.hxx>
-#include <Geom_Curve.hxx>
-#define MAXR 200
-
-
-//void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
-//                                     Handle(Adaptor2d_HCurve2d) *R2,
-//                                     int *NR1,
-//                                     int *NR2,
-//                                     Standard_Integer nbR1,
-//                                     Standard_Integer nbR2,
-//                                     const IntPatch_Point& VTX)
-void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *,
+
+#ifdef DUMPOFIntPatch_Intersection
+
+void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
                                   Handle(Adaptor2d_HCurve2d) *,
+                                  int *NR1,
                                   int *,
-                                  int *,
-                                  Standard_Integer ,
+                                  Standard_Integer nbR1,
                                   Standard_Integer ,
-                                  const IntPatch_Point& )
+                                  const IntPatch_Point& VTX)
 { 
-  /*
+  
   if(VTX.IsOnDomS1()) { 
     
     //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
@@ -2038,18 +1705,17 @@ void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *,
     printf("\n R Pas trouvee  (IntPatch)\n");
     
   }
-  */
 }
+#endif
 
-
-//void IntPatch_Intersection::Dump(const Standard_Integer Mode,
-void IntPatch_Intersection::Dump(const Standard_Integer ,
-                                 const Handle(Adaptor3d_HSurface)&  S1,
-                                 const Handle(Adaptor3d_TopolTool)& D1,
-                                 const Handle(Adaptor3d_HSurface)&  S2,
-                                 const Handle(Adaptor3d_TopolTool)& D2) const 
+void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
+                                 const Handle(Adaptor3d_HSurface)&  /*S1*/,
+                                 const Handle(Adaptor3d_TopolTool)& /*D1*/,
+                                 const Handle(Adaptor3d_HSurface)&  /*S2*/,
+                                 const Handle(Adaptor3d_TopolTool)& /*D2*/) const 
 { 
-  
+#ifdef DUMPOFIntPatch_Intersection
+  const int MAXR = 200;
   //-- ----------------------------------------------------------------------
   //--  construction de la liste des restrictions & vertex 
   //--
@@ -2061,14 +1727,14 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
     NR1[nbR1]=0;
     nbR1++;
   }
-  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) { 
+  for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
     R2[nbR2]=D2->Value();
     NR2[nbR2]=0;
     nbR2++;
   }
   
   printf("\nDUMP_INT:  ----empt:%2ud  tgte:%2ud  oppo:%2ud ---------------------------------",empt,tgte,empt);
-  Standard_Integer i,j,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
+  Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
   nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
   nbl=NbLines();
   for(i=1;i<=nbl;i++) { 
@@ -2151,7 +1817,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
          nbvw,nbvr,nbva,nbvg);
 
+  printf("\n");
 
-
-   printf("\n");
+#endif 
 }
index 799c099..cfe6b03 100644 (file)
@@ -79,14 +79,32 @@ public:
   //! When intersection result returns IntPatch_RLine and another
   //! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
   //! will always keep both lines even if they are coincided.
-  Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False);
+  //! Flag theIsReqToPostWLProc has been enterred only for
+  //! compatibility with TopOpeBRep package. It shall be deleted
+  //! after deleting TopOpeBRep.
+  //! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
+  //! obtained after intersection algorithm directly (wothout any post-processing). 
+  Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
   
   //! If isGeomInt == Standard_False, then method
   //! Param-Param intersection will be used.
-  Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True);
+  //! Flag theIsReqToKeepRLine has been enterred only for
+  //! compatibility with TopOpeBRep package. It shall be deleted
+  //! after deleting TopOpeBRep.
+  //! When intersection result returns IntPatch_RLine and another
+  //! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
+  //! will always keep both lines even if they are coincided.
+  //! Flag theIsReqToPostWLProc has been enterred only for
+  //! compatibility with TopOpeBRep package. It shall be deleted
+  //! after deleting TopOpeBRep.
+  //! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
+  //! obtained after intersection algorithm directly (wothout any post-processing). 
+  Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
   
+  //! Perform with start point
   Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2, const Standard_Real TolArc, const Standard_Real TolTang);
   
+  //! Uses for finding self-intersected surfaces.
   Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolArc, const Standard_Real TolTang);
   
   //! Returns True if the calculus was succesfull.
diff --git a/src/IntPatch/IntPatch_WLineTool.cxx b/src/IntPatch/IntPatch_WLineTool.cxx
new file mode 100644 (file)
index 0000000..02208c1
--- /dev/null
@@ -0,0 +1,953 @@
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <IntPatch_WLineTool.hxx>
+
+#include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_TopolTool.hxx>
+
+//=======================================================================
+//function : MinMax
+//purpose  : Replaces theParMIN = MIN(theParMIN, theParMAX),
+//                    theParMAX = MAX(theParMIN, theParMAX).
+//
+//           Static subfunction in IsSeamOrBound.
+//=======================================================================
+static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
+{
+  if(theParMIN > theParMAX)
+  {
+    const Standard_Real aTmp = theParMAX;
+    theParMAX = theParMIN;
+    theParMIN = aTmp;
+  }
+}
+
+//=========================================================================
+// function : FillPointsHash
+// purpose  : Fill points hash by input data.
+//            Static subfunction in ComputePurgedWLine.
+//=========================================================================
+static void FillPointsHash(const Handle(IntPatch_WLine)         &theWLine,
+                           NCollection_Array1<Standard_Integer> &thePointsHash)
+{
+  // 1 - Delete point.
+  // 0 - Store point.
+  // -1 - Vertex point (not delete).
+  Standard_Integer i, v;
+
+  for(i = 1; i <= theWLine->NbPnts(); i++)
+    thePointsHash.SetValue(i, 0);
+
+  for(v = 1; v <= theWLine->NbVertex(); v++) 
+  {
+    IntPatch_Point aVertex = theWLine->Vertex(v);
+    Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
+    thePointsHash.SetValue(avertexindex, -1);
+  }
+}
+
+//=========================================================================
+// function : MakeNewWLine
+// purpose  : Makes new walking line according to the points hash
+//            Static subfunction in ComputePurgedWLine and DeleteOuter.
+//=========================================================================
+static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine)         &theWLine,
+                                           const NCollection_Array1<Standard_Integer> &thePointsHash)
+{
+  Standard_Integer i;
+
+  Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S();
+  Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False);
+  Standard_Integer anOldLineIdx = 1, aVertexIdx = 1;
+  for(i = 1; i <= thePointsHash.Upper(); i++)
+  {
+    if (thePointsHash(i) == 0)
+    {
+      // Store this point.
+      aPurgedLineOn2S->Add(theWLine->Point(i));
+      anOldLineIdx++;
+    }
+    else if (thePointsHash(i) == -1)
+    {
+      // Add vertex.
+      IntPatch_Point aVertex = theWLine->Vertex(aVertexIdx++);
+      aVertex.SetParameter(anOldLineIdx++);
+      aLocalWLine->AddVertex(aVertex);
+      aPurgedLineOn2S->Add(theWLine->Point(i));
+    }
+  }
+
+  return aLocalWLine;
+}
+
+//=========================================================================
+// function : MovePoint
+// purpose  : Move point into surface param space. No interpolation used 
+//            because walking algorithm should care for closeness to the param space.
+//            Static subfunction in ComputePurgedWLine.
+//=========================================================================
+static void MovePoint(const Handle(Adaptor3d_HSurface)   &theS1,
+                      Standard_Real &U1, Standard_Real &V1)
+{
+  if (U1 < theS1->FirstUParameter())
+    U1 = theS1->FirstUParameter();
+
+  if (U1 > theS1->LastUParameter())
+    U1 = theS1->LastUParameter();
+
+  if (V1 < theS1->FirstVParameter())
+    V1 = theS1->FirstVParameter();
+
+  if (V1 > theS1->LastVParameter())
+   V1 = theS1->LastVParameter();
+}
+
+//=========================================================================
+// function : DeleteOuterPoints
+// purpose  : Check and delete out of bounds points on walking line.
+//            Static subfunction in ComputePurgedWLine.
+//=========================================================================
+static Handle(IntPatch_WLine)
+  DeleteOuterPoints(const Handle(IntPatch_WLine)       &theWLine,
+                    const Handle(Adaptor3d_HSurface)   &theS1,
+                    const Handle(Adaptor3d_HSurface)   &theS2,
+                    const Handle(Adaptor3d_TopolTool)  &theDom1,
+                    const Handle(Adaptor3d_TopolTool)  &theDom2)
+{
+  Standard_Integer i;
+
+  NCollection_Array1<Standard_Integer> aDelOuterPointsHash(1, theWLine->NbPnts());
+  FillPointsHash(theWLine, aDelOuterPointsHash);
+
+  if (theS1->IsUPeriodic() || theS1->IsVPeriodic() ||
+      theS2->IsUPeriodic() || theS2->IsVPeriodic() )
+      return theWLine;
+
+  gp_Pnt2d aPntOnF1, aPntOnF2;
+  Standard_Real aX1, aY1, aX2, aY2;
+
+  // Iterate over points in walking line and delete which are out of bounds.
+  // Forward.
+  Standard_Boolean isAllDeleted = Standard_True;
+  Standard_Boolean aChangedFirst = Standard_False;
+  Standard_Integer aFirstGeomIdx = 1;
+  for(i = 1; i <= theWLine->NbPnts(); i++)
+  {
+    theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2);
+    aPntOnF1.SetCoord(aX1, aY1);
+    aPntOnF2.SetCoord(aX2, aY2);
+
+    TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion());
+    TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion());
+
+    if (aState1 == TopAbs_OUT ||
+        aState2 == TopAbs_OUT )
+    {
+      aDelOuterPointsHash(i) = 1;
+      aChangedFirst = Standard_True;
+    }
+    else
+    {
+      isAllDeleted = Standard_False;
+
+      aFirstGeomIdx = Max (i - 1, 1);
+      if (aDelOuterPointsHash(i) == -1)
+        aFirstGeomIdx = i; // Use data what lies in (i) point / vertex.
+
+      aDelOuterPointsHash(i) = -1;
+      break;
+    }
+  }
+
+  if (isAllDeleted)
+  {
+    // ALL points are out of bounds:
+    // case boolean bcut_complex F5 and similar.
+    return theWLine;
+  }
+
+  // Backward.
+  Standard_Boolean aChangedLast = Standard_False;
+  Standard_Integer aLastGeomIdx = theWLine->NbPnts();
+  for(i = theWLine->NbPnts(); i >= 1; i--)
+  {
+    theWLine->Point(i).Parameters(aX1, aY1, aX2, aY2);
+    aPntOnF1.SetCoord(aX1, aY1);
+    aPntOnF2.SetCoord(aX2, aY2);
+
+    TopAbs_State aState1 = theDom1->Classify(aPntOnF1, Precision::Confusion());
+    TopAbs_State aState2 = theDom2->Classify(aPntOnF2, Precision::Confusion());
+
+    if (aState1 == TopAbs_OUT ||
+        aState2 == TopAbs_OUT )
+    {
+      aDelOuterPointsHash(i) = 1;
+      aChangedLast = Standard_True; // Move vertex to first good point
+    }
+    else
+    {
+      aLastGeomIdx = Min (i + 1, theWLine->NbPnts());
+      if (aDelOuterPointsHash(i) == -1)
+        aLastGeomIdx = i; // Use data what lies in (i) point / vertex.
+
+      aDelOuterPointsHash(i) = -1;
+      break;
+    }
+  }
+
+  if (!aChangedFirst && !aChangedLast)
+  {
+    // Nothing is done, return input.
+    return theWLine;
+  }
+
+  // Build new line and modify geometry of necessary vertexes.
+  Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash);
+
+  if (aChangedFirst)
+&nbs