0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D.cxx
index 4c6d976..b951a20 100644 (file)
@@ -15,6 +15,7 @@
 #include <BOPTools_AlgoTools2D.ixx>
 
 #include <Standard_NotImplemented.hxx>
+#include <Standard_ConstructionError.hxx>
 #include <Precision.hxx>
 #include <gp.hxx>
 
@@ -30,6 +31,7 @@
 #include <Geom2d_Parabola.hxx>
 #include <Geom2d_Hyperbola.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
 
 #include <Geom2dAdaptor.hxx>
 
@@ -284,19 +286,36 @@ 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, 
@@ -306,11 +325,16 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnFace
   Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
   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);
 
@@ -323,10 +347,18 @@ void BOPTools_AlgoTools2D::AdjustPCurveOnFace
   // du
   du = 0.;
   if (aBAS.IsUPeriodic()) {
-    Standard_Real newu;
     aUPeriod = aBAS.UPeriod(); 
+    
     //
-    GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, newu, 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.);
     //
     if (du==0.) {
       if (aBAS.GetType()==GeomAbs_Cylinder) {
@@ -533,7 +565,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; 
@@ -567,28 +599,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();
@@ -606,11 +654,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;
+    }
+  }
 }
 
 //=======================================================================
@@ -731,7 +793,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();
@@ -775,7 +837,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);
@@ -794,7 +856,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;