0028050: Empty result of offset operation in mode complete join type intersection
authoremv <emv@opencascade.com>
Thu, 3 Nov 2016 09:58:25 +0000 (12:58 +0300)
committerapn <apn@opencascade.com>
Tue, 8 Nov 2016 15:08:01 +0000 (18:08 +0300)
1. BRepOffset_Inter3d::ConnexIntByInt
Create unique offset edge for each localized part shared between pair of faces of the input shape.

2. Test cases for the issue.

src/BRepOffset/BRepOffset_Inter3d.cxx
tests/offset/shape_type_i_c/XK3 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK4 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK5 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK6 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK7 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK8 [new file with mode: 0644]
tests/offset/shape_type_i_c/XK9 [new file with mode: 0644]

index 56b539c..9460d58 100644 (file)
@@ -446,8 +446,8 @@ void BRepOffset_Inter3d::ConnexIntByInt
     TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
   }
   //
-  TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2;
-  TopTools_IndexedDataMapOfShapeListOfShape aDMIntE, aDMIntFF;
+  TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMIntE;
   //
   if (bIsPlanar) {
     aNb = VEmap.Extent();
@@ -463,6 +463,7 @@ void BRepOffset_Inter3d::ConnexIntByInt
         continue;
       }
       //
+      // find pairs in which the vertex is alone (not connected to shared edges)
       TopTools_ListOfShape aLF1, aLF2;
       Standard_Boolean bVertexOnly = Standard_False;
       TopTools_MapOfShape aMFence;
@@ -477,7 +478,14 @@ void BRepOffset_Inter3d::ConnexIntByInt
         TopTools_MapOfShape aME;
         TopExp_Explorer aExp(aFV1, TopAbs_EDGE);
         for (; aExp.More(); aExp.Next()) {
-          aME.Add(aExp.Current());
+          const TopoDS_Shape& aE = aExp.Current();
+          TopoDS_Iterator aItV(aE);
+          for (; aItV.More(); aItV.Next()) {
+            if (aS.IsSame(aItV.Value())) {
+              aME.Add(aE);
+              break;
+            }
+          }
         }
         //
         it1.Initialize(aLF);
@@ -621,24 +629,14 @@ void BRepOffset_Inter3d::ConnexIntByInt
           for (; it.More(); it.Next()) {
             const TopoDS_Shape& aNE = it.Value();
             B.Add(C, aNE);
-            if (bEdge) {
-              TopoDS_Vertex aVO1, aVO2;
-              TopExp::Vertices(TopoDS::Edge(aS), aVO1, aVO2);
-              if (!aDMVLF1.IsBound(aVO1) && !aDMVLF1.IsBound(aVO2)) {
-                TopTools_ListOfShape *pListS = aDMIntE.ChangeSeek(aNE);
-                if (!pListS) {
-                  pListS = &aDMIntE.ChangeFromIndex(aDMIntE.Add(aNE, TopTools_ListOfShape()));
-                }
-                pListS->Append(aS);
-                //
-                if (!aDMIntFF.Contains(aNE)) {
-                  TopTools_ListOfShape aLFF;
-                  aLFF.Append(NF1);
-                  aLFF.Append(NF2);
-                  aDMIntFF.Add(aNE, aLFF);
-                }
-              }
-            }
+            //
+            // keep connection from new edge to shape from which it was created
+            TopTools_ListOfShape *pLS = &aDMIntE(aDMIntE.Add(aNE, TopTools_ListOfShape()));
+            pLS->Append(aS);
+            // keep connection to faces created the edge as well
+            TopTools_ListOfShape* pLFF = aDMIntFF.Bound(aNE, TopTools_ListOfShape());
+            pLFF->Append(F1);
+            pLFF->Append(F2);
           }
           //
           Build.Bind(aS,C);
@@ -664,7 +662,6 @@ void BRepOffset_Inter3d::ConnexIntByInt
             }
           }
           //
-          TopTools_ListOfShape aLENew;
           for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
             const TopoDS_Shape &anE1 = it.Value();
             //
@@ -672,23 +669,10 @@ void BRepOffset_Inter3d::ConnexIntByInt
               const TopoDS_Shape &anE2 = it1.Value();
               if (anE1.IsSame(anE2)) {
                 B.Add(C, anE1);
-                if (bEdge) {
-                  TopoDS_Vertex aVO1, aVO2;
-                  TopExp::Vertices(TopoDS::Edge(aS), aVO1, aVO2);
-                  if (!aDMVLF1.IsBound(aVO1) && !aDMVLF1.IsBound(aVO2)) {
-                    TopTools_ListOfShape *pListS = aDMIntE.ChangeSeek(anE1);
-                    if (!pListS) {
-                      pListS = &aDMIntE.ChangeFromIndex(aDMIntE.Add(anE1, TopTools_ListOfShape()));
-                    }
-                    pListS->Append(aS);
-                    //
-                    if (!aDMIntFF.Contains(anE1)) {
-                      TopTools_ListOfShape aLFF;
-                      aLFF.Append(NF1);
-                      aLFF.Append(NF2);
-                      aDMIntFF.Add(anE1, aLFF);
-                    }
-                  }
+                //
+                TopTools_ListOfShape *pLS = aDMIntE.ChangeSeek(anE1);
+                if (pLS) {
+                  pLS->Append(aS);
                 }
               }
             }
@@ -703,36 +687,129 @@ void BRepOffset_Inter3d::ConnexIntByInt
     //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
   }
   //
+  // create unique intersection for each localized shared part
   aNb = aDMIntE.Extent();
   for (i = 1; i <= aNb; ++i) {
-    const TopTools_ListOfShape& aLE = aDMIntE(i);
-    if (aLE.Extent() == 1) {
+    const TopTools_ListOfShape& aLS = aDMIntE(i);
+    if (aLS.Extent() < 2) {
       continue;
     }
     //
-    // make connexity blocks of edges
+    // intersection edge
+    const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i));
+    // faces created the edge
+    const TopTools_ListOfShape& aLFF = aDMIntFF.Find(aE);
+    const TopoDS_Shape& aF1 = aLFF.First();
+    const TopoDS_Shape& aF2 = aLFF.Last();
+
+    // Build really localized blocks from the original shapes in <aLS>:
+    // 1. Find edges from original faces connected to two or more shapes in <aLS>;
+    // 2. Make connexity blocks from edges in <aLS> and found connection edges;
+    // 3. Check if the vertices from <aLS> are not connected by these connection edges:
+    //    a. If so - add these vertices to Connexity Block containing the corresponding
+    //       connexity edge;
+    //    b. If not - add this vertex to list of connexity blocks
+    // 4. Create unique intersection edge for each connexity block
+
+    // list of vertices
+    TopTools_ListOfShape aLV;
+    // compound of edges to build connexity blocks
     TopoDS_Compound aCE;
     B.MakeCompound(aCE);
+    TopTools_MapOfShape aMS;
+    TopTools_ListIteratorOfListOfShape aItLS(aLS);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aS = aItLS.Value();
+      aMS.Add(aS);
+      if (aS.ShapeType() == TopAbs_EDGE) {
+        B.Add(aCE, aS);
+      }
+      else {
+        aLV.Append(aS);
+      }
+    }
     //
-    TopTools_ListIteratorOfListOfShape aItLE(aLE);
-    for (; aItLE.More(); aItLE.Next()) {
-      const TopoDS_Shape& aE = aItLE.Value();
-      B.Add(aCE, aE);
+    // look for additional edges to connect the shared parts
+    TopTools_MapOfShape aMEConnection;
+    for (Standard_Integer j = 0; j < 2; ++j) {
+      const TopoDS_Shape& aF = !j ? aF1 : aF2;
+      //
+      TopExp_Explorer aExp(aF, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Shape& aEF = aExp.Current();
+        if (aMS.Contains(aEF) || aMEConnection.Contains(aEF)) {
+          continue;
+        }
+        //
+        TopoDS_Vertex aV1, aV2;
+        TopExp::Vertices(TopoDS::Edge(aEF), aV1, aV2);
+        //
+        // find parts to which the edge is connected
+        Standard_Integer iCounter = 0;
+        aItLS.Initialize(aLS);
+        for (; aItLS.More(); aItLS.Next()) {
+          const TopoDS_Shape& aS = aItLS.Value();
+          // iterator is not suitable here, because aS may be a vertex
+          TopExp_Explorer aExpV(aS, TopAbs_VERTEX);
+          for (; aExpV.More(); aExpV.Next()) {
+            const TopoDS_Shape& aV = aExpV.Current();
+            if (aV.IsSame(aV1) || aV.IsSame(aV2)) {
+              ++iCounter;
+              break;
+            }
+          }
+        }
+        //
+        if (iCounter >= 2) {
+          B.Add(aCE, aEF);
+          aMEConnection.Add(aEF);
+        }
+      }
     }
     //
     TopTools_ListOfShape aLCBE;
     BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
+    //
+    // create connexity blocks for alone vertices
+    TopTools_ListOfShape aLCBV;
+    TopTools_ListIteratorOfListOfShape aItLV(aLV);
+    for (; aItLV.More(); aItLV.Next()) {
+      const TopoDS_Shape& aV = aItLV.Value();
+      // check if this vertex is contained in some connexity block of edges
+      TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
+      for (; aItLCB.More(); aItLCB.Next()) {
+        TopoDS_Shape& aCB = aItLCB.ChangeValue();
+        TopExp_Explorer aExpV(aCB, TopAbs_VERTEX);
+        for (; aExpV.More(); aExpV.Next()) {
+          if (aV.IsSame(aExpV.Current())) {
+            B.Add(aCB, aV);
+            break;
+          }
+        }
+        if (aExpV.More()) {
+          break;
+        }
+      }
+      //
+      if (!aItLCB.More()) {
+        TopoDS_Compound aCV;
+        B.MakeCompound(aCV);
+        B.Add(aCV, aV);
+        aLCBV.Append(aCV);
+      }
+    }
+    //
+    aLCBE.Append(aLCBV);
+    //
     if (aLCBE.Extent() == 1) {
       continue;
     }
     //
-    const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i));
-    const TopTools_ListOfShape& aLFF = aDMIntFF.FindFromKey(aE);
-    const TopoDS_Shape& aF1 = aLFF.First();
-    const TopoDS_Shape& aF2 = aLFF.Last();
+    const TopoDS_Shape& aNF1 = MES(MapSF(aF1).Face());
+    const TopoDS_Shape& aNF2 = MES(MapSF(aF2).Face());
     //
-    aItLE.Initialize(aLCBE);
-    for (aItLE.Next(); aItLE.More(); aItLE.Next()) {
+    TopTools_ListIteratorOfListOfShape aItLCB(aLCBE);
+    for (aItLCB.Next(); aItLCB.More(); aItLCB.Next()) {
       // make new edge with different tedge instance
       TopoDS_Edge aNewEdge;
       TopoDS_Vertex aV1, aV2;
@@ -743,13 +820,16 @@ void BRepOffset_Inter3d::ConnexIntByInt
       //
       BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge);
       //
-      myAsDes->Add(aF1, aNewEdge);
-      myAsDes->Add(aF2, aNewEdge);
+      myAsDes->Add(aNF1, aNewEdge);
+      myAsDes->Add(aNF2, aNewEdge);
       //
-      const TopoDS_Shape& aCB = aItLE.Value();
+      const TopoDS_Shape& aCB = aItLCB.Value();
       TopoDS_Iterator aItCB(aCB);
       for (; aItCB.More(); aItCB.Next()) {
         const TopoDS_Shape& aS = aItCB.Value();
+        if (aMEConnection.Contains(aS)) {
+          continue;
+        }
         TopoDS_Shape& aCI = Build.ChangeFind(aS);
         //
         TopoDS_Compound aNewCI;
diff --git a/tests/offset/shape_type_i_c/XK3 b/tests/offset/shape_type_i_c/XK3
new file mode 100644 (file)
index 0000000..8bf59fe
--- /dev/null
@@ -0,0 +1,10 @@
+restore [locate_data_file bug26917_rm-104_input_3.brep] s
+
+OFFSETSHAPE 5 {} $calcul $type
+
+checkprops result -v 7.92115e+007 -s 7.499e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 2010 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK4 b/tests/offset/shape_type_i_c/XK4
new file mode 100644 (file)
index 0000000..86247c6
--- /dev/null
@@ -0,0 +1,21 @@
+restore [locate_data_file bug26917_rm-104_input_3_with_faces.brep] c
+
+# get the shape
+explode c
+copy c_1 s
+
+offsetparameter 1e-7 c i
+offsetload s 5
+
+foreach f [explode c_2 f] {
+  offsetonface $f 2
+}
+
+offsetperform result
+
+checkprops result -v 7.11183e+007 -s 7.46447e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 2010 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK5 b/tests/offset/shape_type_i_c/XK5
new file mode 100644 (file)
index 0000000..235fabc
--- /dev/null
@@ -0,0 +1,14 @@
+restore [locate_data_file bug26917_rm-104_input_3_trim1_with_faces.brep] c
+
+#get the shape
+explode c
+copy c_1 s
+
+OFFSETSHAPE 5 {} $calcul $type
+
+checkprops result -v 4.14439e+007 -s 3.99357e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 1067 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK6 b/tests/offset/shape_type_i_c/XK6
new file mode 100644 (file)
index 0000000..a080268
--- /dev/null
@@ -0,0 +1,21 @@
+restore [locate_data_file bug26917_rm-104_input_3_trim1_with_faces.brep] c
+
+#get the shape
+explode c
+copy c_1 s
+
+offsetparameter 1e-7 c i
+offsetload s 5
+
+foreach f [explode c_2 f] {
+  offsetonface $f 2
+}
+
+offsetperform result
+
+checkprops result -v 3.7122e+007 -s 3.97038e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 1067 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK7 b/tests/offset/shape_type_i_c/XK7
new file mode 100644 (file)
index 0000000..367c51c
--- /dev/null
@@ -0,0 +1,14 @@
+restore [locate_data_file bug26917_rm-104_input_3_trim2_with_faces.brep] c
+
+#get the shape
+explode c
+copy c_1 s
+
+OFFSETSHAPE 5 {} $calcul $type
+
+checkprops result -v 3.79514e+007 -s 3.57457e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 941 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK8 b/tests/offset/shape_type_i_c/XK8
new file mode 100644 (file)
index 0000000..07bdc6e
--- /dev/null
@@ -0,0 +1,21 @@
+restore [locate_data_file bug26917_rm-104_input_3_trim2_with_faces.brep] c
+
+#get the shape
+explode c
+copy c_1 s
+
+offsetparameter 1e-7 c i
+offsetload s 5
+
+foreach f [explode c_2 f] {
+  offsetonface $f 2
+}
+
+offsetperform result
+
+checkprops result -v 3.413e+007 -s 3.55307e+006
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 941 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/offset/shape_type_i_c/XK9 b/tests/offset/shape_type_i_c/XK9
new file mode 100644 (file)
index 0000000..2196d13
--- /dev/null
@@ -0,0 +1,10 @@
+restore [locate_data_file bug26917_rm-104_input_3_trim10.brep] s
+
+OFFSETSHAPE 5 {} $calcul $type
+
+checkprops result -v 220856 -s 32106.9
+
+unifysamedom result_unif result
+checknbshapes result_unif -face 13 -shell 1
+
+checkview -display result_unif -2d -path ${imagedir}/${test_image}.png