From b4109929d6fe8fb1c86778bc57b3df86b37c063b Mon Sep 17 00:00:00 2001 From: emv Date: Thu, 26 Sep 2013 20:25:54 +0400 Subject: [PATCH] 0023958: Section of shell by plane is incomplete. Modifications 1 1. To avoid creation of micro edges in the class BOPAlgo_PaveFiller added two new functions ForceInterfVE and ForceInterfVF which updates tolerance of Vertex to make it interfere with Edge and Face accordingly. 2. In the class BOPInt_Tools added new function IsInRange which checks whether two ranges cross each other. 3. In the class BOPTools_AlgoTools added new function IntersectCurves2d which intersects pcurves of the face to check it on the self-interference. 4. In the function IntTools_BeanFaceIntersector::FastComputeExactIntersection() the check on the coincidence of the whole edge with the face (BOPTools_AlgoTools::IsBlockInOnFace) replaced with the check on the coincidence of one intermediate point with that face. 5. Test cases bugs modalg_1 bug1255, bug1255_1 has been updated with more correct value of the result. 6. TODO statement has been removed from the test cases boolean bcut_complex B1,B3,B5,C2,C4,C6,C8 as they are correct. Adding test case for issue CR23958 Modification 2 1. In class BOPAlgo_PaveFiller added new function CheckPlanes(nF1, nF2) that checks whether two planar faces have common or intersecting sub shapes. If these two faces do not have such sub shapes there is no need to intersect them. 2. In the function BOPAlgo_PaveFiller::MakeBlocks() added block for reducing the tolerance values to the previous state for the vertices that were put on the section curve (with increasing of its tolerance value) that was rejected by the algorithm. Modification 3 Back to Extrema_ExtAlgo_Grad algorithm in extrema computations in Boolean Operations algorithm. --- src/BOPAlgo/BOPAlgo_PaveFiller.cdl | 51 +++- src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx | 165 +++++++++++-- src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx | 139 +++++++---- src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx | 220 +++++++++++++++--- src/BOPCol/BOPCol.cdl | 1 + src/BOPCol/BOPCol_DataMapOfIntegerReal.hxx | 32 +++ src/BOPCol/FILES | 1 + src/BOPInt/BOPInt_Context.cxx | 2 +- src/BOPInt/BOPInt_ShrunkRange.cxx | 2 +- src/BOPInt/BOPInt_Tools.cdl | 74 +++--- src/BOPInt/BOPInt_Tools.cxx | 32 ++- src/BOPTools/BOPTools_AlgoTools_1.cxx | 103 ++++++-- src/IntTools/IntTools_BeanFaceIntersector.cxx | 35 +-- tests/boolean/bcut_complex/B1 | 4 +- tests/boolean/bcut_complex/B3 | 4 +- tests/boolean/bcut_complex/B5 | 4 +- tests/boolean/bcut_complex/C2 | 4 +- tests/boolean/bcut_complex/C4 | 4 +- tests/boolean/bcut_complex/C6 | 4 +- tests/boolean/bcut_complex/C8 | 4 +- tests/boolean/bcut_complex/N9 | 7 +- tests/bugs/modalg_1/bug1255 | 2 +- tests/bugs/modalg_1/bug1255_1 | 2 +- tests/bugs/modalg_4/bug62 | 7 +- tests/bugs/modalg_5/bug23958 | 29 +++ 25 files changed, 717 insertions(+), 215 deletions(-) create mode 100644 src/BOPCol/BOPCol_DataMapOfIntegerReal.hxx create mode 100644 tests/bugs/modalg_5/bug23958 diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.cdl b/src/BOPAlgo/BOPAlgo_PaveFiller.cdl index 4c2199e81a..a2dba8013a 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cdl +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cdl @@ -38,7 +38,8 @@ uses IndexedDataMapOfShapeInteger from BOPCol, DataMapOfIntegerListOfInteger from BOPCol, DataMapOfShapeListOfShape from BOPCol, - IndexedDataMapOfShapeListOfShape from BOPCol, + IndexedDataMapOfShapeListOfShape from BOPCol, + DataMapOfIntegerReal from BOPCol, -- Context from BOPInt, -- @@ -180,7 +181,8 @@ is theNC:out Curve from BOPDS; nF1:Integer from Standard; nF2:Integer from Standard; - theMVEF:MapOfInteger from BOPCol) + theMVEF:MapOfInteger from BOPCol; + theMVTol:out DataMapOfIntegerReal from BOPCol) is protected; ExtendedTolerance(me:out; @@ -255,14 +257,16 @@ is nF1 : Integer from Standard; nF2 : Integer from Standard; theNC : out Curve from BOPDS; - theMVEF : MapOfInteger from BOPCol) + theMVEF : MapOfInteger from BOPCol; + theMVTol : out DataMapOfIntegerReal from BOPCol) is protected; PutStickPavesOnCurve(me:out; nF1 : Integer from Standard; nF2 : Integer from Standard; theNC : out Curve from BOPDS; - theMVStick : MapOfInteger from BOPCol) + theMVStick : MapOfInteger from BOPCol; + theMVTol : out DataMapOfIntegerReal from BOPCol) is protected; GetStickVertices(me:out; @@ -287,7 +291,8 @@ is nV : Integer from Standard; theTolR3D : Real from Standard; theNC : Curve from BOPDS; - thePB : out PaveBlock from BOPDS) + thePB : out PaveBlock from BOPDS; + theMVTol : out DataMapOfIntegerReal from BOPCol) is protected; ProcessExistingPaveBlocks(me:out; @@ -326,21 +331,47 @@ is aVC : out VectorOfCurve from BOPDS) is protected; ---Purpose: - ---Keeps data for post treatment + -- Keeps data for post treatment RefineFaceInfoOn(me:out) is protected; ---Purpose: - --- Refines the state On for the all faces having - --- state information + -- Refines the state On for the all faces having + -- state information UpdateFaceInfo(me:out; theDME:out DataMapOfPaveBlockListOfPaveBlock from BOPDS) is protected; ---Purpose: - ---Updates the information about faces + -- Updates the information about faces + + ForceInterfVE(me:out; + nV : Integer from Standard; + aPB : out PaveBlock from BOPDS; + aMPB : out MapOfPaveBlock from BOPDS) + is protected; + ---Purpose: + -- Updates tolerance of vertex with index + -- to make it interfere with edge + + ForceInterfVF(me:out; + nV:Integer from Standard; + nF:Integer from Standard) + returns Boolean from Standard + is protected; + ---Purpose: + -- Updates tolerance of vertex with index + -- to make it interfere with face with index + + CheckPlanes(me:out; + nF1 : Integer from Standard; + nF2 : Integer from Standard) + returns Boolean from Standard + is protected; + ---Purpose: + -- Checks if there are any common or intersecting sub shapes + -- between two planar faces. - fields myArguments : ListOfShape from BOPCol is protected; myDS : PDS from BOPDS is protected; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index 833259a99d..28f47dc151 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -64,6 +64,7 @@ #include #include +#include //======================================================================= // function: PerformEE @@ -74,12 +75,16 @@ Standard_Boolean bJustAdd, bOrder; Standard_Integer i, iX, iSize, nE1, nE2, aDiscretize; Standard_Integer aNbCPrts, nWhat, nWith; - Standard_Real aTS11, aTS12, aTS21, aTS22; + Standard_Real aTS11, aTS12, aTS21, aTS22, + aT11, aT12, aT21, aT22; Standard_Real aTolE1, aTolE2, aDeflection; TopAbs_ShapeEnum aType; TopoDS_Edge aEWhat, aEWith; BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2; Handle(NCollection_IncAllocator) aAllocator; + Handle(BOPDS_PaveBlock) aPBn1, aPBn2; + BOPDS_MapOfPaveBlock aMPBToUpdate; + BOPDS_MapIteratorOfMapOfPaveBlock aItPB; // myErrorStatus=0; // @@ -177,8 +182,17 @@ BOPTools_AlgoTools::CorrectRange (aE1, aE2, aSR1, anewSR1); BOPTools_AlgoTools::CorrectRange (aE2, aE1, aSR2, anewSR2); // - aEdgeEdge.SetRange1(anewSR1); - aEdgeEdge.SetRange2(anewSR2); + aPB1->Range(aT11, aT12); + aPB2->Range(aT21, aT22); + IntTools_Range aPBRange1(aT11, aT12), aPBRange2(aT21, aT22); + // + IntTools_Range aPBR1 = aPBRange1; + IntTools_Range aPBR2 = aPBRange2; + BOPTools_AlgoTools::CorrectRange (aE1, aE2, aPBR1, aPBRange1); + BOPTools_AlgoTools::CorrectRange (aE2, aE1, aPBR2, aPBRange2); + // + aEdgeEdge.SetRange1(aPBRange1); + aEdgeEdge.SetRange2(aPBRange2); // aEdgeEdge.Perform(); if (!aEdgeEdge.IsDone()) { @@ -191,14 +205,29 @@ aEWith=aE2; nWhat=nE1; nWith=nE2; + aSR1=anewSR1; + aSR2=anewSR2; + aPBR1=aPBRange1; + aPBR2=aPBRange2; + aPBn1=aPB1; + aPBn2=aPB2; } else { nWhat=nE2; nWith=nE1; aEWhat=aE2; aEWith=aE1; + aSR1=anewSR2; + aSR2=anewSR1; + aPBR1=aPBRange2; + aPBR2=aPBRange1; + aPBn1=aPB2; + aPBn2=aPB1; } // + IntTools_Range aR11(aPBR1.First(), aSR1.First()), aR12(aSR1.Last(), aPBR1.Last()), + aR21(aPBR2.First(), aSR2.First()), aR22(aSR2.Last(), aPBR2.Last()); + // const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeEdge.CommonParts(); // aNbCPrts=aCPrts.Length(); @@ -207,49 +236,62 @@ aType=aCPart.Type(); switch (aType) { case TopAbs_VERTEX: { - Standard_Boolean bIsOnPave1, bIsOnPave2; + Standard_Boolean bIsOnPave[4], bFlag; + Standard_Integer nV[4], j; Standard_Real aT1, aT2, aTol; - IntTools_Range aR1, aR2; TopoDS_Vertex aVnew; // BOPInt_Tools::VertexParameters(aCPart, aT1, aT2); aTol=Precision::Confusion(); // //decide to keep the pave or not - aR1 = (bOrder) ? anewSR2 : anewSR1; - aR2 = (bOrder) ? anewSR1 : anewSR2; + bIsOnPave[0] = BOPInt_Tools::IsOnPave1(aT1, aR11, aTol); + bIsOnPave[1] = BOPInt_Tools::IsOnPave1(aT1, aR12, aTol); + bIsOnPave[2] = BOPInt_Tools::IsOnPave1(aT2, aR21, aTol); + bIsOnPave[3] = BOPInt_Tools::IsOnPave1(aT2, aR22, aTol); // - bIsOnPave1=BOPInt_Tools::IsOnPave(aT1, aR1, aTol); - bIsOnPave2=BOPInt_Tools::IsOnPave(aT2, aR2, aTol); + aPBn1->Indices(nV[0], nV[1]); + aPBn2->Indices(nV[2], nV[3]); // - if(bIsOnPave1 || bIsOnPave2) { + if((bIsOnPave[0] && bIsOnPave[2]) || (bIsOnPave[0] && bIsOnPave[3]) || + (bIsOnPave[1] && bIsOnPave[2]) || (bIsOnPave[1] && bIsOnPave[3])) { + continue; + } + // + bFlag = Standard_False; + for (j = 0; j < 4; ++j) { + if (bIsOnPave[j]) { + //add interf VE(nV[j], nE) + Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPBn2 : aPBn1; + ForceInterfVE(nV[j], aPB, aMPBToUpdate); + bFlag = Standard_True; + break; + } + } + if (bFlag) { continue; } // BOPTools_AlgoTools::MakeNewVertex(aEWhat, aT1, aEWith, aT2, aVnew); // <-LXBR { - Standard_Integer nV11, nV12, nV21, nV22, nVS[2], k, j, iFound; + Standard_Integer nVS[2], iFound, k; Standard_Real aTolVx, aTolVnew, aD2, aDT2; BOPCol_MapOfInteger aMV; gp_Pnt aPnew, aPx; // iFound=0; j=-1; - nV11=aPB1->Pave1().Index(); - nV12=aPB1->Pave2().Index(); - nV21=aPB2->Pave1().Index(); - nV22=aPB2->Pave2().Index(); - aMV.Add(nV11); - aMV.Add(nV12); + aMV.Add(nV[0]); + aMV.Add(nV[1]); // - if (aMV.Contains(nV21)) { + if (aMV.Contains(nV[2])) { ++j; - nVS[j]=nV21; + nVS[j]=nV[2]; } - if (aMV.Contains(nV22)) { + if (aMV.Contains(nV[3])) { ++j; - nVS[j]=nV22; + nVS[j]=nV[3]; } // aTolVnew=BRep_Tool::Tolerance(aVnew); @@ -327,11 +369,24 @@ //========================================= // post treatment //========================================= + aItPB.Initialize(aMPBToUpdate); + for (; aItPB.More(); aItPB.Next()) { + Handle(BOPDS_PaveBlock) aPB=aItPB.Value(); + if (!myDS->IsCommonBlock(aPB)) { + myDS->UpdatePaveBlock(aPB); + } + else { + const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB); + myDS->UpdateCommonBlock(aCB); + } + } + // BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS); PerformVerticesEE(aMVCPB, aAllocator); //-----------------------------------------------------scope t aMPBLPB.Clear(); aMVCPB.Clear(); + aMPBToUpdate.Clear(); aAllocator.Nullify(); } //======================================================================= @@ -648,6 +703,74 @@ // thePB->SetShrunkData(aTS1, aTS2, aBox); } +//======================================================================= +//function : ForceInterfVE +//purpose : +//======================================================================= +void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV, + Handle(BOPDS_PaveBlock)& aPB, + BOPDS_MapOfPaveBlock& aMPBToUpdate) +{ + Standard_Integer aNbPnt, nE; + gp_Pnt aP; + // + nE = aPB->OriginalEdge(); + // + const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE); + if (aSIE.HasSubShape(nV)) { + return; + } + // + if (myDS->HasInterf(nV, nE)) { + return; + } + // + if (myDS->HasInterfShapeSubShapes(nV, nE)) { + return; + } + // + if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) { + return; + } + // + const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV); + const TopoDS_Edge& aE = *(TopoDS_Edge*) &myDS->Shape(nE); + aP=BRep_Tool::Pnt(aV); + // + GeomAPI_ProjectPointOnCurve& aProjector=myContext->ProjPC(aE); + aProjector.Perform(aP); + // + aNbPnt = aProjector.NbPoints(); + if (aNbPnt) { + Standard_Real aT, aDist; + Standard_Integer i; + BRep_Builder aBB; + BOPDS_Pave aPave; + // + aDist=aProjector.LowerDistance(); + aT=aProjector.LowerDistanceParameter(); + // + BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE(); + i=aVEs.Append()-1; + BOPDS_InterfVE& aVE=aVEs(i); + aVE.SetIndices(nV, nE); + aVE.SetParameter(aT); + // + myDS->AddInterf(nV, nE); + // + aBB.UpdateVertex(aV, aDist); + BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); + Bnd_Box& aBox=aSIDS.ChangeBox(); + BRepBndLib::Add(aV, aBox); + // + aPave.SetIndex(nV); + aPave.SetParameter(aT); + aPB->AppendExtPave(aPave); + // + aMPBToUpdate.Add(aPB); + } +} + /* // DEBf { diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx index d08fd64442..dfba56937d 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx @@ -56,6 +56,7 @@ #include #include #include +#include //======================================================================= @@ -74,9 +75,9 @@ return; } //---------------------------------------------------------------------- - Standard_Boolean bJustAdd; - Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX; - Standard_Real aTolE, aTolF, aTS1, aTS2, aDeflection; + Standard_Boolean bJustAdd, bV[2]; + Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2]; + Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection; Handle(NCollection_IncAllocator) aAllocator; TopAbs_ShapeEnum aType; BOPDS_ListIteratorOfListOfPaveBlock aIt; @@ -158,15 +159,22 @@ // IntTools_Range aSR(aTS1, aTS2); IntTools_Range anewSR=aSR; - // BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR); - aEdgeFace.SetRange (anewSR); + // + aPB->Range(aT1, aT2); + IntTools_Range aPBRange(aT1, aT2); + aSR = aPBRange; + BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange); + // + aEdgeFace.SetRange (aPBRange); // aEdgeFace.Perform(); if (!aEdgeFace.IsDone()) { continue; } // + aPB->Indices(nV[0], nV[1]); + // const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts(); aNbCPrts=aCPrts.Length(); for (i=1; i<=aNbCPrts; ++i) { @@ -174,8 +182,8 @@ aType=aCPart.Type(); switch (aType) { case TopAbs_VERTEX: { - Standard_Boolean bIsOnPave1, bIsOnPave2, bV1, bV2; - Standard_Integer nV1, nV2; + Standard_Boolean bIsOnPave[2]; + Standard_Integer j; Standard_Real aT, aTolToDecide; TopoDS_Vertex aVnew; @@ -184,16 +192,16 @@ // const IntTools_Range& aR=aCPart.Range1(); aTolToDecide=5.e-8; - bIsOnPave1=BOPInt_Tools::IsOnPave1(anewSR.First(), aR, aTolToDecide); - bIsOnPave2=BOPInt_Tools::IsOnPave1(anewSR.Last() , aR, aTolToDecide); // - aPB->Indices(nV1, nV2); + IntTools_Range aR1(aT1, anewSR.First()), aR2(anewSR.Last(), aT2); // - - if (bIsOnPave1 && bIsOnPave2) { - bV1=CheckFacePaves(nV1, aMIFOn, aMIFIn); - bV2=CheckFacePaves(nV2, aMIFOn, aMIFIn); - if (bV1 && bV2) { + bIsOnPave[0]=BOPInt_Tools::IsInRange(aR1, aR, aTolToDecide); + bIsOnPave[1]=BOPInt_Tools::IsInRange(aR2, aR, aTolToDecide); + // + if (bIsOnPave[0] && bIsOnPave[1]) { + bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn); + bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn); + if (bV[0] && bV[1]) { iX=aEFs.Append()-1; IntTools_CommonPrt aCP = aCPart; aCP.SetType(TopAbs_EDGE); @@ -206,36 +214,32 @@ break; } } - if (bIsOnPave1) { - bV1=CheckFacePaves(nV1, aMIFOn, aMIFIn); - if (bV1) { - const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV1))); - BOPTools_AlgoTools::UpdateVertex(aE, aT, aV); - BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1); - Bnd_Box& aBoxDS=aSIDS.ChangeBox(); - BRepBndLib::Add(aV, aBoxDS); - continue; + for (j=0; j<2; ++j) { + if (bIsOnPave[j]) { + bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn); + if (bV[j]) { + const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV[j]))); + BOPTools_AlgoTools::UpdateVertex(aE, aT, aV); + BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV[j]); + Bnd_Box& aBoxDS=aSIDS.ChangeBox(); + BRepBndLib::Add(aV, aBoxDS); + } + else { + bIsOnPave[j] = ForceInterfVF(nV[j], nF); + } } - bIsOnPave1=!bIsOnPave1; } // - if (bIsOnPave2) { - bV2=CheckFacePaves(nV2, aMIFOn, aMIFIn); - if (bV2) { - const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV2))); - BOPTools_AlgoTools::UpdateVertex(aE, aT, aV); - BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV2); - Bnd_Box& aBoxDS=aSIDS.ChangeBox(); - BRepBndLib::Add(aV, aBoxDS); - continue; - } - bIsOnPave2=!bIsOnPave2; - } - // - if (!bIsOnPave1 && !bIsOnPave2) { + if (!bIsOnPave[0] && !bIsOnPave[1]) { if (CheckFacePaves(aVnew, aMIFOn)) { continue; } + // + const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew); + if (!myContext->IsValidPointForFace(aPnew, aF, aTolE)) { + continue; + } + // aBB.UpdateVertex(aVnew, aTolE); // aMIEFC.Add(nF); @@ -263,9 +267,9 @@ BOPDS_InterfEF& aEF=aEFs(iX); aEF.SetIndices(nE, nF); // - Standard_Boolean aCoinsideFlag; - aCoinsideFlag=BOPTools_AlgoTools::IsBlockInOnFace(anewSR, aF, aE, myContext); - if (!aCoinsideFlag) { + bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn); + bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn); + if (!bV[0] || !bV[1]) { myDS->AddInterf(nE, nF); break; } @@ -507,3 +511,54 @@ // return !bRet; } +//======================================================================= +//function : ForceInterfVF +//purpose : +//======================================================================= +Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF(const Standard_Integer nV, + const Standard_Integer nF) +{ + Standard_Boolean bRet; + // + bRet = Standard_False; + const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV); + const TopoDS_Face& aF = *(TopoDS_Face*) &myDS->Shape(nF); + // + GeomAPI_ProjectPointOnSurf& aProj = myContext->ProjPS(aF); + const gp_Pnt& aP = BRep_Tool::Pnt(aV); + aProj.Perform(aP); + if (!aProj.IsDone()) { + return bRet; + } + Standard_Real aDist, U, V; + // + aDist=aProj.LowerDistance(); + aProj.LowerDistanceParameters(U, V); + // + gp_Pnt2d aP2d(U, V); + bRet = myContext->IsPointInFace (aF, aP2d); + if (bRet) { + Standard_Integer i; + BRep_Builder aBB; + // + BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF(); + i=aVFs.Append()-1; + BOPDS_InterfVF& aVF=aVFs(i); + aVF.SetIndices(nV, nF); + aVF.SetUV(U, V); + // + myDS->AddInterf(nV, nF); + // + aBB.UpdateVertex(aV, aDist); + BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); + Bnd_Box& aBoxDS=aSIDS.ChangeBox(); + BRepBndLib::Add(aV, aBoxDS); + // + BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF); + BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn(); + aMVIn.Add(nV); + } + // + return bRet; +} + diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index 872f74ea18..23c21ba498 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -94,8 +95,8 @@ #include #include -static void ToleranceFF(const TopoDS_Face& aF1, - const TopoDS_Face& aF2, +static void ToleranceFF(const BRepAdaptor_Surface& aBAS1, + const BRepAdaptor_Surface& aBAS2, Standard_Real& aTolFF); //======================================================================= @@ -119,6 +120,7 @@ void BOPAlgo_PaveFiller::PerformFF() Standard_Boolean bToSplit, bTangentFaces; Standard_Integer nF1, nF2, aNbCurves, aNbPoints, iX, i, iP, iC, aNbLP; Standard_Real aApproxTol, aTolR3D, aTolR2D, aTolFF; + BRepAdaptor_Surface aBAS1, aBAS2; // BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); aFFs.SetStartSize(iSize); @@ -140,6 +142,24 @@ void BOPAlgo_PaveFiller::PerformFF() const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1))); const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2))); // + aBAS1.Initialize(aF1, Standard_False); + aBAS2.Initialize(aF2, Standard_False); + // + if (aBAS1.GetType() == GeomAbs_Plane && + aBAS2.GetType() == GeomAbs_Plane) { + Standard_Boolean bToIntersect; + // + bToIntersect = CheckPlanes(nF1, nF2); + if (!bToIntersect) { + myDS->AddInterf(nF1, nF2); + iX=aFFs.Append()-1; + BOPDS_InterfFF& aFF=aFFs(iX); + aFF.SetIndices(nF1, nF2); + aFF.Init(0, 0); + continue; + } + } + // IntTools_FaceFace aFaceFace; // IntSurf_ListOfPntOn2S aListOfPnts; @@ -159,7 +179,7 @@ void BOPAlgo_PaveFiller::PerformFF() aTolR2D=aFaceFace.TolReached2d(); bTangentFaces=aFaceFace.TangentFaces(); // - ToleranceFF(aF1, aF2, aTolFF); + ToleranceFF(aBAS1, aBAS2, aTolFF); // if (aTolR3D < aTolFF){ aTolR3D=aTolFF; @@ -247,7 +267,7 @@ void BOPAlgo_PaveFiller::PerformFF() Standard_Boolean bExist, bValid2D; Standard_Integer i, nF1, nF2, aNbC, aNbP, j; Standard_Integer nV1, nV2; - Standard_Real aTolR3D, aTolR2D, aT1, aT2; + Standard_Real aTolR3D, aTolR2D, aT1, aT2, aTol; Handle(NCollection_IncAllocator) aAllocator; BOPDS_ListIteratorOfListOfPaveBlock aItLPB; TopoDS_Edge aES; @@ -266,6 +286,8 @@ void BOPAlgo_PaveFiller::PerformFF() BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator); BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges; + BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator); + BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV; // for (i=0; iVerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn); myDS->SharedEdges(nF1, nF2, aLSE, aAllocator); @@ -332,12 +355,12 @@ void BOPAlgo_PaveFiller::PerformFF() // DEBt aNC.InitPaveBlock1(); // - PutPaveOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMVEF); + PutPaveOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMVEF, aMVTol); // - PutStickPavesOnCurve(nF1, nF2, aNC, aMVStick); + PutStickPavesOnCurve(nF1, nF2, aNC, aMVStick, aMVTol); //904/F7 if (aNbC == 1) { - PutEFPavesOnCurve(nF1, nF2, aNC, aMVEF); + PutEFPavesOnCurve(nF1, nF2, aNC, aMVEF, aMVTol); } // if (aIC.HasBounds()) { @@ -435,10 +458,24 @@ void BOPAlgo_PaveFiller::PerformFF() aMSCPB.Add(aES, aCPB); aMVI.Bind(aV1, nV1); aMVI.Bind(aV2, nV2); + // + aMVTol.UnBind(nV1); + aMVTol.UnBind(nV2); } // aLPBC.RemoveFirst(); }//for (j=0; jShape(nV1); + const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&aV.TShape()); + TV->Tolerance(aTol); + } + // ProcessExistingPaveBlocks(i, aMPBOnIn, aMSCPB, aMVI, aMVB, aMPBAdd); }//for (i=0; iIsVertexOnLine(aV, aIC, aTolR3D, aT); if (!bIsVertexOnLine) { - Standard_Real aTolVExt; BOPCol_MapOfInteger aMI; // - aTolVExt = BRep_Tool::Tolerance(aV); + aTol = BRep_Tool::Tolerance(aV); // GetFullFaceMap(nF1, aMI); GetFullFaceMap(nF2, aMI); // - ExtendedTolerance(nV, aMI, aTolVExt); - bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTolVExt, aIC, aTolR3D, aT); + ExtendedTolerance(nV, aMI, aTol); + bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTol, aIC, aTolR3D, aT); } // if (bIsVertexOnLine) { @@ -1146,7 +1183,16 @@ void BOPAlgo_PaveFiller::PerformFF() // aPB->AppendExtPave(aPave); // + aTol = BRep_Tool::Tolerance(aV); + // BOPTools_AlgoTools::UpdateVertex (aIC, aT, aV); + // + if (!aMVTol.IsBound(nV)) { + aTolNew = BRep_Tool::Tolerance(aV); + if (aTolNew > aTol) { + aMVTol.Bind(nV, aTol); + } + } // BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); Bnd_Box& aBoxDS=aSIDS.ChangeBox(); @@ -1291,7 +1337,8 @@ void BOPAlgo_PaveFiller::PerformFF() void BOPAlgo_PaveFiller::PutEFPavesOnCurve(const Standard_Integer /*nF1*/, const Standard_Integer /*nF2*/, BOPDS_Curve& aNC, - const BOPCol_MapOfInteger& aMVEF) + const BOPCol_MapOfInteger& aMVEF, + BOPCol_DataMapOfIntegerReal& aMVTol) { if (!aMVEF.Extent()) { return; @@ -1331,7 +1378,7 @@ void BOPAlgo_PaveFiller::PerformFF() Standard_Integer aNbPoints = aProjPT.NbPoints(); if (aNbPoints) { aDist = aProjPT.LowerDistance(); - PutPaveOnCurve(nV, aDist, aNC, aPB); + PutPaveOnCurve(nV, aDist, aNC, aPB, aMVTol); } } } @@ -1343,7 +1390,8 @@ void BOPAlgo_PaveFiller::PerformFF() void BOPAlgo_PaveFiller::PutStickPavesOnCurve(const Standard_Integer nF1, const Standard_Integer nF2, BOPDS_Curve& aNC, - const BOPCol_MapOfInteger& aMVStick) + const BOPCol_MapOfInteger& aMVStick, + BOPCol_DataMapOfIntegerReal& aMVTol) { BOPCol_MapOfInteger aMV; aMV.Assign(aMVStick); @@ -1421,7 +1469,7 @@ void BOPAlgo_PaveFiller::PerformFF() aD=sqrt(aD2); // Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1(); - PutPaveOnCurve(nV, aD, aNC, aPB); + PutPaveOnCurve(nV, aD, aNC, aPB, aMVTol); } }//for (jVU=1; jVU=aNbVU; ++jVU) { } @@ -1581,10 +1629,11 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC, void BOPAlgo_PaveFiller::PutPaveOnCurve(const Standard_Integer nV, const Standard_Real aTolR3D, const BOPDS_Curve& aNC, - Handle(BOPDS_PaveBlock)& aPB) + Handle(BOPDS_PaveBlock)& aPB, + BOPCol_DataMapOfIntegerReal& aMVTol) { Standard_Boolean bIsVertexOnLine; - Standard_Real aT; + Standard_Real aT, aTol, aTolNew; BOPDS_Pave aPave; // const TopoDS_Vertex aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV))); @@ -1597,7 +1646,16 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC, // aPB->AppendExtPave(aPave); // + aTol = BRep_Tool::Tolerance(aV); + // BOPTools_AlgoTools::UpdateVertex (aIC, aT, aV); + // + if (!aMVTol.IsBound(nV)) { + aTolNew = BRep_Tool::Tolerance(aV); + if (aTolNew > aTol) { + aMVTol.Bind(nV, aTol); + } + } // BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV); Bnd_Box& aBoxDS=aSIDS.ChangeBox(); @@ -1902,38 +1960,126 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC, aMVI.Bind(aV2, nV2); } +//======================================================================= +//function : CheckPlanes +//purpose : +//======================================================================= +Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes(const Standard_Integer nF1, + const Standard_Integer nF2) +{ + Standard_Boolean bToIntersect; + // + bToIntersect = 1; + // + //1. Find shared vertices + Standard_Integer nS1, nS2, iCountV, iCountE; + BOPCol_MapOfInteger aMI1, aMI2; + BOPCol_MapIteratorOfMapOfInteger aIt; + // + iCountV = 0; + iCountE = 0; + GetFullFaceMap(nF1, aMI1); + GetFullFaceMap(nF2, aMI2); + // + //1. Find shared sub shapes + aIt.Initialize(aMI1); + aIt.Next(); + for (; aIt.More(); aIt.Next()) { + nS1 = aIt.Value(); + if (aMI2.Contains(nS1)) { + const TopoDS_Shape& aS = myDS->Shape(nS1); + if (aS.ShapeType() == TopAbs_EDGE) { + ++iCountE; + iCountV-=2; + } else { + ++iCountV; + } + } + } + // + if ((iCountV + iCountE) > 1) { + return bToIntersect; + } + // + //2. Find intersecting sub shapes + Standard_Integer aNb, i, k; + BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE(); + BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF(); + for (k=0; k<2; ++k) { + aNb = !k ? aEEs.Extent() : aEFs.Extent(); + for (i = 0; i < aNb; ++i) { + BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) : + (BOPDS_Interf*) (&aEFs(i)); + aInt->Indices(nS1, nS2); + if (aMI1.Contains(nS1) && aMI2.Contains(nS2) || + aMI1.Contains(nS2) && aMI2.Contains(nS1)) { + const IntTools_CommonPrt& aCPart = !k ? aEEs(i).CommonPart() : + aEFs(i).CommonPart(); + if (aCPart.Type() == TopAbs_EDGE) { + ++iCountE; + } else { + ++iCountV; + } + if ((iCountV + iCountE) > 1) { + return bToIntersect; + } + } + } + } + // + BOPCol_MapOfInteger aMI; + // + for (k=0; k<2; ++k) { + aMI = !k ? aMI1 : aMI2; + nS2 = !k ? nF2 : nF1; + aIt.Initialize(aMI); + for (; aIt.More(); aIt.Next()) { + nS1 = aIt.Value(); + const TopoDS_Shape& aV = myDS->Shape(nS1); + if (aV.ShapeType() == TopAbs_VERTEX) { + if (myDS->HasInterf(nS1, nS2) || + myDS->HasInterfShapeSubShapes(nS1, nS2)) { + ++iCountV; + } + } + } + } + bToIntersect = ((iCountV + iCountE) > 1); + // + return bToIntersect; +} + //======================================================================= //function : ToleranceFF //purpose : Computes the TolFF according to the tolerance value and // types of the faces. //======================================================================= - void ToleranceFF(const TopoDS_Face& aF1, - const TopoDS_Face& aF2, + void ToleranceFF(const BRepAdaptor_Surface& aBAS1, + const BRepAdaptor_Surface& aBAS2, Standard_Real& aTolFF) { Standard_Real aTol1, aTol2; Standard_Boolean isAna1, isAna2; // - aTol1 = BRep_Tool::Tolerance(aF1); - aTol2 = BRep_Tool::Tolerance(aF2); + aTol1 = aBAS1.Tolerance(); + aTol2 = aBAS2.Tolerance(); aTolFF = Max(aTol1, aTol2); // - BRepAdaptor_Surface BAS1(aF1); - BRepAdaptor_Surface BAS2(aF2); + isAna1 = (aBAS1.GetType() == GeomAbs_Plane || + aBAS1.GetType() == GeomAbs_Cylinder || + aBAS1.GetType() == GeomAbs_Cone || + aBAS1.GetType() == GeomAbs_Sphere || + aBAS1.GetType() == GeomAbs_Torus); // - isAna1 = (BAS1.GetType() == GeomAbs_Plane || - BAS1.GetType() == GeomAbs_Cylinder || - BAS1.GetType() == GeomAbs_Cone || - BAS1.GetType() == GeomAbs_Sphere || - BAS1.GetType() == GeomAbs_Torus); + isAna2 = (aBAS2.GetType() == GeomAbs_Plane || + aBAS2.GetType() == GeomAbs_Cylinder || + aBAS2.GetType() == GeomAbs_Cone || + aBAS2.GetType() == GeomAbs_Sphere || + aBAS2.GetType() == GeomAbs_Torus); // - isAna2 = (BAS2.GetType() == GeomAbs_Plane || - BAS2.GetType() == GeomAbs_Cylinder || - BAS2.GetType() == GeomAbs_Cone || - BAS2.GetType() == GeomAbs_Sphere || - BAS2.GetType() == GeomAbs_Torus); - // - aTolFF = (isAna1 && isAna2) ? aTolFF : Max(aTolFF, 5.e-6); + if (!isAna1 || !isAna2) { + aTolFF = Max(aTolFF, 5.e-6); + } } diff --git a/src/BOPCol/BOPCol.cdl b/src/BOPCol/BOPCol.cdl index baa21e089c..9937dace42 100644 --- a/src/BOPCol/BOPCol.cdl +++ b/src/BOPCol/BOPCol.cdl @@ -33,6 +33,7 @@ is imported ListOfInteger from BOPCol; imported PInteger from BOPCol; imported DataMapOfIntegerInteger from BOPCol; + imported DataMapOfIntegerReal from BOPCol; imported DataMapOfIntegerListOfInteger from BOPCol; imported IndexedDataMapOfShapeBox from BOPCol; imported IndexedMapOfInteger from BOPCol; diff --git a/src/BOPCol/BOPCol_DataMapOfIntegerReal.hxx b/src/BOPCol/BOPCol_DataMapOfIntegerReal.hxx new file mode 100644 index 0000000000..ee6e0f1404 --- /dev/null +++ b/src/BOPCol/BOPCol_DataMapOfIntegerReal.hxx @@ -0,0 +1,32 @@ +// Created by: Eugeny MALTCHIKOV +// Copyright (c) 1999-2012 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + + +#ifndef BOPCol_DataMapOfIntegerReal_HeaderFile +#define BOPCol_DataMapOfIntegerReal_HeaderFile + +#include + +#include + +typedef NCollection_DataMap BOPCol_DataMapOfIntegerReal; +typedef BOPCol_DataMapOfIntegerReal::Iterator BOPCol_DataMapIteratorOfDataMapOfIntegerReal; + +#undef _NCollection_MapHasher + +#endif diff --git a/src/BOPCol/FILES b/src/BOPCol/FILES index f04b945f5c..3543673a7b 100644 --- a/src/BOPCol/FILES +++ b/src/BOPCol/FILES @@ -6,6 +6,7 @@ BOPCol_PInteger.hxx BOPCol_DataMapOfIntegerListOfInteger.hxx BOPCol_IndexedDataMapOfShapeBox.hxx BOPCol_DataMapOfIntegerInteger.hxx +BOPCol_DataMapOfIntegerReal.hxx BOPCol_DataMapOfIntegerMapOfInteger.hxx BOPCol_IndexedMapOfInteger.hxx BOPCol_ListOfShape.hxx diff --git a/src/BOPInt/BOPInt_Context.cxx b/src/BOPInt/BOPInt_Context.cxx index 109ad6ba8e..dcec625170 100644 --- a/src/BOPInt/BOPInt_Context.cxx +++ b/src/BOPInt/BOPInt_Context.cxx @@ -215,7 +215,7 @@ // pProjPS=(GeomAPI_ProjectPointOnSurf*)myAllocator->Allocate(sizeof(GeomAPI_ProjectPointOnSurf)); new (pProjPS) GeomAPI_ProjectPointOnSurf(); - pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT, Extrema_ExtAlgo_Tree); + pProjPS->Init(aS ,Umin, Usup, Vmin, Vsup, anEpsT/*, Extrema_ExtAlgo_Tree*/); Extrema_ExtPS& anExtAlgo = const_cast(pProjPS->Extrema()); anExtAlgo.SetFlag(Extrema_ExtFlag_MIN); // diff --git a/src/BOPInt/BOPInt_ShrunkRange.cxx b/src/BOPInt/BOPInt_ShrunkRange.cxx index 05c765ebc4..396e45dbf7 100644 --- a/src/BOPInt/BOPInt_ShrunkRange.cxx +++ b/src/BOPInt/BOPInt_ShrunkRange.cxx @@ -170,7 +170,7 @@ return; } // - aCoeff=2.; + aCoeff=(aTolE>0.05) ? 1. : 2.; // xf if (aCurveType==GeomAbs_Line) { Standard_Real aTV1, aTV2, aEps; diff --git a/src/BOPInt/BOPInt_Tools.cdl b/src/BOPInt/BOPInt_Tools.cdl index 64ec3aa548..7aea64452c 100644 --- a/src/BOPInt/BOPInt_Tools.cdl +++ b/src/BOPInt/BOPInt_Tools.cdl @@ -19,7 +19,7 @@ class Tools from BOPInt - ---Purpose: +---Purpose: uses Box from Bnd, @@ -36,48 +36,54 @@ uses is - + CheckCurve(myclass; - theC:Curve from Geom; - theTol:Real from Standard; - theBox:out Box from Bnd) - returns Boolean from Standard; + theC:Curve from Geom; + theTol:Real from Standard; + theBox:out Box from Bnd) + returns Boolean from Standard; IsOnPave(myclass; - theT:Real from Standard; - theRange:Range from IntTools; - theTol: Real from Standard) - returns Boolean from Standard; - + theT:Real from Standard; + theRange:Range from IntTools; + theTol: Real from Standard) + returns Boolean from Standard; VertexParameters(myclass; - theCP:CommonPrt from IntTools; - theT1:out Real from Standard; - theT2:out Real from Standard); + theCP:CommonPrt from IntTools; + theT1:out Real from Standard; + theT2:out Real from Standard); VertexParameter(myclass; - theCP:CommonPrt from IntTools; - theT:out Real from Standard); - + theCP:CommonPrt from IntTools; + theT:out Real from Standard); + IsOnPave1(myclass; - theT:Real from Standard; - theRange:Range from IntTools; - theTol: Real from Standard) - returns Boolean from Standard; - + theT:Real from Standard; + theRange:Range from IntTools; + theTol: Real from Standard) + returns Boolean from Standard; + + IsInRange(myclass; + theRRef : Range from IntTools; + theR : Range from IntTools; + theTol : Real from Standard) + returns Boolean from Standard; + ---Purpose: Checks if the range interfere with the range + SegPln(myclass; - theLin : Lin from gp; - theTLin1 : Real from Standard; - theTLin2 : Real from Standard; - theTolLin: Real from Standard; - thePln : Pln from gp; - theTolPln: Real from Standard; - theP :out Pnt from gp; - theT :out Real from Standard; - theTolP :out Real from Standard; - theTmin :out Real from Standard; - theTmax :out Real from Standard) - returns Integer from Standard; + theLin : Lin from gp; + theTLin1 : Real from Standard; + theTLin2 : Real from Standard; + theTolLin: Real from Standard; + thePln : Pln from gp; + theTolPln: Real from Standard; + theP :out Pnt from gp; + theT :out Real from Standard; + theTolP :out Real from Standard; + theTmin :out Real from Standard; + theTmax :out Real from Standard) + returns Integer from Standard; --fields end Tools; diff --git a/src/BOPInt/BOPInt_Tools.cxx b/src/BOPInt/BOPInt_Tools.cxx index 938be660ee..fe213ab7e9 100644 --- a/src/BOPInt/BOPInt_Tools.cxx +++ b/src/BOPInt/BOPInt_Tools.cxx @@ -131,16 +131,28 @@ return bIsOnPave; } - - - - - - - - - - +//======================================================================= +// function: IsInRange +// purpose: +//======================================================================= + Standard_Boolean BOPInt_Tools::IsInRange(const IntTools_Range& aRRef, + const IntTools_Range& aR, + const Standard_Real aTolerance) +{ + Standard_Boolean bIsIn; + Standard_Real aT1, aT2, aTRef1, aTRef2; + // + aR.Range(aT1, aT2); + aRRef.Range(aTRef1, aTRef2); + // + aTRef1-=aTolerance; + aTRef2+=aTolerance; + // + bIsIn = (aT1>=aTRef1 && aT1<=aTRef2) || + (aT2>=aTRef1 && aT2<=aTRef2); + // + return bIsIn; +} //======================================================================= //function : SegPln diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx index 924f85ec4c..ce53efac6b 100644 --- a/src/BOPTools/BOPTools_AlgoTools_1.cxx +++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx @@ -79,6 +79,10 @@ #include #include #include +#include +#include +#include +#include static void CheckEdge (const TopoDS_Edge& E, @@ -100,6 +104,12 @@ static static void CorrectWires(const TopoDS_Face& aF); +static + Standard_Real IntersectCurves2d(const gp_Pnt& aPV, + const TopoDS_Face& aF, + const TopoDS_Edge& aE1, + const TopoDS_Edge& aE2); + static void UpdateEdges(const TopoDS_Face& aF); @@ -166,27 +176,19 @@ static //======================================================================= void CorrectWires(const TopoDS_Face& aFx) { - GeomAbs_SurfaceType aType; - // - const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx); - GeomAdaptor_Surface aGAS (aS); - aType=aGAS.GetType(); - if (aType!=GeomAbs_Cylinder) { - return; - } - // Standard_Integer i, aNbV; - Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT; - TopoDS_Edge aE1, aE2, aEi, aEj; + Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT, aTol2d; gp_Pnt aP, aPV; gp_Pnt2d aP2D; TopoDS_Face aF; BRep_Builder aBB; TopTools_IndexedDataMapOfShapeListOfShape aMVE; - TopTools_ListIteratorOfListOfShape aIt; + TopTools_ListIteratorOfListOfShape aIt, aIt1; // aF=aFx; aF.Orientation(TopAbs_FORWARD); + aTol2d = Precision::Confusion(); + const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx); // TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE); aNbV=aMVE.Extent(); @@ -200,7 +202,7 @@ void CorrectWires(const TopoDS_Face& aFx) const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i); aIt.Initialize(aLE); for (; aIt.More(); aIt.Next()) { - const TopoDS_Edge& aE=TopoDS::Edge(aIt.Value()); + const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value()); aT=BRep_Tool::Parameter(aV, aE); const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); aC2D->D0(aT, aP2D); @@ -209,6 +211,29 @@ void CorrectWires(const TopoDS_Face& aFx) if (aD2>aD2max) { aD2max=aD2; } + //check self interference + if (aNbV == 2) { + continue; + } + aIt1 = aIt; + aIt1.Next(); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value()); + //do not perform check for edges that have two common vertices + { + TopoDS_Vertex aV11, aV12, aV21, aV22; + TopExp::Vertices(aE, aV11, aV12); + TopExp::Vertices(aE1, aV21, aV22); + if (aV11.IsSame(aV21) && aV12.IsSame(aV22) || + aV12.IsSame(aV21) && aV11.IsSame(aV22)) { + continue; + } + } + aD2 = IntersectCurves2d(aPV, aF, aE, aE1); + if (aD2>aD2max) { + aD2max=aD2; + } + } } if (aD2max>aTol2) { aTol=sqrt(aD2max); @@ -216,6 +241,58 @@ void CorrectWires(const TopoDS_Face& aFx) } } } +//======================================================================= +// Function : IntersectCurves2d +// purpose : Intersect 2d curves of edges +//======================================================================= +Standard_Real IntersectCurves2d(const gp_Pnt& aPV, + const TopoDS_Face& aF, + const TopoDS_Edge& aE1, + const TopoDS_Edge& aE2) +{ + const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF); + GeomAdaptor_Surface aGAS (aS); + if (aGAS.IsUPeriodic() || aGAS.IsVPeriodic()) { + return 0; + } + // + Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d; + Standard_Integer j, aNbPnt; + Geom2dInt_GInter aInter; + gp_Pnt aP; + gp_Pnt2d aP2D; + // + aDist = 0.; + aTol2d = Precision::Confusion(); + // + const Handle(Geom2d_Curve)& aC2D1=BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12); + const Handle(Geom2d_Curve)& aC2D2=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22); + // + Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2); + IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, aC2D1->Value(aT12), aT12, aTol2d), + aDom2(aC2D2->Value(aT21), aT21, aTol2d, aC2D2->Value(aT22), aT22, aTol2d); + // + aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d); + if (aInter.IsDone()) { + if (aInter.NbSegments()) { + return aDist; + } + aNbPnt = aInter.NbPoints(); + if (aNbPnt) { + aDist = Precision::Infinite(); + for (j = 1; j <= aNbPnt; ++j) { + aP2D = aInter.Point(j).Value(); + aS->D0(aP2D.X(), aP2D.Y(), aP); + aD=aPV.SquareDistance(aP); + if (aD < aDist) { + aDist = aD; + } + } + } + } + return aDist; +} + //======================================================================= // Function : CorrectEdgeTolerance // purpose : Correct tolerances for Edge diff --git a/src/IntTools/IntTools_BeanFaceIntersector.cxx b/src/IntTools/IntTools_BeanFaceIntersector.cxx index 9819299043..1ab9ed873c 100755 --- a/src/IntTools/IntTools_BeanFaceIntersector.cxx +++ b/src/IntTools/IntTools_BeanFaceIntersector.cxx @@ -62,7 +62,6 @@ #include #include #include -#include static Standard_Boolean AdjustPeriodic(const Standard_Real U, const Standard_Real UFirst, @@ -448,17 +447,17 @@ void IntTools_BeanFaceIntersector::Perform() IntTools_Range aRange = myRangeManager.Range(i); if(myResults.Length() > 0) { - const IntTools_Range& aLastRange = myResults.Last(); - - if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) { - myResults.Append(aRange); - } - else { - myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last()); - } + const IntTools_Range& aLastRange = myResults.Last(); + + if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) { + myResults.Append(aRange); + } + else { + myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last()); + } } else { - myResults.Append(aRange); + myResults.Append(aRange); } } } @@ -934,19 +933,23 @@ Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection() } //modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t // - //modified by NIZHNY-EMV Fri May 17 09:48:49 2013 if (aresult==1) { - IntTools_Range aRange(myFirstParameter, myLastParameter); - const TopoDS_Face& aF = mySurface.Face(); - const TopoDS_Edge& aE = myCurve.Edge(); + //check intermediate point + Standard_Real aTm; + Standard_Boolean bValid; // - if (BOPTools_AlgoTools::IsBlockInOnFace(aRange, aF, aE, myContext)) { + const TopoDS_Face& aF = mySurface.Face(); + aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter); + const gp_Pnt& aPm = myCurve.Value(aTm); + // + bValid = myContext->IsValidPointForFace(aPm, aF, myCriteria); + if (bValid) { + IntTools_Range aRange(myFirstParameter, myLastParameter); myRangeManager.InsertRange(aRange, 2); } else { aresult=2; } } - //modified by NIZHNY-EMV Fri May 17 09:48:53 2013 // return aresult; } diff --git a/tests/boolean/bcut_complex/B1 b/tests/boolean/bcut_complex/B1 index d9d94cf6dc..64b1b153e3 100644 --- a/tests/boolean/bcut_complex/B1 +++ b/tests/boolean/bcut_complex/B1 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file f4] b1 restore [locate_data_file f5] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/B3 b/tests/boolean/bcut_complex/B3 index c5bbd10ff8..a2b41be7ef 100644 --- a/tests/boolean/bcut_complex/B3 +++ b/tests/boolean/bcut_complex/B3 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file f1] b1 restore [locate_data_file f5] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/B5 b/tests/boolean/bcut_complex/B5 index 3464963f27..e8372b9762 100644 --- a/tests/boolean/bcut_complex/B5 +++ b/tests/boolean/bcut_complex/B5 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file f1] b1 restore [locate_data_file f4] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/C2 b/tests/boolean/bcut_complex/C2 index 96b093a0ac..90dcafda7d 100644 --- a/tests/boolean/bcut_complex/C2 +++ b/tests/boolean/bcut_complex/C2 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file f3] b1 restore [locate_data_file f5] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/C4 b/tests/boolean/bcut_complex/C4 index 787baa94ff..e17ad519be 100644 --- a/tests/boolean/bcut_complex/C4 +++ b/tests/boolean/bcut_complex/C4 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file f1] b1 restore [locate_data_file f41] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/C6 b/tests/boolean/bcut_complex/C6 index eba288cb53..5c6b1f6d0a 100644 --- a/tests/boolean/bcut_complex/C6 +++ b/tests/boolean/bcut_complex/C6 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file so1] b1 restore [locate_data_file so4] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/C8 b/tests/boolean/bcut_complex/C8 index a926d3a0da..96a8e7c62e 100644 --- a/tests/boolean/bcut_complex/C8 +++ b/tests/boolean/bcut_complex/C8 @@ -1,8 +1,6 @@ -puts "TODO #22911 ALL: Error : The bcut is not valid. The area is 0" - restore [locate_data_file so1] b1 restore [locate_data_file so2] b2 bcut result b2 b1 -set square 0 +set square empty diff --git a/tests/boolean/bcut_complex/N9 b/tests/boolean/bcut_complex/N9 index b471c10f1d..a8dbbd3189 100644 --- a/tests/boolean/bcut_complex/N9 +++ b/tests/boolean/bcut_complex/N9 @@ -1,12 +1,13 @@ # Original bug : pro14942 # Date : 26Aout98 -puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO #22911 ALL: Error : The area of the resulting shape is" +#CR23958 puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_" +#CR23958 puts "TODO #22911 ALL: Error : The area of the resulting shape is" restore [locate_data_file CTO904_pro14942a.rle] a restore [locate_data_file pro14942b.rle] b bcut result a b -set square 0 +#CR23958 set square 0 +set square 192472 diff --git a/tests/bugs/modalg_1/bug1255 b/tests/bugs/modalg_1/bug1255 index 0d3217514f..30580f8436 100755 --- a/tests/bugs/modalg_1/bug1255 +++ b/tests/bugs/modalg_1/bug1255 @@ -12,5 +12,5 @@ mkface f1 p1 bsection result a f1 -set length 5364.73 +set length 5840.24 set 2dviewer 0 diff --git a/tests/bugs/modalg_1/bug1255_1 b/tests/bugs/modalg_1/bug1255_1 index 841aadd9ce..b0df2d6821 100755 --- a/tests/bugs/modalg_1/bug1255_1 +++ b/tests/bugs/modalg_1/bug1255_1 @@ -19,6 +19,6 @@ if { [catch {bop a f1 } ] } { bopsection result } -set length 5364.73 +set length 5840.24 set 2dviewer 0 diff --git a/tests/bugs/modalg_4/bug62 b/tests/bugs/modalg_4/bug62 index fd9c32a43d..9b9c2a75b1 100755 --- a/tests/bugs/modalg_4/bug62 +++ b/tests/bugs/modalg_4/bug62 @@ -8,8 +8,8 @@ if {[string compare $os "MacOS"] == 0} { puts "TODO #23828 MacOS: Tcl Exception: sh is not a topological shape!!!" puts "TODO #23828 MacOS: TEST INCOMPLETE" } else { - puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" - puts "TODO OCC12345 ALL: Error : The square of result shape is" + #puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" + #puts "TODO OCC12345 ALL: Error : The square of result shape is" } puts "================" @@ -40,6 +40,5 @@ checkshape res5 renamevar res5 result -set square 0 +set square 1.21497e+7 set 2dviewer 0 - diff --git a/tests/bugs/modalg_5/bug23958 b/tests/bugs/modalg_5/bug23958 new file mode 100644 index 0000000000..81e720c7b2 --- /dev/null +++ b/tests/bugs/modalg_5/bug23958 @@ -0,0 +1,29 @@ +puts "=========" +puts "OCC23958" +puts "=========" +puts "" +################################################################################# +# Section of shell by plane is incomplete +################################################################################# + +pload DATAEXCHANGEKERNEL + +# shell +restore [locate_data_file bug23958_bug948-shape.brep] a + +# plane +plane p 10.62752 0 0 1 0 0 +mkface f p + +# check that everything is Ok +checkshape a +tolerance a +bopargcheck a f -S #F + +# build section +bsection result a f + +# check total length of result +set length 1.21473 + +set 2dviewer 1