diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx index 13ec495cf2..1c9975ac73 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx @@ -225,6 +225,14 @@ void BOPAlgo_PaveFiller::IntersectVE const Handle(BOPDS_PaveBlock)& aPB = theVEPairs.FindKey(i); Standard_Integer nE = aPB->OriginalEdge(); // + TColStd_MapOfInteger aMVPB; + const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE); + for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next()) + { + aMVPB.Add (itPB.Value()->Pave1().Index()); + aMVPB.Add (itPB.Value()->Pave2().Index()); + } + const TColStd_ListOfInteger& aLV = theVEPairs(i); TColStd_ListIteratorOfListOfInteger aItLV(aLV); for (; aItLV.More(); aItLV.Next()) { @@ -233,6 +241,9 @@ void BOPAlgo_PaveFiller::IntersectVE Standard_Integer nVSD = nV; myDS->HasShapeSD(nV, nVSD); // + if (aMVPB.Contains (nVSD)) + continue; + BOPDS_Pair aPair(nVSD, nE); TColStd_ListOfInteger* pLI = aDMVSD.ChangeSeek(aPair); if (pLI) { @@ -287,7 +298,21 @@ void BOPAlgo_PaveFiller::IntersectVE Standard_Integer nVx = UpdateVertex(nV, aTolVNew); // 2. Create new pave and add it as extra pave to pave block // for further splitting of the edge - const Handle(BOPDS_PaveBlock)& aPB = aVESolver.PaveBlock(); + const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks (nE); + // Find the appropriate one + Handle(BOPDS_PaveBlock) aPB; + BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); + for (; itPB.More(); itPB.Next()) + { + aPB = itPB.Value(); + Standard_Real aT1, aT2; + aPB->Range (aT1, aT2); + if (aT > aT1 && aT < aT2) + break; + } + if (!itPB.More()) + continue; + BOPDS_Pave aPave; aPave.SetIndex(nVx); aPave.SetParameter(aT); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 5dc2772d12..044bbc83f0 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -2414,7 +2414,7 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve Standard_Integer nVUsed; Standard_Real aPTol, aDTol; // - aDTol = 1.e-12; + aDTol = BOPTools_AlgoTools::DTolerance(); // GeomAdaptor_Curve aGAC(aIC.Curve()); aPTol = aGAC.Resolution(Max(aTolR3D, aTolV)); @@ -2459,7 +2459,8 @@ void BOPAlgo_PaveFiller::PutPaveOnCurve aTolV = BRep_Tool::Tolerance(aV); gp_Pnt aP2 = BRep_Tool::Pnt(aV); Standard_Real aDist = aP1.Distance(aP2); - if (aDist > aTolV) { + if (aTolV < aDist + aDTol) + { BRep_Builder().UpdateVertex(aV, aDist + aDTol); // if (!aMVTol.IsBound(nV)) { @@ -2831,7 +2832,7 @@ void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC) if (aDistVP > aTolV) { - Standard_Integer nVn = UpdateVertex(nV, aDistVP); + Standard_Integer nVn = UpdateVertex(nV, aDistVP + BOPTools_AlgoTools::DTolerance()); if (nVn != nV) { aPave.SetIndex(nVn); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx index dbbb975233..0b299eebc6 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx @@ -784,7 +784,7 @@ void UpdateVertices(const TopoDS_Edge& aE, aD2=aP3D.SquareDistance(aP3Dx); if (aD2>aTolV2) { aD=sqrt(aD2); - aBB.UpdateVertex(aV[j], aD); + aBB.UpdateVertex(aV[j], aD + BOPTools_AlgoTools::DTolerance()); } } } diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index a2724dfca6..3a037f4761 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -1636,7 +1636,7 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC, TopoDS_Edge& theE) { BRep_Builder aBB; - Standard_Real aNeedTol = theTolR3D + 1e-12; + Standard_Real aNeedTol = theTolR3D + BOPTools_AlgoTools::DTolerance(); // aBB.UpdateVertex(theV1, aNeedTol); aBB.UpdateVertex(theV2, aNeedTol); diff --git a/src/BOPTools/BOPTools_AlgoTools.hxx b/src/BOPTools/BOPTools_AlgoTools.hxx index 77ad5e927e..4b83f42683 100644 --- a/src/BOPTools/BOPTools_AlgoTools.hxx +++ b/src/BOPTools/BOPTools_AlgoTools.hxx @@ -61,6 +61,15 @@ public: DEFINE_STANDARD_ALLOC +public: //! @name Constants + + //! Additional tolerance (delta tolerance) is used in Boolean Operations + //! to ensure that the tolerance of new/old entities obtained + //! by intersection of two shapes is slightly bigger than the actual + //! distances to these shapes. It helps to avoid numerical instability + //! which may occur when comparing distances and tolerances. + static Standard_Real DTolerance() { return 1.e-12; } + public: //! @name Intersection of the vertices //! Intersects the vertex with the point with tolerance . diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx index 6b92221f4a..78e1a5e386 100644 --- a/src/BOPTools/BOPTools_AlgoTools_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx @@ -823,7 +823,7 @@ void CorrectEdgeTolerance (const TopoDS_Edge& myShape, Standard_Boolean SameRange = TE->SameRange(); Standard_Real First = myHCurve->FirstParameter(); Standard_Real Last = myHCurve->LastParameter(); - Standard_Real Delta =1.e-12; + Standard_Real Delta = BOPTools_AlgoTools::DTolerance(); Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); const TopLoc_Location& Floc = S.Location(); diff --git a/src/BOPTools/BOPTools_AlgoTools_2.cxx b/src/BOPTools/BOPTools_AlgoTools_2.cxx index 4fd77e5012..d1b30637f3 100644 --- a/src/BOPTools/BOPTools_AlgoTools_2.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_2.cxx @@ -42,7 +42,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Vertex& aVF, const TopoDS_Vertex& aNewVertex) { - Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol; + Standard_Real aTolVF, aTolNewVertex, aDist, aNewTol; // gp_Pnt aPVF=BRep_Tool::Pnt(aVF); gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex); @@ -54,7 +54,7 @@ void BOPTools_AlgoTools::UpdateVertex if (aNewTol>aTolVF) { BRep_Builder BB; - BB.UpdateVertex (aVF, aNewTol+aDTol); + BB.UpdateVertex (aVF, aNewTol + BOPTools_AlgoTools::DTolerance()); } } @@ -66,7 +66,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE, const Standard_Real aT, const TopoDS_Vertex& aV) { - Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast; + Standard_Real aTolV, aDist, aFirst, aLast; gp_Pnt aPc; gp_Pnt aPv=BRep_Tool::Pnt(aV); @@ -77,7 +77,7 @@ void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE, aDist=aPv.Distance(aPc); if (aDist>aTolV) { BRep_Builder BB; - BB.UpdateVertex (aV, aDist+aDTol); + BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance()); } } // @@ -89,7 +89,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC, const Standard_Real aT, const TopoDS_Vertex& aV) { - Standard_Real aTolV, aDist, aDTol=1.e-12; + Standard_Real aTolV, aDist; gp_Pnt aPc; gp_Pnt aPv=BRep_Tool::Pnt(aV); @@ -100,7 +100,7 @@ void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC, aDist=aPv.Distance(aPc); if (aDist>aTolV) { BRep_Builder BB; - BB.UpdateVertex (aV, aDist+aDTol); + BB.UpdateVertex (aV, aDist + BOPTools_AlgoTools::DTolerance()); } } //======================================================================= @@ -265,7 +265,7 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1, const TopoDS_Face& aF1, TopoDS_Vertex& aNewVertex) { - Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12; + Standard_Real aTol1, aTol2, aMaxTol; gp_Pnt aPnt; PointOnEdge (aE1, aParm1, aPnt); @@ -273,8 +273,7 @@ void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1, aTol1=BRep_Tool::Tolerance(aE1); aTol2=BRep_Tool::Tolerance(aF1); // - //aMaxTol=(aTol1>aTol2)? aTol1 : aTol2; - aMaxTol=aTol1+aTol2+delta; + aMaxTol = aTol1 + aTol2 + BOPTools_AlgoTools::DTolerance(); // BRep_Builder aBB; aBB.MakeVertex (aNewVertex, aPnt, aMaxTol); diff --git a/tests/bugs/modalg_7/bug31462 b/tests/bugs/modalg_7/bug31462 new file mode 100644 index 0000000000..5588be6d82 --- /dev/null +++ b/tests/bugs/modalg_7/bug31462 @@ -0,0 +1,44 @@ +puts "========" +puts "0031462: Modeling Algorithms - BOP result depends on the arguments order" +puts "========" +puts "" + +restore [locate_data_file bug31462_obj.brep] s1 +restore [locate_data_file bug31462_tools.brep] s2 + +tcopy s1 obj +tcopy s2 sx +bclearobjects +bcleartools +baddobjects obj +eval baddtools [explode sx] +bfillds +bsplit result1 + +checkshape result1 +if {![regexp "This shape seems to be OK" [bopcheck result1]]} { + puts "Error: self-interfering result" +} + +checknbshapes result1 -wire 19 -face 18 -shell 3 -solid 2 +checkprops result1 -s 103.955 -v 38.7982 + +tcopy s1 obj +tcopy s2 sx +bclearobjects +bcleartools +baddobjects obj +explode sx +baddtools sx_4 sx_5 sx_6 sx_3 sx_2 sx_1 +bfillds +bsplit result2 + +checkshape result2 +if {![regexp "This shape seems to be OK" [bopcheck result2]]} { + puts "Error: self-interfering result" +} + +checknbshapes result2 -ref [nbshapes result1] +checkprops result2 -equal result1 + +checkview -display result1 -2d -path ${imagedir}/${test_image}.png diff --git a/tests/evolved/voluved/HMC008 b/tests/evolved/voluved/HMC008 index aa0f6987d7..63c57b5117 100644 --- a/tests/evolved/voluved/HMC008 +++ b/tests/evolved/voluved/HMC008 @@ -4,13 +4,6 @@ puts "==========" cpulimit 100 -puts "TODO OCC30438 ALL: Error : The area of result shape is" -puts "TODO OCC30438 ALL: Error : The volume of result shape is" -puts "TODO OCC30438 ALL: Error : is WRONG because number of SHELL" -puts "TODO OCC30438 ALL: Error : is WRONG because number of SOLID" -puts "TODO OCC30438 ALL: Error: bopargcheck has found some faulties in result" - - restore [locate_data_file bug29523_cut_extrudewire07.brep] sw restore [locate_data_file bug29523_cut_toolwire07.brep] tw @@ -219,7 +212,7 @@ if {[regexp "Faulties" [bopargcheck result]]} { # the dimensions of the shape "result" are about 1.0e+5. # So, this tolerance seems to be OK. -checkmaxtol result -ref 18.634531507134731 +checkmaxtol result -ref 1.7319951447770465 smallview don result sw tw