0029807: [Regression to 7.0.0] Impossible to cut cone from prism
[occt.git] / src / IntPatch / IntPatch_ImpPrmIntersection.cxx
index 5bdde31..a54ded5 100644 (file)
@@ -19,6 +19,7 @@
 #include <Adaptor3d_HSurface.hxx>
 #include <Adaptor3d_TopolTool.hxx>
 #include <ElCLib.hxx>
+#include <ElSLib.hxx>
 #include <IntPatch_ArcFunction.hxx>
 #include <IntPatch_PointLine.hxx>
 #include <IntPatch_RLine.hxx>
@@ -87,6 +88,7 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
                                          const Handle(IntSurf_LineOn2S)& theLine,
                                          const Standard_Boolean IsReversed,
                                          const Standard_Integer theRefIndex,
+                                         const Standard_Real theTol3D,
                                          const Standard_Real theDeltaMax)
 {
   if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
@@ -96,6 +98,8 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
   Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
   Standard_Real aUQNext, aVQNext, aUPNext, aVPNext;
 
+  const gp_Pnt &aP3d = theLine->Value(theRefIndex + 1).Value();
+
   if(IsReversed)
   {
     theLine->Value(theRefIndex).Parameters  (aUPRef, aVPRef, aUQRef, aVQRef);
@@ -109,6 +113,28 @@ static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_HSurface)& theQS
 
   const GeomAbs_SurfaceType aType = theQSurf->GetType();
 
+  if ((aType == GeomAbs_Cone) && 
+      (theQSurf->Cone().Apex().SquareDistance(aP3d) < theTol3D*theTol3D))
+  {
+    return IntPatch_SPntPoleSeamU;
+  }
+  else if (aType == GeomAbs_Sphere)
+  {
+    const Standard_Real aSqTol = theTol3D*theTol3D;
+    gp_Pnt aP(ElSLib::Value(0.0, M_PI_2, theQSurf->Sphere()));
+    if (aP.SquareDistance(aP3d) < aSqTol)
+    {
+      return IntPatch_SPntPoleSeamU;
+    }
+    
+    aP = ElSLib::Value(0.0, -M_PI_2, theQSurf->Sphere());
+    if (aP.SquareDistance(aP3d) < aSqTol)
+    {
+      return IntPatch_SPntPoleSeamU;
+    }
+  }
+  
+
   const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
 
   if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
@@ -2628,6 +2654,15 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
                                                               PrePoint, IsReversed))
       {
         sline->Add(PrePoint);
+
+        //Avoid adding duplicate points.
+        for (;aFindex <= aLindex; aFindex++)
+        {
+          if (!PrePoint.IsSame(aSSLine->Value(aFindex), theTolTang))
+          {
+            break;
+          }
+        }
       }
       else
       {
@@ -2658,7 +2693,8 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
       DetectOfBoundaryAchievement(theQSurf, IsReversed, aSSLine,
                                   k, aTOL2D, sline, isOnBoundary);
 
-      aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed, k - 1, aDeltaUmax);
+      aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed,
+                                    k - 1, theTolTang, aDeltaUmax);
 
       if (isOnBoundary && (aPrePointExist != IntPatch_SPntPoleSeamU))
       {
@@ -2742,7 +2778,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
           aSupBound(3) = theQSurf->LastUParameter();
 
           IntPatch_SpecialPoints::
-                      AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False,
+                      AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False, 0.0,
                                         aTol, aStartPoint, anInfBound, aSupBound,
                                         aNewPoint, IsReversed);
         }
@@ -2752,9 +2788,10 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
 
           IntPatch_Point aVert;
           aVert.SetValue(aRefPt);
+          aVert.SetTolerance(theTolTang);
 
           if(IntPatch_SpecialPoints::
-                      AddSingularPole(theQSurf, thePSurf, aRefPt, theTolTang,
+                      AddSingularPole(theQSurf, thePSurf, aRefPt,
                                       aVert, aNewPoint, IsReversed))
           {
             aPrePointExist = IntPatch_SPntPole;
@@ -2823,7 +2860,7 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
           aSupBound(3) = theQSurf->LastVParameter();
 
           IntPatch_SpecialPoints::
-                AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, aTol,
+                AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, 0.0, aTol,
                                   aStartPoint, anInfBound, aSupBound, aNewPoint,
                                   IsReversed);
         }
@@ -2878,7 +2915,9 @@ static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLin
     if(sline->NbPoints() == 1)
     {
       flNextLine = Standard_True;
-      aFindex = aBindex;
+      
+      if (aFindex < aBindex)
+        aFindex = aBindex;
 
       //Go to the next part of aSSLine
       //because we cannot create the line