From: emv Date: Thu, 6 Aug 2020 12:30:58 +0000 (+0300) Subject: 0031662: Modeling Algorithms - Incomplete result of section operation X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR0_691_FixS;p=occt-copy.git 0031662: Modeling Algorithms - Incomplete result of section operation BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence. --- diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.cdl b/src/BOPAlgo/BOPAlgo_PaveFiller.cdl index c701a9ee19..268890add5 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cdl +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cdl @@ -52,7 +52,8 @@ uses PaveBlock from BOPDS, CommonBlock from BOPDS, Curve from BOPDS, - IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS, + DataMapOfIntegerMapOfPaveBlock from BOPDS, + IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS, MapOfPaveBlock from BOPDS, IndexedMapOfPaveBlock from BOPDS, ListOfPaveBlock from BOPDS, @@ -265,7 +266,8 @@ is thePB:PaveBlock from BOPDS; theNC:Curve from BOPDS; theTolR3D:Real from Standard; - theMPB:IndexedMapOfPaveBlock from BOPDS; + theMPB:IndexedMapOfPaveBlock from BOPDS; + theMPBCommon:MapOfPaveBlock from BOPDS; thePBOut:out PaveBlock from BOPDS) returns Boolean from Standard is protected; @@ -576,6 +578,18 @@ is -- been put on other section edges with greater tolerance, which has caused -- increase of the tolerance value of the vertices. + ForceInterfEF(me:out) + is protected; + ---Purpose: The method looks for the additional edge/face common blocks + -- among pairs of edge/face having the same vertices. + + ForceInterfEF(me:out; + theMPB: IndexedMapOfPaveBlock from BOPDS; + theAddInterf: Boolean from Standard) + is protected; + ---Purpose: Performs intersection of given pave blocks + -- with all faces from arguments. + fields myArguments : ListOfShape from BOPCol is protected; @@ -585,5 +599,6 @@ fields mySectionAttribute : SectionAttribute from BOPAlgo is protected; myFuzzyValue : Real from Standard is protected; myNonDestructive : Boolean from Standard is protected; - myIsPrimary : Boolean from Standard is protected; + myIsPrimary : Boolean from Standard is protected; + myFPBDone : DataMapOfIntegerMapOfPaveBlock from BOPDS is protected; end PaveFiller; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx index 426ed2c617..7190bad901 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx @@ -50,7 +50,8 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller (const Handle(NCollection_BaseAllocator)& theAllocator) : BOPAlgo_Algo(theAllocator), - myFuzzyValue(0.) + myFuzzyValue(0.), + myFPBDone(1, theAllocator) { myDS=NULL; myIterator=NULL; @@ -296,6 +297,8 @@ void BOPAlgo_PaveFiller::PerformInternal() return; } UpdatePaveBlocksWithSDVertices(); + + ForceInterfEF(); // // 22 PerformFF(); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx index b240574332..e00f7a48f9 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx @@ -36,6 +36,7 @@ #include #include // +#include #include #include #include @@ -53,9 +54,16 @@ #include // #include +#include // #include +#include +#include +#include +#include + + //======================================================================= //class : BOPAlgo_EdgeFace //purpose : @@ -236,7 +244,12 @@ void BOPAlgo_PaveFiller::PerformEF() BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange); aEdgeFace.SetRange (aPBRange); aEdgeFace.SetProgressIndicator(myProgressIndicator); - // + + // Save the pair to avoid their forced intersection + BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF); + if (!pMPB) + pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock()); + pMPB->Add(aPB); }//for (; aIt.More(); aIt.Next()) { }//for (; myIterator->More(); myIterator->Next()) { // @@ -658,3 +671,350 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF } return bRet; } + + +//======================================================================= +//function : ForceInterfEF +//purpose : +//======================================================================= +void BOPAlgo_PaveFiller::ForceInterfEF() +{ + if (!myIsPrimary) + return; + + // Now that we have vertices increased and unified, try to find additional + // edge/face common blocks among the pairs of edge/face. + // Here, we are interested in common blocks only, as all real intersections + // should have happened already. Thus, we need to check only those pairs + // of edge/face which have the same vertices. + + // Collect all pave blocks + BOPDS_IndexedMapOfPaveBlock aMPB; + const Standard_Integer aNbS = myDS->NbSourceShapes(); + for (Standard_Integer nE = 0; nE < aNbS; ++nE) + { + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE); + if (aSI.ShapeType() != TopAbs_EDGE) + // Not an edge + continue; + + if (!aSI.HasReference()) + // Edge has no pave blocks + continue; + + if (aSI.HasFlag()) + // Degenerated edge + continue; + + const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE); + BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB); + for (; aItLPB.More(); aItLPB.Next()) + { + const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); + const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB); + aMPB.Add(aPBR); + } + } + + // Perform intersection of collected pave blocks with faces + ForceInterfEF(aMPB, Standard_True); +} + +//======================================================================= +//function : ForceInterfEF +//purpose : +//======================================================================= +void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB, + const Standard_Boolean theAddInterf) +{ + if (theMPB.IsEmpty()) + return; + + // Fill the tree with bounding boxes of the pave blocks + NCollection_UBTree aBBTree; + NCollection_UBTreeFiller aTreeFiller(aBBTree); + + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; + BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc); + + Standard_Integer aNbPB = theMPB.Extent(); + for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB) + { + Handle(BOPDS_PaveBlock) aPB = theMPB(iPB); + if (!aPB->HasShrunkData()) + { + FillShrunkData(aPB); + if (!aPB->HasShrunkData()) + continue; + } + + Standard_Real f, l; + Bnd_Box aPBBox; + aPB->ShrunkData(f, l, aPBBox); + + aTreeFiller.Add(aPBMap.Add(aPB), aPBBox); + } + + // Shake the tree + aTreeFiller.Fill(); + + const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1); + + // Find pairs of Face/PaveBlock containing the same vertices + // and prepare those pairs for intersection. + BOPAlgo_VectorOfEdgeFace aVEdgeFace; + + const Standard_Integer aNbS = myDS->NbSourceShapes(); + for (Standard_Integer nF = 0; nF < aNbS; ++nF) + { + const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF); + if (aSI.ShapeType() != TopAbs_FACE) + // Not a face + continue; + + if (!aSI.HasReference()) + // Face has no face info + continue; + + const Bnd_Box& aBoxF = aSI.Box(); + BOPCol_BoxBndTreeSelector aSelector; + aSelector.SetBox(aBoxF); + + if (!aBBTree.Select(aSelector)) + continue; + + const TopoDS_Face& aF = TopoDS::Face (aSI.Shape()); + const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF); + // Vertices of the face + BOPCol_MapOfInteger aMVF; + const BOPCol_MapOfInteger* pMVF[] = { &aFI.VerticesOn(), + &aFI.VerticesIn(), + &aFI.VerticesSc() }; + for (Standard_Integer iM = 0; iM < 3; ++iM) + { + BOPCol_MapIteratorOfMapOfInteger itM(*pMVF[iM]); + for (; itM.More(); itM.Next()) + aMVF.Add(itM.Value()); + } + + // Pave Blocks of the face + const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(), + &aFI.PaveBlocksIn(), + &aFI.PaveBlocksSc() }; + for (Standard_Integer iM = 0; iM < 3; ++iM) + { + const Standard_Integer aNb = pMPBF[iM]->Extent(); + for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB) + { + const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB); + aMVF.Add(aPB->Pave1().Index()); + aMVF.Add(aPB->Pave2().Index()); + } + } + + // Projection tool + GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF); + BRepAdaptor_Surface aSurfAdaptor (aF, Standard_False); + + // Iterate on pave blocks and combine pairs containing + // the same vertices + const BOPCol_ListOfInteger& aLIPB = aSelector.Indices(); + BOPCol_ListOfInteger::Iterator itLIPB(aLIPB); + for (; itLIPB.More(); itLIPB.Next()) + { + const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value()); + if (pMPBF[0]->Contains(aPB) || + pMPBF[1]->Contains(aPB) || + pMPBF[2]->Contains(aPB)) + continue; + + // Check if the face contains both vertices of the pave block + Standard_Integer nV1, nV2; + aPB->Indices(nV1, nV2); + if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2)) + // Face does not contain the vertices + continue; + + // Get the edge + Standard_Integer nE; + if (!aPB->HasEdge(nE)) + { + nE = aPB->OriginalEdge(); + if (nE < 0) + continue; + + // Make sure that the edge and face came from different arguments + if (myDS->Rank(nF) == myDS->Rank(nE)) + continue; + } + + const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE)); + BRepAdaptor_Curve aBAC(aE); + + // Check directions coincidence at middle point on the edge + // and projection of that point on the face. + // If the angle between tangent vector to the curve and normal + // of the face is not in the range of 65 - 115 degrees, do not use the additional + // tolerance, as it may lead to undesired unification of edge with the face. + Standard_Boolean bUseAddTol = Standard_True; + + Standard_Real aTS[2]; + Bnd_Box aPBBox; + aPB->ShrunkData(aTS[0], aTS[1], aPBBox); + + // Middle point + gp_Pnt aPOnE; + // Tangent vector in the middle point + gp_Vec aVETgt; + aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt); + if (aVETgt.SquareMagnitude() < gp::Resolution()) + continue; + + aProjPS.Perform(aPOnE); + if (!aProjPS.NbPoints()) + continue; + + // Check the distance in the middle point, using the max vertices + // tolerance as the criteria. + const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1)); + const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2)); + + // In the Self-Interference check mode we are interested in real + // intersections only, so use only the real tolerance of edges, + // no need to use the extended tolerance. + Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue : + 2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2))); + + if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue) + continue; + + Standard_Real U, V; + aProjPS.LowerDistanceParameters(U, V); + if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V))) + continue; + + if (aSurfAdaptor.GetType() != GeomAbs_Plane || + aBAC.GetType() != GeomAbs_Line) + { + gp_Pnt aPOnS = aProjPS.NearestPoint(); + gp_Vec aVFNorm(aPOnS, aPOnE); + if (aVFNorm.SquareMagnitude() > gp::Resolution()) + { + // Angle between vectors should be close to 90 degrees. + // We allow deviation of 10 degrees. + Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized()); + if (Abs(aCos) > 0.17365) + bUseAddTol = Standard_False; + } + } + + // Compute an addition to Fuzzy value + Standard_Real aTolAdd = 0.0; + if (bUseAddTol) + { + // Compute the distance from the bounding points of the edge + // to the face and use the maximal of these distances as a + // fuzzy tolerance for the intersection. + // Use the maximal tolerance of the pave block's vertices + // as a max criteria for the computed distance. + + for (Standard_Integer iP = 0; iP < 2; ++iP) + { + gp_Pnt aP = aBAC.Value(aTS[iP]); + aProjPS.Perform(aP); + if (aProjPS.NbPoints()) + { + Standard_Real aDistEF = aProjPS.LowerDistance(); + if (aDistEF < aTolCheck && aDistEF > aTolAdd) + aTolAdd = aDistEF; + } + } + if (aTolAdd > 0.) + { + aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF)); + if (aTolAdd < 0.) + aTolAdd = 0.; + } + } + + Standard_Boolean bIntersect = aTolAdd > 0; + if (!bIntersect) + { + const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF); + bIntersect = !pMPB || !(pMPB->Contains(aPB)); + } + + if (bIntersect) + { + // Prepare pair for intersection + BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Append1(); + aEdgeFace.SetIndices(nE, nF); + aEdgeFace.SetPaveBlock(aPB); + aEdgeFace.SetEdge(aE); + aEdgeFace.SetFace(aF); + aEdgeFace.SetTolE (BRep_Tool::Tolerance (aE) + aTolAdd / 2.); + aEdgeFace.SetTolF (BRep_Tool::Tolerance (aF) + aTolAdd / 2.); + aEdgeFace.UseQuickCoincidenceCheck(Standard_True); + aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter())); + aEdgeFace.SetProgressIndicator(myProgressIndicator); + } + } + } + + Standard_Integer aNbEFs = aVEdgeFace.Length(); + if (!aNbEFs) + return; + + aPBMap.Clear(); + anAlloc->Reset(); + + // Perform intersection of the found pairs + BOPAlgo_EdgeFaceCnt::Perform (myRunParallel, aVEdgeFace, myContext); + + BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF(); + if (theAddInterf && aEFs.IsEmpty()) + aEFs.SetIncrement(10); + + // Analyze the results of intersection looking for TopAbs_EDGE + // intersection type only. + + // Collect all pairs for common block creation + BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc); + + for (Standard_Integer i = 0; i < aNbEFs; ++i) + { + BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i); + if (!anEdgeFace.IsDone()) + continue; + + const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts(); + if (aCParts.Length() != 1) + continue; + + const IntTools_CommonPrt& aCP = aCParts(1); + if (aCP.Type() != TopAbs_EDGE) + continue; + + Standard_Integer nE, nF; + anEdgeFace.Indices(nE, nF); + if (theAddInterf) + { + // Add interference + BOPDS_InterfEF& aEF = aEFs.Append1(); + aEF.SetIndices(nE, nF); + aEF.SetCommonPart(aCP); + myDS->AddInterf(nE, nF); + } + + const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock(); + // Update face information with new IN pave block + myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB); + if (theAddInterf) + // Fill map for common blocks creation + BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc); + } + + if (aMPBLI.Extent()) + // Create new common blocks for coinciding pairs + BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS); +} diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index d453638f46..caef1458e5 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -438,7 +438,8 @@ void BOPAlgo_PaveFiller::MakeBlocks() aDMBV.Clear(); aMVTol.Clear(); // - myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn); + BOPDS_MapOfPaveBlock aMPBCommon; + myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon); myDS->SharedEdges(nF1, nF2, aLSE, aAllocator); // 1. Treat Points @@ -552,7 +553,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() continue; } // - bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut); + bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut); if (bExist) { if (aMPBAdd.Add(aPBOut)) { Standard_Boolean bInBothFaces = Standard_True; @@ -1266,6 +1267,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock const BOPDS_Curve& theNC, const Standard_Real theTolR3D, const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn, + const BOPDS_MapOfPaveBlock& /*theMPBCommon*/, Handle(BOPDS_PaveBlock&) aPBOut) { Standard_Boolean bRet; @@ -1276,22 +1278,28 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock // bRet=Standard_False; const IntTools_Curve& aIC=theNC.Curve(); + //Standard_Real aTolCheck = theTolR3D + myFuzzyValue; // thePB->Range(aT1, aT2); thePB->Indices(nV11, nV12); + + const Standard_Real aTolV11 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV11))); + const Standard_Real aTolV12 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV12))); + const Standard_Real aTolV1 = Max(aTolV11, aTolV12); + //first point aIC.D0(aT1, aP1); aBoxP1.Add(aP1); - aBoxP1.Enlarge(theTolR3D); + aBoxP1.Enlarge(aTolV11); //intermediate point aTm=IntTools_Tools::IntermediatePoint (aT1, aT2); aIC.D0(aTm, aPm); aBoxPm.Add(aPm); - aBoxPm.Enlarge(theTolR3D); + //aBoxPm.Enlarge(theTolR3D); //last point aIC.D0(aT2, aP2); aBoxP2.Add(aP2); - aBoxP2.Enlarge(theTolR3D); + aBoxP2.Enlarge(aTolV12); // aNbPB = theMPBOnIn.Extent(); for (i = 1; i <= aNbPB; ++i) { @@ -1300,6 +1308,10 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock nSp=aPB->Edge(); if (nSp < 0) continue; + const Standard_Real aTolV21 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV21))); + const Standard_Real aTolV22 = BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&myDS->Shape(nV22))); + const Standard_Real aTolV2 = Max(aTolV21, aTolV22); + const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp); const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape())); const Bnd_Box& aBoxSp=aSISp.Box(); @@ -1309,19 +1321,31 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : (!aBoxSp.IsOut(aBoxP2) ? 1 : 0); if (iFlag1 && iFlag2) { - if (aBoxSp.IsOut(aBoxPm) || myContext->ComputePE(aPm, - theTolR3D, + Standard_Real aRealTol = theTolR3D + myFuzzyValue; + Bnd_Box aBoxTmp = aBoxPm; + if (myDS->IsCommonBlock(aPB)) + { + aRealTol = Max(aRealTol, Max(aTolV1, aTolV2)); + //if (theMPBCommon.Contains (aPB)) + // // for an edge, which is a common block with a face, + // // increase the chance to coincide with section curve + // aRealTol *= 2.; + } + + aBoxTmp.Enlarge (aRealTol); + if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm, + aRealTol, aSp, aTx)) { continue; } // if (iFlag1 == 1) { - iFlag1 = !myContext->ComputePE(aP1, theTolR3D, aSp, aTx); + iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx); } // if (iFlag2 == 1) { - iFlag2 = !myContext->ComputePE(aP2, theTolR3D, aSp, aTx); + iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx); } // if (iFlag1 && iFlag2) { diff --git a/src/BOPDS/BOPDS.cdl b/src/BOPDS/BOPDS.cdl index 2094b7418e..296ffea329 100644 --- a/src/BOPDS/BOPDS.cdl +++ b/src/BOPDS/BOPDS.cdl @@ -82,7 +82,8 @@ is imported VectorOfFaceInfo from BOPDS; imported MapOfPave from BOPDS; imported IndexedDataMapOfPaveBlockListOfPaveBlock from BOPDS; - imported DataMapOfIntegerListOfPaveBlock from BOPDS; + imported DataMapOfIntegerListOfPaveBlock from BOPDS; + imported DataMapOfIntegerMapOfPaveBlock from BOPDS; imported IndexedMapOfPaveBlock from BOPDS; imported IndexedDataMapOfPaveBlockListOfInteger from BOPDS; imported IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS; diff --git a/src/BOPDS/BOPDS_DS.cdl b/src/BOPDS/BOPDS_DS.cdl index 94b1193d35..f25768ed05 100644 --- a/src/BOPDS/BOPDS_DS.cdl +++ b/src/BOPDS/BOPDS_DS.cdl @@ -397,7 +397,8 @@ is theF1:Integer from Standard; theF2:Integer from Standard; theMI:out MapOfInteger from BOPCol; - aMPB: out IndexedMapOfPaveBlock from BOPDS); + theMPB: out IndexedMapOfPaveBlock from BOPDS; + theMPBCommon: out MapOfPaveBlock from BOPDS); ---Purpose: --- Returns the indices of vertices and pave blocks --- that are On/In for the faces with indices theF1, theF2 diff --git a/src/BOPDS/BOPDS_DS.cxx b/src/BOPDS/BOPDS_DS.cxx index d3364dcf66..cfba55dc1b 100644 --- a/src/BOPDS/BOPDS_DS.cxx +++ b/src/BOPDS/BOPDS_DS.cxx @@ -1535,7 +1535,8 @@ void BOPDS_DS::VerticesOnIn (const Standard_Integer nF1, const Standard_Integer nF2, BOPCol_MapOfInteger& aMI, - BOPDS_IndexedMapOfPaveBlock& aMPB)const + BOPDS_IndexedMapOfPaveBlock& aMPB, + BOPDS_MapOfPaveBlock& theMPBCommon) const { Standard_Integer i, j, nV, nV1, nV2, aNbPB; BOPCol_MapIteratorOfMapOfInteger aIt; @@ -1557,6 +1558,10 @@ void BOPDS_DS::VerticesOnIn aPB->Indices(nV1, nV2); aMI.Add(nV1); aMI.Add(nV2); + if (i < 2) { + if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB)) + theMPBCommon.Add(aPB); + } } } // diff --git a/src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx b/src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx new file mode 100644 index 0000000000..26ccb098fb --- /dev/null +++ b/src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx @@ -0,0 +1,24 @@ +// Created by: Eugeny MALTCHIKOV +// Copyright (c) 1999-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef BOPDS_DataMapOfIntegerMapOfPaveBlock_HeaderFile +#define BOPDS_DataMapOfIntegerMapOfPaveBlock_HeaderFile + +#include +#include +#include + +typedef NCollection_DataMap BOPDS_DataMapOfIntegerMapOfPaveBlock; + +#endif diff --git a/src/BOPDS/FILES b/src/BOPDS/FILES index 9c4dc2f1ce..0f6939fc2f 100644 --- a/src/BOPDS/FILES +++ b/src/BOPDS/FILES @@ -32,6 +32,7 @@ BOPDS_DataMapOfShapeCoupleOfPaveBlocks.hxx BOPDS_MapOfPave.hxx BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx BOPDS_DataMapOfIntegerListOfPaveBlock.hxx +BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx BOPDS_IndexedMapOfPaveBlock.hxx BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks.hxx diff --git a/src/IntTools/IntTools_EdgeFace.cdl b/src/IntTools/IntTools_EdgeFace.cdl index 73303e9e3c..dbae187274 100644 --- a/src/IntTools/IntTools_EdgeFace.cdl +++ b/src/IntTools/IntTools_EdgeFace.cdl @@ -168,6 +168,17 @@ is aD:out Real from Standard) returns Boolean from Standard; + UseQuickCoincidenceCheck (me:out; + theFlag: Boolean from Standard); + ---Purpose: + --- Enables the option for quick coincidence check for the edge and face. + --- Disabled by default. + + IsCoincidenceCheckedQuickly (me) + returns Boolean from Standard; + ---Purpose: + --- Returns true if quick coincidence check was enabled. + ------------------------------------------------------- -- Block of protected methods of the algorithm -- ------------------------------------------------------- @@ -247,7 +258,12 @@ is aCP: CommonPrt from IntTools; aTX:out Real from Standard) returns Boolean from Standard - is protected; + is protected; + + IsCoincident(me:out) + returns Boolean from Standard + is protected; + ---Purpose: Checks if the edge is in the face. fields -- Data @@ -287,6 +303,8 @@ fields myPar1 : Real from Standard; myParallel : Boolean from Standard; - myRange : Range from IntTools; + myRange : Range from IntTools; + + myQuickCoincidenceCheck : Boolean from Standard; end EdgeFace; diff --git a/src/IntTools/IntTools_EdgeFace.cxx b/src/IntTools/IntTools_EdgeFace.cxx index 399e8b42bc..8b1372d858 100644 --- a/src/IntTools/IntTools_EdgeFace.cxx +++ b/src/IntTools/IntTools_EdgeFace.cxx @@ -264,6 +264,103 @@ const IntTools_Range& IntTools_EdgeFace::Range() const return myRange; } +//======================================================================= +//function : UseQuickCoincidenceCheck +//purpose : +//======================================================================= +void IntTools_EdgeFace::UseQuickCoincidenceCheck(const Standard_Boolean bFlag) +{ + myQuickCoincidenceCheck=bFlag; +} + +//======================================================================= +//function : IsCoincidenceCheckedQuickly +//purpose : +//======================================================================= +Standard_Boolean IntTools_EdgeFace::IsCoincidenceCheckedQuickly() const +{ + return myQuickCoincidenceCheck; +} + +//======================================================================= +//function : IsCoincident +//purpose : +//======================================================================= +Standard_Boolean IntTools_EdgeFace::IsCoincident() +{ + Standard_Integer i, iCnt; + Standard_Real dT, aT, aD, aT1, aT2, aU, aV; + + gp_Pnt aP; + TopAbs_State aState; + gp_Pnt2d aP2d; + // + GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace); + + const Standard_Integer aNbSeg=23; + const Standard_Real aTresh=0.5; + const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25), + aTreshIdxL = RealToInt((aNbSeg+1)*0.75); + const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(myFace); + + aT1=myRange.First(); + aT2=myRange.Last(); + dT=(aT2-aT1)/aNbSeg; + // + Standard_Boolean isClassified = Standard_False; + iCnt=0; + for(i=0; i <= aNbSeg; ++i) { + aT = aT1+i*dT; + aP=myC.Value(aT); + // + aProjector.Perform(aP); + if (!aProjector.IsDone()) { + continue; + } + // + + aD=aProjector.LowerDistance(); + if (aD>myCriteria) { + continue; + } + // + + ++iCnt; + + //We classify only three points: in the begin, in the + //end and in the middle of the edge. + //However, exact middle point (when i == (aNbSeg + 1)/2) + //can be unprojectable. Therefore, it will not be able to + //be classified. Therefore, points with indexes in + //[aTreshIdxF, aTreshIdxL] range are made available + //for classification. + //isClassified == TRUE if MIDDLE point has been choosen and + //classified correctly. + + if(((0 < i) && (i < aTreshIdxF)) || ((aTreshIdxL < i ) && (i < aNbSeg))) + continue; + + if(isClassified && (i != aNbSeg)) + continue; + + aProjector.LowerDistanceParameters(aU, aV); + aP2d.SetX(aU); + aP2d.SetY(aV); + + IntTools_FClass2d& aClass2d=myContext->FClass2d(myFace); + aState = aClass2d.Perform(aP2d); + + if(aState == TopAbs_OUT) + return Standard_False; + + if(i != 0) + isClassified = Standard_True; + } + // + const Standard_Real aCoeff=(Standard_Real)iCnt/((Standard_Real)aNbSeg+1); + return (aCoeff > aTresh); +} + //======================================================================= //function : CheckData //purpose : @@ -1255,6 +1352,16 @@ void IntTools_EdgeFace::Perform() myFClass2d.Init(myFace, 1.e-6); } + if (myQuickCoincidenceCheck) { + if (IsCoincident()) { + aCommonPrt.SetType(TopAbs_EDGE); + aCommonPrt.SetRange1(myRange.First(), myRange.Last()); + mySeqOfCommonPrts.Append(aCommonPrt); + myIsDone=Standard_True; + return; + } + } + IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF); anIntersector.SetBeanParameters(myRange.First(), myRange.Last()); // diff --git a/tests/boolean/bfuse_complex/E4 b/tests/boolean/bfuse_complex/E4 index 386f94c734..d3d8443ee1 100644 --- a/tests/boolean/bfuse_complex/E4 +++ b/tests/boolean/bfuse_complex/E4 @@ -1,7 +1,7 @@ # Original bug : pro14260 # Date : 21 Sept 98 -puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO #22911 ALL: Error : The area of the resulting shape is" +# puts "TODO #22911 ALL: Faulty shapes in variables faulty_1 to faulty_" +# puts "TODO #22911 ALL: Error : The area of the resulting shape is" restore [locate_data_file CTO900_pro14260c.rle] c restore [locate_data_file pro14260d.rle] d diff --git a/tests/boolean/bfuse_complex/F5 b/tests/boolean/bfuse_complex/F5 index c075d2b074..77374e4e16 100644 --- a/tests/boolean/bfuse_complex/F5 +++ b/tests/boolean/bfuse_complex/F5 @@ -1,6 +1,6 @@ # Original bug : pro10658 # Date : 24mar98 -puts "TODO ALL Error : The area of the resulting shape is" +# puts "TODO ALL Error : The area of the resulting shape is" restore [locate_data_file CTO900_pro10658a.rle] a restore [locate_data_file pro10658b.rle] b diff --git a/tests/boolean/bfuse_complex/Q2 b/tests/boolean/bfuse_complex/Q2 index 45a88e0f0d..6548612dba 100644 --- a/tests/boolean/bfuse_complex/Q2 +++ b/tests/boolean/bfuse_complex/Q2 @@ -1,5 +1,5 @@ # pro10658 -puts "TODO ALL Error : The area of the resulting shape is" +# puts "TODO ALL Error : The area of the resulting shape is" restore [locate_data_file CTO900_pro10658a.rle] a restore [locate_data_file pro10658b.rle] b diff --git a/tests/boolean/bsection/R2 b/tests/boolean/bsection/R2 index d51b9eee28..4d4142cd96 100644 --- a/tests/boolean/bsection/R2 +++ b/tests/boolean/bsection/R2 @@ -10,4 +10,4 @@ updatetolerance b 1 bsection result a b -set length 135.096 +set length 130.625 diff --git a/tests/boolean/bsection/R8 b/tests/boolean/bsection/R8 index 396303f652..2a59a52696 100644 --- a/tests/boolean/bsection/R8 +++ b/tests/boolean/bsection/R8 @@ -8,4 +8,4 @@ restore [locate_data_file ger61235b.brep] object bsection result object tool -set length 11.8242 +set length 16.4762 diff --git a/tests/bugs/modalg_4/bug697_2 b/tests/bugs/modalg_4/bug697_2 index 04206198eb..381b5af369 100755 --- a/tests/bugs/modalg_4/bug697_2 +++ b/tests/bugs/modalg_4/bug697_2 @@ -1,5 +1,5 @@ -puts "TODO OCC25829 ALL: Error : The square of result shape is" -puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" +#puts "TODO OCC25829 ALL: Error : The square of result shape is" +#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" puts "============" puts "OCC697" diff --git a/tests/bugs/modalg_4/bug697_4 b/tests/bugs/modalg_4/bug697_4 index 5621debb59..625c847f6a 100755 --- a/tests/bugs/modalg_4/bug697_4 +++ b/tests/bugs/modalg_4/bug697_4 @@ -1,5 +1,5 @@ -puts "TODO OCC25829 ALL: Error : The square of result shape is" -puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" +#puts "TODO OCC25829 ALL: Error : The square of result shape is" +#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" puts "============" puts "OCC697" diff --git a/tests/bugs/modalg_4/bug697_7 b/tests/bugs/modalg_4/bug697_7 index dc277be079..0233e84b09 100755 --- a/tests/bugs/modalg_4/bug697_7 +++ b/tests/bugs/modalg_4/bug697_7 @@ -1,5 +1,5 @@ -puts "TODO OCC25829 ALL: Error : The square of result shape is" -puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" +#puts "TODO OCC25829 ALL: Error : The square of result shape is" +#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" puts "============" puts "OCC697" diff --git a/tests/bugs/modalg_4/bug697_8 b/tests/bugs/modalg_4/bug697_8 index 916774c0ad..2df9322348 100755 --- a/tests/bugs/modalg_4/bug697_8 +++ b/tests/bugs/modalg_4/bug697_8 @@ -1,5 +1,5 @@ -puts "TODO OCC25829 ALL: Error : The square of result shape is" -puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" +#puts "TODO OCC25829 ALL: Error : The square of result shape is" +#puts "TODO OCC25829 ALL: Faulty shapes in variables faulty_1 to" puts "============" puts "OCC697" diff --git a/tests/bugs/modalg_6/bug27761 b/tests/bugs/modalg_6/bug27761 index abf6323da3..8c41804d31 100644 --- a/tests/bugs/modalg_6/bug27761 +++ b/tests/bugs/modalg_6/bug27761 @@ -13,4 +13,4 @@ bsection result c1 c2 checkshape result # approximate theoretical length of the result -set length 0.00192547 +set length 0.00200173 diff --git a/tests/bugs/modalg_7/bug31662 b/tests/bugs/modalg_7/bug31662 new file mode 100644 index 0000000000..d1bd828189 --- /dev/null +++ b/tests/bugs/modalg_7/bug31662 @@ -0,0 +1,31 @@ +puts "=============================================================================================" +puts "0031662: Modeling Algorithms - Incomplete result of section operation" +puts "=============================================================================================" +puts "" + +restore [locate_data_file bug31662_Surface_0.brep] s0 +restore [locate_data_file bug31662_Surface_1.brep] s1 +box bx -4 -7 -1 40 15 10 + +bclearobjects +bcleartools +baddobjects bx +baddtools s0 s1 +bfillds + +bbop r4 4 + +checkshape r4 +checksection r4 -r 0 +checkprops r4 -l 70.3856 + +bbuild rgf + +explode rgf so +copy rgf_2 result -ni + +checkshape result +checknbshapes result -wire 254 -face 254 -shell 1 -solid 1 +checkprops result -s 668.352 -v 774.749 + +checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_2/bug26_2 b/tests/bugs/moddata_2/bug26_2 index c9f5ec6105..c620be34ee 100755 --- a/tests/bugs/moddata_2/bug26_2 +++ b/tests/bugs/moddata_2/bug26_2 @@ -1,4 +1,4 @@ -puts "TODO CR25432 ALL: Error : The square of result shape is" +#puts "TODO CR25432 ALL: Error : The square of result shape is" puts "================" puts "OCC26"