// Created by: Peter KURNEV // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // 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. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static TopAbs_ShapeEnum TypeToExplore(const Standard_Integer theDim); //======================================================================= //function : //purpose : //======================================================================= BOPAlgo_BOP::BOPAlgo_BOP() : BOPAlgo_Builder(), myTools(myAllocator), myMapTools(100, myAllocator) { Clear(); } //======================================================================= //function : //purpose : //======================================================================= BOPAlgo_BOP::BOPAlgo_BOP (const Handle(NCollection_BaseAllocator)& theAllocator) : BOPAlgo_Builder(theAllocator), myTools(myAllocator), myMapTools(100, myAllocator) { Clear(); } //======================================================================= //function : ~ //purpose : //======================================================================= BOPAlgo_BOP::~BOPAlgo_BOP() { } //======================================================================= //function : Clear //purpose : //======================================================================= void BOPAlgo_BOP::Clear() { myOperation=BOPAlgo_UNKNOWN; myTools.Clear(); myMapTools.Clear(); myDims[0]=-1; myDims[1]=-1; // BOPAlgo_Builder::Clear(); } //======================================================================= //function : SetOperation //purpose : //======================================================================= void BOPAlgo_BOP::SetOperation(const BOPAlgo_Operation theOperation) { myOperation=theOperation; } //======================================================================= //function : Operation //purpose : //======================================================================= BOPAlgo_Operation BOPAlgo_BOP::Operation()const { return myOperation; } //======================================================================= //function : AddTool //purpose : //======================================================================= void BOPAlgo_BOP::AddTool(const TopoDS_Shape& theShape) { if (myMapTools.Add(theShape)) { myTools.Append(theShape); } } //======================================================================= //function : CheckData //purpose : //======================================================================= void BOPAlgo_BOP::CheckData() { Standard_Integer i, j, iDim, aNbArgs, aNbTools; Standard_Boolean bFlag; BOPCol_ListIteratorOfListOfShape aItLS; // myErrorStatus=0; // aNbArgs=myArguments.Extent(); if (!aNbArgs) { myErrorStatus=100; // invalid number of Arguments return; } // aNbTools=myTools.Extent(); if (!aNbTools) { myErrorStatus=100; // invalid number of Tools return; } // if (!myPaveFiller) { myErrorStatus=101; return; } // myErrorStatus=myPaveFiller->ErrorStatus(); if (myErrorStatus) { return; } // for (i=0; i<2; ++i) { const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; aItLS.Initialize(aLS); for (j=0; aItLS.More(); aItLS.Next(), ++j) { const TopoDS_Shape& aS=aItLS.Value(); bFlag=BOPTools_AlgoTools3D::IsEmptyShape(aS); if(bFlag) { myWarningStatus=2; } // iDim=BOPTools_AlgoTools::Dimension(aS); if (iDim<0) { myErrorStatus=13; // non-homogenious argument return; } // if (!j) { myDims[i]=iDim; continue; } // if (iDim!=myDims[i]) { myErrorStatus=13; // non-homogenious argument return; } } } // if (myOperation==BOPAlgo_UNKNOWN) { myErrorStatus=14; // non-licit operation return; } else if (myDims[0]myDims[1]) { if (myOperation==BOPAlgo_FUSE || myOperation==BOPAlgo_CUT) { myErrorStatus=14; // non-licit operation for the arguments return; } } } //======================================================================= //function : Prepare //purpose : //======================================================================= void BOPAlgo_BOP::Prepare() { // BOPAlgo_Builder::Prepare(); // if(myWarningStatus == 2) { Standard_Integer i; BRep_Builder aBB; BOPCol_ListIteratorOfListOfShape aItLS; // switch(myOperation) { case BOPAlgo_FUSE: { for (i=0; i<2; ++i) { const BOPCol_ListOfShape& aLS=(!i)? myArguments : myTools; aItLS.Initialize(aLS); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aS=aItLS.Value(); aBB.Add(myShape, aS); } } } break; // case BOPAlgo_CUT: { aItLS.Initialize(myArguments); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aS=aItLS.Value(); if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { aBB.Add(myShape, aS); } } } break; case BOPAlgo_CUT21: { aItLS.Initialize(myTools); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aS=aItLS.Value(); if(!BOPTools_AlgoTools3D::IsEmptyShape(aS)) { aBB.Add(myShape, aS); } } } break; // case BOPAlgo_COMMON: case BOPAlgo_SECTION: default: break; } } } //======================================================================= //function : BuildResult //purpose : //======================================================================= void BOPAlgo_BOP::BuildResult(const TopAbs_ShapeEnum theType) { TopAbs_ShapeEnum aType; BRep_Builder aBB; BOPCol_MapOfShape aM; BOPCol_ListIteratorOfListOfShape aIt, aItIm; // myErrorStatus=0; // const BOPCol_ListOfShape& aLA=myDS->Arguments(); aIt.Initialize(aLA); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aS=aIt.Value(); aType=aS.ShapeType(); if (aType==theType) { if (myImages.IsBound(aS)){ const BOPCol_ListOfShape& aLSIm=myImages.Find(aS); aItIm.Initialize(aLSIm); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aSIm=aItIm.Value(); if (aM.Add(aSIm)) { aBB.Add(myShape, aSIm); } } } else { if (aM.Add(aS)) { aBB.Add(myShape, aS); } } } } } //======================================================================= //function : Perform //purpose : //======================================================================= void BOPAlgo_BOP::Perform() { Handle(NCollection_BaseAllocator) aAllocator; BOPAlgo_PaveFiller* pPF; BOPCol_ListIteratorOfListOfShape aItLS; // myErrorStatus=0; // if (myEntryPoint==1) { if (myPaveFiller) { delete myPaveFiller; myPaveFiller=NULL; } } // aAllocator=new NCollection_IncAllocator; BOPCol_ListOfShape aLS(aAllocator); // aItLS.Initialize(myArguments); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aS=aItLS.Value(); aLS.Append(aS); } // aItLS.Initialize(myTools); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aS=aItLS.Value(); aLS.Append(aS); } // pPF=new BOPAlgo_PaveFiller(aAllocator); pPF->SetArguments(aLS); // pPF->Perform(); // myEntryPoint=1; PerformInternal(*pPF); } //======================================================================= //function : PerformInternal //purpose : //======================================================================= void BOPAlgo_BOP::PerformInternal(const BOPAlgo_PaveFiller& theFiller) { myErrorStatus=0; myWarningStatus=0; // myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller; myDS=myPaveFiller->PDS(); myContext=myPaveFiller->Context(); // // 1. CheckData CheckData(); if (myErrorStatus && !myWarningStatus) { return; } // // 2. Prepare Prepare(); if (myErrorStatus) { return; } // if(myWarningStatus == 2) { return; } // 3. Fill Images // 3.1 Vertices FillImagesVertices(); if (myErrorStatus) { return; } // BuildResult(TopAbs_VERTEX); if (myErrorStatus) { return; } // 3.2 Edges FillImagesEdges(); if (myErrorStatus) { return; } BuildResult(TopAbs_EDGE); if (myErrorStatus) { return; } //-------------------------------- SECTION if (myOperation==BOPAlgo_SECTION) { BuildSection(); PrepareHistory(); PostTreat(); return; } //-------------------------------- // // 3.3 Wires FillImagesContainers(TopAbs_WIRE); if (myErrorStatus) { return; } BuildResult(TopAbs_WIRE); if (myErrorStatus) { return; } // 3.4 Faces FillImagesFaces(); if (myErrorStatus) { return; } BuildResult(TopAbs_FACE); if (myErrorStatus) { return; } // 3.5 Shells FillImagesContainers(TopAbs_SHELL); if (myErrorStatus) { return; } BuildResult(TopAbs_SHELL); if (myErrorStatus) { return; } // 3.6 Solids FillImagesSolids(); if (myErrorStatus) { return; } BuildResult(TopAbs_SOLID); if (myErrorStatus) { return; } // 3.7 CompSolids FillImagesContainers(TopAbs_COMPSOLID); if (myErrorStatus) { return; } BuildResult(TopAbs_COMPSOLID); if (myErrorStatus) { return; } // 3.8 Compounds FillImagesCompounds(); if (myErrorStatus) { return; } BuildResult(TopAbs_COMPOUND); if (myErrorStatus) { return; } // // 4.BuildShape; BuildShape(); if (myErrorStatus) { return; } // // 5.History PrepareHistory(); // // 6 Post-treatment PostTreat(); } //======================================================================= //function : BuildRC //purpose : //======================================================================= void BOPAlgo_BOP::BuildRC() { Standard_Boolean bFlag1, bFlag2, bIsBound; Standard_Integer aDmin; TopAbs_ShapeEnum aTmin; TopoDS_Compound aC; TopoDS_Shape aSAIm, aSTIm; BRep_Builder aBB; TopExp_Explorer aExp; BOPCol_DataMapOfShapeShape aDMSSA; BOPCol_ListIteratorOfListOfShape aItLS, aItIm; // myErrorStatus=0; // aBB.MakeCompound(aC); // // A. Fuse if (myOperation==BOPAlgo_FUSE) { aTmin=TypeToExplore(myDims[0]); aExp.Init(myShape, aTmin); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape& aS=aExp.Current(); aBB.Add(aC, aS); } myRC=aC; return; } // aDmin=myDims[1]; if (myDims[0] < myDims[1]) { aDmin=myDims[0]; } aTmin=TypeToExplore(aDmin); // // B. Common, Cut, Cut21 // bFlag1=(myOperation==BOPAlgo_COMMON || myOperation==BOPAlgo_CUT21); bFlag2=(myOperation==BOPAlgo_CUT || myOperation==BOPAlgo_CUT21); // const BOPCol_ListOfShape& aLA=( bFlag1) ? myArguments : myTools; aItLS.Initialize(aLA); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aSA=aItLS.Value(); // if (myImages.IsBound(aSA)){ const BOPCol_ListOfShape& aLSAIm=myImages.Find(aSA); aItIm.Initialize(aLSAIm); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aSAIm=aItIm.Value(); aExp.Init(aSAIm, aTmin); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape aSIm=aExp.Current(); aDMSSA.Bind(aSIm, aSIm); } } } // else { aExp.Init(aSA, aTmin); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape aSIm=aExp.Current(); aDMSSA.Bind(aSIm, aSIm); } } } //for (; aItLS.More(); aItLS.Next()) // const BOPCol_ListOfShape& aLT=(!bFlag1) ? myArguments : myTools; aItLS.Initialize(aLT); for (; aItLS.More(); aItLS.Next()) { const TopoDS_Shape& aST=aItLS.Value(); if (myImages.IsBound(aST)){ const BOPCol_ListOfShape& aLSTIm=myImages.Find(aST); aItIm.Initialize(aLSTIm); for (; aItIm.More(); aItIm.Next()) { const TopoDS_Shape& aSTIm=aItIm.Value(); aExp.Init(aSTIm, aTmin); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape aSIm=aExp.Current(); // skip degenerated edges if (aTmin==TopAbs_EDGE) { const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); if (BRep_Tool::Degenerated(aEIm)) { continue; } } // bIsBound=aDMSSA.IsBound(aSIm); if (!bFlag2) { // ie common if (bIsBound) { const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); aBB.Add(aC, aSImA); } } else {// ie cut or cut21 if (!bIsBound) { aBB.Add(aC, aSIm); } } } } } else { aExp.Init(aST, aTmin); for (; aExp.More(); aExp.Next()) { const TopoDS_Shape aSIm=aExp.Current(); // skip degenerated edges if (aTmin==TopAbs_EDGE) { const TopoDS_Edge& aEIm=*((TopoDS_Edge*)&aSIm); if (BRep_Tool::Degenerated(aEIm)) { continue; } } bIsBound=aDMSSA.IsBound(aSIm); if (!bFlag2) { // ie common if (bIsBound) { const TopoDS_Shape& aSImA=aDMSSA.Find(aSIm); aBB.Add(aC, aSImA); } } else {// ie cut or cut21 if (!bIsBound) { aBB.Add(aC, aSIm); } } } } } //for (; aItLS.More(); aItLS.Next()) // // the squats around degeneracy if (aTmin!=TopAbs_EDGE) { myRC=aC; return; } //--------------------------------------------------------- // // The squats around degenerated edges Standard_Integer i, aNbS, nVD; TopAbs_ShapeEnum aType; BOPCol_IndexedMapOfShape aMVC; // // 1. Vertices of aC BOPTools::MapShapes(aC, TopAbs_VERTEX, aMVC); // // 2. DE candidates aNbS=myDS->NbSourceShapes(); for (i=0; iShapeInfo(i); aType=aSI.ShapeType(); if (aType!=aTmin) { continue; } // const TopoDS_Edge& aE=*((TopoDS_Edge*)&aSI.Shape()); if (!BRep_Tool::Degenerated(aE)) { continue; } // nVD=aSI.SubShapes().First(); const TopoDS_Shape& aVD=myDS->Shape(nVD); // if (!aMVC.Contains(aVD)) { continue; } // if (myDS->IsNewShape(nVD)) { continue; } // if (myDS->HasInterf(nVD)) { continue; } // aBB.Add(aC, aE); } // myRC=aC; } //======================================================================= //function : BuildShape //purpose : //======================================================================= void BOPAlgo_BOP::BuildShape() { Standard_Integer aDmin, aNbLCB; TopAbs_ShapeEnum aT1, aT2, aTR; TopoDS_Shape aR, aRC; TopoDS_Iterator aIt; BRep_Builder aBB; BOPCol_ListOfShape aLCB; BOPCol_ListIteratorOfListOfShape aItLCB; // myErrorStatus=0; // BuildRC(); // aDmin=myDims[1]; if (myDims[0]