0029698: Regression vs 7.2.0: Common operation raises FLT_INVALID_OPERATION exception
authoremv <emv@opencascade.com>
Mon, 16 Apr 2018 12:21:35 +0000 (15:21 +0300)
committerabv <abv@opencascade.com>
Wed, 23 May 2018 02:44:12 +0000 (05:44 +0300)
When checking if the split edge is oriented as the original one (BOPTools_AlgoTools::IsSplitToReverse()) the tangent vectors should be computed for both edges at the same point. This point is taken on the split edge and projected on the original edge.
The fix is intended to ensuring that the reference point will be taken inside the valid range of the split edge (i.e. not covered by the tolerance spheres of its bounding vertices) and the projection of this point on the original edge will be successful. Moreover, several sampling points are now taken on the split edge and processed until first valid point is found.

If requested (by a not null pointer) all *BOPTools_AlgoTools::IsSplitToReverse()* methods are now return the error status of the check. Before using the returned flag, the calling program should check this error status. For successful check the error status should be equal to zero.

New warning *BOPAlgo_AlertUnableToOrientTheShape* is now returned in the algorithms in Boolean component in case the check for correct shape orientation failed.

Test case for the issue.

15 files changed:
dox/dev_guides/upgrade/upgrade.md
src/BOPAlgo/BOPAlgo.msg
src/BOPAlgo/BOPAlgo_Alerts.hxx
src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
src/BOPAlgo/BOPAlgo_Builder.hxx
src/BOPAlgo/BOPAlgo_Builder_1.cxx
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_Builder_3.cxx
src/BOPTools/BOPTools_AlgoTools.cxx
src/BOPTools/BOPTools_AlgoTools.hxx
src/BOPTools/BOPTools_AlgoTools2D.hxx
src/BOPTools/BOPTools_AlgoTools2D_1.cxx
src/BOPTools/BOPTools_AlgoTools3D.cxx
src/BOPTools/BOPTools_AlgoTools3D.hxx
tests/bugs/modalg_7/bug29698 [new file with mode: 0644]

index 6742c1e..d1c5e44 100644 (file)
@@ -1503,6 +1503,7 @@ The following obsolete features have been removed:
 * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
 * The class *BOPTools* has been removed as duplicate of the class *TopExp*;
 * The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.
+* The method *BOPTools_AlgoTools::CheckSameGeom()* has been removed as excessive. The method *BOPTools_AlgoTools::AreFacesSameDomain()* can be used instead.
 
 @section upgrade_occt730 Upgrade to OCCT 7.3.0
 
index 72c842f..84cf724 100644 (file)
@@ -91,3 +91,6 @@ Error: The Feature Removal algorithm has failed
 
 .BOPAlgo_AlertSolidBuilderUnusedFaces
 Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
+
+.BOPAlgo_AlertUnableToOrientTheShape
+Warning: Unable to orient the shape correctly
index 7a4f927..8874825 100644 (file)
@@ -104,4 +104,7 @@ DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed)
 //! and not used for solids creation
 DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
 
+//! Unable to orient the shape correctly
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToOrientTheShape)
+
 #endif // _BOPAlgo_Alerts_HeaderFile
index 6cd2187..4eeb549 100644 (file)
@@ -93,4 +93,7 @@ static const char BOPAlgo_BOPAlgo_msg[] =
   "Error: The Feature Removal algorithm has failed\n"
   "\n"
   ".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
-  "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n";
+  "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"
+  "\n"
+  ".BOPAlgo_AlertUnableToOrientTheShape\n"
+  "Warning: Unable to orient the shape correctly\n";
index 6f46abb..6b8cadc 100644 (file)
@@ -58,6 +58,10 @@ class BOPAlgo_PaveFiller;
 //!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
 //!                          most likely will lead to incorrect results.
 //!
+//! The algorithm returns the following warnings:
+//! - *BOPAlgo_AlertUnableToOrientTheShape* - in case the check on the orientation of the split shape
+//!                                           to match the orientation of the original shape has failed.
+//!
 //! The algorithm returns the following Error statuses:
 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
 //! - *BOPAlgo_AlertNoFiller* - in case the intersection tool has not been created;
index 69fc0f8..97ec6c7 100644 (file)
@@ -226,7 +226,7 @@ void BOPAlgo_Builder::FillImagesVertices()
     {
       TopoDS_Shape aSSIm = aItIm.Value();
       if (!aSSIm.IsEqual(aSS) &&
-          BOPTools_AlgoTools::IsSplitToReverse(aSSIm, aSS, myContext))
+          BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSSIm, aSS, myContext, myReport))
       {
         aSSIm.Reverse();
       }
index 15b1b3c..fcc64ed 100644 (file)
@@ -61,7 +61,8 @@
 static
   TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
                              const TopTools_DataMapOfShapeListOfShape& theImages,
-                             Handle(IntTools_Context)& theCtx);
+                             Handle(IntTools_Context)& theCtx,
+                             const Handle(Message_Report)& theReport);
 
 //=======================================================================
 //class    : BOPAlgo_PairOfShapeBoolean
@@ -311,7 +312,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
       // the draft face will be null, as such sub-shapes may split the face on parts
       // (as in the case "bugs modalg_5 bug25245_1").
       // The BuilderFace algorithm will be called in this case.
-      TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext);
+      TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext, myReport);
       if (!aFD.IsNull())
       {
         aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD);
@@ -404,7 +405,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
         }// if (bIsClosed){
         //
         aSp.Orientation(anOriE);
-        bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
+        bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, myContext, myReport);
         if (bToReverse) {
           aSp.Reverse();
         }
@@ -813,21 +814,27 @@ void BOPAlgo_Builder::FillInternalVertices()
 //purpose  : Checks if the edge has multi-connected vertices.
 //=======================================================================
 static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge,
-                                          TopTools_DataMapOfShapeInteger& theMap)
+                                          TopTools_DataMapOfShapeListOfShape& theMap)
 {
   TopoDS_Iterator itV(theEdge);
   for (; itV.More(); itV.Next())
   {
     const TopoDS_Shape& aV = itV.Value();
-    Standard_Integer *pCounter = theMap.ChangeSeek(aV);
-    if (!pCounter)
-      pCounter = theMap.Bound(aV, 1);
+    TopTools_ListOfShape *pList = theMap.ChangeSeek(aV);
+    if (!pList)
+    {
+      pList = theMap.Bound(aV, TopTools_ListOfShape());
+      pList->Append(theEdge);
+    }
     else
     {
-      if (*pCounter == 2)
-        return Standard_True;
+      // The list is expected to be 1-2 elements long,
+      // thus using "Contains" is safe.
+      if (!pList->Contains(theEdge))
+        pList->Append(theEdge);
 
-      ++(*pCounter);
+      if (pList->Extent() > 2)
+        return Standard_True;
     }
   }
   return Standard_False;
@@ -839,7 +846,8 @@ static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge,
 //=======================================================================
 TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
                            const TopTools_DataMapOfShapeListOfShape& theImages,
-                           Handle(IntTools_Context)& theCtx)
+                           Handle(IntTools_Context)& theCtx,
+                           const Handle(Message_Report)& theReport)
 {
   BRep_Builder aBB;
   // Take the information from the original face
@@ -855,7 +863,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
   // the vertices appearance, and if the multi-connexity is met return
   // the null face to use the BuilderFace algorithm for checking the
   // possibility of split.
-  TopTools_DataMapOfShapeInteger aVerticesCounter;
+  TopTools_DataMapOfShapeListOfShape aVerticesCounter;
 
   // Update wires of the original face and add them to draft face
   TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
@@ -885,20 +893,21 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
         return TopoDS_Face();
       }
 
+      // Check if the original edge is degenerated
+      Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
+
       // Check for the splits of the edge
       const TopTools_ListOfShape* pLEIm = theImages.Seek(aE);
       if (!pLEIm)
       {
         // Check if the edge has multi-connected vertices
-        if (HasMultiConnected(aE, aVerticesCounter))
+        if (!bIsDegenerated && HasMultiConnected(aE, aVerticesCounter))
           return TopoDS_Face();
 
         aBB.Add(aNewWire, aE);
         continue;
       }
 
-      // Check if the original edge is degenerated
-      Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
       // Check if the original edge is closed on the face
       Standard_Boolean bIsClosed = BRep_Tool::IsClosed(aE, theFace);
 
@@ -908,7 +917,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
         TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value());
 
         // Check if the split has multi-connected vertices
-        if (HasMultiConnected(aSp, aVerticesCounter))
+        if (!bIsDegenerated && HasMultiConnected(aSp, aVerticesCounter))
           return TopoDS_Face();
 
         aSp.Orientation(anOriE);
@@ -918,13 +927,13 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
           continue;
         }
 
-        // Check closeness of the split edge and if it is not
-        // make the second PCurve
+        // If the original edge is closed on the face check closeness
+        // of the split edge and if it is not closed make the second PCurve
         if (bIsClosed && !BRep_Tool::IsClosed(aSp, theFace))
           BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, theFace);
 
         // Check if the split should be reversed
-        if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, theCtx))
+        if (BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, theCtx, theReport))
           aSp.Reverse();
 
         aBB.Add(aNewWire, aSp);
index f7763d3..1f7d000 100644 (file)
@@ -287,8 +287,8 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
               theLIF.Append(aFx);
             }
             else {
-              bToReverse=BOPTools_AlgoTools::IsSplitToReverse
-                (aFx, aF, myContext);
+              bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn
+                (aFx, aF, myContext, myReport);
               if (bToReverse) {
                 aFx.Reverse();
               }
index b4f474b..b5c07f0 100644 (file)
@@ -17,6 +17,7 @@
 
 
 #include <BOPTools_AlgoTools.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPTools_AlgoTools2D.hxx>
 #include <BOPTools_AlgoTools3D.hxx>
 #include <BOPTools_CoupleOfShape.hxx>
@@ -64,6 +65,7 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_MapOfOrientedShape.hxx>
+#include <Message_Report.hxx>
 #include <NCollection_Array1.hxx>
 #include <algorithm>
 
@@ -77,7 +79,7 @@ static
   Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                   const TopTools_ListOfShape& thLF,
                                   BOPTools_ListOfCoupleOfShape& theLCFF,
-                                  Handle(IntTools_Context)& theContext);
+                                  const Handle(IntTools_Context)& theContext);
 static
   TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
                                  const TopoDS_Face& aF);
@@ -91,7 +93,7 @@ static
                               const Standard_Boolean theSmallFaces,
                               gp_Dir& aDN,
                               gp_Dir& aDB,
-                              Handle(IntTools_Context)& theContext,
+                              const Handle(IntTools_Context)& theContext,
                               GeomAPI_ProjectPointOnSurf& aProjPL,
                               const Standard_Real aDt);
 static
@@ -99,7 +101,7 @@ static
                                    const gp_Pnt& aP,
                                    gp_Dir& aDB,
                                    gp_Pnt& aPOut,
-                                   Handle(IntTools_Context)& theContext,
+                                   const Handle(IntTools_Context)& theContext,
                                    GeomAPI_ProjectPointOnSurf& aProjPL,
                                    const Standard_Real aDt,
                                    const Standard_Real aTolE);
@@ -108,7 +110,7 @@ static
                           const TopoDS_Face& theF1,
                           const BOPTools_ListOfCoupleOfShape& theLCS,
                           const gp_Pnt& aP,
-                          Handle(IntTools_Context)& theContext,
+                          const Handle(IntTools_Context)& theContext,
                           Standard_Boolean& theSmallFaces);
 
 
@@ -589,7 +591,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
   (const TopoDS_Shape& theS,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopAbs_ShapeEnum aType;
@@ -616,7 +618,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
    TopTools_IndexedMapOfShape& theBounds,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopExp_Explorer aExp; 
@@ -665,7 +667,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const TopoDS_Vertex& theV,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   gp_Pnt aP3D; 
@@ -683,7 +685,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const TopoDS_Edge& theE,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aT1, aT2, aT = 0.;
   TopAbs_State aState;
@@ -735,7 +737,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const gp_Pnt& theP,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   //
@@ -755,7 +757,7 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Solid& theSolid,
    TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bDegenerated;
   Standard_Integer aNbF, iRet, iFound;
@@ -866,7 +868,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
   (const TopoDS_Face& theFace,
    const TopoDS_Edge& theEdge,
    TopTools_ListOfShape& theLF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer aNbF, iRet;
   //
@@ -911,7 +913,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Edge& theEdge,
    const TopoDS_Face& theFace1,
    const TopoDS_Face& theFace2,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
   Standard_Integer iRet;
@@ -965,7 +967,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
    const TopoDS_Face& theF1,
    BOPTools_ListOfCoupleOfShape& theLCSOff,
    TopoDS_Face& theFOff,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet, bIsComputed;
   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
@@ -1091,7 +1093,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   (const TopoDS_Face& theF1,
    const TopoDS_Face& theF2,
-   Handle(IntTools_Context)& theContext,
+   const Handle(IntTools_Context)& theContext,
    const Standard_Real theFuzz)
 {
   Standard_Boolean bFacesSD = Standard_False;
@@ -1152,42 +1154,12 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
 }
 
 //=======================================================================
-//function : CheckSameGeom
-//purpose  : 
-//=======================================================================
-Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
-  (const TopoDS_Face& theF1,
-   const TopoDS_Face& theF2,
-   Handle(IntTools_Context)& theContext)
-{
-  Standard_Boolean bRet;
-  Standard_Real aTolF1, aTolF2, aTol;
-  gp_Pnt2d aP2D;
-  gp_Pnt aP;
-  TopExp_Explorer aExp;
-  //
-  bRet=Standard_False;
-  aExp.Init(theF1, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
-    if (!BRep_Tool::Degenerated(aE)) {
-      aTolF1=BRep_Tool::Tolerance(theF1);
-      aTolF2=BRep_Tool::Tolerance(theF2);
-      aTol=aTolF1+aTolF2;
-      BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
-      bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
-      break;
-    }
-  }
-  return bRet;
-}
-//=======================================================================
 // function: Sense
 // purpose: 
 //=======================================================================
-Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
-                                            const TopoDS_Face& theF2,
-                                            const Handle(IntTools_Context)& theContext)
+Standard_Integer BOPTools_AlgoTools::Sense(const TopoDS_Face& theF1,
+                                           const TopoDS_Face& theF2,
+                                           const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iSense=0;
   gp_Dir aDNF1, aDNF2;
@@ -1235,7 +1207,8 @@ Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   (const TopoDS_Shape& theSp,
    const TopoDS_Shape& theSr,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
   Standard_Boolean bRet;
   TopAbs_ShapeEnum aType;
@@ -1247,22 +1220,49 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
     case TopAbs_EDGE: {
       const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
       const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
-      bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
+      bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext, theError);
     }
       break;
       //
     case TopAbs_FACE: {
       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
       const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
-      bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
+      bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext, theError);
     }
       break;
       //
     default:
+      if (theError)
+        *theError = 100;
       break;
   }
   return bRet;
 }
+
+//=======================================================================
+//function : IsSplitToReverseWithWarn
+//purpose  :
+//=======================================================================
+Standard_Boolean BOPTools_AlgoTools::IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit,
+                                                              const TopoDS_Shape& theShape,
+                                                              const Handle(IntTools_Context)& theContext,
+                                                              const Handle(Message_Report)& theReport)
+{
+  Standard_Integer anErr;
+  Standard_Boolean isToReverse = BOPTools_AlgoTools::IsSplitToReverse(theSplit, theShape, theContext, &anErr);
+  if (anErr != 0 && !theReport.IsNull())
+  {
+    // The error occurred during the check.
+    // Add warning to the report, storing the shapes into the warning.
+    TopoDS_Compound aWC;
+    BRep_Builder().MakeCompound(aWC);
+    BRep_Builder().Add(aWC, theSplit);
+    BRep_Builder().Add(aWC, theShape);
+    theReport->AddAlert(Message_Warning, new BOPAlgo_AlertUnableToOrientTheShape(aWC));
+  }
+  return isToReverse;
+}
+
 //=======================================================================
 //function :IsSplitToReverse
 //purpose  : 
@@ -1270,8 +1270,13 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   (const TopoDS_Face& theFSp,
    const TopoDS_Face& theFSr,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
+  // Set OK error status
+  if (theError)
+    *theError = 0;
+
   // Compare surfaces
   Handle(Geom_Surface) aSFSp = BRep_Tool::Surface(theFSp);
   Handle(Geom_Surface) aSFOr = BRep_Tool::Surface(theFSr);
@@ -1305,6 +1310,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
     }
     //
     if (!anExp.More()) {
+      if (theError)
+        *theError = 1;
       // The point has not been found.
       return bDone;
     }
@@ -1315,6 +1322,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   bDone = BOPTools_AlgoTools3D::GetNormalToSurface
     (aSFSp, aP2DFSp.X(), aP2DFSp.Y(), aDNFSp);
   if (!bDone) {
+    if (theError)
+      *theError = 2;
     return bDone;
   }
   //
@@ -1328,6 +1337,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   aProjector.Perform(aPFSp);
   bDone = (aProjector.NbPoints() > 0);
   if (!bDone) {
+    if (theError)
+      *theError = 3;
     return bDone;
   }
   // UV coordinates of the point on the original face
@@ -1338,6 +1349,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   gp_Dir aDNFOr;
   bDone = BOPTools_AlgoTools3D::GetNormalToSurface(aSFOr, aU, aV, aDNFOr);
   if (!bDone) {
+    if (theError)
+      *theError = 4;
     return bDone;
   }
   //
@@ -1354,51 +1367,88 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
 //purpose  : 
 //=======================================================================
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
-  (const TopoDS_Edge& aEF1,
-   const TopoDS_Edge& aEF2,
-   Handle(IntTools_Context)& theContext)
+  (const TopoDS_Edge& theESp,
+   const TopoDS_Edge& theEOr,
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
-  Standard_Boolean bRet, bIsDegenerated;
-  //
-  bRet=Standard_False;
-  bIsDegenerated=(BRep_Tool::Degenerated(aEF1) || 
-                  BRep_Tool::Degenerated(aEF2));
-  if (bIsDegenerated) {
-    return bRet;
+  // The idea is to compare the tangent vectors of two edges computed in
+  // the same point. Thus, we need to take the point on split edge (since it is
+  // shorter) and project it onto original edge to find corresponding parameter.
+
+  if (BRep_Tool::Degenerated(theESp) ||
+      BRep_Tool::Degenerated(theEOr))
+  {
+    if (theError)
+      *theError = 1;
+    return Standard_False;
   }
-  //
-  Standard_Real a, b;
-  TopAbs_Orientation aOrE, aOrSp;
-  Handle(Geom_Curve)aC1, aC2;
-  //
-  aC2=BRep_Tool::Curve(aEF2, a, b);
-  aC1=BRep_Tool::Curve(aEF1, a, b);
-  //
-  if (aC1==aC2) {
-    aOrE=aEF2.Orientation();
-    aOrSp=aEF1.Orientation();
-    bRet=(aOrE!=aOrSp);
-    return bRet;
+
+  // Set OK error status
+  if (theError)
+    *theError = 0;
+
+  // Get the curves from the edges
+  Standard_Real f, l;
+  Handle(Geom_Curve) aCSp = BRep_Tool::Curve(theESp, f, l);
+  Handle(Geom_Curve) aCOr = BRep_Tool::Curve(theEOr, f, l);
+
+  // If the curves are the same, compare orientations only
+  if (aCSp == aCOr)
+    return theESp.Orientation() != theEOr.Orientation();
+
+  // Find valid range of the split edge, to ensure that the point for computing
+  // tangent vectors will be inside both edges.
+  if (!BRepLib::FindValidRange(theESp, f, l))
+    BRep_Tool::Range(theESp, f, l);
+
+  // Error code
+  Standard_Integer anErr = 0;
+  // Try a few sample points on the split edge until first valid found
+  const Standard_Integer aNbP = 11;
+  const Standard_Real aDT = (l - f) / aNbP;
+  for (Standard_Integer i = 1; i < aNbP; ++i)
+  {
+    const Standard_Real aTm = f + i*aDT;
+    // Compute tangent vector on split edge
+    gp_Vec aVSpTgt;
+    if (!BOPTools_AlgoTools2D::EdgeTangent(theESp, aTm, aVSpTgt))
+    {
+      // Unable to compute the tangent vector on the split edge
+      // in this point -> take the next point
+      anErr = 2;
+      continue;
+    }
+
+    // Find corresponding parameter on the original edge
+    Standard_Real aTmOr;
+    if (!theContext->ProjectPointOnEdge(aCSp->Value(aTm), theEOr, aTmOr))
+    {
+      // Unable to project the point inside the split edge
+      // onto the original edge -> take the next point
+      anErr = 3;
+      continue;
+    }
+
+    // Compute tangent vector on original edge
+    gp_Vec aVOrTgt;
+    if (!BOPTools_AlgoTools2D::EdgeTangent(theEOr, aTmOr, aVOrTgt))
+    {
+      // Unable to compute the tangent vector on the original edge
+      // in this point -> take the next point
+      anErr = 4;
+      continue;
+    }
+
+    // Compute the Dot product
+    Standard_Real aCos = aVSpTgt.Dot(aVOrTgt);
+    return (aCos < 0.);
   }
-  //
-  Standard_Real aT1, aT2, aScPr;
-  gp_Vec aV1, aV2;
-  gp_Pnt aP;
-  //
-  aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
-  aC1->D0(aT1, aP);
-  BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
-  gp_Dir aDT1(aV1);
-  //
-  theContext->ProjectPointOnEdge(aP, aEF2, aT2);
-  //
-  BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
-  gp_Dir aDT2(aV2);
-  //
-  aScPr=aDT1*aDT2;
-  bRet=(aScPr<0.);
-  //
-  return bRet;
+
+  if (theError)
+    *theError = anErr;
+
+  return Standard_False;
 }
 
 //=======================================================================
@@ -1715,7 +1765,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                 const TopTools_ListOfShape& thLF,
                                 BOPTools_ListOfCoupleOfShape& theLCFF,
-                                Handle(IntTools_Context)& theContext)
+                                const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bFound;
   Standard_Integer i, aNbCEF;
@@ -1841,7 +1891,7 @@ Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
   (const IntTools_Range& aShrR,
    const TopoDS_Face& aF,
    const TopoDS_Edge& aE1,
-   Handle(IntTools_Context)& aContext)
+   const Handle(IntTools_Context)& aContext)
 {
   Standard_Boolean bFlag;
   Standard_Real f1, l1, ULD, VLD;
@@ -1978,7 +2028,7 @@ Standard_Boolean GetFaceDir(const TopoDS_Edge& aE,
                             const Standard_Boolean theSmallFaces,
                             gp_Dir& aDN,
                             gp_Dir& aDB,
-                            Handle(IntTools_Context)& theContext,
+                            const Handle(IntTools_Context)& theContext,
                             GeomAPI_ProjectPointOnSurf& aProjPL,
                             const Standard_Real aDt)
 {
@@ -2022,7 +2072,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
                                  const gp_Pnt& aP,
                                  gp_Dir& aDB,
                                  gp_Pnt& aPOut,
-                                 Handle(IntTools_Context)& theContext,
+                                 const Handle(IntTools_Context)& theContext,
                                  GeomAPI_ProjectPointOnSurf& aProjPL,
                                  const Standard_Real aDt,
                                  const Standard_Real aTolE)
@@ -2092,7 +2142,7 @@ Standard_Real MinStep3D(const TopoDS_Edge& theE1,
                         const TopoDS_Face& theF1,
                         const BOPTools_ListOfCoupleOfShape& theLCS,
                         const gp_Pnt& aP,
-                        Handle(IntTools_Context)& theContext,
+                        const Handle(IntTools_Context)& theContext,
                         Standard_Boolean& theSmallFaces)
 {
   Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin;
index 96102b3..bb12821 100644 (file)
@@ -45,130 +45,159 @@ class IntTools_Context;
 class TopoDS_Solid;
 class IntTools_Range;
 class TopoDS_Shell;
-
-
-class BOPTools_AlgoTools 
+class Message_Report;
+
+//! Provides tools used in Boolean Operations algorithm:
+//! - Vertices intersection;
+//! - Vertex construction;
+//! - Edge construction;
+//! - Classification algorithms;
+//! - Making connexity blocks;
+//! - Shape validation.
+class BOPTools_AlgoTools
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const gp_Pnt& aP2, const Standard_Real aTolP2);
-  
-  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, 
-                                                     const TopoDS_Vertex& aV2, 
-                                                     const Standard_Real theFuzz = Precision::Confusion());
-  
-  Standard_EXPORT static void MakeVertex (const TopTools_ListOfShape& aLV, TopoDS_Vertex& aV);
-  
-  Standard_EXPORT static void MakeEdge (const IntTools_Curve& theCurve, const TopoDS_Vertex& theV1, const Standard_Real theT1, const TopoDS_Vertex& theV2, const Standard_Real theT2, const Standard_Real theTolR3D, TopoDS_Edge& theE);
-  
-  //! Makes 2d curve of the edge <theE> on the faces <theF1> and <theF2>.<br>
-  //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void MakePCurve (const TopoDS_Edge& theE,
-                                          const TopoDS_Face& theF1,
-                                          const TopoDS_Face& theF2,
-                                          const IntTools_Curve& theCurve,
-                                          const Standard_Boolean thePC1,
-                                          const Standard_Boolean thePC2,
-                                          const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
-  Standard_EXPORT static void MakeContainer (const TopAbs_ShapeEnum theType, TopoDS_Shape& theShape);
-  
-  Standard_EXPORT static Standard_Boolean IsHole (const TopoDS_Shape& aW, const TopoDS_Shape& aF);
-  
-  //! Returns True if the shape theSplit has opposite
-  //! direction than theShape
-  //! theContext - cashed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Shape& theSplit, const TopoDS_Shape& theShape, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if normal direction of the face
-  //! theShape is not the same as for the face
-  //! theSplit
-  //! theContext - cashed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Face& theSplit, const TopoDS_Face& theShape, Handle(IntTools_Context)& theContext);
-  
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, Handle(IntTools_Context)& aContext);
-  
-  Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1,
-                                         const TopoDS_Face& theF2, 
-                                         Handle(IntTools_Context)& theContext,
-                                         const Standard_Real theFuzz = Precision::Confusion());
-  
-  Standard_EXPORT static Standard_Boolean CheckSameGeom (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
-  
-  //! Basing on the normals directions of the faces the method
-  //! Defines whether to reverse the second face or not.<br>
-  //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static Standard_Integer Sense (const TopoDS_Face& theF1,
-                                                 const TopoDS_Face& theF2,
-                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
-  //! Returns True if the face theFace contains
-  //! the edge theEdge but with opposite orientation.
-  //! If the method  returns True theEdgeOff is the
-  //! edge founded
-  Standard_EXPORT static Standard_Boolean GetEdgeOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOff);
-  
-  //! For the face theFace and its edge theEdge
-  //! finds the face suitable to produce shell.
-  //! theLCEF - set of faces to search. All faces
-  //! from theLCEF must share edge theEdge
-  Standard_EXPORT static Standard_Boolean GetFaceOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, BOPTools_ListOfCoupleOfShape& theLCEF, TopoDS_Face& theFaceOff, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside of the
-  //! couple of faces theFace1, theFace2.
-  //! The faces theFace, theFace1, theFace2  must
-  //! share the edge theEdge
-  //! Return values:
-  //!  * 0 state is not IN
-  //!  * 1 state is IN
-  //!  * 2 state can not be found by the method of angles
-  Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside of the
-  //! appropriate couple of faces (from the set theLF)    .
-  //! The faces of the set theLF and theFace  must
-  //! share the edge theEdge
-  //!  * 0 state is not IN
-  //!  * 1 state is IN
-  //!  * 2 state can not be found by the method of angles
-  Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, TopTools_ListOfShape& theLF, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside the
-  //! solid theSolid.
-  //! theMEF - Map Edge/Faces for theSolid
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
-  //! For the face theFace gets the edge theEdgeOnF
-  //! that is the same as theEdge
-  //! Returns True if such edge exists
-  //! Returns False if there is no such edge
-  Standard_EXPORT static Standard_Boolean GetEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOnF);
-  
+public: //! @name Intersection of the vertices
+
+  //! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>.
+  //! Returns the error status:
+  //! - 0 - no error, meaning that the vertex intersects the point;
+  //! - 1 - the distance between vertex and point is grater than the sum of tolerances.
+  Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV,
+                                                    const gp_Pnt& theP,
+                                                    const Standard_Real theTolP);
+
+  //! Intersects the given vertices with given fuzzy value.
+  //! Returns the error status:
+  //! - 0 - no error, meaning that the vertices interferes with given tolerance;
+  //! - 1 - the distance between vertices is grater than the sum of their tolerances.
+  Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV1,
+                                                    const TopoDS_Vertex& theV2,
+                                                    const Standard_Real theFuzz = Precision::Confusion());
+
+public: //! @name Vertices construction
+
+  //! Makes the vertex in the middle of given vertices with
+  //! the tolerance covering all tolerance spheres of vertices.
+  Standard_EXPORT static void MakeVertex(const TopTools_ListOfShape& theLV,
+                                         TopoDS_Vertex& theV);
+
+  //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol>
+  Standard_EXPORT static void MakeNewVertex(const gp_Pnt& aP1,
+                                            const Standard_Real aTol,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex using couple of vertices  <aV1, aV2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Vertex& aV1,
+                                            const TopoDS_Vertex& aV2,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex in place of intersection between two edges
+  //! <aE1, aE2> with parameters <aP1, aP2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Edge& aE2,
+                                            const Standard_Real aP2,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex in place of intersection between the edge <aE1>
+  //! with parameter <aP1> and the face <aF2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Face& aF2,
+                                            TopoDS_Vertex& aNewVertex);
+
+
+public: //! @name Updating the vertex
+
+  //! Update the tolerance value for vertex  <aV>
+  //! taking into account the fact that <aV> lays on
+  //! the curve <aIC>
+  Standard_EXPORT static void UpdateVertex(const IntTools_Curve& aIC,
+                                           const Standard_Real aT,
+                                           const TopoDS_Vertex& aV);
+
+  //! Update the tolerance value for vertex  <aV>
+  //! taking into account the fact that <aV> lays on
+  //! the edge <aE>
+  Standard_EXPORT static void UpdateVertex(const TopoDS_Edge& aE,
+                                           const Standard_Real aT,
+                                           const TopoDS_Vertex& aV);
+
+  //! Update the tolerance value for vertex  <aVN>
+  //! taking into account the fact that <aVN> should
+  //! cover tolerance zone of <aVF>
+  Standard_EXPORT static void UpdateVertex(const TopoDS_Vertex& aVF,
+                                           const TopoDS_Vertex& aVN);
+
+
+public: //! @name Edge construction
+
+  //! Makes the edge based on the given curve with given bounding vertices.
+  Standard_EXPORT static void MakeEdge(const IntTools_Curve& theCurve,
+                                       const TopoDS_Vertex& theV1,
+                                       const Standard_Real theT1,
+                                       const TopoDS_Vertex& theV2,
+                                       const Standard_Real theT2,
+                                       const Standard_Real theTolR3D,
+                                       TopoDS_Edge& theE);
+
+  //! Makes a copy of <theEdge> with vertices.
+  Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge);
+
+  //! Make the edge from base edge <aE1> and two vertices <aV1,aV2>
+  //! at parameters <aP1,aP2>
+  Standard_EXPORT static void MakeSplitEdge(const TopoDS_Edge& aE1,
+                                            const TopoDS_Vertex& aV1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Vertex& aV2,
+                                            const Standard_Real aP2,
+                                            TopoDS_Edge& aNewEdge);
+
+  //! Make the edge from 3D-Curve <aIC>  and two vertices <aV1,aV2>
+  //! at parameters <aP1,aP2>
+  Standard_EXPORT static void MakeSectEdge(const IntTools_Curve& aIC,
+                                           const TopoDS_Vertex& aV1,
+                                           const Standard_Real aP1,
+                                           const TopoDS_Vertex& aV2,
+                                           const Standard_Real aP2,
+                                           TopoDS_Edge& aNewEdge);
+
+
+public: //! @name Point/Edge/Face classification relatively solid
+
   //! Computes the 3-D state of the point thePoint
   //! toward solid theSolid.
   //! theTol - value of precision of computation
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const gp_Pnt& thePoint, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
+  Standard_EXPORT static TopAbs_State ComputeState(const gp_Pnt& thePoint,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   const Handle(IntTools_Context)& theContext);
   
   //! Computes the 3-D state of the vertex theVertex
   //! toward solid theSolid.
   //! theTol - value of precision of computation
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Vertex& theVertex, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Vertex& theVertex,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   const Handle(IntTools_Context)& theContext);
   
   //! Computes the 3-D state of the edge theEdge
   //! toward solid theSolid.
   //! theTol - value of precision of computation
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Edge& theEdge, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Edge& theEdge,
+                                                  const TopoDS_Solid& theSolid,
+                                                  const Standard_Real theTol,
+                                                  const Handle(IntTools_Context)& theContext);
   
   //! Computes the 3-D state of the face theFace
   //! toward solid theSolid.
@@ -176,20 +205,199 @@ public:
   //! theBounds - set of edges of theFace to avoid
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const Standard_Real theTol, TopTools_IndexedMapOfShape& theBounds, Handle(IntTools_Context)& theContext);
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Face& theFace,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   TopTools_IndexedMapOfShape& theBounds,
+                                                   const Handle(IntTools_Context)& theContext);
   
   //! Computes the 3-D state of the shape theShape
   //! toward solid theSolid.
   //! theTol - value of precision of computation
   //! theContext- cahed geometrical tools
   //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeStateByOnePoint (const TopoDS_Shape& theShape, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
+  Standard_EXPORT static TopAbs_State ComputeStateByOnePoint(const TopoDS_Shape& theShape,
+                                                             const TopoDS_Solid& theSolid,
+                                                             const Standard_Real theTol,
+                                                             const Handle(IntTools_Context)& theContext);
+
+
+public: //! @name Face classification relatively solid
+
+  //! For the face theFace and its edge theEdge
+  //! finds the face suitable to produce shell.
+  //! theLCEF - set of faces to search. All faces
+  //! from theLCEF must share edge theEdge
+  Standard_EXPORT static Standard_Boolean GetFaceOff(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Face& theFace,
+                                                     BOPTools_ListOfCoupleOfShape& theLCEF,
+                                                     TopoDS_Face& theFaceOff,
+                                                     const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside of the
+  //! couple of faces theFace1, theFace2.
+  //! The faces theFace, theFace1, theFace2  must
+  //! share the edge theEdge
+  //! Return values:
+  //!  * 0 state is not IN
+  //!  * 1 state is IN
+  //!  * 2 state can not be found by the method of angles
+  Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Edge& theEdge,
+                                                         const TopoDS_Face& theFace1,
+                                                         const TopoDS_Face& theFace2,
+                                                         const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside of the
+  //! appropriate couple of faces (from the set theLF)    .
+  //! The faces of the set theLF and theFace  must
+  //! share the edge theEdge
+  //!  * 0 state is not IN
+  //!  * 1 state is IN
+  //!  * 2 state can not be found by the method of angles
+  Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Edge& theEdge,
+                                                         TopTools_ListOfShape& theLF,
+                                                         const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside the
+  //! solid theSolid.
+  //! theMEF - Map Edge/Faces for theSolid
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  Standard_EXPORT static Standard_Boolean IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Solid& theSolid,
+                                                         TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
+                                                         const Standard_Real theTol,
+                                                         const Handle(IntTools_Context)& theContext);
+
+
+public: //! @name PCurve construction
+
+  //! Makes 2d curve of the edge <theE> on the faces <theF1> and <theF2>.<br>
+  //! <theContext> - storage for caching the geometrical tools
+  Standard_EXPORT static void MakePCurve (const TopoDS_Edge& theE,
+                                          const TopoDS_Face& theF1,
+                                          const TopoDS_Face& theF2,
+                                          const IntTools_Curve& theCurve,
+                                          const Standard_Boolean thePC1,
+                                          const Standard_Boolean thePC2,
+                                          const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+
+
+public: //! @name Wire classification relatively face
+
+  //! Checks if the wire is a hole for the face.
+  Standard_EXPORT static Standard_Boolean IsHole(const TopoDS_Shape& theW,
+                                                 const TopoDS_Shape& theF);
+
+
+public: //! @name Choosing correct orientation for the split shape
+
+  //! Checks if the direction of the split shape is opposite to
+  //! the direction of the original shape.
+  //! The method is an overload for (Edge,Edge) and (Face,Face) corresponding
+  //! methods and checks only these types of shapes.
+  //! For faces the method checks if normal directions are opposite.
+  //! For edges the method checks if tangent vectors are opposite.
+  //!
+  //! In case the directions do not coincide, it returns TRUE, meaning
+  //! that split shape has to be reversed to match the direction of the
+  //! original shape.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - Error from (Edge,Edge) or (Face,Face) corresponding method
+  //! - 100 - bad types.
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split shape
+  //! @param theShape [in] Original shape
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Shape& theSplit,
+                                                           const TopoDS_Shape& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Add-on for the *IsSplitToReverse()* to check for its errors
+  //! and in case of any add the *BOPAlgo_AlertUnableToOrientTheShape*
+  //! warning to the report.
+  Standard_EXPORT static Standard_Boolean IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit,
+                                                                   const TopoDS_Shape& theShape,
+                                                                   const Handle(IntTools_Context)& theContext,
+                                                                   const Handle(Message_Report)& theReport = NULL);
+
+  //! Checks if the normal direction of the split face is opposite to
+  //! the normal direction of the original face.
+  //! The normal directions for both faces are taken in the same point -
+  //! point inside the split face is projected onto the original face.
+  //! Returns TRUE if the normals do not coincide, meaning the necessity
+  //! to revert the orientation of the split face to match the direction
+  //! of the original face.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - 1 - unable to find the point inside split face;
+  //! - 2 - unable to compute the normal for the split face;
+  //! - 3 - unable to project the point inside the split face on the original face;
+  //! - 4 - unable to compute the normal for the original face.
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split face
+  //! @param theShape [in] Original face
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Face& theSplit,
+                                                           const TopoDS_Face& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Checks if the tangent vector of the split edge is opposite to
+  //! the tangent vector of the original edge.
+  //! The tangent vectors for both edges are computed in the same point -
+  //! point inside the split edge is projected onto the original edge.
+  //! Returns TRUE if the tangent vectors do not coincide, meaning the necessity
+  //! to revert the orientation of the split edge to match the direction
+  //! of the original edge.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - 1 - degenerated edges are given;
+  //! - 2 - unable to compute the tangent vector for the split edge;
+  //! - 3 - unable to project the point inside the split edge on the original edge;
+  //! - 4 - unable to compute the tangent vector for the original edge;
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split edge
+  //! @param theShape [in] Original edge
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Edge& theSplit,
+                                                           const TopoDS_Edge& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Checks if the normals direction of the given faces computed near
+  //! the shared edge coincide.
+  //! Returns the status of operation:
+  //! * 0 - in case of error (shared edge not found or directions are not collinear)
+  //! * 1 - normal directions coincide;
+  //! * -1 - normal directions are opposite.
+  Standard_EXPORT static Standard_Integer Sense(const TopoDS_Face& theF1,
+                                                const TopoDS_Face& theF2,
+                                                const Handle(IntTools_Context)& theContext);
+
+public: //! @name Making connexity blocks
+
   //! For the list of faces theLS build block
   //! theLSCB in terms of connexity by edges
   //! theMapAvoid - set of edges to avoid for
   //! the treatment
-  Standard_EXPORT static void MakeConnexityBlock (TopTools_ListOfShape& theLS, TopTools_IndexedMapOfShape& theMapAvoid, TopTools_ListOfShape& theLSCB, const Handle(NCollection_BaseAllocator)& theAllocator);
+  Standard_EXPORT static void MakeConnexityBlock(TopTools_ListOfShape& theLS,
+                                                 TopTools_IndexedMapOfShape& theMapAvoid,
+                                                 TopTools_ListOfShape& theLSCB,
+                                                 const Handle(NCollection_BaseAllocator)& theAllocator);
 
   //! For the compound <theS> builds the blocks (compounds) of
   //! elements of type <theElementType> connected through the shapes
@@ -219,139 +427,136 @@ public:
                                                   const TopAbs_ShapeEnum theElementType,
                                                   BOPTools_ListOfConnexityBlock& theLCB);
 
+public: //! @name Orienting elements in container
+
   //! Correctly orients edges on the wire
-  Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire);
+  Standard_EXPORT static void OrientEdgesOnWire(TopoDS_Shape& theWire);
 
   //! Correctly orients faces on the shell
-  Standard_EXPORT static void OrientFacesOnShell (TopoDS_Shape& theShell);
-  
+  Standard_EXPORT static void OrientFacesOnShell(TopoDS_Shape& theShell);
+
+
+public: //! @name Methods for shape validation (correction)
 
   //! Provides valid values of tolerances for the shape <theS>
   //! <theTolMax> is max value of the tolerance that can be
   //! accepted for correction.  If real value of the tolerance
   //! will be greater than  <aTolMax>, the correction does not
   //! perform.
-  Standard_EXPORT static void CorrectTolerances
-              (const TopoDS_Shape& theS, 
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectTolerances(const TopoDS_Shape& theS, 
+                                                const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                const Standard_Real theTolMax = 0.0001,
+                                                const Standard_Boolean theRunParallel = Standard_False);
 
   //! Provides valid values of tolerances for the shape <theS>
   //! in  terms of BRepCheck_InvalidCurveOnSurface.
-  Standard_EXPORT static void CorrectCurveOnSurface
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectCurveOnSurface(const TopoDS_Shape& theS,
+                                                    const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                    const Standard_Real theTolMax = 0.0001,
+                                                    const Standard_Boolean theRunParallel = Standard_False);
 
   //! Provides valid values of tolerances for the shape <theS>
   //! in  terms of BRepCheck_InvalidPointOnCurve.
-  Standard_EXPORT static void CorrectPointOnCurve
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectPointOnCurve(const TopoDS_Shape& theS,
+                                                  const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                  const Standard_Real theTolMax = 0.0001,
+                                                  const Standard_Boolean theRunParallel = Standard_False);
 
-  //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol>
-  Standard_EXPORT static void MakeNewVertex (const gp_Pnt& aP1, const Standard_Real aTol, TopoDS_Vertex& aNewVertex);
-  
-
-  //! Make a vertex using couple of vertices  <aV1, aV2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2, TopoDS_Vertex& aNewVertex);
-  
-
-  //! Make a vertex in place of intersection between two edges
-  //! <aE1, aE2> with parameters <aP1, aP2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Edge& aE2, const Standard_Real aP2, TopoDS_Vertex& aNewVertex);
-  
+  //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed.
+  Standard_EXPORT static void CorrectShapeTolerances(const TopoDS_Shape& theS,
+                                                     const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                     const Standard_Boolean theRunParallel = Standard_False);
 
-  //! Make a vertex in place of intersection between the edge <aE1>
-  //! with parameter <aP1> and the face <aF2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Face& aF2, TopoDS_Vertex& aNewVertex);
-  
 
-  //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm>
-  Standard_EXPORT static void PointOnEdge (const TopoDS_Edge& aEdge, const Standard_Real aPrm, gp_Pnt& aP);
+public: //! Checking if the faces are coinciding
 
-  //! Makes a copy of <theEdge> with vertices.
-  Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge);
+  //! Checks if the given faces are same-domain, i.e. coincide.
+  Standard_EXPORT static Standard_Boolean AreFacesSameDomain(const TopoDS_Face& theF1,
+                                                             const TopoDS_Face& theF2, 
+                                                             const Handle(IntTools_Context)& theContext,
+                                                             const Standard_Real theFuzz = Precision::Confusion());
 
-  //! Make the edge from base edge <aE1> and two vertices <aV1,aV2>
-  //! at parameters <aP1,aP2>
-  Standard_EXPORT static void MakeSplitEdge (const TopoDS_Edge& aE1, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge);
-  
+public: //! @name Looking for the edge in the face
 
-  //! Make the edge from 3D-Curve <aIC>  and two vertices <aV1,aV2>
-  //! at parameters <aP1,aP2>
-  Standard_EXPORT static void MakeSectEdge (const IntTools_Curve& aIC, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge);
-  
+  //! Returns True if the face theFace contains
+  //! the edge theEdge but with opposite orientation.
+  //! If the method  returns True theEdgeOff is the
+  //! edge founded
+  Standard_EXPORT static Standard_Boolean GetEdgeOff(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Face& theFace,
+                                                     TopoDS_Edge& theEdgeOff);
 
-  //! Update the tolerance value for vertex  <aV>
-  //! taking into account the fact that <aV> lays on
-  //! the curve <aIC>
-  Standard_EXPORT static void UpdateVertex (const IntTools_Curve& aIC, const Standard_Real aT, const TopoDS_Vertex& aV);
-  
+  //! For the face theFace gets the edge theEdgeOnF
+  //! that is the same as theEdge
+  //! Returns True if such edge exists
+  //! Returns False if there is no such edge
+  Standard_EXPORT static Standard_Boolean GetEdgeOnFace(const TopoDS_Edge& theEdge,
+                                                        const TopoDS_Face& theFace,
+                                                        TopoDS_Edge& theEdgeOnF);
 
-  //! Update the tolerance value for vertex  <aV>
-  //! taking into account the fact that <aV> lays on
-  //! the edge <aE>
-  Standard_EXPORT static void UpdateVertex (const TopoDS_Edge& aE, const Standard_Real aT, const TopoDS_Vertex& aV);
-  
 
-  //! Update the tolerance value for vertex  <aVN>
-  //! taking into account the fact that <aVN> should
-  //! cover tolerance zone of <aVF>
-  Standard_EXPORT static void UpdateVertex (const TopoDS_Vertex& aVF, const TopoDS_Vertex& aVN);
-  
+public: //! @name Correction of the edges range
 
   //! Correct shrunk range <aSR> taking into account 3D-curve
-  //! resolution and corresp. tolerances' values of <aE1>, <aE2>
-  Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, const IntTools_Range& aSR, IntTools_Range& aNewSR);
+  //! resolution and corresponding tolerance values of <aE1>, <aE2>
+  Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE1,
+                                           const TopoDS_Edge& aE2,
+                                           const IntTools_Range& aSR,
+                                           IntTools_Range& aNewSR);
   
 
   //! Correct shrunk range <aSR> taking into account 3D-curve
-  //! resolution and corresp. tolerances' values of <aE>, <aF>
-  Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE, const TopoDS_Face& aF, const IntTools_Range& aSR, IntTools_Range& aNewSR);
-  
+  //! resolution and corresponding tolerance values of <aE>, <aF>
+  Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE,
+                                           const TopoDS_Face& aF,
+                                           const IntTools_Range& aSR,
+                                           IntTools_Range& aNewSR);
 
-  //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e
-  //! the <PB> is IN or ON in 2D of <aF>
-  Standard_EXPORT static Standard_Boolean IsBlockInOnFace (const IntTools_Range& aShR, const TopoDS_Face& aF, const TopoDS_Edge& aE, Handle(IntTools_Context)& aContext);
-  
+public: //! @name Checking edge on micro status
 
   //! Checks if it is possible to compute shrunk range for the edge <aE>
   //! Flag <theCheckSplittable> defines whether to take into account 
-  //! the possiblity to split the edge or not.
-  Standard_EXPORT static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge,
-                                                       const Handle(IntTools_Context)& theContext,
-                                                       const Standard_Boolean theCheckSplittable = Standard_True);
-  
+  //! the possibility to split the edge or not.
+  Standard_EXPORT static Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+                                                      const Handle(IntTools_Context)& theContext,
+                                                      const Standard_Boolean theCheckSplittable = Standard_True);
 
-  //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed.
-  Standard_EXPORT static void CorrectShapeTolerances
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Boolean theRunParallel = Standard_False);
+public: //! @name Solid classification
 
-  //! Retutns dimension of the shape <theS>.
-  Standard_EXPORT static Standard_Integer Dimension (const TopoDS_Shape& theS);
-  
-  //! Returns true if the  shell <theShell> is open
-  Standard_EXPORT static Standard_Boolean IsOpenShell (const TopoDS_Shell& theShell);
-  
   //! Returns true if the solid <theSolid> is inverted
-  Standard_EXPORT static Standard_Boolean IsInvertedSolid (const TopoDS_Solid& theSolid);
-  
+  Standard_EXPORT static Standard_Boolean IsInvertedSolid(const TopoDS_Solid& theSolid);
+
+public: //! @name Edge/Face Deviation computation
 
   //! Computes the necessary value of the tolerance for the edge
-  Standard_EXPORT static Standard_Boolean ComputeTolerance (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Standard_Real& theMaxDist, Standard_Real& theMaxPar);
+  Standard_EXPORT static Standard_Boolean ComputeTolerance(const TopoDS_Face& theFace,
+                                                           const TopoDS_Edge& theEdge,
+                                                           Standard_Real& theMaxDist,
+                                                           Standard_Real& theMaxPar);
 
+public: //! @name Other methods
 
-protected:
+  //! Makes empty container of requested type
+  Standard_EXPORT static void MakeContainer(const TopAbs_ShapeEnum theType,
+                                            TopoDS_Shape& theShape);
 
+  //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm>
+  Standard_EXPORT static void PointOnEdge(const TopoDS_Edge& aEdge,
+                                          const Standard_Real aPrm,
+                                          gp_Pnt& aP);
 
-private:
+  //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e
+  //! the <PB> is IN or ON in 2D of <aF>
+  Standard_EXPORT static Standard_Boolean IsBlockInOnFace(const IntTools_Range& aShR,
+                                                          const TopoDS_Face& aF,
+                                                          const TopoDS_Edge& aE,
+                                                          const Handle(IntTools_Context)& aContext);
+
+  //! Retutns dimension of the shape <theS>.
+  Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS);
+
+  //! Returns true if the  shell <theShell> is open
+  Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell);
 
 };
 
index a867d0d..8db49a5 100644 (file)
@@ -42,19 +42,17 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-
   //! Compute P-Curve for the edge <aE> on the face <aF>.<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
-                                                        const TopoDS_Face& aF,
-                                                        const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void BuildPCurveForEdgeOnFace(const TopoDS_Edge& aE,
+                                                       const TopoDS_Face& aF,
+                                                       const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Compute tangent for the edge  <aE> [in 3D]  at parameter <aT>
-  Standard_EXPORT static Standard_Boolean EdgeTangent (const TopoDS_Edge& anE, const Standard_Real aT, gp_Vec& Tau);
-  
+  Standard_EXPORT static Standard_Boolean EdgeTangent(const TopoDS_Edge& anE,
+                                                      const Standard_Real aT,
+                                                      gp_Vec& Tau);
 
   //! Compute surface parameters <U,V> of the face <aF>
   //! for  the point from the edge <aE> at parameter <aT>.<br>
@@ -62,24 +60,23 @@ public:
   //! projection and can
   //! raise exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void PointOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              const Standard_Real aT,
-                                              Standard_Real& U,
-                                              Standard_Real& V,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void PointOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             const Standard_Real aT,
+                                             Standard_Real& U,
+                                             Standard_Real& V,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Get P-Curve <aC>  for the edge <aE> on surface <aF> .<br>
   //! If the P-Curve does not exist, build  it using Make2D().<br>
   //! [aToler] - reached tolerance
   //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              Handle(Geom2d_Curve)& aC,
-                                              Standard_Real& aToler,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+  Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             Handle(Geom2d_Curve)& aC,
+                                             Standard_Real& aToler,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Get P-Curve <aC>  for the edge <aE> on surface <aF> .<br>
   //! If the P-Curve does not exist, build  it using Make2D().<br>
@@ -87,102 +84,108 @@ public:
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              Handle(Geom2d_Curve)& aC,
-                                              Standard_Real& aFirst,
-                                              Standard_Real& aLast,
-                                              Standard_Real& aToler,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             Handle(Geom2d_Curve)& aC,
+                                             Standard_Real& aFirst,
+                                             Standard_Real& aLast,
+                                             Standard_Real& aToler,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Returns TRUE if the edge <aE>  has  P-Curve <aC>
   //! on surface <aF> .
   //! [aFirst, aLast] - range of the P-Curve
   //! [aToler] - reached tolerance
   //! If the P-Curve does not exist, aC.IsNull()=TRUE.
-  Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler);
-  
+  Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE,
+                                                            const TopoDS_Face& aF,
+                                                            Handle(Geom2d_Curve)& aC,
+                                                            Standard_Real& aFirst,
+                                                            Standard_Real& aLast,
+                                                            Standard_Real& aToler);
 
   //! Returns TRUE if the edge <aE>  has  P-Curve <aC>
   //! on surface <aF> .
   //! If the P-Curve does not exist, aC.IsNull()=TRUE.
-  Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF);
-  
+  Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE,
+                                                            const TopoDS_Face& aF);
 
   //! Adjust P-Curve <theC2D> (3D-curve <theC3D>) on surface of the face <theF>.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF,
-                                                  const Handle(Geom_Curve)& theC3D,
-                                                  const Handle(Geom2d_Curve)& theC2D,
-                                                  Handle(Geom2d_Curve)& theC2DA,
-                                                  const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF,
+                                                 const Handle(Geom_Curve)& theC3D,
+                                                 const Handle(Geom2d_Curve)& theC2D,
+                                                 Handle(Geom2d_Curve)& theC2DA,
+                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> .<br>
   //! [aT1,  aT2] - range to adjust<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF,
-                                                  const Standard_Real theFirst,
-                                                  const Standard_Real theLast,
-                                                  const Handle(Geom2d_Curve)& theC2D,
-                                                  Handle(Geom2d_Curve)& theC2DA,
-                                                  const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+  Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF,
+                                                 const Standard_Real theFirst,
+                                                 const Standard_Real theLast,
+                                                 const Handle(Geom2d_Curve)& theC2D,
+                                                 Handle(Geom2d_Curve)& theC2DA,
+                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> .
   //! [aT1,  aT2] - range to adjust
-  Standard_EXPORT static void AdjustPCurveOnSurf (const BRepAdaptor_Surface& aF, const Standard_Real aT1, const Standard_Real aT2, const Handle(Geom2d_Curve)& aC2D, Handle(Geom2d_Curve)& aC2DA);
-  
+  Standard_EXPORT static void AdjustPCurveOnSurf(const BRepAdaptor_Surface& aF,
+                                                 const Standard_Real aT1,
+                                                 const Standard_Real aT2,
+                                                 const Handle(Geom2d_Curve)& aC2D,
+                                                 Handle(Geom2d_Curve)& aC2DA);
 
   //! Compute intermediate  value in  between [aFirst, aLast] .
-  Standard_EXPORT static Standard_Real IntermediatePoint (const Standard_Real aFirst, const Standard_Real aLast);
-  
+  Standard_EXPORT static Standard_Real IntermediatePoint(const Standard_Real aFirst,
+                                                         const Standard_Real aLast);
 
   //! Compute intermediate value of parameter for the edge <anE>.
-  Standard_EXPORT static Standard_Real IntermediatePoint (const TopoDS_Edge& anE);
+  Standard_EXPORT static Standard_Real IntermediatePoint(const TopoDS_Edge& anE);
 
   //! Make P-Curve <aC> for the edge <aE> on surface <aF> .<br>
   //! [aFirst, aLast] - range of the P-Curve<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void Make2D (const TopoDS_Edge& aE,
-                                      const TopoDS_Face& aF,
-                                      Handle(Geom2d_Curve)& aC,
-                                      Standard_Real& aFirst,
-                                      Standard_Real& aLast,
-                                      Standard_Real& aToler,
-                                      const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void Make2D(const TopoDS_Edge& aE,
+                                     const TopoDS_Face& aF,
+                                     Handle(Geom2d_Curve)& aC,
+                                     Standard_Real& aFirst,
+                                     Standard_Real& aLast,
+                                     Standard_Real& aToler,
+                                     const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF,
-                                                const Handle(Geom_Curve)& C3D,
-                                                Handle(Geom2d_Curve)& aC,
-                                                Standard_Real& aToler,
-                                                const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF,
+                                               const Handle(Geom_Curve)& C3D,
+                                               Handle(Geom2d_Curve)& aC,
+                                               Standard_Real& aToler,
+                                               const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br>
   //! [aT1,  aT2] - range to build<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF,
-                                                const Handle(Geom_Curve)& C3D,
-                                                const Standard_Real aT1,
-                                                const Standard_Real aT2,
-                                                Handle(Geom2d_Curve)& aC,
-                                                Standard_Real& aToler,
-                                                const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF,
+                                               const Handle(Geom_Curve)& C3D,
+                                               const Standard_Real aT1,
+                                               const Standard_Real aT2,
+                                               Handle(Geom2d_Curve)& aC,
+                                               Standard_Real& aToler,
+                                               const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+
   //! Attach P-Curve from the edge <aEold> on surface <aF>
   //! to the edge <aEnew>
   //! Returns 0 in case of success
-  Standard_EXPORT static Standard_Integer AttachExistingPCurve (const TopoDS_Edge& aEold, const TopoDS_Edge& aEnew, const TopoDS_Face& aF, const Handle(IntTools_Context)& aCtx);
+  Standard_EXPORT static Standard_Integer AttachExistingPCurve(const TopoDS_Edge& aEold,
+                                                               const TopoDS_Edge& aEnew,
+                                                               const TopoDS_Face& aF,
+                                                               const Handle(IntTools_Context)& aCtx);
 
   //! Checks if CurveOnSurface of theE on theF matches with isoline of theF surface.
   //! Sets corresponding values for isTheUIso and isTheVIso variables.
@@ -199,25 +202,6 @@ public:
                                             Standard_Boolean& isTheUIso,
                                             Standard_Boolean& isTheVIso);
 
-
-protected:
-
-
-
-
-
-private:
-
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPTools_AlgoTools2D_HeaderFile
index 0434b14..e6591cf 100644 (file)
@@ -40,7 +40,7 @@
 #include <IntTools_Context.hxx>
 #include <IntTools_Tools.hxx>
 
-#include <BOPTools_AlgoTools2D.hxx>
+#include <BOPTools_AlgoTools.hxx>
 
 
 
@@ -50,10 +50,6 @@ static
                                       const TopoDS_Face& , 
                                       const Handle(IntTools_Context)& );
 static
-  Standard_Boolean IsToReverse(const TopoDS_Edge& ,
-                               const TopoDS_Edge& ,
-                               const Handle(IntTools_Context)& );
-static
   Standard_Boolean IsClosed(const TopoDS_Edge& ,
                             const TopoDS_Face& );
 
@@ -85,7 +81,7 @@ Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
   //
   aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy());
   //
-  bIsToReverse=IsToReverse(aE2, aE1, aCtx);
+  bIsToReverse = BOPTools_AlgoTools::IsSplitToReverse(aE1, aE2, aCtx);
   if (bIsToReverse) {
     Standard_Real aT21r, aT22r;
     //
@@ -281,49 +277,6 @@ Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold,
   return iRet;
 }
 //=======================================================================
-//function : IsToReverse
-//purpose  : 
-//=======================================================================
-Standard_Boolean IsToReverse(const TopoDS_Edge& aEold,
-                             const TopoDS_Edge& aEnew,
-                             const Handle(IntTools_Context)& aCtx)
-{
-  Standard_Boolean bRet, bIsDegenerated;
-  Standard_Real aTnew, aTold, aScPr, aTa, aTb, aT1, aT2;
-  gp_Vec aVold, aVnew, aVE, aVS;
-  gp_Pnt aP;
-  Handle(Geom_Curve) aCold, aCnew;
-  //
-  bRet=Standard_False;
-  //
-  bIsDegenerated=(BRep_Tool::Degenerated(aEold) ||
-                  BRep_Tool::Degenerated(aEnew));
-  if (bIsDegenerated) {
-    return bRet;
-  }
-  //
-  aCold=BRep_Tool::Curve(aEold, aT1, aT2);
-  aCnew=BRep_Tool::Curve(aEnew, aTa, aTb);
-  //
-  if (aCold==aCnew) {
-    return bRet;
-  }
-  //
-  aTnew=BOPTools_AlgoTools2D::IntermediatePoint(aTa, aTb);
-  aCnew->D1(aTnew, aP, aVnew);
-  aVnew.Normalize(); 
-  //
-  if (!aCtx->ProjectPointOnEdge(aP, aEold, aTold))
-    return Standard_False;
-  aCold->D1(aTold, aP, aVold);
-  aVold.Normalize(); 
-  //
-  aScPr=aVnew*aVold;
-  bRet=(aScPr<0.);
-  //
-  return bRet;
-}
-//=======================================================================
 //function : IsClosed
 //purpose  :
 //=======================================================================
index d45c8a1..06653d1 100644 (file)
@@ -369,7 +369,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
    const Standard_Real aT,
    gp_Pnt& aPNear,
    gp_Dir& aDNF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   gp_Pnt2d aPx2DNear;
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
@@ -398,7 +398,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
    const Standard_Real theStep,
    gp_Pnt& aPNear,
    gp_Dir& aDNF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   gp_Pnt2d aPx2DNear;
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
@@ -510,7 +510,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const Standard_Real aT, 
    gp_Pnt2d& aPx2DNear,
    gp_Pnt& aPxNear,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aTolE, aTolF, dTx, dT2D;
   Handle(Geom_Surface) aS;
@@ -563,7 +563,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const Standard_Real theStep,
    gp_Pnt2d& aPx2DNear,
    gp_Pnt& aPxNear,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
     (aE, aF, aT, theStep, aPx2DNear, aPxNear);
@@ -593,7 +593,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const TopoDS_Face& aF, 
    gp_Pnt2d& aPInFace2D, 
    gp_Pnt& aPInFace,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aT, aT1, aT2;
   //
@@ -783,7 +783,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
   (const TopoDS_Face& theF,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer i, iErr = 1;
   Standard_Real aUMin, aUMax, aVMin, aVMax, aUx;
@@ -822,7 +822,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
    const Standard_Real theDt2D,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iErr;
   Standard_Real f, l;
@@ -870,7 +870,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
    const Handle(Geom2d_Curve)& theL2D,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext,
+   const Handle(IntTools_Context)& theContext,
    const Standard_Real theDt2D)
 {
   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
index a9567b7..9a3d5de 100644 (file)
@@ -100,7 +100,7 @@ public:
                                                                        const Standard_Real aT,
                                                                        gp_Pnt& aPx,
                                                                        gp_Dir& aD,
-                                                                       Handle(IntTools_Context)& theContext);
+                                                                       const Handle(IntTools_Context)& theContext);
   
   //! Computes normal to the face <aF> for the 3D-point that
   //! belongs to the edge <aE> at parameter <aT>.<br>
@@ -142,7 +142,7 @@ public:
                                                                        const Standard_Real aDt2D,
                                                                        gp_Pnt& aP,
                                                                        gp_Dir& aDNF,
-                                                                       Handle(IntTools_Context)& theContext);
+                                                                       const Handle(IntTools_Context)& theContext);
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
   //! the edge <aE>   at parameter <aT>  towards to the
@@ -160,7 +160,7 @@ public:
                                                          const Standard_Real aDt2D,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
   //! the edge <aE>   at parameter <aT>  towards to the
@@ -191,7 +191,7 @@ public:
                                                          const Standard_Real aT,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
   
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
@@ -208,7 +208,7 @@ public:
                                                          const TopoDS_Face& aF,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
   
 
   //! Returns simple step value that is used in 2D-computations
@@ -232,7 +232,7 @@ public:
   Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, 
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext);
+                                                       const Handle(IntTools_Context)& theContext);
 
   //! Computes a point <theP> inside the face <theF> 
   //! using starting point taken by the parameter <theT> 
@@ -249,7 +249,7 @@ public:
                                                        const Standard_Real theDt2D,
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext);
+                                                       const Handle(IntTools_Context)& theContext);
 
   //! Computes a point <theP> inside the face <theF> 
   //! using the line <theL> so that 2D point
@@ -260,7 +260,7 @@ public:
                                                        const Handle(Geom2d_Curve)& theL,
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext,
+                                                       const Handle(IntTools_Context)& theContext,
                                                        const Standard_Real theDt2D = 0.0);
 
 
diff --git a/tests/bugs/modalg_7/bug29698 b/tests/bugs/modalg_7/bug29698
new file mode 100644 (file)
index 0000000..04deaad
--- /dev/null
@@ -0,0 +1,43 @@
+puts "============"
+puts "OCC29698"
+puts "============"
+puts ""
+###############################
+## Regression vs 7.2.0: Common operation raises FLT_INVALID_OPERATION exception
+###############################
+
+# the case is a copy of the test case
+# bugs/modalg_6/bug26952_1
+# to test the BOP operation on the same arguments
+# with FPE signals switched on
+
+restore [locate_data_file bug26952_B41.brep] b1
+restore [locate_data_file bug26952_Tank41_1.brep] b2
+
+# enable FPE signals
+dsetsignal 1
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+bbop result 0
+
+# disable FPE signals
+dsetsignal 0
+
+checkprops result -s 424.666
+checknbshapes result -wire 2 -face 1
+
+# check modification of the front face of the solid
+savehistory h
+explode b2 f
+modified f_mod h b2_12
+
+explode result f
+checkprops f_mod -equal result_1
+
+checknbshapes f_mod -ref [nbshapes result_1]
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png