// Created on: 2004-09-02 // Copyright (c) 2004-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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ================================================================================ // function: Constructor // purpose: // ================================================================================ BOPAlgo_ArgumentAnalyzer::BOPAlgo_ArgumentAnalyzer() : myStopOnFirst(Standard_False), myOperation(BOPAlgo_UNKNOWN), myArgumentTypeMode(Standard_False), mySelfInterMode(Standard_False), mySmallEdgeMode(Standard_False), myRebuildFaceMode(Standard_False), myTangentMode(Standard_False), myMergeVertexMode(Standard_False), myMergeEdgeMode(Standard_False), myEmpty1(Standard_False), myEmpty2(Standard_False) // myMergeFaceMode(Standard_False) { } // ================================================================================ // function: SetShape1 // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::SetShape1(const TopoDS_Shape & TheShape) { myShape1 = TheShape; } // ================================================================================ // function: SetShape2 // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::SetShape2(const TopoDS_Shape & TheShape) { myShape2 = TheShape; } // ================================================================================ // function: GetShape1 // purpose: // ================================================================================ const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape1() const { return myShape1; } // ================================================================================ // function: GetShape2 // purpose: // ================================================================================ const TopoDS_Shape & BOPAlgo_ArgumentAnalyzer::GetShape2() const { return myShape2; } // ================================================================================ // function: OperationType // purpose: // ================================================================================ BOPAlgo_Operation& BOPAlgo_ArgumentAnalyzer::OperationType() { return myOperation; } // ================================================================================ // function: StopOnFirstFaulty // purpose: // ================================================================================ Standard_Boolean & BOPAlgo_ArgumentAnalyzer::StopOnFirstFaulty() { return myStopOnFirst; } // ================================================================================ // function: Prepare // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::Prepare() { Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull(); if (!isS1) { myEmpty1 = BOPTools_AlgoTools3D::IsEmptyShape(myShape1); } if (!isS2) { myEmpty2 = BOPTools_AlgoTools3D::IsEmptyShape(myShape2); } } // ================================================================================ // function: Perform // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::Perform() { try { OCC_CATCH_SIGNALS myResult.Clear(); Prepare(); if(myArgumentTypeMode) { TestTypes(); } if(mySelfInterMode) { TestSelfInterferences(); } if(mySmallEdgeMode) { if(!(!myResult.IsEmpty() && myStopOnFirst)) TestSmallEdge(); } if(myRebuildFaceMode) { if(!(!myResult.IsEmpty() && myStopOnFirst)) TestRebuildFace(); } if(myTangentMode) { if(!(!myResult.IsEmpty() && myStopOnFirst)) TestTangent(); } if(myMergeVertexMode) { if(!(!myResult.IsEmpty() && myStopOnFirst)) TestMergeVertex(); } if(myMergeEdgeMode) { if(!(!myResult.IsEmpty() && myStopOnFirst)) TestMergeEdge(); } } catch(Standard_Failure) { BOPAlgo_CheckResult aResult; aResult.SetCheckStatus(BOPAlgo_CheckUnknown); myResult.Append(aResult); } } // ================================================================================ // function: HasFaulty // purpose: // ================================================================================ Standard_Boolean BOPAlgo_ArgumentAnalyzer::HasFaulty() const { return ( !myResult.IsEmpty()); } // ================================================================================ // function: GetCheckResult // purpose: // ================================================================================ const BOPAlgo_ListOfCheckResult& BOPAlgo_ArgumentAnalyzer::GetCheckResult() const { return myResult; } // ================================================================================ // function: TestTypes // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::TestTypes() { Standard_Boolean isS1 = myShape1.IsNull(), isS2 = myShape2.IsNull(); if(isS1 && isS2) { BOPAlgo_CheckResult aResult; aResult.SetCheckStatus(BOPAlgo_BadType); myResult.Append(aResult); return; } //single shape check if((isS1 && !isS2) || (!isS1 && isS2)) { Standard_Boolean bIsEmpty = (isS1) ? myEmpty2 : myEmpty1; if(bIsEmpty || myOperation!=BOPAlgo_UNKNOWN) { const TopoDS_Shape & aS = (isS1) ? myShape2 : myShape1; BOPAlgo_CheckResult aResult; aResult.SetShape1(aS); aResult.SetCheckStatus(BOPAlgo_BadType); myResult.Append(aResult); return; } } // two shapes check (begin) else { if(myEmpty1 || myEmpty2) { BOPAlgo_CheckResult aResult; if(myEmpty1 && myEmpty2) { aResult.SetShape1(myShape1); aResult.SetShape2(myShape2); } else { const TopoDS_Shape & aS = myEmpty1 ? myShape1 : myShape2; if(myEmpty1) aResult.SetShape1(aS); else aResult.SetShape2(aS); } aResult.SetCheckStatus(BOPAlgo_BadType); myResult.Append(aResult); return; } // Standard_Integer aDim1, aDim2; Standard_Boolean bBadTypes = Standard_False; // aDim1 = BOPTools_AlgoTools::Dimension(myShape1); aDim2 = BOPTools_AlgoTools::Dimension(myShape2); if (aDim1 < aDim2) { if (myOperation == BOPAlgo_FUSE || myOperation == BOPAlgo_CUT21) { bBadTypes = Standard_True; } } else if (aDim1 > aDim2) { if (myOperation == BOPAlgo_FUSE || myOperation == BOPAlgo_CUT) { bBadTypes = Standard_True; } } if (bBadTypes) { BOPAlgo_CheckResult aResult; aResult.SetShape1(myShape1); aResult.SetShape2(myShape2); aResult.SetCheckStatus(BOPAlgo_BadType); myResult.Append(aResult); } } } // ================================================================================ // function: TestSelfInterferences // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences() { Standard_Integer ii = 0, j; Standard_Boolean bSelfInt; for(ii = 0; ii < 2; ii++) { TopoDS_Shape aS = (ii == 0) ? myShape1 : myShape2; if(aS.IsNull()) continue; Standard_Boolean bIsEmpty = (ii == 0) ? myEmpty1 : myEmpty2; if (bIsEmpty) { continue; } BOPAlgo_CheckerSI aChecker; BOPCol_ListOfShape anArgs; anArgs.Append(aS); aChecker.SetArguments(anArgs); // 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; } // if (aTypeInt == 4) { BOPDS_InterfEF& aEF=aEFs(i); if (aEF.CommonPart().Type()==TopAbs_SHAPE) { 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 1) { BOPAlgo_CheckResult aResult; aResult.SetShape1(myShape1); aResult.SetShape2(myShape2); aResult.AddFaultyShape1(aS1); BOPCol_ListIteratorOfListOfShape anIt(aListOfS2); for(; anIt.More(); anIt.Next()) { aResult.AddFaultyShape2(anIt.Value()); } aResult.SetCheckStatus(aStatus); myResult.Append(aResult); if(myStopOnFirst) { return; } } } for(i = 1; i <= aSeq2.Length(); i++) { 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); if(anArrayOfFlag.Value(j, i)) { aListOfS1.Append(aS1); nbs++; } } if(nbs > 1) { BOPAlgo_CheckResult aResult; aResult.SetShape1(myShape1); aResult.SetShape2(myShape2); BOPCol_ListIteratorOfListOfShape anIt(aListOfS1); for(; anIt.More(); anIt.Next()) { aResult.AddFaultyShape1(anIt.Value()); } aResult.AddFaultyShape2(aS2); aResult.SetCheckStatus(aStatus); myResult.Append(aResult); if(myStopOnFirst) { return; } } } } // ================================================================================ // function: TestMergeVertex // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::TestMergeVertex() { TestMergeSubShapes(TopAbs_VERTEX); } // ================================================================================ // function: TestMergeEdge // purpose: // ================================================================================ void BOPAlgo_ArgumentAnalyzer::TestMergeEdge() { TestMergeSubShapes(TopAbs_EDGE); } // ================================================================================ // function: TestMergeFace // purpose: // ================================================================================ // void BOPAlgo_ArgumentAnalyzer::TestMergeFace() // { // not implemented // }