]> OCCT Git - occt.git/commitdiff
0028486: Fuse of several solids fails due to presence of common zones between faces
authoremv <emv@opencascade.com>
Tue, 21 Feb 2017 08:39:29 +0000 (11:39 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 16 Mar 2017 07:47:51 +0000 (10:47 +0300)
1. Exception in intersection of two analytical faces has been fixed by adding a simple check on number of vertices
in the resulting analytical curve;

2. Projection of the Circle on the Cone now checks if the Circle's normal direction is parallel to the Cone direction.
If it is not, the different, more advanced, algorithm will be used for projection - ProjLib_ComputeApprox;

3. Intersection of the Edge with the Face (IntTools_EdgeFace algorithm) in QuickCoincidenceCheck mode has been fixed to
avoid the checking of the type of the intersection result if the coincidence check gives the positive result;

4. All common IN edges of the intersecting faces has been added for intersection with section edges to avoid self-intersection in the result;

5. Post treatment of the section edges in Boolean operations has been improved with the new stage which treats the possible
common zones, not detected by the intersection algorithm, between faces by intersecting each section edge with all faces,
not participated in its creation, and in case of coincidence putting it as IN edge into FaceInfo structure of the face.
The new function has been implemented for that - BOPAlgo_PaveFiller::PutSEInOtherFaces().

6. Checking for the SameDomain splits of faces in Boolean Operations has been modified to process the pairs of faces in
which both the section curves and common zones are present.

7. Adjustment of the test case boolean gdml_private ZH3 as improvement.

8. Test cases for the issue.

9. Test cases for the parent issue - 0026789.

14 files changed:
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/IntPatch/IntPatch_ALineToWLine.cxx
src/IntTools/IntTools_EdgeFace.cxx
src/ProjLib/ProjLib_Cone.cxx
tests/boolean/gdml_private/ZH3
tests/bugs/modalg_6/bug26789_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug26789_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug26789_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug28486_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug28486_2 [new file with mode: 0644]
tests/bugs/modalg_6/bug28486_3 [new file with mode: 0644]
tests/bugs/modalg_6/bug28486_4 [new file with mode: 0644]

index 14275140239728de846acee3c5a7279de17c4599..d6ff8f30827d4e5eda128cbe10e1e3c9087e5e3e 100644 (file)
@@ -475,7 +475,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
 void BOPAlgo_Builder::FillSameDomainFaces()
 {
   Standard_Boolean bFlag;
-  Standard_Integer i, j, k, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
+  Standard_Integer i, j, k, aNbFFs, nF1, nF2, aNbS;
   Handle(NCollection_BaseAllocator) aAllocator;
   BOPCol_ListIteratorOfListOfShape aItF;
   BOPCol_MapOfShape aMFence;
@@ -495,30 +495,6 @@ void BOPAlgo_Builder::FillSameDomainFaces()
     const BOPDS_InterfFF& aFF=aFFs(i);
     aFF.Indices(nF1, nF2);
     //
-    const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
-    aNbCurves=aCurves.Extent();
-    if (aNbCurves) {
-      //
-      bFlag=Standard_False;
-      for (j=0; j<aNbCurves; ++j) {
-        const BOPDS_Curve& aNC=aCurves.Value(j);
-        bFlag=aNC.HasEdge();
-        if (bFlag) {
-          break;
-        }
-      }
-      if (bFlag) {
-        continue;
-      }
-      //continue;
-    }
-    //
-    const BOPDS_VectorOfPoint& aPoints=aFF.Points();
-    aNbPoints=aPoints.Extent();
-    if (aNbPoints) {
-      continue;
-    }
-    //
     if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
       continue;
     }
index 9abf7bc75fada991c7b3320cd514580aed28c2cf..7b07a3c83c41c9a203a35a94a65cd6b7bedcd201 100644 (file)
@@ -398,6 +398,14 @@ protected:
                                             Standard_Real& theSLast,
                                             Bnd_Box& theBox);
 
+  //! Treatment of the possible common zones, not detected by the
+  //! Face/Face intersection algorithm, by intersection of each section edge
+  //! with all faces not participated in creation of that section edge.
+  //! If the intersection says that the section edge is lying on the face
+  //! it will be added into FaceInfo structure of the face as IN edge
+  //! and will be used for splitting.
+  Standard_EXPORT void PutSEInOtherFaces();
+
   BOPCol_ListOfShape myArguments;
   BOPDS_PDS myDS;
   BOPDS_PIterator myIterator;
index d114cefa51580cef210cc781495c1baeaee2b6be..956a33069fe43fd0288c9e321cd1530a5676582a 100644 (file)
@@ -453,7 +453,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     //
     myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
     myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
-    
+    //
+    Standard_Boolean bHasRealSectionEdge = Standard_False;
     // 1. Treat Points
     for (j=0; j<aNbP; ++j) {
       TopoDS_Vertex aV;
@@ -577,7 +578,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
         Standard_Real aTolNew;
         bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
         if (bExist) {
-          if (aMPBAdd.Add(aPBOut)) {
+          if (!aMPBAdd.Contains(aPBOut)) {
             Standard_Boolean bInBothFaces = Standard_True;
             if (!myDS->IsCommonBlock(aPBOut)) {
               Standard_Integer nE;
@@ -600,6 +601,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
                               aFI2.PaveBlocksIn().Contains(aPBOut));
             }
             if (!bInBothFaces) {
+              aMPBAdd.Add(aPBOut);
               PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
             }
           }
@@ -627,6 +629,8 @@ void BOPAlgo_PaveFiller::MakeBlocks()
         //
         aMVTol.UnBind(nV1);
         aMVTol.UnBind(nV2);
+        //
+        bHasRealSectionEdge = Standard_True;
       }
       //
       aLPBC.RemoveFirst();
@@ -655,6 +659,28 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     }
     //
     ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
+    //
+    // If the pair of faces has produced any real section edges
+    // it is necessary to check if these edges do not intersect
+    // any common IN edges of the faces. For that, all such edges
+    // are added for Post Treatment along with sections edges.
+    if (bHasRealSectionEdge) {
+      const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
+      const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
+      //
+      // For simplicity add all IN edges into the first set of section curves.
+      // These existing edges will be removed from the set on the post treatment
+      // stage in the UpdateFaceInfo function.
+      BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks();
+      //
+      Standard_Integer aNbIn1 = aMPBIn1.Extent();
+      for (j = 1; j <= aNbIn1; ++j) {
+        const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j);
+        if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) {
+          PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC);
+        }
+      }
+    }
   }//for (i=0; i<aNbFF; ++i) {
   // 
   // post treatment
@@ -670,6 +696,11 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   UpdateFaceInfo(aDMExEdges, aDMNewSD);
   //Update all pave blocks
   UpdatePaveBlocks(aDMNewSD);
+  //
+  // Treat possible common zones by trying to put each section edge
+  // into all faces, not participated in creation of that edge, as IN edge
+  PutSEInOtherFaces();
+  //
   //-----------------------------------------------------scope t
   aMF.Clear();
   aMVStick.Clear();
@@ -2929,3 +2960,116 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
     }
   }
 }
+
+//=======================================================================
+//function : PutSEInOtherFaces
+//purpose  : 
+//=======================================================================
+void BOPAlgo_PaveFiller::PutSEInOtherFaces()
+{
+  // Try to intersect each section edge with the faces
+  // not participated in its creation
+  //
+  // 1. Get all section edges
+  BOPDS_IndexedMapOfPaveBlock aMPBScAll;
+  //
+  BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
+  Standard_Integer i, j, aNbFF = aFFs.Extent();
+  //
+  for (i = 0; i < aNbFF; ++i) {
+    const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
+    Standard_Integer aNbC = aVNC.Extent();
+    for (j = 0; j < aNbC; ++j) {
+      const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
+      BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
+      for (; aItPB.More(); aItPB.Next()) {
+        aMPBScAll.Add(aItPB.Value());
+      }
+    }
+  }
+  //
+  Standard_Integer aNbPBSc = aMPBScAll.Extent();
+  //
+  // 2. Loop for all faces and check each section curve
+  Standard_Integer aNbS = myDS->NbSourceShapes();
+  for (i = 0; i < aNbS; ++i) {
+    const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+    if (aSI.ShapeType() != TopAbs_FACE) {
+      continue;
+    }
+    //
+    const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
+    BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
+    //
+    // IN edges to add new ones
+    BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn();
+    // Section edges to check the participation of the face
+    const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc();
+    //
+    // Get vertices of the face to check that vertices of the
+    // processed section edge belong to the face
+    BOPCol_MapOfInteger aMFVerts;
+    // Get vertices from ON, IN and Sc pave blocks of the face
+    for (j = 0; j < 3; ++j) {
+      const BOPDS_IndexedMapOfPaveBlock& aMPB =
+        !j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc);
+      Standard_Integer aNbPB = aMPB.Extent();
+      for (Standard_Integer k = 1; k <= aNbPB; ++k) {
+        const Handle(BOPDS_PaveBlock)& aPB = aMPB(k);
+        aMFVerts.Add(aPB->Pave1().Index());
+        aMFVerts.Add(aPB->Pave2().Index());
+      }
+    }
+    // Add ON, IN and Sc vertices of the face
+    for (j = 0; j < 3; ++j) {
+      const BOPCol_MapOfInteger& aMFV = !j ? aFI.VerticesOn() :
+        (j == 1 ? aFI.VerticesIn() : aFI.VerticesSc());
+      BOPCol_MapIteratorOfMapOfInteger aItMI(aMFV);
+      for (; aItMI.More(); aItMI.Next()) {
+        aMFVerts.Add(aItMI.Value());
+      }
+    }
+    //
+    // Check each section edge for possible belonging to the face
+    for (j = 1; j <= aNbPBSc; ++j) {
+      const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j);
+      if (aMFPBSc.Contains(aPB)) {
+        continue;
+      }
+      //
+      // Both vertices of the section edge should belong to the face
+      if (!aMFVerts.Contains(aPB->Pave1().Index()) ||
+        !aMFVerts.Contains(aPB->Pave2().Index())) {
+        continue;
+      }
+      //
+      // Perform intersection
+      const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
+      //
+      IntTools_EdgeFace anEFInt;
+      anEFInt.SetEdge(aE);
+      anEFInt.SetFace(aF);
+      anEFInt.SetFuzzyValue(myFuzzyValue);
+      anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
+      anEFInt.SetContext(myContext);
+      anEFInt.UseQuickCoincidenceCheck(Standard_True);
+      anEFInt.Perform();
+      //
+      const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts();
+      if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) {
+        Handle(BOPDS_CommonBlock) aCB;
+        if (myDS->IsCommonBlock(aPB)) {
+          aCB = myDS->CommonBlock(aPB);
+        }
+        else {
+          aCB = new BOPDS_CommonBlock;
+          aCB->AddPaveBlock(aPB);
+        }
+        //
+        aCB->AddFace(i);
+        //
+        aMFPBIn.Add(aPB);
+      }
+    }
+  }
+}
index 9c7cd0e840d1179e7962e89bb5fa49143c5b5db6..f0b69919cfe26fed1501ad8341d155ce2078d930 100644 (file)
@@ -280,6 +280,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
                                       IntPatch_SequenceOfLine& theLines) const 
 {
   const Standard_Integer aNbVert = theALine->NbVertex();
+  if (!aNbVert) {
+    return;
+  }
   const Standard_Real aTol = 2.0*myTol3D+Precision::Confusion();
   IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
   
index 24401c3af260d594b42345aa3c79ff28f5251c0b..900d5a3ada8907fb2ac8172c809e859934135a37 100644 (file)
@@ -659,7 +659,6 @@ void IntTools_EdgeFace::Perform()
     if (IsCoincident()) {
       aCommonPrt.SetType(TopAbs_EDGE);
       aCommonPrt.SetRange1(myRange.First(), myRange.Last());
-      MakeType (aCommonPrt); 
       mySeqOfCommonPrts.Append(aCommonPrt);
       myIsDone=Standard_True;
       return;
index 9118233252ddcbdd689e6c4c22a38012afa5dea3..429aa9e03559dd9ae1e7219a35f9d6b5c282b620 100644 (file)
@@ -143,7 +143,12 @@ void  ProjLib_Cone::Project(const gp_Circ& C)
 
   gp_Ax3 ConePos = myCone.Position();
   gp_Ax3 CircPos = C.Position();
-
+  //
+  if (!ConePos.Direction().IsParallel(CircPos.Direction(), Precision::Angular())) {
+    isDone = Standard_False;
+    return;
+  }
+  //
   gp_Dir ZCone = ConePos.XDirection().Crossed(ConePos.YDirection());
   gp_Dir ZCir =  CircPos.XDirection().Crossed(CircPos.YDirection());
 
index 646c5f0c2b5430b46312683f40d54231c7b41773..185b524dbef0b7d117f533e177256a1d406e8bf5 100644 (file)
@@ -1,3 +1,2 @@
-puts "TODO OCC26018 ALL: Faulty shapes in variables faulty_1 to faulty_"
 source [locate_data_file 51679_tkz_montecristo_sbr.prt.1.gdml.tcl]
 
diff --git a/tests/bugs/modalg_6/bug26789_1 b/tests/bugs/modalg_6/bug26789_1
new file mode 100644 (file)
index 0000000..c5dddec
--- /dev/null
@@ -0,0 +1,29 @@
+puts "TODO 0026789 ALL: Error : The area of result shape is"
+puts "TODO 0026789 ALL: Error : The volume of result shape is"
+puts "TODO 0026789 ALL: Error :  is WRONG because number of SOLID entities in shape"
+puts "TODO 0026789 ALL: Error :  is WRONG because number of SHELL entities in shape"
+puts "TODO 0026789 ALL: Faulty shapes in variables faulty_"
+
+puts "========"
+puts "OCC26789"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+explode a
+# fusing all solids
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9
+bfillds
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 2
+checkprops result -s 3583.27 -v 11455.2
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug26789_2 b/tests/bugs/modalg_6/bug26789_2
new file mode 100644 (file)
index 0000000..9624d93
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC26789"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+# reducing tolerance of the shape
+settolerance a 1.e-7
+explode a
+# fusing all solids
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_2 a_3 a_4 a_5 a_6 a_7 a_8 a_9
+bfillds
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 2
+checkprops result -s 3583.27 -v 11455.2
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug26789_3 b/tests/bugs/modalg_6/bug26789_3
new file mode 100644 (file)
index 0000000..6e7bab1
--- /dev/null
@@ -0,0 +1,25 @@
+puts "========"
+puts "OCC26789"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+explode a
+# fusing all solids one by one
+bfuse result a_1 a_2
+bfuse result result a_3
+bfuse result result a_4
+bfuse result result a_5
+bfuse result result a_6
+bfuse result result a_7
+bfuse result result a_8
+bfuse result result a_9
+
+checkshape result
+checknbshapes result -solid 1 -shell 2
+checkprops result -s 3583.27 -v 11455.2
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28486_1 b/tests/bugs/modalg_6/bug28486_1
new file mode 100644 (file)
index 0000000..8b063db
--- /dev/null
@@ -0,0 +1,23 @@
+puts "========"
+puts "OCC28486"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails due to presence of common zones between faces
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+explode a
+# fusing first, third and fourth solids
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_3 a_4
+bfillds
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 1
+checkprops result -s 2237.86 -v 5444.61
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28486_2 b/tests/bugs/modalg_6/bug28486_2
new file mode 100644 (file)
index 0000000..4d044c8
--- /dev/null
@@ -0,0 +1,23 @@
+puts "========"
+puts "OCC28486"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails due to presence of common zones between faces
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+explode a
+# fusing third, fourth and seventh solids
+bclearobjects
+bcleartools
+baddobjects a_3
+baddtools a_4 a_7
+bfillds
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 1
+checkprops result -s 2237.86 -v 5444.61
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28486_3 b/tests/bugs/modalg_6/bug28486_3
new file mode 100644 (file)
index 0000000..1106b07
--- /dev/null
@@ -0,0 +1,23 @@
+puts "========"
+puts "OCC28486"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails due to presence of common zones between faces
+#################################################
+
+restore [locate_data_file bug26789_All-Spikes.brep] a
+explode a
+# fusing all solids except seventh and eighth
+bclearobjects
+bcleartools
+baddobjects a_1
+baddtools a_2 a_3 a_4 a_5 a_6 a_9
+bfillds
+bbop result 1
+
+checkshape result
+checknbshapes result -solid 1 -shell 2
+checkprops result -s 3273.89 -v 9907.1
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28486_4 b/tests/bugs/modalg_6/bug28486_4
new file mode 100644 (file)
index 0000000..d91020d
--- /dev/null
@@ -0,0 +1,30 @@
+puts "========"
+puts "OCC28486"
+puts "========"
+puts ""
+#################################################
+# Fuse of several solids fails due to presence of common zones between faces
+#################################################
+
+plane p 0 0 0 0 0 1
+mkface f1 p -10 10 -10 10
+copy f1 f2
+trotate f2 0 0 0 1 0 0 20
+line l 0 0 0 0 1 0
+mkedge e l -8 8
+trotate e 0 0 0 1 0 0 10
+settolerance e 1.5
+donly f1 f2 e
+
+bclearobjects
+bcleartools
+baddobjects f1 f2
+baddtools e
+bfillds
+bbuild result
+
+checkshape result
+checknbshapes result -face 4 -wire 8
+checkprops result -s 800
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file