From 5be33fb66755d98e1b549f33da4b6cf5a9e058fa Mon Sep 17 00:00:00 2001 From: emv Date: Thu, 17 Mar 2016 17:10:11 +0300 Subject: [PATCH] 0027274: Regression vs 6.9.1: Wrong result of General Fuse operation on two cylinders When reducing the tolerance values of the vertices put on section curves take into account all section curves, not only those for which the tolerance have been reduced (method void BOPAlgo_PaveFiller::CorrectToleranceOfSE()). The new protection has been added to avoid reducing of tolerance values of vertices to the values less than the tolerance values of edges containing these vertices. Adjusting of test case bugs/modalg_5/bug25232_9 --- src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx | 118 ++++++++++++++++++++------- tests/bugs/modalg_5/bug25232_9 | 3 - tests/bugs/modalg_6/bug27274 | 36 ++++++++ 3 files changed, 125 insertions(+), 32 deletions(-) create mode 100644 tests/bugs/modalg_6/bug27274 diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index bc973bddd3..49e5ea237d 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -2517,57 +2517,117 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE() { BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF(); NCollection_IndexedDataMap aMVIPBs; + BOPCol_MapOfInteger aMVIToReduce; // - // iterate on all sections F-F + // 1. iterate on all sections F-F Standard_Integer aNb = aFFs.Extent(), i; for (i = 0; i < aNb; ++i) { const BOPDS_InterfFF& aFF = aFFs(i); Standard_Real aTolR3D = aFF.TolR3D(); Standard_Real aTolReal = aFF.TolReal(); - if (aTolReal < aTolR3D) { - // tolerance of intersection has been increased, so process this intersection - const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); - Standard_Integer aNbC = aVNC.Extent(), k; - for (k = 0; k < aNbC; ++k) { - const BOPDS_Curve& aNC = aVNC(k); - const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); - BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); - for (; aItLPB.More(); aItLPB.Next()) { - const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); - Standard_Integer nE; - if (!aPB->HasEdge(nE) || aPB->OriginalEdge() >= 0) { - continue; - } + Standard_Boolean bToReduce = aTolReal < aTolR3D; + // tolerance of intersection has been increased, so process this intersection + const BOPDS_VectorOfCurve& aVNC = aFF.Curves(); + Standard_Integer aNbC = aVNC.Extent(), k; + for (k = 0; k < aNbC; ++k) { + const BOPDS_Curve& aNC = aVNC(k); + const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks(); + BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); + for (; aItLPB.More(); aItLPB.Next()) { + const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); + Standard_Integer nE; + if (!aPB->HasEdge(nE)) { + continue; + } + // + Standard_Boolean bIsReduced = Standard_False; + if (bToReduce && (aPB->OriginalEdge() < 0)) { const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); Standard_Real aTolE = BRep_Tool::Tolerance(aE); if (aTolReal < aTolE) { // reduce edge tolerance reinterpret_cast(aE.TShape().operator->())->Tolerance(aTolReal); + bIsReduced = Standard_True; } - - // fill in the map vertex index - pave blocks - Handle(BOPDS_PaveBlock) aPBR = myDS->RealPaveBlock(aPB); - for (Standard_Integer j=0; j < 2; j++) { - Standard_Integer nV = (j == 0 ? aPBR->Pave1().Index() : aPBR->Pave2().Index()); - BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV); - if (!pPBList) { - pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock())); - } - pPBList->Append(aPBR); + } + // + // fill in the map vertex index - pave blocks + for (Standard_Integer j=0; j < 2; j++) { + Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index()); + BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV); + if (!pPBList) { + pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock())); + } + pPBList->Append(aPB); + if (bIsReduced) { + aMVIToReduce.Add(nV); + } + } + } + } + } + // + if (aMVIToReduce.IsEmpty()) { + return; + } + // + // 2. try to reduce tolerances of connected vertices + // 2.1 find all other edges containing these connected vertices to avoid + // reducing the tolerance to the value less than the tolerances of edges, + // i.e. minimal tolerance for the vertex is the max tolerance of the + // edges containing this vertex + BOPCol_DataMapOfIntegerReal aMVITol; + BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool(); + aNb = aPBP.Extent(); + for (i = 0; i < aNb; ++i) { + const BOPDS_ListOfPaveBlock& aLPB = aPBP(i); + BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); + for (; aItLPB.More(); aItLPB.Next()) { + const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); + Standard_Integer nE; + if (!aPB->HasEdge(nE)) { + continue; + } + const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); + Standard_Real aTolE = BRep_Tool::Tolerance(aE); + // + Standard_Integer nV[2]; + aPB->Indices(nV[0], nV[1]); + // + for (Standard_Integer j = 0; j < 2; j++) { + if (aMVIToReduce.Contains(nV[j])) { + Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]); + if (!aMaxTol) { + aMVITol.Bind(nV[j], aTolE); + } + else if (aTolE > *aMaxTol) { + *aMaxTol = aTolE; } } } } } - // try to reduce tolerances of connected vertices + // + // 2.2 reduce tolerances if possible aNb = aMVIPBs.Extent(); for (i = 1; i <= aNb; ++i) { Standard_Integer nV = aMVIPBs.FindKey(i); + if (!aMVIToReduce.Contains(nV)) { + continue; + } + // const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV)); - gp_Pnt aP = BRep_Tool::Pnt(aV); + Standard_Real aTolV = BRep_Tool::Tolerance(aV); + Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.; + // it makes no sense to compute the real tolerance if it is + // impossible to reduce the tolerance at least 0.1% of the current value + if (aTolV - aMaxTol < 0.001 * aTolV) { + continue; + } // // compute the maximal distance from the vertex to the adjacent edges - Standard_Real aMaxTol = 0.; + gp_Pnt aP = BRep_Tool::Pnt(aV); + // const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i); BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); for (; aItLPB.More(); aItLPB.Next()) { @@ -2583,7 +2643,7 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE() aMaxTol = aDist; } } - Standard_Real aTolV = BRep_Tool::Tolerance(aV); + // if (aMaxTol < aTolV) { reinterpret_cast(aV.TShape().operator->())->Tolerance(aMaxTol); } diff --git a/tests/bugs/modalg_5/bug25232_9 b/tests/bugs/modalg_5/bug25232_9 index b900b2a905..607bde307a 100644 --- a/tests/bugs/modalg_5/bug25232_9 +++ b/tests/bugs/modalg_5/bug25232_9 @@ -1,6 +1,3 @@ -puts "TODO OCC27014 ALL: Faulty shapes in variables faulty_1 to" -puts "TODO OCC27014 ALL: Error : is WRONG because number of .* entities in shape .* is" - puts "============" puts "OCC25232" puts "============" diff --git a/tests/bugs/modalg_6/bug27274 b/tests/bugs/modalg_6/bug27274 new file mode 100644 index 0000000000..1900358afd --- /dev/null +++ b/tests/bugs/modalg_6/bug27274 @@ -0,0 +1,36 @@ +puts "============" +puts "OCC27274" +puts "============" +puts "" +####################################################################### +# Wrong result of General Fuse operation on two cylinders +####################################################################### + +pcylinder b1 50 145 +tcopy b1 b2 +trotate b2 0 0 0 1 0 0 45 + +bclearobjects +bcleartools +baddobjects b1 +baddtools b2 +bfillds +bbuild result + +checkshape result + +set nbshapes_expected " + VERTEX : 5 + EDGE : 11 + WIRE : 10 + FACE : 10 + SHELL : 3 + SOLID : 3 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 43 +" + +checknbshapes result -ref ${nbshapes_expected} -t + +checkprops result -s 154518 \ No newline at end of file -- 2.20.1