From da21902312e0d4def2d9d729b1b0e5dfc98c290b Mon Sep 17 00:00:00 2001 From: emv Date: Wed, 27 Feb 2013 13:04:39 +0400 Subject: [PATCH] 0023648: Add tool for checking shapes on validity for boolean operations. 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 | 98 +++++++--------- src/BRepAlgoAPI/BRepAlgoAPI.cdl | 13 ++- src/BRepAlgoAPI/BRepAlgoAPI.cxx | 110 ++++++++++++++++++ .../BRepAlgoAPI_BooleanOperation.cxx | 24 ++++ 4 files changed, 189 insertions(+), 56 deletions(-) create mode 100644 src/BRepAlgoAPI/BRepAlgoAPI.cxx diff --git a/src/BOPTest/BOPTest_BOPCommands.cxx b/src/BOPTest/BOPTest_BOPCommands.cxx index f3695f5f95..8331f758d9 100755 --- a/src/BOPTest/BOPTest_BOPCommands.cxx +++ b/src/BOPTest/BOPTest_BOPCommands.cxx @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,11 @@ #include #include #include +#include +#include +#include +#include +#include // 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; diff --git a/src/BRepAlgoAPI/BRepAlgoAPI.cdl b/src/BRepAlgoAPI/BRepAlgoAPI.cdl index 7049ad77f3..f351717f24 100755 --- a/src/BRepAlgoAPI/BRepAlgoAPI.cdl +++ b/src/BRepAlgoAPI/BRepAlgoAPI.cdl @@ -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 index 0000000000..f2cc98647c --- /dev/null +++ b/src/BRepAlgoAPI/BRepAlgoAPI.cxx @@ -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 + +#include +#include +#include +#include + +//======================================================================= +//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); +} diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx b/src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx index 460c333015..003384761b 100755 --- a/src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx +++ b/src/BRepAlgoAPI/BRepAlgoAPI_BooleanOperation.cxx @@ -20,6 +20,9 @@ #include +#include +#include + #include #include #include @@ -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 { -- 2.20.1