]> OCCT Git - occt-copy.git/commitdiff
1. BRepOffset_MakeOffset::UpdateValidEdges() - Correct saving of the new intersection...
authoremv <emv@opencascade.com>
Fri, 20 May 2016 12:15:37 +0000 (15:15 +0300)
committeremv <emv@opencascade.com>
Fri, 20 May 2016 12:15:37 +0000 (15:15 +0300)
2. BRepOffset_MakeOffset::RemoveInsideFaces() - Use faces consisting only of invalid edges
and rejected while building the splits of offset faces to find the faces to remove.
3. BRepOffset_MakeOffset::GetBoundsToUpdate() - Update all face's edges (not only valid)
by intersection with new intersection edges.

src/BRepOffset/BRepOffset_MakeOffset.cxx

index 53cf961fd647378d48d5273209fa5ca89c934899..bf85a20ddd0e15f7ed89a8ca3f19c49755d4476b 100644 (file)
@@ -345,6 +345,7 @@ static
                         const TopTools_IndexedMapOfShape& theInvEdges,
                         const TopTools_IndexedMapOfShape& theValidEdges,
                         const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
+                        const TopTools_ListOfShape& theLEInvalid,
                         const TopTools_ListOfShape& theLENeutral,
                         const TopTools_MapOfShape& theMEInverted,
                         TopTools_ListOfShape& theInvFaces);
@@ -455,6 +456,7 @@ static
                          TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
                          const TopTools_DataMapOfShapeShape& theArtInvFaces,
                          const TopTools_IndexedMapOfShape& theInvEdges,
+                         const TopTools_IndexedMapOfShape& theMFToCheckInt,
                          TopTools_IndexedMapOfShape& theMERemoved);
 
 static
@@ -489,9 +491,134 @@ static
                            const TopTools_MapOfShape& theSpRem);
 
 static
-  void RemoveSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages,
-                    BOPAlgo_Builder& theGF,
-                    const TopTools_MapOfShape& theSpRem);
+  void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                                   const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+                                   TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
+                                   const TopTools_DataMapOfShapeShape& theArtInvFaces,
+                                   TopTools_IndexedDataMapOfShapeListOfShape& theFLE,
+                                   TopTools_DataMapOfShapeListOfShape& theMDone,
+                                   TopTools_DataMapOfShapeListOfShape& theDMSF,
+                                   TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
+                                   TopTools_DataMapOfShapeListOfShape& theDMVEFull,
+                                   TopTools_DataMapOfShapeShape& theETrimEInf,
+                                   TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv,
+                                   const Standard_Boolean bLookVertToAvoid);
+
+static
+  void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv,
+                           TopTools_DataMapOfShapeListOfShape& theDMVEFull,
+                           const TopTools_IndexedMapOfShape& theInvEdges,
+                           const TopTools_IndexedMapOfShape& theValidEdges,
+                           TopTools_MapOfShape& theMVRInv);
+
+static
+  void FindFacesForIntersection(const TopoDS_Shape& theFInv,
+                                const TopTools_IndexedMapOfShape& theME,
+                                const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+                                const TopTools_DataMapOfShapeShape& theArtInvFaces,
+                                const TopTools_DataMapOfShapeListOfShape& theDMSF,
+                                const TopTools_MapOfShape& theMVInvAll,
+                                TopTools_IndexedMapOfShape& theMFAvoid,
+                                TopTools_IndexedMapOfShape& theMFInt,
+                                TopTools_ListOfShape& theLFImInt);
+
+static
+  void ProcessCommonEdges(const TopTools_ListOfShape& theLEC,
+                          const TopTools_IndexedMapOfShape& theInvEdges,
+                          const TopTools_IndexedMapOfShape& theValidEdges,
+                          const TopTools_IndexedMapOfShape& theME,
+                          const TopTools_DataMapOfShapeShape& theETrimEInf,
+                          const TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
+                          TopTools_IndexedMapOfShape& theMECV,
+                          TopTools_DataMapOfShapeListOfShape& theDMEETrim,
+                          TopTools_ListOfShape& theLFEi,
+                          TopTools_ListOfShape& theLFEj,
+                          TopTools_IndexedMapOfShape& theMEToInt);
+
+static
+  void UpdateIntersectedFaces(const TopoDS_Shape& theFInv,
+                              const TopoDS_Shape& theFi,
+                              const TopoDS_Shape& theFj,
+                              const TopTools_ListOfShape& theLFInv,
+                              const TopTools_ListOfShape& theLFImi,
+                              const TopTools_ListOfShape& theLFImj,
+                              const TopTools_ListOfShape& theLFEi,
+                              const TopTools_ListOfShape& theLFEj,
+                              TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                              TopTools_IndexedMapOfShape& theMEToInt);
+
+static
+  void IntersectFaces(const TopoDS_Shape& theFInv,
+                      const TopoDS_Shape& theFi,
+                      const TopoDS_Shape& theFj,
+                      const TopTools_ListOfShape& theLFInv,
+                      const TopTools_ListOfShape& theLFImi,
+                      const TopTools_ListOfShape& theLFImj,
+                      TopTools_ListOfShape& theLFEi,
+                      TopTools_ListOfShape& theLFEj,
+                      TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                      TopTools_IndexedMapOfShape& theMECV,
+                      TopTools_IndexedMapOfShape& theMEToInt);
+
+static
+  void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE,
+                                TopTools_DataMapOfShapeListOfShape& theEImages,
+                                const TopTools_DataMapOfShapeListOfShape& theEETrim,
+                                TopTools_MapOfShape& theMEB,
+                                TopTools_MapOfShape& theMVOld,
+                                TopTools_MapOfShape& theMVBounds,
+                                TopTools_ListOfShape& theLENew,
+                                BOPCol_ListOfShape& theLA);
+
+static
+  void IntersectEdges(const BOPCol_ListOfShape& theLA,
+                      const TopTools_ListOfShape& theLE,
+                      const TopTools_ListOfShape& theLENew,
+                      TopTools_DataMapOfShapeListOfShape& theEImages,
+                      TopTools_MapOfShape& theVertsToAvoid,
+                      TopTools_MapOfShape& theMVBounds,
+                      TopTools_MapOfShape& theModifiedEdges,
+                      TopTools_MapOfShape& theMENew,
+                      TopoDS_Shape& theSplits);
+
+static
+  void GetBounds(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                 const TopTools_IndexedDataMapOfShapeListOfShape& theDMFFIm,
+                 const TopTools_MapOfShape& theMEB,
+                 TopoDS_Shape& theBounds);
+
+static
+  void GetBoundsToUpdate(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                         const TopTools_DataMapOfShapeListOfShape& theOEImages,
+                         const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
+                         const TopTools_MapOfShape& theMEB,
+                         TopTools_ListOfShape& theLABounds,
+                         TopTools_ListOfShape& theLAValid,
+                         TopoDS_Shape& theBounds,
+                         Handle(BRepAlgo_AsDes)& theAsDes);
+
+static
+  void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits,
+                               const TopoDS_Shape& theBounds,
+                               const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                               const TopTools_IndexedDataMapOfShapeListOfShape& theDMFFIm,
+                               const TopTools_IndexedMapOfShape& theInvEdges,
+                               const TopTools_MapOfShape& theMVOld,
+                               const TopTools_MapOfShape& theMENew,
+                               TopTools_MapOfShape& theVertsToAvoid,
+                               TopTools_MapOfShape& theMEInv);
+
+static
+  void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE,
+                                  const TopTools_DataMapOfShapeListOfShape& theMELF,
+                                  const TopTools_DataMapOfShapeListOfShape& theEImages,
+                                  TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                                  TopTools_DataMapOfShapeListOfShape& theOEImages,
+                                  TopTools_DataMapOfShapeListOfShape& theOEOrigins,
+                                  TopTools_DataMapOfShapeShape& theETrimEInf,
+                                  TopTools_DataMapOfShapeListOfShape& theEETrim,
+                                  TopTools_MapOfShape& theModifiedEdges,
+                                  Handle(BRepAlgo_AsDes)& theAsDes);
 
 static 
   void FindFacesToRebuild(TopTools_IndexedDataMapOfShapeListOfShape&  theLFImages,
@@ -4195,6 +4322,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   TopTools_DataMapOfShapeListOfShape aDMFLIE;
   // map of inverted edges
   TopTools_MapOfShape aMEInverted;
+  // map of splits to check for internals
+  TopTools_IndexedMapOfShape aMFToCheckInt;
   //
   Handle(IntTools_Context) aCtx = new IntTools_Context;
   // build splits of faces
@@ -4221,36 +4350,43 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
       Standard_Boolean bArtificialCase = aLFImages.IsEmpty() ||
         CheckIfArtificial(aF, aLFImages, aCE, aMapEInv, aMENInv, theAsDes, theOEImages);
       //
-      if (bArtificialCase) {
-        // try to build splits using invalid edges
-        TopTools_IndexedMapOfShape anEmptyInvEdges;
-        TopoDS_Shape aCE1;
-        GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, anEmptyInvEdges,
-          aCtx, theModifiedEdges, aCE1, aMapEInv);
-        //
-        TopTools_ListOfShape aLFImages1;
-        BuildSplitsOfFace(aF, aCE1, Standard_False, theFacesOrigins, aLFImages1);
-        //
-        // additionally check if newly created faces are not the same
-        TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1);
-        for (; aItLFIm.More();) {
-          const TopoDS_Shape& aFIm = aItLFIm.Value();
-          TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
-          for (; aExpE.More(); aExpE.Next()) {
-            const TopoDS_Shape& aE = aExpE.Current();
-            if (!aMapEInv.Contains(aE) && !aMENInv.Contains(aE)) {
-              break;
-            }
-          }
-          //
-          if (!aExpE.More()) {
-            aLFImages1.Remove(aItLFIm);
+      // try to build splits using invalid edges
+      TopTools_IndexedMapOfShape anEmptyInvEdges;
+      TopoDS_Shape aCE1;
+      GetEdges(aF, theAsDes, theOEImages, theLastInvEdges, anEmptyInvEdges,
+        aCtx, theModifiedEdges, aCE1, aMapEInv);
+      //
+      TopTools_ListOfShape aLFImages1;
+      BuildSplitsOfFace(aF, aCE1, Standard_False, theFacesOrigins, aLFImages1);
+      //
+      // additionally check if newly created faces are not the same
+      Standard_Boolean bAllInv = Standard_True;
+      TopTools_ListIteratorOfListOfShape aItLFIm(aLFImages1);
+      for (; aItLFIm.More();) {
+        const TopoDS_Shape& aFIm = aItLFIm.Value();
+        TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
+        for (; aExpE.More(); aExpE.Next()) {
+          const TopoDS_Shape& aE = aExpE.Current();
+          if (!aMapEInv.Contains(aE) && !aMENInv.Contains(aE)) {
+            break;
           }
-          else {
-            aItLFIm.Next();
+          else if (bAllInv) {
+            bAllInv = aMapEInv.Contains(aE);
           }
         }
         //
+        if (!aExpE.More()) {
+          if (bAllInv) {
+            aMFToCheckInt.Add(aFIm);
+          }
+          aLFImages1.Remove(aItLFIm);
+        }
+        else {
+          aItLFIm.Next();
+        }
+      }
+      //
+      if (bArtificialCase) {
         if (aLFImages.Extent() == aLFImages1.Extent()) {
           bArtificialCase = Standard_False;
         }
@@ -4326,9 +4462,11 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
     }
     else {
       // neutral edges
-      const TopTools_ListOfShape& aLEN = aDMFLNE.Find(aF);
+      const TopTools_ListOfShape& aLNE = aDMFLNE.Find(aF);
+      // invalid edges
+      const TopTools_ListOfShape& aLIE = aDMFLIE.Find(aF);
       //
-      FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aLEN, aMEInverted, aLFInv);
+      FindInvalidFaces(aLFImages, theInvEdges, theValidEdges, aDMFLVE, aLIE, aLNE, aMEInverted, aLFInv);
     }
     //
     if (aLFInv.Extent()) {
@@ -4356,7 +4494,8 @@ void BuildSplitsOfFaces(const TopTools_ListOfShape& theLF,
   //
   // remove inside faces
   TopTools_IndexedMapOfShape aMERemoved;
-  RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, theInvEdges, aMERemoved);
+  RemoveInsideFaces(theFImages, theInvFaces, theArtInvFaces, 
+                    theInvEdges, aMFToCheckInt, aMERemoved);
   //
   // make compound of valid splits
   TopoDS_Compound aCFIm;
@@ -4613,149 +4752,24 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
   // Add all faces to rebuild to outgoing map <aFLE>,
   // plus link edges and vertices to the faces to
   // define intersection faces
-  for (i = 1; i <= aNbFR; ++i) {
-    const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
-    //
-    TopTools_ListOfShape aLE;
-    aFLE.Add(aF, aLE);
-    aMDone.Bind(aF, aLE);
-    //
-    const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
-    aItLF.Initialize(aLFIm);
-    for (; aItLF.More(); aItLF.Next()) {
-      const TopoDS_Shape& aFIm = aItLF.Value();
-      aExp.Init(aFIm, TopAbs_EDGE);
-      for (; aExp.More(); aExp.Next()) {
-        const TopoDS_Shape& aE = aExp.Current();
-        // save connection to untrimmed face
-        if (aDMSF.IsBound(aE)) {
-          TopTools_ListOfShape& aLF = aDMSF.ChangeFind(aE);
-          AppendToList(aLF, aF);
-        }
-        else {
-          TopTools_ListOfShape aLF;
-          aLF.Append(aF);
-          aDMSF.Bind(aE, aLF);
-        }
-        //
-        // save connection to untrimmed edge
-        const TopoDS_Shape& aEInf = theETrimEInf.Find(aE);
-        if (aMEInfETrim.IsBound(aEInf)) {
-          TopTools_ListOfShape& aLETrim = aMEInfETrim.ChangeFind(aEInf);
-          AppendToList(aLETrim, aE);
-        }
-        else {
-          TopTools_ListOfShape aLETrim;
-          aLETrim.Append(aE);
-          aMEInfETrim.Bind(aEInf, aLETrim);
-        }
-        //
-        TopExp_Explorer aExpV(aE, TopAbs_VERTEX);
-        for (; aExpV.More(); aExpV.Next()) {
-          const TopoDS_Shape& aV = aExpV.Current();
-          // save connection to face
-          if (aDMSF.IsBound(aV)) {
-            TopTools_ListOfShape& aLFV = aDMSF.ChangeFind(aV);
-            AppendToList(aLFV, aF);
-          }
-          else {
-            TopTools_ListOfShape aLFV;
-            aLFV.Append(aF);
-            aDMSF.Bind(aV, aLFV);
-          }
-          //
-          if (bLookVertToAvoid) {
-            // save connection to edges
-            if (aDMVEFull.IsBound(aV)) {
-              TopTools_ListOfShape& aLEV = aDMVEFull.ChangeFind(aV);
-              AppendToList(aLEV, aE);
-            }
-            else {
-              TopTools_ListOfShape aLEV;
-              aLEV.Append(aE);
-              aDMVEFull.Bind(aV, aLEV);
-            }
-          }
-        }
-      }
-    }
-    //
-    if (bLookVertToAvoid) {
-      // get edges of invalid faces (from invalid splits only)
-      if (!theInvFaces.Contains(aF) || theArtInvFaces.IsBound(aF)) {
-        continue;
-      }
-      //
-      const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF);
-      //
-      aItLF.Initialize(aLFInv);
-      for (; aItLF.More(); aItLF.Next()) {
-        const TopoDS_Shape& aFInv = aItLF.Value();
-        aExp.Init(aFInv, TopAbs_EDGE);
-        for (; aExp.More(); aExp.Next()) {
-          const TopoDS_Shape& aE = aExp.Current();
-          if (aDMEFInv.Contains(aE)) {
-            TopTools_ListOfShape& aLF = aDMEFInv.ChangeFromKey(aE);
-            AppendToList(aLF, aF);
-          }
-          else {
-            TopTools_ListOfShape aLF;
-            aLF.Append(aF);
-            aDMEFInv.Add(aE, aLF);
-          }
-        }
-      }
-    }
-  }
-  //
+  PrepareFacesForIntersection(theFToRebuild, theDMFFIm, theInvFaces, 
+                              theArtInvFaces, aFLE, aMDone, aDMSF, aMEInfETrim, 
+                              aDMVEFull, theETrimEInf, aDMEFInv, bLookVertToAvoid);
+
   // Find vertices to avoid while trimming the edges.
   // These vertices are taken from the invalid edges common between
   // splits of different invalid, but not artificially, faces.
   // Additional condition for these vertices is that all 
   // edges adjacent to this vertex must be either invalid
   // or contained in invalid faces
-  TopTools_MapOfShape aMFence, aMVRInv = theVertsToAvoid;
-  aNbInv = aDMEFInv.Extent();
-  for (i = 1; i <= aNbInv; ++i) {
-    const TopTools_ListOfShape& aLFInv = aDMEFInv(i);
-    if (aLFInv.Extent() == 1) {
-      continue;
-    }
-    //
-    const TopoDS_Shape& aE = aDMEFInv.FindKey(i);
-    if (!theInvEdges.Contains(aE) || theValidEdges.Contains(aE)) {
-      continue;
-    }
-    //
-    aExp.Init(aE, TopAbs_VERTEX);
-    for (; aExp.More(); aExp.Next()) {
-      const TopoDS_Shape& aV = aExp.Current();
-      if (!aDMVEFull.IsBound(aV)) {
-        aMVRInv.Add(aV);
-        continue;
-      }
-      //
-      const TopTools_ListOfShape& aLE = aDMVEFull.Find(aV);
-      //
-      aItLE.Initialize(aLE);
-      for (; aItLE.More(); aItLE.Next()) {
-        const TopoDS_Shape& aEV = aItLE.Value();
-        if (!theInvEdges.Contains(aEV) && !aDMEFInv.Contains(aEV)) {
-          break;
-        }
-      }
-      if (!aItLE.More()) {
-        aMVRInv.Add(aV);
-      }
-    }
-  }
+  TopTools_MapOfShape aMVRInv = theVertsToAvoid;
+  FindVerticesToAvoid(aDMEFInv, aDMVEFull, theInvEdges, theValidEdges, aMVRInv);
   //
   // The faces should be intersected selectively - 
   // intersect only faces neighboring to the same invalid face
   // and connected to its invalid edges and its valid edges with free bounds
-  TopTools_MapOfShape aMEAlone;
+  TopTools_MapOfShape aMEAlone, aMFence;
   TopTools_IndexedDataMapOfShapeListOfShape aDMVEVal;
-  aMFence.Clear();
   //
   aNbInv = theInvFaces.Extent();
   for (i = 1; i <= aNbInv; ++i) {
@@ -4859,34 +4873,9 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
         TopTools_ListOfShape aLFInt;
         // faces to avoid intersection
         TopTools_IndexedMapOfShape aMFAvoid;
-        Standard_Integer aNbE = aME.Extent();
-        for (i = 1; i <= aNbE; ++i) {
-          const TopoDS_Shape& aS = aME(i);
-          if (aDMSF.IsBound(aS)) {
-            const TopTools_ListOfShape& aLF = aDMSF.Find(aS);
-            aItLE.Initialize(aLF);
-            for (; aItLE.More(); aItLE.Next()) {
-              const TopoDS_Shape& aF = aItLE.Value();
-              if (!aMFInt.Contains(aF)) {
-                const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
-                // check if this face is close to invalidity
-                if (theArtInvFaces.IsBound(aFInv) && theArtInvFaces.IsBound(aF)) {
-                  if (aS.ShapeType() != TopAbs_EDGE && !aMVInvAll.Contains(aS)) {
-                    aMFAvoid.Add(aF);
-                  }
-                }
-                //
-                aMFInt.Add(aF);
-                // Debug
-                TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm);
-                for (; aItLFIm.More(); aItLFIm.Next()) {
-                  const TopoDS_Shape& aFIm = aItLFIm.Value();
-                  aLFInt.Append(aFIm);
-                }
-              }
-            }
-          }
-        }
+        //
+        FindFacesForIntersection(aFInv, aME, theDMFFIm, theArtInvFaces, 
+                                 aDMSF, aMVInvAll, aMFAvoid, aMFInt, aLFInt);
         //
         // intersect the faces, but do not intersect the invalid ones
         // among each other (except for the artificially invalid faces)
@@ -4920,56 +4909,11 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
             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
-                const TopTools_ListOfShape& aLVE = aMEInfETrim.Find(aEInt);
-                TopTools_ListIteratorOfListOfShape aItLVE(aLVE);
-                for (; aItLVE.More(); aItLVE.Next()) {
-                  const TopoDS_Shape& aECx = aItLVE.Value();
-                  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);
-              }
+              ProcessCommonEdges(aLEC, theInvEdges, theValidEdges, aME, theETrimEInf,
+                                 aMEInfETrim, aMECV, aDMEETrim, aLFEi, aLFEj, aMEToInt);
+              //
+              // no need to intersect if we have common edges between faces
+              continue;
             }
             //
             // check if both these faces are invalid and sharing edges
@@ -4978,11 +4922,6 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
               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()) {
@@ -4995,58 +4934,8 @@ 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);
-              //
-              TopTools_MapOfShape aMEi;
-              aItLE.Initialize(aLEi);
-              for (; aItLE.More(); aItLE.Next()) {
-                const TopoDS_Shape& aE = aItLE.Value();
-                aMEi.Add(aE);
-              }
-              //
-              // find origins
-              TopTools_IndexedMapOfShape aMEToFindOrigins;
-              TopTools_ListOfShape aLEToFindOrigins;
-              if (!aFi.IsSame(aFInv)) {
-                FindCommonParts(aLFImi, aLFInv, aLEToFindOrigins);
-              }
-              if (!aFj.IsSame(aFInv)) {
-                FindCommonParts(aLFImj, aLFInv, aLEToFindOrigins);
-              }
-              //
-              TopTools_ListOfShape aLEOrInit;
-              aItLE.Initialize(aLEToFindOrigins);
-              for (; aItLE.More(); aItLE.Next()) {
-                const TopoDS_Shape& aEC = aItLE.Value();
-                aMEToFindOrigins.Add(aEC);
-              }
-              //
-              FindOrigins(aLFImi, aLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit);
-              //
-              aItLE.Initialize(aLEj);
-              for (; aItLE.More(); aItLE.Next()) {
-                const TopoDS_Shape& aE = aItLE.Value();
-                if (aMEi.Contains(aE)) {
-                  aMEToInt.Add(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);
-                    }
-                  }
-                }
-              }
-              //
+              UpdateIntersectedFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj,
+                                     aLFEi, aLFEj, theEdgesOrigins, aMEToInt);
               continue;
             }
             //
@@ -5057,57 +4946,8 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
             aLFDone.Append(aFj);
             aMDone.ChangeFind(aFj).Append(aFi);
             //
-            // intersect faces
-            TopAbs_State aSide = TopAbs_OUT;
-            TopTools_ListOfShape aLInt1, aLInt2;
-            TopoDS_Edge aNullEdge;
-            BRepOffset_Tool::Inter3D(aFi, aFj, aLInt1, aLInt2, aSide, aNullEdge);
-            //
-            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;
-            if (!aFi.IsSame(aFInv)) {
-              FindCommonParts(aLFImi, aLFInv, aLEToFindOrigins);
-            }
-            if (!aFj.IsSame(aFInv)) {
-              FindCommonParts(aLFImj, aLFInv, aLEToFindOrigins);
-            }
-            TopTools_ListOfShape aLEOrInit;
-            aItLE.Initialize(aLEToFindOrigins);
-            for (; aItLE.More(); aItLE.Next()) {
-              const TopoDS_Shape& aEC = aItLE.Value();
-              aMEToFindOrigins.Add(aEC);
-            }
-            //
-            FindOrigins(aLFImi, aLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit);
-            //
-            aItLE.Initialize(aLInt1);
-            for (; aItLE.More(); aItLE.Next()) {
-              const TopoDS_Shape& aEInt = aItLE.Value();
-              aLFEi.Append(aEInt);
-              aLFEj.Append(aEInt);
-              //
-              if (aLEOrInit.Extent()) {
-                theEdgesOrigins.Bind(aEInt, aLEOrInit);
-              }
-              //
-              aMEToInt.Add(aEInt);
-            }
+            IntersectFaces(aFInv, aFi, aFj, aLFInv, aLFImi, aLFImj, 
+                           aLFEi, aLFEj, theEdgesOrigins, aMECV, aMEToInt);
           }
         }
         //
@@ -5125,7 +4965,7 @@ void IntersectFaces(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebui
 }
 
 //=======================================================================
-//function : IntersectEdges
+//function : IntersectAndTrimEdges
 //purpose  : 
 //=======================================================================
 void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
@@ -5185,7 +5025,6 @@ void IntersectAndTrimEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theF
     }
     //
     const TopTools_ListOfShape& aLVE = aDMVE.FindFromKey(aV);
-    //
     aIt.Initialize(aLVE);
     for (; aIt.More(); aIt.Next()) {
       const TopoDS_Shape& aE = aIt.Value();
@@ -5342,357 +5181,44 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToReb
   TopTools_MapOfShape aMENew;
   // map of old vertices
   TopTools_MapOfShape aMVOld;
-  // intersect the splits among themselves
+  //
+  // trim the new intersection edges
   BOPCol_ListOfShape aLA;
-  aIt.Initialize(aLE);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aE = aIt.Value();
-    //
-    if (theEETrim.IsBound(aE)) {
-      const TopTools_ListOfShape& aLET = theEETrim.Find(aE);
-      aIt1.Initialize(aLET);
-      for (; aIt1.More(); aIt1.Next()) {
-        const TopoDS_Shape& aET = aIt1.Value();
-        aMEB.Add(aET);
-        TopExp_Explorer aExpV(aET, TopAbs_VERTEX);
-        for (; aExpV.More(); aExpV.Next()) {
-          const TopoDS_Shape& aV = aExpV.Current();
-          aMVOld.Add(aV);
-        }
-      }
+  TrimNewIntersectionEdges(aLE, theEImages, theEETrim, aMEB,
+                           aMVOld, theMVBounds, aLENew, aLA);
+  //
+  // intersect the splits among themselves
+  BOPAlgo_Builder aGF;
+  TopTools_ListOfShape aLAValid, aLABounds;
+  //
+  if (aLA.Extent()) {
+    TopoDS_Shape aSplits1;
+    if (aLA.Extent() > 1) {
+      // fuse all images to avoid self-intersections
+      IntersectEdges(aLA, aLE, aLENew, theEImages, theVertsToAvoid, 
+                     theMVBounds, theModifiedEdges, aMENew, aSplits1);
     }
-    //
-    if (!theEImages.IsBound(aE)) {
-      continue;
+    else {
+      aSplits1 = aLA.First();
     }
     //
-    TopTools_ListOfShape& aLEIm = theEImages.ChangeFind(aE);
-    if (aLEIm.IsEmpty()) {
-      theEImages.UnBind(aE);
-      continue;
-    }
-    //
-    TopoDS_Shape aCEIm;
-    TopTools_MapOfShape aMEVBounds;
-    //
-    if (aLEIm.Extent() > 2) {
-      // fuse these parts
-      BOPAlgo_Builder aGFE;
-      TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
-      for (; aItLEIm.More(); aItLEIm.Next()) {
-        const TopoDS_Shape& aEIm = aItLEIm.Value();
-        aGFE.AddArgument(aEIm);
-      }
-      //
-      // add two bounding vertices of this edge to the operation
-      TopoDS_Vertex aV1, aV2;
-      TopExp::Vertices(TopoDS::Edge(aE), aV1, aV2);
-      //
-      aGFE.AddArgument(aV1);
-      aGFE.AddArgument(aV2);
-      //
-      aGFE.Perform();
-      //
-      // get images of bounding vertices to remove splits containing them
-      const TopTools_ListOfShape& aLV1Im = aGFE.Modified(aV1);
-      const TopTools_ListOfShape& aLV2Im = aGFE.Modified(aV2);
-      //
-      if (aLV1Im.Extent()) {
-        aMEVBounds.Add(aLV1Im.First());
-      }
-      else {
-        aMEVBounds.Add(aV1);
-      }
-      //
-      if (aLV2Im.Extent()) {
-        aMEVBounds.Add(aLV2Im.First());
-      }
-      else {
-        aMEVBounds.Add(aV2);
-      }
-      //
-      {
-        TopTools_MapIteratorOfMapOfShape aItM(theMVBounds);
-        for (; aItM.More(); aItM.Next()) {
-          const TopoDS_Shape& aV = aItM.Key();
-          const TopTools_ListOfShape& aLVIm = aGFE.Modified(aV);
-          if (aLVIm.Extent()) {
-            aMEVBounds.Add(aLVIm.First());
-          }
-          else {
-            aMEVBounds.Add(aV);
-          }
-        }
-      }
-      //
-      aCEIm = aGFE.Shape();
-    }
-    else {
-      aCEIm = aLEIm.First();
-    }
-    //
-    aLEIm.Clear();
-    //
-    TopExp_Explorer aExp(aCEIm, TopAbs_EDGE);
-    for (; aExp.More(); aExp.Next()) {
-      const TopoDS_Shape& aEIm = aExp.Current();
-      //
-      // check the split not to contain bounding vertices
-      TopExp_Explorer aExpV(aEIm, TopAbs_VERTEX);
-      for (; aExpV.More(); aExpV.Next()) {
-        const TopoDS_Shape& aV = aExpV.Current();
-        //
-        if (theMVBounds.Contains(aV) || aMEVBounds.Contains(aV)) {
-          break;
-        }
-      }
-      //
-      if (!aExpV.More()) {
-        aLA.Append(aEIm);
-        aLEIm.Append(aEIm);
-      }
-    }
-    //
-    if (aLEIm.IsEmpty()) {
-      theEImages.UnBind(aE);
-    }
-    else {
-      if (!theEETrim.IsBound(aE)) {
-        TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
-        for (; aItLEIm.More(); aItLEIm.Next()) {
-          const TopoDS_Shape& aEIm = aItLEIm.Value();
-          aLENew.Append(aEIm);
-        }
-      }
-    }
-  }
-  //
-  BOPAlgo_Builder aGF;
-  TopTools_ListOfShape aLAValid, aLABounds;
-  //
-  if (aLA.Extent()) {
-    //
-    TopTools_MapOfShape aMEInv;
-    TopoDS_Shape aSplits1;
-    if (aLA.Extent() > 1) {
-      // fuse all images to avoid self-intersections
-      BOPAlgo_Builder aGFA;
-      aGFA.SetArguments(aLA);
-      aGFA.Perform();
-      //
-      UpdateImages(aLE, theEImages, aGFA, theModifiedEdges);
-      //
-      // compound of valid splits
-      aSplits1 = aGFA.Shape();
-      //
-      // update new edges
-      aIt.Initialize(aLENew);
-      for (; aIt.More(); aIt.Next()) {
-        const TopoDS_Shape& aE = aIt.Value();
-        const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE);
-        if (aLEIm.Extent()) {
-          aIt1.Initialize(aLEIm);
-          for (; aIt1.More(); aIt1.Next()) {
-            const TopoDS_Shape& aEIm= aIt1.Value();
-            aMENew.Add(aEIm);
-          }
-        }
-        else {
-          aMENew.Add(aE);
-        }
-      }
-      //
-      GetInvalidEdges(aGFA, /*aLENew, */theVertsToAvoid, theMVBounds, aMEInv);
-      if (aMEInv.Extent()) {
-        // update shape
-        TopoDS_Compound aSp1;
-        BRep_Builder aBB;
-        aBB.MakeCompound(aSp1);
-        TopExp_Explorer aExp(aSplits1, TopAbs_EDGE);
-        for (; aExp.More(); aExp.Next()) {
-          const TopoDS_Shape& aE = aExp.Current();
-          if (!aMEInv.Contains(aE)) {
-            aBB.Add(aSp1, aE);
-          }
-        }
-        aSplits1 = aSp1;
-      }
-    }
-    else {
-      aSplits1 = aLA.First();
-    }
-    //
-    // make compound of valid edges
-    TopoDS_Compound aBounds;
-    BRep_Builder aBB;
-    aBB.MakeCompound(aBounds);
-    //
-    TopTools_MapOfShape aMAValid, aMFence;
-    //
-    aNb = theFToRebuild.Extent();
-    for (i = 1; i <= aNb; ++i) {
-      const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
-      const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
-      //
-      aIt.Initialize(aLFIm);
-      for (; aIt.More(); aIt.Next()) {
-        const TopoDS_Shape& aFIm = aIt.Value();
-        //
-        TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
-        for (; aExpE.More(); aExpE.Next()) {
-          const TopoDS_Shape& aEIm = aExpE.Current();
-          //
-          if (!aMEB.Contains(aEIm) && aMFence.Add(aEIm)) {
-            aBB.Add(aBounds, aEIm);
-            aLABounds.Append(aEIm);
-          }
-          //
-          if (theOEOrigins.IsBound(aEIm)) {
-            const TopTools_ListOfShape& aLO = theOEOrigins.Find(aEIm);
-            TopTools_ListIteratorOfListOfShape aItLO(aLO);
-            for (; aItLO.More(); aItLO.Next()) {
-              const TopoDS_Shape& aEO = aItLO.Value();
-              //
-              if (aMAValid.Add(aEO)) {
-                aLAValid.Append(aEO);
-              }
-            }
-          }
-          else {
-            if (aMAValid.Add(aEIm)) {
-              aLAValid.Append(aEIm);
-            }
-          }
-        }
-      }
-    }
+    TopoDS_Shape aFilterBounds;
+    GetBounds(theFToRebuild, theDMFFIm, aMEB, aFilterBounds);
     //
     // intersect splits and bounds and remove those splits which have pure E/E intersection
-    BOPAlgo_Builder aGF1;
-    aGF1.AddArgument(aSplits1);
-    aGF1.AddArgument(aBounds);
-    //
-    aGF1.Perform();
-    //
-    // invalid vertices
-    TopTools_IndexedMapOfShape aMVInv;
-    // collect parts for removal
-    const BOPDS_PDS& pDS = aGF1.PDS();
-    //
-    // check edge/edge intersections
-    const BOPDS_VectorOfInterfEE& aEEs = pDS->InterfEE();
-    aNb = aEEs.Extent();
-    for (i = 0; i < aNb; ++i) {
-      const BOPDS_InterfEE& aEE = aEEs(i);
-      const TopoDS_Shape& aE1 = pDS->Shape(aEE.Index1());
-      const TopoDS_Shape& aE2 = pDS->Shape(aEE.Index2());
-      if (!aEE.HasIndexNew()) {
-        continue;
-      }
-      //
-      if (!theInvEdges.Contains(aE2)) {
-        aMEInv.Add(aE1);
-        //
-        TopExp_Explorer aExpV(aE1, TopAbs_VERTEX);
-        for (; aExpV.More(); aExpV.Next()) {
-          const TopoDS_Shape& aV = aExpV.Current();
-          if (!aMVOld.Contains(aV)) {
-            aMVInv.Add(aV);
-          }
-        }
-      }
-    }
-    //
-    // add for check also the vertices connected only to new edges
-    TopTools_IndexedDataMapOfShapeListOfShape aDMVE;
-    TopExp::MapShapesAndAncestors(aSplits1, TopAbs_VERTEX, TopAbs_EDGE, aDMVE);
-    //
-    aNb = aDMVE.Extent();
-    for (i = 1; i <= aNb; ++i) {
-      const TopoDS_Shape& aV = aDMVE.FindKey(i);
-      if (aMVInv.Contains(aV)) {
-        continue;
-      }
-      //
-      Standard_Boolean bNew = Standard_False, bOld = Standard_False;
-      const TopTools_ListOfShape& aLEx = aDMVE(i);
-      aIt.Initialize(aLEx);
-      for (; aIt.More(); aIt.Next()) {
-        const TopoDS_Shape& aE = aIt.Value();
-        if (aMENew.Contains(aE)) {
-          bNew = Standard_True;
-        }
-        else {
-          bOld = Standard_True;
-        }
-        //
-        if (bNew && bOld) {
-          break;
-        }
-      }
-      //
-      if (!bNew || !bOld) {
-        aMVInv.Add(aV);
-      }
-      /*const TopTools_ListOfShape& aLEx = aDMVE(i);
-      aIt.Initialize(aLEx);
-      for (; aIt.More(); aIt.Next()) {
-        const TopoDS_Shape& aE = aIt.Value();
-        if (!aMENew.Contains(aE)) {
-          break;
-        }
-      }
-      if (!aIt.More()) {
-        aMVInv.Add(aV);
-      }*/
-    }
-    //
-    Handle(IntTools_Context) aCtx = new IntTools_Context;
-    // filter vertices
-    Standard_Integer iv, aNbIV = aMVInv.Extent(), aNbF = theFToRebuild.Extent();
-    for (iv = 1; iv <= aNbIV; ++iv) {
-      const TopoDS_Vertex& aV = TopoDS::Vertex(aMVInv(iv));
-      const gp_Pnt& aP = BRep_Tool::Pnt(aV);
-      Standard_Real aTolV = BRep_Tool::Tolerance(aV);
-      //
-      for (i = 1; i <= aNbF; ++i) {
-        const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
-        const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
-        //
-        TopTools_ListIteratorOfListOfShape aItLF(aLFIm);
-        for (; aItLF.More(); aItLF.Next()) {
-          const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value());
-          if (aCtx->IsValidPointForFace(aP, aFIm, aTolV)) {
-            break;
-          }
-        }
-        //
-        if (aItLF.More()) {
-          break;
-        }
-      }
-      //
-      if (i > aNbF) {
-        theVertsToAvoid.Add(aV);
-        if (aDMVE.Contains(aV)) {
-          const TopTools_ListOfShape& aLEInv = aDMVE.FindFromKey(aV);
-          TopTools_ListIteratorOfListOfShape aItLEInv(aLEInv);
-          for (; aItLEInv.More(); aItLEInv.Next()) {
-            const TopoDS_Shape& aEInv = aItLEInv.Value();
-            aMEInv.Add(aEInv);
-          }
-        }
-      }
-    }
-    //
-    //
-    TopoDS_Compound aSplits;
-    aBB.MakeCompound(aSplits);
-    //
-    aMFence.Clear();
+    TopTools_MapOfShape aMEInv;
+    GetInvalidEdgesByBounds(aSplits1, aFilterBounds, theFToRebuild, theDMFFIm, 
+                            theInvEdges, aMVOld, aMENew, theVertsToAvoid, aMEInv);
     //
+    // get valid edges only
+    TopoDS_Shape aSplits;
     // clear images from newly found invalid edges
     if (aMEInv.Extent()) {
+      TopoDS_Compound aSp;
+      BRep_Builder aBB;
+      TopTools_MapOfShape aMFence;
+      aBB.MakeCompound(aSp);
+      //
       aIt.Initialize(aLE);
       for (; aIt.More(); aIt.Next()) {
         const TopoDS_Shape& aE = aIt.Value();
@@ -5710,7 +5236,7 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToReb
           }
           else {
             if (aMFence.Add(aEIm)) {
-              aBB.Add(aSplits, aEIm);
+              aBB.Add(aSp, aEIm);
             }
             aItLEIm.Next();
           }
@@ -5720,11 +5246,16 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToReb
           theEImages.UnBind(aE);
         }
       }
+      aSplits = aSp;
     }
     else {
-      aBB.Add(aSplits, aSplits1);
+      aSplits = aSplits1;
     }
     //
+    TopoDS_Shape aBounds;
+    GetBoundsToUpdate(theFToRebuild, theOEImages, theOEOrigins,
+                      aMEB, aLABounds, aLAValid, aBounds, theAsDes);
+    //
     aGF.AddArgument(aSplits);
     aGF.AddArgument(aBounds);
     aGF.Perform();
@@ -5732,164 +5263,9 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFToReb
     UpdateImages(aLE, theEImages, aGF, theModifiedEdges);
   }
   //
-  TopTools_ListOfShape aLEImEmpty;
-  // update global maps of images and origins with new splits
-  aIt.Initialize(aLE);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aE = aIt.Value();
-    //
-    /*if (!theEImages.IsBound(aE)) {
-      continue;
-    }*/
-    // new images
-    const TopTools_ListOfShape& aLENew = 
-      theEImages.IsBound(aE) ? theEImages.Find(aE) : aLEImEmpty;
-    //
-    // save connection to untrimmed edge for the next steps
-    aIt1.Initialize(aLENew);
-    for (; aIt1.More(); aIt1.Next()) {
-      const TopoDS_Shape& aET = aIt1.Value();
-      theETrimEInf.Bind(aET, aE);
-      theModifiedEdges.Add(aET);
-    }
-    //
-    // check if it is existing edge
-    if (!theEETrim.IsBound(aE)) {
-      const TopTools_ListOfShape& aLF = aMELF.Find(aE);
-      // the edge is new
-      // add this edge to AsDes
-      aIt1.Initialize(aLF);
-      for (; aIt1.More(); aIt1.Next()) {
-        const TopoDS_Shape& aF = aIt1.Value();
-        theAsDes->Add(aF, aLENew);
-      }
-      //
-      // update connection to initial origins
-      if (theEdgesOrigins.IsBound(aE)) {
-        const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aE);
-        aIt1.Initialize(aLENew);
-        for (; aIt1.More(); aIt1.Next()) {
-          const TopoDS_Shape& aENew = aIt1.Value();
-          if (theEdgesOrigins.IsBound(aENew)) {
-            TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew);
-            TopTools_ListIteratorOfListOfShape aItOrInit(aLEOrInit);
-            for (; aItOrInit.More(); aItOrInit.Next()) {
-              const TopoDS_Shape& aEOr = aItOrInit.Value();
-              AppendToList(aLENewOr, aEOr);
-            }
-          }
-          else {
-            theEdgesOrigins.Bind(aENew, aLEOrInit);
-          }
-        }
-      }
-      //
-      continue;
-    }
-    //
-    // old images
-    const TopTools_ListOfShape& aLEOld = theEETrim.Find(aE);
-    //
-    // list of initial origins
-    TopTools_ListOfShape anInitOrigins;
-    //
-    // it is necessary to replace the old edges with new ones
-    aIt1.Initialize(aLEOld);
-    for (; aIt1.More(); aIt1.Next()) {
-      const TopoDS_Shape& aEOld = aIt1.Value();
-      //
-      if (theOEOrigins.IsBound(aEOld)) {
-        // get its origins
-        const TopTools_ListOfShape& aEOrigins = theOEOrigins.Find(aEOld);
-        //
-        TopTools_ListIteratorOfListOfShape aItOr(aEOrigins);
-        for (; aItOr.More(); aItOr.Next()) {
-          const TopoDS_Shape& aEOr = aItOr.Value();
-          //
-          theModifiedEdges.Add(aEOr);
-          //
-          TopTools_ListOfShape& aEImages = theOEImages.ChangeFind(aEOr);
-          //
-          // remove old edge from images
-          TopTools_ListIteratorOfListOfShape aItIm(aEImages);
-          for (; aItIm.More(); ) {
-            const TopoDS_Shape& aEIm = aItIm.Value();
-            if (aEIm.IsSame(aEOld)) {
-              aEImages.Remove(aItIm);
-            }
-            else {
-              aItIm.Next();
-            }
-          }
-          //
-          // add new images
-          TopTools_ListIteratorOfListOfShape aItNew(aLENew);
-          for (; aItNew.More(); aItNew.Next()) {
-            const TopoDS_Shape& aENew = aItNew.Value();
-            AppendToList(aEImages, aENew);
-            if (theOEOrigins.IsBound(aENew)) {
-              TopTools_ListOfShape& aENewOrigins = theOEOrigins.ChangeFind(aENew);
-              AppendToList(aENewOrigins, aEOr);
-            }
-            else {
-              TopTools_ListOfShape aENewOrigins;
-              aENewOrigins.Append(aEOr);
-              theOEOrigins.Bind(aENew, aENewOrigins);
-            }
-          }
-        }
-      }
-      else {
-        // add to images
-        theOEImages.Bind(aEOld, aLENew);
-        //
-        theModifiedEdges.Add(aEOld);
-        //
-        // add to origins
-        TopTools_ListIteratorOfListOfShape aItNew(aLENew);
-        for (; aItNew.More(); aItNew.Next()) {
-          const TopoDS_Shape& aENew = aItNew.Value();
-          if (theOEOrigins.IsBound(aENew)) {
-            TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew);
-            AppendToList(aEOrigins, aEOld);
-          }
-          else {
-            TopTools_ListOfShape aEOrigins;
-            aEOrigins.Append(aEOld);
-            theOEOrigins.Bind(aENew, aEOrigins);
-          }
-        }
-      }
-      //
-      // update connection to initial shape
-      if (theEdgesOrigins.IsBound(aEOld)) {
-        const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aEOld);
-        TopTools_ListIteratorOfListOfShape aItEOrInit(aLEOrInit);
-        for (; aItEOrInit.More(); aItEOrInit.Next()) {
-          const TopoDS_Shape& aEOrInit = aItEOrInit.Value();
-          AppendToList(anInitOrigins, aEOrInit);
-        }
-      }
-    }
-    //
-    if (anInitOrigins.Extent()) {
-      TopTools_ListIteratorOfListOfShape aItNew(aLENew);
-      for (; aItNew.More(); aItNew.Next()) {
-        const TopoDS_Shape& aENew = aItNew.Value();
-        if (theEdgesOrigins.IsBound(aENew)) {
-          TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew);
-          TopTools_ListIteratorOfListOfShape aItOrInit(anInitOrigins);
-          for (; aItOrInit.More(); aItOrInit.Next()) {
-            const TopoDS_Shape& aEOr = aItOrInit.Value();
-            AppendToList(aLENewOr, aEOr);
-          }
-        }
-        else {
-          theEdgesOrigins.Bind(aENew, anInitOrigins);
-        }
-      }
-    }
-  }
+  // update intersection edges
+  UpdateNewIntersectionEdges(aLE, aMELF, theEImages, theEdgesOrigins, theOEImages, 
+    theOEOrigins, theETrimEInf, theEETrim, theModifiedEdges, theAsDes);
   //
   // update bounds
   UpdateImages(aLAValid, theOEImages, aGF, theModifiedEdges);
@@ -6833,6 +6209,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
                       const TopTools_IndexedMapOfShape& theInvEdges,
                       const TopTools_IndexedMapOfShape& theValidEdges,
                       const TopTools_DataMapOfShapeListOfShape& theDMFLVE,
+                      const TopTools_ListOfShape& theLEInvalid,
                       const TopTools_ListOfShape& theLENeutral,
                       const TopTools_MapOfShape& theMEInverted,
                       TopTools_ListOfShape& theInvFaces)
@@ -6859,6 +6236,27 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
   //
   Standard_Boolean bCheckInverted = (theLFImages.Extent() == 1);
   //
+  TopTools_MapOfShape aMEChecked;
+  // valid edges
+  aIt.Initialize(theLFImages);
+  for (; aIt.More(); aIt.Next() ) {
+    const TopoDS_Shape& aFIm = aIt.Value();
+    if (theDMFLVE.IsBound(aFIm)) {
+      const TopTools_ListOfShape& aLVE = theDMFLVE.Find(aFIm);
+      TopTools_ListIteratorOfListOfShape aItLE(aLVE);
+      for (; aItLE.More(); aItLE.Next()) {
+        const TopoDS_Shape& aE = aItLE.Value();
+        aMEChecked.Add(aE);
+      }
+    }
+  }
+  // invalid edges
+  aIt.Initialize(theLEInvalid);
+  for (; aIt.More(); aIt.Next() ) {
+    const TopoDS_Shape& anInvE = aIt.Value();
+    aMEChecked.Add(anInvE);
+  }
+  //
   aIt.Initialize(theLFImages);
   for (; aIt.More(); ) {
     const TopoDS_Face& aFIm = *(TopoDS_Face*)&aIt.Value();
@@ -6908,7 +6306,7 @@ void FindInvalidFaces(TopTools_ListOfShape& theLFImages,
       //
       bAllValid = bAllValid && bValidLoc;
       bAllInvalid = bAllInvalid && bInvalid;
-      bHasReallyInvalid = bInvalid && !bValid;
+      bHasReallyInvalid = bInvalid && !bValid && aMEChecked.Contains(aEIm);
       bAllInvNeutral = bAllInvNeutral && bAllInvalid && bNeutral;
       //
       if (bHasReallyInvalid) {
@@ -7330,6 +6728,7 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
                        TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
                        const TopTools_DataMapOfShapeShape& theArtInvFaces,
                        const TopTools_IndexedMapOfShape& theInvEdges,
+                       const TopTools_IndexedMapOfShape& theMFToCheckInt,
                        TopTools_IndexedMapOfShape& theMERemoved)
 {
   BOPCol_ListOfShape aLS;
@@ -7363,6 +6762,14 @@ void RemoveInsideFaces(TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
     }
   }
   //
+  aNb = theMFToCheckInt.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aFSp = theMFToCheckInt(i);
+    if (aMFence.Add(aFSp)) {
+      aLS.Append(aFSp);
+    }
+  }
+  //
   BOPAlgo_MakerVolume aMV;
   aMV.SetArguments(aLS);
   aMV.SetIntersect(Standard_True);
@@ -7798,6 +7205,1038 @@ void RemoveInvalidSplits(TopTools_IndexedDataMapOfShapeListOfShape& theImages,
   }
 }
 
+//=======================================================================
+//function : PrepareFacesForIntersection
+//purpose  : 
+//=======================================================================
+void PrepareFacesForIntersection(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                                 const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+                                 TopTools_IndexedDataMapOfShapeListOfShape& theInvFaces,
+                                 const TopTools_DataMapOfShapeShape& theArtInvFaces,
+                                 TopTools_IndexedDataMapOfShapeListOfShape& theFLE,
+                                 TopTools_DataMapOfShapeListOfShape& theMDone,
+                                 TopTools_DataMapOfShapeListOfShape& theDMSF,
+                                 TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
+                                 TopTools_DataMapOfShapeListOfShape& theDMVEFull,
+                                 TopTools_DataMapOfShapeShape& theETrimEInf,
+                                 TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv,
+                                 const Standard_Boolean bLookVertToAvoid)
+{
+  Standard_Integer i, aNb = theFToRebuild.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
+    //
+    TopTools_ListOfShape aLE;
+    theFLE.Add(aF, aLE);
+    theMDone.Bind(aF, aLE);
+    //
+    const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF);
+    TopTools_ListIteratorOfListOfShape aItLF(aLFIm);
+    for (; aItLF.More(); aItLF.Next()) {
+      const TopoDS_Shape& aFIm = aItLF.Value();
+      TopExp_Explorer aExp(aFIm, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Shape& aE = aExp.Current();
+        // save connection to untrimmed face
+        if (theDMSF.IsBound(aE)) {
+          TopTools_ListOfShape& aLF = theDMSF.ChangeFind(aE);
+          AppendToList(aLF, aF);
+        }
+        else {
+          TopTools_ListOfShape aLF;
+          aLF.Append(aF);
+          theDMSF.Bind(aE, aLF);
+        }
+        //
+        // save connection to untrimmed edge
+        const TopoDS_Shape& aEInf = theETrimEInf.Find(aE);
+        if (theMEInfETrim.IsBound(aEInf)) {
+          TopTools_ListOfShape& aLETrim = theMEInfETrim.ChangeFind(aEInf);
+          AppendToList(aLETrim, aE);
+        }
+        else {
+          TopTools_ListOfShape aLETrim;
+          aLETrim.Append(aE);
+          theMEInfETrim.Bind(aEInf, aLETrim);
+        }
+        //
+        TopExp_Explorer aExpV(aE, TopAbs_VERTEX);
+        for (; aExpV.More(); aExpV.Next()) {
+          const TopoDS_Shape& aV = aExpV.Current();
+          // save connection to face
+          if (theDMSF.IsBound(aV)) {
+            TopTools_ListOfShape& aLFV = theDMSF.ChangeFind(aV);
+            AppendToList(aLFV, aF);
+          }
+          else {
+            TopTools_ListOfShape aLFV;
+            aLFV.Append(aF);
+            theDMSF.Bind(aV, aLFV);
+          }
+          //
+          if (bLookVertToAvoid) {
+            // save connection to edges
+            if (theDMVEFull.IsBound(aV)) {
+              TopTools_ListOfShape& aLEV = theDMVEFull.ChangeFind(aV);
+              AppendToList(aLEV, aE);
+            }
+            else {
+              TopTools_ListOfShape aLEV;
+              aLEV.Append(aE);
+              theDMVEFull.Bind(aV, aLEV);
+            }
+          }
+        }
+      }
+    }
+    //
+    if (bLookVertToAvoid) {
+      // get edges of invalid faces (from invalid splits only)
+      if (!theInvFaces.Contains(aF) || theArtInvFaces.IsBound(aF)) {
+        continue;
+      }
+      //
+      const TopTools_ListOfShape& aLFInv = theInvFaces.FindFromKey(aF);
+      aItLF.Initialize(aLFInv);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Shape& aFInv = aItLF.Value();
+        TopExp_Explorer aExp(aFInv, TopAbs_EDGE);
+        for (; aExp.More(); aExp.Next()) {
+          const TopoDS_Shape& aE = aExp.Current();
+          if (theDMEFInv.Contains(aE)) {
+            TopTools_ListOfShape& aLF = theDMEFInv.ChangeFromKey(aE);
+            AppendToList(aLF, aF);
+          }
+          else {
+            TopTools_ListOfShape aLF;
+            aLF.Append(aF);
+            theDMEFInv.Add(aE, aLF);
+          }
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : FindVerticesToAvoid
+//purpose  : 
+//=======================================================================
+void FindVerticesToAvoid(const TopTools_IndexedDataMapOfShapeListOfShape& theDMEFInv,
+                         TopTools_DataMapOfShapeListOfShape& theDMVEFull,
+                         const TopTools_IndexedMapOfShape& theInvEdges,
+                         const TopTools_IndexedMapOfShape& theValidEdges,
+                         TopTools_MapOfShape& theMVRInv)
+{
+  TopTools_MapOfShape aMFence;
+  Standard_Integer i, aNb = theDMEFInv.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopTools_ListOfShape& aLFInv = theDMEFInv(i);
+    if (aLFInv.Extent() == 1) {
+      continue;
+    }
+    //
+    const TopoDS_Shape& aE = theDMEFInv.FindKey(i);
+    if (!theInvEdges.Contains(aE) || theValidEdges.Contains(aE)) {
+      continue;
+    }
+    //
+    TopExp_Explorer aExp(aE, TopAbs_VERTEX);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Shape& aV = aExp.Current();
+      if (!theDMVEFull.IsBound(aV)) {
+        theMVRInv.Add(aV);
+        continue;
+      }
+      //
+      const TopTools_ListOfShape& aLE = theDMVEFull.Find(aV);
+      TopTools_ListIteratorOfListOfShape aItLE(aLE);
+      for (; aItLE.More(); aItLE.Next()) {
+        const TopoDS_Shape& aEV = aItLE.Value();
+        if (!theInvEdges.Contains(aEV) && !theDMEFInv.Contains(aEV)) {
+          break;
+        }
+      }
+      if (!aItLE.More()) {
+        theMVRInv.Add(aV);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : FindFacesForIntersection
+//purpose  : 
+//=======================================================================
+void FindFacesForIntersection(const TopoDS_Shape& theFInv,
+                              const TopTools_IndexedMapOfShape& theME,
+                              const TopTools_IndexedDataMapOfShapeListOfShape& theFImages,
+                              const TopTools_DataMapOfShapeShape& theArtInvFaces,
+                              const TopTools_DataMapOfShapeListOfShape& theDMSF,
+                              const TopTools_MapOfShape& theMVInvAll,
+                              TopTools_IndexedMapOfShape& theMFAvoid,
+                              TopTools_IndexedMapOfShape& theMFInt,
+                              TopTools_ListOfShape& theLFImInt)
+{
+  Standard_Integer i, aNbE = theME.Extent();
+
+  for (i = 1; i <= aNbE; ++i) {
+    const TopoDS_Shape& aS = theME(i);
+    if (!theDMSF.IsBound(aS)) {
+      continue;
+    }
+    //
+    const TopTools_ListOfShape& aLF = theDMSF.Find(aS);
+    TopTools_ListIteratorOfListOfShape aItLE(aLF);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aF = aItLE.Value();
+      if (theMFInt.Contains(aF)) {
+        continue;
+      }
+      //
+      const TopTools_ListOfShape& aLFIm = theFImages.FindFromKey(aF);
+      // check if this face is close to invalidity
+      if (theArtInvFaces.IsBound(theFInv) && theArtInvFaces.IsBound(aF)) {
+        if (aS.ShapeType() != TopAbs_EDGE && !theMVInvAll.Contains(aS)) {
+          theMFAvoid.Add(aF);
+        }
+      }
+      //
+      theMFInt.Add(aF);
+      // Debug
+      TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm);
+      for (; aItLFIm.More(); aItLFIm.Next()) {
+        const TopoDS_Shape& aFIm = aItLFIm.Value();
+        theLFImInt.Append(aFIm);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : ProcessCommonEdges
+//purpose  : 
+//=======================================================================
+void ProcessCommonEdges(const TopTools_ListOfShape& theLEC,
+                        const TopTools_IndexedMapOfShape& theInvEdges,
+                        const TopTools_IndexedMapOfShape& theValidEdges,
+                        const TopTools_IndexedMapOfShape& theME,
+                        const TopTools_DataMapOfShapeShape& theETrimEInf,
+                        const TopTools_DataMapOfShapeListOfShape& theMEInfETrim,
+                        TopTools_IndexedMapOfShape& theMECV,
+                        TopTools_DataMapOfShapeListOfShape& theDMEETrim,
+                        TopTools_ListOfShape& theLFEi,
+                        TopTools_ListOfShape& theLFEj,
+                        TopTools_IndexedMapOfShape& theMEToInt)
+{
+  // process common edges
+  TopTools_ListIteratorOfListOfShape aItLE(theLEC);
+  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 (!theME.Contains(aEC)) {
+      TopExp_Explorer aExpV(aEC, TopAbs_VERTEX);
+      for (; aExpV.More(); aExpV.Next()) {
+        const TopoDS_Shape& aVE = aExpV.Current();
+        if (theME.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
+    const TopTools_ListOfShape& aLVE = theMEInfETrim.Find(aEInt);
+    TopTools_ListIteratorOfListOfShape aItLVE(aLVE);
+    for (; aItLVE.More(); aItLVE.Next()) {
+      const TopoDS_Shape& aECx = aItLVE.Value();
+      TopExp::MapShapes(aECx, TopAbs_VERTEX, theMECV);
+    }
+    //
+    // bind unlimited edge to its trimmed part in face to update maps of 
+    // images and origins in the future
+    if (theDMEETrim.IsBound(aEInt)) {
+      TopTools_ListOfShape& aLTAdded = theDMEETrim.ChangeFind(aEInt);
+      AppendToList(aLTAdded, aEC);
+    }
+    else {
+      TopTools_ListOfShape aLT;
+      aLT.Append(aEC);
+      theDMEETrim.Bind(aEInt, aLT);
+    }
+    //
+    AppendToList(theLFEi, aEInt);
+    AppendToList(theLFEj, aEInt);
+    theMEToInt.Add(aEInt);
+  }
+}
+
+//=======================================================================
+//function : UpdateIntersectedFaces
+//purpose  : 
+//=======================================================================
+void UpdateIntersectedFaces(const TopoDS_Shape& theFInv,
+                            const TopoDS_Shape& theFi,
+                            const TopoDS_Shape& theFj,
+                            const TopTools_ListOfShape& theLFInv,
+                            const TopTools_ListOfShape& theLFImi,
+                            const TopTools_ListOfShape& theLFImj,
+                            const TopTools_ListOfShape& theLFEi,
+                            const TopTools_ListOfShape& theLFEj,
+                            TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                            TopTools_IndexedMapOfShape& theMEToInt)
+{
+  // Find common edges in these two lists
+  TopTools_MapOfShape aMEi;
+  TopTools_ListIteratorOfListOfShape aItLE(theLFEi);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aE = aItLE.Value();
+    aMEi.Add(aE);
+  }
+  //
+  // find origins
+  TopTools_IndexedMapOfShape aMEToFindOrigins;
+  TopTools_ListOfShape aLEToFindOrigins;
+  if (!theFi.IsSame(theFInv)) {
+    FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins);
+  }
+  if (!theFj.IsSame(theFInv)) {
+    FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins);
+  }
+  //
+  TopTools_ListOfShape aLEOrInit;
+  aItLE.Initialize(aLEToFindOrigins);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aEC = aItLE.Value();
+    aMEToFindOrigins.Add(aEC);
+  }
+  //
+  FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit);
+  //
+  aItLE.Initialize(theLFEj);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aE = aItLE.Value();
+    if (aMEi.Contains(aE)) {
+      theMEToInt.Add(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);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : IntersectFaces
+//purpose  : 
+//=======================================================================
+void IntersectFaces(const TopoDS_Shape& theFInv,
+                    const TopoDS_Shape& theFi,
+                    const TopoDS_Shape& theFj,
+                    const TopTools_ListOfShape& theLFInv,
+                    const TopTools_ListOfShape& theLFImi,
+                    const TopTools_ListOfShape& theLFImj,
+                    TopTools_ListOfShape& theLFEi,
+                    TopTools_ListOfShape& theLFEj,
+                    TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                    TopTools_IndexedMapOfShape& theMECV,
+                    TopTools_IndexedMapOfShape& theMEToInt)
+{
+  // intersect faces
+  TopAbs_State aSide = TopAbs_OUT;
+  TopTools_ListOfShape aLInt1, aLInt2;
+  TopoDS_Edge aNullEdge;
+  BRepOffset_Tool::Inter3D(TopoDS::Face(theFi), TopoDS::Face(theFj), aLInt1, aLInt2, aSide, aNullEdge);
+  //
+  if (aLInt1.IsEmpty()) {
+    return;
+  }
+  //
+  // find common vertices for trimming edges
+  TopTools_ListOfShape aLCV;
+  TopTools_ListIteratorOfListOfShape aItLE;
+  FindCommonParts(theLFImi, theLFImj, aLCV, TopAbs_VERTEX);
+  if (aLCV.Extent() > 1) {
+    aItLE.Initialize(aLCV);
+    for (; aItLE.More(); aItLE.Next()) {
+      const TopoDS_Shape& aCV = aItLE.Value();
+      theMECV.Add(aCV);
+    }
+  }
+  //
+  // find origins
+  TopTools_IndexedMapOfShape aMEToFindOrigins;
+  TopTools_ListOfShape aLEToFindOrigins;
+  if (!theFi.IsSame(theFInv)) {
+    FindCommonParts(theLFImi, theLFInv, aLEToFindOrigins);
+  }
+  if (!theFj.IsSame(theFInv)) {
+    FindCommonParts(theLFImj, theLFInv, aLEToFindOrigins);
+  }
+  TopTools_ListOfShape aLEOrInit;
+  aItLE.Initialize(aLEToFindOrigins);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aEC = aItLE.Value();
+    aMEToFindOrigins.Add(aEC);
+  }
+  //
+  FindOrigins(theLFImi, theLFImj, aMEToFindOrigins, theEdgesOrigins, aLEOrInit);
+  //
+  aItLE.Initialize(aLInt1);
+  for (; aItLE.More(); aItLE.Next()) {
+    const TopoDS_Shape& aEInt = aItLE.Value();
+    theLFEi.Append(aEInt);
+    theLFEj.Append(aEInt);
+    //
+    if (aLEOrInit.Extent()) {
+      theEdgesOrigins.Bind(aEInt, aLEOrInit);
+    }
+    //
+    theMEToInt.Add(aEInt);
+  }
+}
+
+//=======================================================================
+//function : TrimNewIntersectionEdges
+//purpose  : 
+//=======================================================================
+void TrimNewIntersectionEdges(const TopTools_ListOfShape& theLE,
+                              TopTools_DataMapOfShapeListOfShape& theEImages,
+                              const TopTools_DataMapOfShapeListOfShape& theEETrim,
+                              TopTools_MapOfShape& theMEB,
+                              TopTools_MapOfShape& theMVOld,
+                              TopTools_MapOfShape& theMVBounds,
+                              TopTools_ListOfShape& theLENew,
+                              BOPCol_ListOfShape& theLA)
+{
+  TopTools_ListIteratorOfListOfShape aIt, aIt1;
+  aIt.Initialize(theLE);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aE = aIt.Value();
+    //
+    if (theEETrim.IsBound(aE)) {
+      const TopTools_ListOfShape& aLET = theEETrim.Find(aE);
+      aIt1.Initialize(aLET);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aET = aIt1.Value();
+        theMEB.Add(aET);
+        TopExp_Explorer aExpV(aET, TopAbs_VERTEX);
+        for (; aExpV.More(); aExpV.Next()) {
+          const TopoDS_Shape& aV = aExpV.Current();
+          theMVOld.Add(aV);
+        }
+      }
+    }
+    //
+    if (!theEImages.IsBound(aE)) {
+      continue;
+    }
+    //
+    TopTools_ListOfShape& aLEIm = theEImages.ChangeFind(aE);
+    if (aLEIm.IsEmpty()) {
+      theEImages.UnBind(aE);
+      continue;
+    }
+    //
+    TopoDS_Shape aCEIm;
+    TopTools_MapOfShape aMEVBounds;
+    //
+    if (aLEIm.Extent() > 2) {
+      // fuse these parts
+      BOPAlgo_Builder aGFE;
+      TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
+      for (; aItLEIm.More(); aItLEIm.Next()) {
+        const TopoDS_Shape& aEIm = aItLEIm.Value();
+        aGFE.AddArgument(aEIm);
+      }
+      //
+      // add two bounding vertices of this edge to the operation
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(TopoDS::Edge(aE), aV1, aV2);
+      //
+      aGFE.AddArgument(aV1);
+      aGFE.AddArgument(aV2);
+      //
+      aGFE.Perform();
+      //
+      // get images of bounding vertices to remove splits containing them
+      const TopTools_ListOfShape& aLV1Im = aGFE.Modified(aV1);
+      const TopTools_ListOfShape& aLV2Im = aGFE.Modified(aV2);
+      //
+      if (aLV1Im.Extent()) {
+        aMEVBounds.Add(aLV1Im.First());
+      }
+      else {
+        aMEVBounds.Add(aV1);
+      }
+      //
+      if (aLV2Im.Extent()) {
+        aMEVBounds.Add(aLV2Im.First());
+      }
+      else {
+        aMEVBounds.Add(aV2);
+      }
+      //
+      {
+        TopTools_MapIteratorOfMapOfShape aItM(theMVBounds);
+        for (; aItM.More(); aItM.Next()) {
+          const TopoDS_Shape& aV = aItM.Key();
+          const TopTools_ListOfShape& aLVIm = aGFE.Modified(aV);
+          if (aLVIm.Extent()) {
+            aMEVBounds.Add(aLVIm.First());
+          }
+          else {
+            aMEVBounds.Add(aV);
+          }
+        }
+      }
+      //
+      aCEIm = aGFE.Shape();
+    }
+    else {
+      aCEIm = aLEIm.First();
+    }
+    //
+    aLEIm.Clear();
+    //
+    TopExp_Explorer aExp(aCEIm, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Shape& aEIm = aExp.Current();
+      //
+      // check the split not to contain bounding vertices
+      TopExp_Explorer aExpV(aEIm, TopAbs_VERTEX);
+      for (; aExpV.More(); aExpV.Next()) {
+        const TopoDS_Shape& aV = aExpV.Current();
+        //
+        if (theMVBounds.Contains(aV) || aMEVBounds.Contains(aV)) {
+          break;
+        }
+      }
+      //
+      if (!aExpV.More()) {
+        theLA.Append(aEIm);
+        aLEIm.Append(aEIm);
+      }
+    }
+    //
+    if (aLEIm.IsEmpty()) {
+      theEImages.UnBind(aE);
+    }
+    else {
+      if (!theEETrim.IsBound(aE)) {
+        TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
+        for (; aItLEIm.More(); aItLEIm.Next()) {
+          const TopoDS_Shape& aEIm = aItLEIm.Value();
+          theLENew.Append(aEIm);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : IntersectEdges
+//purpose  : 
+//=======================================================================
+void IntersectEdges(const BOPCol_ListOfShape& theLA,
+                    const TopTools_ListOfShape& theLE,
+                    const TopTools_ListOfShape& theLENew,
+                    TopTools_DataMapOfShapeListOfShape& theEImages,
+                    TopTools_MapOfShape& theVertsToAvoid,
+                    TopTools_MapOfShape& theMVBounds,
+                    TopTools_MapOfShape& theModifiedEdges,
+                    TopTools_MapOfShape& theMENew,
+                    TopoDS_Shape& theSplits)
+{
+  BOPAlgo_Builder aGFA;
+  aGFA.SetArguments(theLA);
+  aGFA.Perform();
+  //
+  UpdateImages(theLE, theEImages, aGFA, theModifiedEdges);
+  //
+  // compound of valid splits
+  theSplits = aGFA.Shape();
+  //
+  // update new edges
+  TopTools_ListIteratorOfListOfShape aIt, aIt1;
+  aIt.Initialize(theLENew);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aE = aIt.Value();
+    const TopTools_ListOfShape& aLEIm = aGFA.Modified(aE);
+    if (aLEIm.Extent()) {
+      aIt1.Initialize(aLEIm);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aEIm = aIt1.Value();
+        theMENew.Add(aEIm);
+      }
+    }
+    else {
+      theMENew.Add(aE);
+    }
+  }
+  //
+  TopTools_MapOfShape aMEInv;
+  GetInvalidEdges(aGFA, /*aLENew, */theVertsToAvoid, theMVBounds, aMEInv);
+  if (aMEInv.Extent()) {
+    // update shape
+    TopoDS_Compound aSp;
+    BRep_Builder aBB;
+    aBB.MakeCompound(aSp);
+    TopExp_Explorer aExp(theSplits, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Shape& aE = aExp.Current();
+      if (!aMEInv.Contains(aE)) {
+        aBB.Add(aSp, aE);
+      }
+    }
+    theSplits = aSp;
+  }
+}
+
+//=======================================================================
+//function : GetBounds
+//purpose  : 
+//=======================================================================
+void GetBounds(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+               const TopTools_IndexedDataMapOfShapeListOfShape& theDMFFIm,
+               const TopTools_MapOfShape& theMEB,
+               TopoDS_Shape& theBounds)
+{
+  // make compound of edges contained in the faces splits
+  TopoDS_Compound aBounds;
+  BRep_Builder aBB;
+  aBB.MakeCompound(aBounds);
+  //
+  TopTools_MapOfShape aMFence;
+  //
+  Standard_Integer i, aNb = theFToRebuild.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
+    const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
+    //
+    TopTools_ListIteratorOfListOfShape aIt(aLFIm);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aFIm = aIt.Value();
+      TopExp_Explorer aExpE(aFIm, TopAbs_EDGE);
+      for (; aExpE.More(); aExpE.Next()) {
+        const TopoDS_Shape& aEIm = aExpE.Current();
+        if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) {
+          aBB.Add(aBounds, aEIm);
+        }
+      }
+    }
+  }
+  theBounds = aBounds;
+}
+
+//=======================================================================
+//function : GetBoundsToUpdate
+//purpose  : 
+//=======================================================================
+void GetBoundsToUpdate(const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                       const TopTools_DataMapOfShapeListOfShape& theOEImages,
+                       const TopTools_DataMapOfShapeListOfShape& theOEOrigins,
+                       const TopTools_MapOfShape& theMEB,
+                       TopTools_ListOfShape& theLABounds,
+                       TopTools_ListOfShape& theLAValid,
+                       TopoDS_Shape& theBounds,
+                       Handle(BRepAlgo_AsDes)& theAsDes)
+{
+  // get all edges
+  TopoDS_Compound aBounds;
+  BRep_Builder aBB;
+  aBB.MakeCompound(aBounds);
+  //
+  TopTools_MapOfShape aMAValid, aMFence;
+  //
+  Standard_Integer i, aNb = theFToRebuild.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
+    //
+    TopTools_IndexedMapOfShape aMDE;
+    const TopTools_ListOfShape& aLFDes = theAsDes->Descendant(aF);
+    TopTools_ListIteratorOfListOfShape aItLFDes(aLFDes);
+    for (; aItLFDes.More(); aItLFDes.Next()) {
+      const TopoDS_Shape& aED = aItLFDes.Value();
+      if (!theOEImages.IsBound(aED)) {
+        aMDE.Add(aED);
+        continue;
+      }
+      //
+      const TopTools_ListOfShape& aLEDIm = theOEImages.Find(aED);
+      TopTools_ListIteratorOfListOfShape aItLEDIm(aLEDIm);
+      for (; aItLEDIm.More(); aItLEDIm.Next()) {
+        const TopoDS_Shape& aEDIm = aItLEDIm.Value();
+        aMDE.Add(aEDIm);
+      }
+    }
+    //
+    Standard_Integer j, aNbE = aMDE.Extent();
+    for (j = 1; j <= aNbE; ++j) {
+      const TopoDS_Edge& aEIm = TopoDS::Edge(aMDE(j));
+      //
+      if (!theMEB.Contains(aEIm) && aMFence.Add(aEIm)) {
+        aBB.Add(aBounds, aEIm);
+        theLABounds.Append(aEIm);
+      }
+      //
+      if (theOEOrigins.IsBound(aEIm)) {
+        const TopTools_ListOfShape& aLO = theOEOrigins.Find(aEIm);
+        TopTools_ListIteratorOfListOfShape aItLO(aLO);
+        for (; aItLO.More(); aItLO.Next()) {
+          const TopoDS_Shape& aEO = aItLO.Value();
+          //
+          if (aMAValid.Add(aEO)) {
+            theLAValid.Append(aEO);
+          }
+        }
+      }
+      else {
+        if (aMAValid.Add(aEIm)) {
+          theLAValid.Append(aEIm);
+        }
+      }
+    }
+  }
+  theBounds = aBounds;
+}
+
+//=======================================================================
+//function : GetInvalidEdgesByBounds
+//purpose  : 
+//=======================================================================
+void GetInvalidEdgesByBounds(const TopoDS_Shape& theSplits,
+                             const TopoDS_Shape& theBounds,
+                             const TopTools_IndexedDataMapOfShapeListOfShape& theFToRebuild,
+                             const TopTools_IndexedDataMapOfShapeListOfShape& theDMFFIm,
+                             const TopTools_IndexedMapOfShape& theInvEdges,
+                             const TopTools_MapOfShape& theMVOld,
+                             const TopTools_MapOfShape& theMENew,
+                             TopTools_MapOfShape& theVertsToAvoid,
+                             TopTools_MapOfShape& theMEInv)
+{
+  BOPAlgo_Builder aGF;
+  aGF.AddArgument(theSplits);
+  aGF.AddArgument(theBounds);
+  //
+  aGF.Perform();
+  //
+  // invalid vertices
+  TopTools_IndexedMapOfShape aMVInv;
+  // collect parts for removal
+  const BOPDS_PDS& pDS = aGF.PDS();
+  //
+  // check edge/edge intersections
+  const BOPDS_VectorOfInterfEE& aEEs = pDS->InterfEE();
+  Standard_Integer i, aNb = aEEs.Extent();
+  for (i = 0; i < aNb; ++i) {
+    const BOPDS_InterfEE& aEE = aEEs(i);
+    const TopoDS_Shape& aE1 = pDS->Shape(aEE.Index1());
+    const TopoDS_Shape& aE2 = pDS->Shape(aEE.Index2());
+    if (!aEE.HasIndexNew()) {
+      continue;
+    }
+    //
+    if (!theInvEdges.Contains(aE2)) {
+      theMEInv.Add(aE1);
+      //
+      TopExp_Explorer aExpV(aE1, TopAbs_VERTEX);
+      for (; aExpV.More(); aExpV.Next()) {
+        const TopoDS_Shape& aV = aExpV.Current();
+        if (!theMVOld.Contains(aV)) {
+          aMVInv.Add(aV);
+        }
+      }
+    }
+  }
+  //
+  // add for check also the vertices connected only to new edges
+  TopTools_IndexedDataMapOfShapeListOfShape aDMVE;
+  TopExp::MapShapesAndAncestors(theSplits, TopAbs_VERTEX, TopAbs_EDGE, aDMVE);
+  //
+  aNb = aDMVE.Extent();
+  for (i = 1; i <= aNb; ++i) {
+    const TopoDS_Shape& aV = aDMVE.FindKey(i);
+    if (aMVInv.Contains(aV)) {
+      continue;
+    }
+    //
+    Standard_Boolean bNew = Standard_False, bOld = Standard_False;
+    const TopTools_ListOfShape& aLEx = aDMVE(i);
+    TopTools_ListIteratorOfListOfShape aIt(aLEx);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Shape& aE = aIt.Value();
+      if (theMENew.Contains(aE)) {
+        bNew = Standard_True;
+      }
+      else {
+        bOld = Standard_True;
+      }
+      //
+      if (bNew && bOld) {
+        break;
+      }
+    }
+    //
+    if (!bNew || !bOld) {
+      aMVInv.Add(aV);
+    }
+  }
+  //
+  Handle(IntTools_Context) aCtx = new IntTools_Context;
+  // filter vertices
+  Standard_Integer iv, aNbIV = aMVInv.Extent(), aNbF = theFToRebuild.Extent();
+  for (iv = 1; iv <= aNbIV; ++iv) {
+    const TopoDS_Vertex& aV = TopoDS::Vertex(aMVInv(iv));
+    const gp_Pnt& aP = BRep_Tool::Pnt(aV);
+    Standard_Real aTolV = BRep_Tool::Tolerance(aV);
+    //
+    for (i = 1; i <= aNbF; ++i) {
+      const TopoDS_Shape& aF = theFToRebuild.FindKey(i);
+      const TopTools_ListOfShape& aLFIm = theDMFFIm.FindFromKey(aF);
+      //
+      TopTools_ListIteratorOfListOfShape aItLF(aLFIm);
+      for (; aItLF.More(); aItLF.Next()) {
+        const TopoDS_Face& aFIm = TopoDS::Face(aItLF.Value());
+        if (aCtx->IsValidPointForFace(aP, aFIm, aTolV)) {
+          break;
+        }
+      }
+      //
+      if (aItLF.More()) {
+        break;
+      }
+    }
+    //
+    if (i > aNbF) {
+      theVertsToAvoid.Add(aV);
+      if (aDMVE.Contains(aV)) {
+        const TopTools_ListOfShape& aLEInv = aDMVE.FindFromKey(aV);
+        TopTools_ListIteratorOfListOfShape aItLEInv(aLEInv);
+        for (; aItLEInv.More(); aItLEInv.Next()) {
+          const TopoDS_Shape& aEInv = aItLEInv.Value();
+          theMEInv.Add(aEInv);
+        }
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : UpdateNewIntersectionEdges
+//purpose  : 
+//=======================================================================
+void UpdateNewIntersectionEdges(const TopTools_ListOfShape& theLE,
+                                const TopTools_DataMapOfShapeListOfShape& theMELF,
+                                const TopTools_DataMapOfShapeListOfShape& theEImages,
+                                TopTools_DataMapOfShapeListOfShape& theEdgesOrigins,
+                                TopTools_DataMapOfShapeListOfShape& theOEImages,
+                                TopTools_DataMapOfShapeListOfShape& theOEOrigins,
+                                TopTools_DataMapOfShapeShape& theETrimEInf,
+                                TopTools_DataMapOfShapeListOfShape& theEETrim,
+                                TopTools_MapOfShape& theModifiedEdges,
+                                Handle(BRepAlgo_AsDes)& theAsDes)
+{
+  TopTools_ListOfShape aLEImEmpty;
+  TopTools_ListIteratorOfListOfShape aIt, aIt1;
+  // update global maps of images and origins with new splits
+  aIt.Initialize(theLE);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aE = aIt.Value();
+    //
+    /*if (!theEImages.IsBound(aE)) {
+      continue;
+    }*/
+    // new images
+    const TopTools_ListOfShape& aLENew = 
+      theEImages.IsBound(aE) ? theEImages.Find(aE) : aLEImEmpty;
+    //
+    // save connection to untrimmed edge for the next steps
+    aIt1.Initialize(aLENew);
+    for (; aIt1.More(); aIt1.Next()) {
+      const TopoDS_Shape& aET = aIt1.Value();
+      theETrimEInf.Bind(aET, aE);
+      theModifiedEdges.Add(aET);
+    }
+    //
+    // check if it is existing edge
+    if (!theEETrim.IsBound(aE)) {
+      const TopTools_ListOfShape& aLF = theMELF.Find(aE);
+      // the edge is new
+      // add this edge to AsDes
+      aIt1.Initialize(aLF);
+      for (; aIt1.More(); aIt1.Next()) {
+        const TopoDS_Shape& aF = aIt1.Value();
+        theAsDes->Add(aF, aE);
+      }
+      //
+      // add aE to the images
+      theOEImages.Bind(aE, aLENew);
+      theModifiedEdges.Add(aE);
+      //
+      // add to origins
+      TopTools_ListIteratorOfListOfShape aItNew(aLENew);
+      for (; aItNew.More(); aItNew.Next()) {
+        const TopoDS_Shape& aENew = aItNew.Value();
+        if (theOEOrigins.IsBound(aENew)) {
+          TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew);
+          AppendToList(aEOrigins, aE);
+        }
+        else {
+          TopTools_ListOfShape aEOrigins;
+          aEOrigins.Append(aE);
+          theOEOrigins.Bind(aENew, aEOrigins);
+        }
+      }
+      //
+      // update connection to initial origins
+      if (theEdgesOrigins.IsBound(aE)) {
+        const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aE);
+        aIt1.Initialize(aLENew);
+        for (; aIt1.More(); aIt1.Next()) {
+          const TopoDS_Shape& aENew = aIt1.Value();
+          if (theEdgesOrigins.IsBound(aENew)) {
+            TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew);
+            TopTools_ListIteratorOfListOfShape aItOrInit(aLEOrInit);
+            for (; aItOrInit.More(); aItOrInit.Next()) {
+              const TopoDS_Shape& aEOr = aItOrInit.Value();
+              AppendToList(aLENewOr, aEOr);
+            }
+          }
+          else {
+            theEdgesOrigins.Bind(aENew, aLEOrInit);
+          }
+        }
+      }
+      //
+      continue;
+    }
+    //
+    // old images
+    const TopTools_ListOfShape& aLEOld = theEETrim.Find(aE);
+    //
+    // list of initial origins
+    TopTools_ListOfShape anInitOrigins;
+    //
+    // it is necessary to replace the old edges with new ones
+    aIt1.Initialize(aLEOld);
+    for (; aIt1.More(); aIt1.Next()) {
+      const TopoDS_Shape& aEOld = aIt1.Value();
+      //
+      if (theOEOrigins.IsBound(aEOld)) {
+        // get its origins
+        const TopTools_ListOfShape& aEOrigins = theOEOrigins.Find(aEOld);
+        //
+        TopTools_ListIteratorOfListOfShape aItOr(aEOrigins);
+        for (; aItOr.More(); aItOr.Next()) {
+          const TopoDS_Shape& aEOr = aItOr.Value();
+          //
+          theModifiedEdges.Add(aEOr);
+          //
+          TopTools_ListOfShape& aEImages = theOEImages.ChangeFind(aEOr);
+          //
+          // remove old edge from images
+          TopTools_ListIteratorOfListOfShape aItIm(aEImages);
+          for (; aItIm.More(); ) {
+            const TopoDS_Shape& aEIm = aItIm.Value();
+            if (aEIm.IsSame(aEOld)) {
+              aEImages.Remove(aItIm);
+            }
+            else {
+              aItIm.Next();
+            }
+          }
+          //
+          // add new images
+          TopTools_ListIteratorOfListOfShape aItNew(aLENew);
+          for (; aItNew.More(); aItNew.Next()) {
+            const TopoDS_Shape& aENew = aItNew.Value();
+            AppendToList(aEImages, aENew);
+            if (theOEOrigins.IsBound(aENew)) {
+              TopTools_ListOfShape& aENewOrigins = theOEOrigins.ChangeFind(aENew);
+              AppendToList(aENewOrigins, aEOr);
+            }
+            else {
+              TopTools_ListOfShape aENewOrigins;
+              aENewOrigins.Append(aEOr);
+              theOEOrigins.Bind(aENew, aENewOrigins);
+            }
+          }
+        }
+      }
+      else {
+        // add to images
+        theOEImages.Bind(aEOld, aLENew);
+        //
+        theModifiedEdges.Add(aEOld);
+        //
+        // add to origins
+        TopTools_ListIteratorOfListOfShape aItNew(aLENew);
+        for (; aItNew.More(); aItNew.Next()) {
+          const TopoDS_Shape& aENew = aItNew.Value();
+          if (theOEOrigins.IsBound(aENew)) {
+            TopTools_ListOfShape& aEOrigins = theOEOrigins.ChangeFind(aENew);
+            AppendToList(aEOrigins, aEOld);
+          }
+          else {
+            TopTools_ListOfShape aEOrigins;
+            aEOrigins.Append(aEOld);
+            theOEOrigins.Bind(aENew, aEOrigins);
+          }
+        }
+      }
+      //
+      // update connection to initial shape
+      if (theEdgesOrigins.IsBound(aEOld)) {
+        const TopTools_ListOfShape& aLEOrInit = theEdgesOrigins.Find(aEOld);
+        TopTools_ListIteratorOfListOfShape aItEOrInit(aLEOrInit);
+        for (; aItEOrInit.More(); aItEOrInit.Next()) {
+          const TopoDS_Shape& aEOrInit = aItEOrInit.Value();
+          AppendToList(anInitOrigins, aEOrInit);
+        }
+      }
+    }
+    //
+    if (anInitOrigins.Extent()) {
+      TopTools_ListIteratorOfListOfShape aItNew(aLENew);
+      for (; aItNew.More(); aItNew.Next()) {
+        const TopoDS_Shape& aENew = aItNew.Value();
+        if (theEdgesOrigins.IsBound(aENew)) {
+          TopTools_ListOfShape& aLENewOr = theEdgesOrigins.ChangeFind(aENew);
+          TopTools_ListIteratorOfListOfShape aItOrInit(anInitOrigins);
+          for (; aItOrInit.More(); aItOrInit.Next()) {
+            const TopoDS_Shape& aEOr = aItOrInit.Value();
+            AppendToList(aLENewOr, aEOr);
+          }
+        }
+        else {
+          theEdgesOrigins.Bind(aENew, anInitOrigins);
+        }
+      }
+    }
+  }
+}
+
 //=======================================================================
 //function : AppendToList
 //purpose  : to be used for very short lists (1-3 elements)