0027664: Incomplete intersection curve from the attached shapes
[occt.git] / src / IntPatch / IntPatch_RstInt.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 36789e8..9b66768
@@ -1,23 +1,18 @@
 // Created on: 1993-05-07
 // Created by: Jacques GOUSSARD
 // Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 // ----------------------------------------------------------------------
 //-- lbr: Modifs importantes du 16-17 Nov 95
 //--      - Pour rester coherent avec cette facon de faire, 
 //--      Chercher(Nbvtx++). 
 
-#include <IntPatch_RstInt.ixx>
-
-#include <IntSurf.hxx>
-
-#include <TColgp_SequenceOfPnt.hxx>
-#include <TColgp_SequenceOfPnt2d.hxx>
+#include <Adaptor2d_HCurve2d.hxx>
+#include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_TopolTool.hxx>
+#include <gp_Pnt2d.hxx>
 #include <Intf_SectionPoint.hxx>
 #include <Intf_TangentZone.hxx>
-#include <gp_Pnt2d.hxx>
-#include <Precision.hxx>
-
-#include <Adaptor2d_HCurve2d.hxx>
-#include <IntPatch_WLine.hxx>
-#include <IntPatch_RLine.hxx>
-#include <IntPatch_HInterTool.hxx>
-#include <IntPatch_SearchPnt.hxx>
-#include <IntPatch_PolyLine.hxx>
-#include <IntPatch_PolyArc.hxx>
 #include <IntPatch_CSFunction.hxx>
 #include <IntPatch_CurvIntSurf.hxx>
+#include <IntPatch_HInterTool.hxx>
+#include <IntPatch_Line.hxx>
+#include <IntPatch_PolyArc.hxx>
+#include <IntPatch_PolyLine.hxx>
+#include <IntPatch_RLine.hxx>
+#include <IntPatch_RstInt.hxx>
+#include <IntPatch_SearchPnt.hxx>
+#include <IntPatch_WLine.hxx>
+#include <IntSurf.hxx>
+#include <Precision.hxx>
+#include <Standard_DomainError.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_SequenceOfPnt2d.hxx>
+
+#include <ElCLib.hxx>
 
+#define myInfinite 1.e15 // the same as was in Adaptor3d_TopolTool
 
 static void Recadre(GeomAbs_SurfaceType typeS1,
                     GeomAbs_SurfaceType typeS2,
@@ -193,9 +192,9 @@ static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
                            const Standard_Boolean OnFirst,
                            Standard_Real& U, Standard_Real& V)
 {
+  Handle(IntPatch_WLine) wlin = Handle(IntPatch_WLine)::DownCast(L);
+  Handle(IntPatch_RLine) rlin = Handle(IntPatch_RLine)::DownCast(L);
   IntPatch_IType typL = L->ArcType();
-  const Handle(IntPatch_WLine)& wlin = (const Handle(IntPatch_WLine)&)L;
-  const Handle(IntPatch_RLine)& rlin = (const Handle(IntPatch_RLine)&)L;
   Standard_Integer Nbptlin = (typL == IntPatch_Walking
                              ? wlin->NbPnts()
                              : rlin->NbPnts());
@@ -290,8 +289,8 @@ static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
   // Dans le cas d une ligne de cheminement, il faudrait voir la projection
   // et le calcul de la tangente.
 
-  const Handle(IntPatch_RLine)&  rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est 
-  const Handle(IntPatch_WLine)&  wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast. 
+  Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est 
+  Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast. 
   gp_Pnt ptbid;
   gp_Vec d1u,d1v;
   gp_Pnt2d p2d;
@@ -444,12 +443,12 @@ static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
 //purpose  : 
 //=======================================================================
 
-void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
-                                      const Handle(Adaptor3d_HSurface)& Surf,
-                                      const Handle(Adaptor3d_TopolTool)& Domain,
-                                      const Handle(Adaptor3d_HSurface)& OtherSurf,
-                                      const Standard_Boolean OnFirst,
-                                      const Standard_Real Tol )
+void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
+                                       const Handle(Adaptor3d_HSurface)& Surf,
+                                       const Handle(Adaptor3d_TopolTool)& Domain,
+                                       const Handle(Adaptor3d_HSurface)& OtherSurf,
+                                       const Standard_Boolean OnFirst,
+                                       const Standard_Real Tol)
  {
 
 // Domain est le domaine de restriction de la surface Surf.
@@ -465,8 +464,8 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
   Standard_Integer i,j,k;
   TColgp_SequenceOfPnt locpt;
   TColgp_SequenceOfPnt2d locpt2;
-  const Handle(IntPatch_RLine)&  rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est 
-  const Handle(IntPatch_WLine)&  wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast. 
+  Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est 
+  Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast. 
   Standard_Integer Nbvtx =0; 
   Standard_Integer Nbptlin =0;
   Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
@@ -558,11 +557,15 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
     Standard_Real VRes = Surf->VResolution(edgeTol);
 
     IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
-    if (Precision::IsNegativeInfinite(PFirst) || 
-       Precision::IsPositiveInfinite(PLast)) { 
-      //-- cout<<" IntPatch_RstInt::PutVertexOnLine  ---> Restrictions Infinies :"<<endl;
-      return; 
-    }
+    if(Precision::IsNegativeInfinite(PFirst))
+      PFirst = -myInfinite;
+    if(Precision::IsPositiveInfinite(PLast))
+      PLast = myInfinite;
+    //if (Precision::IsNegativeInfinite(PFirst) || 
+          // Precision::IsPositiveInfinite(PLast)) { 
+    //  //-- cout<<" IntPatch_RstInt::PutVertexOnLine  ---> Restrictions Infinies :"<<endl;
+    //  return;
+    //}
 
     Standard_Boolean isVFirst = Standard_False, isVLast = Standard_False;
     gp_Pnt2d p2dFirst,p2dLast;
@@ -588,29 +591,40 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
     }
 
     Bnd_Box2d BPLin = PLin.Bounding();
-
-    if(SurfaceIsPeriodic) { 
-      Standard_Real xmin,ymin,xmax,ymax,g;
-      BPLin.Get(xmin,ymin,xmax,ymax);
-      g = BPLin.GetGap();
-      BPLin.SetVoid();
-      BPLin.Update(xmin-M_PI-M_PI,ymin,
-                  xmax+M_PI+M_PI,ymax);
-      BPLin.SetGap(g);
-    }
-    if(SurfaceIsBiPeriodic) { 
-      Standard_Real xmin,ymin,xmax,ymax,g;
-      BPLin.Get(xmin,ymin,xmax,ymax);
-      g = BPLin.GetGap();
-      BPLin.SetVoid();
-      BPLin.Update(xmin,ymin-M_PI-M_PI,
-                  xmax,ymax+M_PI+M_PI);
-      BPLin.SetGap(g);
-    }
+    Standard_Real OffsetV = 0.0;
+    Standard_Real OffsetU = 0.0;
 
     switch(arc->GetType())
     { 
-      case GeomAbs_Line: NbEchant=10; break;
+      case GeomAbs_Line:
+        {
+          NbEchant=10;
+          
+          Standard_Real aXmin, aYmin, aXmax, aYmax;
+          BPLin.Get(aXmin, aYmin, aXmax, aYmax);
+          gp_Lin2d aLin = arc->Curve2d().Line();
+          const gp_Pnt2d& aLoc = aLin.Location();
+          const gp_Dir2d& aDir = aLin.Direction();
+
+          //Here, we consider rectangular axis-aligned domain only.
+          const Standard_Boolean isAlongU = (Abs(aDir.X()) > Abs(aDir.Y()));
+
+          if(SurfaceIsPeriodic && !isAlongU)
+          {
+            //Shift along U-direction
+            const Standard_Real aNewLocation = 
+                      ElCLib::InPeriod(aLoc.X(), aXmin, aXmin + M_PI + M_PI);
+            OffsetU = aNewLocation - aLoc.X();
+          }
+          else if(SurfaceIsBiPeriodic && isAlongU)
+          {
+            //Shift along V-direction
+            const Standard_Real aNewLocation = 
+                      ElCLib::InPeriod(aLoc.Y(), aYmin, aYmin + M_PI + M_PI);
+            OffsetV = aNewLocation - aLoc.Y();
+          }
+        }
+        break;
       case GeomAbs_BezierCurve:
       {
         NbEchant = (3 + arc->NbPoles());
@@ -633,26 +647,45 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
       }
     }
 
+    if(SurfaceIsPeriodic) { 
+      Standard_Real xmin,ymin,xmax,ymax,g;
+      BPLin.Get(xmin,ymin,xmax,ymax);
+      g = BPLin.GetGap();
+      BPLin.SetVoid();
+      BPLin.Update(xmin-M_PI-M_PI,ymin,
+                  xmax+M_PI+M_PI,ymax);
+      BPLin.SetGap(g);
+    }
+    if(SurfaceIsBiPeriodic) { 
+      Standard_Real xmin,ymin,xmax,ymax,g;
+      BPLin.Get(xmin,ymin,xmax,ymax);
+      g = BPLin.GetGap();
+      BPLin.SetVoid();
+      BPLin.Update(xmin,ymin-M_PI-M_PI,
+                  xmax,ymax+M_PI+M_PI);
+      BPLin.SetGap(g);
+    }
+
     IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin);
 
     Standard_Integer IndiceOffsetBiPeriodic = 0;    
-    Standard_Integer IndiceOffsetPeriodic   = 0;    
-    Standard_Real OffsetV = 0.0;
-    Standard_Real OffsetU = 0.0;
-    
+    Standard_Integer IndiceOffsetPeriodic   = 0;
+    const Standard_Real aRefOU = OffsetU,
+                        aRefOV = OffsetV;
+
     do { 
       if(IndiceOffsetBiPeriodic == 1) 
-       OffsetV = -M_PI-M_PI;
+        OffsetV = aRefOV - M_PI - M_PI;
       else if(IndiceOffsetBiPeriodic == 2) 
-       OffsetV = M_PI+M_PI;
-      
+        OffsetV = aRefOV + M_PI + M_PI;
+
       do { 
-       if(IndiceOffsetPeriodic == 1) 
-         OffsetU = -M_PI-M_PI;
-       else if(IndiceOffsetPeriodic == 2) 
-         OffsetU = M_PI+M_PI;
-       
-       Brise.SetOffset(OffsetU,OffsetV);
+        if(IndiceOffsetPeriodic == 1) 
+          OffsetU = aRefOU - M_PI - M_PI;
+        else if(IndiceOffsetPeriodic == 2) 
+          OffsetU = aRefOU + M_PI + M_PI;
+
+        Brise.SetOffset(OffsetU,OffsetV);
        
        static int debug_polygon2d =0;
        if(debug_polygon2d) { 
@@ -699,13 +732,15 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
              (!Domain->Has3d() && Standard_Integer(nptCh)+1 < Nbptlin);
            if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) {
              // treat both ends
-             Standard_Real UMinChP,UMaxChP,UMinArP,UMaxArP;
-             UMinChP = IntegerPart(UMinCh); UMinArP = IntegerPart(UMinAr);
-             UMaxChP = IntegerPart(UMaxCh); UMaxArP = IntegerPart(UMaxAr);
-             Standard_Integer irangCh1,irangCh2,irangAr1,irangAr2;
-             irangCh1 = Standard_Integer(UMinChP)+1; irangCh2 = Standard_Integer(UMaxChP)+1;
-             irangAr1 = Standard_Integer(UMinArP)+1; irangAr2 = Standard_Integer(UMaxArP)+1;
-             UMinChP = UMinCh - UMinChP; UMinArP = UMinAr - UMinArP;
+             Standard_Real UMinChP,UMinArP,UMaxArP;
+             UMinChP = IntegerPart(UMinCh);
+              UMinArP = IntegerPart(UMinAr);
+              UMaxArP = IntegerPart(UMaxAr);
+             Standard_Integer irangAr1,irangAr2;
+             irangAr1 = Standard_Integer(UMinArP)+1;
+              irangAr2 = Standard_Integer(UMaxArP)+1;
+             UMinChP = UMinCh - UMinChP;
+              UMinArP = UMinAr - UMinArP;
              //UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP;
              const Standard_Real eps = 1e-10;
 //           Standard_Boolean isChExtr1 = irangCh1==1 && UMinChP<eps;
@@ -764,26 +799,38 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
            }
 
            Standard_Boolean refined = Standard_False;
-           if (refine[ip]) {
-             //------------------------------------------------------------------------
-             //-- On a trouve un point 2d approche Ua,Va  intersection de la ligne
-             //-- de cheminement et de la restriction. 
-             //--
-             //-- On injecte ce point ds les intersections Courbe-Surface
-             //-- 
-             IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
-             // MSV: extend UV bounds to not miss solution near the boundary
-             Standard_Real margCoef = 0.004;
-             IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
-             if (IntCS.IsDone()) {
-               if (!IntCS.IsEmpty()) {
-                 ptsommet = IntCS.Point();
-                 IntCS.ParameterOnSurface(U2,V2);
-                 paramarc = IntCS.ParameterOnCurve();
-                 refined = Standard_True;
-               }
-             }
-           }
+            if (refine[ip])
+            {
+              //------------------------------------------------------------------------
+              //-- On a trouve un point 2d approche Ua,Va  intersection de la ligne
+              //-- de cheminement et de la restriction. 
+              //--
+              //-- On injecte ce point ds les intersections Courbe-Surface
+              //-- 
+              IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
+              // MSV: extend UV bounds to not miss solution near the boundary
+              Standard_Real margCoef = 0.004;
+              IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
+              if (IntCS.IsDone())
+              {
+                if (!IntCS.IsEmpty())
+                {
+                  ptsommet = IntCS.Point();
+                  IntCS.ParameterOnSurface(U2,V2);
+                  gp_Pnt anOldPnt, aNewPnt;
+                  OtherSurf->D0(U,V, anOldPnt);
+                  OtherSurf->D0(U2,V2, aNewPnt);
+                  if (anOldPnt.SquareDistance(aNewPnt) < Precision::Confusion()
+                    * Precision::Confusion())
+                  {
+                    U2 = U;
+                    V2 = V;
+                  }
+                  paramarc = IntCS.ParameterOnCurve();
+                  refined = Standard_True;
+                }
+              }
+            }
            else {
              U2 = U; V2 = V;
              paramarc = W;
@@ -1230,11 +1277,6 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
     wlin->ComputeVertexParameters(Tol);
   }
   else {
-#ifdef DEB
-    //if(rlin->NbVertex()==0) { 
-    //  cout<<" \n *** IntPatch RstInt.gxx  : nbvtx = 0 sur rline *** \n"<<endl;
-    //}
-#endif
     rlin->ComputeVertexParameters(Tol);
   }
 }