From: pkv Date: Thu, 5 Sep 2013 09:32:05 +0000 (+0400) Subject: 0024122: Hang-up during a topological operation. X-Git-Tag: V6_7_0_beta~151 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=744511c84512592cad18d130669599e7d75d1958;p=occt-copy.git 0024122: Hang-up during a topological operation. I. New features: no New features. II. Changes: II.1. class : BOPAlgo_Builder - method: void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& , BOPCol_DataMapOfShapeShape& , const BOPCol_BaseAllocator& ) The algorithm of finding 3D-parts for solids has ben changed. To improve the performance the unbalanced binary tree is used. II.2. class : BOPTools_AlgoTools - method: Standard_Boolean BOPTools_AlgoTools::GetFaceOff (const TopoDS_Edge&, const TopoDS_Face& BOPTools_ListOfCoupleOfShape& , TopoDS_Face& Handle(BOPInt_Context& ) The data treatment for tangent cases has been changed III. Modified entities: packages: BOPAlgo BOPTools Small corrections of test cases --- diff --git a/src/BOPAlgo/BOPAlgo.cdl b/src/BOPAlgo/BOPAlgo.cdl index de618553d6..0e13d851a9 100644 --- a/src/BOPAlgo/BOPAlgo.cdl +++ b/src/BOPAlgo/BOPAlgo.cdl @@ -21,7 +21,8 @@ package BOPAlgo ---Purpose: uses - gp, + gp, + Bnd, TopAbs, Geom, GeomAPI, diff --git a/src/BOPAlgo/BOPAlgo_Builder.cdl b/src/BOPAlgo/BOPAlgo_Builder.cdl index 6f91c78311..79dd265489 100644 --- a/src/BOPAlgo/BOPAlgo_Builder.cdl +++ b/src/BOPAlgo/BOPAlgo_Builder.cdl @@ -24,7 +24,8 @@ class Builder from BOPAlgo ---Purpose: -uses +uses + Box from Bnd, ShapeEnum from TopAbs, Shape from TopoDS, ListOfShape from TopTools, @@ -189,16 +190,21 @@ is FillIn3DParts(me:out; theInParts:out DataMapOfShapeListOfShape from BOPCol; - theDraftSolids:out DataMapOfShapeShape from BOPCol; - theAllocator:BaseAllocator from BOPCol) + theDraftSolids:out DataMapOfShapeShape from BOPCol; + theAllocator:BaseAllocator from BOPCol) is virtual protected; - + BuildSplitSolids(me:out; theInParts:out DataMapOfShapeListOfShape from BOPCol; theDraftSolids:out DataMapOfShapeShape from BOPCol; - theAllocator:BaseAllocator from BOPCol) + theAllocator:BaseAllocator from BOPCol) is protected; - + + BuildBndBox(me:out; + theIndex:Integer from Standard; + theBox: out Box from Bnd) + is protected; + FillInternalShapes(me:out) is protected; -- diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx index 72bb42379f..44d244111a 100644 --- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx +++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -58,289 +59,325 @@ // #include +#include +#include +#include + +#include +#include +#include +#include + + +static + Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh); static void OwnInternalShapes(const TopoDS_Shape& , BOPCol_IndexedMapOfShape& ); +//======================================================================= +//class : BOPAlgo_ShapeBox +//purpose : Auxiliary class +//======================================================================= +class BOPAlgo_ShapeBox { + public: + BOPAlgo_ShapeBox() { + }; + // + ~BOPAlgo_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; + }; + // + protected: + TopoDS_Shape myShape; + Bnd_Box myBox; +}; +// +typedef NCollection_DataMap\ + \ + BOPAlgo_DataMapOfIntegerShapeBox; +// +typedef BOPAlgo_DataMapOfIntegerShapeBox::Iterator \ + BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox; +// + //======================================================================= //function : FillImagesSolids //purpose : //======================================================================= - void BOPAlgo_Builder::FillImagesSolids() +void BOPAlgo_Builder::FillImagesSolids() { + Standard_Boolean bHasSolids; + Standard_Integer i, aNbS; + // myErrorStatus=0; // - Handle(NCollection_IncAllocator) aAllocator; - //-----------------------------------------------------scope_1 f - aAllocator=new NCollection_IncAllocator(); + bHasSolids=Standard_False; + aNbS=myDS->NbSourceShapes(); + for (i=0; iShapeInfo(i); + if (aSI.ShapeType()==TopAbs_SOLID) { + bHasSolids=!bHasSolids; + break; + } + } + // + if (!bHasSolids) { + return; + } + // + Handle(NCollection_IncAllocator) aAlr; // - BOPCol_DataMapOfShapeListOfShape theInParts(100, aAllocator); - BOPCol_DataMapOfShapeShape theDraftSolids(100, aAllocator); + aAlr=new NCollection_IncAllocator(); // - FillIn3DParts(theInParts, theDraftSolids, aAllocator); - BuildSplitSolids(theInParts, theDraftSolids, aAllocator); + BOPCol_DataMapOfShapeListOfShape theInParts(100, aAlr); + BOPCol_DataMapOfShapeShape theDraftSolids(100, aAlr); + // + FillIn3DParts(theInParts, theDraftSolids, aAlr); + BuildSplitSolids(theInParts, theDraftSolids, aAlr); FillInternalShapes(); // theInParts.Clear(); theDraftSolids.Clear(); - //-----------------------------------------------------scope_1 t } //======================================================================= //function : FillIn3DParts //purpose : //======================================================================= - void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts, - BOPCol_DataMapOfShapeShape& theDraftSolids, - const Handle(NCollection_BaseAllocator)& theAllocator) +void BOPAlgo_Builder::FillIn3DParts(BOPCol_DataMapOfShapeListOfShape& theInParts, + BOPCol_DataMapOfShapeShape& theDraftSolids, + const BOPCol_BaseAllocator& ) { - myErrorStatus=0; + Standard_Boolean bHasImage; + Standard_Integer i, k, aNbS, aNbLIF, nFP, aNbFP, aNbFIN, iIsIN; + TopoDS_Solid aSD; + TopoDS_Iterator aIt; + BRep_Builder aBB; + BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1; + BOPCol_ListIteratorOfListOfShape aItLS; + BOPAlgo_ShapeBox aSB; + Handle(NCollection_IncAllocator) aAlr0; // - Standard_Boolean bIsIN, bHasImage; - Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF, aNbEFP; - TopAbs_ShapeEnum aType; - TopAbs_State aState; - TopoDS_Iterator aIt, aItF; - BRep_Builder aBB; - TopoDS_Solid aSolidSp; - TopoDS_Face aFP; - BOPCol_ListIteratorOfListOfShape aItS, aItFP, aItEx; - // - //BOPCol_ListOfShape aLIF(theAllocator); - //BOPCol_MapOfShape aMFDone(100, theAllocator); - //BOPCol_IndexedMapOfShape aMFIN(100, theAllocator); - //BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, theAllocator); - //BOPCol_IndexedMapOfShape aMS(100, theAllocator); - BOPCol_IndexedMapOfShape aMSolids(100, theAllocator); - BOPCol_IndexedMapOfShape aMFaces(100, theAllocator); + aAlr0=new NCollection_IncAllocator(); + BOPAlgo_DataMapOfIntegerShapeBox aDMISB(100, aAlr0); + BOPAlgo_DataMapIteratorOfDataMapOfIntegerShapeBox aItDMISB; // + myErrorStatus=0; theDraftSolids.Clear(); // + // 1. aDMISB map Index/FaceBox + k=0; aNbS=myDS->NbSourceShapes(); for (i=0; iShapeInfo(i); + if (aSI.ShapeType()!=TopAbs_FACE) { + continue; + } + // const TopoDS_Shape& aS=aSI.Shape(); // - aType=aSI.ShapeType(); - switch(aType) { - case TopAbs_SOLID: { - aMSolids.Add(aS); - break; + if (myImages.IsBound(aS)) { + const BOPCol_ListOfShape& aLS=myImages.Find(aS); + aItLS.Initialize(aLS); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aSx=aItLS.Value(); + // + Bnd_Box aBox; + BRepBndLib::Add(aSx, aBox); + // + aSB.SetShape(aSx); + aSB.SetBox(aBox); + // + aDMISB.Bind(k, aSB); + ++k; } + } + else { + const Bnd_Box& aBox=aSI.Box(); // - case TopAbs_FACE: { - // all faces (originals or images) - if (myImages.IsBound(aS)) { - const BOPCol_ListOfShape& aLS=myImages.Find(aS); - aItS.Initialize(aLS); - for (; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aFx=aItS.Value(); - aMFaces.Add(aFx); - } - } - else { - aMFaces.Add(aS); - } - break; - } + aSB.SetShape(aS); + aSB.SetBox(aBox); // - default: - break; + aDMISB.Bind(k, aSB); + ++k; } - } + }//for (i=0; iShapeInfo(i); + if (aSI.ShapeType()!=TopAbs_SOLID) { + continue; + } + // + //--------------------------------------------- + Handle(NCollection_IncAllocator) aAlr1; // - BOPCol_MapOfShape aMFDone(100, aAllocator1); - BOPCol_IndexedMapOfShape aMFIN(100, aAllocator1); - BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAllocator1); - BOPCol_ListOfShape aLIF(aAllocator1); - BOPCol_IndexedMapOfShape aMS(100, aAllocator1); + aAlr1=new NCollection_IncAllocator(); // - aMFDone.Clear(); - aMFIN.Clear(); - aMEF.Clear(); + BOPCol_ListOfShape aLFIN(aAlr1); + BOPCol_ListOfShape aLIF(aAlr1); + BOPCol_IndexedMapOfShape aMF(100, aAlr1); + BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1); // - const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aMSolids(i))); + BOPDS_BoxBndTreeSelector aSelector; + BOPDS_BoxBndTree aBBTree; + NCollection_UBTreeFiller aTreeFiller(aBBTree); + Bnd_Box aBoxS; // - aBB.MakeSolid(aSolidSp); - // - // Draft solid and its pure internal faces => aSolidSp, aLIF - aLIF.Clear(); - BuildDraftSolid(aSolid, aSolidSp, aLIF); - aNbLIF=aLIF.Extent(); + const TopoDS_Shape& aS=aSI.Shape(); + const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); // - // 1 all faces/edges from aSolid [ aMS ] + // 2.0 Flag bHasImage bHasImage=Standard_False; - aMS.Clear(); - aIt.Initialize(aSolid); + aIt.Initialize(aS); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aShell=aIt.Value(); - // - if (myImages.IsBound(aShell)) { - bHasImage=Standard_True; - // - const BOPCol_ListOfShape& aLS=myImages.Find(aShell); - aItS.Initialize(aLS); - for (; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aSx=aItS.Value(); - aMS.Add(aSx); - BOPTools::MapShapes(aSx, TopAbs_FACE, aMS); - BOPTools::MapShapes(aSx, TopAbs_EDGE, aMS); - BOPTools::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF); - } - } - else { - //aMS.Add(aShell); - BOPTools::MapShapes(aShell, TopAbs_FACE, aMS); - BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF); + bHasImage=myImages.IsBound(aShell); + if (bHasImage){ + break; } } // - // 2 all faces that are not from aSolid [ aLFP1 ] - BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAllocator1); - BOPCol_ListOfShape aLFP1(aAllocator1); - BOPCol_ListOfShape aLFP(aAllocator1); - BOPCol_ListOfShape aLCBF(aAllocator1); - BOPCol_ListOfShape aLFIN(aAllocator1); - BOPCol_ListOfShape aLEx(aAllocator1); + // 2.1 Compute Bnd_Box for the solid aS [ aBoxS ] + BuildBndBox(i, aBoxS); + //----- // - // for all non-solid faces build EF map [ aMEFP ] - for (j=1; j<=aNbFaces; ++j) { - const TopoDS_Shape& aFace=aMFaces(j); - if (!aMS.Contains(aFace)) { - BOPTools::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP); - } - } + // 2.2 Build Draft Solid [aSD] + aBB.MakeSolid(aSD); // - // among all faces from aMEFP select these that have same edges - // with the solid (i.e aMEF). These faces will be treated first - // to prevent the usage of 3D classifier. - // The full list of faces to process is aLFP1. - aNbEFP=aMEFP.Extent(); - for (j=1; j<=aNbEFP; ++j) { - const TopoDS_Shape& aE=aMEFP.FindKey(j); - // - if (aMEF.Contains(aE)) { // !! - const BOPCol_ListOfShape& aLF=aMEFP(j); - aItFP.Initialize(aLF); - for (; aItFP.More(); aItFP.Next()) { - const TopoDS_Shape& aF=aItFP.Value(); - if (aMFDone.Add(aF)) { - aLFP1.Append(aF); - } - } - } - else { - aLEx.Append(aE); - } + BuildDraftSolid(aSolid, aSD, aLIF); + aNbLIF=aLIF.Extent(); + // + BOPTools::MapShapesAndAncestors(aSD, TopAbs_EDGE, TopAbs_FACE, aMEF); + // + // 2.3 Faces from aSD and own internal faces => aMF + BOPTools::MapShapes(aSD, TopAbs_FACE, aMF); + // + aItLS.Initialize(aLIF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aFI=aItLS.Value(); + aMF.Add(aFI); } // - aItEx.Initialize(aLEx); - for (; aItEx.More(); aItEx.Next()) { - const TopoDS_Shape& aE=aItEx.Value(); - const BOPCol_ListOfShape& aLF=aMEFP.FindFromKey(aE); - aItFP.Initialize(aLF); - for (; aItFP.More(); aItFP.Next()) { - const TopoDS_Shape& aF=aItFP.Value(); - if (aMFDone.Add(aF)) { - //aLFP2.Append(aF); - aLFP1.Append(aF); - } + // 2.4. Prepare TreeFiller + aItDMISB.Initialize(aDMISB); + for (; aItDMISB.More(); aItDMISB.Next()) { + k=aItDMISB.Key(); + const BOPAlgo_ShapeBox& aSBk=aItDMISB.Value(); + const TopoDS_Shape& aFk=aSBk.Shape(); + if (aMF.Contains(aFk)) { + continue; } + // + const Bnd_Box& aBk=aSBk.Box(); + // + aTreeFiller.Add(k, aBk); } // - //========== + // 2.5. Shake TreeFiller + aTreeFiller.Fill(); + // + // 2.6. Select boxes of faces that are not out of aBoxS + aSelector.Clear(); + aSelector.SetBox(aBoxS); + // + aNbFP=aBBTree.Select(aSelector); // - // 3 Process faces aLFP1 - aMFDone.Clear(); - aNbFP=aLFP1.Extent(); - aItFP.Initialize(aLFP1); - for (; aItFP.More(); aItFP.Next()) { - const TopoDS_Shape& aSP=aItFP.Value(); - if (!aMFDone.Add(aSP)) { - continue; + const BOPCol_ListOfInteger& aLIFP=aSelector.Indices(); + // + // 2.7. Collect faces that are IN aSolid [ aLFIN ] + BOPCol_ListOfShape aLFP(aAlr1); + BOPCol_ListOfShape aLCBF(aAlr1); + BOPCol_MapOfShape aMFDone(100, aAlr1); + BOPCol_IndexedMapOfShape aME(100, aAlr1); + // + BOPTools::MapShapes(aSD, TopAbs_EDGE, aME); + // + aItLI.Initialize(aLIFP); + for (; aItLI.More(); aItLI.Next()) { + nFP=aItLI.Value(); + const BOPAlgo_ShapeBox& aSBF=aDMISB.Find(nFP); + const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape()); + if (aMFDone.Contains(aFP)) { + continue; } - // - // first face to process - aFP=(*(TopoDS_Face*)(&aSP)); - bIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, myContext); - aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT; + aMFDone.Add(aFP); + // + iIsIN=BOPTools_AlgoTools::IsInternalFace(aFP, aSD, aMEF, 1.e-14, myContext); // - // collect faces to process [ aFP is the first ] aLFP.Clear(); aLFP.Append(aFP); - aItS.Initialize(aLFP1); - for (; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aSk=aItS.Value(); - if (!aMFDone.Contains(aSk)) { - aLFP.Append(aSk); - } + // + aItLI1.Initialize(aLIFP); + for (; aItLI1.More(); aItLI1.Next()) { + const TopoDS_Shape& aFx=aDMISB.Find(aItLI1.Value()).Shape(); + if (!aMFDone.Contains(aFx)) { + aLFP.Append(aFx); + } } // - // Connexity Block that spreads from aFP the Bound - // or till the end of the block itself aLCBF.Clear(); + //---------------------------------------- { - Handle(NCollection_IncAllocator) aAllocator; - aAllocator=new NCollection_IncAllocator(); - // - BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aMS, aLCBF, aAllocator); + Handle(NCollection_IncAllocator) aAlr2; + aAlr2=new NCollection_IncAllocator(); // + BOPTools_AlgoTools::MakeConnexityBlock(aLFP, aME, aLCBF, aAlr2); } - // - // - // fill states for the Connexity Block - aItS.Initialize(aLCBF); - for (; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aSx=aItS.Value(); - aMFDone.Add(aSx); - if (aState==TopAbs_IN) { - aMFIN.Add(aSx); + //---------------------------------------- + aItLS.Initialize(aLCBF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aFx=aItLS.Value(); + aMFDone.Add(aFx); + if (iIsIN) { + aLFIN.Append(aFx); } } - // - aNbFPx=aMFDone.Extent(); - if (aNbFPx==aNbFP) { - break; - } - }//for (; aItFP.More(); aItFP.Next()) + }// for (; aItLI.More(); aItLI.Next()) { // - // faces Inside aSolid - aLFIN.Clear(); - aNbFIN=aMFIN.Extent(); + // 2.8. Store the results in theInParts, theDraftSolids + aNbFIN=aLFIN.Extent(); if (aNbFIN || aNbLIF) { - for (j=1; j<=aNbFIN; ++j) { - const TopoDS_Shape& aFIn=aMFIN(j); - aLFIN.Append(aFIn); - } - // - aItS.Initialize(aLIF); - for (; aItS.More(); aItS.Next()) { - const TopoDS_Shape& aFIN=aItS.Value(); - aLFIN.Append(aFIN); + aItLS.Initialize(aLIF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aFI=aItLS.Value(); + aLFIN.Append(aFI); } - // theInParts.Bind(aSolid, aLFIN); } + // if (aNbFIN || bHasImage) { - theDraftSolids.Bind(aSolid, aSolidSp); + theDraftSolids.Bind(aSolid, aSD); } - }//for (i=1; i<=aNbSolids; ++i) { + //--------------------------------------------- + }// for (i=0; iNbSourceShapes(); @@ -504,12 +544,12 @@ static } // aNbSFS=aSFS.Extent(); - //DEB f - // <-A - //DEB t // - // 1.3 Build new solids - BOPAlgo_BuilderSolid aSB(theAllocator); + // 1.3 Build new solids + Handle(NCollection_IncAllocator) aAlr1; + aAlr1=new NCollection_IncAllocator(); + // + BOPAlgo_BuilderSolid aSB(aAlr1); // //aSB.SetContext(myContext); aSB.SetShapes(aSFS); @@ -548,14 +588,14 @@ static } } } - } // for (; aIt1.More(); aIt1.Next()) { + }// for (i=0; iShapeInfo(theIndex); + const TopoDS_Shape& aS=aSI.Shape(); + const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS)); + // + bIsOpenBox=Standard_False; + // + aTolS=0.; + const BOPCol_ListOfInteger& aLISh=aSI.SubShapes(); + aItLI.Initialize(aLISh); + for (; aItLI.More(); aItLI.Next()) { + nSh=aItLI.Value(); + const BOPDS_ShapeInfo& aSISh=myDS->ShapeInfo(nSh); + if (aSISh.ShapeType()!=TopAbs_SHELL) { + continue; + } + // + const BOPCol_ListOfInteger& aLIFc=aSISh.SubShapes(); + aItLI1.Initialize(aLIFc); + for (; aItLI1.More(); aItLI1.Next()) { + nFc=aItLI1.Value(); + const BOPDS_ShapeInfo& aSIFc=myDS->ShapeInfo(nFc); + if (aSIFc.ShapeType()!=TopAbs_FACE) { + continue; + } + // + const Bnd_Box& aBFc=aSIFc.Box(); + aBoxS.Add(aBFc); + // + if (!bIsOpenBox) { + bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() || + aBFc.IsOpenYmin() || aBFc.IsOpenYmax() || + aBFc.IsOpenZmin() || aBFc.IsOpenZmax()); + if (bIsOpenBox) { + break; + } + } + // + const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape()); + aTolFc=BRep_Tool::Tolerance(aFc); + if (aTolFc>aTolS) { + aTolS=aTolFc; + } + }//for (; aItLI1.More(); aItLI1.Next()) { + if (bIsOpenBox) { + break; + } + // + const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape()); + bIsOpenBox=IsClosedShell(aSh); + if (bIsOpenBox) { + break; + } + }//for (; aItLI.More(); aItLI.Next()) { + // + if (bIsOpenBox) { + aBoxS.SetWhole(); + } + else { + BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); + aSC.PerformInfinitePoint(aTolS); + aState=aSC.State(); + if (aState==TopAbs_IN) { + aBoxS.SetWhole(); + } + } +} +//======================================================================= //function : OwnInternalShapes //purpose : //======================================================================= @@ -785,23 +904,52 @@ static } } } +//======================================================================= +//function : IsClosedShell +//purpose : +//======================================================================= +Standard_Boolean IsClosedShell(const TopoDS_Shell& aSh) +{ + Standard_Boolean bRet; + Standard_Integer i, aNbE, aNbF; + TopAbs_Orientation aOrF; + BOPCol_IndexedDataMapOfShapeListOfShape aMEF; + BOPCol_ListIteratorOfListOfShape aItLS; + // + bRet=Standard_False; + // + BOPTools::MapShapesAndAncestors(aSh, TopAbs_EDGE, TopAbs_FACE, aMEF); + // + aNbE=aMEF.Extent(); + for (i=1; i<=aNbE; ++i) { + const TopoDS_Edge& aE=*((TopoDS_Edge*)&aMEF.FindKey(i)); + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // + aNbF=0; + const BOPCol_ListOfShape& aLF=aMEF(i); + aItLS.Initialize(aLF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aF=aItLS.Value(); + aOrF=aF.Orientation(); + if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) { + continue; + } + ++aNbF; + } + // + if (aNbF==1) { + bRet=!bRet; // True + break; + } + } + // + return bRet; +} + + // // ErrorStatus // 30 - SolidBuilder failed // A -/* - { - TopoDS_Compound aCx; - BRep_Builder aBBx; - BOPCol_ListIteratorOfListOfShape aItx; - // - aBBx.MakeCompound(aCx); - aItx.Initialize(aSFS1); - for (; aItx.More(); aItx.Next()) { - const TopoDS_Shape& aFx=aItx.Value(); - aBBx.Add(aCx, aFx); - } - BRepTools::Write(aCx, "cxso"); - int a=0; - } - */ diff --git a/src/BOPTools/BOPTools_AlgoTools.cdl b/src/BOPTools/BOPTools_AlgoTools.cdl index e5e88810cd..8d9f6ca52e 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cdl +++ b/src/BOPTools/BOPTools_AlgoTools.cdl @@ -148,7 +148,9 @@ is theFace :Face from TopoDS; theLCEF :out ListOfCoupleOfShape from BOPTools; theFaceOff :out Face from TopoDS; - theContext :out Context from BOPInt); + theContext :out Context from BOPInt) + returns Boolean from Standard; + ---Purpose: For the face theFace and its edge theEdge -- finds the face suitable to produce shell. -- theLCEF - set of faces to search. All faces @@ -164,7 +166,7 @@ is -- couple of faces theFace1, theFace2. -- The faces theFace, theFace1, theFace2 must -- share the edge theEdge - returns Boolean from Standard; + returns Integer from Standard; IsInternalFace(myclass; theFace :Face from TopoDS; @@ -175,7 +177,7 @@ is -- appropriate couple of faces (from the set theLF) . -- The faces of the set theLF and theFace must -- share the edge theEdge - returns Boolean from Standard; + returns Integer from Standard; IsInternalFace(myclass; theFace :Face from TopoDS; @@ -188,7 +190,7 @@ is -- theMEF - Map Edge/Faces for theSolid -- theTol - value of precision of computation -- theContext- cahed geometrical tools - returns Boolean from Standard; + returns Integer from Standard; GetEdgeOnFace (myclass; diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 5611f37fe2..bc1a0ba73f 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -110,10 +110,10 @@ static // function: MakeConnexityBlocks // purpose: //======================================================================= - void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS, - const TopAbs_ShapeEnum theType1, - const TopAbs_ShapeEnum theType2, - BOPCol_ListOfShape& theLCB) +void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS, + const TopAbs_ShapeEnum theType1, + const TopAbs_ShapeEnum theType2, + BOPCol_ListOfShape& theLCB) { Standard_Integer aNbF, aNbAdd, aNbAdd1, i; BRep_Builder aBB; @@ -196,7 +196,7 @@ static // function: OrientFacesOnShell // purpose: //======================================================================= - void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell) +void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell) { Standard_Boolean bIsProcessed1, bIsProcessed2; Standard_Integer i, aNbE, aNbF, j; @@ -324,8 +324,8 @@ static //function : Orientation //purpose : //======================================================================= - TopAbs_Orientation Orientation(const TopoDS_Edge& anE, - const TopoDS_Face& aF) +TopAbs_Orientation Orientation(const TopoDS_Edge& anE, + const TopoDS_Face& aF) { TopAbs_Orientation anOr=TopAbs_INTERNAL; @@ -348,10 +348,10 @@ static // function: MakeConnexityBlock. // purpose: //======================================================================= - void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn, - BOPCol_IndexedMapOfShape& theMEAvoid, - BOPCol_ListOfShape& theLCB, - const Handle(NCollection_BaseAllocator)& theAllocator) +void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn, + BOPCol_IndexedMapOfShape& theMEAvoid, + BOPCol_ListOfShape& theLCB, + const Handle(NCollection_BaseAllocator)& theAllocator) { Standard_Integer aNbF, aNbAdd1, aNbAdd, i; TopExp_Explorer aExp; @@ -428,10 +428,10 @@ static // function: ComputeStateByOnePoint // purpose: //======================================================================= - TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS, - const TopoDS_Solid& theRef, - const Standard_Real theTol, - Handle(BOPInt_Context)& theContext) +TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + Handle(BOPInt_Context)& theContext) { TopAbs_State aState; TopAbs_ShapeEnum aType; @@ -453,11 +453,11 @@ static // function: ComputeState // purpose: //======================================================================= - TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF, - const TopoDS_Solid& theRef, - const Standard_Real theTol, - BOPCol_IndexedMapOfShape& theBounds, - Handle(BOPInt_Context)& theContext) +TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF, + const TopoDS_Solid& theRef, + const Standard_Real theTol, + BOPCol_IndexedMapOfShape& theBounds, + Handle(BOPInt_Context)& theContext) { TopAbs_State aState; TopExp_Explorer aExp; @@ -579,22 +579,33 @@ static //function : IsInternalFace //purpose : //======================================================================= - Standard_Boolean BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace, - const TopoDS_Solid& theSolid, - BOPCol_IndexedDataMapOfShapeListOfShape& theMEF, - const Standard_Real theTol, - Handle(BOPInt_Context)& theContext) +Standard_Integer BOPTools_AlgoTools::IsInternalFace + (const TopoDS_Face& theFace, + const TopoDS_Solid& theSolid, + BOPCol_IndexedDataMapOfShapeListOfShape& theMEF, + const Standard_Real theTol, + Handle(BOPInt_Context)& theContext) { - Standard_Boolean bRet, bDegenerated; - Standard_Integer aNbF; + Standard_Boolean bDegenerated; + Standard_Integer aNbF, iRet, iFound; TopAbs_Orientation aOr; - TopoDS_Edge aEL; + TopoDS_Edge aE1; TopExp_Explorer aExp; BOPCol_ListIteratorOfListOfShape aItF; // - bRet=Standard_False; + // For all invoked functions: [::IsInternalFace(...)] + // the returned value iRet means: + // iRet=0; - state is not IN + // iRet=1; - state is IN + // iRet=2; - state can not be found by the method of angles + // + // For this function the returned value iRet means: + // iRet=0; - state is not IN + // iRet=1; - state is IN // + iRet=0; // 1 Try to find an edge from theFace in theMEF + iFound=0; aExp.Init(theFace, TopAbs_EDGE); for(; aExp.More(); aExp.Next()) { const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current())); @@ -602,6 +613,8 @@ static continue; } // + ++iFound; + // aOr=aE.Orientation(); if (aOr==TopAbs_INTERNAL) { continue; @@ -614,64 +627,85 @@ static BOPCol_ListOfShape& aLF=theMEF.ChangeFromKey(aE); aNbF=aLF.Extent(); if (!aNbF) { - return bRet; // it can not be so + return iRet; // it can not be so } + // else if (aNbF==1) { // aE is internal edge on aLF.First() const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First())); - bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext); - return bRet; + BOPTools_AlgoTools::GetEdgeOnFace(aE, aF1, aE1); + if (aE1.Orientation()!=TopAbs_INTERNAL) { + iRet=2; + break; + } + // + iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext); + break; } + // else if (aNbF==2) { const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First())); const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last())); // if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) { // treat as it was for 1 face - bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext); - return bRet; + iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext); + break; } } + // if (aNbF%2) { - return bRet; // it can not be so + iRet=0; + return iRet; // it can not be so } else { // aNbF=2,4,6,8,... - bRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext); - return bRet; + iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext); + break; } }//for(; aExp.More(); aExp.Next()) { // + if (!iFound) { + // the face has no shared edges with the solid + iRet=2; + } + // + if (iRet!=2) { + return iRet; + } + // //======================================== // 2. Classify face using classifier // TopAbs_State aState; BOPCol_IndexedMapOfShape aBounds; // + BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds); + // aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, theTol, aBounds, theContext); - bRet=(aState==TopAbs_IN); // - return bRet; + iRet=(aState==TopAbs_IN)? 1 : 0; + // + return iRet; } //======================================================================= //function : IsInternalFace //purpose : //======================================================================= - Standard_Boolean BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace, - const TopoDS_Edge& theEdge, - BOPCol_ListOfShape& theLF, - Handle(BOPInt_Context)& theContext) +Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + BOPCol_ListOfShape& theLF, + Handle(BOPInt_Context)& theContext) { - Standard_Boolean bRet; - Standard_Boolean aNbF; + Standard_Integer aNbF, iRet; // - bRet=Standard_False; + iRet=0; // aNbF=theLF.Extent(); if (aNbF==2) { const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First())); const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last())); - bRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); - return bRet; + iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); + return iRet; } // else { @@ -686,25 +720,27 @@ static // const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1())); const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2())); - bRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); - if (bRet) { - return bRet; + iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext); + if (iRet) { + return iRet; } } } - return bRet; + return iRet; } //======================================================================= //function : IsInternalFace //purpose : //======================================================================= - Standard_Boolean BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace, - const TopoDS_Edge& theEdge, - const TopoDS_Face& theFace1, - const TopoDS_Face& theFace2, - Handle(BOPInt_Context)& theContext) +Standard_Integer BOPTools_AlgoTools::IsInternalFace + (const TopoDS_Face& theFace, + const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace1, + const TopoDS_Face& theFace2, + Handle(BOPInt_Context)& theContext) { Standard_Boolean bRet; + Standard_Integer iRet; TopoDS_Edge aE1, aE2; TopoDS_Face aFOff; BOPTools_ListOfCoupleOfShape theLCSOff; @@ -733,21 +769,31 @@ static aCS2.SetShape2(theFace2); theLCSOff.Append(aCS2); // - GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext); + bRet=GetFaceOff(aE1, theFace1, theLCSOff, aFOff, theContext); // - bRet = theFace.IsEqual(aFOff); - return bRet; + iRet=0; // theFace is not internal + if (theFace.IsEqual(aFOff)) { + // theFace is internal + iRet=1; + if (!bRet) { + // theFace seems to be internal + iRet=2; + } + } + return iRet; } //======================================================================= //function : GetFaceOff //purpose : //======================================================================= - void BOPTools_AlgoTools::GetFaceOff(const TopoDS_Edge& theE1, - const TopoDS_Face& theF1, - BOPTools_ListOfCoupleOfShape& theLCSOff, - TopoDS_Face& theFOff, - Handle(BOPInt_Context)& theContext) +Standard_Boolean BOPTools_AlgoTools::GetFaceOff + (const TopoDS_Edge& theE1, + const TopoDS_Face& theF1, + BOPTools_ListOfCoupleOfShape& theLCSOff, + TopoDS_Face& theFOff, + Handle(BOPInt_Context)& theContext) { + Standard_Boolean bRet; Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin; gp_Pnt aPn1, aPn2, aPx; gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF; @@ -770,6 +816,7 @@ static // aDTF=aDN1^aDBF; // + bRet=Standard_True; aIt.Initialize(theLCSOff); for (; aIt.More(); aIt.Next()) { const BOPTools_CoupleOfShape& aCS=aIt.Value(); @@ -798,7 +845,12 @@ static aAngleMin=aAngle; theFOff=aF2; } + else if (aAngle==aAngleMin) { + // the minimal angle can not be found + bRet=Standard_False; + } } + return bRet; } //======================================================================= //function : GetEdgeOff diff --git a/tests/bugs/modalg_1/buc60462_2 b/tests/bugs/modalg_1/buc60462_2 index 0396531d2b..4520c12561 100755 --- a/tests/bugs/modalg_1/buc60462_2 +++ b/tests/bugs/modalg_1/buc60462_2 @@ -1,4 +1,5 @@ puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" +puts "TODO ?OCC24122 ALL: Error : The square of result shape is" puts "==========" puts "BUC60462" diff --git a/tests/bugs/modalg_2/bug472_2 b/tests/bugs/modalg_2/bug472_2 index 4860fd4b15..cce8581a7e 100755 --- a/tests/bugs/modalg_2/bug472_2 +++ b/tests/bugs/modalg_2/bug472_2 @@ -1,4 +1,6 @@ -puts "TODO OCC12345 ALL: Error : The command is not valid. The square is" +puts "TODO ?OCC12345 ALL: Error : The command is not valid. The square is" +puts "TODO ?OCC24122 ALL: Error : The square of result shape is" +puts "TODO ?OCC24122 ALL: Faulty shapes in variables faulty_1 to faulty_" puts "========================" puts " OCC472 " puts "(case 2)" diff --git a/tests/bugs/modalg_4/bug772 b/tests/bugs/modalg_4/bug772 index 3b3233171f..11216ea3bc 100755 --- a/tests/bugs/modalg_4/bug772 +++ b/tests/bugs/modalg_4/bug772 @@ -1,5 +1,6 @@ puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC12345 ALL: Error : The square of result shape is" +puts "TODO ?OCC12345 ALL: Error : The square of result shape is" +puts "TODO ?OCC12345 ALL: Error : The command is not valid. The square is" puts "========" puts "OCC772" diff --git a/tests/bugs/modalg_4/bug825_2 b/tests/bugs/modalg_4/bug825_2 index ab5430e375..83a1d29230 100755 --- a/tests/bugs/modalg_4/bug825_2 +++ b/tests/bugs/modalg_4/bug825_2 @@ -1,7 +1,8 @@ pload QAcommands -puts "TODO OCC12345 ALL: Error : The command is not valid. The square is" +puts "TODO ?OCC12345 ALL: Error : The square of result shape is" +puts "TODO ?OCC12345 ALL: Error : The command is not valid. The square is" puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC12345 ALL: Faulty : Resulting shape is empty COMPOUND" +puts "TODO ?OCC12345 ALL: Faulty : Resulting shape is empty COMPOUND" puts "========" puts "OCC825" diff --git a/tests/bugs/moddata_1/bug152_2 b/tests/bugs/moddata_1/bug152_2 index f312b6c22a..e132331387 100755 --- a/tests/bugs/moddata_1/bug152_2 +++ b/tests/bugs/moddata_1/bug152_2 @@ -1,6 +1,6 @@ # by apn master-master 03.12.2012 puts "TODO ?OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC12345 ALL: Error : The square of result shape is" +puts "TODO ?OCC12345 ALL: Error : The square of result shape is" #puts "TODO OCC12345 ALL: An exception was caught" #puts "TODO OCC12345 ALL: \\*\\* Exception \\*\\*.*" #puts "TODO OCC12345 ALL: TEST INCOMPLETE"