0023648: Add tool for checking shapes on validity for boolean operations.
authoremv <emv@opencascade.com>
Wed, 27 Feb 2013 09:04:39 +0000 (13:04 +0400)
committeremv <emv@opencascade.com>
Thu, 7 Mar 2013 09:38:27 +0000 (13:38 +0400)
Modifications:
1. To provide the checking tool for single or couple of shapes in the
context of issue "0021762:Integration of new Boolean Operation Algorithm
into OCCT" has been implemented new class BRepAlgoAPI_Check.
This class provides possibility to check single shape or couple of shapes
on topological validity, small edges and self-interference. Also, the couple
of shapes can be checked on validity for boolean operation of given type.
2. According to the issue "0023613:Add diagnostic tool for BOP" by GKA
has been implemented new static public function BRepAlgoAPI::BoolDump().
This function is used for saving the initial shapes and the result shape of
boolean operation in case if the arguments or the result are not valid shapes
in terms of BRepAlgoAPI_Check.

src/BOPTest/BOPTest_BOPCommands.cxx
src/BRepAlgoAPI/BRepAlgoAPI.cdl
src/BRepAlgoAPI/BRepAlgoAPI.cxx [new file with mode: 0644]
src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx

index f3695f5..8331f75 100755 (executable)
@@ -34,7 +34,6 @@
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_Operation.hxx>
 #include <BOPAlgo_BOP.hxx>
-#include <BOPAlgo_SectionAttribute.hxx>
 #include <BOPDS_DS.hxx>
 #include <BOPTest_DrawableShape.hxx>
 #include <BOPCol_ListOfShape.hxx>
 #include <DrawTrSurf.hxx>
 #include <Draw_Color.hxx>
 #include <Draw.hxx>
+#include <BRepAlgoAPI_BooleanOperation.hxx>
+#include <BRepAlgoAPI_Common.hxx>
+#include <BRepAlgoAPI_Fuse.hxx>
+#include <BRepAlgoAPI_Cut.hxx>
+#include <BRepAlgoAPI_Section.hxx>
 
 //
 static BOPAlgo_PaveFiller* pPF=NULL;
@@ -307,14 +311,18 @@ Standard_Integer  bsection(Draw_Interpretor& di,
     return 1;
   }
 
-  BOPAlgo_SectionAttribute aSec(Standard_True, Standard_True, Standard_True);
+  Standard_Boolean bApp, bPC1, bPC2;
+  //
+  bApp = Standard_True;
+  bPC1 = Standard_True;
+  bPC2 = Standard_True;
+  
   Standard_Boolean isbadparameter = Standard_False;
   
   if(n > 4) {
     const char* key1 = a[4];
     const char* key2 = (n > 5) ? a[5] : NULL;
     const char* pcurveconf = NULL;
-    Standard_Boolean approx = Standard_True;
 
 #ifdef WNT
     if (key1 && (!strcasecmp(key1,"-n2d") || !strcasecmp(key1,"-n2d1") || !strcasecmp(key1,"-n2d2"))) {
@@ -329,7 +337,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
 #else 
       if(!strncasecmp(key1,"-na", 3)) {
 #endif
-        approx = Standard_False;
+        bApp = Standard_False;
       }
       else {
         isbadparameter = Standard_True;
@@ -341,7 +349,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
 #else 
       if (!strncasecmp(key2,"-na", 3)) {
 #endif
-        approx = Standard_False;
+        bApp = Standard_False;
       }
       else {
         isbadparameter = Standard_True;
@@ -354,7 +362,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
 #else 
       if (!strncasecmp(pcurveconf, "-n2d1", 5)) {
 #endif
-        aSec.PCurveOnS1(Standard_False);
+        bPC1 = Standard_False;
       }
       else {
 #ifdef WNT
@@ -362,7 +370,7 @@ Standard_Integer  bsection(Draw_Interpretor& di,
 #else 
         if (!strncasecmp(pcurveconf, "-n2d2", 5)) {
 #endif
-          aSec.PCurveOnS2(Standard_False);
+          bPC2 = Standard_False;
         }
         else {
 #ifdef WNT
@@ -370,49 +378,32 @@ Standard_Integer  bsection(Draw_Interpretor& di,
 #else 
           if (!strncasecmp(pcurveconf, "-n2d", 4)) {
 #endif
-            aSec.PCurveOnS1(Standard_False);
-            aSec.PCurveOnS2(Standard_False);
+            bPC1 = Standard_False;
+            bPC2 = Standard_False;
           }
         }
       }
     }
-    aSec.Approximation(approx);
   }
       
-  if(!isbadparameter) {        
-    BOPCol_ListOfShape aLC;
-    Handle(NCollection_BaseAllocator)aAL=new NCollection_IncAllocator;
+  if(!isbadparameter) {
     Standard_Integer iErr;
     char buf[80];
     //
-    aLC.Append(aS1);
-    aLC.Append(aS2);
-    BOPAlgo_PaveFiller aPF(aAL);
-    aPF.SetArguments(aLC);
-    aPF.SetSectionAttribute(aSec);
+    BRepAlgoAPI_Section aSec(aS1, aS2, Standard_False);
+    aSec.Approximation(bApp);
+    aSec.ComputePCurveOn1(bPC1);
+    aSec.ComputePCurveOn2(bPC2);
     //
-    aPF.Perform();
-    iErr=aPF.ErrorStatus();
-    if (iErr) {
+    aSec.Build();
+    iErr=aSec.ErrorStatus();
+    if (!aSec.IsDone()) {
       Sprintf(buf, " ErrorStatus : %d\n",  iErr);
       di << buf;
       return 0;
     }
     //
-    BOPAlgo_BOP aBOP;
-    aBOP.AddArgument(aS1);
-    aBOP.AddTool(aS2);
-    aBOP.SetOperation(BOPAlgo_SECTION);
-    //
-    aBOP.PerformWithFiller(aPF);
-    iErr=aBOP.ErrorStatus();
-    if (iErr) {
-      Sprintf(buf, " ErrorStatus : %d\n",  iErr);
-      di << buf;
-      return 0;
-    }
-    //
-    const TopoDS_Shape& aR=aBOP.Shape();
+    const TopoDS_Shape& aR=aSec.Shape();
     if (aR.IsNull()) {
       di << " null shape\n";
       return 0;
@@ -440,14 +431,7 @@ Standard_Integer bsmt (Draw_Interpretor& di,
   TopoDS_Shape aS1, aS2;
   BOPCol_ListOfShape aLC;
   //
-  if (aOp==BOPAlgo_SECTION) {
-    if (n<4) {
-      di << " use bsection r s1 s2\n";
-      return 1;
-    }
-  }
-  //
-  else if (n!=4) {
+  if (n!=4) {
     di << " use bx r s1 s2\n";
     return 1;
   }
@@ -459,7 +443,6 @@ Standard_Integer bsmt (Draw_Interpretor& di,
     di << " null shapes are not allowed \n";
     return 1;
   }
-  //
   aLC.Append(aS1);
   aLC.Append(aS2);
   //
@@ -476,21 +459,28 @@ Standard_Integer bsmt (Draw_Interpretor& di,
     return 0;
   }
   //
-  BOPAlgo_BOP aBOP;
-  //
-  aBOP.AddArgument(aS1);
-  aBOP.AddTool(aS2);
-  aBOP.SetOperation(aOp);
+  BRepAlgoAPI_BooleanOperation* pBuilder=NULL;
+  // 
+  if (aOp==BOPAlgo_COMMON) {
+    pBuilder=new BRepAlgoAPI_Common(aS1, aS2, aPF);
+  }
+  else if (aOp==BOPAlgo_FUSE) {
+    pBuilder=new BRepAlgoAPI_Fuse(aS1, aS2, aPF);
+  }
+  else if (aOp==BOPAlgo_CUT) {
+    pBuilder=new BRepAlgoAPI_Cut (aS1, aS2, aPF);
+  }
+  else if (aOp==BOPAlgo_CUT21) {
+    pBuilder=new BRepAlgoAPI_Cut(aS1, aS2, aPF, Standard_False);
+  }
   //
-  aBOP.PerformWithFiller(aPF);
-  iErr=aBOP.ErrorStatus();
-  if (iErr) {
+  iErr = pBuilder->ErrorStatus();
+  if (!pBuilder->IsDone()) {
     Sprintf(buf, " ErrorStatus : %d\n",  iErr);
     di << buf;
     return 0;
   }
-  //
-  const TopoDS_Shape& aR=aBOP.Shape();
+  const TopoDS_Shape& aR=pBuilder->Shape();
   if (aR.IsNull()) {
     di << " null shape\n";
     return 0;
index 7049ad7..f351717 100755 (executable)
@@ -114,11 +114,20 @@ is
        ---Purpose: Perform the boolean operation CUT.
        ---    
     class Section;                       
-       ---Purpose: Perform the operation SECTION. 
-       --- 
+        ---Purpose: Perform the operation SECTION. 
+        --- 
     class Check;
         ---Purpose: Check shapes on validity for boolean
         --- operation.
+    DumpOper( theFilePath : CString from Standard;
+              theShape1 : Shape from TopoDS;
+              theShape2 : Shape from TopoDS;
+              theResult : Shape from TopoDS;
+              theOperation : Operation from BOPAlgo;
+              isNonValidArgs : Boolean from Standard );
+        ---Purpose: Dump arguments and result of boolean operation in the file specified by path.
+        ---Level: Public
 
 end BRepAlgoAPI;
 
diff --git a/src/BRepAlgoAPI/BRepAlgoAPI.cxx b/src/BRepAlgoAPI/BRepAlgoAPI.cxx
new file mode 100644 (file)
index 0000000..f2cc986
--- /dev/null
@@ -0,0 +1,110 @@
+// Created on: 2012-12-25
+// Created by: KULIKOVA Galina
+// Copyright (c) 2012 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.
+//
+// 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.
+//
+// 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.
+
+
+#include <BRepAlgoAPI.ixx>
+
+#include <stdio.h>
+#include <TCollection_AsciiString.hxx>
+#include <BRepTools.hxx>
+#include <OSD_File.hxx>
+
+//=======================================================================
+//function : dumpOper
+//purpose  : 
+//=======================================================================
+void BRepAlgoAPI::DumpOper(const Standard_CString theFilePath,
+                           const TopoDS_Shape& theShape1,
+                           const TopoDS_Shape& theShape2,
+                           const TopoDS_Shape& theResult,
+                           BOPAlgo_Operation theOperation,
+                           Standard_Boolean isNonValidArgs)
+{
+  TCollection_AsciiString aPath(theFilePath);
+  aPath += "/";
+  Standard_Integer aNumOper = 1;
+  Standard_Boolean isExist = Standard_True;
+  TCollection_AsciiString aFileName;
+  while(isExist)
+  {
+    aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) +".tcl";
+    OSD_File aScript(aFileName);
+    isExist = aScript.Exists();
+    if(isExist)
+      aNumOper++;
+  }
+
+  FILE* afile = fopen(aFileName.ToCString(), "w+");
+  if(!afile)
+    return;
+  if(isNonValidArgs)
+    fprintf(afile,"%s\n","# Arguments are invalid");
+
+  TCollection_AsciiString aName1;
+  TCollection_AsciiString aName2;
+  TCollection_AsciiString aNameRes;
+  if(!theShape1.IsNull())
+  {
+    aName1 = aPath +
+      "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
+    BRepTools::Write(theShape1, aName1.ToCString());
+  }
+  else
+    fprintf(afile,"%s\n","# First argument is Null ");
+   
+  if(!theShape2.IsNull())
+  {
+    aName2 =  aPath +
+      "Arg2_"+ TCollection_AsciiString(aNumOper) + ".brep";
+
+    BRepTools::Write(theShape2, aName2.ToCString());
+  }
+  else
+    fprintf(afile,"%s\n","# Second argument is Null ");
+   
+   if(!theResult.IsNull())
+  {
+    aNameRes =  aPath +
+      "Result_"+ TCollection_AsciiString(aNumOper) + ".brep";
+
+    BRepTools::Write(theResult, aNameRes.ToCString());
+  }
+  else
+    fprintf(afile,"%s\n","# Result is Null ");
+  
+  fprintf(afile, "%s %s %s\n","restore",  aName1.ToCString(), "arg1");
+  fprintf(afile, "%s %s %s\n","restore",  aName2.ToCString(), "arg2");;
+  TCollection_AsciiString aBopString;
+  switch (theOperation)
+  {
+    case BOPAlgo_COMMON : aBopString += "bcommon Res "; break;
+    case BOPAlgo_FUSE   : aBopString += "bfuse Res "; break;
+    case BOPAlgo_CUT    : 
+    case BOPAlgo_CUT21  : aBopString += "bcut Res "; break;
+    case BOPAlgo_SECTION : aBopString += "bsection Res "; break;
+    default : break;
+  };
+  aBopString += ("arg1 arg2");
+  if(theOperation == BOPAlgo_CUT21)
+    aBopString += " 1";
+
+  fprintf(afile, "%s\n",aBopString.ToCString());
+  fclose(afile);
+}
index 460c333..0033847 100755 (executable)
@@ -20,6 +20,9 @@
 
 #include <BRepAlgoAPI_BooleanOperation.ixx>
 
+#include <BRepAlgoAPI.hxx>
+#include <BRepAlgoAPI_Check.hxx>
+
 #include <BRepLib_FuseEdges.hxx>
 #include <TopExp.hxx>
 #include <TopTools_MapOfShape.hxx>
@@ -233,6 +236,13 @@ const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified(const TopoDS_
   Standard_Boolean bIsNewFiller;
   Standard_Integer iErr;
   //
+  //dump arguments and result of boolean operation in tcl script
+  char *pathdump = getenv("CSF_DEBUG_BOP");
+  Standard_Boolean isDump = (pathdump != NULL),
+                   isDumpArgs = Standard_False,
+                   isDumpRes = Standard_False;
+  Standard_CString aPath = pathdump;
+  //
   myBuilderCanWork=Standard_False;
   NotDone();
   //
@@ -256,6 +266,11 @@ const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified(const TopoDS_
   const TopoDS_Shape& aS1 = myS1;
   const TopoDS_Shape& aS2 = myS2;
   //
+  if (isDump) {
+    BRepAlgoAPI_Check aChekArgs(aS1, aS2, myOperation);
+    isDumpArgs = !aChekArgs.IsValid();
+  }
+  //
   myShape.Nullify();
 
   myBuilder=new BOPAlgo_BOP;
@@ -269,6 +284,15 @@ const TopTools_ListOfShape& BRepAlgoAPI_BooleanOperation::Modified(const TopoDS_
     myErrorStatus=0;
     myBuilderCanWork=Standard_True;
     myShape=myBuilder->Shape();
+    //
+    if (isDump) {
+      BRepAlgoAPI_Check aCheckRes(myShape);
+      isDumpRes = !aCheckRes.IsValid();
+      if (isDumpArgs || isDumpRes) {
+        BRepAlgoAPI::DumpOper(aPath, aS1, aS2, myShape, myOperation, isDumpArgs);
+      }
+    }
+    //
     Done(); 
   } 
   else {