]> OCCT Git - occt-copy.git/commitdiff
0031662: Modeling Algorithms - Incomplete result of section operation CR0_691_FixS
authoremv <emv@opencascade.com>
Thu, 6 Aug 2020 12:30:58 +0000 (15:30 +0300)
committeremv <emv@opencascade.com>
Mon, 10 Aug 2020 07:04:13 +0000 (10:04 +0300)
BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence.

23 files changed:
src/BOPAlgo/BOPAlgo_PaveFiller.cdl
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPDS/BOPDS.cdl
src/BOPDS/BOPDS_DS.cdl
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DataMapOfIntegerMapOfPaveBlock.hxx [new file with mode: 0644]
src/BOPDS/FILES
src/IntTools/IntTools_EdgeFace.cdl
src/IntTools/IntTools_EdgeFace.cxx
tests/boolean/bfuse_complex/E4
tests/boolean/bfuse_complex/F5
tests/boolean/bfuse_complex/Q2
tests/boolean/bsection/R2
tests/boolean/bsection/R8
tests/bugs/modalg_4/bug697_2
tests/bugs/modalg_4/bug697_4
tests/bugs/modalg_4/bug697_7
tests/bugs/modalg_4/bug697_8
tests/bugs/modalg_6/bug27761
tests/bugs/modalg_7/bug31662 [new file with mode: 0644]
tests/bugs/moddata_2/bug26_2

index c701a9ee1981e72c810a5f15278c59ce58432cea..268890add5db1867b809a66c3d36c3a2034b07ac 100644 (file)
@@ -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;
index 426ed2c6178813748e5a8b957f7c8f5e093bc337..7190bad901cdc500af8d704e2786e1b8a3666e90 100644 (file)
@@ -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();
index b240574332082ce74a37dc15f701e7f8b75245b1..e00f7a48f9876c99fac7622aceecdbfc74fd87c9 100644 (file)
@@ -36,6 +36,7 @@
 #include <IntTools_SequenceOfCommonPrts.hxx>
 #include <IntTools_CommonPrt.hxx>
 //
+#include <BOPCol_BoxBndTree.hxx>
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_NCVector.hxx>
 #include <BOPCol_Parallel.hxx>
 #include <BOPDS_CoupleOfPaveBlocks.hxx>
 //
 #include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools2D.hxx>
 //
 #include <BOPAlgo_Tools.hxx>
 
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <TopoDS.hxx>
+
+
 //=======================================================================
 //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<Standard_Integer, Bnd_Box> aBBTree;
+  NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> 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);
+}
index d453638f46534de78672bfefecc344b8caf98ac4..caef1458e5c9c43a9281661a89327f106b539f09 100644 (file)
@@ -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) {
index 2094b7418e11b5038c80840713ab6b084e83fd46..296ffea3296a004b21d7e26c0ab9adf68ba18f59 100644 (file)
@@ -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;
index 94b1193d3580120abab2657c53bf517e2d79d4c7..f25768ed05ea8bf04660060699c488e7c7acf266 100644 (file)
@@ -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  
index d3364dcf668ae78c48f4429f3d17ee8a5796a64c..cfba55dc1bd212fd59e9cc11a63635ecdb2f9d8b 100644 (file)
@@ -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 (file)
index 0000000..26ccb09
--- /dev/null
@@ -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 <NCollection_DataMap.hxx>
+#include <TColStd_MapTransientHasher.hxx>
+#include <BOPDS_MapOfPaveBlock.hxx>
+
+typedef NCollection_DataMap<Standard_Integer, BOPDS_MapOfPaveBlock, TColStd_MapIntegerHasher> BOPDS_DataMapOfIntegerMapOfPaveBlock; 
+#endif
index 9c4dc2f1ce35545ea51141ddd4c76693964efaa2..0f6939fc2f263529ccb570eac1cdb10d37f44ccf 100644 (file)
@@ -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
index 73303e9e3c5757f8cac8bad22ca6046f130e39ef..dbae1872746648706ab1e1be9a03449dfd87ff4e 100644 (file)
@@ -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;
index 399e8b42bc806e72f4473d82a5175e417bf5f108..8b1372d8588ad5ac442b7607690fb1855ac06346 100644 (file)
@@ -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());
   //
index 386f94c73490489298658730cebbbadd1fe47913..d3d8443ee15f33b2d056eae25e42c36bea008a00 100644 (file)
@@ -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
index c075d2b0740b14924a54ce2f96420f36c7f807fb..77374e4e16631502b8873e904510f8d92df1c6fb 100644 (file)
@@ -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
 
index 45a88e0f0d157ab2c20293ee0ccb2f652f2a7a54..6548612dba8f4c43a5d4b66d140725738f4b3565 100644 (file)
@@ -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
 
index d51b9eee28473fe172373ff830d64e8beef1591a..4d4142cd961f53e7e3097aeb8ff664fb962658cc 100644 (file)
@@ -10,4 +10,4 @@ updatetolerance b 1
 
 bsection result a b
 
-set length 135.096
+set length 130.625
index 396303f6526e077dd312247f4e75caee64650c55..2a59a52696eb381baa1e850ce43a2f93e85fbb51 100644 (file)
@@ -8,4 +8,4 @@ restore [locate_data_file ger61235b.brep] object
 
 bsection result object tool 
 
-set length 11.8242
+set length 16.4762
index 04206198ebf5820a90941c3a02281381f3a1922f..381b5af3697483c66d22810fe9e0aaecdd4306ae 100755 (executable)
@@ -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"
index 5621debb59c3db2ac8c151aae2634ec605f39214..625c847f6a5b0328fd17719e3e00f14036de6e12 100755 (executable)
@@ -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"
index dc277be079686fd9dddad05ccdb321b7e937d572..0233e84b09ac36f7495b396d709157b9a1e25516 100755 (executable)
@@ -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"
index 916774c0ada4eeb102a8d47d16955f7218b848e0..2df93223481c2b8c9e804eebb41faedffe933ccf 100755 (executable)
@@ -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"
index abf6323da32fb61f49a14fcabe511fae0bce8daf..8c41804d31b3aec88a6319568743035f6e002844 100644 (file)
@@ -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 (file)
index 0000000..d1bd828
--- /dev/null
@@ -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
index c9f5ec61057c8009428b56d22452d180fbfaacbb..c620be34ee8e80eee94ec002ddb362ff3f10499a 100755 (executable)
@@ -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"