From 787c4320b1f35b0bec9b5ef1996a1febfe014b5c Mon Sep 17 00:00:00 2001 From: emv Date: Wed, 29 Jul 2015 15:24:03 +0300 Subject: [PATCH] 0026444: Boolean operation "bcut" gives invalid result between solid and halfspace solid. class BOPAlgo_PaveFiller method void BOPAlgo_PaveFiller::PutPaveOnCurve (const Standard_Integer nV, const Standard_Real aTolR3D, BOPDS_Curve& aNC, const BOPCol_MapOfInteger& aMI, BOPCol_DataMapOfIntegerReal& aMVTol, const Standard_Integer iCheckExtend) Do not put the pave on the curve in case if there is already one with the same parameter. Update tolerance of the existing vertex to reach the new one. Added test case bugs/modalg_6/bug26444. Test boolean/volumemaker/G1 is stable now (deleted TODOs), test offset/faces_type_i/C9 is bad (offset is done with wrong result). --- src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx | 73 +++++++++++++++++++--------- src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx | 4 +- src/BOPDS/BOPDS_PaveBlock.cxx | 16 +++--- src/BOPDS/BOPDS_PaveBlock.hxx | 19 ++++++-- tests/boolean/volumemaker/G1 | 3 -- tests/bugs/modalg_6/bug26444 | 17 +++++++ tests/offset/faces_type_i/C9 | 4 +- 7 files changed, 93 insertions(+), 43 deletions(-) create mode 100644 tests/bugs/modalg_6/bug26444 diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index afbfeedb2f..7097c7c7d6 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -1725,41 +1725,70 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC, const Standard_Integer iCheckExtend) { Standard_Boolean bIsVertexOnLine; - Standard_Real aT, aTol, aTolNew; - BOPDS_Pave aPave; + Standard_Real aT, aTolV; // - const TopoDS_Vertex aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); + const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1(); const IntTools_Curve& aIC = aNC.Curve(); // bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT); if (!bIsVertexOnLine && iCheckExtend) { - aTol = BRep_Tool::Tolerance(aV); + aTolV = BRep_Tool::Tolerance(aV); // - ExtendedTolerance(nV, aMI, aTol, iCheckExtend); - bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTol, aIC, aTolR3D, aT); + ExtendedTolerance(nV, aMI, aTolV, iCheckExtend); + bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D, aT); } // if (bIsVertexOnLine) { - aPave.SetIndex(nV); - aPave.SetParameter(aT); + // check if aPB contains the parameter aT + Standard_Boolean bExist; + Standard_Integer nVToUpdate; + Standard_Real aPTol, aDist, aTolVNew, aTolV2, aDTol; + TopoDS_Vertex aVToUpdate; + gp_Pnt aP1, aP2; // - aPB->AppendExtPave(aPave); + aTolV2 = 0.; + aDTol = 1.e-12; // - aTol = BRep_Tool::Tolerance(aV); + GeomAdaptor_Curve aGAC(aIC.Curve()); + aPTol = aGAC.Resolution(aTolR3D); // - BOPTools_AlgoTools::UpdateVertex (aIC, aT, aV); - // - if (!aMVTol.IsBound(nV)) { - aTolNew = BRep_Tool::Tolerance(aV); - if (aTolNew > aTol) { - aMVTol.Bind(nV, aTol); - } + bExist = aPB->ContainsParameter(aT, aPTol, nVToUpdate); + if (bExist) { + // use existing pave + aP1 = BRep_Tool::Pnt(aV); + aTolV2 = BRep_Tool::Tolerance(aV); + aVToUpdate = (*(TopoDS_Vertex *)(&myDS->Shape(nVToUpdate))); + } + else { + // add new pave + BOPDS_Pave aPave; + aPave.SetIndex(nV); + aPave.SetParameter(aT); + aPB->AppendExtPave(aPave); + // + aP1 = aGAC.Value(aT); + nVToUpdate = nV; + aVToUpdate = aV; + } + // + aTolV = BRep_Tool::Tolerance(aVToUpdate); + aP2 = BRep_Tool::Pnt(aVToUpdate); + aDist = aP1.Distance(aP2); + aTolVNew = aDist - aTolV2; + // + if (aTolVNew > aTolV) { + BRep_Builder aBB; + aBB.UpdateVertex(aVToUpdate, aTolVNew+aDTol); + // + if (!aMVTol.IsBound(nVToUpdate)) { + aMVTol.Bind(nVToUpdate, aTolV); + } + // + BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVToUpdate); + Bnd_Box& aBoxDS=aSIDS.ChangeBox(); + BRepBndLib::Add(aVToUpdate, aBoxDS); } - // - BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); - Bnd_Box& aBoxDS=aSIDS.ChangeBox(); - BRepBndLib::Add(aV, aBoxDS); } } @@ -2179,7 +2208,7 @@ void BOPAlgo_PaveFiller::UpdatePaveBlocks } // if (bRebuild) { - nSp = SplitEdge(aPB->Edge(), nV[0], aT[0], nV[1], aT[1]); + nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]); if (bCB) { aCB->SetEdge(nSp); } diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx index 2e967df6f0..1638690b7d 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx @@ -239,7 +239,7 @@ static const Handle(BOPDS_PaveBlock)& aPBD) { Standard_Boolean bXDir, bIsDone; - Standard_Integer nE, aNbPoints, j; + Standard_Integer nE, aNbPoints, j, anInd; Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT; Standard_Real aTolCmp; gp_Pnt2d aP2d1, aP2d2, aP2D; @@ -324,7 +324,7 @@ static continue; } // - if (aPBD->ContainsParameter(aX, aDT)) { + if (aPBD->ContainsParameter(aX, aDT, anInd)) { continue; } aPave.SetParameter(aX); diff --git a/src/BOPDS/BOPDS_PaveBlock.cxx b/src/BOPDS/BOPDS_PaveBlock.cxx index a5175f7efb..c8fd2cfe4d 100755 --- a/src/BOPDS/BOPDS_PaveBlock.cxx +++ b/src/BOPDS/BOPDS_PaveBlock.cxx @@ -236,21 +236,19 @@ //purpose : //======================================================================= Standard_Boolean BOPDS_PaveBlock::ContainsParameter(const Standard_Real theT, - const Standard_Real theTol)const + const Standard_Real theTol, + Standard_Integer& theInd) const { Standard_Boolean bRet; - Standard_Real dT; BOPDS_ListIteratorOfListOfPave aIt; // - bRet=Standard_False; + bRet = Standard_False; aIt.Initialize(myExtPaves); for (; aIt.More(); aIt.Next()) { - dT=aIt.Value().Parameter()-theT; - if (dT<0.) { - dT=-dT; - } - if (dT //! of the pave block - Standard_EXPORT void Indices (Standard_Integer& theIndex1, Standard_Integer& theIndex2) const; + Standard_EXPORT void Indices (Standard_Integer& theIndex1, + Standard_Integer& theIndex2) const; //! Query @@ -162,28 +163,36 @@ public: //! to create new pave blocks . //! - if true, the first pave and the second //! pave are used to produce new pave blocks. - Standard_EXPORT void Update (BOPDS_ListOfPaveBlock& theLPB, const Standard_Boolean theFlag = Standard_True); + Standard_EXPORT void Update (BOPDS_ListOfPaveBlock& theLPB, + const Standard_Boolean theFlag = Standard_True); //! Query //! Returns true if the extra paves contain the pave //! with given value of the parameter //! - the value of the tolerance to compare - Standard_EXPORT Standard_Boolean ContainsParameter (const Standard_Real thePrm, const Standard_Real theTol) const; + //! - index of the found pave + Standard_EXPORT Standard_Boolean ContainsParameter (const Standard_Real thePrm, + const Standard_Real theTol, + Standard_Integer& theInd) const; //! Modifier //! Sets the shrunk data for the pave block //! , - shrunk range //! - the bounding box - Standard_EXPORT void SetShrunkData (const Standard_Real theTS1, const Standard_Real theTS2, const Bnd_Box& theBox); + Standard_EXPORT void SetShrunkData (const Standard_Real theTS1, + const Standard_Real theTS2, + const Bnd_Box& theBox); //! Selector //! Returns the shrunk data for the pave block //! , - shrunk range //! - the bounding box - Standard_EXPORT void ShrunkData (Standard_Real& theTS1, Standard_Real& theTS2, Bnd_Box& theBox) const; + Standard_EXPORT void ShrunkData (Standard_Real& theTS1, + Standard_Real& theTS2, + Bnd_Box& theBox) const; //! Query diff --git a/tests/boolean/volumemaker/G1 b/tests/boolean/volumemaker/G1 index 8c59ae6013..d7be6d1778 100644 --- a/tests/boolean/volumemaker/G1 +++ b/tests/boolean/volumemaker/G1 @@ -2,9 +2,6 @@ # cone cylinder plane # Error status: 102 -puts "TODO OCC26020 ALL: Error status" -puts "TODO OCC26020 ALL: TEST INCOMPLETE" - # conical face cone con_f1 -59.814698440000001 384.36473473000001 127 0.41716766026590824 -0.90882954575006414 -5.4874902763032048e-016 89.995898744693349 0 erase con_f1 diff --git a/tests/bugs/modalg_6/bug26444 b/tests/bugs/modalg_6/bug26444 new file mode 100644 index 0000000000..c873f15bcf --- /dev/null +++ b/tests/bugs/modalg_6/bug26444 @@ -0,0 +1,17 @@ +puts "========" +puts "OCC26444" +puts "========" +puts "" +#################################################################################### +# Boolean operation "bcut" gives invalid result between solid and halfspace solid. +#################################################################################### + +restore [locate_data_file bug26444_cutting_shape.brep] a +restore [locate_data_file bug26444_shape_to_cut.brep] b +restore [locate_data_file bug26444_ref_out.brep] p2 +dump p2 +halfspace s1 a -0.541421905726473 0.200000002980232 0.00899999961256981 +bcut result b s1 + +set square 0.106547 +set 2dviewer 1 diff --git a/tests/offset/faces_type_i/C9 b/tests/offset/faces_type_i/C9 index 180f24236b..30efb80b06 100644 --- a/tests/offset/faces_type_i/C9 +++ b/tests/offset/faces_type_i/C9 @@ -1,5 +1,5 @@ -puts "TODO OCC23748 ALL: ERROR. offsetperform operation not done." -puts "TODO OCC23547 ALL: TEST INCOMPLETE" +puts "TODO OCC23748 ALL: Faulty shapes in variables faulty_1 to faulty_" +puts "TODO OCC23547 ALL: Error : The volume of the resulting shape is" psphere s 15 270 OFFSETSHAPE 1 {s_2} $calcul $type