0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D.cxx
index 2798ee3..4e54d58 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BOPTools_AlgoTools2D.ixx>
 
-#include <Standard_NotImplemented.hxx>
-#include <Precision.hxx>
-#include <gp.hxx>
-
-#include <gp_Pnt.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Vec2d.hxx>
-
-#include <Geom2d_Curve.hxx>
-#include <Geom2d_Line.hxx>
+#include <BOPCol_IndexedMapOfShape.hxx>
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_CurveRepresentation.hxx>
+#include <BRep_GCurve.hxx>
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepClass_FaceClassifier.hxx>
+#include <BRepTools.hxx>
+#include <Geom2d_BSplineCurve.hxx>
 #include <Geom2d_Circle.hxx>
+#include <Geom2d_Curve.hxx>
 #include <Geom2d_Ellipse.hxx>
-#include <Geom2d_Parabola.hxx>
 #include <Geom2d_Hyperbola.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2d_Parabola.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
-
 #include <Geom2dAdaptor.hxx>
-
 #include <Geom_Curve.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_Surface.hxx>
 #include <Geom_Plane.hxx>
-
-#include <GeomAdaptor_Surface.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GeomAdaptor_HCurve.hxx>
 #include <GeomAdaptor_HSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-
+#include <GeomAdaptor_Surface.hxx>
+#include <GeomInt.hxx>
 #include <GeomProjLib.hxx>
-
-#include <TopLoc_Location.hxx>
-#include <TopExp.hxx>
-
+#include <gp.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec.hxx>
+#include <gp_Vec2d.hxx>
+#include <IntTools_Context.hxx>
+#include <IntTools_Tools.hxx>
+#include <Precision.hxx>
 #include <ProjLib_ProjectedCurve.hxx>
-
-#include <BRep_Tool.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
-#include <BRep_TEdge.hxx>
-#include <BRep_CurveRepresentation.hxx>
-#include <BRep_GCurve.hxx>
-
-#include <BRepAdaptor_HSurface.hxx>
-
-#include <BRepAdaptor_Curve.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepClass_FaceClassifier.hxx>
-
-#include <BRepTools.hxx>
-
-#include <BOPCol_IndexedMapOfShape.hxx>
-
-#include <BOPTools.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
 
 static 
   Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
@@ -87,6 +81,8 @@ static
                                                 Standard_Real& ,
                                                 Standard_Real& ,
                                                 Standard_Boolean& );
+static
+  Standard_Real MaxToleranceEdge (const TopoDS_Face& );
 
 //=======================================================================
 //function : BuildPCurveForEdgeOnFace
@@ -278,34 +274,55 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnFace
    const Handle(Geom2d_Curve)& aC2D, 
    Handle(Geom2d_Curve)& aC2DA)
 {
-  Standard_Real first, last;
-
-  first = aC3D -> FirstParameter();
-  last  = aC3D -> LastParameter();
-  BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
-} 
+  Standard_Real aT1, aT2;
+  //
+  aT1=aC3D->FirstParameter();
+  aT2=aC3D->LastParameter();
+  //
+  BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aT1, aT2, aC2D, aC2DA);
+}
 //=======================================================================
 //function : AdjustPCurveOnFace
 //purpose  : 
 //=======================================================================
 void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
   (const TopoDS_Face& aF,
+   const Standard_Real aT1,
+   const Standard_Real aT2,
+   const Handle(Geom2d_Curve)& aC2D, 
+   Handle(Geom2d_Curve)& aC2DA)
+{
+  BRepAdaptor_Surface aBAS(aF, Standard_True);
+  //
+  BOPTools_AlgoTools2D::AdjustPCurveOnFace(aBAS, aT1, aT2, 
+                                          aC2D, aC2DA);
+}
+
+//=======================================================================
+//function : AdjustPCurveOnFace
+//purpose  : 
+//=======================================================================
+void BOPTools_AlgoTools2D::AdjustPCurveOnFace 
+  (const BRepAdaptor_Surface& aBAS,
    const Standard_Real aFirst,
    const Standard_Real aLast,
    const Handle(Geom2d_Curve)& aC2D, 
    Handle(Geom2d_Curve)& aC2DA)
 {
-  Standard_Boolean mincond, maxcond, decalu, decalv;
-  Standard_Integer k, iCnt;
+  Standard_Boolean mincond, maxcond;
   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
-  Standard_Real aUPeriod, aUP2, aUP1, aUNew, aDif, aUx;
+  Standard_Real aUPeriod;
   //
-  aDelta=Precision::PConfusion();
-  
-  BRepAdaptor_Surface aBAS(aF, Standard_False);
-  BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
+  const TopoDS_Face& aF=aBAS.Face();
+  UMin=aBAS.FirstUParameter();
+  UMax=aBAS.LastUParameter();
+  VMin=aBAS.FirstVParameter();
+  VMax=aBAS.LastVParameter();
+  //
+  //BRepAdaptor_Surface aBAS(aF, Standard_False);
+  //BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
+  //
+  aDelta=Precision::PConfusion(); 
   
   aT =.5*(aFirst+aLast);
 
@@ -314,68 +331,57 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnFace
 
   u2 = pC2D.X();
   v2 = pC2D.Y();
+  //
+  // du
   du = 0.;
   if (aBAS.IsUPeriodic()) {
-    aUPeriod=aBAS.UPeriod(); 
-    mincond = (u2 < UMin-aDelta);
-    maxcond = (u2 > UMax+aDelta); 
+    aUPeriod = aBAS.UPeriod(); 
     
-    decalu = mincond || maxcond;
-    if (decalu) {
-      //du = ( mincond ) ? UPeriod : -UPeriod;
-      //
-      iCnt=1;
-      aUP2=aUPeriod+aUPeriod+aDelta;
-      aUP1=aUPeriod+aDelta;
-      //
-      if (u2 > aUP2) {
-        k=1;
-        do {
-          aUx=u2-k*aUPeriod;
-          iCnt = k++;
-        } while (aUx >= aUP1);
-      }
-      else if (u2 < -aUP2) {
-        k=1;
-        do {
-          aUx=u2+k*aUPeriod;
-          iCnt = (k++) + 1;
-        } while (aUx <= -aUP1);
-      }
-      du = ( mincond ) ? aUPeriod : -aUPeriod;
-      du=iCnt*du;
+    //
+    // a. try to clarify u2 using the precision (aDelta)
+    if (fabs(u2-UMin) < aDelta) {
+      u2=UMin;
+    }
+    else if (fabs(u2-UMin-aUPeriod) < aDelta) {
+      u2=UMin+aUPeriod;
     }
+    // b. compute du again using clarified value of u2
+    GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
     //
-    aUNew=u2+du;
-    if (aUNew<(UMin-aDelta) || 
-        aUNew>(UMax+aDelta)) {
-      // So previous correction was wrong.
-      // Try to be closer to UMin or UMax.
-      du=0.;
-      if (u2>UMax){
-        aDif=u2-UMax;
-        if (aDif < 4.e-7) {
-          du=-aDif;
+    if (du==0.) {
+      if (aBAS.GetType()==GeomAbs_Cylinder) {
+        Standard_Real aR, dFi, aTol;
+        //
+        gp_Cylinder aCylinder=aBAS.Cylinder();
+        aR=aCylinder.Radius();
+        aTol=MaxToleranceEdge(aF);
+        dFi=aTol/aR;
+        if (dFi<aDelta) {
+          dFi=aDelta;
+        }
+        //
+        mincond = (UMin - u2 > dFi);
+        maxcond = (u2 - UMax > dFi);
+        if (mincond || maxcond) {
+          du = ( mincond ) ? aUPeriod : -aUPeriod;
         }
       }
-    }
-  } // if (BAHS->IsUPeriodic())
-  //
+    } 
+  }
+  
   // dv
   dv = 0.;
   if (aBAS.IsVPeriodic()) {
     Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
     //
-    aVPeriod=aBAS.VPeriod();
+    aVPeriod = aBAS.VPeriod();
     mincond = (VMin - v2 > aDelta);
     maxcond = (v2 - VMax > aDelta);
-    decalv = mincond || maxcond;
-    if (decalv) {
+    //
+    if (mincond || maxcond) {
       dv = ( mincond ) ? aVPeriod : -aVPeriod;
     }
     //
-    //xf
     if ((VMax-VMin<aVPeriod) && dv) {
       aVm=v2;
       aVr=v2+dv;
@@ -386,7 +392,6 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnFace
         dv=0.;
       }
     }
-    //xt
   }
   //
   {
@@ -548,7 +553,7 @@ void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
   }
   
   //
-  aToler=.5*BRep_Tool::Tolerance(aE);
+  aToler = BRep_Tool::Tolerance(aE);
   BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
   //
   aFirst = f3d; 
@@ -582,28 +587,44 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
 void BOPTools_AlgoTools2D::MakePCurveOnFace 
   (const TopoDS_Face& aF,
    const Handle(Geom_Curve)& aC3D,
-   const Standard_Real aFirst,
-   const Standard_Real aLast,
+   const Standard_Real aT1,
+   const Standard_Real aT2,
    Handle(Geom2d_Curve)& aC2D, 
    Standard_Real& TolReached2d)
 {
-  Standard_Real aTolR;
+  Standard_Real aTolR, aT;
+  Standard_Real aUMin, aUMax, aVMin, aVMax;
   Handle(Geom2d_Curve) aC2DA;
+  Handle(GeomAdaptor_HSurface) aBAHS;
+  Handle(GeomAdaptor_HCurve) aBAHC;
+  Handle(Geom_Surface) aS;
+  //
+  BRepAdaptor_Surface aBAS(aF, Standard_True);
+  aUMin=aBAS.FirstUParameter();
+  aUMax=aBAS.LastUParameter();
+  aVMin=aBAS.FirstVParameter();
+  aVMax=aBAS.LastVParameter();
+  aS=aBAS.Surface().Surface();
+  aS=Handle(Geom_Surface)::DownCast(aS->Transformed(aBAS.Trsf()));
+  GeomAdaptor_Surface aGAS(aS, aUMin, aUMax, aVMin, aVMax);
+  //
+  aBAHS=new GeomAdaptor_HSurface(aGAS);
+  aBAHC=new GeomAdaptor_HCurve(aC3D, aT1, aT2);
   //
-  Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
-  GeomAdaptor_Surface aGAS(aS);
-  Handle(GeomAdaptor_HSurface) aBAHS=
-    new GeomAdaptor_HSurface(aGAS);
-  Handle(GeomAdaptor_HCurve) aBAHC = 
-    new GeomAdaptor_HCurve(aC3D, aFirst, aLast);
-  
   //when the type of surface is GeomAbs_SurfaceOfRevolution
   if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
-    Standard_Real aTR = 1.e-7;
+    Standard_Real aTR;
+    //
+    aTR=Precision::Confusion();//1.e-7;
+    if (TolReached2d > aTR) {
+      aTR=TolReached2d;
+    }
+    //
     ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
     BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
     aTolR = aProj1.GetTolerance();
-  } else {
+  } 
+  else {
     ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
     BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
     aTolR=aProjCurv.GetTolerance();
@@ -621,11 +642,25 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
       aTolR = aProj3.GetTolerance();
     }
   }
+  //
+  if(aC2D.IsNull())
+  {
+    Standard_ConstructionError::Raise("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null");
+  }
+  //
   TolReached2d=aTolR;
-  
-  BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aFirst, aLast, 
+  BOPTools_AlgoTools2D::AdjustPCurveOnFace (aBAS, aT1, aT2, 
                                             aC2D, aC2DA);
+  //
   aC2D=aC2DA;
+  //
+  // compute the appropriate tolerance for the edge
+  if (IntTools_Tools::ComputeTolerance
+      (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
+    if (aTolR > TolReached2d) {
+      TolReached2d = aTolR;
+    }
+  }
 }
 
 //=======================================================================
@@ -746,7 +781,7 @@ Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
   while (itcr.More()) {
     const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
     if (cr->IsCurveOnSurface(S,loc)) {
-      const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
+      Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
       GC->Range(First,Last);
       if (GC->IsCurveOnClosedSurface() && Eisreversed)
         return GC->PCurve2();
@@ -790,7 +825,7 @@ Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
     if (!LC.IsIdentity()) {
       const gp_Trsf& T = LC.Transformation();
       Handle(Geom_Geometry) GPT = GP->Transformed(T);
-      Plane = *((Handle(Geom_Plane)*)&GPT);
+      Plane = Handle(Geom_Plane)::DownCast (GPT);
     }
     GeomAdaptor_Surface& GAS = HS->ChangeSurface();
     GAS.Load(Plane);
@@ -809,7 +844,7 @@ Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
 
     if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
       Handle(Geom2d_TrimmedCurve) TC = 
-        (*((Handle(Geom2d_TrimmedCurve)*)&pc));
+        Handle(Geom2d_TrimmedCurve)::DownCast (pc);
       pc = TC->BasisCurve();
     }
     First = f; Last = l;
@@ -821,3 +856,23 @@ Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
   
   return nullPCurve;
 }
+//=======================================================================
+//function : MaxToleranceEdge
+//purpose  : 
+//=======================================================================
+Standard_Real MaxToleranceEdge (const TopoDS_Face& aF) 
+{
+  Standard_Real aTol, aTolMax;
+  TopExp_Explorer aExp;
+  //
+  aTolMax=0.;
+  aExp.Init(aF, TopAbs_EDGE);
+  for (; aExp.More(); aExp.Next()) {
+    const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
+    aTol=BRep_Tool::Tolerance(aE);
+    if (aTol>aTolMax) {
+      aTolMax=aTol;
+    }
+  }
+  return aTolMax;
+}