From: gka Date: Thu, 30 Oct 2014 16:03:55 +0000 (+0300) Subject: Fix for regressions for case infinite box ( case 46) X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=fe7caef6da5b2cf00bd0296f5f156b5e726c03ff;p=occt-copy.git Fix for regressions for case infinite box ( case 46) Test cases --- diff --git a/src/BOPAlgo/BOPAlgo.cdl b/src/BOPAlgo/BOPAlgo.cdl index f4097cd6fc..8cd289d2d2 100644 --- a/src/BOPAlgo/BOPAlgo.cdl +++ b/src/BOPAlgo/BOPAlgo.cdl @@ -74,6 +74,7 @@ is class CheckerSI; class ArgumentAnalyzer; class CheckResult; + class ShellSplitter; -- -- pointers -- diff --git a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx index f2d3b3e9a0..784f39db95 100644 --- a/src/BOPAlgo/BOPAlgo_BuilderFace.cxx +++ b/src/BOPAlgo/BOPAlgo_BuilderFace.cxx @@ -57,6 +57,8 @@ #include #include #include +#include +#include static @@ -444,6 +446,7 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const } // // 2. Find outer growth shell that is most close to each hole shell + BOPCol_ListOfShape anUnUsedHoles; aIt2.Initialize(aHoleWires); for (; aIt2.More(); aIt2.Next()) { const TopoDS_Shape& aHole = aIt2.Value(); @@ -481,8 +484,26 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const aMSH.Bind(aF, aLH); } } + else { + anUnUsedHoles.Append(aHole); + } }// for (; aIt2.More(); aIt2.Next()) // + if (anUnUsedHoles.Extent()) { + // add the infinite face to new faces + Bnd_Box aBox; + BRepBndLib::Add(myFace, aBox); + if (aBox.IsOpenXmin() || aBox.IsOpenXmax() || + aBox.IsOpenYmin() || aBox.IsOpenYmax() || + aBox.IsOpenZmin() || aBox.IsOpenZmax()) { + TopoDS_Face aFace; + aBB.MakeFace(aFace, aS, aLoc, aTol); + // + aNewFaces.Append(aFace); + aMSH.Bind(aFace, anUnUsedHoles); + } + } + // // 3. Add aHoles to Faces aItMSH.Initialize(aMSH); for (; aItMSH.More(); aItMSH.Next()) { diff --git a/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx b/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx index 1f44fd4849..ff11819486 100644 --- a/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx +++ b/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx @@ -6,29 +6,35 @@ // // 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 version 2.1 as published +// 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 @@ -40,25 +46,32 @@ #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 static Standard_Boolean IsGrowthShell(const TopoDS_Shape& , @@ -74,14 +87,63 @@ static void MakeInternalShells(const BOPCol_MapOfShape& , BOPCol_ListOfShape& ); -static - Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell); - +//======================================================================= +//class : BOPAlgo_BuilderSolid_ShapeBox +//purpose : Auxiliary class +//======================================================================= +class BOPAlgo_BuilderSolid_ShapeBox { + public: + BOPAlgo_BuilderSolid_ShapeBox() { + myIsHole=Standard_False; + }; + // + ~BOPAlgo_BuilderSolid_ShapeBox() { + }; + // + void SetShape(const TopoDS_Shape& aS) { + myShape=aS; + }; + // + const TopoDS_Shape& Shape()const { + return myShape; + }; + // + void SetBox(const Bnd_Box& aBox) { + myBox=aBox; + }; + // + const Bnd_Box& Box()const { + return myBox; + }; + // + void SetIsHole(const Standard_Boolean bFlag) { + myIsHole=bFlag; + }; + // + Standard_Boolean IsHole()const { + return myIsHole; + }; + // + protected: + Standard_Boolean myIsHole; + TopoDS_Shape myShape; + Bnd_Box myBox; +}; +// +typedef NCollection_DataMap + BOPAlgo_DataMapOfIntegerBSSB; +// +typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator + BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB; +// +// //======================================================================= //function : //purpose : //======================================================================= - BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid() +BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid() : BOPAlgo_BuilderArea() { @@ -90,7 +152,8 @@ static //function : //purpose : //======================================================================= - BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator) +BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid + (const Handle(NCollection_BaseAllocator)& theAllocator) : BOPAlgo_BuilderArea(theAllocator) { @@ -99,20 +162,18 @@ static //function : ~ //purpose : //======================================================================= - BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid() +BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid() { } //======================================================================= //function : Perform //purpose : //======================================================================= - void BOPAlgo_BuilderSolid::Perform() +void BOPAlgo_BuilderSolid::Perform() { myErrorStatus=0; // if (myContext.IsNull()) { - //myErrorStatus=11;// Null Context - //return; myContext=new BOPInt_Context; } // @@ -127,7 +188,6 @@ static aBB.Add(aC, aF); } // - // PerformShapesToAvoid(); if (myErrorStatus) { return; @@ -137,10 +197,12 @@ static if (myErrorStatus) { return; } + // PerformAreas(); if (myErrorStatus) { return; } + // PerformInternalShapes(); if (myErrorStatus) { return; @@ -150,7 +212,7 @@ static //function :PerformShapesToAvoid //purpose : //======================================================================= - void BOPAlgo_BuilderSolid::PerformShapesToAvoid() +void BOPAlgo_BuilderSolid::PerformShapesToAvoid() { Standard_Boolean bFound; Standard_Integer i, iCnt, aNbE, aNbF; @@ -171,7 +233,10 @@ static for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (!myShapesToAvoid.Contains(aF)) { - BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); + BOPTools::MapShapesAndAncestors(aF, + TopAbs_EDGE, + TopAbs_FACE, + aMEF); } } aNbE=aMEF.Extent(); @@ -221,153 +286,53 @@ static break; } // - }//while (1) + }//for(;;) { } //======================================================================= //function : PerformLoops //purpose : //======================================================================= - void BOPAlgo_BuilderSolid::PerformLoops() +void BOPAlgo_BuilderSolid::PerformLoops() { - myErrorStatus=0; - // - myLoops.Clear(); - // - Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA; - Standard_Integer i; - TopAbs_Orientation anOr; - TopoDS_Edge aEL; - BRep_Builder aBB; + Standard_Integer iErr; + BOPCol_ListIteratorOfListOfShape aIt; TopoDS_Iterator aItS; - // - BOPCol_ListIteratorOfListOfShape aItF, aIt; BOPCol_MapIteratorOfMapOfOrientedShape aItM; - BOPTools_CoupleOfShape aCSOff; - // - BOPCol_MapOfOrientedShape AddedFacesMap; - BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP; - // - //================================================= + BOPAlgo_ShellSplitter aSSp; + // + myErrorStatus=0; + myLoops.Clear(); // // 1. Shells Usual + aIt.Initialize (myShapes); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aF=aIt.Value(); + if (!myShapesToAvoid.Contains(aF)) { + aSSp.AddStartElement(aF); + } + } // - aItF.Initialize (myShapes); - for (; aItF.More(); aItF.Next()) { - const TopoDS_Shape& aFF = aItF.Value(); - BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); + aSSp.Perform(); + iErr=aSSp.ErrorStatus(); + if (iErr) { + return; } // - aItF.Initialize (myShapes); - for (i=1; aItF.More(); aItF.Next(), ++i) { - const TopoDS_Shape& aFF = aItF.Value(); - if (myShapesToAvoid.Contains(aFF)) { - continue; - } - if (!AddedFacesMap.Add(aFF)) { - continue; - } - // - // make a new shell - TopoDS_Shell aShell; - aBB.MakeShell(aShell); - aBB.Add(aShell, aFF); - // - aMEFP.Clear(); - BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP); - // - // loop on faces added to Shell; add their neighbor faces to Shell and so on - TopoDS_Iterator aItAddedF (aShell); - for (; aItAddedF.More(); aItAddedF.Next()) { - const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value())); - // - // loop on edges of aF; find a good neighbor face of aF by aE - TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); - for (; aEdgeExp.More(); aEdgeExp.Next()) { - const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current())); - // - //1 - if (aMEFP.Contains(aE)) { - const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE); - aNbFP=aLFP.Extent(); - if (aNbFP>1) { - continue; - } - } - //2 - anOr=aE.Orientation(); - if (anOr==TopAbs_INTERNAL) { - continue; - } - //3 - if (BRep_Tool::Degenerated(aE)) { - continue; - } - // - // candidate faces list - const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); - aNbLF=aLF.Extent(); - if (!aNbLF) { - continue; - } - // - // try to select one of neighbors - // check if a face already added to Shell shares E - Standard_Boolean bFound; - BOPCol_ListIteratorOfListOfShape aItLF; - BOPTools_ListOfCoupleOfShape aLCSOff; - // - aItLF.Initialize(aLF); - for (; aItLF.More(); aItLF.Next()) { - const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value())); - if (myShapesToAvoid.Contains(aFL)) { - continue; - } - if (aF.IsSame(aFL)) { - continue; - } - if (AddedFacesMap.Contains(aFL)){ - continue; - } - // - bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL); - if (!bFound) { - continue; - } - // - aCSOff.SetShape1(aEL); - aCSOff.SetShape2(aFL); - aLCSOff.Append(aCSOff); - }//for (; aItLF.More(); aItLF.Next()) { - // - aNbOff=aLCSOff.Extent(); - if (!aNbOff){ - continue; - } - // - TopoDS_Face aSelF; - if (aNbOff==1) { - aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2())); - } - else if (aNbOff>1){ - BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext); - } - // - if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { - aBB.Add(aShell, aSelF); - BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP); - } - } // for (; aEdgeExp.More(); aEdgeExp.Next()) { - } //for (; aItAddedF.More(); aItAddedF.Next()) { - // - if (IsClosedShell(aShell)) { - myLoops.Append(aShell); - } - } // for (; aItF.More(); aItF.Next()) { - + const BOPCol_ListOfShape& aLSh=aSSp.Shells(); + aIt.Initialize (aLSh); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSh=aIt.Value(); + myLoops.Append(aSh); + } + //================================================= // - // Post Treatment + // 2. Post Treatment + Standard_Integer aNbFA; + BRep_Builder aBB; + BOPCol_MapOfOrientedShape AddedFacesMap; + BOPCol_IndexedDataMapOfShapeListOfShape aEFMap; BOPCol_MapOfOrientedShape aMP; - // + // // a. collect all edges that are in loops aIt.Initialize (myLoops); for (; aIt.More(); aIt.Next()) { @@ -396,8 +361,7 @@ static } //================================================= // - // 2.Internal Shells - // + // 3.Internal Shells myLoopsInternal.Clear(); // aEFMap.Clear(); @@ -408,7 +372,9 @@ static aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aFF=aItM.Key(); - BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); + BOPTools::MapShapesAndAncestors(aFF, + TopAbs_EDGE, TopAbs_FACE, + aEFMap); } // aItM.Initialize(myShapesToAvoid); @@ -431,15 +397,16 @@ static for (; aEdgeExp.More(); aEdgeExp.Next()) { const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current())); const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); - aItF.Initialize(aLF); - for (; aItF.More(); aItF.Next()) { - const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value())); + aIt.Initialize(aLF); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value())); if (AddedFacesMap.Add(aFL)){ aBB.Add(aShell, aFL); } } } } + aShell.Closed (BRep_Tool::IsClosed (aShell)); myLoopsInternal.Append(aShell); } } @@ -447,131 +414,185 @@ static //function : PerformAreas //purpose : //======================================================================= - void BOPAlgo_BuilderSolid::PerformAreas() +void BOPAlgo_BuilderSolid::PerformAreas() { - myErrorStatus=0; - // - Standard_Boolean bIsGrowthShell, bIsHole; + Standard_Boolean bIsGrowth, bIsHole; + Standard_Integer k,aNbHoles; BRep_Builder aBB; - TopoDS_Shape anInfinitePointShape; - BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH; - BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt; - // + BOPCol_ListIteratorOfListOfShape aItLS; BOPCol_ListOfShape aNewSolids, aHoleShells; BOPCol_DataMapOfShapeShape aInOutMap; - BOPCol_DataMapOfShapeListOfShape aMSH; BOPCol_IndexedMapOfShape aMHF; + BOPCol_ListIteratorOfListOfInteger aItLI; + BOPDS_BoxBndTreeSelector aSelector; + BOPDS_BoxBndTree aBBTree; + NCollection_UBTreeFiller + aTreeFiller(aBBTree); + BOPAlgo_DataMapOfIntegerBSSB aDMISB(100); + BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB; + BOPCol_DataMapOfShapeListOfShape aMSH; + BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS; + BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH; + // + myErrorStatus=0; // myAreas.Clear(); // // Draft solids [aNewSolids] - aShellIt.Initialize(myLoops); - for ( ; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aShell = aShellIt.Value(); + aItLS.Initialize(myLoops); + for (k=0; aItLS.More(); aItLS.Next(), ++k) { + TopoDS_Solid aSolid; + Bnd_Box aBox; + BOPAlgo_BuilderSolid_ShapeBox aSB; + // + const TopoDS_Shape& aShell = aItLS.Value(); + aSB.SetShape(aShell); // - bIsGrowthShell=IsGrowthShell(aShell, aMHF); - if (bIsGrowthShell) { + BRepBndLib::Add(aShell, aBox); + bIsHole=Standard_False; + // + bIsGrowth=IsGrowthShell(aShell, aMHF); + if (bIsGrowth) { // make a growth solid from a shell - TopoDS_Solid Solid; - aBB.MakeSolid(Solid); - aBB.Add (Solid, aShell); + aBB.MakeSolid(aSolid); + aBB.Add (aSolid, aShell); // - aNewSolids.Append (Solid); + aNewSolids.Append (aSolid); + aSB.SetShape(aSolid); } else{ // check if a shell is a hole - //XX bIsHole=IsHole(aShell, myContext); - //XX if (bIsHole) { aHoleShells.Append(aShell); BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF); + aSB.SetShape(aShell); } else { // make a growth solid from a shell - TopoDS_Solid Solid; - aBB.MakeSolid(Solid); - aBB.Add (Solid, aShell); + aBB.MakeSolid(aSolid); + aBB.Add (aSolid, aShell); // - aNewSolids.Append (Solid); + aNewSolids.Append (aSolid); + aSB.SetShape(aSolid); } } + // + aSB.SetBox(aBox); + aSB.SetIsHole(bIsHole); + aDMISB.Bind(k, aSB); + } + // + // 2. Prepare TreeFiller + aItDMISB.Initialize(aDMISB); + for (; aItDMISB.More(); aItDMISB.Next()) { + k=aItDMISB.Key(); + const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value(); + // + bIsHole=aSB.IsHole(); + if (bIsHole) { + const Bnd_Box& aBox=aSB.Box(); + aTreeFiller.Add(k, aBox); + } } // - // 2. Find outer growth shell that is most close to each hole shell - aShellIt.Initialize(aHoleShells); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aHole = aShellIt.Value(); + // 3. Shake TreeFiller + aTreeFiller.Fill(); + // + // 4. Find outer growth shell that is most close + // to each hole shell + aItDMISB.Initialize(aDMISB); + for (; aItDMISB.More(); aItDMISB.Next()) { + k=aItDMISB.Key(); + const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value(); + bIsHole=aSB.IsHole(); + if (bIsHole) { + continue; + } // - aSolidIt.Initialize(aNewSolids); - for ( ; aSolidIt.More(); aSolidIt.Next()) { - const TopoDS_Shape& aSolid = aSolidIt.Value(); + const TopoDS_Shape aSolid=aSB.Shape(); + const Bnd_Box& aBoxSolid=aSB.Box(); + // + aSelector.Clear(); + aSelector.SetBox(aBoxSolid); + // + aNbHoles=aBBTree.Select(aSelector); + // + const BOPCol_ListOfInteger& aLI=aSelector.Indices(); + // + aItLI.Initialize(aLI); + for (; aItLI.More(); aItLI.Next()) { + k=aItLI.Value(); + const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k); + const TopoDS_Shape& aHole=aSBk.Shape(); // if (!IsInside(aHole, aSolid, myContext)){ continue; } // - if ( aInOutMap.IsBound (aHole)){ - const TopoDS_Shape& aSolid2 = aInOutMap(aHole); - if (IsInside(aSolid, aSolid2, myContext)) { + if (aInOutMap.IsBound (aHole)){ + const TopoDS_Shape& aHole2=aInOutMap(aHole); + if (IsInside(aHole, aHole2, myContext)) { aInOutMap.UnBind(aHole); aInOutMap.Bind (aHole, aSolid); } } else{ - aInOutMap.Bind (aHole, aSolid); + aInOutMap.Bind(aHole, aSolid); } } + }//for (; aItDMISB.More(); aItDMISB.Next()) { + // + // 5. Map [Solid/Holes] -> aMSH + aItDMSS.Initialize(aInOutMap); + for (; aItDMSS.More(); aItDMSS.Next()) { + const TopoDS_Shape& aHole=aItDMSS.Key(); + const TopoDS_Shape& aSolid=aItDMSS.Value(); // - // Add aHole to a map Solid/ListOfHoles [aMSH] - if (aInOutMap.IsBound(aHole)){ - const TopoDS_Shape& aSolid=aInOutMap(aHole); - if (aMSH.IsBound(aSolid)) { - BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid); - aLH.Append(aHole); - } - else { - BOPCol_ListOfShape aLH; - aLH.Append(aHole); - aMSH.Bind(aSolid, aLH); - } - //aBB.Add (aSolid, aHole); + if (aMSH.IsBound(aSolid)) { + BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid); + aLH.Append(aHole); + } + else { + BOPCol_ListOfShape aLH; + aLH.Append(aHole); + aMSH.Bind(aSolid, aLH); } - }// for (; aShellIt.More(); aShellIt.Next()) { + } // - // 3. Add aHoles to Solids + // 6. Add aHoles to Solids aItMSH.Initialize(aMSH); for (; aItMSH.More(); aItMSH.Next()) { TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key())); // const BOPCol_ListOfShape& aLH=aItMSH.Value(); - aShellIt.Initialize(aLH); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aHole = aShellIt.Value(); + aItLS.Initialize(aLH); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aHole = aItLS.Value(); aBB.Add (aSolid, aHole); } // // update classifier - BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); + BRepClass3d_SolidClassifier& aSC= + myContext->SolidClassifier(aSolid); aSC.Load(aSolid); // } // - // These aNewSolids are draft solids that + // 7. These aNewSolids are draft solids that // do not contain any internal shapes - // - aShellIt.Initialize(aNewSolids); - for ( ; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aSx = aShellIt.Value(); + aItLS.Initialize(aNewSolids); + for ( ; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSx=aItLS.Value(); myAreas.Append(aSx); } - // Add holes that outside the solids to myAreas - aShellIt.Initialize(aHoleShells); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aHole = aShellIt.Value(); + aItLS.Initialize(aHoleShells); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aHole = aItLS.Value(); if (!aInOutMap.IsBound(aHole)){ TopoDS_Solid aSolid; + // aBB.MakeSolid(aSolid); aBB.Add (aSolid, aHole); // @@ -583,7 +604,7 @@ static //function : PerformInternalShapes //purpose : //======================================================================= - void BOPAlgo_BuilderSolid::PerformInternalShapes() +void BOPAlgo_BuilderSolid::PerformInternalShapes() { myErrorStatus=0; // @@ -592,95 +613,169 @@ static return; } // + Standard_Integer k, aNbVFS, aNbSLF, aNbF, aNbA; BRep_Builder aBB; TopoDS_Iterator aIt; - BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt; - BOPCol_MapIteratorOfMapOfShape aItMF; - // - BOPCol_MapOfShape aMF, aMFP, aMFx; - BOPCol_IndexedDataMapOfShapeListOfShape aMEF; + TopExp_Explorer aExp; + BOPCol_ListIteratorOfListOfShape aItLS; + BOPCol_MapOfShape aMFs; BOPCol_ListOfShape aLSI; - // - // 1. All internal faces - aShellIt.Initialize(myLoopsInternal); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aShell=aShellIt.Value(); + BOPCol_ListIteratorOfListOfInteger aItLI; + BOPDS_BoxBndTreeSelector aSelector; + BOPDS_BoxBndTree aBBTree; + NCollection_UBTreeFiller + aTreeFiller(aBBTree); + BOPCol_DataMapOfIntegerShape aDMIS; + // + aNbA=myAreas.Extent(); + // + // 1. Prepare tree filler + k = 0; + aItLS.Initialize(myLoopsInternal); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aShell=aItLS.Value(); aIt.Initialize(aShell); for (; aIt.More(); aIt.Next()) { - const TopoDS_Shape& aF=aIt.Value(); - aMF.Add(aF); + const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value()); + // + if (aMFs.Add(aF)) { + if (aNbA) { + Bnd_Box aBox; + BRepBndLib::Add(aF, aBox); + aDMIS.Bind(k, aF); + aTreeFiller.Add(k++, aBox); + } + } } } - aNbFI=aMF.Extent(); // - // 2 Process solids - aSolidIt.Initialize(myAreas); - for ( ; aSolidIt.More(); aSolidIt.Next()) { - TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value())); + if (!aNbA) { + // 7b. "Rest" faces treatment + TopoDS_Solid aSolid; + aBB.MakeSolid(aSolid); // - TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);; - for (; anExpSol.More(); anExpSol.Next()) { - const TopoDS_Shape& aF = anExpSol.Current(); - TopoDS_Shape aFF=aF; - // - aFF.Orientation(TopAbs_FORWARD); - aMFx.Add(aFF); - aFF.Orientation(TopAbs_REVERSED); - aMFx.Add(aFF); + MakeInternalShells(aMFs, aLSI); + // + aItLS.Initialize(aLSI); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSI=aItLS.Value(); + aBB.Add (aSolid, aSI); } - aMEF.Clear(); - BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF); - // - // 2.1 Separate faces to process aMFP - aMFP.Clear(); - aItMF.Initialize(aMF); - for (; aItMF.More(); aItMF.Next()) { - const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key())); - if (!aMFx.Contains(aF)) { - if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) { - aMFP.Add(aF); + myAreas.Append(aSolid); + // + return; // => + }//if (!aNbA) { + // + //2. fill tree filler + aTreeFiller.Fill(); + // + // 3. Face/Solid candidates: aVFS + BOPCol_IndexedDataMapOfShapeListOfShape aMSLF; + BOPCol_MapOfShape aMFProcessed; + // + aItLS.Initialize(myAreas); + for (; aItLS.More(); aItLS.Next()) { + Bnd_Box aBox; + // + TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value())); + BRepBndLib::Add(aSolid, aBox); + // + aMFs.Clear(); + aExp.Init(aSolid, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aFs=aExp.Current(); + aMFs.Add(aFs); + } + // + aSelector.Clear(); + aSelector.SetBox(aBox); + // + aNbF=aBBTree.Select(aSelector); + // + const BOPCol_ListOfInteger& aLI=aSelector.Indices(); + aItLI.Initialize(aLI); + for (; aItLI.More(); aItLI.Next()) { + k=aItLI.Value(); + const TopoDS_Face& aF = *(TopoDS_Face*)&aDMIS.Find(k); + if (aMFs.Contains(aF)) { + continue; + } + // + gp_Pnt aP; + gp_Pnt2d aP2D; + // + BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext); + // + TopAbs_State aState=BOPTools_AlgoTools::ComputeState(aP, aSolid, + Precision::Confusion(), + myContext); + if (aState==TopAbs_IN) { + if (aMSLF.Contains(aSolid)) { + BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid); + aLF.Append(aF); + } + else { + BOPCol_ListOfShape aLF; + // + aLF.Append(aF); + aMSLF.Add(aSolid, aLF); } } } - aMFx.Clear(); + }// for (k=0; k < aNbVE; ++k) { + // + // 6. Update Solids by internal Faces + aNbSLF=aMSLF.Extent(); + for (k=1; k <= aNbSLF; ++k) { + const TopoDS_Shape& aSolid=aMSLF.FindKey(k); + TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid; // - // 2.2 Make Internal Shells - aLSI.Clear(); - MakeInternalShells(aMFP, aLSI); + const BOPCol_ListOfShape& aLF=aMSLF(k); // - // 2.3 Add them to aSolid - aShellIt.Initialize(aLSI); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aSI=aShellIt.Value(); - aBB.Add (aSolid, aSI); + aMFs.Clear(); + aItLS.Initialize(aLF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aF=aItLS.Value(); + aMFs.Add(aF); + aMFProcessed.Add(aF); } // - // 2.4 Remove faces aMFP from aMF - aItMF.Initialize(aMFP); - for (; aItMF.More(); aItMF.Next()) { - const TopoDS_Shape& aF=aItMF.Key(); - aMF.Remove(aF); - } + aLSI.Clear(); + MakeInternalShells(aMFs, aLSI); // - aNbFI=aMF.Extent(); - if (!aNbFI) { - break; + aItLS.Initialize(aLSI); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSI=aItLS.Value(); + aBB.Add (*pSolid, aSI); } - } //for ( ; aSolidIt.More(); aSolidIt.Next()) { + } + // + // 7. "Rest" faces treatment (if there are) + aMFs.Clear(); + aNbVFS = aDMIS.Extent(); + for (k=0; k < aNbVFS; ++k) { + const TopoDS_Face& aF=*(TopoDS_Face*)&aDMIS.Find(k); + if (!aMFProcessed.Contains(aF)) { + aMFs.Add(aF); + } + } + // + aNbFI=aMFs.Extent(); if (aNbFI) { TopoDS_Solid aSolid; aBB.MakeSolid(aSolid); // - MakeInternalShells(aMF, aLSI); - aShellIt.Initialize(aLSI); - for (; aShellIt.More(); aShellIt.Next()) { - const TopoDS_Shape& aSI=aShellIt.Value(); + aLSI.Clear(); + MakeInternalShells(aMFs, aLSI); + // + aItLS.Initialize(aLSI); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSI=aItLS.Value(); aBB.Add (aSolid, aSI); } myAreas.Append(aSolid); } } - //======================================================================= //function : MakeInternalShells //purpose : @@ -698,7 +793,9 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF, aItM.Initialize(theMF); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); - BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); + BOPTools::MapShapesAndAncestors(aF, + TopAbs_EDGE, TopAbs_FACE, + aMEF); } // aItM.Initialize(theMF); @@ -732,6 +829,7 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF, } } } + aShell.Closed (BRep_Tool::IsClosed (aShell)); theShells.Append(aShell); } } @@ -772,7 +870,9 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1, BOPCol_IndexedMapOfShape aBounds; BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds); const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current())); - aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext); + aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, + Precision::Confusion(), + aBounds, theContext); } return (aState==TopAbs_IN); } @@ -798,42 +898,3 @@ Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell, } return bRet; } -//======================================================================= -//function : IsClosedShell -//purpose : -//======================================================================= -Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell) -{ - Standard_Integer aNbE; - Standard_Boolean bRet; - TopoDS_Iterator aIt; - TopExp_Explorer aExp; - // - BOPCol_MapOfShape aM; - // - bRet=Standard_False; - aIt.Initialize(theShell); - for(; aIt.More(); aIt.Next()) { - const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value())); - aExp.Init(aF, TopAbs_EDGE); - for (; aExp.More(); aExp.Next()) { - const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current())); - if (BRep_Tool::Degenerated(aE)) { - continue; - } - // - if (aE.Orientation()==TopAbs_INTERNAL) { - continue; - } - if (!aM.Add(aE)) { - aM.Remove(aE); - } - } - } - // - aNbE=aM.Extent(); - if (!aNbE) { - bRet=!bRet; - } - return bRet; -} diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx index 8be816ceeb..16e39da299 100644 --- a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx +++ b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx @@ -65,8 +65,8 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const //purpose : //======================================================================= IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, - const Standard_Real aTol) -: + const Standard_Real aTol) + : Tol(aTol), done(Standard_False), nbpnt(0), @@ -95,7 +95,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, Standard_Boolean bFlag; // { - Standard_Real dU, dV, dA, dB, aR, aTresh; + Standard_Real dU, dV, dA, dB, aTresh; bFlag=Standard_True; // aTresh=100.; @@ -104,18 +104,12 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, dA=dU; dB=dV; if (dV>dU) { - dA=dV; - dB=dU; + dA=dV; + dB=dU; } // - aR=dA/dB; - if (dBaTresh) { - bFlag=!bFlag; - } + if (dB < Precision::PConfusion() || dA > dB * aTresh) { + bFlag=!bFlag; } } // @@ -125,7 +119,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, if(nbsu>40) nbsu = 40; if(nbsv>40) nbsv = 40; PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) - new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1); + new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1); } // /* diff --git a/tests/bugs/modalg_5/bug25416_1 b/tests/bugs/modalg_5/bug25416_1 new file mode 100644 index 0000000000..b0abf57243 --- /dev/null +++ b/tests/bugs/modalg_5/bug25416_1 @@ -0,0 +1,124 @@ +puts "================" +puts "OCC25416" +puts "================" +puts "" +####################################################################### +# Face/Face intersection algorithm gives different results for different order of the arguments +####################################################################### + +# Check if list of xdistcs-command is valid +proc checkList {List Tolerance D_good Limit_Tol} { + set L1 [llength ${List}] + set L2 10 + set L3 5 + set N [expr (${L1} - ${L2})/${L3} + 1] + + for {set i 1} {${i} <= ${N}} {incr i} { + set j1 [expr ${L2} + (${i}-1)*${L3}] + set j2 [expr ${j1} + 2] + set T [lindex ${List} ${j1}] + set D [lindex ${List} ${j2}] + #puts "i=${i} j1=${j1} j2=${j2} T=${T} D=${D}" + if { [expr abs(${D} - ${D_good})] > ${Tolerance} } { + puts "Error: T=${T} D=${D}" + } + + if { ${Tolerance} > ${Limit_Tol} } { + if { [expr abs(${D} - ${D_good})] > ${Limit_Tol} + && [expr abs(${D} - ${D_good})] <= ${Tolerance} } { + puts "Attention (critical value of tolerance) : T=${T} D=${D}" + } + } + } +} + + +puts "##############################" +puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!" +puts "##############################" +puts "" +puts "" + +# bopcurves command + +restore [locate_data_file bug25416_f1.brep] f1 +restore [locate_data_file bug25416_f2.brep] f2 + +############################# +set log [bopcurves f1 f2 -2d] +############################# + +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv + +#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. +set MaxTol 1.e-7 + +#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. +set GoodNbCurv 1 + +if {${Toler} > ${MaxTol}} { + puts "Error: Tolerance is too big!" +} +if {${NbCurv} != ${GoodNbCurv}} { + puts "Error: Curve Number is bad!" +} + +#------------- + +mksurface s1 f1 +mksurface s2 f2 + +erase s1 s2 + +for {set i 1} {$i <= ${NbCurv}} {incr i} { + set log [dump c_$i] + set dumptrimres [regexp {Trimmed curve\nParameters : +([-0-9.+eE]+) +([-0-9.+eE]+)} ${log} full U1 U2] + + if {${dumptrimres} == 0} { + regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles + + puts "Degree=${Degree}" + puts "Poles=${Poles}" + puts "KnotsPoles=${KnotsPoles}" + puts "" + + set Knot 1 + set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" + regexp ${exp_string} ${log} full U1 Mult1 + + set Knot ${KnotsPoles} + set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" + regexp ${exp_string} ${log} full U2 Mult2 + } + + puts "U1=${U1}" + puts "U2=${U2}" + + if {[expr {$U2 - $U1}] < 1.0e-20} { + puts "Error: Wrong curve's range!" + } + + dlog reset + dlog on + xdistcs c_$i s1 ${U1} ${U2} 10 + set Log2 [dlog get] + set List2 [split ${Log2} {TD= \t\n}] + set Tolerance 1.0e-7 + set Limit_Tol 1.0e-7 + set D_good 0. + checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + + dlog reset + dlog on + xdistcs c_$i s2 ${U1} ${U2} 10 + set Log2 [dlog get] + set List2 [split ${Log2} {TD= \t\n}] + set Tolerance 1.0e-7 + set Limit_Tol 1.0e-7 + set D_good 0. + checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} +} + +smallview +fit +set only_screen_axo 1 diff --git a/tests/bugs/modalg_5/bug25697_1 b/tests/bugs/modalg_5/bug25697_1 new file mode 100644 index 0000000000..a0c7d87d5f --- /dev/null +++ b/tests/bugs/modalg_5/bug25697_1 @@ -0,0 +1,20 @@ +puts "===========" +puts "OCC25697" +puts "===========" +puts "" +########################################################################################## +# Regression : Section obtained after command "bsection" in Test Harness is incorrect. +########################################################################################## + +restore [locate_data_file bug25697_shell_for_seam.brep] s1 +restore [locate_data_file bug25697_prism.brep] p1 +bsection result s1 p1 -n2d2 + +regexp {nb alone Vertices : +([-0-9.+eE]+)} [checksection result] full nb_alone_Vertices +if { ${nb_alone_Vertices} == 2 } { + puts "OK: Good result done by Boolean Operation algorithm" +} else { + puts "Error: Wrong result done by Boolean Operation algorithm" +} + +set length 107.503 diff --git a/tests/bugs/modalg_5/bug25697_2 b/tests/bugs/modalg_5/bug25697_2 new file mode 100644 index 0000000000..a41b690111 --- /dev/null +++ b/tests/bugs/modalg_5/bug25697_2 @@ -0,0 +1,63 @@ +puts "==========" +puts "OCC25697" +puts "==========" +puts "" +######################################################################################## +# Regression : Section obtained after command "bsection" in Test Harness is incorrect. +######################################################################################## + +restore [locate_data_file bug25697_shell_for_seam.brep] b1 +restore [locate_data_file bug25697_prism.brep] b2 +explode b1 f +copy b1_1 b1 +explode b2 f +copy b2_1 b2 + +################################# +set log [bopcurves b1 b2 -2d1] +################################# + +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv + +set MaxTol 1.e-7 +set GoodNbCurv 3 + +if { ${Toler} > ${MaxTol} } { + puts "Error: Tolerance is too big!" +} + +if { ${NbCurv} != ${GoodNbCurv} } { + puts "Error: Curve Number is bad!" +} + +#--------------- +mksurface s1 b1 +mksurface s2 b2 + +for {set i 1} {$i <= ${NbCurv}} {incr i} { + bounds c_$i u1 u2 + dump u1 u2 + dlog reset + dlog on + xdistcs c_$i s1 u1 u2 10 + set Log2 [dlog get] + set List2 [split ${Log2} {TD= \t\n}] + set Tolerance 1.0e-7 + set Limit_Tol 1.0e-7 + set D_good 0. + checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + + dlog reset + dlog on + xdistcs c_$i s2 u1 u2 10 + set Log2 [dlog get] + set List2 [split ${Log2} {TD= \t\n}] + set Tolerance 1.0e-7 + set Limit_Tol 1.0e-7 + set D_good 0. + checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} +} + +smallview +fit +set only_screen_axo 1