0029351: Boolean Operations create invalid pcurves
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D.cxx
index 9e41adb..b24667e 100644 (file)
@@ -13,8 +13,6 @@
 // commercial license or contractual agreement.
 
 
-#include <BOPCol_IndexedMapOfShape.hxx>
-#include <BOPTools.hxx>
 #include <BOPTools_AlgoTools2D.hxx>
 #include <BRep_Builder.hxx>
 #include <BRep_CurveRepresentation.hxx>
@@ -46,6 +44,7 @@
 #include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_Surface.hxx>
 #include <GeomInt.hxx>
+#include <GeomLib.hxx>
 #include <GeomProjLib.hxx>
 #include <gp.hxx>
 #include <gp_Cylinder.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 
-static
-  Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
-                                                const TopoDS_Face& ,
-                                                Standard_Real& ,
-                                                Standard_Real& ,
-                                                Standard_Boolean& );
-static
-  Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& , 
-                                                const Handle(Geom_Surface)& ,
-                                                const TopLoc_Location& ,
-                                                Standard_Real& ,
-                                                Standard_Real& ,
-                                                Standard_Boolean& );
 static
   Standard_Real MaxToleranceEdge (const TopoDS_Face& );
 
@@ -473,57 +459,6 @@ Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
   aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
   return aT;
 }
-
-//=======================================================================
-//function : BuildPCurveForEdgeOnPlane
-//purpose  : 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
-  (const TopoDS_Edge& aE,
-   const TopoDS_Face& aF)
-{
-  Standard_Boolean bToUpdate;
-  Standard_Real aTolE, aT1, aT2;
-  Handle(Geom2d_Curve) aC2D;
-  BRep_Builder aBB;
-  //
-  aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
-  if (bToUpdate) {
-    aTolE=BRep_Tool::Tolerance(aE);
-    aBB.UpdateEdge(aE, aC2D, aF, aTolE);
-  }
-}
-
-//=======================================================================
-//function : BuildPCurveForEdgeOnPlane
-//purpose  : 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane 
-  (const TopoDS_Edge& aE,
-   const TopoDS_Face& aF,
-   Handle(Geom2d_Curve)& aC2D,
-   Standard_Boolean& bToUpdate)
-{
-  Standard_Real aT1, aT2;
-  aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
-}
-
-//=======================================================================
-// function: BuildPCurveForEdgesOnPlane
-// purpose: 
-//=======================================================================
-void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane 
-  (const BOPCol_ListOfShape& aLE,
-   const TopoDS_Face& aF)
-{
-  BOPCol_ListIteratorOfListOfShape aIt;
-  //
-  aIt.Initialize(aLE);
-  for(; aIt.More(); aIt.Next()) {
-    const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
-    BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
-  }
-}
 //=======================================================================
 //function : Make2D
 //purpose  : 
@@ -684,12 +619,25 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
   }
   //
   TolReached2d=aTolR;
-  //
+
+  // Adjust curve for periodic surface
   Handle(Geom2d_Curve) aC2DA;
   BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA);
-  //
-  aC2D=aC2DA;
-  //
+  aC2D = aC2DA;
+
+  // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve.
+  Standard_Real aTCFirst = aC2D->FirstParameter();
+  Standard_Real aTCLast  = aC2D->LastParameter();
+  if ((aTCFirst - aT1) > Precision::PConfusion() ||
+      (aT2 - aTCLast ) > Precision::PConfusion())
+  {
+    if (aTCFirst < aT1) aTCFirst = aT1;
+    if (aTCLast  > aT2) aTCLast  = aT2;
+
+    GeomLib::SameRange(Precision::PConfusion(), aC2D,
+                       aTCFirst, aTCLast, aT1, aT2, aC2D);
+  }
+
   // compute the appropriate tolerance for the edge
   Handle(Geom_Surface) aS = pBAS->Surface().Surface();
   aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf()));
@@ -703,124 +651,6 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
   }
 }
 
-//=======================================================================
-//function : BRep_Tool_CurveOnSurface
-//purpose  : 
-//=======================================================================
-Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E, 
-                                              const TopoDS_Face& F,
-                                              Standard_Real& First,
-                                              Standard_Real& Last,
-                                              Standard_Boolean& bToUpdate)
-{
-  TopLoc_Location l;
-  const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
-  TopoDS_Edge aLocalEdge = E;
-  if (F.Orientation() == TopAbs_REVERSED) {
-    aLocalEdge.Reverse();
-  }
-  //
-  return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
-}
-//=======================================================================
-//function : BRep_Tool_CurveOnSurface
-//purpose  : 
-//=======================================================================
-Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
-       (const TopoDS_Edge& E, 
-        const Handle(Geom_Surface)& S,
-        const TopLoc_Location& L,
-        Standard_Real& First,
-        Standard_Real& Last,
-        Standard_Boolean& bToUpdate)
-{
-  static const Handle(Geom2d_Curve) nullPCurve;
-  bToUpdate=Standard_False;
-  TopLoc_Location loc = L.Predivided(E.Location());
-  Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
-
-  // find the representation
-  BRep_ListIteratorOfListOfCurveRepresentation itcr
-    ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
-
-  while (itcr.More()) {
-    const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
-    if (cr->IsCurveOnSurface(S,loc)) {
-      Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
-      GC->Range(First,Last);
-      if (GC->IsCurveOnClosedSurface() && Eisreversed)
-        return GC->PCurve2();
-      else
-        return GC->PCurve();
-    }
-    itcr.Next();
-  }
-
-  // for planar surface and 3d curve try a projection
-  // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
-  Handle(Geom_Plane) GP;
-  Handle(Geom_RectangularTrimmedSurface) GRTS;
-  GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
-  if(!GRTS.IsNull())
-    GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
-  else
-    GP = Handle(Geom_Plane)::DownCast(S);
-  //fin modif du 21-05-97
-
-  if (!GP.IsNull()) {
-
-    Handle(GeomAdaptor_HCurve) HC;
-    Handle(GeomAdaptor_HSurface) HS;
-
-    HC = new GeomAdaptor_HCurve();
-    HS = new GeomAdaptor_HSurface();
-
-    TopLoc_Location LC;
-
-    Standard_Real f, l;// for those who call with (u,u).
-    Handle(Geom_Curve) C3d =
-      BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
-    // we can loose scale factor of Curve transformation (eap 13 May 2002)
-
-    LC = L/*.Predivided(LC)*/;
-
-    if (C3d.IsNull()) return nullPCurve;
-
-    Handle(Geom_Plane) Plane = GP;
-    if (!LC.IsIdentity()) {
-      const gp_Trsf& T = LC.Transformation();
-      Handle(Geom_Geometry) GPT = GP->Transformed(T);
-      Plane = Handle(Geom_Plane)::DownCast (GPT);
-    }
-    GeomAdaptor_Surface& GAS = HS->ChangeSurface();
-    GAS.Load(Plane);
-    
-    Handle(Geom_Curve) ProjOnPlane = 
-      GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
-                                  Plane,
-                                  Plane->Position().Direction(),
-                                  Standard_True);
-    
-    GeomAdaptor_Curve& GAC = HC->ChangeCurve();
-    GAC.Load(ProjOnPlane);
-
-    ProjLib_ProjectedCurve Proj(HS,HC);
-    Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
-
-    if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
-      Handle(Geom2d_TrimmedCurve) TC = 
-        Handle(Geom2d_TrimmedCurve)::DownCast (pc);
-      pc = TC->BasisCurve();
-    }
-    First = f; Last = l;
-    //
-    bToUpdate=Standard_True;
-    //
-    return pc;
-  }
-  
-  return nullPCurve;
-}
 //=======================================================================
 //function : MaxToleranceEdge
 //purpose  :