0027431: [Regression to 6.9.1] Huge tolerance obtained during intersection of cylinde...
authornbv <nbv@opencascade.com>
Wed, 2 Nov 2016 12:25:36 +0000 (15:25 +0300)
committerapn <apn@opencascade.com>
Thu, 3 Nov 2016 11:15:41 +0000 (14:15 +0300)
The root of the problem is incorrect processing of cases when intersection line goes through the apex(es) of sphere. The fix improves this situation. The algorithm is taken from DecomposeResult(...) function (see IntPatch_ImpPrmIntersection.cxx file). Before the fix, faltering steps were done to solve this problem. As result, it worked in some particular cases. Now, its possibilities have been extended significantly.

Following changes have been made in the fix:

1. Class IntPatch_ALineToWLine has been rewritten cardinally. It touches as interfaces of existing methods as adding/removing some methods/fields. Correction touches both cases: going through seam of Cone/Sphere and through pole(s) of sphere. Old interface did not allow making some actions with analytical line (ALine), e.g. splitting it on several Walking-lines (WLine).

2. Restriction-line support has been removed from Implicit-Implicit intersection result (see IntPatch_Intersection::GeomGeomPerfom(...) method). It connects with the fact that the intersection algorithm itself returns precise intersection line in analytical cases (in compare with parametric intersector). Therefore, we do not need in additional (restriction) line.

3. New class IntPatch_SpecialPoints has been added. This class contains methods to add some special points (such as apex of cone, pole of sphere, point on surface boundary etc.) in intersection line (IntPatch_PointLine). It is based on the static functions, which already exist in IntPatch_ImpPrmIntersection.cxx file (these functions have been moved to the new class).

4. Method IntPatch_WLineTool::ExtendTwoWlinesToEachOther(...) has been renamed to IntPatch_WLineTool::ExtendTwoWLines(...). It is connected with changing main idea of the method. Now it allows extending WLine to the surface boundary or to the singular point (if it is possible): cone apex, sphere pole etc. Interface of this method has been corrected, too. At that, old functionality (extending to each other) has been kept. For implementation of this algorithm, new enumeration "IntPatchWT_WLsConnectionType" has been created.

5. Method IntPatch_PointLine::CurvatureRadiusOfIntersLine(...) has been added. See IntPatch_PointLine.hxx for detail information. It allows correct step computing depended on the local curvature of the intersection line. This method uses geometrical properties of intersected surfaces to compute local curvature. Therefore, it can be applied in wide range of cases even if the intersection curve is not represented in explicit form (e.g. in case of param-param-intersection).

6. Method IntSurf::SetPeriod(...) has been created.

7. Additional check has been added in Draft_Modification::Perform() method for better choice of correct fragment of intersection line for processing DRAFT operation.

8. New overload method IntPatch_Point::SetValue() has been added.

9. Some refactoring of the code has been made.

Creation of test case for issue #27431.

---------------------------------------------------------------------------------------------
Some test cases have been adjusted according to their new behavior.

   tests\bugs\modalg_4\bug62
It is really IMPROVEMENT (but fortuitous).

   tests\bugs\modalg_5\bug25838
The behavior of this test has been reverted to the state before fixing the issue #27341. Main problem has not been fixed in #27341. It was fortuitous improvement.

    tests\bugs\moddata_2\bug565
Quality of intersection curve was not checked. And the curve is bad on both MASTER and FIX. Input data are really wrong: plane-like-cone. However, on the MASTER, four intersection curves (the quality is insignificant) are expected. On the fix, not empty intersection result is expected simply.

   tests\boolean\volumemaker\A8
Differences in images and CPU is expected. Difference in images is expected to be fixed in the issue #26020. Now, we should apply this behavior.
Much CPU time is spent by IntTools_FaceFace::ComputeTolReached3d(...) and GeomInt_IntSS::BuildPCurves(...) methods calling. These methods are not touched by the algorithm. It is the result of change of intersection curve(s) form. However, the new Curve(s) seems to be valid and can be applied. As result, new behavior can be applied, too.

   tests\boolean\volumemaker\F8
   tests\boolean\volumemaker\F9
   tests\boolean\volumemaker\G5
   tests\boolean\volumemaker\G6
CPU difference is expected. Much CPU time is spent by IntPatch_PointLine::CurvatureRadiusOfIntersLine(...) method calling. This method is really new (it does not exist on the MASTER) and is really useful. Therefore, we should apply new behavior.

   tests\boolean\volumemaker\G1
CPU difference is expected. Much CPU time is spent by IntTools_WLineTool::DecompositionOfWLine(...) and IntTools_FaceFace::ComputeTolReached3d(...) methods calling. These methods are not touched by the algorithm. It is the result of change of intersection curve(s) form. However, the new Curve(s) seems to be valid and can be applied. As result, new behavior can be applied, too.

   tests\bugs\modalg_6\bug26619
Differences in images is expected. The test keeps its BAD status on the FIX. But the result on the fix is nearer to expected than on the MASTER. Issue #27014 is still actual. As before, it is not clear, why the number of entities is different. The number of section curves has not been changed. Interfered entities are the same as on the MASTER.

   tests\bugs\modalg_5\bug25319_1(2)
The reason is described in the issue #27896.

Small correction in the test case

37 files changed:
src/Draft/Draft_Modification_1.cxx
src/ElCLib/ElCLib.hxx
src/GeomInt/GeomInt_IntSS.cxx
src/GeomInt/GeomInt_IntSS_1.cxx
src/IntAna/IntAna_Curve.cxx
src/IntPatch/FILES
src/IntPatch/IntPatch_ALineToWLine.cxx
src/IntPatch/IntPatch_ALineToWLine.hxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntPatch/IntPatch_Intersection.cxx
src/IntPatch/IntPatch_Point.hxx
src/IntPatch/IntPatch_Point.lxx
src/IntPatch/IntPatch_PointLine.cxx
src/IntPatch/IntPatch_PointLine.hxx
src/IntPatch/IntPatch_SpecPntType.hxx [new file with mode: 0644]
src/IntPatch/IntPatch_SpecialPoints.cxx [new file with mode: 0644]
src/IntPatch/IntPatch_SpecialPoints.hxx [new file with mode: 0644]
src/IntPatch/IntPatch_WLineTool.cxx
src/IntPatch/IntPatch_WLineTool.hxx
src/IntSurf/IntSurf.cxx
src/IntSurf/IntSurf.hxx
src/IntTools/IntTools_FaceFace.cxx
src/IntTools/IntTools_Tools.cxx
src/TopOpeBRep/TopOpeBRep_LineInter.cxx
tests/bugs/modalg_4/bug62
tests/bugs/modalg_4/bug826
tests/bugs/modalg_4/bug826_1
tests/bugs/modalg_5/bug25292_33
tests/bugs/modalg_5/bug25292_34
tests/bugs/modalg_5/bug25319_1
tests/bugs/modalg_5/bug25319_2
tests/bugs/modalg_5/bug25838
tests/bugs/modalg_6/bug27282_2
tests/bugs/modalg_6/bug27302
tests/bugs/modalg_6/bug27431 [new file with mode: 0644]
tests/bugs/moddata_2/bug565
tests/bugs/moddata_3/bug23981

index 47c00b5..e7928c9 100644 (file)
@@ -1549,6 +1549,58 @@ void Draft_Modification::Perform ()
       Vf.Reverse();
       Vl.Reverse();
     }
+
+    if(myVMap.Contains(Vf) && myVMap.Contains(Vl))
+    {
+      //Here, we compare directions of the source edge (from input shape)
+      //and corresponding selected part of the intersection edge.
+      //If these directions are opposite then we reverse intersection edge
+      //and recompute corresponding vertex-parameters.
+
+      Standard_Real aParF = myVMap.ChangeFromKey(Vf).Parameter(edg);
+      Standard_Real aParL = myVMap.ChangeFromKey(Vl).Parameter(edg);
+
+      if(aParL < aParF)
+      {
+        Draft_EdgeInfo& aEinf = myEMap.ChangeFromKey(edg);
+        TopLoc_Location aLoc;
+        Standard_Real aF = 0.0, aL = 0.0;
+        const Handle(Geom_Curve) aSCurve = BRep_Tool::Curve(edg, aF, aL);
+        Handle(Geom_Curve) anIntCurv = aEinf.Geometry();
+        gp_Pnt aPf, aPl;
+        gp_Vec aDirNF, aDirNL, aDirOF, aDirOL;
+        aSCurve->D1(BRep_Tool::Parameter(Vf, edg), aPf, aDirOF);
+        aSCurve->D1(BRep_Tool::Parameter(Vl, edg), aPl, aDirOL);
+        anIntCurv->D1(aParF, aPf, aDirNF);
+        anIntCurv->D1(aParL, aPl, aDirNL);
+
+        aDirNF.Normalize();
+        aDirNL.Normalize();
+        aDirOF.Normalize();
+        aDirOL.Normalize();
+
+        const Standard_Real aCosF = aDirNF.Dot(aDirOF), aCosL = aDirNL.Dot(aDirOL);
+        const Standard_Real aCosMax = Abs(aCosF) > Abs(aCosL) ? aCosF : aCosL;
+
+        if(aCosMax < 0.0)
+        {
+          Standard_Integer anErr = 0;
+          anIntCurv->Reverse();
+          aEinf.ChangeGeometry() = anIntCurv;
+          Standard_Real aPar = Parameter(aEinf.Geometry(), aPf, anErr);
+          if(anErr == 0)
+          {
+            myVMap.ChangeFromKey(Vf).ChangeParameter(edg) = aPar;
+          }
+          aPar = Parameter(aEinf.Geometry(), aPl, anErr);
+          if(anErr == 0)
+          {
+            myVMap.ChangeFromKey(Vl).ChangeParameter(edg) = aPar;
+          }
+        }
+      }
+    }
+
     Standard_Real pf,pl,tolerance;
     if (!NewParameter(Vf,edg,pf,tolerance)) {
       pf = BRep_Tool::Parameter(Vf,edg);
index 6373a63..6c56554 100644 (file)
@@ -78,6 +78,8 @@ public:
   //! Return a value in   the  range <UFirst, ULast>  by
   //! adding or removing the period <ULast -  UFirst> to
   //! <U>.
+  //! ATTENTION!!!
+  //!   It is expected but not checked that (ULast > UFirst)
   Standard_EXPORT static Standard_Real InPeriod (const Standard_Real U, const Standard_Real UFirst, const Standard_Real ULast);
   
   //! Adjust U1 and  U2 in the  parametric range  UFirst
index b44c0c1..0e2d7c9 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <GeomInt_IntSS.hxx>
 
 #include <Adaptor3d_TopolTool.hxx>
-#include <Bnd_Box2d.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Surface.hxx>
 #include <GeomAdaptor_HSurface.hxx>
-#include <GeomAdaptor_Surface.hxx>
-#include <GeomInt_IntSS.hxx>
-#include <gp_Pnt2d.hxx>
-#include <IntPatch_RLine.hxx>
-#include <Standard_ConstructionError.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <StdFail_NotDone.hxx>
 
 //=======================================================================
 //function : Perform
index f95970b..8ba1c0c 100644 (file)
@@ -24,7 +24,6 @@
 #include <Geom2dAdaptor.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 #include <Geom2dInt_GInter.hxx>
-#include <Geom2d_Curve.hxx>
 #include <Geom2d_Line.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <GeomAdaptor.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_RLine.hxx>
 #include <IntPatch_WLine.hxx>
 #include <IntRes2d_IntersectionSegment.hxx>
 #include <IntSurf_Quadric.hxx>
-#include <Geom_Surface.hxx>
+#include <Precision.hxx>
 
 //=======================================================================
 //function : AdjustUPeriodic
@@ -552,134 +549,9 @@ void GeomInt_IntSS::MakeCurve(const Standard_Integer Index,
                          //########################################  
                          // Analytic
                          //######################################## 
-  case IntPatch_Analytic: {
-    IntSurf_Quadric quad1,quad2;
-    //
-    GetQuadric(myHS1, quad1);
-    GetQuadric(myHS2, quad2);
-    //=========
-    IntPatch_ALineToWLine convert (quad1, quad2);
-
-    if (!myApprox) {
-      Handle(Geom2d_BSplineCurve) aH1, aH2;
-      //
-      aNbParts=myLConstruct.NbParts();
-      for (i=1; i<=aNbParts; i++) {
-        myLConstruct.Part(i, fprm, lprm);
-        Handle(IntPatch_WLine) WL = 
-          convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
-        //
-        if(myApprox1) {
-          aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-        }
-
-        if(myApprox2) {
-          aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-        }
-        sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
-        slineS1.Append(aH1);
-        slineS2.Append(aH2);
-      }
-    } // if (!myApprox)
-
-    else { // myApprox=TRUE
-      GeomInt_WLApprox theapp3d;
-      Standard_Real tol2d = myTolApprox;
-      //       
-      theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
-
-      aNbParts=myLConstruct.NbParts();
-      for (i=1; i<=aNbParts; i++) {
-        myLConstruct.Part(i, fprm, lprm);
-        Handle(IntPatch_WLine) WL = 
-          convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
-
-        theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
-        if (!theapp3d.IsDone()) {
-          //
-          Handle(Geom2d_BSplineCurve) aH1, aH2;
-
-          if(myApprox1) {
-            aH1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-          }
-
-          if(myApprox2) {
-            aH2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-          }
-          sline.Append(MakeBSpline(WL,1,WL->NbPnts()));
-          slineS1.Append(aH1);
-          slineS2.Append(aH1);
-        }
-        //
-        else {
-          if(myApprox1 || myApprox2) { 
-            if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) { 
-              myTolReached2d = theapp3d.TolReached2d();
-            }
-          }
+  case IntPatch_Analytic:
+    //This case was processed earlier (in IntPatch_Intersection)
 
-          if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) { 
-            myTolReached3d = theapp3d.TolReached3d();
-          }
-
-          Standard_Integer aNbMultiCurves, nbpoles;
-          aNbMultiCurves=theapp3d.NbMultiCurves();
-          for (j=1; j<=aNbMultiCurves; j++) {
-            const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-
-            nbpoles = mbspc.NbPoles();
-            TColgp_Array1OfPnt tpoles(1, nbpoles);
-            mbspc.Curve(1, tpoles);
-            Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
-              mbspc.Knots(),
-              mbspc.Multiplicities(),
-              mbspc.Degree());
-
-            GeomLib_CheckBSplineCurve Check(BS, myTolCheck, myTolAngCheck);
-            Check.FixTangent(Standard_True,Standard_True);
-            // 
-            sline.Append(BS);
-            //
-            if(myApprox1) { 
-              TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-              mbspc.Curve(2,tpoles2d);
-              Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
-                mbspc.Knots(),
-                mbspc.Multiplicities(),
-                mbspc.Degree());
-
-              GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-              newCheck.FixTangent(Standard_True,Standard_True);
-              slineS1.Append(BS2);             
-            }
-            else {
-              slineS1.Append(H1);
-            }
-
-            if(myApprox2) { 
-              TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
-              Standard_Integer TwoOrThree;
-              TwoOrThree=myApprox1 ? 3 : 2;
-              mbspc.Curve(TwoOrThree, tpoles2d);
-              Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
-                mbspc.Knots(),
-                mbspc.Multiplicities(),
-                mbspc.Degree());
-
-              GeomLib_Check2dBSplineCurve newCheck(BS2,myTolCheck,myTolAngCheck);
-              newCheck.FixTangent(Standard_True,Standard_True);
-              //       
-              slineS2.Append(BS2);
-            }
-            else { 
-              slineS2.Append(H1);
-            }
-            // 
-          }// for (j=1; j<=aNbMultiCurves; j++) {
-        }// else from if (!theapp3d.IsDone())
-      }// for (i=1; i<=aNbParts; i++) {
-    }// else { // myApprox=TRUE
-  }// case IntPatch_Analytic:
   break;
 
   //########################################  
index 12e3baa..f644f73 100644 (file)
                                     Standard_Real& sint,
                                     Standard_Real& SigneSqrtDis) const 
 {
+  const Standard_Real aRelTolp = 1.0+Epsilon(1.0), aRelTolm = 1.0-Epsilon(1.0);
   Standard_Real Theta=theta;
   Standard_Boolean SecondSolution=Standard_False; 
 
-  if((Theta<DomainInf)  ||  
-     ((Theta>DomainSup) && (!TwoCurves)) ||  
-     (Theta>(DomainSup+DomainSup-DomainInf+0.00000000000001))) {
+  if((Theta<DomainInf*aRelTolm)  ||  
+     ((Theta>DomainSup*aRelTolp) && (!TwoCurves)) ||  
+     (Theta>(DomainSup+DomainSup-DomainInf)*aRelTolp)) {
     SigneSqrtDis = 0.;
     Standard_DomainError::Raise("IntAna_Curve::Domain");
   }
     +Z0CosSin*costsint;
   
 
-  Standard_Real Discriminant = B*B-4.0*A*C;
+  const Standard_Real aDiscriminant = Max(B*B-4.0*A*C, 0.0);
   
-  if(Abs(A)<=0.000000001) {   
+  if(Abs(A)<=Precision::PConfusion()) {   
     //-- cout<<" IntAna_Curve:: Internal UV Value : A="<<A<<"  -> Abs(A)="<<Abs(A)<<endl;
-    if(Abs(B)<=0.0000000001) { 
+    if(Abs(B)<=Precision::PConfusion()) { 
       //-- cout<<" Probleme :  Pas de solutions "<<endl;
       Param2=0.0;
     }
     }
   }
   else {
-    if(Discriminant<=0.0000000001 || 
-       Abs(Discriminant/(4*A))<=0.0000000001) Discriminant=0.0;
-    SigneSqrtDis = (SecondSolution)? Sqrt(Discriminant) 
-      : -Sqrt(Discriminant);
+    SigneSqrtDis = (SecondSolution)? Sqrt(aDiscriminant) : -Sqrt(aDiscriminant);
     Param2=(-B+SigneSqrtDis)/(A+A);
   }
 }
index ea0520e..1791573 100755 (executable)
@@ -19,6 +19,7 @@ IntPatch_HCurve2dTool.lxx
 IntPatch_HInterTool.cxx
 IntPatch_HInterTool.hxx
 IntPatch_HInterTool.lxx
+IntPatch_IType.hxx
 IntPatch_ImpImpIntersection.cxx
 IntPatch_ImpImpIntersection.hxx
 IntPatch_ImpImpIntersection.lxx
@@ -37,7 +38,6 @@ IntPatch_InterferencePolyhedron.hxx
 IntPatch_Intersection.cxx
 IntPatch_Intersection.hxx
 IntPatch_Intersection.lxx
-IntPatch_IType.hxx
 IntPatch_Line.cxx
 IntPatch_Line.hxx
 IntPatch_Line.lxx
@@ -50,6 +50,8 @@ IntPatch_PointLine.cxx
 IntPatch_PointLine.hxx
 IntPatch_PolyArc.cxx
 IntPatch_PolyArc.hxx
+IntPatch_PolyLine.cxx
+IntPatch_PolyLine.hxx
 IntPatch_Polygo.cxx
 IntPatch_Polygo.hxx
 IntPatch_Polygo.lxx
@@ -57,8 +59,6 @@ IntPatch_Polyhedron.cxx
 IntPatch_Polyhedron.hxx
 IntPatch_PolyhedronTool.hxx
 IntPatch_PolyhedronTool.lxx
-IntPatch_PolyLine.cxx
-IntPatch_PolyLine.hxx
 IntPatch_PrmPrmIntersection.cxx
 IntPatch_PrmPrmIntersection.hxx
 IntPatch_PrmPrmIntersection.lxx
@@ -76,18 +76,21 @@ IntPatch_SequenceOfLine.hxx
 IntPatch_SequenceOfPathPointOfTheSOnBounds.hxx
 IntPatch_SequenceOfPoint.hxx
 IntPatch_SequenceOfSegmentOfTheSOnBounds.hxx
-IntPatch_TheIWalking.hxx
-IntPatch_TheIWalking_0.cxx
+IntPatch_SpecPntType.hxx
+IntPatch_SpecialPoints.cxx
+IntPatch_SpecialPoints.hxx
 IntPatch_TheIWLineOfTheIWalking.hxx
 IntPatch_TheIWLineOfTheIWalking_0.cxx
+IntPatch_TheIWalking.hxx
+IntPatch_TheIWalking_0.cxx
 IntPatch_ThePathPointOfTheSOnBounds.hxx
 IntPatch_ThePathPointOfTheSOnBounds_0.cxx
+IntPatch_TheSOnBounds.hxx
+IntPatch_TheSOnBounds_0.cxx
 IntPatch_TheSearchInside.hxx
 IntPatch_TheSearchInside_0.cxx
 IntPatch_TheSegmentOfTheSOnBounds.hxx
 IntPatch_TheSegmentOfTheSOnBounds_0.cxx
-IntPatch_TheSOnBounds.hxx
-IntPatch_TheSOnBounds_0.cxx
 IntPatch_TheSurfFunction.hxx
 IntPatch_TheSurfFunction_0.cxx
 IntPatch_WLine.cxx
index b31c05a..0f9826c 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <IntPatch_ALineToWLine.hxx>
 
-#include <Adaptor2d_HCurve2d.hxx>
-#include <GeomAbs_SurfaceType.hxx>
-#include <gp_Cone.hxx>
-#include <gp_Lin2d.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-#include <IntAna2d_AnaIntersection.hxx>
-#include <IntAna2d_IntPoint.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <ElSLib.hxx>
 #include <IntPatch_ALine.hxx>
-#include <IntPatch_ALineToWLine.hxx>
+#include <IntPatch_Point.hxx>
+#include <IntPatch_SpecialPoints.hxx>
 #include <IntPatch_WLine.hxx>
+#include <IntSurf.hxx>
 #include <IntSurf_LineOn2S.hxx>
-#include <IntSurf_PntOn2S.hxx>
-#include <IntSurf_Quadric.hxx>
-#include <IntSurf_Situation.hxx>
-#include <IntSurf_TypeTrans.hxx>
-#include <Precision.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-
-static 
-  gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline, 
-                 const Standard_Real U, 
-                 Standard_Real& DU,
-                 const Standard_Real CurvDef, 
-                 const Standard_Real AngDef);
-
-static 
-  Standard_Boolean SameCurve(const Handle(Adaptor2d_HCurve2d)& C1,
-                            const Handle(Adaptor2d_HCurve2d)& C2);
-
-static 
-  void RecadreMemePeriode(Standard_Real& u1,
-                         Standard_Real& u2,
-                         const Standard_Real anu1,
-                         const Standard_Real anu2);
-
-static
-  void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
-                             const Standard_Real ref_u1,
-                             const Standard_Real ref_u2,
-                             Standard_Real& new_u1,
-                             Standard_Real& new_u2);
-
-//
-static
-  void RefineParameters(const Handle(IntPatch_ALine)& aALine,
-                     const Standard_Real aTb,
-                     const Standard_Real aTe,
-                     const Standard_Real aTx,
-                     const Standard_Integer iDir,
-                     const IntSurf_Quadric& aQuadric,
-                     const Standard_Real aTol3D,
-                     Standard_Real& aUx,
-                     Standard_Real& aVx);
-static
-  Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
-                                    const Standard_Real aTx,
-                                    const Standard_Integer iDir,
-                                    const Standard_Real aTol3D,
-                                    Standard_Real& aT1);
-static
-  Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
-                         const Standard_Real aVx,
-                         const Standard_Real aTol3D);
-//
 
-//--  Je ne sais pas faire mieux et ca m'ennerve.  lbr. 
 //=======================================================================
-//function : IntPatch_ALineToWLine
+//function : AddPointIntoLine
 //purpose  : 
 //=======================================================================
-  IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
-                                              const IntSurf_Quadric& Quad2) 
-: 
-  quad1(Quad1),
-  quad2(Quad2),
-  deflectionmax(0.01),
-  nbpointsmax(200),
-  type(0),
-  myTolParam(1.e-12),
-  myTolOpenDomain(1.e-9),
-  myTolTransition(1.e-8)
-{ 
-  myTol3D=Precision::Confusion();
+static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
+                                    const Standard_Real* const theArrPeriods,
+                                    IntSurf_PntOn2S &thePoint,
+                                    IntPatch_Point* theVertex = 0)
+{
+   if(theLine->NbPoints() > 0)
+   {
+     if(thePoint.IsSame(theLine->Value(theLine->NbPoints()), Precision::Confusion()))
+       return;
+
+     IntPatch_SpecialPoints::AdjustPointAndVertex(theLine->Value(theLine->NbPoints()),
+                                                    theArrPeriods, thePoint, theVertex);
+   }
+
+   theLine->Add(thePoint);
+}
+
+//=======================================================================
+//function : AddVertexPoint
+//purpose  : Extracts IntSurf_PntOn2S from theVertex and adds result in theLine.
+//=======================================================================
+static void AddVertexPoint(Handle(IntSurf_LineOn2S)& theLine,
+                                       IntPatch_Point &theVertex,
+                                       const Standard_Real* const theArrPeriods)
+{
+  IntSurf_PntOn2S anApexPoint = theVertex.PntOn2S();
+  AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
 }
+
+//=======================================================================
+//function : IsPoleOrSeam
+//purpose  : Processes theVertex depending on its type
+//            (pole/apex/point on boundary etc.) and adds it in theLine.
+//           theSingularSurfaceID contains the ID of surface with
+//            special point (0 - none, 1 - theS1, 2 - theS2)
+//=======================================================================
+static IntPatch_SpecPntType IsPoleOrSeam(const Handle(Adaptor3d_HSurface)& theS1,
+                                         const Handle(Adaptor3d_HSurface)& theS2,
+                                         Handle(IntSurf_LineOn2S)& theLine,
+                                         IntPatch_Point &theVertex,
+                                         const Standard_Real* const theArrPeriods,
+                                         const Standard_Real theTol3d,
+                                         Standard_Integer& theSingularSurfaceID)
+{
+  const Standard_Integer aNbPnts = theLine->NbPoints();
+  if(aNbPnts == 0)
+    return IntPatch_SPntNone;
+
+  theSingularSurfaceID = 0;
+
+  for(Standard_Integer i = 0; i < 2; i++)
+  {
+    const Standard_Boolean isReversed = (i > 0);
+    const GeomAbs_SurfaceType aType = isReversed? theS2->GetType() : theS1->GetType();
+
+    IntPatch_SpecPntType anAddedPType = IntPatch_SPntNone;
+    IntSurf_PntOn2S anApexPoint;
+
+    switch(aType)
+    {
+    case GeomAbs_Sphere:
+    case GeomAbs_Cone:
+      {
+        if(IntPatch_SpecialPoints::
+              AddSingularPole((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
+                               theLine->Value(aNbPnts), theTol3d, theVertex,
+                               anApexPoint, isReversed, Standard_True))
+        {
+          anAddedPType = IntPatch_SPntPole;
+          break;
+        }
+      }
+    case GeomAbs_Torus:
+      if(aType == GeomAbs_Torus)
+      {
+        if(IntPatch_SpecialPoints::
+            AddCrossUVIsoPoint((isReversed? theS2 : theS1), (isReversed? theS1 : theS2),
+                                          theLine->Value(aNbPnts), theTol3d,
+                                          anApexPoint, isReversed))
+        {
+          anAddedPType = IntPatch_SPntSeamUV;
+          break;
+        }
+      }
+    case GeomAbs_Cylinder:
+      theSingularSurfaceID = i + 1;
+      AddVertexPoint(theLine, theVertex, theArrPeriods);
+      return IntPatch_SPntSeamU;
+
+    default:
+      break;
+    }
+
+    if(anAddedPType != IntPatch_SPntNone)
+    {
+      theSingularSurfaceID = i + 1;
+      AddPointIntoLine(theLine, theArrPeriods, anApexPoint, &theVertex);
+      return anAddedPType;
+    }
+  }
+
+  return IntPatch_SPntNone;
+}
+
 //=======================================================================
 //function : IntPatch_ALineToWLine
 //purpose  : 
 //=======================================================================
-  IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
-                                              const IntSurf_Quadric& Quad2,
-                                              const Standard_Real    Deflection,
-                                              const Standard_Real    ,
-                                              const Standard_Integer NbMaxPoints) 
-:
-  quad1(Quad1),
-  quad2(Quad2),
-  deflectionmax(Deflection),
-  nbpointsmax(NbMaxPoints),
-  myTolParam(1.e-12),
+IntPatch_ALineToWLine::IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& theS1,
+                                             const Handle(Adaptor3d_HSurface)& theS2,
+                                             const Standard_Integer theNbPoints) :
+  myS1(theS1),
+  myS2(theS2),
+  myNbPointsInWline(theNbPoints),
   myTolOpenDomain(1.e-9),
-  myTolTransition(1.e-8)
+  myTolTransition(1.e-8),
+  myTol3D(Precision::Confusion())
 { 
-  myTol3D=Precision::Confusion();
-  type = 0;
+  const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
+  const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
+
+  switch(aTyps1)
+  {
+  case GeomAbs_Plane:
+    myQuad1.SetValue(theS1->Plane());
+    break;
+
+  case GeomAbs_Cylinder:
+    myQuad1.SetValue(theS1->Cylinder());
+    break;
+
+  case GeomAbs_Sphere:
+    myQuad1.SetValue(theS1->Sphere());
+    break;
+
+  case GeomAbs_Cone:
+    myQuad1.SetValue(theS1->Cone());
+    break;
+
+  case GeomAbs_Torus:
+    myQuad1.SetValue(theS1->Torus());
+    break;
+
+  default:
+    break;
+  }
+
+  switch(aTyps2)
+  {
+  case GeomAbs_Plane:
+    myQuad2.SetValue(theS2->Plane());
+    break;
+  case GeomAbs_Cylinder:
+    myQuad2.SetValue(theS2->Cylinder());
+    break;
+
+  case GeomAbs_Sphere:
+    myQuad2.SetValue(theS2->Sphere());
+    break;
+
+  case GeomAbs_Cone:
+    myQuad2.SetValue(theS2->Cone());
+    break;
+
+  case GeomAbs_Torus:
+    myQuad2.SetValue(theS2->Torus());
+    break;
+
+  default:
+    break;
+  }
 }
+
 //=======================================================================
 //function : SetTol3D
 //purpose  : 
@@ -157,22 +235,6 @@ static
   return myTolTransition;
 }
 //=======================================================================
-//function : SetTolParam
-//purpose  : 
-//=======================================================================
-  void IntPatch_ALineToWLine::SetTolParam(const Standard_Real aTolParam)
-{
-  myTolParam = aTolParam;
-}
-//=======================================================================
-//function : TolParam
-//purpose  : 
-//=======================================================================
-  Standard_Real IntPatch_ALineToWLine::TolParam()const
-{
-  return myTolParam;
-}
-//=======================================================================
 //function : SetTolOpenDomain
 //purpose  : 
 //=======================================================================
@@ -189,1051 +251,445 @@ static
   return myTolOpenDomain;
 }
 //=======================================================================
-//function : SetConstantParameter
-//purpose  : 
-//=======================================================================
-  void IntPatch_ALineToWLine::SetConstantParameter() const 
-{ 
-}
-//=======================================================================
-//function : SetUniformAbscissa
-//purpose  : 
-//=======================================================================
-  void IntPatch_ALineToWLine::SetUniformAbscissa() const 
-{ 
-}
-//=======================================================================
-//function : SetUniformDeflection
-//purpose  : 
-//=======================================================================
-  void IntPatch_ALineToWLine::SetUniformDeflection() const 
-{ 
-}
-//=======================================================================
 //function : MakeWLine
 //purpose  : 
 //=======================================================================
-  Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline) const 
+void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theAline,
+                                      IntPatch_SequenceOfLine& theLines) const
 { 
   Standard_Boolean included;
-  Standard_Real f = aline->FirstParameter(included); 
+  Standard_Real f = theAline->FirstParameter(included); 
   if(!included) {
     f+=myTolOpenDomain;
   }
-  Standard_Real l = aline->LastParameter(included); 
+  Standard_Real l = theAline->LastParameter(included); 
   if(!included) { 
     l-=myTolOpenDomain;
   }
-  return(MakeWLine(aline,f,l));
+
+  MakeWLine(theAline, f, l, theLines);
 }
 
 //=======================================================================
 //function : MakeWLine
 //purpose  : 
 //=======================================================================
-  Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline,
-                                                   const Standard_Real _firstparam,
-                                                   const Standard_Real _lastparam) const 
+void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
+                                      const Standard_Real theFPar,
+                                      const Standard_Real theLPar,
+                                      IntPatch_SequenceOfLine& theLines) const 
 {
-  //
-  Standard_Real dl, dumin, dumax, U, pv, pu1, pv1, pu2, pv2; 
-  Standard_Real firstparam, lastparam;
-  Standard_Integer v, nbvtx;
-  Standard_Boolean TriOk;
-  //
-  firstparam = _firstparam;
-  lastparam  = _lastparam;
-  // Pas Bon ... 
-  // nbpointsmax It is the field. ( =200. by default)
-  dl = (lastparam - firstparam)/(Standard_Real)(nbpointsmax-1);
-  dumin = 0.1*dl;
-  dumax = 10 * dl;
-  //
-  nbvtx = aline->NbVertex();
-  //
-  TColStd_Array1OfReal paramvertex(1,Max(nbvtx,1)), newparamvertex(1,Max(nbvtx,1));
-  //
-  for(v = 1; v<=nbvtx; v++) { 
-    const IntPatch_Point& aVtx = aline->Vertex(v);
-    pv=aVtx.ParameterOnLine();
-    paramvertex(v)=pv;
-    newparamvertex(v)=-1.;
-  }
-  //
-  //-- Tri et Confusion des vertex proches 
-  do { 
-    TriOk = Standard_True;
-    for(v=2; v<=nbvtx;v++) { 
-      if(paramvertex(v) < paramvertex(v-1)) { 
-       pv=paramvertex(v);
-       paramvertex(v-1)=paramvertex(v);
-       paramvertex(v)=pv;
-       TriOk = Standard_False;
-      }
-    }
-  }
-  while(!TriOk);
-  //
-  for(v=2; v<=nbvtx;v++) { 
-    pv=paramvertex(v);
-    pv1=paramvertex(v-1);
-    if(pv-pv1 < myTolParam) { 
-      paramvertex(v)=pv1;
-    }
+  const Standard_Integer aNbVert = theALine->NbVertex();
+  const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
+  IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
+  
+  NCollection_Array1<Standard_Real> aVertexParams(1, aNbVert);
+  NCollection_Array1<IntPatch_Point> aSeqVertex(1, aNbVert);
+
+  //It is possible to have several vertices with equal parameters.
+  NCollection_Array1<Standard_Boolean> hasVertexBeenChecked(1, aNbVert);
+
+  Handle(IntSurf_LineOn2S) aLinOn2S;
+  Standard_Real aParameter = theFPar;
+  
+  for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
+  {
+    const Standard_Real aPar = theALine->Vertex(i).ParameterOnLine();
+    aVertexParams(i) = aPar;
+    hasVertexBeenChecked(i) = Standard_False;
   }
-  //
-  Standard_Integer t, nbpwline;
-  Standard_Real u1,v1,u2,v2, anu1, anv1, anu2, anv2;
-  Standard_Real aL, dl_sur_2;
-  gp_Pnt Pnt3d, aPnt3d1;
-  IntSurf_PntOn2S POn2S;
-  Handle(IntSurf_LineOn2S) LinOn2S;
-  //
-  LinOn2S = new IntSurf_LineOn2S;
-
-  //// Modified by jgv, 17.09.09 for OCC21255 ////
-  Standard_Real refpar = RealLast(), ref_u1 = 0., ref_u2 = 0.;
-  if (nbvtx)
+
+  Standard_Integer aSingularSurfaceID = 0;
+  Standard_Real anArrPeriods[] = { 0.0,  //U1
+                                   0.0,  //V1
+                                   0.0,  //U2
+                                   0.0}; //V2
+
+  IntSurf::SetPeriod(myS1, myS2, anArrPeriods);
+
+  IntSurf_PntOn2S aPrevLPoint;
+
+  while(aParameter < theLPar)
+  {
+    Standard_Real aStep = (theLPar - aParameter) / (Standard_Real)(myNbPointsInWline - 1);
+    if(aStep < Epsilon(theLPar))
+      break;
+
+    Standard_Integer aNewVertID = 0;
+    aLinOn2S = new IntSurf_LineOn2S;
+    
+    const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep;
+
+    Standard_Boolean isLast = Standard_False;
+    Standard_Real aPrevParam = aParameter;
+    for(; !isLast; aParameter += aStep)
     {
-      const IntPatch_Point& FirstVertex = aline->Vertex(1);
-      refpar = FirstVertex.ParameterOnLine();
-      FirstVertex.Parameters(ref_u1, v1, ref_u2, v2);
-    }
-  ////////////////////////////////////////////////
-
-  //-----------------------------------------------------
-  //-- Estimation Grossiere de la longueur de la courbe
-  //-- 
-  aL=0.;
-  dl_sur_2=0.5*dl; 
-  Pnt3d = aline->Value(firstparam); 
-  for(t=0, U=firstparam+dumin; U<lastparam; t++,U+=dl_sur_2) {
-    aPnt3d1 = aline->Value(U);
-    aL+=Pnt3d.Distance(aPnt3d1);
-    Pnt3d=aPnt3d1;
-  }
-  //------------------------------------------------------
-  aL/=t;
-  aL*=2;
-  //------------------------------------------------------
-  //-- Calcul du premier point 
-  //--
-  //------------------------------------------------------
-  //-- On reajuste firstparam et lastparam au cas ou ces 
-  //-- valeurs sont tres proches des parametres de vertex
-  if(nbvtx) { 
-    Standard_Real pvtxmin, pvtxmax;
-    //
-    pvtxmin = aline->Vertex(1).ParameterOnLine();
-    pvtxmax = pvtxmin;
-    //
-    for(v=2; v<=nbvtx; v++) { 
-      pv=aline->Vertex(v).ParameterOnLine();
-      if(pvtxmin>pv){
-       pvtxmin = pv;
-      }
-      if(pvtxmax<pv){
-       pvtxmax =pv;
-      }
-    }
-    if(Abs(pvtxmin-firstparam)<myTolOpenDomain) {
-      firstparam=pvtxmin;
-    }
-    if(Abs(pvtxmax-lastparam)<myTolOpenDomain) {
-      lastparam=pvtxmax;
-    }
-  }
-  //
-  // First Point
-  Pnt3d = aline->Value(firstparam);
-  quad1.Parameters(Pnt3d,u1,v1);
-  //
-  RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad1, 10.*myTol3D, u1,v1);
-  //
-  //
-  quad2.Parameters(Pnt3d,u2,v2);
-  //
-  RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad2, 10.*myTol3D, u2,v2);
-  //
-
-  POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
-  anu1 = u1;
-  anu2 = u2;
-  LinOn2S->Add(POn2S);
-  nbpwline = 1;
-  U = firstparam;
-  //-------------------------------------------------------
-  //-- On detecte le cas : Point de debut == vertex
-  //-- On affecte un parametre bidon qui sera recadre
-  //-- dans l insertion des vertex dans la ligne
-  //--
-  for(v=1;v<=nbvtx;v++) {
-    if(newparamvertex(v)<0.) { 
-      pv=paramvertex(v);
-      if((pv>=U-2.0*myTolOpenDomain) && (pv<=U+2.0*myTolOpenDomain)) { 
-       if(pv-U > myTolParam) {
-         newparamvertex(v) = 1.000001;
-       }
-       else if(U-pv>myTolParam) {
-         newparamvertex(v) = 0.999999;
-       }
-      }
-    }
-  }
-  //
-  Standard_Real DeltaU;
-  //
-  // the loop
-  DeltaU=0.;
-  //// Modified by jgv, 17.09.09 for OCC21255 ////
-  Standard_Boolean Corrected = Standard_False;
-  ////////////////////////////////////////////////
-  while(U<lastparam) { 
-    Standard_Integer NbCalculD1;
-    Standard_Real UPourCalculD1, pvavant, pvapres;
-    gp_Vec VPourCalculD1;
-    gp_Pnt PPourCalculD1;
-    //
-    DeltaU=0.;
-    NbCalculD1=0;
-    UPourCalculD1=U;
-    do { 
-      if(aline->D1(UPourCalculD1,PPourCalculD1,VPourCalculD1)) { 
-       Standard_Real NormV = VPourCalculD1.Magnitude();
-       if(NormV > 1.0e-16) {
-         DeltaU = aL/NormV;
-       }
-      }
-      if(DeltaU < dumin) 
-       DeltaU = dumin;
-      else if (DeltaU > dumax) 
-       DeltaU = dumax;
-      UPourCalculD1+=dumin;
-    }
-    while((++NbCalculD1<10)&&(DeltaU==0.));
-    //
-    //OCC541(apo)->
-    // static  //xft 
-    Standard_Real CurvDef = deflectionmax, AngDef = CurvDef; 
-    if(U+DeltaU < lastparam) {
-      DefineDU(aline,U,DeltaU,CurvDef,AngDef); 
-    }
-    //<-OCC451(apo)
-    //
-    if(DeltaU==0.){ 
-      DeltaU = (dumin+dumax)*0.5;
-    }
-    //--------------------------------------------------------
-    //-- On cherche a placer un minimum de ??? Points entre 
-    //-- 2 vertex 
-    //--------------------------------------------------------
-    pvavant = firstparam;
-    pvapres = lastparam;
-    for(v=1;v<=nbvtx;v++) {
-      pv=paramvertex(v);
-      if(pv-U > myTolParam) { 
-       if(pvapres>pv) { 
-         pvapres = pv;
-       }
-      }
-      else { 
-       if(U-pv > myTolParam) { 
-         if(pvavant<pv) { 
-           pvavant = pv;
-         }
-       }
+      IntSurf_PntOn2S aPOn2S;
+
+      if(theLPar <= aParameter)
+      {
+        isLast = Standard_True;
+        if(aPrePointExist != IntPatch_SPntNone)
+        {
+          break;
+        }
+        else
+        {
+          aParameter = theLPar;
+        }
       }
-    }
-    pvapres-=pvavant;
-    if(pvapres < (10.*DeltaU)) { 
-      if(pvapres > (10.*dumin)) { 
-       DeltaU = pvapres*0.1;
+
+      Standard_Real aTgMagn = 0.0;
+      {
+        gp_Pnt aPnt3d;
+        gp_Vec aTg;
+        theALine->D1(aParameter, aPnt3d, aTg);
+        aTgMagn = aTg.Magnitude();
+        Standard_Real u1 = 0.0, v1 = 0.0, u2 = 0.0, v2 = 0.0;
+        myQuad1.Parameters(aPnt3d, u1, v1);
+        myQuad2.Parameters(aPnt3d, u2, v2);
+        aPOn2S.SetValue(aPnt3d, u1, v1, u2, v2);
       }
-      else { 
-       DeltaU = dumin;
+
+      if(aPrePointExist != IntPatch_SPntNone)
+      {
+        const Standard_Real aURes = Max(myS1->UResolution(myTol3D),
+                                                myS2->UResolution(myTol3D)),
+                            aVRes = Max(myS1->VResolution(myTol3D),
+                                                myS2->VResolution(myTol3D));
+
+        const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 : 
+                    (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
+                    (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
+
+        IntSurf_PntOn2S aRPT = aPOn2S;
+
+        if (aPrePointExist == IntPatch_SPntPole)
+        {
+          Standard_Real aPrt = 0.5*(aPrevParam + theLPar);
+          for (Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
+          {
+            const Standard_Real aParam = aVertexParams(i);
+
+            if (aParam <= aPrevParam)
+              continue;
+
+            aPrt = 0.5*(aParam + aPrevParam);
+            break;
+          }
+
+          const gp_Pnt aPnt3d(theALine->Value(aPrt));
+          Standard_Real u1, v1, u2, v2;
+          myQuad1.Parameters(aPnt3d, u1, v1);
+          myQuad2.Parameters(aPnt3d, u2, v2);
+          aRPT.SetValue(aPnt3d, u1, v1, u2, v2);
+
+          if (aPOn2S.IsSame(aPrevLPoint, Max(Precision::Approximation(), aTol)))
+          {
+            //Set V-parameter as precise value found on the previous step.
+            if (aSingularSurfaceID == 1)
+            {
+              aPOn2S.ParametersOnS1(u2, v2);
+              aPOn2S.SetValue(Standard_True, u1, v2);
+            }
+            else //if (aSingularSurfaceID == 2)
+            {
+              aPOn2S.ParametersOnS2(u1, v1);
+              aPOn2S.SetValue(Standard_False, u2, v1);
+            }
+          }
+        }
+
+        if(IntPatch_SpecialPoints::
+                      ContinueAfterSpecialPoint(myS1, myS2, aRPT,
+                                                aPrePointExist, aTol2d,
+                                                aPrevLPoint, Standard_False))
+        {
+          AddPointIntoLine(aLinOn2S, anArrPeriods, aPrevLPoint);
+        }
+        else if(aParameter == theLPar)
+        {// Strictly equal!!!
+          break;
+        }
       }
-    }
-    //xf
-    if (nbpwline==1 && nbvtx) {
-      Standard_Real aUnext;
-      //
-      aUnext=U+DeltaU;
-      pv=paramvertex(1);
-      if (aUnext>pv){
-       DeltaU=0.5*(pv-firstparam);
+
+      aPrePointExist = IntPatch_SPntNone;
+
+      Standard_Integer aVertexNumber = -1;
+      for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
+      {
+        if(hasVertexBeenChecked(i))
+          continue;
+
+        const Standard_Real aParam = aVertexParams(i);
+        if( ((aPrevParam < aParam) && (aParam <= aParameter)) ||
+            ((aPrevParam == aParameter) && (aParam == aParameter)))
+        {
+          aVertexNumber = i;
+          break;
+        }
       }
-    }
-    //xt
-    //--------------------------------------------------------
-    //-- Calcul des nouveaux parametres sur les vertex
-    //--
-    for(v=1;v<=nbvtx;v++) {
-      if(newparamvertex(v)<0.) { 
-       pv=paramvertex(v);
-       if(pv>=U  && pv<(U+DeltaU) && (U+DeltaU<lastparam) ) {
-         newparamvertex(v) = (Standard_Real)nbpwline + (pv-U)/DeltaU;
-       }
+
+      aPrevParam = aParameter;
+      
+      if(aVertexNumber < 0)
+      {
+        StepComputing(theALine, aPOn2S, theLPar, aParameter, aTgMagn,
+                              aStepMin, aStepMax, myTol3D, aStep);
+        AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
+        aPrevLPoint = aPOn2S;
+        continue;
       }
-    }
 
-    //// Modified by jgv, 17.09.09 for OCC21255 ////
-    if (!Corrected && U >= refpar)
+      IntPatch_Point aVtx = theALine->Vertex(aVertexNumber);
+      const Standard_Real aNewVertexParam = aLinOn2S->NbPoints() + 1;
+
+      //ATTENTION!!!
+      // IsPoleOrSeam inserts new point in aLinOn2S if aVtx respects
+      //to some special point. Otherwise, aLinOn2S is not changed.
+
+      aPrePointExist = IsPoleOrSeam(myS1, myS2, aLinOn2S, aVtx,
+                                anArrPeriods, aTol, aSingularSurfaceID);
+
+      const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
+      if(aPrePointExist != IntPatch_SPntNone)
       {
-       CorrectFirstPartOfLine(LinOn2S, ref_u1, ref_u2, anu1, anu2);
-       Corrected = Standard_True;
+        aPrevParam = aParameter = aCurVertParam;
       }
-    ////////////////////////////////////////////////
-    U+=DeltaU;
-    if(U < lastparam) { 
-      nbpwline++;
-      Pnt3d = aline->Value(U);
-      quad1.Parameters(Pnt3d,u1,v1);
-      quad2.Parameters(Pnt3d,u2,v2);
-      RecadreMemePeriode(u1,u2,anu1,anu2);
-      anu1 = u1;
-      anu2 = u2;
-      POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
-      LinOn2S->Add(POn2S);
-    }
-  }//while(U<lastparam) 
-  
-  U-=DeltaU;
-  for(v=1;v<=nbvtx;v++) {
-    if(newparamvertex(v)<0.) { 
-      pv=paramvertex(v);
-      if(pv <= lastparam+myTolOpenDomain) {
-       if(lastparam-U) { 
-         newparamvertex(v) = (Standard_Real)nbpwline+(pv-U)/(lastparam-U);
-       }
-       else { 
-         newparamvertex(v) = nbpwline+1;
-       }
+      else
+      {
+        if(aVtx.Tolerance() > aTol)
+        {
+          aVtx.SetValue(aPOn2S);
+          AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
+        }
+        else
+        {
+          AddVertexPoint(aLinOn2S, aVtx, anArrPeriods);
+        }
       }
-    }
-  }
-  //
-  Pnt3d = aline->Value(lastparam);
-  quad1.Parameters(Pnt3d,u1,v1);
-  //
-  RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad1, 10.*myTol3D, u1,v1);
-  //
-  quad2.Parameters(Pnt3d,u2,v2);
-  //
-  RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad2, 10.*myTol3D, u2,v2);
-  //
-  RecadreMemePeriode(u1,u2,anu1,anu2);
-  POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
-  LinOn2S->Add(POn2S);
-  nbpwline++;
-
-  //// Modified by jgv, 17.09.09 for OCC21255 ////
-  if (!Corrected && 
-      (lastparam >= refpar || refpar-lastparam < Precision::Confusion()))
-    CorrectFirstPartOfLine(LinOn2S, ref_u1, ref_u2, anu1, anu2);
-  ////////////////////////////////////////////////
-
-  //
-  //-----------------------------------------------------------------
-  //--  Calcul de la transition de la ligne sur les surfaces      ---
-  //-----------------------------------------------------------------
-  IntSurf_TypeTrans trans1,trans2;
-  Standard_Integer indice1;
-  Standard_Real dotcross;
-  gp_Pnt aPP0, aPP1;
-  //
-  trans1=IntSurf_Undecided;
-  trans2=IntSurf_Undecided;
-  //
-  indice1 = nbpwline/3;
-  if(indice1<=2) {
-    indice1 = 2;
-  }
-  //
-  aPP1=LinOn2S->Value(indice1).Value();
-  aPP0=LinOn2S->Value(indice1-1).Value();
-  //
-  gp_Vec tgvalid(aPP0, aPP1);
-  gp_Vec aNQ1=quad1.Normale(aPP0);
-  gp_Vec aNQ2=quad2.Normale(aPP0);
-  //
-  dotcross = tgvalid.DotCross(aNQ2, aNQ1);
-  if (dotcross > myTolTransition) {
-    trans1 = IntSurf_Out;
-    trans2 = IntSurf_In;
-  }
-  else if(dotcross < -myTolTransition) { 
-    trans1 = IntSurf_In;
-    trans2 = IntSurf_Out;
-  } 
-  //-----------------------------------------------------------------
-  //--              C r e a t i o n  d  e   la   W L i n e        ---
-  //-----------------------------------------------------------------
-  Handle(IntPatch_WLine) wline;
-  //
-  if(aline->TransitionOnS1() == IntSurf_Touch)  { 
-    Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
-                                             aline->IsTangent(),
-                                             aline->SituationS1(),
-                                             aline->SituationS2());
-    wline = wlinetemp;
-  }
-  if(aline->TransitionOnS1() == IntSurf_Undecided)  { 
-    Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
-                                             aline->IsTangent());
-    wline = wlinetemp;
-  }
-  else { 
-    Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
-                                             aline->IsTangent(),
-                                             trans1, // aline->TransitionOnS1(),
-                                             trans2);  //aline->TransitionOnS2());
-    wline = wlinetemp; 
-  }
 
-  //-----------------------------------------------------------------
-  //--         I n s e r t i o n   d  e s  v e r t e x            ---
-  //-----------------------------------------------------------------
-  TColStd_Array1OfInteger Redir(1,Max(nbvtx,1));
-  //
-  for(v=1;v<=nbvtx;v++) { 
-    Redir(v) = v;
-  }
-  //
-  TriOk=Standard_True;
-  Standard_Integer tamp;
-  do { 
-    TriOk = Standard_True;
-    for(v=2; v<=nbvtx;v++) { 
-      if(newparamvertex(Redir(v))<newparamvertex(Redir(v-1))) { 
-       tamp = Redir(v-1);
-       Redir(v-1) = Redir(v);
-       Redir(v) = tamp;
-       TriOk = Standard_False;
+      aPrevLPoint = aPOn2S = aLinOn2S->Value(aLinOn2S->NbPoints());
+
+      {
+        Standard_Boolean isFound = Standard_False;
+        const Standard_Real aSqTol = aTol*aTol;
+        const gp_Pnt aP1(theALine->Value(aCurVertParam));
+        const IntSurf_PntOn2S& aVertP2S = aVtx.PntOn2S();
+        const Standard_Real aVertToler  = aVtx.Tolerance();
+
+        for(Standard_Integer i = aVertexParams.Lower(); i <= aVertexParams.Upper(); i++)
+        {
+          if(hasVertexBeenChecked(i))
+            continue;
+
+          const gp_Pnt aP2(theALine->Value(aVertexParams(i)));
+          
+          if(aP1.SquareDistance(aP2) < aSqTol)
+          {
+            IntPatch_Point aVtx = theALine->Vertex(i);
+            aVtx.SetValue(aVertP2S);
+            aVtx.SetTolerance(aVertToler);
+            aVtx.SetParameter(aNewVertexParam);
+            aSeqVertex(++aNewVertID) = aVtx;
+            hasVertexBeenChecked(i) = Standard_True;
+            isFound = Standard_True;
+          }
+          else if(isFound)
+          {
+            break;
+          }
+        }
       }
+
+      if(aPrePointExist != IntPatch_SPntNone)
+        break;
+    }//for(; !isLast; aParameter += aStep)
+
+    if(aLinOn2S->NbPoints() < 2)
+    {
+      aParameter += aStep;
+      continue;
     }
-  }
-  while(!TriOk);
-  //-----------------------------------------------------------------
-  //-- On detecte le cas ou un Vtx de param 1 ou nbpwline OnArc est double
-  //-- Dans ce cas on supprime le vertex qui reference un arc deja reference 
-  //-- par un autre vertex 
-  //nbvtx = aline->NbVertex();
-  Standard_Boolean APointHasBeenRemoved;
-  //
-  do { 
-    Standard_Boolean RemoveVtxo, RemoveVtx;
-    Standard_Integer vo, voo;
-    Standard_Real ponl, ponlo, aDist13, aDist23;
-    //
-    APointHasBeenRemoved = Standard_False;
-    RemoveVtxo = Standard_False;
-    RemoveVtx  = Standard_False;
-    //
-    for(v=1; v<=nbvtx   && !APointHasBeenRemoved; v++) { 
-      //
-      if(newparamvertex(v)>=0.) { 
-       const IntPatch_Point& Vtx = aline->Vertex(v);
-       ponl = Vtx.ParameterOnLine();
-       const gp_Pnt& aP=Vtx.Value();
-       //
-       for(vo=1; vo<=nbvtx && !APointHasBeenRemoved; vo++) { 
-         if(v!=vo) { 
-           if(newparamvertex(vo)>=0.) { 
-             const IntPatch_Point& Vtxo = aline->Vertex(vo);
-             ponlo = Vtxo.ParameterOnLine();
-             const gp_Pnt& aPo=Vtxo.Value();
-             //
-             if(ponl-ponlo<myTolParam && ponlo-ponl<myTolParam) { 
-               //
-               for(voo=1; voo<=nbvtx && !APointHasBeenRemoved; voo++) { 
-                 if(voo!=v && voo!=vo) {
-                   if(newparamvertex(voo)>=0.) { 
-                     const IntPatch_Point& Vtxoo = aline->Vertex(voo);
-                     const gp_Pnt& aPoo=Vtxoo.Value();
-                     //
-                     aDist13=aP.Distance(aPoo);
-                     //
-                     if(aDist13<=myTol3D) { 
-                       //-- 2 vertex de meme param  + un confondu geometriquement
-                       if((Vtx.IsOnDomS1() == Vtxoo.IsOnDomS1()) &&
-                          (Vtx.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) { 
-                         
-                         if(Vtx.IsOnDomS1()) { 
-                           if(Vtx.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) { 
-                             if(SameCurve(Vtxoo.ArcOnS1(),Vtx.ArcOnS1())) { //-- param on s1 ?
-                               RemoveVtx = Standard_True;
-                             }
-                           }
-                         }
-                         if(Vtx.IsOnDomS2()) { 
-                           if(Vtx.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) { 
-                             if(SameCurve(Vtxoo.ArcOnS2(),Vtx.ArcOnS2())) { 
-                               RemoveVtx = Standard_True;
-                             }
-                           }
-                           else { 
-                             RemoveVtx = Standard_False;
-                           }
-                         }
-                       }
-                       //
-                       if(RemoveVtx==Standard_False) { 
-                         //
-                         aDist23=aPo.Distance(aPoo);
-                         //
-                         if(aDist23<=myTol3D) { 
-                           //-- 2 vertex de meme param  + un confondu geometriquement
-                           if((Vtxo.IsOnDomS1() == Vtxoo.IsOnDomS1())&&
-                              (Vtxo.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) { 
-                             if(Vtxo.IsOnDomS1()) { 
-                               if(Vtxo.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) { 
-                                 if(SameCurve(Vtxoo.ArcOnS1(),Vtxo.ArcOnS1())) { //-- param on s1 ?
-                                   RemoveVtxo = Standard_True;
-                                 }
-                               }
-                             }
-                             if(Vtxo.IsOnDomS2()) { 
-                               if(Vtxo.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) { 
-                                 if(SameCurve(Vtxoo.ArcOnS2(),Vtxo.ArcOnS2())) { 
-                                   RemoveVtxo = Standard_True;
-                                 }
-                               }
-                               else { 
-                                 RemoveVtxo = Standard_False;
-                               }
-                             }
-                           }
-                         }
-                       } //-- 
-                       if(RemoveVtx) { 
-                         newparamvertex(v) = -1.;
-                         APointHasBeenRemoved = Standard_True;
-                       }
-                       else if(RemoveVtxo) { 
-                         newparamvertex(vo) = -1.;
-                         APointHasBeenRemoved = Standard_True;
-                       }
-                     } //-- Pnt = Pntoo 
-                   } //-- voo!=v && voo!=vo
-                 } //-- Fin boucle sur voo 
-               }
-             }
-           }  
-         }
-       }
-      }
-    }//for(v=1; v<=nbvtx   && !APointHasBeenRemoved; v++) 
-  }
-  while(APointHasBeenRemoved);
-  //
-  Standard_Integer ParamVtxPrecedent, refpointonwline, aIndV;
-  Standard_Real pvtx, approxparamonwline, aDst;
-  Standard_Boolean bIsApex1, bIsApex2;
-  //
-  ParamVtxPrecedent = 0;
-  //
-  for(v=1; v<=nbvtx; v++) { 
-    aIndV=Redir(v);
-    pv=paramvertex(v);// parameter from ALine
-    pvtx = newparamvertex(aIndV);
-    if(pvtx>=0. && (pvtx <= nbpwline+1)) {
-      approxparamonwline=newparamvertex(aIndV);
-      refpointonwline=1;
-      //
-      IntPatch_Point NewPoint = aline->Vertex(aIndV);
-      //
-      Pnt3d = NewPoint.Value();
-      quad1.Parameters(Pnt3d, u1, v1);
-      quad2.Parameters(Pnt3d, u2, v2);
-      //-------------------------------------------------------
-      //-- On recadre les parametres des vertex dans la bonne -
-      //-- periode en recadrant avec le point le plus proche  -
-      //-------------------------------------------------------
-      if(approxparamonwline > nbpwline) { 
-       refpointonwline = nbpwline-1;
-      }
-      else if(approxparamonwline < 1) { 
-       refpointonwline = 1;
-      }
-      else { 
-       refpointonwline = (Standard_Integer)approxparamonwline;
-      }
-      //
-      //
-      const IntSurf_PntOn2S& aP2Sx=LinOn2S->Value(refpointonwline);
-      aP2Sx.ParametersOnS1(anu1, anv1);
-      aP2Sx.ParametersOnS2(anu2, anv2);
+
+    //-----------------------------------------------------------------
+    //--  Computation of transitions of the line on two surfaces    ---
+    //-----------------------------------------------------------------
+    IntSurf_TypeTrans trans1,trans2;
+    {
+      Standard_Integer indice1;
+      Standard_Real dotcross;
+      gp_Pnt aPP0, aPP1;
       //
-      bIsApex1=IsApex(quad1, v1, myTol3D);
-      bIsApex2=IsApex(quad2, v2, myTol3D);
+      trans1=IntSurf_Undecided;
+      trans2=IntSurf_Undecided;
       //
-      //if (refpointonwline==1 || refpointonwline==nbpwline) {
-      if (bIsApex1 || bIsApex2) {
-       if (fabs(pv-firstparam)<myTolParam || fabs(pv-lastparam)<myTolParam) {
-         // aline starts(ends) on vertex 
-         const gp_Pnt& aP1x=aP2Sx.Value();
-         //
-         aDst=aP1x.Distance(Pnt3d);
-         if (aDst<10.*myTol3D) {
-           u1=anu1;
-           v1=anv1;
-           u2=anu2;
-           v2=anv2;
-         }
-       }
-       //
-       else {
-         // aline goes through vertex 
-         if (bIsApex1) {
-           u1=0.;
-         }
-         if (bIsApex2) {
-           u2=0.;
-         }
-       }
+      indice1 = aLinOn2S->NbPoints()/3;
+      if(indice1<=2) {
+        indice1 = 2;
       }
       //
+      aPP1=aLinOn2S->Value(indice1).Value();
+      aPP0=aLinOn2S->Value(indice1-1).Value();
       //
-      if(v==1) { 
-       ParamVtxPrecedent=refpointonwline;
-       RecadreMemePeriode(u1,u2,anu1,anu2);
-       NewPoint.SetParameter(refpointonwline);
-       //
-       NewPoint.SetParameters(u1,v1,u2,v2);
-       wline->AddVertex(NewPoint);
-      }
+      gp_Vec tgvalid(aPP0, aPP1);
+      gp_Vec aNQ1 = myQuad1.Normale(aPP0);
+      gp_Vec aNQ2 = myQuad2.Normale(aPP0);
       //
-      else { 
-       if(ParamVtxPrecedent==refpointonwline) { 
-         //-- 2 vertex renseignent le meme point de la LineOn2S
-         //-- On insere un nv point  =  vtx
-         //-- On decale tous les vtx apres de 1 
-         RecadreMemePeriode(u1,u2,anu1,anu2);
-         POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
-         LinOn2S->InsertBefore(refpointonwline+1, POn2S);
-         nbpwline++;
-         NewPoint.SetParameter(refpointonwline+1);
-         NewPoint.SetParameters(u1,v1,u2,v2);
-         wline->AddVertex(NewPoint);
-         ParamVtxPrecedent = refpointonwline+1;
-         //
-         Standard_Integer vv=v+1;
-         for(; vv<=nbvtx; vv++) { 
-           if(newparamvertex(Redir(vv))!=-1.) { 
-             newparamvertex(Redir(vv))=newparamvertex(Redir(vv))+1.;
-           }
-         }
-       }
-       //
-       else { 
-         RecadreMemePeriode(u1,u2, anu1, anu2);
-         NewPoint.SetParameter(refpointonwline);
-         //
-         NewPoint.SetParameters(u1, v1, u2, v2);
-         wline->AddVertex(NewPoint);
-         ParamVtxPrecedent = refpointonwline;
-       }
+      dotcross = tgvalid.DotCross(aNQ2, aNQ1);
+      if (dotcross > myTolTransition) {
+        trans1 = IntSurf_Out;
+        trans2 = IntSurf_In;
       }
+      else if(dotcross < -myTolTransition) { 
+        trans1 = IntSurf_In;
+        trans2 = IntSurf_Out;
+      } 
     }
-  }
-  //
-  pu1=0.;
-  pv1=0.;
-  pu2=0.;
-  pv2=0.;
-  //
-  switch(quad1.TypeQuadric()) { 
-  case GeomAbs_Cylinder:
-  case GeomAbs_Cone:
-  case GeomAbs_Sphere:
-    pu1=M_PI+M_PI;
-    break;
-  case GeomAbs_Torus:
-    pu1=pv1=M_PI+M_PI;
-    break;
-  default:
-    break;
-  }
-  switch(quad2.TypeQuadric()) { 
-  case GeomAbs_Cylinder:
-  case GeomAbs_Cone:
-  case GeomAbs_Sphere:
-    pu2=M_PI+M_PI;
-    break;
-  case GeomAbs_Torus:
-    pu2=pv2=M_PI+M_PI;
-    break;
-  default:
-    break;
-  }
-  wline->SetPeriod(pu1,pv1,pu2,pv2);
-  
-  wline->ComputeVertexParameters(myTol3D);
-  return(wline);
-}
-//=======================================================================
-//function : DefineDU
-//purpose  : 
-//=======================================================================
-gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline, 
-               const Standard_Real U, 
-               Standard_Real& DU,
-               const Standard_Real CurvDef, 
-               const Standard_Real AngDef)
-{
-  gp_Pnt P1 = aline->Value(U), P2, P3;
-  gp_Vec V13, V12, V23;
-  Standard_Real dU = DU/2.0, curvDef, angDef, m1, m2, m3;
-  for(;;) { //According to class TangentialDeflection from GCPnts
-    P2=aline->Value(U+dU);  P3=aline->Value(U+DU);
-    V13 = P3.XYZ().Subtracted(P1.XYZ());  m1 = V13.Magnitude();
-    V12 = P2.XYZ().Subtracted(P1.XYZ());  m2 = V12.Magnitude();
-    V23 = P3.XYZ().Subtracted(P2.XYZ());  m3 = V23.Magnitude();
-    if(m1 < CurvDef || m2 < CurvDef || m3 < CurvDef) break;
-    curvDef = Abs(V13.Angle(V12));
-    angDef = Abs(V13.Angle(V23));
-    if(curvDef < CurvDef && angDef < AngDef) break;
-    DU = dU;  dU /= 2.0;  
-  }
-  return P3;
-}
-//=======================================================================
-//function : SameCurve
-//purpose  : 
-//=======================================================================
-Standard_Boolean SameCurve(const Handle(Adaptor2d_HCurve2d)& C1,const Handle(Adaptor2d_HCurve2d)& C2) 
-{ 
-  Standard_Real C1f = C1->FirstParameter();
-  Standard_Real C2f = C2->FirstParameter();
-  if(C1f!=C2f) return(Standard_False);
-  Standard_Real C1l = C1->LastParameter();
-  Standard_Real C2l = C2->LastParameter();
-  if(C1l!=C2l) return(Standard_False);
-  Standard_Real u=0.3*C1f+0.7*C1l;
-  gp_Pnt2d P1 = C1->Value(u);
-  gp_Pnt2d P2 = C2->Value(u);
-  if(P1.X()!=P2.X()) return(Standard_False);
-  if(P1.Y()!=P2.Y()) return(Standard_False);
-  return(Standard_True);
-}
-//=======================================================================
-//function : RecadreMemePeriode
-//purpose  : 
-//=======================================================================
-void RecadreMemePeriode(Standard_Real& u1,
-                       Standard_Real& u2,
-                       const Standard_Real anu1,
-                       const Standard_Real anu2) 
-{ 
-  //
-  while(anu1-u1 > 5.0) {
-    u1+=M_PI+M_PI;
-  }
-  while(u1-anu1 > 5.0) { 
+
+    //-----------------------------------------------------------------
+    //--              W  L  i  n  e     c  r  e  a  t  i  o  n      ---
+    //-----------------------------------------------------------------
+    Handle(IntPatch_WLine) aWLine;
     //
-    /*
-    if (!bBothCylinders) {//cfe900/H6
-      // this check on Cylinder/Cylinder intersection is probably 
-      // because of pbs with ALine on it.
-      // For other Quadrics there was no pbs found during 
-      // grid tests.
-      // (it is necessary to see ...IntCyCy(...) for details).
-      //
-      // In any case the pb does not deal with apex problem. 
-      //
-      if (u1-M_PI-M_PI<0.) {
-       break;
-      }
+    if(theALine->TransitionOnS1() == IntSurf_Touch)  { 
+                                  aWLine = new IntPatch_WLine(aLinOn2S,
+                                  theALine->IsTangent(),
+                                  theALine->SituationS1(),
+                                  theALine->SituationS2());
     }
-    */
-    //
-    u1-=M_PI+M_PI;
-  }
-  while(anu2-u2 > 5.0) { 
-    u2+=M_PI+M_PI;
-  }
-  while(u2-anu2 > 5.0) {
-    //
-    /*
-    if (!bBothCylinders) {//cfe900/H6
-      if (u2-M_PI-M_PI<0.) {
-       break;
-      }
+    if(theALine->TransitionOnS1() == IntSurf_Undecided)  { 
+      aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent());
+    }
+    else { 
+      aWLine = new IntPatch_WLine(aLinOn2S, theALine->IsTangent(),
+                                  trans1, // aline->TransitionOnS1(),
+                                  trans2);  //aline->TransitionOnS2());
     }
-    */
-    //
-    u2-=M_PI+M_PI;
-  }
-}
 
-//=======================================================================
-//function : CorrectFirstPartOfLine
-//purpose  : 
-//=======================================================================
-void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
-                           const Standard_Real ref_u1,
-                           const Standard_Real ref_u2,
-                           Standard_Real& new_u1,
-                           Standard_Real& new_u2)
-{
-  Standard_Integer nbp = LinOn2S->NbPoints();
-  Standard_Real u1, v1, u2, v2, OffsetOnS1, OffsetOnS2;
-
-  IntSurf_PntOn2S aPoint = LinOn2S->Value(nbp);
-  aPoint.Parameters(u1, v1, u2, v2);
-
-  new_u1 = u1;
-  new_u2 = u2;
-  RecadreMemePeriode(new_u1, new_u2, ref_u1, ref_u2);
-  OffsetOnS1 = new_u1 - u1;
-  OffsetOnS2 = new_u2 - u2;
-  if (Abs(OffsetOnS1) > 1. || Abs(OffsetOnS2) > 1.) //recadre on n*2*PI is done
+    for(Standard_Integer i = aSeqVertex.Lower(); i <= aNewVertID; i++)
     {
-      Standard_Integer i;
-      for (i = 1; i <= nbp; i++)
-       {
-         aPoint = LinOn2S->Value(i);
-         aPoint.Parameters(u1, v1, u2, v2);
-         LinOn2S->SetUV( i, Standard_True,  u1 + OffsetOnS1, v1 );
-         LinOn2S->SetUV( i, Standard_False, u2 + OffsetOnS2, v2 );
-       }
+      const IntPatch_Point& aVtx = aSeqVertex(i);
+      aWLine->AddVertex(aVtx);
     }
+
+    aWLine->SetPeriod(anArrPeriods[0],anArrPeriods[1],anArrPeriods[2],anArrPeriods[3]);
+
+    aWLine->ComputeVertexParameters(myTol3D);
+
+    aWLine->EnablePurging(Standard_False);
+    theLines.Append(aWLine);
+  }//while(aParameter < theLPar)
 }
 
-//
 //=======================================================================
-//function : IsApex
-//purpose  : 
+//function : CheckDeflection
+//purpose  : Returns:
+//            -1 - step is too small
+//            0  - step is normal
+//            +1 - step is too big
 //=======================================================================
-Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
-                       const Standard_Real aVx,
-                       const Standard_Real aTol3D)
-                       
+Standard_Integer IntPatch_ALineToWLine::CheckDeflection(const gp_XYZ& theMidPt,
+                                                        const Standard_Real theMaxDeflection) const
 {
-  Standard_Boolean bFlag;
-  Standard_Real aHalfPi, aEpsilon;
-  GeomAbs_SurfaceType aType;
-  //
-  bFlag=Standard_False;
-  //
-  aType=aQuadric.TypeQuadric();
-  if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
-    return bFlag;
-  }
-  //
-  aEpsilon=Epsilon(10.);//1.77e-15
-  //
-  // apex on the Sphere
-  if(aType==GeomAbs_Sphere) {
-    aHalfPi=0.5*M_PI;
-    if (fabs(aVx-aHalfPi)<aEpsilon) {
-      bFlag=!bFlag;
-    }
-    else if (fabs(aVx+aHalfPi)<aEpsilon){
-      bFlag=!bFlag;
-    }
-  }
-  //
-  // apex on the Cone
-  else if(aType==GeomAbs_Cone) {
-    Standard_Real aDst;
-    gp_Pnt aPap, aPx;
-    gp_Cone aCone;
-    //
-    aCone=aQuadric.Cone();
-    aPap=aCone.Apex();
-    aPx=aQuadric.Value(0.,aVx);
-    //
-    aDst=aPx.Distance(aPap);
-    if(aDst<aTol3D) {
-      bFlag=!bFlag;
-    }
-  }
-  return bFlag;
-}   
+  Standard_Real aDist = Abs(myQuad1.Distance(theMidPt));
+  if(aDist > theMaxDeflection)
+    return 1;
+
+  aDist = Max(Abs(myQuad2.Distance(theMidPt)), aDist);
+  
+  if(aDist > theMaxDeflection)
+    return 1;
+
+  if((aDist + aDist) < theMaxDeflection)
+    return -1;
+
+  return 0;
+}
+
 //=======================================================================
-//function : RefineParameters
+//function : StepComputing
 //purpose  : 
 //=======================================================================
-void RefineParameters(const Handle(IntPatch_ALine)& aALine,
-                     const Standard_Real aTb,
-                     const Standard_Real aTe,
-                     const Standard_Real aTx,
-                     const Standard_Integer iDir,
-                     const IntSurf_Quadric& aQuadric,
-                     const Standard_Real aTol3D,
-                     Standard_Real& aUx,
-                     Standard_Real& aVx)
+Standard_Boolean IntPatch_ALineToWLine::
+                      StepComputing(const Handle(IntPatch_ALine)& theALine,
+                                    const IntSurf_PntOn2S& thePOn2S,
+                                    const Standard_Real theLastParOfAline,
+                                    const Standard_Real theCurParam,
+                                    const Standard_Real theTgMagnitude,
+                                    const Standard_Real theStepMin,
+                                    const Standard_Real theStepMax,
+                                    const Standard_Real theMaxDeflection,
+                                    Standard_Real& theStep) const
 {
-  GeomAbs_SurfaceType aType;
-  //
-  aType=aQuadric.TypeQuadric();
-  if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
-    return;
+  if(theTgMagnitude < Precision::Confusion())
+    return Standard_False;
+  
+  const Standard_Real anEps = myTol3D;
+
+  //Indeed, 1.0e+15 < 2^50 < 1.0e+16. Therefore,
+  //if we apply bisection method to the range with length
+  //1.0e+6 then we will be able to find solution with max error ~1.0e-9.
+  const Standard_Integer aNbIterMax = 50;
+
+  const Standard_Real aNotFilledRange = theLastParOfAline - theCurParam;
+  Standard_Real aMinStep = theStepMin, aMaxStep = Min(theStepMax, aNotFilledRange);
+
+  if(aMinStep > aMaxStep)
+  {
+    theStep = aMaxStep;
+    return Standard_True;
   }
-  //
-  Standard_Boolean bIsDone, bIsEmpty, bParallel, bFound;
-  Standard_Integer aNbPoints = 0;
-  Standard_Real aHalfPi, aEpsilon, aLimV, dT, aT1, aT2 = 0., aEpsT;
-  Standard_Real aU1, aV1, aU2, aV2;
-  gp_Pnt aP1, aP2, aPx;
-  gp_Pnt2d  aP2D1, aP2D2, aPLim(0., 0.);
-  gp_Vec2d aVLim(1., 0.);
-  gp_Lin2d aLLim;
-  IntAna2d_AnaIntersection aAI;
-  //
-  aEpsilon=Epsilon(10.);//1.77e-15
-  aEpsT=0.0001;
-  aLLim.SetDirection(aVLim);
-  //
-  // apex on the Cone
-  if(aType==GeomAbs_Cone) {
-    Standard_Real aDst;
-    gp_Pnt aPap;
-    gp_Cone aCone;
-    //
-    aCone=aQuadric.Cone();
-    aPap=aCone.Apex();
-    //aPx=aQuadric.Value(0.,aVx);
-    aPx=aALine->Value(aTx);
-    //
-    aDst=aPx.Distance(aPap);
-    if(aDst>aTol3D) {// nothing to do
-      return;
-    }
-    //
-    aPLim.SetY(aVx);
-    aLLim.SetLocation(aPLim);
-    //
+
+  const Standard_Real aR = IntPatch_PointLine::
+                            CurvatureRadiusOfIntersLine(myS1, myS2, thePOn2S);
+
+  if(aR < 0.0)
+  {
+    return Standard_False;
+  }
+  else
+  {
+    //The 3D-step is defined as length of the tangent to the osculating circle
+    //by the condition that the distance from end point of the tangent to the
+    //circle is no greater than anEps. theStep is the step in
+    //parameter space of intersection curve (must be converted from 3D-step).
+
+    theStep = Min(sqrt(anEps*(2.0*aR + anEps))/theTgMagnitude, aMaxStep);
+    theStep = Max(theStep, aMinStep);
   }
-  //
-  // apex on the Sphere
-  if(aType==GeomAbs_Sphere) {
-    aHalfPi=0.5*M_PI;
-    //
-    if (fabs(aVx-aHalfPi)<aEpsilon) {
-      aLimV=aHalfPi;
-    }
-    else if (fabs(aVx+aHalfPi)<aEpsilon){
-      aLimV=-aHalfPi;
-    }
-    else {
-      //Check: aUx must be 0 or 2*pi
-      if(fabs(aUx) < aEpsilon || fabs(aUx - 2.*M_PI) < aEpsilon) {
-       //aUx = 0 or 2*pi, but may be it must be 2*pi or 0?
-       bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
-       if(!bFound) {
-         dT=aEpsT*(aTe-aTb);
-         if (iDir<0) {
-           dT=-dT;
-         }
-         aT1=aTx+dT;
-       }
-
-       aP1=aALine->Value(aT1);
-       aQuadric.Parameters(aP1, aU1, aV1);
-
-       if(fabs(aU1) > fabs(aU1 - 2.*M_PI)) {
-         aUx = 2.*M_PI;
-       }
-       else {
-         aUx = 0.;
-       }
-      }
-       
-      return;
+
+  //The step value has been computed for osculating circle.
+  //Now it should be checked for real intersection curve
+  //and is made more precise in case of necessity.
+
+  Standard_Integer aNbIter = 0;
+  do
+  {
+    aNbIter++;
+
+    const gp_XYZ& aP1 = thePOn2S.Value().XYZ();
+    const gp_XYZ aP2(theALine->Value(theCurParam + theStep).XYZ());
+    const Standard_Integer aStatus = CheckDeflection(0.5*(aP1 + aP2), theMaxDeflection);
+
+    if(aStatus == 0)
+      break;
+
+    if(aStatus < 0)
+    {
+      aMinStep = theStep;
     }
-    //
-    aPLim.SetY(aLimV);
-    aLLim.SetLocation(aPLim);
-  }
-  //
-  // aT1, aT2
-  //
-  // Try to find aT1, aT2 taking into acc 3D Tolerance
-  bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
-  if (bFound) {
-    bFound=FindNearParameter(aALine, aT1, iDir, aTol3D, aT2);
-  }
-  if (!bFound) {
-    // Assign aT1, aT2 by some values
-    dT=aEpsT*(aTe-aTb);
-    if (iDir<0) {
-      dT=-dT;
+    else //if(aStatus > 0)
+    {
+      aMaxStep = theStep;
     }
-    aT1=aTx+dT;
-    aT2=aT1+dT;
-  }
-  //
-  aP1=aALine->Value(aT1);
-  aQuadric.Parameters(aP1, aU1, aV1);
-  aP2D1.SetCoord(aU1, aV1);
-  //
-  aP2=aALine->Value(aT2);
-  aQuadric.Parameters(aP2, aU2, aV2);
-  aP2D2.SetCoord(aU2, aV2);
-  //
-  gp_Vec2d aV12(aP2D1, aP2D2);
-
-  if(aV12.SquareMagnitude() <= aEpsilon) {
-    return;
-  }
-  gp_Lin2d aL12(aP2D1, aV12);
-  //
-  aAI.Perform(aLLim, aL12);
-  bIsDone=aAI.IsDone();
-  if (!bIsDone) {
-    return;
-  }
-  bIsEmpty=aAI.IsEmpty();
-  if (bIsEmpty) {
-    return;
-  }
-  aNbPoints=aAI.NbPoints();
-  if (!aNbPoints) {
-    return;
-  }
-  bParallel=aAI.ParallelElements();
-  if (bParallel) {
-    return;
-  }
-  const IntAna2d_IntPoint& aIAPnt=aAI.Point(1);
-  const gp_Pnt2d& aP2D=aIAPnt.Value();
-  aUx=aP2D.X();
-}
-//=======================================================================
-//function : FindNearParameter
-//purpose  : 
-//=======================================================================
-Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
-                                  const Standard_Real aTx,
-                                  const Standard_Integer iDir,
-                                  const Standard_Real aTol3D,
-                                  Standard_Real& aT1)
-{
-  Standard_Boolean bFound;
-  Standard_Real aX, aY, aZ;
-  gp_Pnt aPx, aP1;
-  gp_Vec aVx;
-  //
-  aT1=0.;
-  //
-  bFound=aALine->D1(aTx, aPx, aVx);
-  if(!bFound){
-    return bFound;
-  }
-  gp_Dir aDx(aVx);
-  if (iDir<0) {
-    aDx.Reverse();
+
+    theStep = 0.5*(aMinStep + aMaxStep);
   }
-  aX=aPx.X()+aDx.X()*aTol3D;
-  aY=aPx.Y()+aDx.Y()*aTol3D;
-  aZ=aPx.Z()+aDx.Z()*aTol3D;
-  aP1.SetCoord(aX, aY, aZ);
-  //
-  bFound=aALine->FindParameter(aP1, aT1);
-  //
-  return bFound;
+  while(((aMaxStep - aMinStep) > Precision::PConfusion()) && (aNbIter <= aNbIterMax));
+
+  if(aNbIter > aNbIterMax)
+    return Standard_False;
+
+  return Standard_True;
 }
-                     
index eb88c27..815dd79 100644 (file)
 #ifndef _IntPatch_ALineToWLine_HeaderFile
 #define _IntPatch_ALineToWLine_HeaderFile
 
-#include <Standard.hxx>
+#include <IntPatch_SequenceOfLine.hxx>
+#include <IntSurf_Quadric.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
+#include <Standard_Macro.hxx>
 
-#include <IntSurf_Quadric.hxx>
-#include <Standard_Real.hxx>
-#include <Standard_Integer.hxx>
-class IntSurf_Quadric;
-class IntPatch_WLine;
+class Adaptor3d_HSurface;
 class IntPatch_ALine;
-
-
+class IntSurf_PntOn2S;
 
 class IntPatch_ALineToWLine 
 {
@@ -36,14 +33,10 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  Standard_EXPORT IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1, const IntSurf_Quadric& Quad2);
-  
-  Standard_EXPORT IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1, const IntSurf_Quadric& Quad2, const Standard_Real Deflection, const Standard_Real PasMaxUV, const Standard_Integer NbMaxPoints);
-  
-  Standard_EXPORT void SetTolParam (const Standard_Real aT);
-  
-  Standard_EXPORT Standard_Real TolParam() const;
+  //! Constructor
+  Standard_EXPORT IntPatch_ALineToWLine(const Handle(Adaptor3d_HSurface)& theS1,
+                                        const Handle(Adaptor3d_HSurface)& theS2,
+                                        const Standard_Integer theNbPoints = 200);
   
   Standard_EXPORT void SetTolOpenDomain (const Standard_Real aT);
   
@@ -57,46 +50,57 @@ public:
   
   Standard_EXPORT Standard_Real Tol3D() const;
   
-  Standard_EXPORT void SetConstantParameter() const;
-  
-  Standard_EXPORT void SetUniformAbscissa() const;
-  
-  Standard_EXPORT void SetUniformDeflection() const;
-  
-  Standard_EXPORT Handle(IntPatch_WLine) MakeWLine (const Handle(IntPatch_ALine)& aline) const;
+  //! Converts aline to the set of Walking-lines and adds
+  //! them in theLines.
+  Standard_EXPORT void MakeWLine (const Handle(IntPatch_ALine)& aline,
+                                  IntPatch_SequenceOfLine& theLines) const;
   
-  Standard_EXPORT Handle(IntPatch_WLine) MakeWLine (const Handle(IntPatch_ALine)& aline, const Standard_Real paraminf, const Standard_Real paramsup) const;
-
-
-
+  //! Converts aline (limitted by paraminf and paramsup) to the set of 
+  //! Walking-lines and adds them in theLines.
+  Standard_EXPORT void MakeWLine (const Handle(IntPatch_ALine)& aline,
+                                  const Standard_Real paraminf,
+                                  const Standard_Real paramsup,
+                                  IntPatch_SequenceOfLine& theLines) const;
 
 protected:
+  //! Computes step value to construct point-line. The step depends on
+  //! the local curvature of the intersection line computed in thePOn2S.
+  //! theTgMagnitude is the magnitude of tangent vector to the intersection
+  //! line (in the point thePOn2S).
+  //! Computed step is always in the range [theStepMin, theStepMax].
+  //! Returns FALSE if the step cannot be computed. In this case, its value
+  //! will not be changed.
+  Standard_EXPORT Standard_Boolean StepComputing(const Handle(IntPatch_ALine)& theALine,
+                                                 const IntSurf_PntOn2S& thePOn2S,
+                                                 const Standard_Real theLastParOfAline,
+                                                 const Standard_Real theCurParam,
+                                                 const Standard_Real theTgMagnitude,
+                                                 const Standard_Real theStepMin,
+                                                 const Standard_Real theStepMax,
+                                                 const Standard_Real theMaxDeflection,
+                                                 Standard_Real& theStep) const;
 
 
+  Standard_EXPORT Standard_Integer CheckDeflection(const gp_XYZ& theMidPt,
+                                                   const Standard_Real theMaxDeflection) const;
 
 
 
 private:
 
 
+  Handle(Adaptor3d_HSurface) myS1;
+  Handle(Adaptor3d_HSurface) myS2;
+  IntSurf_Quadric myQuad1;
+  IntSurf_Quadric myQuad2;
 
-  IntSurf_Quadric quad1;
-  IntSurf_Quadric quad2;
-  Standard_Real deflectionmax;
-  Standard_Integer nbpointsmax;
-  Standard_Integer type;
-  Standard_Real myTolParam;
+  //! Approximate number of points in resulting
+  //! WLine (precise number of points is computed
+  //! by the algorithms)
+  Standard_Integer myNbPointsInWline;
   Standard_Real myTolOpenDomain;
   Standard_Real myTolTransition;
   Standard_Real myTol3D;
-
-
 };
 
-
-
-
-
-
-
 #endif // _IntPatch_ALineToWLine_HeaderFile
index 3a9982d..5c270f0 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <IntPatch_ImpPrmIntersection.hxx>
 
-#include <Adaptor2d_HCurve2d.hxx>
 #include <Adaptor3d_HSurface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
+#include <ElCLib.hxx>
 #include <IntPatch_ArcFunction.hxx>
-#include <IntPatch_ImpPrmIntersection.hxx>
-#include <IntPatch_Line.hxx>
-#include <IntPatch_Point.hxx>
+#include <IntPatch_PointLine.hxx>
 #include <IntPatch_RLine.hxx>
 #include <IntPatch_RstInt.hxx>
-#include <IntPatch_SequenceOfLine.hxx>
-#include <IntPatch_TheIWalking.hxx>
+#include <IntPatch_SpecialPoints.hxx>
 #include <IntPatch_TheIWLineOfTheIWalking.hxx>
-#include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
-#include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
+#include <IntPatch_TheIWalking.hxx>
 #include <IntPatch_TheSurfFunction.hxx>
 #include <IntPatch_WLine.hxx>
 #include <IntSurf.hxx>
-#include <IntSurf_InteriorPoint.hxx>
-#include <IntSurf_LineOn2S.hxx>
-#include <IntSurf_PathPoint.hxx>
-#include <IntSurf_PntOn2S.hxx>
+#include <IntSurf_Quadric.hxx>
+#include <IntSurf_QuadricTool.hxx>
 #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 <TopAbs_Orientation.hxx>
+#include <TopTrans_CurveTransition.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
 
 #ifndef OCCT_DEBUG
 #define No_Standard_RangeError
 #define No_Standard_OutOfRange
 #endif
 
-#include <math_Vector.hxx>
-#include <math_Matrix.hxx>
-#include <TopTrans_CurveTransition.hxx>
-#include <TopAbs_State.hxx>
-#include <TopAbs_Orientation.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_Array1OfReal.hxx>
-
-#include <IntSurf_SequenceOfInteriorPoint.hxx>
-#include <IntSurf_QuadricTool.hxx>
-#include <GeomAbs_SurfaceType.hxx>
-#include <IntAna2d_AnaIntersection.hxx>
-#include <gp_Lin2d.hxx>
-#include <ElCLib.hxx>
-
-#include <Bnd_Box2d.hxx>
-#include <IntPatch_PointLine.hxx>
-
-#include <Extrema_GenLocateExtPS.hxx>
-#include <math_FunctionSetRoot.hxx>
-
 static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
                                         const Standard_Boolean       IsReversed,
                                         const IntSurf_Quadric&       theQuad,
@@ -108,24 +79,18 @@ static
                               const Standard_Real theToler2D,
                               const Standard_Real thePeriod);
 
-enum PrePoint_Type
-{
-  PrePoint_NONE,
-  PrePoint_SEAMU,
-  PrePoint_SEAMV,
-  PrePoint_SEAMUV,
-  PrePoint_POLESEAMU,
-  PrePoint_POLE
-};
-
-static PrePoint_Type IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQSurf,
-                                  const Handle(IntSurf_LineOn2S)& theLine,
-                                  const Standard_Boolean IsReversed,
-                                  const Standard_Integer theRefIndex,
-                                  const Standard_Real theDeltaMax)
+//=======================================================================
+//function : IsSeamOrPole
+//purpose  : 
+//=======================================================================
+static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                         const Handle(IntSurf_LineOn2S)& theLine,
+                                         const Standard_Boolean IsReversed,
+                                         const Standard_Integer theRefIndex,
+                                         const Standard_Real theDeltaMax)
 {
   if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
-    return PrePoint_NONE;
+    return IntPatch_SPntNone;
 
   //Parameters on Quadric and on parametric for reference point
   Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
@@ -147,151 +112,38 @@ static PrePoint_Type IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQSurf,
   const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
 
   if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
-    return PrePoint_NONE;
+    return IntPatch_SPntNone;
 
   switch(aType)
   {
   case GeomAbs_Cylinder:
-    return PrePoint_SEAMU;
+    return IntPatch_SPntSeamU;
 
   case GeomAbs_Torus:
     {
       const Standard_Real aDeltaV = Abs(aVQRef - aVQNext);
 
       if((aDeltaU >= theDeltaMax) && (aDeltaV >= theDeltaMax))
-        return PrePoint_SEAMUV;
+        return IntPatch_SPntSeamUV;
 
       if(aDeltaU >= theDeltaMax)
-        return PrePoint_SEAMU;
+        return IntPatch_SPntSeamU;
 
       if(aDeltaV >= theDeltaMax)
-        return PrePoint_SEAMV;
+        return IntPatch_SPntSeamV;
     }
 
     break;
   case GeomAbs_Sphere:
   case GeomAbs_Cone:
-    return PrePoint_POLESEAMU;
+    return IntPatch_SPntPoleSeamU;
   default:
     break;
   }
 
-  return PrePoint_NONE;
+  return IntPatch_SPntNone;
 }
 
-// The function for searching intersection point, which 
-// lies in the seam-edge of the quadric definetely.
-class FuncPreciseSeam: public math_FunctionSetWithDerivatives
-{
-public:
-  FuncPreciseSeam(const Handle(Adaptor3d_HSurface)& theQSurf, const Handle(Adaptor3d_HSurface)& thePSurf, const Standard_Boolean isTheUSeam): myQSurf(theQSurf), myPSurf(thePSurf), myIsUSeam(isTheUSeam) {};
-  
-  Standard_EXPORT virtual Standard_Integer NbVariables() const
-  {
-    return 3;
-  };
-
-  Standard_EXPORT virtual Standard_Integer NbEquations() const
-  {
-    return 3;
-  }
-
-  Standard_EXPORT virtual Standard_Boolean Value (const math_Vector& theX, math_Vector& theF)
-  {
-    try
-    {
-      const Standard_Integer anIndX = theX.Lower(), anIndF = theF.Lower();
-      const gp_Pnt aP1(myPSurf->Value(theX(anIndX), theX(anIndX+1)));
-      const gp_Pnt aP2(myIsUSeam? myQSurf->Value(0.0, theX(anIndX+2)) : myQSurf->Value(theX(anIndX+2), 0.0));
-
-      (aP1.XYZ()-aP2.XYZ()).Coord(theF(anIndF), theF(anIndF+1), theF(anIndF+2));
-    }
-    catch(Standard_Failure)
-    {
-      return Standard_False;
-    }
-
-    return Standard_True;
-  };
-
-  Standard_EXPORT virtual Standard_Boolean Derivatives (const math_Vector& theX, math_Matrix& theD)
-  {
-    try
-    {
-      const Standard_Integer anIndX = theX.Lower(), anIndRD = theD.LowerRow(), anIndCD = theD.LowerCol();
-      gp_Pnt aPt;
-      gp_Vec aD1u, aD1v, aD2u, aD2v;
-      myPSurf->D1(theX(anIndX), theX(anIndX+1), aPt, aD1u, aD1v);
-      if(myIsUSeam)
-        myQSurf->D1(0.0, theX(anIndX+2), aPt, aD2u, aD2v);
-      else
-        myQSurf->D1(theX(anIndX+2), 0.0, aPt, aD2u, aD2v);
-
-      // d/dX1
-      aD1u.Coord(theD(anIndRD, anIndCD), theD(anIndRD+1, anIndCD), theD(anIndRD+2, anIndCD));
-
-      // d/dX1
-      aD1v.Coord(theD(anIndRD, anIndCD+1), theD(anIndRD+1, anIndCD+1), theD(anIndRD+2, anIndCD+1));
-
-      // d/dX3
-      if(myIsUSeam)
-        aD2v.Reversed().Coord(theD(anIndRD, anIndCD+2), theD(anIndRD+1, anIndCD+2), theD(anIndRD+2, anIndCD+2));
-      else
-        aD2u.Reversed().Coord(theD(anIndRD, anIndCD+2), theD(anIndRD+1, anIndCD+2), theD(anIndRD+2, anIndCD+2));
-    }
-    catch(Standard_Failure)
-    {
-      return Standard_False;
-    }
-
-    return Standard_True;
-  };
-
-  Standard_EXPORT virtual Standard_Boolean Values (const math_Vector& theX, math_Vector& theF, math_Matrix& theD)
-  {
-    try
-    {
-      const Standard_Integer anIndX = theX.Lower(), anIndF = theF.Lower(), anIndRD = theD.LowerRow(), anIndCD = theD.LowerCol();
-      gp_Pnt aP1, aP2;
-      gp_Vec aD1u, aD1v, aD2u, aD2v;
-      myPSurf->D1(theX(anIndX), theX(anIndX+1), aP1, aD1u, aD1v);
-      if(myIsUSeam)
-        myQSurf->D1(0.0, theX(anIndX+2), aP2, aD2u, aD2v);
-      else
-        myQSurf->D1(theX(anIndX+2), 0.0, aP2, aD2u, aD2v);
-
-      //Value
-      (aP1.XYZ()-aP2.XYZ()).Coord(theF(anIndF), theF(anIndF+1), theF(anIndF+2));
-
-      // d/dX1
-      aD1u.Coord(theD(anIndRD, anIndCD), theD(anIndRD+1, anIndCD), theD(anIndRD+2, anIndCD));
-
-      // d/dX1
-      aD1v.Coord(theD(anIndRD, anIndCD+1), theD(anIndRD+1, anIndCD+1), theD(anIndRD+2, anIndCD+1));
-
-      // d/dX3
-      if(myIsUSeam)
-        aD2v.Reversed().Coord(theD(anIndRD, anIndCD+2), theD(anIndRD+1, anIndCD+2), theD(anIndRD+2, anIndCD+2));
-      else
-        aD2u.Reversed().Coord(theD(anIndRD, anIndCD+2), theD(anIndRD+1, anIndCD+2), theD(anIndRD+2, anIndCD+2));
-    }
-    catch(Standard_Failure)
-    {
-      return Standard_False;
-    }
-
-    return Standard_True;
-  }
-
-protected:
-  FuncPreciseSeam operator=(FuncPreciseSeam&);
-
-private:
-  const Handle(Adaptor3d_HSurface)& myQSurf;
-  const Handle(Adaptor3d_HSurface)& myPSurf;
-  const Standard_Boolean myIsUSeam;
-};
-
 //=======================================================================
 //function : IntPatch_ImpPrmIntersection
 //purpose  : 
@@ -2622,7 +2474,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
   // build WLine parts (if any)
   Standard_Boolean flNextLine = Standard_True;
   Standard_Boolean hasBeenDecomposed = Standard_False;
-  PrePoint_Type aPrePointExist = PrePoint_NONE;
+  IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
 
   IntSurf_PntOn2S PrePoint;
   while(flNextLine)
@@ -2643,81 +2495,19 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
 
     if(aPrePointExist)
     {
-      //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).
-
-      //Here, we forbid "jumping" between two neighbor Walking-point
-      //with step greater than pi/4
-      const Standard_Real aPeriod = M_PI_2, aHalfPeriod = M_PI_4;
       const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aFindex);
 
       const Standard_Real aURes = theQSurf->UResolution(theArcTol),
-                          aVRes = theQSurf->UResolution(theArcTol);
+                          aVRes = theQSurf->VResolution(theArcTol);
 
-      const Standard_Real aTol2d = (aPrePointExist == PrePoint_POLE) ? 0.0 : 
-              (aPrePointExist == PrePoint_SEAMV)? aVRes :
-              (aPrePointExist == PrePoint_SEAMUV)? Max(aURes, aVRes) : aURes;
+      const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 : 
+              (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
+              (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
 
-      if(!PrePoint.IsSame(aRefPt, Precision::Confusion(), aTol2d))
+      if(IntPatch_SpecialPoints::ContinueAfterSpecialPoint(theQSurf, thePSurf, aRefPt,
+                                                              aPrePointExist, aTol2d,
+                                                              PrePoint, IsReversed))
       {
-        Standard_Real aURef = 0.0, aVRef = 0.0;
-        Standard_Real aUquad = 0.0, aVquad = 0.0;
-
-        //Take parameters on quadric
-        if(IsReversed)
-        {
-          PrePoint.ParametersOnS2(aUquad, aVquad);
-          aRefPt.ParametersOnS2(aURef, aVRef);
-        }
-        else
-        {
-          PrePoint.ParametersOnS1(aUquad, aVquad);
-          aRefPt.ParametersOnS1(aURef, aVRef);
-        }
-
-        if(theQSurf->IsUPeriodic())
-        {
-          Standard_Real aDeltaPar = aURef-aUquad;
-          const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
-          while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-          {
-            aUquad += anIncr;
-            aDeltaPar = aURef-aUquad;
-          }
-        }
-
-        if(theQSurf->IsVPeriodic())
-        {
-          Standard_Real aDeltaPar = aVRef-aVquad;
-          const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
-          while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-          {
-            aVquad += anIncr;
-            aDeltaPar = aVRef-aVquad;
-          }
-        }
-
-        PrePoint.SetValue(!IsReversed, aUquad, aVquad);
         sline->Add(PrePoint);
       }
       else
@@ -2727,7 +2517,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
       }
     }
 
-    aPrePointExist = PrePoint_NONE;
+    aPrePointExist = IntPatch_SPntNone;
 
     // analyze other points
     for(Standard_Integer k = aFindex; k <= aLindex; k++)
@@ -2750,90 +2540,49 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
 
       aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k-1, aDeltaUmax);
 
-      if(aPrePointExist != PrePoint_NONE)
+      if(aPrePointExist != IntPatch_SPntNone)
       {
         aBindex = k;
         isDecomposited = Standard_True;
         ////
-        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;
+        Standard_Real aCompareTol3D = Precision::Confusion();
+        Standard_Real aCompareTol2D = Precision::PConfusion();
 
-        if(IsReversed)
-        {
-          aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
-        }
-        else
-        {
-          aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
-        }
+        IntSurf_PntOn2S aNewPoint = aRefPt;
+        IntPatch_SpecPntType aLastType = IntPatch_SPntNone;
 
-        if(aPrePointExist == PrePoint_SEAMUV)
+        if(aPrePointExist == IntPatch_SPntSeamUV)
         {
-          aPrePointExist = PrePoint_NONE;
-
-          gp_Pnt aPQuad;
-          Standard_Real aUquad = 0.0;
-          Standard_Real aVquad = 0.0; 
-
-          theQSurf->D0(aUquad, aVquad, aPQuad);
+          aPrePointExist = IntPatch_SPntNone;
+          aLastType = IntPatch_SPntSeamUV;
+          IntPatch_SpecialPoints::AddCrossUVIsoPoint(theQSurf, thePSurf, 
+                                                        aRefPt, theTolTang,
+                                                        aNewPoint, IsReversed);
+        }
+        else if(aPrePointExist == IntPatch_SPntSeamV)
+        {//WLine goes through seam
+          aPrePointExist = IntPatch_SPntNone;
+          aLastType = IntPatch_SPntSeamV;
 
-          Extrema_GenLocateExtPS anExtr(thePSurf->Surface());
-          anExtr.Perform(aPQuad, aU0, aV0);
+          //Not quadric point
+          Standard_Real aU0 = 0.0, aV0 = 0.0;
+          //Quadric point
+          Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
 
-          if(!anExtr.IsDone())
+          if(IsReversed)
           {
-            break;
+            aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
           }
-
-          if(anExtr.SquareDistance() < theTolTang*theTolTang)
+          else
           {
-            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()))
-            {
-              //Adjust found U-paramter to previous point of the Walking-line
-              Standard_Real aDeltaPar = aUQuadRef-aUquad;
-              const Standard_Real anIncrU = Sign(aPeriod, aDeltaPar);
-              while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-              {
-                aUquad += anIncrU;
-                aDeltaPar = aUQuadRef-aUquad;
-              }
-
-              //Adjust found V-paramter to previous point of the Walking-line
-              aDeltaPar = aVQuadRef-aVquad;
-              const Standard_Real anIncrV = Sign(aPeriod, aDeltaPar);
-              while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-              {
-                aVquad += anIncrV;
-                aDeltaPar = aVQuadRef-aVquad;
-              }
-
-              aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
-              
-              sline->Add(aNewPoint);
-              aPrePointExist = PrePoint_SEAMUV;
-              PrePoint = aNewPoint;
-            }
+            aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
           }
-        }
-        else if(aPrePointExist == PrePoint_SEAMV)
-        {//WLine goes through seam
-          aPrePointExist = PrePoint_NONE;
 
-          FuncPreciseSeam aF(theQSurf, thePSurf, Standard_False);
           math_Vector aTol(1, 3), aStartPoint(1,3),
-                      anInfBound(1, 3), aSupBound(1, 3);
-          
+            anInfBound(1, 3), aSupBound(1, 3);
+
           //Parameters on parametric surface
           Standard_Real aUp = 0.0, aVp = 0.0;
           if(IsReversed)
@@ -2858,358 +2607,51 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
           aSupBound(2) = thePSurf->LastVParameter();
           aSupBound(3) = theQSurf->LastUParameter();
 
-          math_FunctionSetRoot aSRF(aF, aTol);
-          aSRF.Perform(aF, aStartPoint, anInfBound, aSupBound);
-
-          if(!aSRF.IsDone())
-          {
-            break;
-          }
-
-          // Now aStartPoint is useless. Therefore, we use it for keeping
-          // new point.
-          aSRF.Root(aStartPoint);
-          
-          //On parametric
-          aU0 = aStartPoint(1);
-          aV0 = aStartPoint(2);
-
-          //On quadric
-          Standard_Real aUquad = aStartPoint(3);
-          Standard_Real aVquad = 0.0; 
-          const gp_Pnt aPQuad(theQSurf->Value(aUquad, aVquad));
-          const gp_Pnt aP0(thePSurf->Value(aU0, aV0));
-
-          {
-            //Adjust found U-paramter to previous point of the Walking-line
-            Standard_Real aDeltaPar = aVQuadRef-aVquad;
-            const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
-            while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-            {
-              aVquad += anIncr;
-              aDeltaPar = aVQuadRef-aVquad;
-            }
-          }
+          IntPatch_SpecialPoints::
+                      AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False,
+                                        aTol, aStartPoint, anInfBound, aSupBound,
+                                        aNewPoint, IsReversed);
+        }
+        else if(aPrePointExist == IntPatch_SPntPoleSeamU)
+        {
+          aPrePointExist = IntPatch_SPntNone;          
 
-          IntSurf_PntOn2S aNewPoint;
-          if(IsReversed)
-            aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
-          else
-            aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+          IntPatch_Point aVert;
+          aVert.SetValue(aRefPt);
 
-          if(!aNewPoint.IsSame(aRefPt, Precision::Confusion(), Precision::PConfusion()))
+          if(IntPatch_SpecialPoints::
+                      AddSingularPole(theQSurf, thePSurf, aRefPt, theTolTang,
+                                      aVert, aNewPoint, IsReversed))
           {
-            aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
-            sline->Add(aNewPoint);
-            aPrePointExist = PrePoint_SEAMV;
-            PrePoint = aNewPoint;
-          }
+            aPrePointExist = IntPatch_SPntPole;
+            aLastType = IntPatch_SPntPole;
+            aCompareTol2D = -1.0;
+          } //if(IntPatch_AddSpecialPoints::AddSingularPole(...))
           else
-          {
-            if(sline->NbPoints() == 1)
-            {
-              //FIRST point of the sline is the pole of the quadric.
-              //Therefore, there is no point in decomposition.
-
-              PrePoint = aRefPt;
-              aPrePointExist = PrePoint_SEAMV;
-            }
+          {//Pole is not an intersection point
+            aPrePointExist = IntPatch_SPntSeamU;
           }
         }
-        else if(aPrePointExist == PrePoint_POLESEAMU)
-        {//Check if WLine goes through pole
-          
-          aPrePointExist = PrePoint_NONE;
 
-          //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);
+        if(aPrePointExist == IntPatch_SPntSeamU)
+        {//WLine goes through seam
+          aPrePointExist = IntPatch_SPntNone;
+          aLastType = IntPatch_SPntSeamU;
 
-          Extrema_GenLocateExtPS anExtr(thePSurf->Surface());
-          anExtr.Perform(aPQuad, aU0, aV0);
+          //Not quadric point
+          Standard_Real aU0 = 0.0, aV0 = 0.0;
+          //Quadric point
+          Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
 
-          if(!anExtr.IsDone())
+          if(IsReversed)
           {
-            break;
+            aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
           }
-
-          if(anExtr.SquareDistance() < theTolTang*theTolTang)
-          { //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);
-
-              //Transforms parametric surface in coordinate-system of the quadric
-              gp_Trsf aTr;
-              aTr.SetTransformation((theQuad.TypeQuadric() == GeomAbs_Sphere) ?
-                                      theQuad.Sphere().Position() :
-                                      theQuad.Cone().Position());
-
-              //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()) < Precision::PConfusion()) &&
-                  (Abs(aVecDv.Z()) < Precision::PConfusion()))
-                {
-                  //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).
-                  //Another reason is that we have tangent zone around the pole
-                  //(see bug #26576).
-                  //Computation correct value of aUquad is impossible. Therefore,
-                  //we should throw an exception in this case.
-                  //Also, any Walking line cannot be created in this case.
-                  //Hovewer, Restriction line is not created by intersection algorithm.
-                  //It is already exists (above we check simply, if this line is
-                  //intersection line).
-                  //Therefore, we can try to find the aUquad-parameter on (existing)
-                  //Restriction line. Here, we will do it with
-                  //extrapolation algorithm.
-                  //Use interpolation algorithm is wrong because aUquad parameter
-                  //jumps while the line going though the pole.
-
-                  if((theLine->ArcType() == IntPatch_Walking) ||
-                    (aBindex < 3))
-                  {
-                    //We must have at least two previous points
-                    //in order to do linear extrapolation.
-                    Standard_NumericError::
-                      Raise("IntPatch_ImpPrmIntersection.cxx, DecomposeResult(...): "
-                      "Cannot find UV-coordinate for quadric in the pole");
-                  }
-                  else
-                  {
-#ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG
-                    cout << "Cannot find UV-coordinate for quadric in the pole."
-                      " See considered comment above. IntPatch_ImpPrmIntersection.cxx,"
-                      " DecomposeResult(...)" << endl;
-#endif
-
-                    //    *----------*------------x
-                    // QuadPrev   QuadRef     Quad (must be found)
-
-                    const IntSurf_PntOn2S& aPt2S = aSSLine->Value(aBindex-2);
-                    //Quadric point
-                    Standard_Real aUQuadPrev = 0.0, aVQuadPrev = 0.0;
-                    if(IsReversed)
-                    {
-                      aPt2S.ParametersOnS2(aUQuadPrev, aVQuadPrev);
-                    }
-                    else
-                    {
-                      aPt2S.ParametersOnS1(aUQuadPrev, aVQuadPrev);
-                    }
-
-                    Standard_NumericError_Raise_if(
-                      Abs(aVQuadPrev - aVQuadRef) < gp::Resolution(),
-                      "Division by zero");
-
-                    aUquad = 
-                      aUQuadPrev + (aUQuadRef - aUQuadPrev)*
-                      (aVquad - aVQuadPrev)/(aVQuadRef - aVQuadPrev);
-                  }
-                }
-                else
-                {
-                  if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
-                  {
-                    const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
-
-                    aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
-                      aVecDu.Y()*aDusDvs - aVecDv.Y());
-                  }
-                  else
-                  {
-                    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 = Sign(aPeriod, aDeltaPar);
-                  while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-                  {
-                    aUquad += anIncr;
-                    aDeltaPar = aUQuadRef-aUquad;
-                  }
-                }
-              }
-
-              aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
-              
-              sline->Add(aNewPoint);
-              aPrePointExist = PrePoint_POLE;
-              PrePoint = aNewPoint;
-            } // if(!aNewPoint.IsSame(aRefPt, Precision::Confusion()))
-            else
-            {
-              aPrePointExist = PrePoint_NONE;
-
-              if(sline->NbPoints() == 1)
-              {
-                //FIRST point of the sline is the pole of the quadric.
-                //Therefore, there is no point in decomposition.
-
-                PrePoint = aRefPt;
-                aPrePointExist = PrePoint_POLE;
-              }
-            }
-          } //if(anExtr.SquareDistance() < aTol*aTol)
           else
-          {//Pole is not an intersection point
-            aPrePointExist = PrePoint_SEAMU;
+          {
+            aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
           }
-        }
-
-        if(aPrePointExist == PrePoint_SEAMU)
-        {//WLine goes through seam
 
-          aPrePointExist = PrePoint_NONE;
-
-          FuncPreciseSeam aF(theQSurf, thePSurf, Standard_True);
           math_Vector aTol(1, 3), aStartPoint(1,3),
                       anInfBound(1, 3), aSupBound(1, 3);
           
@@ -3237,62 +2679,27 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
           aSupBound(2) = thePSurf->LastVParameter();
           aSupBound(3) = theQSurf->LastVParameter();
 
-          math_FunctionSetRoot aSRF(aF, aTol);
-          aSRF.Perform(aF, aStartPoint, anInfBound, aSupBound);
-
-          if(!aSRF.IsDone())
-          {
-            break;
-          }
-
-          // Now aStartPoint is useless. Therefore, we use it for keeping
-          // new point.
-          aSRF.Root(aStartPoint);
-          
-          //On parametric
-          aU0 = aStartPoint(1);
-          aV0 = aStartPoint(2);
-
-          //On quadric
-          Standard_Real aUquad = 0.0;
-          Standard_Real aVquad = aStartPoint(3); 
-          const gp_Pnt aPQuad(theQSurf->Value(aUquad, aVquad));
-          const gp_Pnt aP0(thePSurf->Value(aU0, aV0));
-
-          {
-            //Adjust found U-paramter to previous point of the Walking-line
-            Standard_Real aDeltaPar = aUQuadRef-aUquad;
-            const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
-            while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
-            {
-              aUquad += anIncr;
-              aDeltaPar = aUQuadRef-aUquad;
-            }
-          }
-
-          IntSurf_PntOn2S aNewPoint;
-          if(IsReversed)
-            aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
-          else
-            aNewPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+          IntPatch_SpecialPoints::
+                AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, aTol,
+                                  aStartPoint, anInfBound, aSupBound, aNewPoint,
+                                  IsReversed);
+        }
 
-          if(!aNewPoint.IsSame(aRefPt, Precision::Confusion(), Precision::PConfusion()))
-          {
-            aNewPoint.SetValue(!IsReversed, aUquad, aVquad);
-            sline->Add(aNewPoint);
-            aPrePointExist = PrePoint_SEAMU;
-            PrePoint = aNewPoint;
-          }
-          else
+        if(!aNewPoint.IsSame(aRefPt, aCompareTol3D, aCompareTol2D))
+        {
+          sline->Add(aNewPoint);
+          aPrePointExist = aLastType;
+          PrePoint = aNewPoint;
+        }
+        else
+        {
+          if(sline->NbPoints() == 1)
           {
-            if(sline->NbPoints() == 1)
-            {
-              //FIRST point of the sline is the pole of the quadric.
-              //Therefore, there is no point in decomposition.
+            //FIRST point of the sline is the pole of the quadric.
+            //Therefore, there is no point in decomposition.
 
-              PrePoint = aRefPt;
-              aPrePointExist = PrePoint_SEAMU;
-            }
+            PrePoint = aRefPt;
+            aPrePointExist = aLastType;
           }
         }
 
index 754e89a..0a441ab 100644 (file)
@@ -12,6 +12,7 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <stdio.h>
 #include <IntPatch_Intersection.hxx>
 
 #include <Adaptor3d_HSurface.hxx>
 #include <IntPatch_GLine.hxx>
 #include <IntPatch_ImpImpIntersection.hxx>
 #include <IntPatch_ImpPrmIntersection.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: SequenceOfLine
@@ -1332,165 +1320,105 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
 {
   IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
                                       myTolArc,myTolTang, theIsReqToKeepRLine);
-  if (interii.IsDone())
-  {
-    done = (interii.GetStatus() == IntPatch_ImpImpIntersection::IntStatus_OK);
-    empt = interii.IsEmpty();
-    if (!empt)
-    {
-      tgte = interii.TangentFaces();
-      if (tgte)
-        oppo = interii.OppositeFaces();
 
-      Standard_Boolean isQuadSet = Standard_False;
-      IntSurf_Quadric Quad1,Quad2;
-
-      for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
-      {
-        const Handle(IntPatch_Line)& line = interii.Line(i);
-        if (line->ArcType() == IntPatch_Analytic)
-        {
-          if(!isQuadSet)
-          {
-            isQuadSet = Standard_True;
-            
-            const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
-            const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
-
-            switch(aTyps1)
-            {
-            case GeomAbs_Plane:
-              Quad1.SetValue(theS1->Plane());
-              break;
-
-            case GeomAbs_Cylinder:
-              Quad1.SetValue(theS1->Cylinder());
-              break;
-
-            case GeomAbs_Sphere:
-              Quad1.SetValue(theS1->Sphere());
-              break;
-
-            case GeomAbs_Cone:
-              Quad1.SetValue(theS1->Cone());
-              break;
-
-            case GeomAbs_Torus:
-              Quad1.SetValue(theS1->Torus());
-              break;
-
-            default:
-              isQuadSet = Standard_False;
-              break;
-            }
+  if (!interii.IsDone())
+  {
+    done = Standard_False;
+    ParamParamPerfom(theS1, theD1, theS2, theD2, 
+                TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
+    return;
+  }
 
-            switch(aTyps2)
-            {
-            case GeomAbs_Plane:
-              Quad2.SetValue(theS2->Plane());
-              break;
-            case GeomAbs_Cylinder:
-              Quad2.SetValue(theS2->Cylinder());
-              break;
-
-            case GeomAbs_Sphere:
-              Quad2.SetValue(theS2->Sphere());
-              break;
-
-            case GeomAbs_Cone:
-              Quad2.SetValue(theS2->Cone());
-              break;
-
-            case GeomAbs_Torus:
-              Quad2.SetValue(theS2->Torus());
-              break;
-
-            default:
-              isQuadSet = Standard_False;
-              break;
-            }
+  done = (interii.GetStatus() == IntPatch_ImpImpIntersection::IntStatus_OK);
+  empt = interii.IsEmpty();
 
-            if(!isQuadSet)
-            {
-              break;
-            }
-          }
+  if(empt)
+  {
+    return;
+  }
 
-          IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
-          Handle(IntPatch_WLine) wlin = 
-                      AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line));
-          wlin->EnablePurging(Standard_False);
-          slin.Append(wlin);
-        }
-        else
-        {
-          if(line->ArcType() == IntPatch_Walking)
-          {
-            Handle(IntPatch_WLine)::DownCast(line)->EnablePurging(Standard_False);
-          }
+  const Standard_Integer aNbPointsInALine = 200;
 
-          slin.Append(line);
-        }
-      }
+  tgte = interii.TangentFaces();
+  if (tgte)
+    oppo = interii.OppositeFaces();
 
-      for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
-      {
-        spnt.Append(interii.Point(i));
-      }
+  Standard_Boolean isWLExist = Standard_False;
+  IntPatch_ALineToWLine AToW(theS1, theS2, aNbPointsInALine);
 
-      if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
+  for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
+  {
+    const Handle(IntPatch_Line)& line = interii.Line(i);
+    if (line->ArcType() == IntPatch_Analytic)
+    {
+      isWLExist = Standard_True;
+      AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line), slin);
+    }
+    else
+    {
+      if (line->ArcType() == IntPatch_Walking)
       {
-        IntPatch_WLineTool::JoinWLines( slin, spnt, TolTang,
-                                        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());
+        Handle(IntPatch_WLine)::DownCast(line)->EnablePurging(Standard_False);
       }
 
-      if(isQuadSet)
-      {
-        Bnd_Box2d aBx1, aBx2;
-        const Standard_Real aU1F = theS1->FirstUParameter(),
-                            aU1L = theS1->LastUParameter(),
-                            aV1F = theS1->FirstVParameter(),
-                            aV1L = theS1->LastVParameter(),
-                            aU2F = theS2->FirstUParameter(),
-                            aU2L = theS2->LastUParameter(),
-                            aV2F = theS2->FirstVParameter(),
-                            aV2L = theS2->LastVParameter();
-        aBx1.Add(gp_Pnt2d(aU1F, aV1F));
-        aBx1.Add(gp_Pnt2d(aU1L, aV1F));
-        aBx1.Add(gp_Pnt2d(aU1L, aV1L));
-        aBx1.Add(gp_Pnt2d(aU1F, aV1L));
-        aBx2.Add(gp_Pnt2d(aU2F, aV2F));
-        aBx2.Add(gp_Pnt2d(aU2L, aV2F));
-        aBx2.Add(gp_Pnt2d(aU2L, aV2L));
-        aBx2.Add(gp_Pnt2d(aU2F, aV2L));
-
-        aBx1.Enlarge(Precision::PConfusion());
-        aBx2.Enlarge(Precision::PConfusion());
-
-        IntPatch_WLineTool::
-          ExtendTwoWlinesToEachOther(slin, Quad1, Quad2, TolTang,
-                                     theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
-                                     theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
-                                     theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
-                                     theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
-                                     aBx1, aBx2);
-      }
+      if((line->ArcType() != IntPatch_Restriction) || theIsReqToKeepRLine)
+        slin.Append(line);
     }
   }
-  else
-    ParamParamPerfom(theS1, theD1, theS2, theD2, 
-                TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
+
+  for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
+  {
+    spnt.Append(interii.Point(i));
+  }
+
+  if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
+  {
+    IntPatch_WLineTool::JoinWLines( slin, spnt, TolTang,
+                                    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());
+  }
+
+  if(isWLExist)
+  {
+    Bnd_Box2d aBx1, aBx2;
+    const Standard_Real aU1F = theS1->FirstUParameter(),
+                        aU1L = theS1->LastUParameter(),
+                        aV1F = theS1->FirstVParameter(),
+                        aV1L = theS1->LastVParameter(),
+                        aU2F = theS2->FirstUParameter(),
+                        aU2L = theS2->LastUParameter(),
+                        aV2F = theS2->FirstVParameter(),
+                        aV2L = theS2->LastVParameter();
+    aBx1.Add(gp_Pnt2d(aU1F, aV1F));
+    aBx1.Add(gp_Pnt2d(aU1L, aV1F));
+    aBx1.Add(gp_Pnt2d(aU1L, aV1L));
+    aBx1.Add(gp_Pnt2d(aU1F, aV1L));
+    aBx2.Add(gp_Pnt2d(aU2F, aV2F));
+    aBx2.Add(gp_Pnt2d(aU2L, aV2F));
+    aBx2.Add(gp_Pnt2d(aU2L, aV2L));
+    aBx2.Add(gp_Pnt2d(aU2F, aV2L));
+
+    aBx1.Enlarge(Precision::PConfusion());
+    aBx2.Enlarge(Precision::PConfusion());
+
+    const Standard_Real
+            anArrOfPeriod[4] = {theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
+                                theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
+                                theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
+                                theS2->IsVPeriodic()? theS2->VPeriod() : 0.0};
+    IntPatch_WLineTool::ExtendTwoWLines(slin, theS1, theS2, TolTang,
+                                        anArrOfPeriod, aBx1, aBx2);
+  }
 }
 
 //=======================================================================
index 5c9367b..414e464 100644 (file)
@@ -54,6 +54,10 @@ public:
   Standard_EXPORT void SetValue (const gp_Pnt& Pt, const Standard_Real Tol, const Standard_Boolean Tangent);
   
     void SetValue (const gp_Pnt& Pt);
+
+  //! Sets the value of <pt> member
+  void SetValue (const IntSurf_PntOn2S& thePOn2S);
+
   
     void SetTolerance (const Standard_Real Tol);
   
index c2b409b..7bd5fb4 100644 (file)
@@ -27,6 +27,14 @@ inline void IntPatch_Point::SetValue (const gp_Pnt& Pt)
   pt.SetValue(Pt);
 }
 
+//=======================================================================
+////function : SetValue
+//purpose  : 
+//=======================================================================
+inline void IntPatch_Point::SetValue(const IntSurf_PntOn2S& thePOn2S)
+{
+  pt = thePOn2S;
+}
 
 inline void IntPatch_Point::SetTolerance (const Standard_Real Tol)
 {
index 5109061..3598b10 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <IntPatch_PointLine.hxx>
+
+#include <Adaptor3d_HSurface.hxx>
 #include <IntSurf_PntOn2S.hxx>
-#include <Standard_DomainError.hxx>
-#include <Standard_OutOfRange.hxx>
-#include <Standard_Type.hxx>
+#include <Precision.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line)
 
@@ -39,4 +38,165 @@ IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang) :
   IntPatch_Line(Tang)
 {}
 
+//=======================================================================
+//function : CurvatureRadiusOfIntersLine
+//purpose  :
+//        ATTENTION!!!
+//            Returns negative value if computation is not possible
+//=======================================================================
+Standard_Real IntPatch_PointLine::
+                CurvatureRadiusOfIntersLine(const Handle(Adaptor3d_HSurface)& theS1,
+                                            const Handle(Adaptor3d_HSurface)& theS2,
+                                            const IntSurf_PntOn2S& theUVPoint)
+{
+  const Standard_Real aSmallValue = 1.0/Precision::Infinite();
+  const Standard_Real aSqSmallValue = aSmallValue*aSmallValue;
+
+  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
+  theUVPoint.Parameters(aU1, aV1, aU2, aV2);
+  gp_Pnt aPt;
+  gp_Vec aDU1, aDV1, aDUU1, aDUV1, aDVV1;
+  gp_Vec aDU2, aDV2, aDUU2, aDUV2, aDVV2;
+  
+  theS1->D2(aU1, aV1, aPt, aDU1, aDV1, aDUU1, aDVV1, aDUV1);
+  theS2->D2(aU2, aV2, aPt, aDU2, aDV2, aDUU2, aDVV2, aDUV2);
+
+#if 0
+  //The code in this block contains TEST CASES for
+  //this algorithm only. It is stupedly to create OCCT-test for
+  //the method, which will be changed possibly never.
+  //However, if we do something in this method we can check its
+  //functionality easily. For that:
+  //  1. Initialyze aTestID variable by the correct value;
+  //  2. Compile this test code fragment.
+
+  int aTestID = 0;
+  Standard_Real anExpectedSqRad = -1.0;
+  switch(aTestID)
+  {
+  case 1:
+    //Intersection between two spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 3
+    //and O2(5.0, 0.0, 0.0), R2 = 5.0.
+    //Considered point has coordinates: (0.9, 0.0, 0.3*sqrt(91.0)).
+
+    aDU1.SetCoord(0.00000000000000000, 0.90000000000000002, 0.00000000000000000);
+    aDV1.SetCoord(-2.8618176042508372, 0.00000000000000000, 0.90000000000000002);
+    aDUU1.SetCoord(-0.90000000000000002, 0.00000000000000000, 0.00000000000000000);
+    aDUV1.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000);
+    aDVV1.SetCoord(-0.90000000000000002, 0.00000000000000000, -2.8618176042508372);
+    aDU2.SetCoord(0.00000000000000000, -4.0999999999999996, 0.00000000000000000);
+    aDV2.SetCoord(-2.8618176042508372, 0.00000000000000000, -4.0999999999999996);
+    aDUU2.SetCoord(4.0999999999999996, 0.00000000000000000, 0.00000000000000000);
+    aDUV2.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000);
+    aDVV2.SetCoord(4.0999999999999996, 0.00000000000000000, -2.8618176042508372);
+    anExpectedSqRad = 819.0/100.0;
+    break;
+  case 2:
+    //Intersection between spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 10
+    //and the plane 3*x+4*y+z=26.
+    //Considered point has coordinates: (-1.68, 5.76, 8.0).
+
+    aDU1.SetCoord(-5.76, -1.68, 0.0);
+    aDV1.SetCoord(2.24, -7.68, 6.0);
+    aDUU1.SetCoord(1.68, -5.76, 0.0);
+    aDUV1.SetCoord(7.68, 2.24, 0.0);
+    aDVV1.SetCoord(1.68, -5.76, -8.0);
+    aDU2.SetCoord(1.0, 0.0, -3.0);
+    aDV2.SetCoord(0.0, 1.0, -4.0);
+    aDUU2.SetCoord(0.0, 0.0, 0.0);
+    aDUV2.SetCoord(0.0, 0.0, 0.0);
+    aDVV2.SetCoord(0.0, 0.0, 0.0);
+    anExpectedSqRad = 74.0;
+    break;
+  default:
+    aTestID = 0;
+    break;
+  }
+#endif
+
+  const gp_Vec aN1(aDU1.Crossed(aDV1)), aN2(aDU2.Crossed(aDV2));
+  //Tangent vactor to the intersection curve
+  const gp_Vec aCTan(aN1.Crossed(aN2));
+  const Standard_Real aSqMagnFDer = aCTan.SquareMagnitude();
+  
+  if(aSqMagnFDer < aSqSmallValue)
+    return -1.0;
+
+  Standard_Real aDuS1 = 0.0, aDvS1 = 0.0, aDuS2 = 0.0, aDvS2 = 1.0;
+
+  {
+    //This algorithm is described in NonSingularProcessing() function
+    //in ApproxInt_ImpPrmSvSurfaces.gxx file
+    Standard_Real aSqNMagn = aN1.SquareMagnitude();
+    gp_Vec aTgU(aCTan.Crossed(aDU1)), aTgV(aCTan.Crossed(aDV1));
+    Standard_Real aDeltaU = aTgV.SquareMagnitude()/aSqNMagn;
+    Standard_Real aDeltaV = aTgU.SquareMagnitude()/aSqNMagn;
+
+    aDuS1 = Sign(sqrt(aDeltaU), aTgV.Dot(aN1));
+    aDvS1 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN1));
+
+    aSqNMagn = aN2.SquareMagnitude();
+    aTgU.SetXYZ(aCTan.Crossed(aDU2).XYZ());
+    aTgV.SetXYZ(aCTan.Crossed(aDV2).XYZ());
+    aDeltaU = aTgV.SquareMagnitude()/aSqNMagn;
+    aDeltaV = aTgU.SquareMagnitude()/aSqNMagn;
+
+    aDuS2 = Sign(sqrt(aDeltaU), aTgV.Dot(aN2));
+    aDvS2 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN2));
+  }
+
+  //According to "Marching along surface/surface intersection curves
+  //with an adaptive step length"
+  //by Tz.E.Stoyagov
+  //(http://www.sciencedirect.com/science/article/pii/016783969290046R)
+  //we obtain the system:
+  //            {A*a+B*b=F1
+  //            {B*a+C*b=F2
+  //where a and b should be found.
+  //After that, 2nd derivative of the intersection curve can be computed as
+  //            r''(t)=a*aN1+b*aN2.
+
+  const Standard_Real aA = aN1.Dot(aN1), aB = aN1.Dot(aN2), aC = aN2.Dot(aN2);
+  const Standard_Real aDetSyst = aB*aB - aA*aC;
+
+  if(Abs(aDetSyst) < aSmallValue)
+  {//Indetermined system solution
+    return -1.0;
+  }
+
+  const Standard_Real aF1 = aDuS1*aDuS1*aDUU1.Dot(aN1) + 
+                            2.0*aDuS1*aDvS1*aDUV1.Dot(aN1) +
+                            aDvS1*aDvS1*aDVV1.Dot(aN1);
+  const Standard_Real aF2 = aDuS2*aDuS2*aDUU2.Dot(aN2) +
+                            2.0*aDuS2*aDvS2*aDUV2.Dot(aN2) +
+                            aDvS2*aDvS2*aDVV2.Dot(aN2);
+
+  //Principal normal to the intersection curve
+  const gp_Vec aCNorm((aF1*aC-aF2*aB)/aDetSyst*aN1 + (aA*aF2-aF1*aB)/aDetSyst*aN2);
+  const Standard_Real aSqMagnSDer = aCNorm.CrossSquareMagnitude(aCTan);
+
+  if(aSqMagnSDer < aSqSmallValue)
+  {//Intersection curve has null curvature in observed point
+    return Precision::Infinite();
+  }
+
+  //square of curvature radius
+  const Standard_Real aFactSqRad = aSqMagnFDer*aSqMagnFDer*aSqMagnFDer/aSqMagnSDer;
+
+#if 0
+  if(aTestID)
+  {
+    if(Abs(aFactSqRad - anExpectedSqRad) < Precision::Confusion())
+    {
+      printf("OK: Curvature radius is equal to expected (%5.10g)", anExpectedSqRad);
+    }
+    else
+    {
+      printf("Error: Curvature radius is not equal to expected: %5.10g != %5.10g",
+              aFactSqRad, anExpectedSqRad);
+    }
+  }
+#endif
 
+  return sqrt(aFactSqRad);
+}
index 9dc3bad..ec0a78a 100644 (file)
 #ifndef _IntPatch_PointLine_HeaderFile
 #define _IntPatch_PointLine_HeaderFile
 
-#include <Standard.hxx>
+#include <IntPatch_Line.hxx>
 #include <Standard_Type.hxx>
 
-#include <IntPatch_Line.hxx>
-#include <IntPatch_Point.hxx>
-#include <Standard_Boolean.hxx>
-#include <IntSurf_TypeTrans.hxx>
-#include <IntSurf_Situation.hxx>
-#include <Standard_Integer.hxx>
-class Standard_DomainError;
-class Standard_OutOfRange;
 class IntSurf_PntOn2S;
 class IntSurf_LineOn2S;
+class IntPatch_Point;
+class Adaptor3d_HSurface;
 
-
-class IntPatch_PointLine;
 DEFINE_STANDARD_HANDLE(IntPatch_PointLine, IntPatch_Line)
 
 //! Definition of an intersection line between two
@@ -42,7 +34,6 @@ DEFINE_STANDARD_HANDLE(IntPatch_PointLine, IntPatch_Line)
 //! defined in the class WLine or RLine (Restriction line).
 class IntPatch_PointLine : public IntPatch_Line
 {
-
 public:
 
   //! Adds a vertex in the list. If theIsPrepend == TRUE the new
@@ -76,6 +67,15 @@ public:
   //! Returns set of intersection points
   Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const = 0;
 
+  //! Returns the radius of curvature of
+  //! the intersection line in given point.
+  //! Returns negative value if computation is not possible.
+  Standard_EXPORT static Standard_Real
+            CurvatureRadiusOfIntersLine(const Handle(Adaptor3d_HSurface)& theS1,
+                                        const Handle(Adaptor3d_HSurface)& theS2,
+                                        const IntSurf_PntOn2S& theUVPoint);
+
+
   DEFINE_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line)
 
 protected:
diff --git a/src/IntPatch/IntPatch_SpecPntType.hxx b/src/IntPatch/IntPatch_SpecPntType.hxx
new file mode 100644 (file)
index 0000000..40ccced
--- /dev/null
@@ -0,0 +1,34 @@
+//! Created on: 2016-06-03
+//! Created by: NIKOLAI BUKHALOV
+//! Copyright (c) 2016 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.
+
+#ifndef _IntPatch_SpecPntType_HeaderFile
+#define _IntPatch_SpecPntType_HeaderFile
+
+//! This enum describe the  different kinds of
+//! special (singular) points of Surface-Surface
+//! intersection algorithm. Such as pole of sphere,
+//! apex of cone, point on U- or V-seam etc.
+
+enum IntPatch_SpecPntType
+{
+  IntPatch_SPntNone,
+  IntPatch_SPntSeamU,
+  IntPatch_SPntSeamV,
+  IntPatch_SPntSeamUV,
+  IntPatch_SPntPoleSeamU,
+  IntPatch_SPntPole
+};
+
+#endif // _IntPatch_SpecPntType_HeaderFile
\ No newline at end of file
diff --git a/src/IntPatch/IntPatch_SpecialPoints.cxx b/src/IntPatch/IntPatch_SpecialPoints.cxx
new file mode 100644 (file)
index 0000000..81d4130
--- /dev/null
@@ -0,0 +1,717 @@
+//! Created on: 2016-06-03
+//! Created by: NIKOLAI BUKHALOV
+//! Copyright (c) 2016 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_SpecialPoints.hxx>
+
+#include <Adaptor3d_HSurface.hxx>
+#include <Extrema_ExtPS.hxx>
+#include <Extrema_GenLocateExtPS.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <IntPatch_Point.hxx>
+#include <IntSurf.hxx>
+#include <IntSurf_PntOn2S.hxx>
+#include <Standard_TypeMismatch.hxx>
+#include <math_FunctionSetRoot.hxx>
+#include <math_FunctionSetWithDerivatives.hxx>
+#include <math_Matrix.hxx>
+
+// The function for searching intersection point, which 
+// lies in the seam-edge of the quadric definetely.
+class FuncPreciseSeam: public math_FunctionSetWithDerivatives
+{
+public:
+  FuncPreciseSeam(const Handle(Adaptor3d_HSurface)& theQSurf, // quadric
+                  const Handle(Adaptor3d_HSurface)& thePSurf, // another surface
+                  const Standard_Boolean isTheUSeam): 
+        myQSurf(theQSurf),
+        myPSurf(thePSurf),
+        mySeamCoordInd(isTheUSeam? 1 : 0) // Defines, U- or V-seam is used
+  {
+  };
+  
+  virtual Standard_Integer NbVariables() const
+  {
+    return 3;
+  };
+
+  virtual Standard_Integer NbEquations() const
+  {
+    return 3;
+  }
+
+  virtual Standard_Boolean Value(const math_Vector& theX,
+                                 math_Vector& theF)
+  {
+    try
+    {
+      const Standard_Integer anIndX = theX.Lower(), anIndF = theF.Lower();
+      Standard_Real aUV[] = {0.0, 0.0};
+      aUV[mySeamCoordInd] = theX(anIndX+2);
+      const gp_Pnt aP1(myPSurf->Value(theX(anIndX), theX(anIndX+1)));
+      const gp_Pnt aP2(myQSurf->Value(aUV[0], aUV[1]));
+
+      (aP1.XYZ()-aP2.XYZ()).Coord(theF(anIndF), theF(anIndF+1), theF(anIndF+2));
+    }
+    catch(Standard_Failure)
+    {
+      return Standard_False;
+    }
+
+    return Standard_True;
+  };
+
+  virtual Standard_Boolean Derivatives(const math_Vector& theX,
+                                       math_Matrix& theD)
+  {
+    try
+    {
+      const Standard_Integer anIndX = theX.Lower(),
+                             anIndRD = theD.LowerRow(),
+                             anIndCD = theD.LowerCol();
+      Standard_Real aUV[] = {0.0, 0.0};
+      aUV[mySeamCoordInd] = theX(anIndX+2);
+
+      gp_Pnt aPt;
+
+      //0 for U-coordinate, 1 - for V one
+      gp_Vec aD1[2], aD2[2];
+      myPSurf->D1(theX(anIndX), theX(anIndX+1), aPt, aD1[0], aD1[1]);
+      myQSurf->D1(aUV[0], aUV[1], aPt, aD2[0], aD2[1]);
+
+      // d/dX1
+      aD1[0].Coord(theD(anIndRD, anIndCD),
+                      theD(anIndRD+1, anIndCD), theD(anIndRD+2, anIndCD));
+
+      // d/dX2
+      aD1[1].Coord(theD(anIndRD, anIndCD+1),
+                      theD(anIndRD+1, anIndCD+1), theD(anIndRD+2, anIndCD+1));
+
+      // d/dX3
+      aD2[mySeamCoordInd].Reversed().Coord(theD(anIndRD, anIndCD+2),
+                                theD(anIndRD+1, anIndCD+2), theD(anIndRD+2, anIndCD+2));
+    }
+    catch(Standard_Failure)
+    {
+      return Standard_False;
+    }
+
+    return Standard_True;
+  };
+
+  virtual Standard_Boolean Values (const math_Vector& theX,
+                                   math_Vector& theF,
+                                   math_Matrix& theD)
+  {
+    if(!Value(theX, theF))
+      return Standard_False;
+
+    if(!Derivatives(theX, theD))
+      return Standard_False;
+
+    return Standard_True;
+  }
+
+protected:
+  FuncPreciseSeam operator=(FuncPreciseSeam&);
+
+private:
+  const Handle(Adaptor3d_HSurface)& myQSurf;
+  const Handle(Adaptor3d_HSurface)& myPSurf;
+
+  // 1 for U-coordinate, 0 - for V one. 
+  const Standard_Integer mySeamCoordInd;
+};
+
+//=======================================================================
+//function : IsPointOnSurface
+//purpose  : Checks if thePt is in theSurf (with given tolerance).
+//            Returns the foot of projection (theProjPt) and its parameters
+//           on theSurf.
+//=======================================================================
+static Standard_Boolean IsPointOnSurface(const Handle(Adaptor3d_HSurface)& theSurf,
+                                         const gp_Pnt& thePt,
+                                         const Standard_Real theTol,
+                                         gp_Pnt& theProjPt,
+                                         Standard_Real& theUpar,
+                                         Standard_Real& theVpar)
+{
+  Standard_Boolean aRetVal = Standard_False;
+
+  switch(theSurf->GetType())
+  {
+  case GeomAbs_Plane:
+  case GeomAbs_Cylinder:
+  case GeomAbs_Cone:
+  case GeomAbs_Sphere:
+  case GeomAbs_Torus:
+  case GeomAbs_SurfaceOfExtrusion:
+  case GeomAbs_SurfaceOfRevolution:
+    {
+      Extrema_ExtPS anExtr(thePt, theSurf->Surface(), theSurf->UResolution(theTol),
+                              theSurf->VResolution(theTol), Extrema_ExtFlag_MIN);
+      if(!anExtr.IsDone() || (anExtr.NbExt() < 1))
+      {
+        aRetVal = Standard_False;
+      }
+      else
+      {
+        Standard_Integer anExtrIndex = 1;
+        Standard_Real aSqDistMin = anExtr.SquareDistance(anExtrIndex);
+        for(Standard_Integer i = anExtrIndex + 1; i <= anExtr.NbExt(); i++)
+        {
+          const Standard_Real aSqD = anExtr.SquareDistance(i);
+          if(aSqD < aSqDistMin)
+          {
+            aSqDistMin = aSqD;
+            anExtrIndex = i;
+          }
+        }
+
+        if(aSqDistMin > theTol*theTol)
+        {
+          aRetVal = Standard_False;
+        }
+        else
+        {
+          theProjPt.SetXYZ(anExtr.Point(anExtrIndex).Value().XYZ());
+          anExtr.Point(anExtrIndex).Parameter(theUpar, theVpar);
+          aRetVal = Standard_True;
+        }
+      }
+    }
+    break;
+  default:
+    {
+      Extrema_GenLocateExtPS anExtr(theSurf->Surface());
+      anExtr.Perform(thePt, theUpar, theVpar);
+      if(!anExtr.IsDone() || (anExtr.SquareDistance() > theTol*theTol))
+      {
+        aRetVal = Standard_False;
+      }
+      else
+      {
+        anExtr.Point().Parameter(theUpar, theVpar);
+        theProjPt.SetXYZ(anExtr.Point().Value().XYZ());
+        aRetVal = Standard_True;
+      }
+    }
+    break;
+  }
+
+  return aRetVal;
+}
+
+//=======================================================================
+//function : AddCrossUVIsoPoint
+//purpose  : theQSurf is the surface possibly containing special point, 
+//            thePSurf is another surface to intersect.
+//=======================================================================
+Standard_Boolean IntPatch_SpecialPoints::
+                      AddCrossUVIsoPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                         const Handle(Adaptor3d_HSurface)& thePSurf,
+                                         const IntSurf_PntOn2S& theRefPt,
+                                         const Standard_Real theTol,
+                                         IntSurf_PntOn2S& theAddedPoint,
+                                         const Standard_Boolean theIsReversed)
+{
+  Standard_Real anArrOfPeriod[4] = {0.0, 0.0, 0.0, 0.0};
+  IntSurf::SetPeriod(theIsReversed ? thePSurf : theQSurf,
+                     theIsReversed ? theQSurf : thePSurf, anArrOfPeriod);
+
+  gp_Pnt aPQuad;
+
+  //Not quadric point
+  Standard_Real aU0 = 0.0, aV0 = 0.0;
+  if(theIsReversed)
+    theRefPt.ParametersOnS1(aU0, aV0);
+  else
+    theRefPt.ParametersOnS2(aU0, aV0);
+
+  //Quadric point
+  Standard_Real aUquad = 0.0, aVquad = 0.0; 
+
+  theQSurf->D0(aUquad, aVquad, aPQuad);
+
+  Extrema_GenLocateExtPS anExtr(thePSurf->Surface());
+  anExtr.Perform(aPQuad, aU0, aV0);
+
+  if(!anExtr.IsDone())
+  {
+    return Standard_False;
+  }
+
+  if(anExtr.SquareDistance() > theTol*theTol)
+  {
+    return Standard_False;
+  }
+
+  anExtr.Point().Parameter(aU0, aV0);
+  gp_Pnt aP0(anExtr.Point().Value());
+  
+  if(theIsReversed)
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
+  else
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+
+  AdjustPointAndVertex(theRefPt, anArrOfPeriod, theAddedPoint);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : AddPointOnUorVIso
+//purpose  : theQSurf is the surface possibly containing special point, 
+//            thePSurf is another surface to intersect.
+//=======================================================================
+Standard_Boolean IntPatch_SpecialPoints::
+                      AddPointOnUorVIso(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                        const Handle(Adaptor3d_HSurface)& thePSurf,
+                                        const IntSurf_PntOn2S& theRefPt,
+                                        const Standard_Boolean theIsU,
+                                        const math_Vector& theToler,
+                                        const math_Vector& theInitPoint,
+                                        const math_Vector& theInfBound,
+                                        const math_Vector& theSupBound,
+                                        IntSurf_PntOn2S& theAddedPoint,
+                                        const Standard_Boolean theIsReversed)
+{
+  Standard_Real anArrOfPeriod[4] = {0.0, 0.0, 0.0, 0.0};
+  IntSurf::SetPeriod(theIsReversed ? thePSurf : theQSurf,
+                     theIsReversed ? theQSurf : thePSurf, anArrOfPeriod);
+
+  FuncPreciseSeam aF(theQSurf, thePSurf, theIsU);
+
+  math_FunctionSetRoot aSRF(aF, theToler);
+  aSRF.Perform(aF, theInitPoint, theInfBound, theSupBound);
+
+  if(!aSRF.IsDone())
+  {
+    return Standard_False;
+  }
+
+  math_Vector aRoots(theInitPoint.Lower(), theInitPoint.Upper());
+  aSRF.Root(aRoots);
+
+  //On parametric
+  Standard_Real aU0 = aRoots(1), aV0 = aRoots(2);
+
+  //On quadric
+  Standard_Real aUquad = theIsU ? 0.0 : aRoots(3);
+  Standard_Real aVquad = theIsU ? aRoots(3) : 0.0; 
+  const gp_Pnt aPQuad(theQSurf->Value(aUquad, aVquad));
+  const gp_Pnt aP0(thePSurf->Value(aU0, aV0));
+
+  if(theIsReversed)
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
+  else
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+
+  AdjustPointAndVertex(theRefPt, anArrOfPeriod, theAddedPoint);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : AddSingularPole
+//purpose  : theQSurf is the surface possibly containing special point, 
+//            thePSurf is another surface to intersect.
+//           Returns TRUE, if the pole is an intersection point.
+//=======================================================================
+Standard_Boolean IntPatch_SpecialPoints::
+                      AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                      const Handle(Adaptor3d_HSurface)& thePSurf,
+                                      const IntSurf_PntOn2S& thePtIso,
+                                      const Standard_Real theTol,
+                                      IntPatch_Point& theVertex,
+                                      IntSurf_PntOn2S& theAddedPoint,                                      
+                                      const Standard_Boolean theIsReversed,
+                                      const Standard_Boolean theIsReqRefCheck)
+{
+  const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;
+  const Standard_Real aUqPeriod = theQSurf->IsUPeriodic() ? theQSurf->UPeriod() : 0.0;
+  const Standard_Real aVpPeriod = thePSurf->IsVPeriodic() ? thePSurf->VPeriod() : 0.0;
+  const Standard_Real aVqPeriod = theQSurf->IsVPeriodic() ? theQSurf->VPeriod() : 0.0;
+
+  const Standard_Real anArrOfPeriod[4] = {theIsReversed? aUpPeriod : aUqPeriod,
+                                          theIsReversed? aVpPeriod : aVqPeriod,
+                                          theIsReversed? aUqPeriod : aUpPeriod,
+                                          theIsReversed? aVqPeriod : aVpPeriod};
+
+  //On parametric
+  Standard_Real aU0 = 0.0, aV0 = 0.0;
+  //aPQuad is Pole
+  gp_Pnt aPQuad, aP0;
+  Standard_Real aUquad = 0.0, aVquad = 0.0;
+  if(theIsReversed)
+    theVertex.Parameters(aU0, aV0, aUquad, aVquad);
+  else
+    theVertex.Parameters(aUquad, aVquad, aU0, aV0);
+
+  aUquad = 0.0;
+
+  if(theQSurf->GetType() == GeomAbs_Sphere)
+  {
+    aVquad = Sign(M_PI_2, aVquad);
+  }
+  else if(theQSurf->GetType() == GeomAbs_Cone)
+  {
+    const gp_Cone aCo = theQSurf->Cone();
+    const Standard_Real aRadius = aCo.RefRadius();
+    const Standard_Real aSemiAngle = aCo.SemiAngle();
+    aVquad = -aRadius / sin(aSemiAngle);
+  }
+  else
+  {
+    Standard_TypeMismatch::Raise( "IntPatch_SpecialPoints::AddSingularPole(),"
+                                  "Unsupported quadric with Pole");
+  }
+
+  theQSurf->D0(aUquad, aVquad, aPQuad);
+
+  if (theIsReqRefCheck && (aPQuad.SquareDistance(theVertex.Value()) >= theTol*theTol))
+  {
+    return Standard_False;
+  }
+
+  if(!IsPointOnSurface(thePSurf, aPQuad, theTol, aP0, aU0, aV0))
+  {
+    return Standard_False;
+  }
+
+  //Pole is an intersection point
+  //(lies in the quadric and the parametric surface)
+
+  if(theIsReversed)
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
+  else
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+
+  Standard_Boolean isSame = Standard_False;
+
+  if (theAddedPoint.IsSame(theVertex.PntOn2S(), Precision::Confusion()))
+  {
+    isSame = Standard_True;
+  }
+
+  //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);
+
+  //Transforms parametric surface in coordinate-system of the quadric
+  gp_Trsf aTr;
+  aTr.SetTransformation((theQSurf->GetType() == GeomAbs_Sphere) ?
+                          theQSurf->Sphere().Position() :
+                                      theQSurf->Cone().Position());
+
+  //Derivatives of transformed thePSurf
+  aVecDu.Transform(aTr);
+  aVecDv.Transform(aTr);
+
+  Standard_Boolean isIsoChoosen = Standard_False;
+
+  if(theQSurf->GetType() == 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()) < Precision::PConfusion()) &&
+        (Abs(aVecDv.Z()) < Precision::PConfusion()))
+    {
+      //Example of this case is an intersection of 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).
+      //Another reason is that we have tangent zone around the pole
+      //(see bug #26576).
+      //Computation of correct value of aUquad is impossible.
+      //Therefore, (in oreder to return something) we will consider
+      //the intersection line goes along some isoline in neighbourhood
+      //of the pole.
+
+#ifdef INTPATCH_ADDSPECIALPOINTS_DEBUG
+      cout << "Cannot find UV-coordinate for quadric in the pole."
+        " See considered comment above. IntPatch_AddSpecialPoints.cxx,"
+        " AddSingularPole(...)" << endl;
+#endif
+      Standard_Real aUIso = 0.0, aVIso = 0.0;
+      if(theIsReversed)
+        thePtIso.ParametersOnS2(aUIso, aVIso);
+      else
+        thePtIso.ParametersOnS1(aUIso, aVIso);
+
+      aUquad = aUIso;
+      isIsoChoosen = Standard_True;
+    }
+    else
+    {
+      if(Abs(aVecDu.Z()) > Abs(aVecDv.Z()))
+      {
+        const Standard_Real aDusDvs = aVecDv.Z()/aVecDu.Z();
+        aV1.SetCoord( aVecDu.X()*aDusDvs - aVecDv.X(),
+                      aVecDu.Y()*aDusDvs - aVecDv.Y());
+      }
+      else
+      {
+        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);
+    }
+  }
+  else //if(theQSurf->GetType() == GeomAbs_Cone)
+  {
+    // This case is not processed. However,
+    // it can be done using the same algorithm
+    // as for sphere (formulas will be different).
+    return Standard_False;
+  }
+
+  if(theIsReversed)
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aU0, aV0, aUquad, aVquad);
+  else
+    theAddedPoint.SetValue(0.5*(aP0.XYZ() + aPQuad.XYZ()), aUquad, aVquad, aU0, aV0);
+
+  if (isSame)
+  {
+    theVertex.SetValue(theAddedPoint);
+    return Standard_True;
+  }
+
+  if (!isIsoChoosen)
+  {
+    AdjustPointAndVertex(theVertex.PntOn2S(), anArrOfPeriod, theAddedPoint);
+  }
+  else
+  {
+    theVertex.SetValue(theAddedPoint);
+  }
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : ContinueAfterSpecialPoint
+//purpose  : 
+//=======================================================================
+Standard_Boolean IntPatch_SpecialPoints::
+                  ContinueAfterSpecialPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                            const Handle(Adaptor3d_HSurface)& thePSurf,
+                                            const IntSurf_PntOn2S& theRefPt,
+                                            const IntPatch_SpecPntType theSPType,
+                                            const Standard_Real theTol2D,
+                                            IntSurf_PntOn2S& theNewPoint,
+                                            const Standard_Boolean theIsReversed)
+{
+  if(theSPType == IntPatch_SPntNone)
+    return Standard_False;
+
+  //If the last point of the line is the pole of the quadric.
+  //In this case, 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/apex, 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).
+    
+  if(theNewPoint.IsSame(theRefPt, Precision::Confusion(), theTol2D))
+  {
+    return Standard_False;
+  }
+
+  //Here, in case of pole/apex adding, we forbid "jumping" between two neighbor
+  //Walking-point with step greater than pi/4
+  const Standard_Real aPeriod = (theSPType == IntPatch_SPntPole)? M_PI_2 : 2.0*M_PI;
+
+  const Standard_Real aUpPeriod = thePSurf->IsUPeriodic() ? thePSurf->UPeriod() : 0.0;
+  const Standard_Real aUqPeriod = theQSurf->IsUPeriodic() ? aPeriod : 0.0;
+  const Standard_Real aVpPeriod = thePSurf->IsVPeriodic() ? thePSurf->VPeriod() : 0.0;
+  const Standard_Real aVqPeriod = theQSurf->IsVPeriodic() ? aPeriod : 0.0;
+
+  const Standard_Real anArrOfPeriod[4] = {theIsReversed? aUpPeriod : aUqPeriod,
+                                          theIsReversed? aVpPeriod : aVqPeriod,
+                                          theIsReversed? aUqPeriod : aUpPeriod,
+                                          theIsReversed? aVqPeriod : aVpPeriod};
+
+  AdjustPointAndVertex(theRefPt, anArrOfPeriod, theNewPoint);
+  return Standard_True;
+}
+
+//=======================================================================
+//function : AdjustPointAndVertex
+//purpose  : 
+//=======================================================================
+void IntPatch_SpecialPoints::
+                AdjustPointAndVertex(const IntSurf_PntOn2S &theRefPoint,
+                                     const Standard_Real theArrPeriods[4],
+                                     IntSurf_PntOn2S &theNewPoint,
+                                     IntPatch_Point* const theVertex)
+{
+  Standard_Real aRefPar[2] = {0.0, 0.0};
+  Standard_Real aPar[4] = {0.0, 0.0, 0.0, 0.0};
+  theNewPoint.Parameters(aPar[0], aPar[1], aPar[2], aPar[3]);
+
+  for(Standard_Integer i = 0; i < 4; i++)
+  {
+    if(theArrPeriods[i] == 0)
+      continue;
+
+    const Standard_Real aPeriod = theArrPeriods[i], aHalfPeriod = 0.5*theArrPeriods[i];
+
+    if(i < 2)
+    {// 1st surface is used
+      theRefPoint.ParametersOnS1(aRefPar[0], aRefPar[1]);
+    }
+    else
+    {
+      theRefPoint.ParametersOnS2(aRefPar[0], aRefPar[1]);
+    }
+
+    const Standard_Integer aRefInd = i%2;
+
+    {
+      Standard_Real aDeltaPar = aRefPar[aRefInd]-aPar[i];
+      const Standard_Real anIncr = Sign(aPeriod, aDeltaPar);
+      while((aDeltaPar > aHalfPeriod) || (aDeltaPar < -aHalfPeriod))
+      {
+        aPar[i] += anIncr;
+        aDeltaPar = aRefPar[aRefInd]-aPar[i];
+      }
+    }
+  }
+
+  if(theVertex)
+    (*theVertex).SetParameters(aPar[0], aPar[1], aPar[2], aPar[3]);
+
+  theNewPoint.SetValue(aPar[0], aPar[1], aPar[2], aPar[3]);
+}
+
diff --git a/src/IntPatch/IntPatch_SpecialPoints.hxx b/src/IntPatch/IntPatch_SpecialPoints.hxx
new file mode 100644 (file)
index 0000000..cfd2f74
--- /dev/null
@@ -0,0 +1,125 @@
+//! Created on: 2016-06-03
+//! Created by: NIKOLAI BUKHALOV
+//! Copyright (c) 2016 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.
+
+#ifndef _IntPatch_SpecialPoints_HeaderFile
+#define _IntPatch_SpecialPoints_HeaderFile
+
+//! Contains methods to add some special points
+//! (such as apex of cone, pole of sphere,
+//! point on surface boundary etc.) in the intersection line.
+
+#include <IntPatch_SpecPntType.hxx>
+#include <Standard_Handle.hxx>
+
+class Adaptor3d_HSurface;
+class IntPatch_Point;
+class IntSurf_PntOn2S;
+class math_Vector;
+
+class IntPatch_SpecialPoints
+{
+public:
+  //! Adds the point defined as intersection
+  //! of two isolines (U = 0 and V = 0) on theQSurf in theLine.
+  //! theRefPt is used to correct adjusting parameters.
+  //! If theIsReversed is TRUE then theQSurf correspond to the 
+  //! second (otherwise, the first) surface while forming
+  //! intersection point IntSurf_PntOn2S.
+  Standard_EXPORT static Standard_Boolean 
+                      AddCrossUVIsoPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                         const Handle(Adaptor3d_HSurface)& thePSurf,
+                                         const IntSurf_PntOn2S& theRefPt,
+                                         const Standard_Real theTol3d,
+                                         IntSurf_PntOn2S& theAddedPoint,
+                                         const Standard_Boolean theIsReversed
+                                                                = Standard_False);
+
+  //! Adds the point lain strictly in the isoline U = 0 or V = 0 of theQSurf,
+  //! in theLine.
+  //! theRefPt is used to correct adjusting parameters.
+  //! If theIsReversed is TRUE then theQSurf corresponds to the 
+  //! second (otherwise, the first) surface while forming
+  //! intersection point IntSurf_PntOn2S.  
+  Standard_EXPORT static Standard_Boolean
+                      AddPointOnUorVIso(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                        const Handle(Adaptor3d_HSurface)& thePSurf,
+                                        const IntSurf_PntOn2S& theRefPt,
+                                        const Standard_Boolean theIsU,
+                                        const math_Vector& theToler,
+                                        const math_Vector& theInitPoint,
+                                        const math_Vector& theInfBound,
+                                        const math_Vector& theSupBound,
+                                        IntSurf_PntOn2S& theAddedPoint,
+                                        const Standard_Boolean theIsReversed
+                                                                = Standard_False);
+
+  //! Computes the pole of sphere to add it in the intersection line.
+  //! Stores the result in theAddedPoint variable (does not add in the line).
+  //! At that, cone and sphere (with singularity) must be set in theQSurf parameter.
+  //! By default (if theIsReversed == FALSE), theQSurf is the first surface of the
+  //! Walking line. If it is not, theIsReversed parameter must be set to TRUE.
+  //! theIsReqRefCheck is TRUE if and only if 3D-point of theRefPt must be pole or apex
+  //! for check (e.g. if it is vertex).
+  //! thePtIso is the reference point for obtaining isoline where must be placed the Apex/Pole.
+  //!
+  //! ATTENTION!!!
+  //!   theVertex must be initialized before calling the method .
+  Standard_EXPORT static Standard_Boolean
+                      AddSingularPole(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                      const Handle(Adaptor3d_HSurface)& thePSurf,
+                                      const IntSurf_PntOn2S& thePtIso,
+                                      const Standard_Real theTol3d,
+                                      IntPatch_Point& theVertex,
+                                      IntSurf_PntOn2S& theAddedPoint,                                      
+                                      const Standard_Boolean theIsReversed =
+                                                                Standard_False,
+                                      const Standard_Boolean theIsReqRefCheck = 
+                                                                Standard_False);
+
+  //! Special point has already been added in the line. Now, we need in correct
+  //! prolongation of the line or in start new line. This function returns new point.
+  //!
+  //! ATTENTION!!!
+  //!   theNewPoint is not only Output parameter. It is Input/Output one. I.e. 
+  //! theNewPoint is reference point together with theRefPt.
+  Standard_EXPORT static Standard_Boolean
+                    ContinueAfterSpecialPoint(const Handle(Adaptor3d_HSurface)& theQSurf,
+                                              const Handle(Adaptor3d_HSurface)& thePSurf,
+                                              const IntSurf_PntOn2S& theRefPt,
+                                              const IntPatch_SpecPntType theSPType,
+                                              const Standard_Real theTol2D,
+                                              IntSurf_PntOn2S& theNewPoint,
+                                              const Standard_Boolean theIsReversed
+                                                                = Standard_False);
+
+  //! Sets theNewPoint parameters in 2D-space the closest to
+  //! theRefPoint with help of adding/subtracting corresponding periods.
+  //! theArrPeriods must be filled as follows:
+  //! {<U-period of 1st surface>, <V-period of 1st surface>,
+  //!  <U-period of 2nd surface>, <V-period of 2nd surface>}.
+  //! If theVertex != 0 then its parameters will befilled as
+  //! corresponding parameters of theNewPoint.
+  //!
+  //! ATTENTION!!!
+  //!   theNewPoint is not only Output parameter. It is Input/Output one. I.e. 
+  //! theNewPoint is reference point together with theRefPt.
+  Standard_EXPORT static void 
+                      AdjustPointAndVertex(const IntSurf_PntOn2S &theRefPoint,
+                                           const Standard_Real theArrPeriods[4],
+                                           IntSurf_PntOn2S &theNewPoint,
+                                           IntPatch_Point* const theVertex = 0);
+};
+
+#endif // _IntPatch_AddSpecialPoints_HeaderFile
index bb09d22..0f30e2a 100644 (file)
 #include <Adaptor3d_HSurface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
 #include <ElCLib.hxx>
+#include <ElSLib.hxx>
+#include <IntPatch_SpecialPoints.hxx>
 
 // It is pure empirical value.
 const Standard_Real IntPatch_WLineTool::myMaxConcatAngle = M_PI/6;
 
 //Bit-mask is used for information about 
 //the operation made in
-//IntPatch_WLineTool::ExtendTwoWlinesToEachOther() method.
+//IntPatch_WLineTool::ExtendTwoWLines(...) method.
 enum
 {
   IntPatchWT_EnAll = 0x00,
@@ -32,6 +34,13 @@ enum
   IntPatchWT_DisFirstFirst = 0x08
 };
 
+enum IntPatchWT_WLsConnectionType
+{
+  IntPatchWT_NotConnected,
+  IntPatchWT_Singular,
+  IntPatchWT_EachOther
+};
+
 //=======================================================================
 //function : MinMax
 //purpose  : Replaces theParMIN = MIN(theParMIN, theParMAX),
@@ -668,27 +677,6 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
 }
 
 //=======================================================================
-//function : AbjustPeriodicToPrevPoint
-//purpose  : Returns theCurrentParam in order to the distance betwen 
-//            theRefParam and theCurrentParam is less than 0.5*thePeriod.
-//=======================================================================
-static void AbjustPeriodicToPrevPoint(const Standard_Real theRefParam,
-                                      const Standard_Real thePeriod,
-                                      Standard_Real& theCurrentParam)
-{
-  if(thePeriod == 0.0)
-    return;
-
-  Standard_Real aDeltaPar = 2.0*(theRefParam - theCurrentParam);
-  const Standard_Real anIncr = Sign(thePeriod, aDeltaPar);
-  while(Abs(aDeltaPar) > thePeriod)
-  {
-    theCurrentParam += anIncr;
-    aDeltaPar = 2.0*(theRefParam-theCurrentParam);
-  }
-}
-
-//=======================================================================
 //function : IsIntersectionPoint
 //purpose  : Returns True if thePmid is intersection point
 //            between theS1 and theS2 with given tolerance.
@@ -696,31 +684,73 @@ static void AbjustPeriodicToPrevPoint(const Standard_Real theRefParam,
 //            will be recomputed and returned.
 //=======================================================================
 static Standard_Boolean IsIntersectionPoint(const gp_Pnt& thePmid,
-                                            const IntSurf_Quadric& theS1,
-                                            const IntSurf_Quadric& theS2,
+                                            const Handle(Adaptor3d_HSurface)& theS1,
+                                            const Handle(Adaptor3d_HSurface)& theS2,
                                             const IntSurf_PntOn2S& theRefPt,
                                             const Standard_Real theTol,
-                                            const Standard_Real theU1Period,
-                                            const Standard_Real theU2Period,
-                                            const Standard_Real theV1Period,
-                                            const Standard_Real theV2Period,
-                                            Standard_Real &theU1,
-                                            Standard_Real &theV1,
-                                            Standard_Real &theU2,
-                                            Standard_Real &theV2)
+                                            const Standard_Real* const theArrPeriods,
+                                            IntSurf_PntOn2S& theNewPt)
 {
-  Standard_Real aU1Ref = 0.0, aV1Ref = 0.0, aU2Ref = 0.0, aV2Ref = 0.0;
-  theRefPt.Parameters(aU1Ref, aV1Ref, aU2Ref, aV2Ref);
-  theS1.Parameters(thePmid, theU1, theV1);
-  theS2.Parameters(thePmid, theU2, theV2);
+  Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
+  
+  switch(theS1->GetType())
+  {
+  case GeomAbs_Plane:
+    ElSLib::Parameters(theS1->Plane(), thePmid, aU1, aV1);
+    break;
+
+  case GeomAbs_Cylinder:
+    ElSLib::Parameters(theS1->Cylinder(), thePmid, aU1, aV1);
+    break;
+
+  case GeomAbs_Sphere:
+    ElSLib::Parameters(theS1->Sphere(), thePmid, aU1, aV1);
+    break;
+
+  case GeomAbs_Cone:
+    ElSLib::Parameters(theS1->Cone(), thePmid, aU1, aV1);
+    break;
+
+  case GeomAbs_Torus:
+    ElSLib::Parameters(theS1->Torus(), thePmid, aU1, aV1);
+    break;
+
+  default:
+    return Standard_False;
+  }
+
+  switch(theS2->GetType())
+  {
+  case GeomAbs_Plane:
+    ElSLib::Parameters(theS2->Plane(), thePmid, aU2, aV2);
+    break;
+
+  case GeomAbs_Cylinder:
+    ElSLib::Parameters(theS2->Cylinder(), thePmid, aU2, aV2);
+    break;
+
+  case GeomAbs_Sphere:
+    ElSLib::Parameters(theS2->Sphere(), thePmid, aU2, aV2);
+    break;
 
-  AbjustPeriodicToPrevPoint(aU1Ref, theU1Period, theU1);
-  AbjustPeriodicToPrevPoint(aV1Ref, theV1Period, theV1);
-  AbjustPeriodicToPrevPoint(aU2Ref, theU2Period, theU2);
-  AbjustPeriodicToPrevPoint(aV2Ref, theV2Period, theV2);
+  case GeomAbs_Cone:
+    ElSLib::Parameters(theS2->Cone(), thePmid, aU2, aV2);
+    break;
 
-  const gp_Pnt aP1(theS1.Value(theU1, theV1));
-  const gp_Pnt aP2(theS2.Value(theU2, theV2));
+  case GeomAbs_Torus:
+    ElSLib::Parameters(theS2->Torus(), thePmid, aU2, aV2);
+    break;
+
+  default:
+    return Standard_False;
+  }
+
+  theNewPt.SetValue(thePmid, aU1, aV1, aU2, aV2);
+
+  IntPatch_SpecialPoints::AdjustPointAndVertex(theRefPt, theArrPeriods, theNewPt);
+
+  const gp_Pnt aP1(theS1->Value(aU1, aV1));
+  const gp_Pnt aP2(theS2->Value(aU2, aV2));
 
   return (aP1.SquareDistance(aP2) <= theTol*theTol);
 }
@@ -809,10 +839,7 @@ static void ExtendLast(const Handle(IntPatch_WLine)& theWline,
 static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1,
                                       const Bnd_Box2d& theBoxS2,
                                       const IntSurf_PntOn2S &thePOn2S,
-                                      const Standard_Real theU1Period,
-                                      const Standard_Real theU2Period,
-                                      const Standard_Real theV1Period,
-                                      const Standard_Real theV2Period)
+                                      const Standard_Real* const theArrPeriods)
 {
   Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
   Standard_Real aU1min = 0.0, aU1max = 0.0, aV1min = 0.0, aV1max = 0.0;
@@ -823,10 +850,10 @@ static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1,
   theBoxS1.Get(aU1min, aV1min, aU1max, aV1max);
   theBoxS2.Get(aU2min, aV2min, aU2max, aV2max);
 
-  aU1 = ElCLib::InPeriod(aU1, aU1min, aU1min + theU1Period);
-  aV1 = ElCLib::InPeriod(aV1, aV1min, aV1min + theV1Period);
-  aU2 = ElCLib::InPeriod(aU2, aU2min, aU2min + theU2Period);
-  aV2 = ElCLib::InPeriod(aV2, aV2min, aV2min + theV2Period);
+  aU1 = ElCLib::InPeriod(aU1, aU1min, aU1min + theArrPeriods[0]);
+  aV1 = ElCLib::InPeriod(aV1, aV1min, aV1min + theArrPeriods[1]);
+  aU2 = ElCLib::InPeriod(aU2, aU2min, aU2min + theArrPeriods[2]);
+  aV2 = ElCLib::InPeriod(aV2, aV2min, aV2min + theArrPeriods[3]);
 
   return (theBoxS1.IsOut(gp_Pnt2d(aU1, aV1)) ||
           theBoxS2.IsOut(gp_Pnt2d(aU2, aV2)));
@@ -835,84 +862,138 @@ static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1,
 //=======================================================================
 //function : CheckArgumentsToExtend
 //purpose  : Check if extending is possible
-//            (see IntPatch_WLineTool::ExtendTwoWlinesToEachOther)
+//            (see IntPatch_WLineTool::ExtendTwoWLines)
 //=======================================================================
-Standard_Boolean CheckArgumentsToExtend(const IntSurf_Quadric& theS1,
-                                        const IntSurf_Quadric& theS2,
-                                        const IntSurf_PntOn2S& thePtWL1,
-                                        const IntSurf_PntOn2S& thePtWL2,
-                                        IntSurf_PntOn2S& theNewPoint,
-                                        const gp_Vec& theVec1,
-                                        const gp_Vec& theVec2,
-                                        const gp_Vec& theVec3,
-                                        const Bnd_Box2d& theBoxS1,
-                                        const Bnd_Box2d& theBoxS2,
-                                        const Standard_Real theToler3D,
-                                        const Standard_Real theU1Period,
-                                        const Standard_Real theU2Period,
-                                        const Standard_Real theV1Period,
-                                        const Standard_Real theV2Period)
+static IntPatchWT_WLsConnectionType
+                    CheckArgumentsToExtend(const Handle(Adaptor3d_HSurface)& theS1,
+                                           const Handle(Adaptor3d_HSurface)& theS2,
+                                           const IntSurf_PntOn2S& thePtWL1,
+                                           const IntSurf_PntOn2S& thePtWL2,
+                                           IntSurf_PntOn2S& theNewPoint,
+                                           const gp_Vec& theVec1,
+                                           const gp_Vec& theVec2,
+                                           const gp_Vec& theVec3,
+                                           const Bnd_Box2d& theBoxS1,
+                                           const Bnd_Box2d& theBoxS2,
+                                           const Standard_Real theToler3D,
+                                           const Standard_Real* const theArrPeriods)
 {
   const Standard_Real aSqToler = theToler3D*theToler3D;
 
   if(theVec3.SquareMagnitude() <= aSqToler)
   {
-    return Standard_False;
+    return IntPatchWT_NotConnected;
   }
 
   if((theVec1.Angle(theVec2) > IntPatch_WLineTool::myMaxConcatAngle) ||
      (theVec1.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle) ||
      (theVec2.Angle(theVec3) > IntPatch_WLineTool::myMaxConcatAngle))
   {
-    return Standard_False;
+    return IntPatchWT_NotConnected;
   }
 
   const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
 
-  Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0;
+  Standard_Real aNewPar[4] = {0.0, 0.0, 0.0, 0.0};
 
-  theBoxS1.Get(aU1, aV1, aU2, aV2);
-  const Standard_Real aU1f = aU1, aV1f = aV1;
-  theBoxS2.Get(aU1, aV1, aU2, aV2);
-  const Standard_Real aU2f = aU1, aV2f = aV1;
+  //Left-bottom corner
+  Standard_Real aParLBC[4] = {0.0, 0.0, 0.0, 0.0};
+  theBoxS1.Get(aParLBC[0], aParLBC[1], aNewPar[0], aNewPar[0]);  
+  theBoxS2.Get(aParLBC[2], aParLBC[3], aNewPar[0], aNewPar[0]);
 
   if(!IsIntersectionPoint(aPmid, theS1, theS2, thePtWL1, theToler3D,
-                          theU1Period, theU2Period, theV1Period, theV2Period,
-                          aU1, aV1, aU2, aV2))
+                          theArrPeriods, theNewPoint))
   {
-    return Standard_False;
+    return IntPatchWT_NotConnected;
   }
 
-  theNewPoint.SetValue(aPmid, aU1, aV1, aU2, aV2);
-
-  if(IsOutOfDomain(theBoxS1, theBoxS2, theNewPoint,
-                   theU1Period, theU2Period,
-                   theV1Period, theV2Period))
+  if(IsOutOfDomain(theBoxS1, theBoxS2, theNewPoint, theArrPeriods))
   {
-    return Standard_False;
+    return IntPatchWT_NotConnected;
   }
 
-  Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
-                aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
+  Standard_Real aParWL1[4] = {0.0, 0.0, 0.0, 0.0},
+                aParWL2[4] = {0.0, 0.0, 0.0, 0.0};
+  
+  thePtWL1.Parameters(aParWL1[0], aParWL1[1], aParWL1[2], aParWL1[3]);
+  thePtWL2.Parameters(aParWL2[0], aParWL2[1], aParWL2[2], aParWL2[3]);
+  theNewPoint.Parameters(aNewPar[0], aNewPar[1], aNewPar[2], aNewPar[3]);
 
-  thePtWL1.Parameters(aU11, aV11, aU21, aV21);
-  thePtWL2.Parameters(aU12, aV12, aU22, aV22);
+  Standard_Boolean isOnBoundary = Standard_False;
+  for(Standard_Integer i = 0; i < 4; i++)
+  {
+    if(IsOnPeriod(aParWL1[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[i]))
+    {
+      //Check, if we intersect surface boundary when we will extend Wline1 or Wline2
+      //to theNewPoint
+      MinMax(aParWL1[i], aParWL2[i]);
+      if(theArrPeriods[i] > 0.0)
+      {
+        if(aNewPar[i] > aParWL2[i])
+        {
+          //Source situation:
+          //
+          //---*---------------*------------*-----
+          // aParWL1[i]   aParWL2[i]    aNewPar[i]
+          //
+          //After possible adjusting:
+          //
+          //---*---------------*------------*-----
+          // aParWL1[i]   aNewPar[i]    aParWL2[i]
+          //
+          //Now we will be able to extend every WLine to
+          //aNewPar[i] to make them close to each other.
+          //However, it is necessary to add check if we
+          //intersect boundary.
+          const Standard_Real aPar = aParWL1[i] +
+                theArrPeriods[0]*Ceiling((aNewPar[i]-aParWL1[i])/theArrPeriods[0]);
+          aParWL1[i] = aParWL2[i];
+          aParWL2[i] = aPar;
+        }
+        else if(aNewPar[i] < aParWL1[i])
+        {
+          //See comments to main "if".
+          //Source situation:
+          //
+          //---*---------------*------------*-----
+          // aNewPar[i]    aParWL1[i]   aParWL2[i]    
+          //
+          //After possible adjusting:
+          //
+          //---*---------------*------------*-----
+          // aParWL1[i]   aNewPar[i]    aParWL2[i]
+          
+          const Standard_Real aPar = aParWL2[i] - 
+                theArrPeriods[0]*Ceiling((aParWL2[i]-aNewPar[i])/theArrPeriods[0]);
+          aParWL2[i] = aParWL1[i];
+          aParWL1[i] = aPar;
+        }
+      }
+
+      if( IsOnPeriod(aParWL1[i] - aParLBC[i], aNewPar[i] - aParLBC[i], theArrPeriods[0]) ||
+          IsOnPeriod(aNewPar[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[0]))
+      {
+        return IntPatchWT_NotConnected;
+      }
+      else
+      {
+        isOnBoundary = Standard_True;
+      }
+    }
+  }
 
-  if(IsOnPeriod(aU11 - aU1f, aU12 - aU1f, theU1Period) ||
-     IsOnPeriod(aV11 - aV1f, aV12 - aV1f, theV1Period) ||
-     IsOnPeriod(aU21 - aU2f, aU22 - aU2f, theU2Period) ||
-     IsOnPeriod(aV21 - aV2f, aV22 - aV2f, theV2Period))
+  if(isOnBoundary)
   {
-    return Standard_False;
+    return IntPatchWT_Singular;
   }
 
-  return Standard_True;
+  return IntPatchWT_EachOther;
 }
 
 //=======================================================================
 //function : CheckArgumentsToJoin
 //purpose  : Check if joining is possible
-//            (see IntPatch_WLineTool::JoinWLines)
+//            (see IntPatch_WLineTool::JoinWLines(...))
 //=======================================================================
 Standard_Boolean CheckArgumentsToJoin(const gp_Vec& theVec1,
                                       const gp_Vec& theVec2)
@@ -928,40 +1009,40 @@ Standard_Boolean CheckArgumentsToJoin(const gp_Vec& theVec1,
 //purpose  : Performs extending theWLine1 and theWLine2 through their
 //            respecting start point.
 //=======================================================================
-static void ExtendTwoWLFirstFirst(const IntSurf_Quadric& theS1,
-                                   const IntSurf_Quadric& theS2,
-                                   const Handle(IntPatch_WLine)& theWLine1,
-                                   const Handle(IntPatch_WLine)& theWLine2,
-                                   const IntSurf_PntOn2S& thePtWL1,
-                                   const IntSurf_PntOn2S& thePtWL2,
-                                   const gp_Vec& theVec1,
-                                   const gp_Vec& theVec2,
-                                   const gp_Vec& theVec3,
-                                   const Bnd_Box2d& theBoxS1,
-                                   const Bnd_Box2d& theBoxS2,
-                                   const Standard_Real theToler3D,
-                                   const Standard_Real theU1Period,
-                                   const Standard_Real theU2Period,
-                                   const Standard_Real theV1Period,
-                                   const Standard_Real theV2Period,
-                                   unsigned int &theCheckResult,
-                                   Standard_Boolean &theHasBeenJoined)
+static void ExtendTwoWLFirstFirst(const Handle(Adaptor3d_HSurface)& theS1,
+                                  const Handle(Adaptor3d_HSurface)& theS2,
+                                  const Handle(IntPatch_WLine)& theWLine1,
+                                  const Handle(IntPatch_WLine)& theWLine2,
+                                  const IntSurf_PntOn2S& thePtWL1,
+                                  const IntSurf_PntOn2S& thePtWL2,
+                                  const gp_Vec& theVec1,
+                                  const gp_Vec& theVec2,
+                                  const gp_Vec& theVec3,
+                                  const Bnd_Box2d& theBoxS1,
+                                  const Bnd_Box2d& theBoxS2,
+                                  const Standard_Real theToler3D,
+                                  const Standard_Real* const theArrPeriods,
+                                  unsigned int &theCheckResult,
+                                  Standard_Boolean &theHasBeenJoined)
 {
   IntSurf_PntOn2S aPOn2S;
-  if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
-                             theVec1, theVec2, theVec3, 
-                             theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period))
-  {
+  const IntPatchWT_WLsConnectionType aCheckRes = 
+                      CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
+                                             theVec1, theVec2, theVec3,
+                                             theBoxS1, theBoxS2,
+                                             theToler3D, theArrPeriods);
+
+  if(aCheckRes != IntPatchWT_NotConnected)
+    theCheckResult |= (IntPatchWT_DisFirstLast | IntPatchWT_DisLastFirst);
+  else
     return;
-  }
-
-  theCheckResult |= (IntPatchWT_DisFirstLast | IntPatchWT_DisLastFirst);
 
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL1, theArrPeriods, aPOn2S);
   ExtendFirst(theWLine1, aPOn2S);
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL2, theArrPeriods, aPOn2S);
   ExtendFirst(theWLine2, aPOn2S);
 
-  if(theHasBeenJoined)
+  if(theHasBeenJoined || (aCheckRes == IntPatchWT_Singular))
     return;
 
   Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
@@ -1002,8 +1083,8 @@ static void ExtendTwoWLFirstFirst(const IntSurf_Quadric& theS1,
 //purpose  : Performs extending theWLine1 through its start point and theWLine2
 //            through its end point.
 //=======================================================================
-static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1,
-                                 const IntSurf_Quadric& theS2,
+static void ExtendTwoWLFirstLast(const Handle(Adaptor3d_HSurface)& theS1,
+                                 const Handle(Adaptor3d_HSurface)& theS2,
                                  const Handle(IntPatch_WLine)& theWLine1,
                                  const Handle(IntPatch_WLine)& theWLine2,
                                  const IntSurf_PntOn2S& thePtWL1,
@@ -1014,28 +1095,28 @@ static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1,
                                  const Bnd_Box2d& theBoxS1,
                                  const Bnd_Box2d& theBoxS2,
                                  const Standard_Real theToler3D,
-                                 const Standard_Real theU1Period,
-                                 const Standard_Real theU2Period,
-                                 const Standard_Real theV1Period,
-                                 const Standard_Real theV2Period,
+                                 const Standard_Real* const theArrPeriods,
                                  unsigned int &theCheckResult,
                                  Standard_Boolean &theHasBeenJoined)
 {
   IntSurf_PntOn2S aPOn2S;
-  if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
-                             theVec1, theVec2, theVec3, 
-                             theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period))
-  {
+  const IntPatchWT_WLsConnectionType aCheckRes = 
+                      CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
+                                             theVec1, theVec2, theVec3,
+                                             theBoxS1, theBoxS2,
+                                             theToler3D, theArrPeriods);
+
+  if(aCheckRes != IntPatchWT_NotConnected)
+    theCheckResult |= IntPatchWT_DisLastLast;
+  else
     return;
-  }
-
-  theCheckResult |= IntPatchWT_DisLastLast;
 
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL1, theArrPeriods, aPOn2S);
   ExtendFirst(theWLine1, aPOn2S);
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL2, theArrPeriods, aPOn2S);
   ExtendLast (theWLine2, aPOn2S);
 
-  if(theHasBeenJoined)
+  if(theHasBeenJoined || (aCheckRes == IntPatchWT_Singular))
     return;
 
   Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
@@ -1074,8 +1155,8 @@ static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1,
 //purpose  : Performs extending theWLine1 through its end point and theWLine2
 //            through its start point.
 //=======================================================================
-static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1,
-                                 const IntSurf_Quadric& theS2,
+static void ExtendTwoWLLastFirst(const Handle(Adaptor3d_HSurface)& theS1,
+                                 const Handle(Adaptor3d_HSurface)& theS2,
                                  const Handle(IntPatch_WLine)& theWLine1,
                                  const Handle(IntPatch_WLine)& theWLine2,
                                  const IntSurf_PntOn2S& thePtWL1,
@@ -1086,28 +1167,28 @@ static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1,
                                  const Bnd_Box2d& theBoxS1,
                                  const Bnd_Box2d& theBoxS2,
                                  const Standard_Real theToler3D,
-                                 const Standard_Real theU1Period,
-                                 const Standard_Real theU2Period,
-                                 const Standard_Real theV1Period,
-                                 const Standard_Real theV2Period,
+                                 const Standard_Real* const theArrPeriods,
                                  unsigned int &theCheckResult,
                                  Standard_Boolean &theHasBeenJoined)
 {
   IntSurf_PntOn2S aPOn2S;
-  if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
-                             theVec1, theVec2, theVec3, 
-                             theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period))
-  {
+  const IntPatchWT_WLsConnectionType aCheckRes = 
+                      CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
+                                             theVec1, theVec2, theVec3,
+                                             theBoxS1, theBoxS2,
+                                             theToler3D, theArrPeriods);
+
+  if(aCheckRes != IntPatchWT_NotConnected)
+    theCheckResult |= IntPatchWT_DisLastLast;
+  else
     return;
-  }
-
-  theCheckResult |= IntPatchWT_DisLastLast;
 
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL1, theArrPeriods, aPOn2S);
   ExtendLast (theWLine1, aPOn2S);
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL2, theArrPeriods, aPOn2S);
   ExtendFirst(theWLine2, aPOn2S);
 
-  if(theHasBeenJoined)
+  if(theHasBeenJoined || (aCheckRes == IntPatchWT_Singular))
   {
     return;
   }
@@ -1142,8 +1223,8 @@ static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1,
 //function : ExtendTwoWLLastLast
 //purpose  : 
 //=======================================================================
-static void ExtendTwoWLLastLast(const IntSurf_Quadric& theS1,
-                                const IntSurf_Quadric& theS2,
+static void ExtendTwoWLLastLast(const Handle(Adaptor3d_HSurface)& theS1,
+                                const Handle(Adaptor3d_HSurface)& theS2,
                                 const Handle(IntPatch_WLine)& theWLine1,
                                 const Handle(IntPatch_WLine)& theWLine2,
                                 const IntSurf_PntOn2S& thePtWL1,
@@ -1154,28 +1235,28 @@ static void ExtendTwoWLLastLast(const IntSurf_Quadric& theS1,
                                 const Bnd_Box2d& theBoxS1,
                                 const Bnd_Box2d& theBoxS2,
                                 const Standard_Real theToler3D,
-                                const Standard_Real theU1Period,
-                                const Standard_Real theU2Period,
-                                const Standard_Real theV1Period,
-                                const Standard_Real theV2Period,
-                                unsigned int &/*theCheckResult*/,
+                                const Standard_Real* const theArrPeriods,
+                                unsigned int &theCheckResult,
                                 Standard_Boolean &theHasBeenJoined)
 {
   IntSurf_PntOn2S aPOn2S;
-  if(!CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
-                             theVec1, theVec2, theVec3, 
-                             theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period))
-  {
-    return;
-  }
+  const IntPatchWT_WLsConnectionType aCheckRes = 
+                      CheckArgumentsToExtend(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
+                                             theVec1, theVec2, theVec3,
+                                             theBoxS1, theBoxS2,
+                                             theToler3D, theArrPeriods);
   
-  //theCheckResult |= IntPatchWT_DisLastLast;
+  if(aCheckRes != IntPatchWT_NotConnected)
+    theCheckResult |= IntPatchWT_DisLastLast;
+  else
+    return;
 
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL1, theArrPeriods, aPOn2S);
   ExtendLast(theWLine1, aPOn2S);
+  IntPatch_SpecialPoints::AdjustPointAndVertex(thePtWL2, theArrPeriods, aPOn2S);
   ExtendLast(theWLine2, aPOn2S);
 
-  if(theHasBeenJoined)
+  if(theHasBeenJoined || (aCheckRes == IntPatchWT_Singular))
     return;
 
   Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine();
@@ -1403,6 +1484,7 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
       {
         const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
         const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
+
         Standard_Boolean aCond = 
               CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()),
                                    gp_Vec(aPt2.Value(), aPntFWL2.Value()));
@@ -1549,20 +1631,17 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
 }
 
 //=======================================================================
-//function : ExtendTwoWlinesToEachOther
+//function : ExtendTwoWLines
 //purpose  : Performs extending theWLine1 and theWLine2 through their
 //            respecting end point.
 //=======================================================================
-void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
-                                                    const IntSurf_Quadric& theS1,
-                                                    const IntSurf_Quadric& theS2,
-                                                    const Standard_Real theToler3D,
-                                                    const Standard_Real theU1Period,
-                                                    const Standard_Real theU2Period,
-                                                    const Standard_Real theV1Period,
-                                                    const Standard_Real theV2Period,
-                                                    const Bnd_Box2d& theBoxS1,
-                                                    const Bnd_Box2d& theBoxS2)
+void IntPatch_WLineTool::ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
+                                         const Handle(Adaptor3d_HSurface)& theS1,
+                                         const Handle(Adaptor3d_HSurface)& theS2,
+                                         const Standard_Real theToler3D,
+                                         const Standard_Real* const theArrPeriods,
+                                         const Bnd_Box2d& theBoxS1,
+                                         const Bnd_Box2d& theBoxS2)
 {
   if(theSlin.Length() < 2)
     return;
@@ -1587,6 +1666,49 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
     if(aWLine1->Vertex(aWLine1->NbVertex()).ParameterOnLine() != aWLine1->NbPnts())
       continue;
 
+    const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
+    const IntSurf_PntOn2S& aPntFp1WL1 = aWLine1->Point(2);
+
+    const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
+    const IntSurf_PntOn2S& aPntLm1WL1 = aWLine1->Point(aNbPntsWL1-1);
+
+    //Enable/Disable of some ckeck. Bit-mask is used for it.
+    //E.g. if 1st point of aWLine1 matches with
+    //1st point of aWLine2 then we do not need in check
+    //1st point of aWLine1 and last point of aWLine2 etc.
+    unsigned int aCheckResult = IntPatchWT_EnAll;
+
+    //If aWLine1 is already connected with another Wline then
+    //there is no point in extending.
+    for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1;
+        aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
+    {
+      Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::
+                                    DownCast(theSlin.Value(aNumOfLine2)));
+
+      if(aWLine2.IsNull())
+        continue;
+
+      const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
+      const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aWLine2->NbPnts());
+
+      if( aPntFWL1.IsSame(aPntFWL2, theToler3D) ||
+          aPntFWL1.IsSame(aPntLWL2, theToler3D) )
+      {
+        aCheckResult |= IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast;
+      }
+
+      if( aPntLWL1.IsSame(aPntFWL2, theToler3D) ||
+          aPntLWL1.IsSame(aPntFWL2, theToler3D))
+      {
+        aCheckResult |= IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast;
+      }
+    }
+
+    if(aCheckResult == (IntPatchWT_DisFirstFirst | IntPatchWT_DisFirstLast |
+                        IntPatchWT_DisLastFirst | IntPatchWT_DisLastLast))
+      continue;
+
     for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1;
         aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
     {
@@ -1602,22 +1724,10 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
       if(aWLine2->Vertex(aWLine2->NbVertex()).ParameterOnLine() != aWLine2->NbPnts())
         continue;
 
-      //Enable/Disable of some ckeck. Bit-mask is used for it.
-      //E.g. if 1st point of aWLine1 matches with
-      //1st point of aWLine2 then we do not need in check
-      //1st point of aWLine1 and last point of aWLine2 etc.
-      unsigned int aCheckResult = IntPatchWT_EnAll;
-
       Standard_Boolean hasBeenJoined = Standard_False;
 
       const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
 
-      const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
-      const IntSurf_PntOn2S& aPntFp1WL1 = aWLine1->Point(2);
-
-      const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
-      const IntSurf_PntOn2S& aPntLm1WL1 = aWLine1->Point(aNbPntsWL1-1);
-      
       const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
       const IntSurf_PntOn2S& aPntFp1WL2 = aWLine2->Point(2);
 
@@ -1632,8 +1742,7 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
 
         ExtendTwoWLFirstFirst(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntFWL2,
                               aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
-                              theU1Period, theU2Period, theV1Period, theV2Period,
-                              aCheckResult, hasBeenJoined);
+                              theArrPeriods, aCheckResult, hasBeenJoined);
       }
 
       if(!(aCheckResult & IntPatchWT_DisFirstLast))
@@ -1644,8 +1753,7 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
 
         ExtendTwoWLFirstLast(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntLWL2,
                              aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period,
-                             aCheckResult, hasBeenJoined);
+                             theArrPeriods, aCheckResult, hasBeenJoined);
       }
 
       if(!(aCheckResult & IntPatchWT_DisLastFirst))
@@ -1656,8 +1764,7 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
 
         ExtendTwoWLLastFirst(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntFWL2,
                              aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
-                             theU1Period, theU2Period, theV1Period, theV2Period,
-                             aCheckResult, hasBeenJoined);
+                             theArrPeriods, aCheckResult, hasBeenJoined);
       }
 
       if(!(aCheckResult & IntPatchWT_DisLastLast))
@@ -1668,8 +1775,7 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
 
         ExtendTwoWLLastLast(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntLWL2,
                             aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
-                            theU1Period, theU2Period, theV1Period, theV2Period,
-                            aCheckResult, hasBeenJoined);
+                            theArrPeriods, aCheckResult, hasBeenJoined);
       }
 
       if(hasBeenJoined)
index 02e4584..9a40853 100644 (file)
 #ifndef _IntPatch_WLineTool_HeaderFile
 #define _IntPatch_WLineTool_HeaderFile
 
-#include <Standard_Boolean.hxx>
-#include <Standard_Macro.hxx>
-#include <IntPatch_WLine.hxx>
 #include <IntPatch_SequenceOfLine.hxx>
-#include <IntSurf_Quadric.hxx>
-class TopoDS_Face;
-class GeomAdaptor_HSurface;
-class GeomInt_LineConstructor;
-class IntTools_Context;
+#include <IntPatch_WLine.hxx>
+#include <Standard_Macro.hxx>
+
 class Adaptor3d_TopolTool;
-class Adaptor3d_HSurface;
 
 //! IntPatch_WLineTool provides set of static methods related to walking lines.
 class IntPatch_WLineTool
@@ -84,20 +78,21 @@ public:
 //! in strictly determined point (in the place of joint of two lines).
 //! As result, some gaps between two lines will vanish.
 //! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
-//! to be computed as a result of intersection of two quadrics.
-//! The quadrics definition is accepted in input parameters.
-  Standard_EXPORT static void ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
-                                                         const IntSurf_Quadric& theS1,
-                                                         const IntSurf_Quadric& theS2,
-                                                         const Standard_Real theToler3D,
-                                                         const Standard_Real theU1Period,
-                                                         const Standard_Real theU2Period,
-                                                         const Standard_Real theV1Period,
-                                                         const Standard_Real theV2Period,
-                                                         const Bnd_Box2d& theBoxS1,
-                                                         const Bnd_Box2d& theBoxS2);
+//! to be computed as a result of intersection. Both theS1 and theS2 
+//! must be quadrics. Other cases are not supported.
+//! theArrPeriods must be filled as follows:
+//! {<U-period of 1st surface>, <V-period of 1st surface>,
+//!               <U-period of 2nd surface>, <V-period of 2nd surface>}.
+  Standard_EXPORT static void
+            ExtendTwoWLines(IntPatch_SequenceOfLine& theSlin,
+                            const Handle(Adaptor3d_HSurface)& theS1,
+                            const Handle(Adaptor3d_HSurface)& theS2,
+                            const Standard_Real theToler3D,
+                            const Standard_Real* const theArrPeriods,
+                            const Bnd_Box2d& theBoxS1,
+                            const Bnd_Box2d& theBoxS2);
 
-//! Max angle to concatenate two WLines to avoid result with C0-continuity
+  //! Max angle to concatenate two WLines to avoid result with C0-continuity
   static const Standard_Real myMaxConcatAngle;
 };
 
index 86ff1be..d1d8e5c 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
-#include <gp.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Vec.hxx>
 #include <IntSurf.hxx>
+
+#include <Adaptor3d_HSurface.hxx>
 #include <IntSurf_Transition.hxx>
 #include <Precision.hxx>
+#include <gp_Vec.hxx>
 
 //--------------------------------------------------------------
 //-- IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
@@ -98,7 +97,18 @@ void IntSurf::MakeTransition (const gp_Vec& TgFirst,
   }
 }
 
-
-
+//=======================================================================
+//function : SetPeriod
+//purpose  : 
+//=======================================================================
+void IntSurf::SetPeriod(const Handle(Adaptor3d_HSurface)& theFirstSurf,
+                        const Handle(Adaptor3d_HSurface)& theSecondSurf,
+                        Standard_Real theArrOfPeriod[4])
+{
+  theArrOfPeriod[0] = theFirstSurf->IsUPeriodic()? theFirstSurf->UPeriod() : 0.0;
+  theArrOfPeriod[1] = theFirstSurf->IsVPeriodic()? theFirstSurf->VPeriod() : 0.0;
+  theArrOfPeriod[2] = theSecondSurf->IsUPeriodic()? theSecondSurf->UPeriod() : 0.0;
+  theArrOfPeriod[3] = theSecondSurf->IsVPeriodic()? theSecondSurf->VPeriod() : 0.0;
+}
 
 
index 6448b6b..80890c8 100644 (file)
 #ifndef _IntSurf_HeaderFile
 #define _IntSurf_HeaderFile
 
-#include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
-class gp_Vec;
-class gp_Dir;
-class IntSurf_Transition;
-class IntSurf_PntOn2S;
-class IntSurf_Couple;
-class IntSurf_LineOn2S;
-class IntSurf_Quadric;
-class IntSurf_QuadricTool;
-class IntSurf_PathPoint;
-class IntSurf_PathPointTool;
-class IntSurf_InteriorPoint;
-class IntSurf_InteriorPointTool;
+class Adaptor3d_HSurface;
 class IntSurf_Transition;
-
+class gp_Dir;
+class gp_Vec;
 
 //! This package provides resources for
 //! all the packages concerning the intersection
@@ -56,6 +45,17 @@ public:
   //! TSecond is the transition of the point on the second line.
   Standard_EXPORT static void MakeTransition (const gp_Vec& TgFirst, const gp_Vec& TgSecond, const gp_Dir& Normal, IntSurf_Transition& TFirst, IntSurf_Transition& TSecond);
 
+  //! Fills theArrOfPeriod array by the period values of theFirstSurf and theSecondSurf.
+  //! [0] = U-period of theFirstSurf,
+  //! [1] = V-period of theFirstSurf,
+  //! [2] = U-period of theSecondSurf,
+  //! [3] = V-period of theSecondSurf.
+  //!
+  //! If surface is not periodic in correspond direction then
+  //! its period is considered to be equal to 0.
+  Standard_EXPORT static void SetPeriod(const Handle(Adaptor3d_HSurface)& theFirstSurf,
+                                        const Handle(Adaptor3d_HSurface)& theSecondSurf,
+                                        Standard_Real theArrOfPeriod[4]);
 
 
 
index 166b4f1..ce8f371 100644 (file)
 
 #include <IntTools_FaceFace.hxx>
 
-#include <Precision.hxx>
-
-#include <TColStd_HArray1OfReal.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <TColStd_Array1OfInteger.hxx>
-#include <TColStd_SequenceOfReal.hxx>
-#include <TColStd_ListOfInteger.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TColStd_Array1OfListOfInteger.hxx>
-
-#include <Bnd_Box.hxx>
-
-#include <TColgp_HArray1OfPnt2d.hxx>
-#include <TColgp_SequenceOfPnt2d.hxx>
-#include <TColgp_Array1OfPnt.hxx>
-#include <TColgp_Array1OfPnt2d.hxx>
-
-#include <IntAna_QuadQuadGeo.hxx>
-
-#include <IntSurf_PntOn2S.hxx>
-#include <IntSurf_LineOn2S.hxx>
-#include <IntSurf_PntOn2S.hxx>
-#include <IntSurf_ListOfPntOn2S.hxx>
-#include <IntRes2d_Domain.hxx>
-#include <ProjLib_Plane.hxx>
-
-#include <IntPatch_GLine.hxx>
-#include <IntPatch_RLine.hxx>
-#include <IntPatch_WLine.hxx>
-#include <IntPatch_ALine.hxx>
-#include <IntPatch_ALineToWLine.hxx>
-
-#include <ElSLib.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
 #include <ElCLib.hxx>
-
-#include <BndLib_AddSurface.hxx>
-
-#include <Adaptor3d_SurfacePtr.hxx>
-#include <Adaptor2d_HLine2d.hxx>
-
-#include <GeomAbs_SurfaceType.hxx>
-#include <GeomAbs_CurveType.hxx>
-
-#include <Geom_Surface.hxx>
-#include <Geom_Line.hxx>
+#include <ElSLib.hxx>
+#include <Geom2dAdaptor_Curve.hxx>
+#include <Geom2dInt_GInter.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomInt_IntSS.hxx>
+#include <GeomInt_WLApprox.hxx>
+#include <GeomLib_Check2dBSplineCurve.hxx>
+#include <GeomLib_CheckBSplineCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_Ellipse.hxx>
-#include <Geom_Parabola.hxx>
 #include <Geom_Hyperbola.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_Line.hxx>
 #include <Geom_OffsetSurface.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Conic.hxx>
-
-#include <Geom2d_TrimmedCurve.hxx>
-#include <Geom2d_BSplineCurve.hxx>
-#include <Geom2d_Line.hxx>
-#include <Geom2d_Curve.hxx>
-
-#include <Geom2dInt_GInter.hxx>
-#include <Geom2dAdaptor.hxx>
-#include <GeomAdaptor_HSurface.hxx>
-#include <GeomAdaptor_Surface.hxx>
-#include <GeomLib_CheckBSplineCurve.hxx>
-#include <GeomLib_Check2dBSplineCurve.hxx>
-
-#include <GeomInt_WLApprox.hxx>
-#include <GeomProjLib.hxx>
-#include <GeomAPI_ProjectPointOnSurf.hxx>
-#include <Geom2dAdaptor_Curve.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopExp_Explorer.hxx>
-
-#include <BRep_Tool.hxx>
-#include <BRepTools.hxx>
-#include <BRepAdaptor_Surface.hxx>
-
-#include <IntTools_Curve.hxx>
-#include <IntTools_Tools.hxx>
+#include <Geom_Parabola.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <IntAna_QuadQuadGeo.hxx>
+#include <IntPatch_GLine.hxx>
+#include <IntPatch_RLine.hxx>
+#include <IntPatch_WLine.hxx>
+#include <IntRes2d_Domain.hxx>
+#include <IntSurf_Quadric.hxx>
+#include <IntTools_Context.hxx>
 #include <IntTools_Tools.hxx>
 #include <IntTools_TopolTool.hxx>
-#include <IntTools_PntOnFace.hxx>
-#include <IntTools_PntOn2Faces.hxx>
-#include <IntTools_Context.hxx>
-#include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
-
-#include <Approx_CurveOnSurface.hxx>
-#include <GeomAdaptor.hxx>
-#include <GeomInt_IntSS.hxx>
 #include <IntTools_WLineTool.hxx>
-#include <IntPatch_WLineTool.hxx>
+#include <ProjLib_Plane.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <gp_Elips.hxx>
 
 static
   void TolR3d(const TopoDS_Face& ,
@@ -1333,183 +1278,8 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     }// IntPatch_Circle: IntPatch_Ellipse:
     break;
     
-  case IntPatch_Analytic: {
-    IntSurf_Quadric quad1,quad2;
-    GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
-    
-    switch (typs) {
-      case GeomAbs_Plane:
-        quad1.SetValue(myHS1->Surface().Plane());
-        break;
-      case GeomAbs_Cylinder:
-        quad1.SetValue(myHS1->Surface().Cylinder());
-        break;
-      case GeomAbs_Cone:
-        quad1.SetValue(myHS1->Surface().Cone());
-        break;
-      case GeomAbs_Sphere:
-        quad1.SetValue(myHS1->Surface().Sphere());
-        break;
-    case GeomAbs_Torus:
-      quad1.SetValue(myHS1->Surface().Torus());
-      break;
-      default:
-        Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
-      }
-      
-    typs = myHS2->Surface().GetType();
-    
-    switch (typs) {
-      case GeomAbs_Plane:
-        quad2.SetValue(myHS2->Surface().Plane());
-        break;
-      case GeomAbs_Cylinder:
-        quad2.SetValue(myHS2->Surface().Cylinder());
-        break;
-      case GeomAbs_Cone:
-        quad2.SetValue(myHS2->Surface().Cone());
-        break;
-      case GeomAbs_Sphere:
-        quad2.SetValue(myHS2->Surface().Sphere());
-        break;
-    case GeomAbs_Torus:
-      quad2.SetValue(myHS2->Surface().Torus());
-      break;
-      default:
-        Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
-      }
-    //
-    //=========
-    IntPatch_ALineToWLine convert (quad1, quad2);
-      
-    if (!myApprox) {
-      aNbParts=myLConstruct.NbParts();
-      for (i=1; i<=aNbParts; i++) {
-        myLConstruct.Part(i, fprm, lprm);
-        Handle(IntPatch_WLine) WL = 
-          convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
-        //
-        Handle(Geom2d_BSplineCurve) H1;
-        Handle(Geom2d_BSplineCurve) H2;
-
-        if(myApprox1) {
-          H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-        }
-        
-        if(myApprox2) {
-          H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-        }
-        //          
-        mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
-      }
-    } // if (!myApprox)
-
-    else { // myApprox=TRUE
-      GeomInt_WLApprox theapp3d;
-      // 
-      Standard_Real tol2d = myTolApprox;
-      //         
-      theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_True);
-      
-      aNbParts=myLConstruct.NbParts();
-      for (i=1; i<=aNbParts; i++) {
-        myLConstruct.Part(i, fprm, lprm);
-        Handle(IntPatch_WLine) WL = 
-          convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
-
-        theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
-
-        if (!theapp3d.IsDone()) {
-          //
-          Handle(Geom2d_BSplineCurve) H1;
-          Handle(Geom2d_BSplineCurve) H2;
-
-          if(myApprox1) {
-            H1 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
-          }
-          
-          if(myApprox2) {
-            H2 = GeomInt_IntSS::MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
-          }
-          //          
-          mySeqOfCurve.Append(IntTools_Curve(GeomInt_IntSS::MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
-        }
-
-        else {
-          if(myApprox1 || myApprox2) { 
-            if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) { 
-              myTolReached2d = theapp3d.TolReached2d();
-            }
-          }
-          
-          if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) { 
-            myTolReached3d = theapp3d.TolReached3d();
-          }
-
-          Standard_Integer aNbMultiCurves, nbpoles;
-          aNbMultiCurves=theapp3d.NbMultiCurves();
-          for (j=1; j<=aNbMultiCurves; j++) {
-            const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
-            nbpoles = mbspc.NbPoles();
-            
-            TColgp_Array1OfPnt tpoles(1, nbpoles);
-            mbspc.Curve(1, tpoles);
-            Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
-                                                               mbspc.Knots(),
-                                                               mbspc.Multiplicities(),
-                                                               mbspc.Degree());
-            
-            GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
-            Check.FixTangent(Standard_True,Standard_True);
-            // 
-            IntTools_Curve aCurve;
-            aCurve.SetCurve(BS);
-            
-            if(myApprox1) { 
-              TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
-              mbspc.Curve(2,tpoles2d);
-              Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
-                                                                      mbspc.Knots(),
-                                                                      mbspc.Multiplicities(),
-                                                                      mbspc.Degree());
-
-              GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
-              newCheck.FixTangent(Standard_True,Standard_True);
-              //                 
-              aCurve.SetFirstCurve2d(BS2);
-            }
-            else {
-              Handle(Geom2d_BSplineCurve) H1;
-              aCurve.SetFirstCurve2d(H1);
-            }
-            
-            if(myApprox2) { 
-              TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
-              Standard_Integer TwoOrThree;
-              TwoOrThree=myApprox1 ? 3 : 2;
-              mbspc.Curve(TwoOrThree, tpoles2d);
-              Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
-                                                                       mbspc.Knots(),
-                                                                       mbspc.Multiplicities(),
-                                                                       mbspc.Degree());
-                
-              GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
-              newCheck.FixTangent(Standard_True,Standard_True);
-              //         
-              aCurve.SetSecondCurve2d(BS2);
-            }
-            else { 
-              Handle(Geom2d_BSplineCurve) H2;
-              aCurve.SetSecondCurve2d(H2);
-            }
-            // 
-            mySeqOfCurve.Append(aCurve);
-
-          }// for (j=1; j<=aNbMultiCurves; j++) {
-        }// else from if (!theapp3d.IsDone())
-      }// for (i=1; i<=aNbParts; i++) {
-    }// else { // myApprox=TRUE
-  }// case IntPatch_Analytic:
+  case IntPatch_Analytic:
+    //This case was processed earlier (in IntPatch_Intersection)
     break;
 
   case IntPatch_Walking:{
index c6a71f3..a6b3975 100644 (file)
@@ -805,7 +805,7 @@ Standard_Boolean IntTools_Tools::ComputeTolerance
   //e.g. after trimming) we will be able to come
   //to the more precise minimum point. As result, this curve with the
   //tolerance computed earlier will become invalid.
-  const Standard_Real anEps = (1.0+1.0e-9);
+  const Standard_Real anEps = (1.0+1.0e-7);
   theMaxDist = anEps*aCS.MaxDistance();
   theMaxPar  = aCS.MaxParameter();
   //
index edabcd5..892229a 100644 (file)
@@ -33,6 +33,7 @@
 #include <IntPatch_IType.hxx>
 #include <IntPatch_Line.hxx>
 #include <IntPatch_RLine.hxx>
+#include <IntPatch_SequenceOfLine.hxx>
 #include <IntPatch_WLine.hxx>
 #include <IntSurf_Quadric.hxx>
 #include <Standard_NotImplemented.hxx>
 #include <TopOpeBRep_WPointInter.hxx>
 #include <TopOpeBRepDS_Transition.hxx>
 
+#include <BRepAdaptor_HSurface.hxx>
+
 #ifdef OCCT_DEBUG
 extern Standard_Boolean TopOpeBRep_GetcontextALWLNBP(Standard_Integer&);
 extern Standard_Boolean TopOpeBRep_GettraceCONIC();
 #endif
 
 //-----------------------------------------------------------------------
-static Handle(IntPatch_WLine) FUN_ALINETOWLINE
-(const Handle(IntPatch_ALine)& AL,
- const BRepAdaptor_Surface surf1,const BRepAdaptor_Surface surf2)
-//-----------------------------------------------------------------------
+static void FUN_ALINETOWLINE (const Handle(IntPatch_ALine)& AL,
+                              const Handle(BRepAdaptor_HSurface) surf1,
+                              const Handle(BRepAdaptor_HSurface) surf2,
+                              IntPatch_SequenceOfLine& theLines)
 {
-  IntSurf_Quadric Quad1,Quad2;
-
-  switch(surf1.GetType())
-  {
-    case GeomAbs_Plane:    Quad1.SetValue(surf1.Plane()); break;
-    case GeomAbs_Cylinder: Quad1.SetValue(surf1.Cylinder()); break;
-    case GeomAbs_Sphere:   Quad1.SetValue(surf1.Sphere()); break;
-    case GeomAbs_Cone:     Quad1.SetValue(surf1.Cone()); break;
-    default : Standard_ProgramError::Raise
-      ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
-  }
-  
-  switch(surf2.GetType())
-  {
-    case GeomAbs_Plane:    Quad2.SetValue(surf2.Plane()); break;
-    case GeomAbs_Cylinder: Quad2.SetValue(surf2.Cylinder()); break;
-    case GeomAbs_Sphere:   Quad2.SetValue(surf2.Sphere()); break;
-    case GeomAbs_Cone:     Quad2.SetValue(surf2.Cone()); break;
-    default : Standard_ProgramError::Raise
-      ("TopOpeBRep_LineInter::FUN_ALINETOWLINE"); break;
-  }
-
-  const Standard_Real deflectionmax = 0.01;
-  const Standard_Real pasUVmax = 0.05;
   Standard_Integer nbpointsmax = 200;
 #ifdef OCCT_DEBUG
   Standard_Integer newnbp;
   if (TopOpeBRep_GetcontextALWLNBP(newnbp)) nbpointsmax = newnbp;
 #endif
   IntPatch_ALineToWLine 
-    AToL(Quad1,Quad2,deflectionmax,pasUVmax,nbpointsmax);
-  return AToL.MakeWLine(AL);
+    AToL(surf1,surf2,nbpointsmax);
+
+  AToL.MakeWLine(AL, theLines);
 }
 
 //=======================================================================
@@ -135,7 +115,13 @@ void TopOpeBRep_LineInter::SetLine(const Handle(IntPatch_Line)& L,
 
   // transform an analytic line to a walking line
   if (myTypeLineCurve == TopOpeBRep_ANALYTIC) {
-    myILW = ::FUN_ALINETOWLINE(myILA,S1,S2);
+    IntPatch_SequenceOfLine aSLin;
+    FUN_ALINETOWLINE(myILA,new BRepAdaptor_HSurface(S1),
+                        new BRepAdaptor_HSurface(S2), aSLin);
+
+    if(aSLin.Length() > 0)
+      myILW = Handle(IntPatch_WLine)::DownCast(aSLin.Value(1));
+
     myTypeLineCurve = TopOpeBRep_WALKING;
   }
 
index 3341ee6..ed7e59d 100755 (executable)
@@ -1,6 +1,3 @@
-puts "TODO OCC25735 ALL: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC22033 ALL: Error : The area of result shape is"
-
 puts "================"
 puts "OCC62"
 puts "BUC61001"
@@ -32,5 +29,5 @@ checkshape res5
 
 renamevar res5 result
 
-checkprops result -s 1.23063e+7
+checkprops result -s 1.20915e+007
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index f31416e..166c3e5 100755 (executable)
@@ -7,7 +7,16 @@ puts ""
 ###################################
 ## BRepAlgoAPI_Fuse fails on revolved and sphere
 ###################################
-## (old topology)
+## Now this test uses BOPAlgo.
+## Intersection of cylinder and sphere. At that,
+## the intersection line goes near to the pole
+## of the sphere (near, but not through).
+## Walking-line has a point in the seam of
+## the sphere and neighbour point. Both sections of the
+## sphere (through every of these points and parallel to
+## equatorial plane) are circles with small radii. As result,
+## in 2D-space U-coordinates of these points are too different
+## (may be even ~60 degrees) in spite of its neighbourhood.
 #####################################
 
 if { [ catch { set info_result [OCC826 a1 a2 result] } ] } {
@@ -23,6 +32,6 @@ if { [ catch { set info_result [OCC826 a1 a2 result] } ] } {
     }
 }
 
-checkprops result -s 272939 
+checkprops result -s 272935 
 checkshape result
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index c238478..e41a1c7 100755 (executable)
@@ -7,10 +7,17 @@ puts ""
 ###################################
 ## BRepAlgoAPI_Fuse fails on revolved and sphere
 ###################################
-##
-## Note: test for old topology
-##
-################################
+## Now this test uses BOPAlgo.
+## Intersection of cylinder and sphere. At that,
+## the intersection line goes near to the pole
+## of the sphere (near, but not through).
+## Walking-line has a point in the seam of
+## the sphere and neighbour point. Both sections of the
+## sphere (through every of these points and parallel to
+## equatorial plane) are circles with small radii. As result,
+## in 2D-space U-coordinates of these points are too different
+## (may be even ~60 degrees) in spite of its neighbourhood.
+#####################################
 
 if { [ catch { set result [OCC826 a1 a2 a3] } ] } {
     puts "Faulty : an exception was caught"
@@ -25,6 +32,6 @@ if { [ catch { set result [OCC826 a1 a2 a3] } ] } {
     }
 }
 
-checkprops result -s 272939 
+checkprops result -s 272935 
 checkshape result
 checkview -display result -2d -path ${imagedir}/${test_image}.png
index 7fcd7ae..4c9a5ca 100644 (file)
@@ -6,27 +6,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -49,60 +28,37 @@ intersect res s1 s2
 
 set che [whatis res]
 set ind [string first "3d curve" $che]
+
+set AllowRepeate 1
+set ic 1
+
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
+  renamevar res res_1
+}
+
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
+    break
   }
   
-  set U1 0.0
-  set U2 0.0
+  bounds res_$ic U1 U2
   
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
-
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval (U2-U1)] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
   
-  xdistcs res s1 ${U1} ${U2} 10 1e-6 1e-7
-  xdistcs res s2 ${U1} ${U2} 10 1e-6 1e-7
-} else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-6 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-6 1e-7
-      
-      incr ic
-    }
-  }
+  xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7
+  xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7
   
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
+  incr ic
 }
+  
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm"
+} else {
+  puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found"
+}
\ No newline at end of file
index 0266bbb..9d23d65 100644 (file)
@@ -1,3 +1,4 @@
+
 puts "================"
 puts "OCC25292"
 puts "================"
@@ -6,27 +7,6 @@ puts ""
 # Face/Face intersection algorithm gives different results for different order of the arguments
 #######################################################################
 
-proc GetRange { curve } {
-  global U1
-  global U2
-  
-  set log [uplevel dump $curve]
-  
-  regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
-  puts "Degree=${Degree}"
-  puts "Poles=${Poles}"
-  puts "KnotsPoles=${KnotsPoles}"
-  puts ""
-
-  set Knot 1
-  set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U1 Mult1
-
-  set Knot ${KnotsPoles}
-  set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
-  regexp ${exp_string} ${log} full U2 Mult2
-}
-
 puts "##############################"
 puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
 puts "##############################"
@@ -49,60 +29,37 @@ intersect res s2 s1
 
 set che [whatis res]
 set ind [string first "3d curve" $che]
+
+set AllowRepeate 1
+set ic 1
+
 if {${ind} >= 0} {
   #Only variable "res" exists
-  
-  if { $GoodNbCurv == 1 } {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
+  renamevar res res_1
+}
+
+while { $AllowRepeate != 0 } {
+  set che [whatis res_$ic]
+  set ind [string first "3d curve" $che]
+  if {${ind} < 0} {
+    set AllowRepeate 0
+    break
   }
   
-  set U1 0.0
-  set U2 0.0
+  bounds res_$ic U1 U2
   
-  GetRange res
-
-  puts "U1 = ${U1}"
-  puts "U2 = ${U2}"
-
-  if {[expr {$U2 - $U1}] < 1.0e-20} {
+  if {[dval (U2-U1)] < 1.0e-20} {
     puts "Error: Wrong curve's range!"
   }
   
-  xdistcs res s1 ${U1} ${U2} 10 1e-6 1e-7
-  xdistcs res s2 ${U1} ${U2} 10 1e-6 1e-7
-} else {
-  set ic 1
-  set AllowRepeate 1
-  while { $AllowRepeate != 0 } {
-    set che [whatis res_$ic]
-    set ind [string first "3d curve" $che]
-    if {${ind} < 0} {
-      set AllowRepeate 0
-    } else {
-      set U1 0.0
-      set U2 0.0
-      
-      GetRange res_$ic
-      
-      puts "U1 = ${U1}"
-      puts "U2 = ${U2}"
-      
-      if {[expr {$U2 - $U1}] < 1.0e-20} {
-        puts "Error: Wrong curve's range!"
-      }
-      
-      xdistcs res_$ic s1 ${U1} ${U2} 10 1e-6 1e-7
-      xdistcs res_$ic s2 0 1 10 1e-6 1e-7
-      
-      incr ic
-    }
-  }
+  xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7
+  xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7
   
-  if {[expr {$ic - 1}] == $GoodNbCurv} {
-    puts "OK: Curve Number is good!"
-  } else {
-    puts "Error: Curve Number is bad!"
-  }
+  incr ic
 }
+  
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+  puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm"
+} else {
+  puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found"
+}
\ No newline at end of file
index 48038e0..fc35232 100644 (file)
@@ -6,6 +6,8 @@ puts ""
 # Bop Common produces strange results with same shapes.
 ########################################################################
 
+puts "TODO #OCC27896 ALL: Faulty shapes in variables faulty_1 to faulty_"
+
 restore [locate_data_file bug25319_S1.brep] b1
 restore [locate_data_file bug25319_S2.brep] b2
 
index ecca179..60cf73e 100644 (file)
@@ -6,6 +6,8 @@ puts ""
 # Bop Common produces strange results with same shapes.
 ########################################################################
 
+puts "TODO #OCC27896 ALL: Faulty shapes in variables faulty_1 to faulty_"
+
 restore [locate_data_file bug25319_S1.brep] b1
 restore [locate_data_file bug25319_S2.brep] b2
 
index c499c8b..708889e 100644 (file)
@@ -6,6 +6,7 @@ puts ""
 # Wrong result obtained by General Fuse operator.
 ###############################################
 puts "TODO #OCC26816 ALL: Error : Result done by General Fuse operator is WRONG because number of"
+puts "TODO #OCC26816 ALL: Faulty shapes in variables faulty_1 to faulty_"
 
 restore [locate_data_file bug25715_p02c3s1.brep] b1
 restore [locate_data_file bug25838_p02c3s2.brep] b2
index da6fbca..0fb4de1 100644 (file)
@@ -6,7 +6,7 @@ puts ""
 ## [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape
 ###############################
 
-set MaxTol 4.8106952270863644e-006
+set MaxTol 3.8178537637632889e-006
 set GoodNbCurv 1
 
 restore [locate_data_file bug27282_cmpd.brep] a
index efd39e5..14f0396 100644 (file)
@@ -6,7 +6,7 @@ puts ""
 ## Invalid curves number in intersection result
 ###############################
 
-set MaxTol 9.9579577516847715e-005
+set MaxTol 6.899054167648517e-007
 set GoodNbCurv 1
 
 restore [locate_data_file CTO900_pro12913a.rle] a
diff --git a/tests/bugs/modalg_6/bug27431 b/tests/bugs/modalg_6/bug27431
new file mode 100644 (file)
index 0000000..311bafb
--- /dev/null
@@ -0,0 +1,67 @@
+puts "============"
+puts "OCC27431"
+puts "============"
+puts ""
+###############################
+## [Regression to 6.9.1] Huge tolerance obtained during intersection of cylinder and sphere
+###############################
+
+pload ALL
+
+set MaxTol1 0.00042926432143107718
+set MaxTol2 0.00042926432143107718
+
+set GoodNbCurv 4
+
+restore [locate_data_file OCC13116_sh1.brep] b1
+restore [locate_data_file OCC13116_sh2.brep] b2
+
+explode b1 f
+explode b2 f
+
+set log1 [bopcurves b1_3 b2_1 -2d]
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log1} full Toler NbCurv
+
+# Before fixing: Tolerance Reached=27.904993728420369
+checkreal ToleranceReached ${Toler} ${MaxTol1} 0.0 0.01
+
+smallview
+don b1_3 b2_1 c_*
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d_1.png
+
+v2d
+don c2d*
+2dfit
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d_1.png
+
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: Number of curves is bad!"
+}
+
+# increasing tolerance values of the faces on Precision::Confusion()
+# dramatically increased (before fixing) the tolerance of 
+# the produced section curves
+
+settolerance b1_3 2.34623727264857e-007
+settolerance b2_1 2.e-7
+
+set log2 [bopcurves b1_3 b2_1 -2d]
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log2} full Toler NbCurv
+
+# Before fixing: Tolerance Reached=40.000000093341022
+checkreal ToleranceReached ${Toler} ${MaxTol2} 0.0 0.01
+
+smallview
+don b1_3 b2_1 c_*
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}_3d_2.png
+
+v2d
+don c2d*
+2dfit
+checkview -screenshot -2d -path ${imagedir}/${test_image}_2d_2.png
index ae63aad..b474787 100755 (executable)
@@ -3,51 +3,71 @@ puts "========| OCC565 |========"
 ## Can not intersect two trimmed conical surfaces 
 ##################################
 
+puts "TODO OCC28016 Linux: Error: 1 is expected but .* is found!"
+
+set GoodNbCurv 1
+
+foreach c [directory result*] {
+  unset $c
+}
+
+foreach c [directory inf*] {
+  unset $c
+}
+
 restore [locate_data_file OCC565a.draw] s1 
 restore [locate_data_file OCC565b.draw] s2 
 
 puts "Preliminary check: intersection work with infinite cones:"
 if { [catch {intersect inf s1 s2 } catch_result] } {
-    puts "Faulty OCC565: function intersection works wrongly with infinite cones"
+  puts "Faulty OCC565: function intersection works wrongly with infinite cones"
 } else {
-    set j 1
-    set er [lindex [whatis inf] 5]
-    repeat 4 {
-       set err [lindex [whatis inf_$j] 5]
-       if { $err != "curve" && $er != "curve"} {
-           puts " Faulty OCC565: function intersection works wrongly with infinite cones"
-           break
-       } else {
-           puts [format "curve inf_%s : exist " $j]
-       }
-       incr j
+  set isFound 0
+  foreach c [directory inf*] {
+    set ind [string first "3d curve" [whatis $c]]
+    if {${ind} < 0} {
+      dump $c
+      puts "Error: Intersection result (with infinite cones) is not 3D-curve"
+    } else {
+      set isFound 1
     }
-    puts "Function intersection works correctly with infinite cones. Then check OCC565:"
+  }
+  
+  if { !$isFound } {
+    puts "Error: Empty intersection result (with infinite cones)"    
+  }
 }
 
 trim s1x s1 0 2*pi 0 2.8
 trim s2x s2 0 2*pi 0 2.8
 
 if { [catch {intersect result s1x s2x } catch_result] } {
-    puts "Faulty OCC565 exception: function intersection works wrongly with trimmed cones"
+  puts "Faulty OCC565 exception: function intersection works wrongly with trimmed cones"
 } else {
-    set nom 0
-    set j 1
-    set er [lindex [whatis result] 5]
-    repeat 4 {
-       set err [lindex [whatis result_$j] 5]
-       if { $err != "curve" && $er != "curve"} {
-           break
-        } else {
-           set nom [expr $nom + 1]
-        }
-       incr j
-    }
-    if { $nom == 0} {
-       puts " Faulty OCC565: function intersection works wrongly with trimmed cones"
-    } else {
-       puts " OCC565 OK: function intersection works with trimmed cones"
+  foreach c [directory result*] {
+    bounds $c U1 U2
+    
+    if {[dval U2-U1] < 1.0e-9} {
+      puts "Error: Wrong curve's range!"
     }
+    
+    xdistcs $c s1 U1 U2 10 1.0e-7
+    xdistcs $c s2 U1 U2 10 1.0e-7
+  }
+
+  set NbCurv [llength [directory result*]]
+
+  if { $NbCurv == $GoodNbCurv } {
+    puts "OK: Number of curves is good!"
+  } else {
+    puts "Error: $GoodNbCurv is expected but $NbCurv is found!"
+  }
+
+  smallview
+  don result*
+  fit
+  disp s1x s2x
+  checkview -screenshot -2d -path ${imagedir}/${test_image}.png
 }
 
 
index 5fbce92..2c69254 100755 (executable)
@@ -12,10 +12,10 @@ restore [locate_data_file bug23981_s2.draw] s2
 intersect i s1 s2
 
 puts "First test"
-xdistcs i_1 s1 0 1 100 1e-5
+xdistcs i_1 s1 0 1 100 1e-7
 
 puts "Second test"
-xdistcs i_2 s1 0 1 100 1e-5
+xdistcs i_2 s1 0 1 100 1e-7
 
 smallview
 fit