0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BOPAlgo / BOPAlgo_ArgumentAnalyzer.cxx
index 87a55ca..bb075bf 100644 (file)
@@ -1,71 +1,63 @@
 // Created on: 2004-09-02
-// Copyright (c) 2004-2012 OPEN CASCADE SAS
+// Copyright (c) 2004-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-#include <BOPAlgo_ArgumentAnalyzer.ixx>
 
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-#include <TopExp.hxx>
-#include <TopExp_Explorer.hxx>
+#include <BOPAlgo_ArgumentAnalyzer.hxx>
+#include <BOPAlgo_BuilderFace.hxx>
+#include <BOPAlgo_CheckerSI.hxx>
+#include <BOPAlgo_Operation.hxx>
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPCol_MapOfShape.hxx>
+#include <BOPCol_SequenceOfShape.hxx>
+#include <BOPDS_DS.hxx>
+#include <BOPDS_MapOfPassKey.hxx>
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
 #include <BRep_Builder.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_TFace.hxx>
 #include <BRep_Tool.hxx>
+#include <BRep_TVertex.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
+#include <Geom_Surface.hxx>
 #include <gp_Pnt.hxx>
-#include <TopoDS_Iterator.hxx>
+#include <IntTools_CommonPrt.hxx>
+#include <IntTools_Context.hxx>
+#include <IntTools_EdgeEdge.hxx>
+#include <IntTools_Range.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+#include <TColStd_Array2OfBoolean.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Solid.hxx>
-#include <BOPCol_ListOfShape.hxx>
-#include <BOPCol_SequenceOfShape.hxx>
-#include <BOPCol_MapOfShape.hxx>
-
-#include <TColStd_Array2OfBoolean.hxx>
-
-#include <IntTools_Range.hxx>
-#include <IntTools_EdgeEdge.hxx>
-#include <IntTools_CommonPrt.hxx>
-
-#include <BOPAlgo_Operation.hxx>
-#include <BOPAlgo_CheckerSI.hxx>
-#include <BOPAlgo_BuilderFace.hxx>
-
-#include <BOPDS_DS.hxx>
-#include <BOPDS_VectorOfInterfVV.hxx>
-#include <BOPDS_VectorOfInterfVE.hxx>
-#include <BOPDS_VectorOfInterfEE.hxx>
-#include <BOPDS_VectorOfInterfVF.hxx>
-#include <BOPDS_VectorOfInterfEF.hxx>
-#include <BOPDS_VectorOfInterfFF.hxx>
-
-#include <BOPInt_Context.hxx>
-
-#include <BOPTools_AlgoTools3D.hxx>
-#include <BOPTools_AlgoTools.hxx>
-#include <BOPCol_ListOfShape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
 
+//
 // ================================================================================
 // function: Constructor
 // purpose:
 // ================================================================================
 BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() : 
+BOPAlgo_Algo(),
 myStopOnFirst(Standard_False),
 myOperation(BOPAlgo_UNKNOWN),
 myArgumentTypeMode(Standard_False),
@@ -75,10 +67,21 @@ myRebuildFaceMode(Standard_False),
 myTangentMode(Standard_False),
 myMergeVertexMode(Standard_False),
 myMergeEdgeMode(Standard_False),
+myContinuityMode(Standard_False),
+myCurveOnSurfaceMode(Standard_False),
 myEmpty1(Standard_False),
-myEmpty2(Standard_False)
-// myMergeFaceMode(Standard_False)
+myEmpty2(Standard_False),
+myFuzzyValue(0.)
+{
+}
+//=======================================================================
+// function: ~
+// purpose: 
+//=======================================================================
+BOPAlgo_ArgumentAnalyzer::~BOPAlgo_ArgumentAnalyzer()
 {
+  myResult.Clear();
+  myToleranceMap.Clear();
 }
 
 // ================================================================================
@@ -158,47 +161,94 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
   try {
     OCC_CATCH_SIGNALS
     myResult.Clear();
-
+    //
+    UserBreak();
+    //
+    // 1. Prepare
     Prepare();
-
+    //
+    UserBreak();
+    //
+    // 2. Update Tolerances according to myFuzzyValue
+    UpdateTolerances();
+    //
+    UserBreak();
+    //
+    // 3. Test types
     if(myArgumentTypeMode) {
       TestTypes();
     }
-
+    //
+    UserBreak();
+    //
+    // 4. Test self-interference
     if(mySelfInterMode) {
       TestSelfInterferences();
     }
-
+    //
+    UserBreak();
+    //
+    // 5. Test small edges
     if(mySmallEdgeMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestSmallEdge();
     }
-
+    //
+    UserBreak();
+    //
+    // 6. Test possibility to rebuild faces
     if(myRebuildFaceMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestRebuildFace();
     }
-
+    //
+    UserBreak();
+    //
+    // 7. Test tangent
     if(myTangentMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestTangent();
     }
-
+    //
+    UserBreak();
+    //
+    // 8. Test merge vertices
     if(myMergeVertexMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestMergeVertex();
     }
-    
+    //
+    UserBreak();
+    //
+    // 9. Test merge edges
     if(myMergeEdgeMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestMergeEdge();
     }
+    //
+    UserBreak();
+    //
+    // 10. Test shapes continuity
+    if(myContinuityMode) {
+      if(!(!myResult.IsEmpty() && myStopOnFirst))
+        TestContinuity();
+    }
+    //
+    UserBreak();
+    //
+    // 11. Test validity of the curves on the surfaces
+    if(myCurveOnSurfaceMode) {
+      if(!(!myResult.IsEmpty() && myStopOnFirst))
+        TestCurveOnSurface();
+    }
   }
   catch(Standard_Failure) {
     BOPAlgo_CheckResult aResult;
     aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
     myResult.Append(aResult);
   }
+  //
+  SetDefaultTolerances();
 }
 
 // ================================================================================
@@ -293,125 +343,83 @@ void BOPAlgo_ArgumentAnalyzer::TestTypes()
     }
   }
 }
-
-// ================================================================================
-// function: TestSelfInterferences
-// purpose:
-// ================================================================================
+//=======================================================================
+//function : TestSelfInterferences
+//purpose  : 
+//=======================================================================
 void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
 {
-  Standard_Integer ii = 0, j;
-  Standard_Boolean bSelfInt;
-
+  Standard_Integer ii;
+  //
   for(ii = 0; ii < 2; ii++) {
-    TopoDS_Shape aS = (ii == 0) ? myShape1 : myShape2;
-
-    if(aS.IsNull())
+    const TopoDS_Shape& aS = (ii == 0) ? myShape1 : myShape2;
+    if(aS.IsNull()) {
       continue;
-
+    }
+    //
     Standard_Boolean bIsEmpty = (ii == 0) ? myEmpty1 : myEmpty2;
     if (bIsEmpty) {
       continue;
     }
-
-    BOPAlgo_CheckerSI aChecker;
+    //
+    Standard_Integer iErr, n1, n2;
+    BOPDS_MapIteratorMapOfPassKey aItMPK;
     BOPCol_ListOfShape anArgs;
+    BOPAlgo_CheckerSI aChecker;
+    //
     anArgs.Append(aS);
     aChecker.SetArguments(anArgs);
+    aChecker.SetNonDestructive(Standard_True);
+    aChecker.SetRunParallel(myRunParallel);
+    aChecker.SetProgressIndicator(myProgressIndicator);
     //
     aChecker.Perform();
-    Standard_Integer iErr = aChecker.ErrorStatus();
-    //
-    const BOPDS_PDS& theDS = aChecker.PDS();
-    BOPDS_VectorOfInterfVV& aVVs=theDS->InterfVV();
-    BOPDS_VectorOfInterfVE& aVEs=theDS->InterfVE();
-    BOPDS_VectorOfInterfEE& aEEs=theDS->InterfEE();
-    BOPDS_VectorOfInterfVF& aVFs=theDS->InterfVF();
-    BOPDS_VectorOfInterfEF& aEFs=theDS->InterfEF();
-    BOPDS_VectorOfInterfFF& aFFs=theDS->InterfFF();
-    //
-    Standard_Integer aNb[6] = {aVVs.Extent(), aVEs.Extent(), aEEs.Extent(), 
-                               aVFs.Extent(), aEFs.Extent(), aFFs.Extent()};
-    //
-    Standard_Integer ind = 0;
-    for (Standard_Integer aTypeInt = 0; aTypeInt < 6; ++aTypeInt) {
-      for (Standard_Integer i = 0; i < aNb[aTypeInt]; ++i) {
-        BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : 
-          ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
-           ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : 
-            ((aTypeInt==3) ? (BOPDS_Interf*)(&aVFs(i)) :
-             ((aTypeInt==4) ? (BOPDS_Interf*)(&aEFs(i)) : (BOPDS_Interf*)(&aFFs(i))))));
-        //
-        Standard_Integer nI1 = aInt->Index1();
-        Standard_Integer nI2 = aInt->Index2();
-        if (nI1 == nI2) {
-          continue;
-        }
-        //
-        const TopoDS_Shape& aS1 = theDS->Shape(nI1);
-        const TopoDS_Shape& aS2 = theDS->Shape(nI2);
-        //
-        if (aTypeInt == 5) {
-          bSelfInt = Standard_False;
-          BOPDS_InterfFF& aFF = aFFs(i);
-          BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
-          Standard_Integer aNbP=aVP.Extent();
-          BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
-          Standard_Integer aNbC=aVC.Extent();
-          if (!aNbP && !aNbC) {
-            continue;
-          }
-          for (j=0; j<aNbC; ++j) {
-            BOPDS_Curve& aNC=aVC(j);
-            BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
-            if (aLPBC.Extent()) {
-              bSelfInt = Standard_True;
-              break;
-            }
-          }
-          if (!bSelfInt) {
-            continue;
-          }
-        }
-        //
-        BOPAlgo_CheckResult aResult;
-        if(ii == 0)
-          aResult.SetShape1(myShape1);
-        else
-          aResult.SetShape2(myShape2);
-
-        if(ii == 0) {
-          aResult.AddFaultyShape1(aS1);
-          aResult.AddFaultyShape1(aS2);
-        }
-        else {
-          aResult.AddFaultyShape2(aS1);
-          aResult.AddFaultyShape2(aS2);
-        }
-        aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
-        myResult.Append(aResult);
+    iErr=aChecker.ErrorStatus();
+    //
+    const BOPDS_DS& aDS=*(aChecker.PDS());
+    const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
+    //
+    aItMPK.Initialize(aMPK);
+    for (; aItMPK.More(); aItMPK.Next()) {
+      const BOPDS_PassKey& aPK=aItMPK.Value();
+      aPK.Ids(n1, n2);
+      if(aDS.IsNewShape(n1) || aDS.IsNewShape(n2)) {
+        continue;
       }
-    }
-    if (iErr) {
+      //
+      const TopoDS_Shape& aS1=aDS.Shape(n1);
+      const TopoDS_Shape& aS2=aDS.Shape(n2);
+      //
       BOPAlgo_CheckResult aResult;
-      if(ii == 0)
+      if(ii == 0) {
         aResult.SetShape1(myShape1);
-      else
+        aResult.AddFaultyShape1(aS1);
+        aResult.AddFaultyShape1(aS2);
+      }
+      else {
         aResult.SetShape2(myShape2);
-      
+        aResult.AddFaultyShape2(aS1);
+        aResult.AddFaultyShape2(aS2);
+      }
+      aResult.SetCheckStatus(BOPAlgo_SelfIntersect);
+      myResult.Append(aResult);
+    }
+    //
+    if (iErr) {
+      BOPAlgo_CheckResult aResult;
       if(ii == 0) {
+        aResult.SetShape1(myShape1);
         aResult.AddFaultyShape1(myShape1);
       }
       else {
+        aResult.SetShape2(myShape2);
         aResult.AddFaultyShape2(myShape2);
       }
       aResult.SetCheckStatus(BOPAlgo_OperationAborted);
       myResult.Append(aResult);
     }
-  }
-  
+  }// for(ii = 0; ii < 2; ii++) {
 }
-
 // ================================================================================
 // function: TestSmallEdge
 // purpose:
@@ -420,12 +428,12 @@ void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
 {
   Standard_Integer i = 0;
   BRepExtrema_DistShapeShape aDist;
-  Handle(BOPInt_Context) aCtx;
+  Handle(IntTools_Context) aCtx;
   //
-  aCtx = new BOPInt_Context;
+  aCtx = new IntTools_Context;
   
   for(i = 0; i < 2; i++) {
-    TopoDS_Shape aS = (i == 0) ? myShape1 : myShape2;
+    const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
 
     if(aS.IsNull())
       continue;
@@ -433,13 +441,16 @@ void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
     TopExp_Explorer anExp(aS, TopAbs_EDGE);
 
     for(; anExp.More(); anExp.Next()) {
-      TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
+      const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&anExp.Current();
+      if (BRep_Tool::Degenerated(anEdge)) {
+        continue;
+      }
 
       if(BOPTools_AlgoTools::IsMicroEdge(anEdge, aCtx)) {
         Standard_Boolean bKeepResult = Standard_True;
         
         if(myOperation == BOPAlgo_SECTION) {
-          TopoDS_Shape anOtherS = (i == 0) ? myShape2 : myShape1;
+          const TopoDS_Shape& anOtherS = (i == 0) ? myShape2 : myShape1;
           
           if(!anOtherS.IsNull()) {
             aDist.LoadS2(anOtherS);
@@ -449,7 +460,7 @@ void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
             TopExp_Explorer anExpV(anEdge, TopAbs_VERTEX);
             
             for(; anExpV.More(); anExpV.Next()) {
-              TopoDS_Shape aV = anExpV.Current();
+              const TopoDS_Shape& aV = anExpV.Current();
               
               aDist.LoadS1(aV);
               aDist.Perform();
@@ -457,20 +468,20 @@ void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
               if(aDist.IsDone()) {
                 
                 for(ii = 1; ii <= aDist.NbSolution(); ii++) {
-                  Standard_Real aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aV));
-                  TopoDS_Shape aSupportShape = aDist.SupportOnShape2(ii);
+                  Standard_Real aTolerance = BRep_Tool::Tolerance(*(TopoDS_Vertex*)&aV);
+                  const TopoDS_Shape& aSupportShape = aDist.SupportOnShape2(ii);
                   
                   switch(aSupportShape.ShapeType()) {
                   case TopAbs_VERTEX: {
-                    aTolerance += BRep_Tool::Tolerance(TopoDS::Vertex(aSupportShape));
+                    aTolerance += BRep_Tool::Tolerance(*(TopoDS_Vertex*)&(aSupportShape));
                     break;
                   }
                   case TopAbs_EDGE: {
-                    aTolerance += BRep_Tool::Tolerance(TopoDS::Edge(aSupportShape));
+                    aTolerance += BRep_Tool::Tolerance(*(TopoDS_Edge*)&(aSupportShape));
                     break;
                   }
                   case TopAbs_FACE: {
-                    aTolerance += BRep_Tool::Tolerance(TopoDS::Face(aSupportShape));
+                    aTolerance += BRep_Tool::Tolerance(*(TopoDS_Face*)&(aSupportShape));
                     break;
                   }
                   default:
@@ -514,7 +525,6 @@ void BOPAlgo_ArgumentAnalyzer::TestSmallEdge()
     }
   }
 }
-
 // ================================================================================
 // function: TestRebuildFace
 // purpose:
@@ -527,7 +537,7 @@ void BOPAlgo_ArgumentAnalyzer::TestRebuildFace()
   Standard_Integer i = 0;
 
   for(i = 0; i < 2; i++) {
-    TopoDS_Shape aS = (i == 0) ? myShape1 : myShape2;
+    const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
 
     if(aS.IsNull())
       continue;
@@ -536,7 +546,7 @@ void BOPAlgo_ArgumentAnalyzer::TestRebuildFace()
     BOPCol_ListOfShape aLS;
 
     for(; anExp.More(); anExp.Next()) {
-      TopoDS_Face aFace = TopoDS::Face(anExp.Current());
+      const TopoDS_Face& aFace = *(TopoDS_Face*)&(anExp.Current());
 
       TopoDS_Face aFF = aFace;
       aFF.Orientation(TopAbs_FORWARD);
@@ -649,7 +659,7 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent()
   BOPCol_MapOfShape aMap1, aMap2;
 
   for(; anExp1.More(); anExp1.Next()) {
-    TopoDS_Shape aS1 = anExp1.Current();
+    const TopoDS_Shape& aS1 = anExp1.Current();
 
     if(aMap1.Contains(aS1))
       continue;
@@ -658,7 +668,7 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent()
   }
 
   for(; anExp2.More(); anExp2.Next()) {
-    TopoDS_Shape aS2 = anExp2.Current();
+    const TopoDS_Shape& aS2 = anExp2.Current();
     if(aMap2.Contains(aS2))
       continue;
     aSeq2.Append(aS2);
@@ -672,18 +682,18 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent()
       anArrayOfFlag.SetValue(i, j, Standard_False);
 
   for(i = 1; i <= aSeq1.Length(); i++) {
-    TopoDS_Shape aS1 = aSeq1.Value(i);
+    const TopoDS_Shape& aS1 = aSeq1.Value(i);
     BOPCol_ListOfShape aListOfS2;
     Standard_Integer nbs = 0;
 
     for(j = 1; j <= aSeq2.Length(); j++) {
-      TopoDS_Shape aS2 = aSeq2.Value(j);
+      const TopoDS_Shape& aS2 = aSeq2.Value(j);
       Standard_Boolean bIsEqual = Standard_False;
 
       if(theType == TopAbs_VERTEX) {
 
-        TopoDS_Vertex aV1 = TopoDS::Vertex(aS1);
-        TopoDS_Vertex aV2 = TopoDS::Vertex(aS2);
+        const TopoDS_Vertex& aV1 = *(TopoDS_Vertex*)&(aS1);
+        const TopoDS_Vertex& aV2 = *(TopoDS_Vertex*)&(aS2);
         gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
         gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
         Standard_Real aDist = aP1.Distance(aP2);
@@ -693,28 +703,12 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent()
         }
       }
       else if(theType == TopAbs_EDGE) {
-        Standard_Integer aDiscretize = 30;
-        Standard_Real    aDeflection = 0.01;
-        TopoDS_Edge aE1 = TopoDS::Edge(aS1);
-        TopoDS_Edge aE2 = TopoDS::Edge(aS2);
-        
-        IntTools_EdgeEdge aEE;
-        aEE.SetEdge1 (aE1);
-        aEE.SetEdge2 (aE2);
-        aEE.SetTolerance1 (BRep_Tool::Tolerance(aE1));
-        aEE.SetTolerance2 (BRep_Tool::Tolerance(aE2));
-        aEE.SetDiscretize (aDiscretize);
-        aEE.SetDeflection (aDeflection);
-        
-        Standard_Real f = 0., l = 0.;
-        BRep_Tool::Range(aE1, f, l);
-        aEE.SetRange1(f, l);
-        
-        BRep_Tool::Range(aE2, f, l);
-        aEE.SetRange2(f, l);
-        
+        const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&(aS1);
+        const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&(aS2);
+        //
+        IntTools_EdgeEdge aEE(aE1, aE2);
+        //
         aEE.Perform();
-        
         if (aEE.IsDone()) {
           const IntTools_SequenceOfCommonPrts& aCPrts = aEE.CommonParts();
           Standard_Integer ii = 0;
@@ -761,12 +755,12 @@ void BOPAlgo_ArgumentAnalyzer::TestTangent()
   }
 
   for(i = 1; i <= aSeq2.Length(); i++) {
-    TopoDS_Shape aS2 = aSeq2.Value(i);
+    const TopoDS_Shape& aS2 = aSeq2.Value(i);
     BOPCol_ListOfShape aListOfS1;
     Standard_Integer nbs = 0;
 
     for(j = 1; j <= aSeq1.Length(); j++) {
-      TopoDS_Shape aS1 = aSeq1.Value(j);
+      const TopoDS_Shape& aS1 = aSeq1.Value(j);
 
       if(anArrayOfFlag.Value(j, i)) {
         aListOfS1.Append(aS1);
@@ -815,10 +809,229 @@ void BOPAlgo_ArgumentAnalyzer::TestMergeEdge()
 }
 
 // ================================================================================
-// function: TestMergeFace
+// function: TestContinuity
 // purpose:
 // ================================================================================
-// void BOPAlgo_ArgumentAnalyzer::TestMergeFace() 
-// {
-  // not implemented
-// }
+void BOPAlgo_ArgumentAnalyzer::TestContinuity() 
+{
+  Standard_Integer i;
+  Standard_Real f, l;
+  TopExp_Explorer aExp;
+  BOPCol_MapIteratorOfMapOfShape aIt;
+  //
+  for (i = 0; i < 2; ++i) {
+    const TopoDS_Shape& aS = !i ? myShape1 : myShape2;
+    if(aS.IsNull()) {
+      continue;
+    }
+    //
+    BOPCol_MapOfShape aMS;
+    //Edges
+    aExp.Init(aS, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, f, l);
+      if (aC->Continuity() == GeomAbs_C0) {
+        aMS.Add(aE);
+      }
+    }
+    //Faces
+    aExp.Init(aS, TopAbs_FACE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
+      const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF);
+      if (aS->Continuity() == GeomAbs_C0) {
+        aMS.Add(aF);
+      }
+    }
+    //
+    //add shapes with continuity C0 to result
+    aIt.Initialize(aMS);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aFS = aIt.Value();
+      BOPAlgo_CheckResult aResult;
+      if(i == 0) {
+        aResult.SetShape1(myShape1);
+        aResult.AddFaultyShape1(aFS);
+      } else {
+        aResult.SetShape2(myShape2);
+        aResult.AddFaultyShape2(aFS);
+      }
+      aResult.SetCheckStatus(BOPAlgo_GeomAbs_C0);
+      myResult.Append(aResult);
+    }
+  }
+}
+
+// ================================================================================
+// function: TestCurveOnSurface
+// purpose:
+// ================================================================================
+void BOPAlgo_ArgumentAnalyzer::TestCurveOnSurface()
+{
+  Standard_Integer i;
+  Standard_Real aT, aD, aTolE;
+  TopExp_Explorer aExpF, aExpE;
+  //
+  for(i = 0; i < 2; i++) {
+    const TopoDS_Shape& aS = (i == 0) ? myShape1 : myShape2;
+    if(aS.IsNull()) {
+      continue;
+    }
+    //
+    aExpF.Init(aS, TopAbs_FACE);
+    for (; aExpF.More(); aExpF.Next()) {
+      const TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current();
+      //
+      aExpE.Init(aF, TopAbs_EDGE);
+      for (; aExpE.More(); aExpE.Next()) {
+        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
+        //
+        if (BOPTools_AlgoTools::ComputeTolerance(aF, aE, aD, aT)) {
+          aTolE = BRep_Tool::Tolerance(aE);
+          if (aD > aTolE) {
+            BOPAlgo_CheckResult aResult;
+            aResult.SetCheckStatus(BOPAlgo_InvalidCurveOnSurface);
+            if(i == 0) {
+              aResult.SetShape1(myShape1);
+              aResult.AddFaultyShape1(aE);
+              aResult.AddFaultyShape1(aF);
+              aResult.SetMaxDistance1(aD);
+              aResult.SetMaxParameter1(aT);
+            }
+            else {
+              aResult.SetShape2(myShape2);
+              aResult.AddFaultyShape2(aE);
+              aResult.AddFaultyShape2(aF);
+              aResult.SetMaxDistance2(aD);
+              aResult.SetMaxParameter2(aT);
+            }
+            myResult.Append(aResult);
+          }
+        }
+      }
+    }
+  }
+}
+
+// ================================================================================
+// function: UpdateTolerances
+// purpose:
+// ================================================================================
+void BOPAlgo_ArgumentAnalyzer::UpdateTolerances()
+{
+  if (myFuzzyValue == 0.) {
+    return;
+  }
+  //
+  BOPCol_MapOfShape aMapShapes;
+  //
+  if (!myShape1.IsNull()) {
+    BOPTools::MapShapes(myShape1, aMapShapes);
+  }
+  if (!myShape2.IsNull()) {
+    BOPTools::MapShapes(myShape2, aMapShapes);
+  }
+  //
+  if (aMapShapes.IsEmpty()) {
+    return;
+  }
+  //
+  Standard_Real aTol, aFuzz;
+  TopAbs_ShapeEnum aType;
+  BOPCol_MapIteratorOfMapOfShape aIt;
+  //
+  aFuzz = myFuzzyValue / 2.;
+  aIt.Initialize(aMapShapes);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aS = aIt.Value();
+    aType = aS.ShapeType();
+    //
+    switch (aType) {
+    case TopAbs_VERTEX: {
+      const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
+      const Handle(BRep_TVertex)& TV = 
+        *((Handle(BRep_TVertex)*)&aV.TShape());
+      aTol = TV->Tolerance();
+      myToleranceMap.Bind(aS, aTol);
+      TV->Tolerance(aTol + aFuzz);
+      break;
+    }
+    case TopAbs_EDGE: {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
+      const Handle(BRep_TEdge)& TE = 
+        *((Handle(BRep_TEdge)*)&aE.TShape());
+      aTol = TE->Tolerance();
+      myToleranceMap.Bind(aS, aTol);
+      TE->Tolerance(aTol + aFuzz);
+      break;
+    }
+    case TopAbs_FACE: {
+      const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
+      const Handle(BRep_TFace)& TF = 
+        *((Handle(BRep_TFace)*)&aF.TShape());
+      aTol = TF->Tolerance();
+      myToleranceMap.Bind(aS, aTol);
+      TF->Tolerance(aTol + aFuzz);
+      break;
+    }
+    default:
+      break;
+    } // switch (aType) {
+  } // for (; aIt.More(); aIt.Next()) {
+}
+
+// ================================================================================
+// function: SetDefaultTolerances
+// purpose:
+// ================================================================================
+void BOPAlgo_ArgumentAnalyzer::SetDefaultTolerances()
+{
+  if (myFuzzyValue == 0.) {
+    return;
+  }
+  //
+  if (myToleranceMap.IsEmpty()) {
+    return;
+  }
+  //
+  Standard_Real aTol;
+  TopAbs_ShapeEnum aType;
+  BOPCol_DataMapIteratorOfDataMapOfShapeReal aIt;
+  //
+  aIt.Initialize(myToleranceMap);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aS = aIt.Key();
+    aTol = aIt.Value();
+    aType = aS.ShapeType();
+    //
+    switch (aType) {
+    case TopAbs_VERTEX: {
+      const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
+      const Handle(BRep_TVertex)& TV = 
+        *((Handle(BRep_TVertex)*)&aV.TShape());
+      TV->Tolerance(aTol);
+      break;
+    }
+    case TopAbs_EDGE: {
+      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
+      const Handle(BRep_TEdge)& TE = 
+        *((Handle(BRep_TEdge)*)&aE.TShape());
+      TE->Tolerance(aTol);
+      break;
+    }
+    case TopAbs_FACE: {
+      const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
+      const Handle(BRep_TFace)& TF = 
+        *((Handle(BRep_TFace)*)&aF.TShape());
+      TF->Tolerance(aTol);
+      break;
+    }
+    default:
+      break;
+    } // switch (aType) {
+  } // for (; aIt.More(); aIt.Next()) {
+}