0027772: Foundation Classes - define Standard_Boolean using C++ type "bool" instead...
[occt.git] / src / BOPTools / BOPTools_AlgoTools.cxx
index f24ef62..2a4f64a 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BOPTools_AlgoTools.ixx>
-//
-#include <Precision.hxx>
-//
-#include <gp_Pnt.hxx>
-#include <gp_XYZ.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Cylinder.hxx>
-#include <gp_Cone.hxx>
-#include <gp_Sphere.hxx>
-#include <gp_Torus.hxx>
-#include <gp_Lin.hxx>
-//
+
+#include <BOPCol_IndexedMapOfShape.hxx>
+#include <BOPCol_MapOfShape.hxx>
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+#include <BOPTools_CoupleOfShape.hxx>
+#include <BOPTools_ListOfCoupleOfShape.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve2d.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepLib.hxx>
 #include <Geom2d_Curve.hxx>
-#include <Geom_Surface.hxx>
+#include <Geom2dInt_Geom2dCurveTool.hxx>
+#include <Geom_Curve.hxx>
 #include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
 #include <Geom_TrimmedCurve.hxx>
-#include <Geom_Curve.hxx>
 #include <GeomAPI_ProjectPointOnSurf.hxx>
-#include <Geom2dInt_Geom2dCurveTool.hxx>
-//
+#include <gp_Cone.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Sphere.hxx>
+#include <gp_Torus.hxx>
+#include <gp_XYZ.hxx>
+#include <IntTools_Context.hxx>
+#include <IntTools_Curve.hxx>
+#include <IntTools_Range.hxx>
+#include <IntTools_ShrunkRange.hxx>
+#include <IntTools_Tools.hxx>
+#include <Precision.hxx>
 #include <TopAbs_Orientation.hxx>
-//
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_CompSolid.hxx>
-#include <TopoDS_Solid.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
-//
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepLib.hxx>
-#include <BRepAdaptor_Curve2d.hxx>
-#include <BRepAdaptor_Surface.hxx>
-#include <BRepClass3d_SolidClassifier.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
-//
-#include <IntTools_Tools.hxx>
-//
-#include <BOPTools.hxx>
-#include <BOPTools_CoupleOfShape.hxx>
-#include <BOPTools_ListOfCoupleOfShape.hxx>
-#include <BOPTools_AlgoTools2D.hxx>
-#include <BOPTools_AlgoTools3D.hxx>
-//
-#include <BOPCol_IndexedMapOfShape.hxx>
-#include <BOPCol_MapOfShape.hxx>
-//
-#include <IntTools_ShrunkRange.hxx>
-//
+#include <NCollection_Array1.hxx>
+#include <algorithm>
 
+//
 static
   Standard_Real AngleWithRef(const gp_Dir& theD1,
                              const gp_Dir& theD2,
@@ -107,6 +107,8 @@ static
                           const BOPTools_ListOfCoupleOfShape& theLCS,
                           const gp_Pnt& aP);
 
+
+
 //=======================================================================
 // function: MakeConnexityBlocks
 // purpose: 
@@ -590,7 +592,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
 //function : IsInternalFace
 //purpose  : 
 //=======================================================================
-Standard_Integer BOPTools_AlgoTools::IsInternalFace
+Standard_Boolean BOPTools_AlgoTools::IsInternalFace
   (const TopoDS_Face& theFace,
    const TopoDS_Solid& theSolid,
    BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
@@ -638,7 +640,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
     BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE);
     aNbF=aLF.Extent();
     if (!aNbF) {
-      return iRet; // it can not be so
+      return iRet != 0; // it can not be so
     }
     //
     else if (aNbF==1) {
@@ -668,8 +670,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
     }
     //
     if (aNbF%2) {
-      iRet=0;
-      return iRet; // it can not be so
+      return Standard_False; // it can not be so
     }
     else { // aNbF=2,4,6,8,...
       iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, 
@@ -684,7 +685,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
   }
   //
   if (iRet!=2) {
-    return iRet;
+    return iRet == 1;
   }
   //
   //========================================
@@ -697,10 +698,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
   //
   aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, 
                                           theTol, aBounds, theContext);
-  //
-  iRet=(aState==TopAbs_IN)? 1 : 0;
-  //
-  return iRet;
+  return aState == TopAbs_IN;
 }
 //=======================================================================
 //function : IsInternalFace
@@ -813,7 +811,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
 {
   Standard_Boolean bRet;
   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
-  Standard_Real aUmin, aUsup, aVmin, aVsup;
+  Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
   gp_Pnt aPn1, aPn2, aPx;
   gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
   gp_Vec aVTgt;
@@ -823,6 +821,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
   BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
   GeomAPI_ProjectPointOnSurf aProjPL;
   //
+  aPA=Precision::Angular();
   aAngleMin=100.;
   aTwoPI=M_PI+M_PI;
   aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
@@ -860,7 +859,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
       aAngle=aTwoPI+aAngle;
     }
     //
-    if (aAngle<Precision::Angular()) {
+    if (aAngle<aPA) {
       if (aF2==theF1) {
         aAngle=M_PI;
       }
@@ -869,6 +868,11 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
       }
     }
     //
+    if (fabs(aAngle-aAngleMin)<aPA) {
+      // the minimal angle can not be found
+      bRet=Standard_False; 
+    }
+    //
     if (aAngle<aAngleMin){
       aAngleMin=aAngle;
       theFOff=aF2;
@@ -948,7 +952,7 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   }
   // 2
   aTolF2=BRep_Tool::Tolerance(aF2);
-  aTol=aTolF1+aTolF2;
+  aTol = aTolF1 + aTolF2 + Precision::Confusion();
   //
   iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
                                            theContext);
@@ -1149,7 +1153,7 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   //
   aProjector.LowerDistanceParameters(aU, aV);
   gp_Pnt2d aP2D(aU, aV);
-  bInFace=theContext->IsPointInFace (theFSr, aP2D);
+  bInFace=theContext->IsPointInOnFace (theFSr, aP2D);
   if (!bInFace) {
     return bRet;
   }
@@ -1274,10 +1278,10 @@ Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
       dU=-dU;
     }
     //
-    aC2D->D0(aU, aP2D0);
+    aBAC2D.D0(aU, aP2D0);
     for(i=2; i<=aNbS; i++) {
       aU=aU1+(i-1)*dU;
-      aC2D->D0(aU, aP2D1);
+      aBAC2D.D0(aU, aP2D1);
       aP2D0.Coord(aX0, aY0);
       aP2D1.Coord(aX1, aY1);
       //
@@ -1447,7 +1451,7 @@ Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
   //
   aTolV1=BRep_Tool::Tolerance(aV1);
   
-  aTolSum=aTolV1+aTolP2;
+  aTolSum = aTolV1 + aTolP2 + Precision::Confusion();
   aTolSum2=aTolSum*aTolSum;
   //
   aP1=BRep_Tool::Pnt(aV1);
@@ -1470,7 +1474,7 @@ Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
   //
   aTolV1=BRep_Tool::Tolerance(aV1);
   aTolV2=BRep_Tool::Tolerance(aV2);
-  aTolSum=aTolV1+aTolV2;
+  aTolSum = aTolV1 + aTolV2 + Precision::Confusion();
   aTolSum2=aTolSum*aTolSum;
   //
   aP1=BRep_Tool::Pnt(aV1);
@@ -1486,44 +1490,19 @@ Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
 // function: MakeVertex
 // purpose : 
 //=======================================================================
-void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
+void BOPTools_AlgoTools::MakeVertex(const BOPCol_ListOfShape& aLV,
                                     TopoDS_Vertex& aVnew)
 {
-  Standard_Integer aNb;
-  Standard_Real aTi, aDi, aDmax;
-  gp_Pnt aPi, aP;
-  gp_XYZ aXYZ(0.,0.,0.), aXYZi;
-  BOPCol_ListIteratorOfListOfShape aIt;
-  //
-  aNb=aLV.Extent();
-  if (aNb) {
-    aIt.Initialize(aLV);
-    for (; aIt.More(); aIt.Next()) {
-      TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
-      aPi=BRep_Tool::Pnt(aVi);
-      aXYZi=aPi.XYZ();
-      aXYZ=aXYZ+aXYZi;
-    }
-    //
-    aXYZ.Divide((Standard_Real)aNb);
-    aP.SetXYZ(aXYZ);
-    //
-    aDmax=-1.;
-    aIt.Initialize(aLV);
-    for (; aIt.More(); aIt.Next()) {
-      TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
-      aPi=BRep_Tool::Pnt(aVi);
-      aTi=BRep_Tool::Tolerance(aVi);
-      aDi=aP.SquareDistance(aPi);
-      aDi=sqrt(aDi);
-      aDi=aDi+aTi;
-      if (aDi > aDmax) {
-        aDmax=aDi;
-      }
-    }
-    //
+  Standard_Integer aNb = aLV.Extent();
+  if (aNb == 1)
+    aVnew=*((TopoDS_Vertex*)(&aLV.First()));
+  else if (aNb > 1)
+  {
+    Standard_Real aNTol;
+    gp_Pnt aNC;
+    BRepLib::BoundingVertex(aLV, aNC, aNTol);
     BRep_Builder aBB;
-    aBB.MakeVertex (aVnew, aP, aDmax);
+    aBB.MakeVertex(aVnew, aNC, aNTol);
   }
 }
 //=======================================================================
@@ -1777,10 +1756,10 @@ Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
 //=======================================================================
 Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
   (const TopoDS_Edge& aE,
-   const Handle(IntTools_Context)& aCtx) 
+   const Handle(IntTools_Context)& aCtx,
+   const Standard_Boolean bCheckSplittable)
 {
   Standard_Boolean bRet;
-  Standard_Integer iErr;
   Standard_Real aT1, aT2, aTmp;
   Handle(Geom_Curve) aC3D;
   TopoDS_Vertex aV1, aV2;
@@ -1805,8 +1784,10 @@ Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
   aSR.SetContext(aCtx);
   aSR.SetData(aE, aT1, aT2, aV1, aV2);
   aSR.Perform();
-  iErr=aSR.ErrorStatus();
-  bRet = !(iErr==0);
+  bRet = !aSR.IsDone();
+  if (!bRet && bCheckSplittable) {
+    bRet = !aSR.IsSplittable();
+  }
   //
   return bRet;
 }
@@ -1860,7 +1841,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
                                  const Standard_Real aTolE)
 {
   Standard_Integer aNbItMax;
-  Standard_Real aDist, aDTol, aPM;
+  Standard_Real aDist, aDTol, aPM, anEps;
   Standard_Boolean bRet;
   gp_Pnt aP1, aPS;
   //
@@ -1871,6 +1852,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
   }
   bRet = Standard_False;
   aNbItMax = 15;
+  anEps = Precision::SquareConfusion();
   //
   GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
   //
@@ -1884,7 +1866,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
   aPS=aProjPL.NearestPoint();
   //
   aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
-   aProj.Perform(aPS);
+  aProj.Perform(aPS);
   if (!aProj.IsDone()) {
     return bRet;
   }
@@ -1892,7 +1874,6 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
   aProjPL.Perform(aPS);
   aPS=aProjPL.NearestPoint();
   //
-  //
   do {
     aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
     //
@@ -1907,6 +1888,9 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
     aPOut = aProjPL.NearestPoint();
     //
     gp_Vec aV(aPS, aPOut);
+    if (aV.SquareMagnitude() < anEps) {
+      return bRet;
+    }
     aDB.SetXYZ(aV.XYZ());
   } while (aDist > aDTol && --aNbItMax);
   //
@@ -1948,26 +1932,33 @@ Standard_Real MinStep3D(const TopoDS_Edge& theE1,
     aR = 0.;
     aBAS.Initialize(aF, Standard_False);
     GeomAbs_SurfaceType aSType = aBAS.GetType();
-    if (aSType == GeomAbs_Cylinder) {
+    switch (aSType) {
+    case GeomAbs_Cylinder: {
       aR = aBAS.Cylinder().Radius();
+      break;
     }
-    else if (aSType == GeomAbs_Cone) {
+    case GeomAbs_Cone: {
       gp_Lin aL(aBAS.Cone().Axis());
       aR = aL.Distance(aP);
+      break;
     }
-    else if (aSType == GeomAbs_Sphere) {
+    case GeomAbs_Sphere: {
+      aDtMin = Max(aDtMin, 5.e-4);
       aR = aBAS.Sphere().Radius();
+      break;
     }
-    else if (aSType == GeomAbs_Torus) {
+    case GeomAbs_Torus: {
       aR = aBAS.Torus().MajorRadius();
+      break;
     }
-    else if (aSType == GeomAbs_SurfaceOfRevolution) {
-      aDtMin = 5.e-4;
+    default:
+      aDtMin = Max(aDtMin, 5.e-4);
+      break;
     }
     //
     if (aR > 100.) {
-      Standard_Real d = Precision::PConfusion();
-      aDtMin = sqrt(d*d + 2*d*aR);
+      Standard_Real d = 10*Precision::PConfusion();
+      aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
     }
     //
     if (aDt > aDtMax) {