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); } } } } } - // try to reduce tolerances of connected vertices + // + 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; + } + } + } + } + } + // + // 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