From 6f1ea0f4b1bc48a023f191712ea1f680434ff107 Mon Sep 17 00:00:00 2001 From: nbv Date: Thu, 7 Dec 2017 11:28:20 +0300 Subject: [PATCH] 0029179: Result of Boolean common depends on an order of arguments Usage of Bnd_Box-filtering is eliminated while putting a (definitely) common vertex between two faces on the intersection curve. Algorithm of putting not-common (ON/IN) vertices has not been changed. --- src/BOPAlgo/BOPAlgo_PaveFiller.hxx | 19 ++++--- src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx | 83 +++++++++++++++------------- src/BOPDS/BOPDS_DS.cxx | 65 +++++++++++++--------- src/BOPDS/BOPDS_DS.hxx | 14 +++-- src/BOPTools/BOPTools_AlgoTools.cxx | 12 ++-- tests/bugs/modalg_6/bug26938_1 | 6 +- tests/bugs/modalg_6/bug26938_2 | 5 +- tests/bugs/modalg_6/bug26938_3 | 8 ++- tests/bugs/modalg_6/bug26938_4 | 5 ++ tests/bugs/modalg_7/bug29179 | 50 +++++++++++++++++ 10 files changed, 174 insertions(+), 93 deletions(-) create mode 100644 tests/bugs/modalg_7/bug29179 diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.hxx b/src/BOPAlgo/BOPAlgo_PaveFiller.hxx index 3eb8b817ae..6bde207118 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.hxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.hxx @@ -254,15 +254,16 @@ protected: Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP, const Standard_Real theTol, const TColStd_MapOfInteger& theMVOn) const; - //! Checks and puts paves from on the curve . - Standard_EXPORT void PutPavesOnCurve (const TColStd_MapOfInteger& theMVOn, - BOPDS_Curve& theNC, - const Standard_Integer nF1, - const Standard_Integer nF2, - const TColStd_MapOfInteger& theMI, - const TColStd_MapOfInteger& theMVEF, - TColStd_DataMapOfIntegerReal& theMVTol, - TColStd_DataMapOfIntegerListOfInteger& aDMVLV); + //! Checks and puts paves from on the curve . + //! At that, common (from theMVCommon) and not common vertices + //! are processed differently. + Standard_EXPORT void PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn, + const TColStd_MapOfInteger& theMVCommon, + BOPDS_Curve& theNC, + const TColStd_MapOfInteger& theMI, + const TColStd_MapOfInteger& theMVEF, + TColStd_DataMapOfIntegerReal& theMVTol, + TColStd_DataMapOfIntegerListOfInteger& theDMVLV); Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 654c9079a6..ce4e2b9286 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -391,7 +391,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() NCollection_BaseAllocator::CommonBaseAllocator(); // TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator); - TColStd_MapOfInteger aMVOnIn(100, aAllocator), + TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator), aMVStick(100,aAllocator), aMVEF(100, aAllocator), aMI(100, aAllocator), aMVBounds(100, aAllocator); BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator); @@ -432,13 +432,14 @@ void BOPAlgo_PaveFiller::MakeBlocks() BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2); // aMVOnIn.Clear(); + aMVCommon.Clear(); aMPBOnIn.Clear(); aMPBCommon.Clear(); aDMBV.Clear(); aMVTol.Clear(); aLSE.Clear(); // - myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon); + myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon); myDS->SharedEdges(nF1, nF2, aLSE, aAllocator); // Standard_Boolean bHasRealSectionEdge = Standard_False; @@ -470,7 +471,13 @@ void BOPAlgo_PaveFiller::MakeBlocks() // DEBt aNC.InitPaveBlock1(); // - PutPavesOnCurve(aMVOnIn, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV); + // In order to avoid problems connected with + // extending tolerance of vertex while putting + // (e.g. see "bugs modalg_6 bug26789_1" test case), + // all not-common vertices will be checked by + // BndBoxes before putting. For common-vertices, + // filtering by BndBoxes is not necessary. + PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV); } // if some E-F vertex was put on a curve due to large E-F intersection range, @@ -706,6 +713,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() aMVStick.Clear(); aMPBOnIn.Clear(); aMVOnIn.Clear(); + aMVCommon.Clear(); aDMExEdges.Clear(); aMI.Clear(); aDMNewSD.Clear(); @@ -1570,57 +1578,54 @@ void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1, //function : PutPavesOnCurve //purpose : //======================================================================= -void BOPAlgo_PaveFiller::PutPavesOnCurve - (const TColStd_MapOfInteger& aMVOnIn, - BOPDS_Curve& aNC, - const Standard_Integer nF1, - const Standard_Integer nF2, - const TColStd_MapOfInteger& aMI, - const TColStd_MapOfInteger& aMVEF, - TColStd_DataMapOfIntegerReal& aMVTol, - TColStd_DataMapOfIntegerListOfInteger& aDMVLV) +void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn, + const TColStd_MapOfInteger& theMVCommon, + BOPDS_Curve& theNC, + const TColStd_MapOfInteger& theMI, + const TColStd_MapOfInteger& theMVEF, + TColStd_DataMapOfIntegerReal& theMVTol, + TColStd_DataMapOfIntegerListOfInteger& theDMVLV) { - Standard_Boolean bInBothFaces; Standard_Integer nV; TColStd_MapIteratorOfMapOfInteger aIt; // - const Bnd_Box& aBoxC=aNC.Box(); - Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance()); + const Bnd_Box& aBoxC = theNC.Box(); + const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance()); // //Put EF vertices first - aIt.Initialize(aMVEF); - for (; aIt.More(); aIt.Next()) { - nV=aIt.Value(); - PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2); + aIt.Initialize(theMVEF); + for (; aIt.More(); aIt.Next()) + { + nV = aIt.Value(); + PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2); } + //Put all other vertices - aIt.Initialize(aMVOnIn); - for (; aIt.More(); aIt.Next()) { - nV=aIt.Value(); - if (aMVEF.Contains(nV)) { + aIt.Initialize(theMVOnIn); + for (; aIt.More(); aIt.Next()) + { + nV = aIt.Value(); + if (theMVEF.Contains(nV)) + { continue; } - // - const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV); - const Bnd_Box& aBoxV=aSIV.Box(); - // - if (aBoxC.IsOut(aBoxV)){ - continue; - } - if (!myDS->IsNewShape(nV)) { - const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1); - const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2); + + if (!theMVCommon.Contains(nV)) + { + const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV); + const Bnd_Box& aBoxV = aSIV.Box(); // - bInBothFaces = (aFI1.VerticesOn().Contains(nV) || - aFI1.VerticesIn().Contains(nV))&& - (aFI2.VerticesOn().Contains(nV) || - aFI2.VerticesIn().Contains(nV)); - if (!bInBothFaces) { + if (aBoxC.IsOut(aBoxV)) + { + continue; + } + if (!myDS->IsNewShape(nV)) + { continue; } } // - PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1); + PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1); } } diff --git a/src/BOPDS/BOPDS_DS.cxx b/src/BOPDS/BOPDS_DS.cxx index aeb49a0161..d7d3aa31b2 100644 --- a/src/BOPDS/BOPDS_DS.cxx +++ b/src/BOPDS/BOPDS_DS.cxx @@ -1453,56 +1453,71 @@ void BOPDS_DS::AloneVertices(const Standard_Integer theI, //function : VerticesOnIn //purpose : //======================================================================= -void BOPDS_DS::SubShapesOnIn - (const Standard_Integer nF1, - const Standard_Integer nF2, - TColStd_MapOfInteger& theMVOnIn, - BOPDS_IndexedMapOfPaveBlock& thePBOnIn, - BOPDS_MapOfPaveBlock& theCommonPB)const +void BOPDS_DS::SubShapesOnIn(const Standard_Integer theNF1, + const Standard_Integer theNF2, + TColStd_MapOfInteger& theMVOnIn, + TColStd_MapOfInteger& theMVCommon, + BOPDS_IndexedMapOfPaveBlock& thePBOnIn, + BOPDS_MapOfPaveBlock& theCommonPB)const { Standard_Integer i, j, nV, nV1, nV2, aNbPB; TColStd_MapIteratorOfMapOfInteger aIt; BOPDS_IndexedMapOfPaveBlock pMPB[4]; // - const BOPDS_FaceInfo& aFI1=FaceInfo(nF1); - const BOPDS_FaceInfo& aFI2=FaceInfo(nF2); + const BOPDS_FaceInfo& aFI1 = FaceInfo(theNF1); + const BOPDS_FaceInfo& aFI2 = FaceInfo(theNF2); // - pMPB[0]=aFI1.PaveBlocksOn(); - pMPB[1]=aFI1.PaveBlocksIn(); - pMPB[2]=aFI2.PaveBlocksOn(); - pMPB[3]=aFI2.PaveBlocksIn(); + pMPB[0] = aFI1.PaveBlocksOn(); + pMPB[1] = aFI1.PaveBlocksIn(); + pMPB[2] = aFI2.PaveBlocksOn(); + pMPB[3] = aFI2.PaveBlocksIn(); // - for (i=0; i<4; ++i) { + for (i = 0; i < 4; ++i) + { aNbPB = pMPB[i].Extent(); - for (j = 1; j <= aNbPB; ++j) { + for (j = 1; j <= aNbPB; ++j) + { const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j); thePBOnIn.Add(aPB); aPB->Indices(nV1, nV2); + theMVOnIn.Add(nV1); theMVOnIn.Add(nV2); - if (i < 2) { + + if (i < 2) + { if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB)) + { theCommonPB.Add(aPB); + theMVCommon.Add(nV1); + theMVCommon.Add(nV2); + } } } } // - const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn(); - const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn(); - const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn(); - const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn(); + const TColStd_MapOfInteger& aMVOn1 = aFI1.VerticesOn(); + const TColStd_MapOfInteger& aMVIn1 = aFI1.VerticesIn(); + const TColStd_MapOfInteger& aMVOn2 = aFI2.VerticesOn(); + const TColStd_MapOfInteger& aMVIn2 = aFI2.VerticesIn(); // - for (i=0; i<2; ++i) { - const TColStd_MapOfInteger& aMV1=(!i) ? aMVOn1 : aMVIn1; + for (i = 0; i < 2; ++i) + { + const TColStd_MapOfInteger& aMV1 = (!i) ? aMVOn1 : aMVIn1; aIt.Initialize(aMV1); - for (; aIt.More(); aIt.Next()) { - nV=aIt.Value(); - if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) { + for (; aIt.More(); aIt.Next()) + { + nV = aIt.Value(); + if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) + { theMVOnIn.Add(nV); + + // Vertex taken from the 1st face is in the 2nd one. + theMVCommon.Add(nV); } } } -} +} //======================================================================= //function : SharedEdges //purpose : diff --git a/src/BOPDS/BOPDS_DS.hxx b/src/BOPDS/BOPDS_DS.hxx index 3dbea3e780..2201d5f499 100644 --- a/src/BOPDS/BOPDS_DS.hxx +++ b/src/BOPDS/BOPDS_DS.hxx @@ -304,15 +304,17 @@ Standard_EXPORT virtual ~BOPDS_DS(); Standard_EXPORT void RefineFaceInfoOn(); - //! Returns information about ON/IN subshapes of the given faces. + //! Returns information about ON/IN sub-shapes of the given faces. //! @param theMVOnIn the indices of ON/IN vertices from both faces + //! @param theMVCommon the indices of common vertices for both faces //! @param thePBOnIn all On/In pave blocks from both faces //! @param theCommonPB the common pave blocks (that are shared by both faces). - Standard_EXPORT void SubShapesOnIn (const Standard_Integer theF1, - const Standard_Integer theF2, - TColStd_MapOfInteger& theMVOnIn, - BOPDS_IndexedMapOfPaveBlock& thePBOnIn, - BOPDS_MapOfPaveBlock& theCommonPB) const; + Standard_EXPORT void SubShapesOnIn(const Standard_Integer theNF1, + const Standard_Integer theNF2, + TColStd_MapOfInteger& theMVOnIn, + TColStd_MapOfInteger& theMVCommon, + BOPDS_IndexedMapOfPaveBlock& thePBOnIn, + BOPDS_MapOfPaveBlock& theCommonPB) const; //! Returns the indices of edges that are shared diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index d6b743288f..b971decf90 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -645,10 +645,14 @@ TopAbs_State BOPTools_AlgoTools::ComputeState } // !!<- process edges that are all on theRef if (!aE1.IsNull()) { - BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, - aP2D, aP3D, theContext); - aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, - theContext); + const Standard_Integer anErrID = BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, + aP2D, aP3D, + theContext); + if(anErrID == 0) + { + aState = BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, + theContext); + } } // return aState; diff --git a/tests/bugs/modalg_6/bug26938_1 b/tests/bugs/modalg_6/bug26938_1 index b4c23234ed..e6f8ea31eb 100644 --- a/tests/bugs/modalg_6/bug26938_1 +++ b/tests/bugs/modalg_6/bug26938_1 @@ -1,7 +1,3 @@ -puts "TODO OCC28802 Linux: Faulty shapes in variables faulty_1 to" -puts "TODO OCC28802 Linux: Error : The area of result shape is" -puts "TODO OCC28802 Linux: Error : The result of General Fuse operation is self-interfered shape" - puts "==========" puts "OCC26938 " puts "==========" @@ -27,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } { puts "Error : The result of General Fuse operation is self-interfered shape" } +checknbshapes result -solid 1 -shell 1 -t -m "Result" + checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug26938_2 b/tests/bugs/modalg_6/bug26938_2 index fb528374e8..bf138833d4 100644 --- a/tests/bugs/modalg_6/bug26938_2 +++ b/tests/bugs/modalg_6/bug26938_2 @@ -1,6 +1,3 @@ -puts "TODO OCC28802 Linux: Error : The command is not valid. The area is 0" -puts "TODO OCC28802 Linux: Error : The area of result shape is 0" - puts "==========" puts "OCC26938 " puts "==========" @@ -26,4 +23,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } { puts "Error : The result of General Fuse operation is self-interfered shape" } +checknbshapes result -solid 1 -shell 1 -t -m "Result" + checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug26938_3 b/tests/bugs/modalg_6/bug26938_3 index da850d7b36..42ced6af77 100644 --- a/tests/bugs/modalg_6/bug26938_3 +++ b/tests/bugs/modalg_6/bug26938_3 @@ -1,6 +1,6 @@ -puts "TODO OCC28802 Linux: Error : The area of result shape is" -puts "TODO OCC24694 Windows: Error : The result of cut operation is self-interfered shape" - +puts "TODO OCC24694 All: Error : The result of cut operation is self-interfered shape" +puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2" +puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2" puts "==========" puts "OCC26938 " puts "==========" @@ -26,4 +26,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } { puts "Error : The result of cut operation is self-interfered shape" } +checknbshapes result -solid 3 -shell 3 -t -m "Result" + checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug26938_4 b/tests/bugs/modalg_6/bug26938_4 index 83ce69c49f..2ac00095dc 100644 --- a/tests/bugs/modalg_6/bug26938_4 +++ b/tests/bugs/modalg_6/bug26938_4 @@ -1,4 +1,7 @@ puts "TODO OCC24694 ALL: Error : The result of cut operation is self-interfered shape" +puts "TODO OCC24694 ALL: Result is WRONG because number of SHELL entities in shape \"result\" is 2" +puts "TODO OCC24694 ALL: Result is WRONG because number of SOLID entities in shape \"result\" is 2" + puts "==========" puts "OCC26938 " puts "==========" @@ -24,4 +27,6 @@ if { [regexp "This shape seems to be OK" ${info}] != 1 } { puts "Error : The result of cut operation is self-interfered shape" } +checknbshapes result -solid 3 -shell 3 -t -m "Result" + checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_7/bug29179 b/tests/bugs/modalg_7/bug29179 new file mode 100644 index 0000000000..251a4f42da --- /dev/null +++ b/tests/bugs/modalg_7/bug29179 @@ -0,0 +1,50 @@ +puts "========" +puts "OCC29179" +puts "========" +puts "" +################################################# +# Result of Boolean common depends on an order of arguments +################################################# + +restore [locate_data_file bug26938.brep] a +explode a + +bcommon res1 a_1 a_2 + +restore [locate_data_file bug26938.brep] a +explode a + +bcommon res2 a_2 a_1 + +checkview -display res1 -2d -path ${imagedir}/${test_image}_1.png +checkview -display res2 -2d -path ${imagedir}/${test_image}_2.png + +checkshape res1 +checkshape res2 + +if {[regexp "Faulties" [bopargcheck res1]]} { + puts "Error: bopargcheck has found some faulties in res1" +} + +if {[regexp "Faulties" [bopargcheck res2]]} { + puts "Error: bopargcheck has found some faulties in res2" +} + +checkprops res1 -v 4.93528e+008 +checkprops res2 -v 4.93528e+008 + +set nbshapes_expected " +Number of shapes in .* + VERTEX : 5 + EDGE : 7 + WIRE : 4 + FACE : 4 + SHELL : 1 + SOLID : 1 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 23 +" + +checknbshapes res1 -ref ${nbshapes_expected} -t -m "1st COMMON" +checknbshapes res2 -ref ${nbshapes_expected} -t -m "2nd COMMON"