0029807: [Regression to 7.0.0] Impossible to cut cone from prism
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_2.gxx
old mode 100755 (executable)
new mode 100644 (file)
index c5801c2..f1d3376
@@ -1,14 +1,32 @@
-// File:      IntPatch_ImpImpIntersection_2.gxx
-// Created:   Thu May  7 08:47:45 1992
-// Author:    Jacques GOUSSARD
-// Copyright: OPEN CASCADE 1992
+// Created on: 1992-05-07
+// Created by: Jacques GOUSSARD
+// Copyright (c) 1992-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <IntPatch_WLine.hxx>
+
+static 
+  Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
+                           GeomAbs_SurfaceType& theTS,
+                           IntSurf_Quadric& theQuad);
 
 //=======================================================================
 //function : IntPatch_ImpImpIntersection
 //purpose  : 
 //=======================================================================
 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
-       done(Standard_False)
+myDone(IntStatus_Fail)
 {
 }
 //=======================================================================
@@ -17,28 +35,33 @@ IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
 //=======================================================================
 IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection
        (const Handle(Adaptor3d_HSurface)&  S1,
-       const Handle(Adaptor3d_TopolTool)& D1,
+        const Handle(Adaptor3d_TopolTool)& D1,
         const Handle(Adaptor3d_HSurface)&  S2,
-       const Handle(Adaptor3d_TopolTool)& D2,
-       const Standard_Real TolArc,
-       const Standard_Real TolTang)
+        const Handle(Adaptor3d_TopolTool)& D2,
+        const Standard_Real TolArc,
+        const Standard_Real TolTang,
+        const Standard_Boolean theIsReqToKeepRLine)
 {
-  Perform(S1,D1,S2,D2,TolArc,TolTang);
+  Perform(S1,D1,S2,D2,TolArc,TolTang, theIsReqToKeepRLine);
 }
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
 void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
-                                         const Handle(Adaptor3d_TopolTool)& D1,
-                                         const Handle(Adaptor3d_HSurface)&  S2,
-                                         const Handle(Adaptor3d_TopolTool)& D2,
-                                         const Standard_Real TolArc,
-                                         const Standard_Real TolTang) {
-  done = Standard_False;
+                                          const Handle(Adaptor3d_TopolTool)& D1,
+                                          const Handle(Adaptor3d_HSurface)&  S2,
+                                          const Handle(Adaptor3d_TopolTool)& D2,
+                                          const Standard_Real TolArc,
+                                          const Standard_Real TolTang,
+                                          const Standard_Boolean theIsReqToKeepRLine)
+{
+  myDone = IntStatus_Fail;
   spnt.Clear();
   slin.Clear();
 
+  Standard_Boolean isPostProcessingRequired = Standard_True;
+
   empt = Standard_True;
   tgte = Standard_False;
   oppo = Standard_False;
@@ -57,427 +80,358 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   IntPatch_SequenceOfPathPointOfTheSOnBounds pnt1,pnt2;
   //
   // On commence par intersecter les supports des surfaces
-  IntSurf_Quadric quad1;
-  IntSurf_Quadric quad2;
+  IntSurf_Quadric quad1, quad2;
   IntPatch_ArcFunction AFunc;
-  Standard_Real Tolang = 1.e-8;
-  GeomAbs_SurfaceType typs1 = S1->GetType();
-  GeomAbs_SurfaceType typs2 = S2->GetType();
+  const Standard_Real Tolang = 1.e-8;
+  GeomAbs_SurfaceType typs1, typs2;
+  Standard_Boolean bEmpty = Standard_False;
   //
-  switch (typs1) {
-
-  case GeomAbs_Plane :
-    {
-      quad1.SetValue(S1->Plane());
-
-      switch (typs2) {
-
-      case GeomAbs_Plane:
-       {
-         quad2.SetValue(S2->Plane());
-         if (!IntPP(quad1,quad2,Tolang,TolTang,SameSurf,slin)) {
-           return;
-         }
-       }
-       break;
-       
-       
-      case GeomAbs_Cylinder:
-       {
-         quad2.SetValue(S2->Cylinder());
-         if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_False,empt,slin)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Sphere:
-       {
-         quad2.SetValue(S2->Sphere());
-         //modified by NIZNHY-PKV Tue Sep 20 09:03:06 2011f
-         if (!IntPSp(quad1,quad2,Tolang,TolTang,Standard_False,empt,slin,spnt)) {
-         //if (!IntPSp(quad1,quad2,TolTang,Standard_False,empt,slin,spnt)) {
-           //modified by NIZNHY-PKV Tue Sep 20 09:03:10 2011t
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-       
-      case GeomAbs_Cone:
-       {
-         quad2.SetValue(S2->Cone());
-         if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_False,
-                     empt,multpoint,slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-      default: 
-       {
-         Standard_ConstructionError::Raise();
-         break;
-       }
+  const Standard_Integer iT1 = SetQuad(S1, typs1, quad1);
+  const Standard_Integer iT2 = SetQuad(S2, typs2, quad2);
+  //
+  if (!iT1 || !iT2) {
+    throw Standard_ConstructionError();
+    return;
+  }
+  //
+  const Standard_Boolean bReverse = iT1 > iT2;
+  const Standard_Integer iTT = iT1*10 + iT2;
+  //
+  switch (iTT) {
+    case 11: { // Plane/Plane
+      if (!IntPP(quad1, quad2, Tolang, TolTang, SameSurf, slin)) {
+        return;
       }
+      break;
     }
-    break;
-
-  case GeomAbs_Cylinder:
-    {
-      quad1.SetValue(S1->Cylinder());
-      switch (typs2){
-
-      case GeomAbs_Plane:
-       {
-         quad2.SetValue(S2->Plane());
-         if (!IntPCy(quad1,quad2,Tolang,TolTang,Standard_True,empt,slin)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cylinder:
-       {
-         quad2.SetValue(S2->Cylinder());
-         if (!IntCyCy(quad1,quad2,TolTang,empt,SameSurf,multpoint,slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Sphere:
-       {
-         quad2.SetValue(S2->Sphere());
-         if (!IntCySp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cone:
-       {
-         quad2.SetValue(S2->Cone());
-         if (!IntCyCo(quad1,quad2,TolTang,Standard_False,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-      default: 
-       {
-         Standard_ConstructionError::Raise();
-         break;
-       }
+    //
+    case 12:
+    case 21: { // Plane/Cylinder
+      Standard_Real VMin, VMax, H;
+      //
+      const Handle(Adaptor3d_HSurface)& aSCyl = bReverse ? S2 : S1;
+      VMin = aSCyl->FirstVParameter();
+      VMax = aSCyl->LastVParameter();
+      H = (Precision::IsNegativeInfinite(VMin) || 
+           Precision::IsPositiveInfinite(VMax)) ? 0 : (VMax - VMin);
+      //
+      if (!IntPCy(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, H)) {
+        return;
       }
-
+      bEmpty = empt;
+      break;
     }
-    break;
-
-  case GeomAbs_Sphere:
-    {
-      quad1.SetValue(S1->Sphere());
-
-      switch (typs2){
-
-      case GeomAbs_Plane:
-       {
-         quad2.SetValue(S2->Plane());
-         //modified by NIZNHY-PKV Tue Sep 20 09:03:35 2011f
-         if (!IntPSp(quad1,quad2,Tolang,TolTang,Standard_True,empt,slin,spnt)) {
-         //if (!IntPSp(quad1,quad2,TolTang,Standard_True,empt,slin,spnt)) {
-           //modified by NIZNHY-PKV Tue Sep 20 09:03:38 2011t
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cylinder:
-       {
-         quad2.SetValue(S2->Cylinder());
-         if (!IntCySp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Sphere:
-       {
-         quad2.SetValue(S2->Sphere());
-         if (!IntSpSp(quad1,quad2,TolTang,empt,SameSurf,slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cone:
-       {
-         quad2.SetValue(S2->Cone());
-         if (!IntCoSp(quad1,quad2,TolTang,Standard_True,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-      default: 
-       {
-         Standard_ConstructionError::Raise();
-         break;
-       }
+    //
+    case 13:
+    case 31: { // Plane/Cone
+      if (!IntPCo(quad1, quad2, Tolang, TolTang, bReverse, empt, multpoint, slin, spnt)) {
+        return;
       }
-
+      bEmpty = empt;
+      break;
     }
-    break;
-
-  case GeomAbs_Cone:
-    {
-      quad1.SetValue(S1->Cone());
-
-      switch (typs2){
-
-      case GeomAbs_Plane:
-       {
-         quad2.SetValue(S2->Plane());
-         if (!IntPCo(quad1,quad2,Tolang,TolTang,Standard_True,
-                     empt,multpoint,slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cylinder:
-       {
-         quad2.SetValue(S2->Cylinder());
-         if (!IntCyCo(quad1,quad2,TolTang,Standard_True,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Sphere:
-       {
-         quad2.SetValue(S2->Sphere());
-         if (!IntCoSp(quad1,quad2,TolTang,Standard_False,empt,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      case GeomAbs_Cone:
-       {
-         quad2.SetValue(S2->Cone());
-         if (!IntCoCo(quad1,quad2,TolTang,empt,SameSurf,multpoint,
-                      slin,spnt)) {
-           return;
-         }
-         if (empt) {
-           done = Standard_True;
-           return;
-         }
-       }
-       break;
-
-      default:
-       {
-         Standard_ConstructionError::Raise();
-         break;
-       }
+    //
+    case 14:
+    case 41: { // Plane/Sphere
+      if (!IntPSp(quad1, quad2, Tolang, TolTang, bReverse, empt, slin, spnt)) {
+        return;
       }
-
-    }
-    break;
-    default:
-    {
-      Standard_ConstructionError::Raise();
+      bEmpty = empt;
       break;
     }
-  } //switch (typs1) {
-  //
-  if (!SameSurf) {
-    AFunc.SetQuadric(quad2);
-    AFunc.Set(S1);
-    
-    solrst.Perform(AFunc, D1, TolArc, TolTang);
-    if (!solrst.IsDone()) {
-      return;
-    }
-
-    if (solrst.AllArcSolution() && typs1 == typs2) {
-      all1 = Standard_True;
-    }
-    nbpt = solrst.NbPoints();
-    nbseg= solrst.NbSegments();
-    for (i=1; i<= nbpt; i++) {
-      pnt1.Append(solrst.Point(i));
-    }
-    for (i=1; i<= nbseg; i++) {
-      edg1.Append(solrst.Segment(i));
-    }
-    nosolonS1 = (nbpt == 0) && (nbseg == 0);
-
-    if (nosolonS1 && all1) {  // cas de face sans restrictions
-      all1 = Standard_False;
-    }
-  }//if (!SameSurf) {
-  else {
-    nosolonS1 = Standard_True;
-  }
-
-  if (!SameSurf) {
-    AFunc.SetQuadric(quad1);
-    AFunc.Set(S2);
-
-    solrst.Perform(AFunc, D2, TolArc, TolTang);
-    if (!solrst.IsDone()) {
-      return;
-    }
-    
-    if (solrst.AllArcSolution() && typs1 == typs2) {
-      all2 = Standard_True;
+    //
+    case 15:
+    case 51: { // Plane/Torus
+      if (!IntPTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
+        return;
+      }
+      bEmpty = empt;
+      break;
     }
-    nbpt = solrst.NbPoints();
-    nbseg= solrst.NbSegments();
-    for (i=1; i<= nbpt; i++) {
-      pnt2.Append(solrst.Point(i));
+    //
+    case 22:
+      { // Cylinder/Cylinder
+        Bnd_Box2d aBox1, aBox2;
+
+        const Standard_Real aU1f = S1->FirstUParameter();
+        Standard_Real aU1l = S1->LastUParameter();
+        const Standard_Real aU2f = S2->FirstUParameter();
+        Standard_Real aU2l = S2->LastUParameter();
+
+        const Standard_Real anUperiod = 2.0*M_PI;
+
+        if(aU1l - aU1f > anUperiod)
+          aU1l = aU1f + anUperiod;
+
+        if(aU2l - aU2f > anUperiod)
+          aU2l = aU2f + anUperiod;
+
+        aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter()));
+        aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter()));
+        aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter()));
+        aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter()));
+
+        // Resolution is too big if the cylinder radius is
+        // too small. Therefore, we shall bind its value above. 
+        // Here, we use simple constant.
+        const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang),
+                                            S2->UResolution(TolTang)));
+
+        myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
+                                    empt, SameSurf, multpoint, slin, spnt);
+
+        if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
+        {
+          return;
+        }
+
+        bEmpty = empt;
+        if(!slin.IsEmpty())
+        {
+          const Handle(IntPatch_WLine)& aWLine = 
+                                    Handle(IntPatch_WLine)::DownCast(slin.Value(1));
+
+          if(!aWLine.IsNull())
+          {//No geometric solution
+            isPostProcessingRequired = Standard_False;
+          }
+        }
+
+        break;
+      }
+    //
+    case 23:
+    case 32: { // Cylinder/Cone
+      if (!IntCyCo(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
+        return;
+      }
+      bEmpty = empt;
+      break;
     }
-    
-    for (i=1; i<= nbseg; i++) {
-      edg2.Append(solrst.Segment(i));
+    //
+    case 24:
+    case 42: { // Cylinder/Sphere
+      if (!IntCySp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
+        return;
+      }
+      bEmpty = empt;
+      break;
     }
-    nosolonS2 = (nbpt == 0) && (nbseg == 0);
-
-    if (nosolonS2 && all2) {  // cas de face sans restrictions
-      all2 = Standard_False;
+    //
+    case 25:
+    case 52: { // Cylinder/Torus
+      if (!IntCyTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
+        return;
+      }
+      bEmpty = empt;
+      break;
     }
-  }// if (!SameSurf) {
-  else {
-    nosolonS2 = Standard_True;
-  }
-  //
-  if (SameSurf || (all1 && all2)) {
-    // faces "paralleles" parfaites
-    empt = Standard_False;
-    tgte = Standard_True;
-    slin.Clear();
-    spnt.Clear();
-
-    gp_Pnt Ptreference;
-
-    switch (typs1) {
-    case GeomAbs_Plane:      {
-      Ptreference = (S1->Plane()).Location();
+    //
+    case 33: { // Cone/Cone
+      if (!IntCoCo(quad1, quad2, TolTang, empt, SameSurf, multpoint, slin, spnt)) {
+        return;
+      }
+      bEmpty = empt;
+      break;
     }
+    //
+    case 34:
+    case 43: { // Cone/Sphere
+      if (!IntCoSp(quad1, quad2, TolTang, bReverse, empt, multpoint, slin, spnt)) {
+        return;
+      }
+      bEmpty = empt;
       break;
-    case GeomAbs_Cylinder: {
-      Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
     }
+    //
+    case 35:
+    case 53: { // Cone/Torus
+      if (!IntCoTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
+        return;
+      }
       break;
-    case GeomAbs_Sphere:      {
-      Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
     }
+    //
+    case 44: { // Sphere/Sphere
+      if (!IntSpSp(quad1, quad2, TolTang, empt, SameSurf, slin, spnt)) {
+        return;
+      }
+      bEmpty = empt;
       break;
-    case GeomAbs_Cone:      {
-      Ptreference = ElSLib::Value(0.,10.,S1->Cone());
     }
+    //
+    case 45:
+    case 54: { // Sphere/Torus
+      if (!IntSpTo(quad1, quad2, TolTang, bReverse, empt, slin)) {
+        return;
+      }
+      bEmpty = empt;
       break;
-    default: 
+    }
+    //
+    case 55: { // Torus/Torus
+      if (!IntToTo(quad1, quad2, TolTang, SameSurf, empt, slin)) {
+        return;
+      }
+      bEmpty = empt;
       break;
     }
     //
-    oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
-    done = Standard_True;
+    default: {
+      throw Standard_ConstructionError();
+      break;
+    }
+  }
+  //
+  if (bEmpty) {
+    if (myDone == IntStatus_Fail)
+      myDone = IntStatus_OK;
+
     return;
-  }// if (SameSurf || (all1 && all2)) {
+  }
+  //
 
-  if (!nosolonS1 || !nosolonS2) {
-    empt = Standard_False;
-    // C est la qu il faut commencer a bosser...
-    PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
-                   multpoint,TolArc);
+  if(isPostProcessingRequired)
+  {
+    if (!SameSurf) {
+      AFunc.SetQuadric(quad2);
+      AFunc.Set(S1);
     
-    PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
-                   multpoint,TolArc);
+      solrst.Perform(AFunc, D1, TolArc, TolTang);
+      if (!solrst.IsDone()) {
+        return;
+      }
 
-    if (edg1.Length() != 0) {
-      ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
+      if (solrst.AllArcSolution() && typs1 == typs2) {
+        all1 = Standard_True;
+      }
+      nbpt = solrst.NbPoints();
+      nbseg= solrst.NbSegments();
+      for (i = 1; i <= nbpt; i++)
+      {
+        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
+        pnt1.Append(aPt);
+      }
+      for (i = 1; i <= nbseg; i++)
+      {
+        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
+        edg1.Append(aSegm);
+      }
+      nosolonS1 = (nbpt == 0) && (nbseg == 0);
+
+      if (nosolonS1 && all1) {  // cas de face sans restrictions
+        all1 = Standard_False;
+      }
+    }//if (!SameSurf) {
+    else {
+      nosolonS1 = Standard_True;
     }
 
-    if (edg2.Length() != 0) {
-      ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
+    if (!SameSurf) {
+      AFunc.SetQuadric(quad1);
+      AFunc.Set(S2);
+
+      solrst.Perform(AFunc, D2, TolArc, TolTang);
+      if (!solrst.IsDone()) {
+        return;
+      }
+    
+      if (solrst.AllArcSolution() && typs1 == typs2) {
+        all2 = Standard_True;
+      }
+
+      nbpt = solrst.NbPoints();
+      nbseg= solrst.NbSegments();
+      for (i=1; i<= nbpt; i++) {
+        const IntPatch_ThePathPointOfTheSOnBounds& aPt = solrst.Point(i);
+        pnt2.Append(aPt);
+      }
+    
+      for (i=1; i<= nbseg; i++) {
+        const IntPatch_TheSegmentOfTheSOnBounds& aSegm = solrst.Segment(i);
+        edg2.Append(aSegm);
+      }
+      
+      nosolonS2 = (nbpt == 0) && (nbseg == 0);
+
+      if (nosolonS2 && all2) {  // cas de face sans restrictions
+        all2 = Standard_False;
+      }
+    }// if (!SameSurf) {
+    else {
+      nosolonS2 = Standard_True;
     }
+    //
+    if (SameSurf || (all1 && all2)) {
+      // faces "paralleles" parfaites
+      empt = Standard_False;
+      tgte = Standard_True;
+      slin.Clear();
+      spnt.Clear();
+
+      gp_Pnt Ptreference;
+
+      switch (typs1) {
+      case GeomAbs_Plane:      {
+        Ptreference = (S1->Plane()).Location();
+      }
+        break;
+      case GeomAbs_Cylinder: {
+        Ptreference = ElSLib::Value(0.,0.,S1->Cylinder());
+      }
+        break;
+      case GeomAbs_Sphere:      {
+        Ptreference = ElSLib::Value(M_PI/4.,M_PI/4.,S1->Sphere());
+      }
+        break;
+      case GeomAbs_Cone:      {
+        Ptreference = ElSLib::Value(0.,10.,S1->Cone());
+      }
+        break;
+      case GeomAbs_Torus:      {
+        Ptreference = ElSLib::Value(0.,0.,S1->Torus());
+      }
+        break;
+      default: 
+        break;
+      }
+      //
+      oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
+      myDone = IntStatus_OK;
+      return;
+    }// if (SameSurf || (all1 && all2)) {
+
+    if (!nosolonS1 || !nosolonS2) {
+      empt = Standard_False;
+      // C est la qu il faut commencer a bosser...
+      PutPointsOnLine(S1,S2,pnt1, slin, Standard_True, D1, quad1,quad2,
+                      multpoint,TolArc);
+    
+      PutPointsOnLine(S1,S2,pnt2, slin, Standard_False,D2, quad2,quad1,
+                      multpoint,TolArc);
+
+      if (edg1.Length() != 0) {
+        ProcessSegments(edg1,slin,quad1,quad2,Standard_True,TolArc);
+      }
 
-    if (edg1.Length() !=0 || edg2.Length() !=0) {
-      //      ProcessRLine(slin,S1,S2,TolArc);
-      ProcessRLine(slin,quad1,quad2,TolArc);
+      if (edg2.Length() != 0) {
+        ProcessSegments(edg2,slin,quad1,quad2,Standard_False,TolArc);
+      }
+
+      if (edg1.Length() !=0 || edg2.Length() !=0) {
+        //      ProcessRLine(slin,S1,S2,TolArc);
+        ProcessRLine(slin,quad1,quad2,TolArc, theIsReqToKeepRLine);
+      }
+    }//if (!nosolonS1 || !nosolonS2) {
+    else {
+      empt = ((slin.Length()==0) && (spnt.Length()==0));
     }
-  }//if (!nosolonS1 || !nosolonS2) {
-  else {
-    empt = ((slin.Length()==0) && (spnt.Length()==0));
   }
-  //
-  Standard_Integer nblin, aNbPnt;
+  
+  Standard_Integer  nblin = slin.Length(),
+                    aNbPnt = spnt.Length();
   //
   //modified by NIZNHY-PKV Tue Sep 06 10:03:35 2011f
-  aNbPnt=spnt.Length();
   if (aNbPnt) {
     IntPatch_SequenceOfPoint aSIP;
     //
@@ -496,7 +450,7 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
       aState2=D2->Classify(aP2D, TolArc);
       //
       if(aState1!=TopAbs_OUT && aState2!=TopAbs_OUT) {
-       aSIP.Append(aIP);
+        aSIP.Append(aIP);
       }
     }
     //
@@ -511,7 +465,6 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
   }//  if (aNbPnt) {
   //modified by NIZNHY-PKV Tue Sep 06 10:18:20 2011t
   //
-  nblin = slin.Length();
   for(i=1; i<=nblin; i++) {
     IntPatch_IType thetype = slin.Value(i)->ArcType();
     if(  (thetype ==  IntPatch_Ellipse)
@@ -539,53 +492,88 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
     gp_Pnt P;
     IntPatch_Point point;
     Standard_Real u1,v1,u2,v2; 
-    Standard_Integer nbv;
     if(slin.Value(i)->ArcType() == IntPatch_Circle) { 
       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
-      nbv = glin->NbVertex();
       if(glin->NbVertex() == 0) { 
-       gp_Circ Circ = glin->Circle();
-       P=ElCLib::Value(0.0,Circ);
-       quad1.Parameters(P,u1,v1);
-       quad2.Parameters(P,u2,v2);
-       point.SetValue(P,TolArc,Standard_False);
-       point.SetParameters(u1,v1,u2,v2);
-       point.SetParameter(0.0);
-       glin->AddVertex(point);
-
-       P=ElCLib::Value(0.0,Circ);
-       quad1.Parameters(P,u1,v1);
-       quad2.Parameters(P,u2,v2);
-       point.SetValue(P,TolArc,Standard_False);
-       point.SetParameters(u1,v1,u2,v2);
-       point.SetParameter(M_PI+M_PI);
-       glin->AddVertex(point);
+        gp_Circ Circ = glin->Circle();
+        P=ElCLib::Value(0.0,Circ);
+        quad1.Parameters(P,u1,v1);
+        quad2.Parameters(P,u2,v2);
+        point.SetValue(P,TolArc,Standard_False);
+        point.SetParameters(u1,v1,u2,v2);
+        point.SetParameter(0.0);
+        glin->AddVertex(point);
+
+        P=ElCLib::Value(0.0,Circ);
+        quad1.Parameters(P,u1,v1);
+        quad2.Parameters(P,u2,v2);
+        point.SetValue(P,TolArc,Standard_False);
+        point.SetParameters(u1,v1,u2,v2);
+        point.SetParameter(M_PI+M_PI);
+        glin->AddVertex(point);
       }
     }
     
     else if(slin.Value(i)->ArcType() == IntPatch_Ellipse) { 
       const Handle(IntPatch_GLine)& glin = *((Handle(IntPatch_GLine)*)&slin.Value(i));
-      nbv = glin->NbVertex();
       if(glin->NbVertex() == 0) { 
-       gp_Elips Elips = glin->Ellipse();
-       P=ElCLib::Value(0.0,Elips);
-       quad1.Parameters(P,u1,v1);
-       quad2.Parameters(P,u2,v2);
-       point.SetValue(P,TolArc,Standard_False);
-       point.SetParameters(u1,v1,u2,v2);
-       point.SetParameter(0.0);
-       glin->AddVertex(point);
-
-       P=ElCLib::Value(0.0,Elips);
-       quad1.Parameters(P,u1,v1);
-       quad2.Parameters(P,u2,v2);
-       point.SetValue(P,TolArc,Standard_False);
-       point.SetParameters(u1,v1,u2,v2);
-       point.SetParameter(M_PI+M_PI);
-       glin->AddVertex(point);
+        gp_Elips Elips = glin->Ellipse();
+        P=ElCLib::Value(0.0,Elips);
+        quad1.Parameters(P,u1,v1);
+        quad2.Parameters(P,u2,v2);
+        point.SetValue(P,TolArc,Standard_False);
+        point.SetParameters(u1,v1,u2,v2);
+        point.SetParameter(0.0);
+        glin->AddVertex(point);
+
+        P=ElCLib::Value(0.0,Elips);
+        quad1.Parameters(P,u1,v1);
+        quad2.Parameters(P,u2,v2);
+        point.SetValue(P,TolArc,Standard_False);
+        point.SetParameters(u1,v1,u2,v2);
+        point.SetParameter(M_PI+M_PI);
+        glin->AddVertex(point);
       }
     }
   }
-  done = Standard_True;
+  myDone = IntStatus_OK;
+}
+
+//=======================================================================
+//function : SetQuad
+//purpose  : 
+//=======================================================================
+Standard_Integer SetQuad(const Handle(Adaptor3d_HSurface)& theS,
+                         GeomAbs_SurfaceType& theTS,
+                         IntSurf_Quadric& theQuad)
+{
+  theTS = theS->GetType();
+  Standard_Integer iRet = 0;
+  switch (theTS) {
+  case GeomAbs_Plane:
+    theQuad.SetValue(theS->Plane());
+    iRet = 1;
+    break;
+  case GeomAbs_Cylinder:
+    theQuad.SetValue(theS->Cylinder());
+    iRet = 2;
+    break;
+  case GeomAbs_Cone:
+    theQuad.SetValue(theS->Cone());
+    iRet = 3;
+    break;
+  case GeomAbs_Sphere:
+    theQuad.SetValue(theS->Sphere());
+    iRet = 4;
+    break;
+  case GeomAbs_Torus:
+    theQuad.SetValue(theS->Torus());
+    iRet = 5;
+    break;
+  default:
+    break;
+  }
+  //
+  return iRet;
 }