]> OCCT Git - occt-copy.git/commitdiff
BRepOffset_Inter3d::CompletInt - Make unique offset edges for each block of collinea...
authoremv <emv@opencascade.com>
Fri, 1 Apr 2016 08:48:37 +0000 (11:48 +0300)
committermsv <msv@opencascade.com>
Fri, 22 Apr 2016 12:48:16 +0000 (15:48 +0300)
src/BRepOffset/BRepOffset_Inter3d.cxx
src/BRepOffset/BRepOffset_MakeOffset.cxx

index 33e5c6f1ff0f560db46adde3138a13491fce7ff0..52801fda7554a6be487845ff45823eabed770aa3 100644 (file)
@@ -41,8 +41,8 @@
 #include <TopTools_MapOfShape.hxx>
 #include <Precision.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
-
-
+//
+#include <BOPTools_AlgoTools.hxx>
 
 //=======================================================================
 //function : BRepOffset_Inter3d
@@ -429,65 +429,38 @@ void BRepOffset_Inter3d::ConnexIntByInt
   //TopExp_Explorer Exp(SI,TopAbs_EDGE);
   TopTools_IndexedMapOfShape VEmap;
   TopTools_IndexedDataMapOfShapeListOfShape aMVF;
-  TopoDS_Face     F1,F2,OF1,OF2,NF1,NF2;
+  TopoDS_Face     F1, F2, OF1, OF2, NF1, NF2;
   TopAbs_State    CurSide = mySide;
   BRep_Builder    B;
   Standard_Boolean bEdge;
   Standard_Integer i, aNb;
   TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2;
   //
-  TopExp::MapShapes(SI, TopAbs_EDGE  , VEmap);
+  TopExp::MapShapes(SI, TopAbs_EDGE, VEmap);
   // map the shape for vertices
   if (bIsPlanar) {
     TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
     TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
   }
   //
-  aNb = VEmap.Extent();
-  for (i = 1; i <= aNb; ++i) {
-    const TopoDS_Shape& aS = VEmap(i);
-    //
-    TopoDS_Edge E;
-    TopTools_ListOfShape aLF1, aLF2;
-    //
-    bEdge = (aS.ShapeType() == TopAbs_EDGE);
-    if (bEdge) {
-      // faces connected by the edge
-      E = *(TopoDS_Edge*)&aS;
-      //
-      const BRepOffset_ListOfInterval& L = Analyse.Type(E);
-      if (L.IsEmpty()) {
-        continue;
-      }
-      //
-      BRepOffset_Type    OT   = L.First().Type();
-      if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
-        continue;
-      }
-      //
-      if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
-      else                          CurSide = TopAbs_OUT;
-      //-----------------------------------------------------------
-      // edge is of the proper type, return adjacent faces.
-      //-----------------------------------------------------------
-      const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
-      if (Anc.Extent() != 2) {
+  TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMIntE, aDMIntFF;
+  //
+  if (bIsPlanar) {
+    aNb = VEmap.Extent();
+    for (i = 1; i <= aNb; ++i) {
+      const TopoDS_Shape& aS = VEmap(i);
+      if (aS.ShapeType() != TopAbs_VERTEX) {
         continue;
       }
       //
-      F1  = TopoDS::Face(Anc.First());
-      F2  = TopoDS::Face(Anc.Last ());
-      //
-      aLF1.Append(F1);
-      aLF2.Append(F2);
-    }
-    else {
       // faces connected by the vertex
       const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS);
       if (aLF.Extent() < 2) {
         continue;
       }
       //
+      TopTools_ListOfShape aLF1, aLF2;
       Standard_Boolean bVertexOnly = Standard_False;
       TopTools_MapOfShape aMFence;
       //
@@ -533,6 +506,57 @@ void BRepOffset_Inter3d::ConnexIntByInt
         continue;
       }
       //
+      aDMVLF1.Bind(aS, aLF1);
+      aDMVLF2.Bind(aS, aLF2);
+    }
+  }
+  //
+  aNb = VEmap.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aS = VEmap(i);
+    //
+    TopoDS_Edge E;
+    TopTools_ListOfShape aLF1, aLF2;
+    //
+    bEdge = (aS.ShapeType() == TopAbs_EDGE);
+    if (bEdge) {
+      // faces connected by the edge
+      E = *(TopoDS_Edge*)&aS;
+      //
+      const BRepOffset_ListOfInterval& L = Analyse.Type(E);
+      if (L.IsEmpty()) {
+        continue;
+      }
+      //
+      BRepOffset_Type    OT = L.First().Type();
+      if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) {
+        continue;
+      }
+      //
+      if (OT == BRepOffset_Concave) CurSide = TopAbs_IN;
+      else                          CurSide = TopAbs_OUT;
+      //-----------------------------------------------------------
+      // edge is of the proper type, return adjacent faces.
+      //-----------------------------------------------------------
+      const TopTools_ListOfShape& Anc = Analyse.Ancestors(E);
+      if (Anc.Extent() != 2) {
+        continue;
+      }
+      //
+      F1 = TopoDS::Face(Anc.First());
+      F2 = TopoDS::Face(Anc.Last());
+      //
+      aLF1.Append(F1);
+      aLF2.Append(F2);
+    }
+    else {
+      if (!aDMVLF1.IsBound(aS)) {
+        continue;
+      }
+      //
+      aLF1 = aDMVLF1.Find(aS);
+      aLF2 = aDMVLF2.Find(aS);
+      //
       CurSide = mySide;
     }
     //
@@ -547,9 +571,9 @@ void BRepOffset_Inter3d::ConnexIntByInt
       if (!MES.IsBound(OF1)) {
         Standard_Boolean enlargeU = Standard_True;
         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
-        BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
-        BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
-        MES.Bind(OF1,NF1);
+        BRepOffset_Tool::CheckBounds(F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast);
+        BRepOffset_Tool::EnLargeFace(OF1, NF1, Standard_True, Standard_True, enlargeU, enlargeVfirst, enlargeVlast);
+        MES.Bind(OF1, NF1);
       }
       else {
         NF1 = TopoDS::Face(MES(OF1));
@@ -558,25 +582,25 @@ void BRepOffset_Inter3d::ConnexIntByInt
       if (!MES.IsBound(OF2)) {
         Standard_Boolean enlargeU = Standard_True;
         Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True;
-        BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast );
-        BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast);
-        MES.Bind(OF2,NF2); 
+        BRepOffset_Tool::CheckBounds(F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast);
+        BRepOffset_Tool::EnLargeFace(OF2, NF2, Standard_True, Standard_True, enlargeU, enlargeVfirst, enlargeVlast);
+        MES.Bind(OF2, NF2);
       }
       else {
         NF2 = TopoDS::Face(MES(OF2));
       }
       //
-      if (!IsDone(NF1,NF2)) {
-        TopTools_ListOfShape LInt1,LInt2;
-        BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge);
-        if (LInt1.Extent() > 1) { 
+      if (!IsDone(NF1, NF2)) {
+        TopTools_ListOfShape LInt1, LInt2;
+        BRepOffset_Tool::Inter3D(NF1, NF2, LInt1, LInt2, CurSide, E, bEdge);
+        if (LInt1.Extent() > 1) {
           // intersection is in seceral edges (free sewing)
           SelectEdge(aS, LInt1);
           SelectEdge(aS, LInt2);
         }
-        SetDone(NF1,NF2);
+        SetDone(NF1, NF2);
         if (!LInt1.IsEmpty()) {
-          Store (NF1,NF2,LInt1,LInt2);
+          Store(NF1, NF2, LInt1, LInt2);
           //
           TopoDS_Compound C;
           B.MakeCompound(C);
@@ -594,18 +618,40 @@ 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)) {
+                if (aDMIntE.Contains(aNE)) {
+                  aDMIntE.ChangeFromKey(aNE).Append(aS);
+                }
+                else {
+                  TopTools_ListOfShape aListS;
+                  aListS.Append(aS);
+                  aDMIntE.Add(aNE, aListS);
+                }
+                //
+                if (!aDMIntFF.Contains(aNE)) {
+                  TopTools_ListOfShape aLFF;
+                  aLFF.Append(NF1);
+                  aLFF.Append(NF2);
+                  aDMIntFF.Add(aNE, aLFF);
+                }
+              }
+            }
           }
           //
-          Build.Bind(aS,C);
+          Build.Bind(aS, C);
         }
         else {
           Failed.Append(aS);
         }
-      } else { // IsDone(NF1,NF2)
+      }
+      else { // IsDone(NF1,NF2)
         //  Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin
         const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1);
         const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2);
-        
+
         if (!aLInt1.IsEmpty()) {
           TopoDS_Compound C;
           B.MakeCompound(C);
@@ -619,17 +665,39 @@ void BRepOffset_Inter3d::ConnexIntByInt
             }
           }
           //
-          for (it.Initialize(aLInt1) ; it.More(); it.Next()) {
+          TopTools_ListOfShape aLENew;
+          for (it.Initialize(aLInt1); it.More(); it.Next()) {
             const TopoDS_Shape &anE1 = it.Value();
             //
-            for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) {
+            for (it1.Initialize(aLInt2); it1.More(); it1.Next()) {
               const TopoDS_Shape &anE2 = it1.Value();
-              
-              if (anE1.IsSame(anE2))
+              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)) {
+                    if (aDMIntE.Contains(anE1)) {
+                      aDMIntE.ChangeFromKey(anE1).Append(aS);
+                    }
+                    else {
+                      TopTools_ListOfShape aListS;
+                      aListS.Append(aS);
+                      aDMIntE.Add(anE1, aListS);
+                    }
+                    //
+                    if (!aDMIntFF.Contains(anE1)) {
+                      TopTools_ListOfShape aLFF;
+                      aLFF.Append(NF1);
+                      aLFF.Append(NF2);
+                      aDMIntFF.Add(anE1, aLFF);
+                    }
+                  }
+                }
+              }
             }
           }
-          Build.Bind(aS,C);
+          Build.Bind(aS, C);
         }
         else {
           Failed.Append(aS);
@@ -638,6 +706,73 @@ void BRepOffset_Inter3d::ConnexIntByInt
     }
     //  Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End
   }
+  //
+  aNb = aDMIntE.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopTools_ListOfShape& aLE = aDMIntE(i);
+    if (aLE.Extent() == 1) {
+      continue;
+    }
+    //
+    // make connexity blocks of edges
+    TopoDS_Compound aCE;
+    B.MakeCompound(aCE);
+    //
+    TopTools_ListIteratorOfListOfShape aItLE(aLE);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aE = aItLE.Value();
+      B.Add(aCE, aE);
+    }
+    //
+    BOPCol_ListOfShape aLCBE;
+    BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE);
+    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();
+    //
+    TopTools_ListOfShape& aLFE1 = myAsDes->ChangeDescendant(aF1);
+    TopTools_ListOfShape& aLFE2 = myAsDes->ChangeDescendant(aF2);
+    //
+    BOPCol_ListIteratorOfListOfShape aItLCBE(aLCBE);
+    for (aItLCBE.Next(); aItLCBE.More(); aItLCBE.Next()) {
+      // make new edge with different tedge instance
+      TopoDS_Edge aNewEdge;
+      TopoDS_Vertex aV1, aV2;
+      Standard_Real aT1, aT2;
+      //
+      TopExp::Vertices(aE, aV1, aV2);
+      BRep_Tool::Range(aE, aT1, aT2);
+      //
+      BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge);
+      //
+      aLFE1.Append(aNewEdge);
+      aLFE2.Append(aNewEdge);
+      //
+      const TopoDS_Shape& aCB = aItLCBE.Value();
+      TopoDS_Iterator aItCB(aCB);
+      for (; aItCB.More(); aItCB.Next()) {
+        const TopoDS_Shape& aS = aItCB.Value();
+        TopoDS_Shape& aCI = Build.ChangeFind(aS);
+        //
+        TopoDS_Compound aNewCI;
+        B.MakeCompound(aNewCI);
+        TopExp_Explorer aExp(aCI, TopAbs_EDGE);
+        for (; aExp.More(); aExp.Next()) {
+          const TopoDS_Shape& aSx = aExp.Current();
+          if (!aSx.IsSame(aE)) {
+            B.Add(aNewCI, aSx);
+          }
+        }
+        B.Add(aNewCI, aNewEdge);
+        aCI = aNewCI;
+      }
+    }
+  }
 }
 
 //=======================================================================
index ca12646749327bf4cba9cb3eafc4667e76010fc7..3fbeb168187115f4cc1633100161c5d1288c3f55 100644 (file)
@@ -387,6 +387,8 @@ static
                              const TopTools_IndexedMapOfShape& theMFInt,
                              const TopTools_IndexedMapOfShape& theMEInt,
                              const TopTools_DataMapOfShapeListOfShape& theDMEETrim,
+                             const TopTools_IndexedMapOfShape& theMSInv,
+                             const TopTools_IndexedMapOfShape& theMVE,
                              const TopTools_MapOfShape& theVertsToAvoid,
                              const TopTools_MapOfShape& theNewVertsToAvoid,
                              TopTools_MapOfShape& theMVBounds,
@@ -4939,7 +4941,7 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
   //
   Standard_Integer i, j, k, aNbInv;
   TopTools_ListIteratorOfListOfShape aItLE, aItLEO, aItLF;
-  TopTools_MapOfShape aMFence, aMEC, aMVBounds;
+  TopTools_MapOfShape aMFence, aMVBounds;
   TopTools_DataMapOfShapeListOfShape aDMEF, aMDone, aEImages;
   TopTools_IndexedDataMapOfShapeListOfShape aFLE;
   TopExp_Explorer aExp;
@@ -5111,14 +5113,25 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
       BOPCol_ListIteratorOfListOfShape aItLCBE(aLCBE);
       for (; aItLCBE.More(); aItLCBE.Next()) {
         const TopoDS_Shape& aCBELoc = aItLCBE.Value();
-        // map of connection edges
+        //
+        // map to keep connection between vertices and edges
+        TopTools_IndexedDataMapOfShapeListOfShape aDMVE;
+        // map of edges and vertices of processing invalidity
         TopTools_IndexedMapOfShape aME;
+        // map of vertices to trim the new edges
+        TopTools_IndexedMapOfShape  aMECV;
         TopExp::MapShapes(aCBELoc, TopAbs_EDGE, aME);
+        aMECV = aME;
         TopExp::MapShapes(aCBELoc, TopAbs_VERTEX, aME);
         //
         // Using the map <aME> find chain of faces to be intersected;
+        //
+        // faces for intersection
+        TopTools_IndexedMapOfShape aMFInt;
+        // splits of faces for intersection
         TopTools_ListOfShape aLFInt;
-        TopTools_IndexedMapOfShape aMFInt, aMFAvoid;
+        // faces to avoid intersection
+        TopTools_IndexedMapOfShape aMFAvoid;
         Standard_Integer aNbE = aME.Extent();
         for (i = 1; i <= aNbE; ++i) {
           const TopoDS_Shape& aS = aME(i);
@@ -5142,16 +5155,15 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
                 for (; aItLFIm.More(); aItLFIm.Next()) {
                   const TopoDS_Shape& aFIm = aItLFIm.Value();
                   aLFInt.Append(aFIm);
+                  TopExp::MapShapesAndAncestors(aFIm, TopAbs_VERTEX, TopAbs_EDGE, aDMVE);
                 }
               }
             }
           }
         }
         //
-        // check if the face is artificially invalid
-        // in this case in pair of faces for intersection
-        // one of the faces must be invalid
-        //
+        // intersect the faces, but do not intersect the invalid ones
+        // among each other (except for the artificially invalid faces)
         TopTools_IndexedMapOfShape aMEToInt;
         Standard_Integer aNb = aMFInt.Extent();
         for (i = 1; i <= aNb; ++i) {
@@ -5166,11 +5178,76 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
             const TopoDS_Face& aFj = TopoDS::Face(aMFInt(j));
             const TopTools_ListOfShape& aLFImj = theDMFFIm.FindFromKey(aFj);
             //
-            Standard_Boolean bArtInvI = theArtInvFaces.IsBound(aFi);
-            Standard_Boolean bArtInvJ = theArtInvFaces.IsBound(aFj);
+            TopTools_ListOfShape& aLFEj = aFLE.ChangeFromKey(aFj);
+            //
+            // if there are some common edges between faces
+            // we should use these edges and do not intersect again.
+            TopTools_ListOfShape aLEC;
+            FindCommonParts(aLFImi, aLFImj, aLEC);
+            //
+            if (aLEC.Extent()) {
+              aItLE.Initialize(aLEC);
+              for (; aItLE.More(); aItLE.Next()) {
+                const TopoDS_Shape& aEC = aItLE.Value();
+                //
+                // check first if common edges are valid
+                if (theInvEdges.Contains(aEC) && !theValidEdges.Contains(aEC)) {
+                  continue;
+                }
+                //
+                // common edge should have connection to current invalidity
+                if (!aME.Contains(aEC)) {
+                  TopExp_Explorer aExpV(aEC, TopAbs_VERTEX);
+                  for (; aExpV.More(); aExpV.Next()) {
+                    const TopoDS_Shape& aVE = aExpV.Current();
+                    if (aME.Contains(aVE)) {
+                      break;
+                    }
+                  }
+                  //
+                  if (!aExpV.More()) {
+                    continue;
+                  }
+                }
+                //
+                const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC);
+                // find the edges of the same original edge
+                // and take their vertices as well
+                TopExp_Explorer aExpV(aEC, TopAbs_VERTEX);
+                for (; aExpV.More(); aExpV.Next()) {
+                  const TopoDS_Shape& aV = aExpV.Current();
+                  const TopTools_ListOfShape& aLVE = aDMVE.FindFromKey(aV);
+                  TopTools_ListIteratorOfListOfShape aItLVE(aLVE);
+                  for (; aItLVE.More(); aItLVE.Next()) {
+                    const TopoDS_Shape& aECx = aItLVE.Value();
+                    const TopoDS_Shape& aEIntx = theETrimEInf.Find(aECx);
+                    if (aEInt.IsSame(aEIntx)) {
+                      TopExp::MapShapes(aECx, TopAbs_VERTEX, aMECV);
+                    }
+                  }
+                }
+                //
+                // bind unlimited edge to its trimmed part in face to update maps of 
+                // images and origins in the future
+                if (aDMEETrim.IsBound(aEInt)) {
+                  TopTools_ListOfShape& aLTAdded = aDMEETrim.ChangeFind(aEInt);
+                  AppendToList(aLTAdded, aEC);
+                }
+                else {
+                  TopTools_ListOfShape aLT;
+                  aLT.Append(aEC);
+                  aDMEETrim.Bind(aEInt, aLT);
+                }
+                //
+                AppendToList(aLFEi, aEInt);
+                AppendToList(aLFEj, aEInt);
+                aMEToInt.Add(aEInt);
+              }
+            }
             //
             // check if both these faces are invalid and sharing edges
-            if (theInvFaces.Contains(aFi) && theInvFaces.Contains(aFj) && !bArtInvI && !bArtInvJ) {
+            if (theInvFaces.Contains(aFi) && theInvFaces.Contains(aFj) &&
+              !theArtInvFaces.IsBound(aFi) && !theArtInvFaces.IsBound(aFj)) {
               const TopTools_ListOfShape& aLFInvi = theInvFaces.FindFromKey(aFi);
               const TopTools_ListOfShape& aLFInvj = theInvFaces.FindFromKey(aFj);
               //
@@ -5190,10 +5267,15 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
                     }
                   }
                 }
-                //
-                continue;
               }
+              continue;
             }
+            //
+            if (aLEC.Extent()) {
+              // no need to intersect if we have common edges between faces
+              continue;
+            }
+            //
             // check if these two faces have already been treated
             aItLE.Initialize(aLFDone);
             for (; aItLE.More(); aItLE.Next()) {
@@ -5204,6 +5286,9 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
             }
             //
             if (aItLE.More()) {
+              // use intersection line obtained on the previous steps
+              // plus, find new origins for these lines
+              //
               // Find common edges in these two lists
               const TopTools_ListOfShape& aLEi = aFLE.FindFromKey(aFi);
               const TopTools_ListOfShape& aLEj = aFLE.FindFromKey(aFj);
@@ -5239,89 +5324,22 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
                 const TopoDS_Shape& aE = aItLE.Value();
                 if (aMEi.Contains(aE)) {
                   aMEToInt.Add(aE);
-                  if (!aDMEETrim.IsBound(aE)) {
-                    if (aLEOrInit.Extent()) {
-                      if (theEdgesOrigins.IsBound(aE)) {
-                        TopTools_ListOfShape& aLEOr = theEdgesOrigins.ChangeFind(aE);
-                        TopTools_ListIteratorOfListOfShape aItLEOr(aLEOrInit);
-                        for (; aItLEOr.More(); aItLEOr.Next()) {
-                          const TopoDS_Shape& aEOr = aItLEOr.Value();
-                          AppendToList(aLEOr, aEOr);
-                        }
-                      }
-                      else {
-                        theEdgesOrigins.Bind(aE, aLEOrInit);
+                  if (aLEOrInit.Extent()) {
+                    if (theEdgesOrigins.IsBound(aE)) {
+                      TopTools_ListOfShape& aLEOr = theEdgesOrigins.ChangeFind(aE);
+                      TopTools_ListIteratorOfListOfShape aItLEOr(aLEOrInit);
+                      for (; aItLEOr.More(); aItLEOr.Next()) {
+                        const TopoDS_Shape& aEOr = aItLEOr.Value();
+                        AppendToList(aLEOr, aEOr);
                       }
                     }
-                  }
-                }
-              }
-              //
-              continue;
-            }
-            //
-            TopTools_ListOfShape& aLFEj = aFLE.ChangeFromKey(aFj);
-            //
-            // if there are some common edges between faces
-            // it means that these faces have already been intersected,
-            // on the previous steps. This intersection edge is saved in the map
-            TopTools_ListOfShape aLEC;
-            FindCommonParts(aLFImi, aLFImj, aLEC);
-            //
-            if (aLEC.Extent()) {
-              Standard_Boolean bDone = Standard_False;
-              //
-              aItLE.Initialize(aLEC);
-              for (; aItLE.More(); aItLE.Next()) {
-                const TopoDS_Shape& aEC = aItLE.Value();
-                //
-                // check first if common edges are valid
-                if (theInvEdges.Contains(aEC) && !theValidEdges.Contains(aEC)) {
-                  continue;
-                }
-                //
-                // common edge should have connection to current invalidity
-                if (!aME.Contains(aEC)) {
-                  TopExp_Explorer aExpV(aEC, TopAbs_VERTEX);
-                  for (; aExpV.More(); aExpV.Next()) {
-                    const TopoDS_Shape& aVE = aExpV.Current();
-                    if (aME.Contains(aVE)) {
-                      break;
+                    else {
+                      theEdgesOrigins.Bind(aE, aLEOrInit);
                     }
                   }
-                  //
-                  if (!aExpV.More()) {
-                    continue;
-                  }
-                }
-                //
-                bDone = Standard_True;
-                //
-                const TopoDS_Shape& aEInt = theETrimEInf.Find(aEC);
-                //
-                // bind unlimited edge to its trimmed part in face to update maps of 
-                // images and origins in the future
-                if (aDMEETrim.IsBound(aEInt)) {
-                  TopTools_ListOfShape& aLTAdded = aDMEETrim.ChangeFind(aEInt);
-                  AppendToList(aLTAdded, aEC);
-                }
-                else {
-                  TopTools_ListOfShape aLT;
-                  aLT.Append(aEC);
-                  aDMEETrim.Bind(aEInt, aLT);
-                }
-                //
-                if (aMEC.Add(aEC) && aMFence.Add(aEInt)) {
-                  aLFEi.Append(aEInt);
-                  aLFEj.Append(aEInt);
-                  aMEToInt.Add(aEInt);
                 }
               }
               //
-              if (bDone) {
-                aLFDone.Append(aFj);
-                aMDone.ChangeFind(aFj).Append(aFi);
-              }
               continue;
             }
             //
@@ -5341,6 +5359,18 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
             if (aLInt1.IsEmpty()) {
               continue;
             }
+            //
+            // find common vertices for trimming edges
+            TopTools_ListOfShape aLCV;
+            FindCommonParts(aLFImi, aLFImj, aLCV, TopAbs_VERTEX);
+            if (aLCV.Extent() > 1) {
+              aItLE.Initialize(aLCV);
+              for (; aItLE.More(); aItLE.Next()) {
+                const TopoDS_Shape& aCV = aItLE.Value();
+                aMECV.Add(aCV);
+              }
+            }
+            //
             // find origins
             TopTools_IndexedMapOfShape aMEToFindOrigins;
             TopTools_ListOfShape aLEToFindOrigins;
@@ -5376,7 +5406,7 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
         //
         // intersect and trim edges for this chain
         IntersectAndTrimEdges(theFToRebuild, aMFInt, aMEToInt, aDMEETrim,
-                              aMVInv, aMVRInv, aMVBounds, aEImages);
+                              aME, aMECV, aMVInv, aMVRInv, aMVBounds, aEImages);
       }
     }
   }
@@ -5395,46 +5425,76 @@ void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theF
                            const TopTools_IndexedMapOfShape& theMFInt,
                            const TopTools_IndexedMapOfShape& theMEInt,
                            const TopTools_DataMapOfShapeListOfShape& theDMEETrim,
+                           const TopTools_IndexedMapOfShape& theMSInv,
+                           const TopTools_IndexedMapOfShape& theMVE,
                            const TopTools_MapOfShape& theVertsToAvoid,
                            const TopTools_MapOfShape& theNewVertsToAvoid,
                            TopTools_MapOfShape& theMVBounds,
                            TopTools_DataMapOfShapeListOfShape& theEImages)
 {
-  Standard_Integer aNb = theMEInt.Extent();
+  Standard_Integer i, aNb = theMEInt.Extent();
   if (!aNb) {
     return;
   }
   //
-  Standard_Integer i;
-  TopTools_ListOfShape aLVBounds;
-  TopTools_MapOfShape aMFence;
   BOPCol_ListOfShape aLArgs;
+  TopTools_MapOfShape aMFence;
   TopTools_ListIteratorOfListOfShape aIt, aIt1;
   TopExp_Explorer aExp;
   //
-  // get vertices from valid edges
-  // add vertices from invalid edges as well to avoid
-  // building of incorrect splits
+  // get vertices from the splits of intersected faces
+  // vertices are taken from the edges close to invalidity
   //
+  TopTools_IndexedDataMapOfShapeListOfShape aDMVE;
   aNb = theMFInt.Extent();
   for (i = 1; i <= aNb; ++i) {
     const TopoDS_Shape& aF = theMFInt(i);
-    const TopTools_ListOfShape& aLFEVal = theFToRebuild.FindFromKey(aF);
+    const TopTools_ListOfShape& aLE = theFToRebuild.FindFromKey(aF);
     //
-    aIt.Initialize(aLFEVal);
+    aIt.Initialize(aLE);
     for (; aIt.More(); aIt.Next()) {
       const TopoDS_Shape& aE = aIt.Value();
+      TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aDMVE);
       //
       aExp.Init(aE, TopAbs_VERTEX);
       for (; aExp.More(); aExp.Next()) {
-        const TopoDS_Shape& aV = aExp.Current();
-        if (aMFence.Add(aV) && !theVertsToAvoid.Contains(aV)) {
-          aLArgs.Append(aV);
+        const TopoDS_Shape& aV1 = aExp.Current();
+        if (!theVertsToAvoid.Contains(aV1) && theMVE.Contains(aV1) && aMFence.Add(aV1)) {
+          aLArgs.Append(aV1);
         }
-      } // for (; aExp.More(); aExp.Next()) {
-    } // for (; aIt.More(); aIt.Next()) {
+      }
+    }
   }
   //
+  aNb = theMSInv.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aV = theMSInv(i);
+    if (aV.ShapeType() != TopAbs_VERTEX) {
+      continue;
+    }
+    //
+    if (!aDMVE.Contains(aV)) {
+      continue;
+    }
+    //
+    const TopTools_ListOfShape& aLVE = aDMVE.FindFromKey(aV);
+    //
+    aIt.Initialize(aLVE);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aE = aIt.Value();
+      //
+      aExp.Init(aE, TopAbs_VERTEX);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Shape& aV1 = aExp.Current();
+        if (!theVertsToAvoid.Contains(aV1) && aMFence.Add(aV1)) {
+          aLArgs.Append(aV1);
+        }
+      }
+    }
+  }
+  //
+  // bounding vertices of untrimmed edges
+  TopTools_ListOfShape aLVBounds;
   // new intersection edges
   TopTools_ListOfShape aLENew;
   // get edges to intersect