Salome HOME
Merge from V6_3_BR 06/06/2011
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Builder_2.cxx
index 45e7543b4cd17e5312c91f78cee4e3f6510e8857..dc0c5c228d42545cf6c7346bbe1d9341941df025 100755 (executable)
@@ -1,28 +1,28 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-// File:       GEOMAlgo_Builder_2.cxx
-// Created:    
-// Author:     Peter KURNEV 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+// File:        GEOMAlgo_Builder_2.cxx
+// Author:      Peter KURNEV
+
 #include <GEOMAlgo_Builder.hxx>
 
 #include <TColStd_IndexedMapOfInteger.hxx>
@@ -69,6 +69,8 @@
 #include <BOPTools_CArray1OfESInterference.hxx>
 
 #include <NMTDS_ShapesDataStructure.hxx>
+#include <NMTDS_InterfPool.hxx>
+
 #include <NMTTools_PaveFiller.hxx>
 #include <NMTTools_ListOfCoupleOfShape.hxx>
 #include <NMTTools_Tools.hxx>
 #include <GEOMAlgo_Tools3D.hxx>
 #include <GEOMAlgo_WireEdgeSet.hxx>
 #include <GEOMAlgo_BuilderFace.hxx>
-#include <NMTDS_InterfPool.hxx>
+
+#include <GEOMAlgo_ShapeSet.hxx>
+//
+#include <NMTDS_BoxBndTree.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <TopTools_DataMapOfIntegerShape.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
 
 static
   void UpdateCandidates(const Standard_Integer ,
-                       const Standard_Integer ,
-                       NMTTools_IndexedDataMapOfIndexedMapOfInteger& );
+                        const Standard_Integer ,
+                        NMTTools_IndexedDataMapOfIndexedMapOfInteger& );
 
 //=======================================================================
 //function : FillImagesFaces
-//purpose  : 
+//purpose  :
 //=======================================================================
   void GEOMAlgo_Builder::FillImagesFaces()
 {
@@ -104,9 +115,10 @@ static
   FillImagesFaces1();
   FillInternalVertices();
 }
+
 //=======================================================================
 // function: FillIn2DParts
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Builder::FillIn2DParts()
 {
@@ -145,15 +157,15 @@ static
       NMTTools_ListOfCommonBlock& aLCB=aCBP(j);
       aItCB.Initialize(aLCB);
       for (; aItCB.More(); aItCB.Next()) {
-       NMTTools_CommonBlock& aCB=aItCB.Value();
-       if (aCB.IsPaveBlockOnFace(nF)) {
-         const BOPTools_PaveBlock& aPB1=aCB.PaveBlock1();
-         nSpIn=aPB1.Edge();
-         const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
-         if (aMFence.Add(aSpIn)){
-           aLSpIn.Append(aSpIn);
-         }
-       }
+        NMTTools_CommonBlock& aCB=aItCB.Value();
+        if (aCB.IsPaveBlockOnFace(nF)) {
+          const BOPTools_PaveBlock& aPB1=aCB.PaveBlock1();
+          nSpIn=aPB1.Edge();
+          const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
+          if (aMFence.Add(aSpIn)){
+            aLSpIn.Append(aSpIn);
+          }
+        }
       }
     }
     //
@@ -162,24 +174,24 @@ static
       BOPTools_SSInterference& aFF=aFFs(j);
       aFF.Indices(n1, n2);
       if (!(n1==nF || n2==nF)) {
-       continue;
+        continue;
       }
       BOPTools_SequenceOfCurves& aSC=aFF.Curves();
       aNbCurves=aSC.Length();
       if (!aNbCurves) {
-       continue;
+        continue;
       }
       //
       const BOPTools_Curve& aBC=aSC(1);
       const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
       aItPB.Initialize(aLPB);
       for (; aItPB.More(); aItPB.Next()) {
-       const BOPTools_PaveBlock& aPBSc=aItPB.Value();
-       nSpSc=aPBSc.Edge();
-       const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
-       if (aMFence.Add(aSpSc)){
-         aLSpIn.Append(aSpSc);
-       }
+        const BOPTools_PaveBlock& aPBSc=aItPB.Value();
+        nSpSc=aPBSc.Edge();
+        const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
+        if (aMFence.Add(aSpSc)){
+          aLSpIn.Append(aSpSc);
+        }
       }
     }
     aNbSpIn=aLSpIn.Extent();
@@ -188,9 +200,10 @@ static
     }
   }//for (nF=1; nF<=aNbS; ++nF) {
 }
+
 //=======================================================================
 // function: BuildSplitFaces
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Builder::BuildSplitFaces()
 {
@@ -232,8 +245,8 @@ static
     for (; anExp.More(); anExp.Next()) {
       const TopoDS_Shape& aE=anExp.Current();
       if (myImages.HasImage(aE)) {
-       aMFP.Add(i);
-       break;
+        aMFP.Add(i);
+        break;
       }
     }
     //
@@ -243,17 +256,18 @@ static
       //
       aNbFFs=aFFs.Extent();
       for (j=1; j<=aNbFFs; ++j) {
-       BOPTools_SSInterference& aFFj=aFFs(j);
-       aFFj.Indices(n1, n2);
-       if (!(n1==i || n2==i)) {
-         continue;
-       }
-       //
-       const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
-       aNbSE=aLSE.Extent();
-       if (aNbSE) {
-         aMFP.Add(i);
-       }
+        BOPTools_SSInterference& aFFj=aFFs(j);
+        aFFj.Indices(n1, n2);
+        if (!(n1==i || n2==i)) {
+          continue;
+        }
+        //
+        const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
+        aNbSE=aLSE.Extent();
+        if (aNbSE) {
+          aMFP.Add(i);
+          break;
+        }
       }
     }
     //===
@@ -271,7 +285,7 @@ static
     //
     aMFence.Clear();
     //
-    // 2.1. Fill WES 
+    // 2.1. Fill WES
     GEOMAlgo_WireEdgeSet aWES;
     aWES.SetFace(aFF);
     //
@@ -282,17 +296,17 @@ static
       anOriE=aE.Orientation();
       //
       if (!myImages.HasImage(aE)) {
-       if (anOriE==TopAbs_INTERNAL) {
-         aEE=aE;
-         aEE.Orientation(TopAbs_FORWARD);
-         aWES.AddStartElement(aEE);
-         aEE.Orientation(TopAbs_REVERSED);
-         aWES.AddStartElement(aEE);
-       }
-       else {
-         aWES.AddStartElement(aE);
-       }
-       continue;
+        if (anOriE==TopAbs_INTERNAL) {
+          aEE=aE;
+          aEE.Orientation(TopAbs_FORWARD);
+          aWES.AddStartElement(aEE);
+          aEE.Orientation(TopAbs_REVERSED);
+          aWES.AddStartElement(aEE);
+        }
+        else {
+          aWES.AddStartElement(aE);
+        }
+        continue;
       }
       //
       bIsDegenerated=BRep_Tool::Degenerated(aE);
@@ -301,43 +315,43 @@ static
       const TopTools_ListOfShape& aLIE=myImages.Image(aE);
       aIt.Initialize(aLIE);
       for (; aIt.More(); aIt.Next()) {
-       aSp=TopoDS::Edge(aIt.Value());
-       //
-       if (bIsDegenerated) {
-         aSp.Orientation(anOriE);
-         aWES.AddStartElement(aSp);
-         continue;
-       }
-       //
-       if (anOriE==TopAbs_INTERNAL) {
-         aSp.Orientation(TopAbs_FORWARD);
-         aWES.AddStartElement(aSp);
-         aSp.Orientation(TopAbs_REVERSED);
-         aWES.AddStartElement(aSp);
-         continue;
-       }
-       //
-       if (bIsClosed){
-         if (aMFence.Add(aSp)) {
-           //
-           if (!BRep_Tool::IsClosed(aSp, aF)){
-             BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
-           }
-           //
-           aSp.Orientation(TopAbs_FORWARD);
-           aWES.AddStartElement(aSp);
-           aSp.Orientation(TopAbs_REVERSED);
-           aWES.AddStartElement(aSp);
-         }
-         continue;
-       }// if (aMFence.Add(aSp))
-       //
-       aSp.Orientation(anOriE);
-       bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
-       if (bToReverse) {
-         aSp.Reverse();
-       }
-       aWES.AddStartElement(aSp);
+        aSp=TopoDS::Edge(aIt.Value());
+        //
+        if (bIsDegenerated) {
+          aSp.Orientation(anOriE);
+          aWES.AddStartElement(aSp);
+          continue;
+        }
+        //
+        if (anOriE==TopAbs_INTERNAL) {
+          aSp.Orientation(TopAbs_FORWARD);
+          aWES.AddStartElement(aSp);
+          aSp.Orientation(TopAbs_REVERSED);
+          aWES.AddStartElement(aSp);
+          continue;
+        }
+        //
+        if (bIsClosed){
+          if (aMFence.Add(aSp)) {
+            //
+            if (!BRep_Tool::IsClosed(aSp, aF)){
+              BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
+            }
+            //
+            aSp.Orientation(TopAbs_FORWARD);
+            aWES.AddStartElement(aSp);
+            aSp.Orientation(TopAbs_REVERSED);
+            aWES.AddStartElement(aSp);
+          }
+          continue;
+        }// if (aMFence.Add(aSp))
+        //
+        aSp.Orientation(anOriE);
+        bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
+        if (bToReverse) {
+          aSp.Reverse();
+        }
+        aWES.AddStartElement(aSp);
       }// for (; aIt.More(); aIt.Next()) {
     }// for (; anExp.More(); anExp.Next()) {
     //
@@ -346,80 +360,71 @@ static
       const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
       aIt.Initialize(aLE);
       for (; aIt.More(); aIt.Next()) {
-       aSp=TopoDS::Edge(aIt.Value());
-       //
-       aSp.Orientation(TopAbs_FORWARD);
-       aWES.AddStartElement(aSp);
-       //
-       aSp.Orientation(TopAbs_REVERSED);
-       aWES.AddStartElement(aSp);
+        aSp=TopoDS::Edge(aIt.Value());
+        //
+        aSp.Orientation(TopAbs_FORWARD);
+        aWES.AddStartElement(aSp);
+        //
+        aSp.Orientation(TopAbs_REVERSED);
+        aWES.AddStartElement(aSp);
       }
     }
     //
     // 2.2. Build images Faces
-    GEOMAlgo_BuilderFace aBF;
+    TopTools_ListOfShape aLFR;
+    GEOMAlgo_ShapeSet aS1, aS2;
     //
-    aBF.SetFace(aFF);
-    aBF.SetContext(aCtx);
     const TopTools_ListOfShape& aSE=aWES.StartElements();
-    //
-    //DEB f
-    /*
-    {
-      TopoDS_Compound aCx;
-      BRep_Builder aBBx;
-      TopTools_ListIteratorOfListOfShape aItx;
-      //
-      aBBx.MakeCompound(aCx);
-      aBBx.Add(aCx, aFF);
-      aItx.Initialize(aSE);
-      for (; aItx.More(); aItx.Next()) {
-       TopoDS_Shape& aEx=aItx.Value();
-       aBBx.Add(aCx, aEx);
-      }
-      int a=0;
+    aS1.Add(aSE);
+    aS2.Add(aFF, TopAbs_EDGE);
+    if (aS1.IsEqual(aS2)) {
+      aLFR.Append(aF);
     }
-    */
-    //DEB t
-    //
-    aBF.SetShapes(aSE);
-    //
-    aBF.Perform();
-    //
-    const TopTools_ListOfShape& aLF=aBF.Areas();
-    //
-    TopTools_ListOfShape aLFR;
-    //
-    aIt.Initialize(aLF);
-    for (; aIt.More(); aIt.Next()) {
-      TopoDS_Shape& aFR=aIt.Value();
-      if (anOriF==TopAbs_REVERSED) {
-       aFR.Orientation(TopAbs_REVERSED);
+    else {
+      GEOMAlgo_BuilderFace aBF;
+      //
+      aBF.SetFace(aFF);
+      aBF.SetContext(aCtx);
+      aBF.SetShapes(aSE);
+      // <-DEB
+      aBF.Perform();
+      //
+      const TopTools_ListOfShape& aLF=aBF.Areas();
+      aIt.Initialize(aLF);
+      for (; aIt.More(); aIt.Next()) {
+        TopoDS_Shape& aFR=aIt.Value();
+        if (anOriF==TopAbs_REVERSED) {
+          aFR.Orientation(TopAbs_REVERSED);
+        }
+        aLFR.Append(aFR);
       }
-      aLFR.Append(aFR);
     }
     //
     // 2.3. Collect draft images Faces
     mySplitFaces.Bind(aF, aLFR);
   }//for (i=1; i<=aNbF; ++i)
 }
+
 //=======================================================================
 // function: FillSameDomainFaces
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Builder::FillSameDomainFaces()
 {
+  Standard_Boolean bIsSDF, bHasImage1, bHasImage2, bForward;
+  Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE;
+  Standard_Integer aNbF1, aNbF2, i2s, aNbSD;
+  TopTools_MapOfShape aMFence;
+  TopTools_ListOfShape aLX1, aLX2;
+  TopTools_ListIteratorOfListOfShape aItF1, aItF2;
+  NMTTools_ListOfCoupleOfShape aLCS;
+  //
   const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
   NMTTools_PaveFiller* pPF=myPaveFiller;
   NMTDS_InterfPool* pIP=pPF->IP();
   BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
   IntTools_Context& aCtx= pPF->ChangeContext();
   //
-  Standard_Boolean bIsSDF;
-  Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE;
-  TopTools_MapOfShape aMFence;
-  TopTools_ListIteratorOfListOfShape aItF1, aItF2;
-  NMTTools_ListOfCoupleOfShape aLCS;   
   //
   //mySameDomainShapes.Clear();
   //
@@ -457,57 +462,129 @@ static
     // the faces are suspected to be SDF.
     // Try to find SDF among images of nF1, nF2
     aMFence.Clear();
-    const TopTools_ListOfShape& aLF1=mySplitFaces.Image(aF1);
-    const TopTools_ListOfShape& aLF2=mySplitFaces.Image(aF2);
     //
+    //--------------------------------------------------------
+    bHasImage1=mySplitFaces.HasImage(aF1);
+    bHasImage2=mySplitFaces.HasImage(aF2);
+    //
+    aLX1.Clear();
+    if (!bHasImage1) {
+      aLX1.Append(aF1);
+    }
+    //
+    aLX2.Clear();
+    if (!bHasImage2) {
+      aLX2.Append(aF2);
+    }
+    //
+    const TopTools_ListOfShape& aLF1r=(bHasImage1)? mySplitFaces.Image(aF1) : aLX1;
+    const TopTools_ListOfShape& aLF2r=(bHasImage2)? mySplitFaces.Image(aF2) : aLX2;
+    //
+    TopTools_DataMapOfIntegerShape aMIS;
+    TColStd_ListIteratorOfListOfInteger aItLI;
+    NMTDS_BoxBndTreeSelector aSelector;
+    NMTDS_BoxBndTree aBBTree;
+    NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+    //
+    aNbF1=aLF1r.Extent();
+    aNbF2=aLF2r.Extent();
+    bForward=(aNbF1<aNbF2);
+    //
+    const TopTools_ListOfShape& aLF1=bForward ? aLF1r : aLF2r;
+    const TopTools_ListOfShape& aLF2=bForward ? aLF2r : aLF1r;
+    //
+    // 1. aTreeFiller
+    aItF2.Initialize(aLF2);
+    for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
+      Bnd_Box aBoxF2s;
+      //
+      const TopoDS_Face& aF2s=*((TopoDS_Face*)(&aItF2.Value()));
+      //
+      BRepBndLib::Add(aF2s, aBoxF2s);
+      //
+      aMIS.Bind(i2s, aF2s);
+      //
+      aTreeFiller.Add(i2s, aBoxF2s);
+    }//for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
+    //
+    aTreeFiller.Fill();
+    //
+    // 2.
     aItF1.Initialize(aLF1);
-    for (; aItF1.More(); aItF1.Next()) {
-      const TopoDS_Face& aF1x=TopoDS::Face(aItF1.Value());
+    for (j=1; aItF1.More(); aItF1.Next(), ++j) {
+      Bnd_Box aBoxF1x;
+      //
+      const TopoDS_Face& aF1x=*((TopoDS_Face*)(&aItF1.Value()));
+      //
+      BRepBndLib::Add(aF1x, aBoxF1x);
       //
-      aItF2.Initialize(aLF2);
-      for (; aItF2.More(); aItF2.Next()) {
-       const TopoDS_Face& aF2y=TopoDS::Face(aItF2.Value());
-       bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
-       if (bIsSDF) {
-         if (aMFence.Contains(aF1x) ||
-             aMFence.Contains(aF2y)) {
-           continue;
-         }
-         aMFence.Add(aF1x);
-         aMFence.Add(aF2y);
-         //
-         NMTTools_CoupleOfShape aCS;
-         //
-         aCS.SetShape1(aF1x);
-         aCS.SetShape2(aF2y);
-         aLCS.Append(aCS);
-         //
-         if (aF1x==aF1) {
-           if (!mySplitFaces.HasImage(aF1)) {
-             mySplitFaces.Bind(aF1, aF1);
-           }
-         }
-         if (aF2y==aF2) {
-           if (!mySplitFaces.HasImage(aF2)) {
-             mySplitFaces.Bind(aF2, aF2);
-           }
-         }
-         //
-         
-       }
+      aSelector.Clear();
+      aSelector.SetBox(aBoxF1x);
+      aNbSD=aBBTree.Select(aSelector);
+      if (!aNbSD) {
+        continue;
       }
-    }
+      //
+      const TColStd_ListOfInteger& aLI=aSelector.Indices();
+      aItLI.Initialize(aLI);
+      for (; aItLI.More(); aItLI.Next()) {
+        i2s=aItLI.Value();
+        const TopoDS_Face& aF2y=*((TopoDS_Face*)(&aMIS.Find(i2s)));
+        //
+        bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
+        if (bIsSDF) {
+          if (aMFence.Contains(aF1x) || aMFence.Contains(aF2y)) {
+            continue;
+          }
+          aMFence.Add(aF1x);
+          aMFence.Add(aF2y);
+          //
+          NMTTools_CoupleOfShape aCS;
+          //
+          aCS.SetShape1(aF1x);
+          aCS.SetShape2(aF2y);
+          aLCS.Append(aCS);
+          //
+          if (bForward) {
+            if (aF1x==aF1) {
+              if (!mySplitFaces.HasImage(aF1)) {
+                mySplitFaces.Bind(aF1, aF1);
+              }
+            }
+            if (aF2y==aF2) {
+              if (!mySplitFaces.HasImage(aF2)) {
+                mySplitFaces.Bind(aF2, aF2);
+              }
+            }
+          }
+          else {
+            if (aF1x==aF2) {
+              if (!mySplitFaces.HasImage(aF2)) {
+                mySplitFaces.Bind(aF2, aF2);
+              }
+            }
+            if (aF2y==aF1) {
+              if (!mySplitFaces.HasImage(aF1)) {
+                mySplitFaces.Bind(aF1, aF1);
+              }
+            }
+          }
+          //
+          break;
+        }//if (bIsSDF) {
+      }//for (; aItLI.More(); aItLI.Next()) {
+    }//for (; aItF1.More(); aItF1.Next()) {
   }//for (i=1; i<=aNbFF; ++i)
-  //
+  //-------------------------------------------------------------
   aNbC=aLCS.Extent();
   if (!aNbC) {
     return;
   }
   //
   // 2. Find Chains
-  NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;  
+  NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
   //
-  NMTTools_Tools::FindChains(aLCS, aMC); 
+  NMTTools_Tools::FindChains(aLCS, aMC);
   //
   // 3. Fill the map of SDF mySameDomainFaces
   aNbC=aMC.Extent();
@@ -523,13 +600,14 @@ static
   }
   //
 }
+
 //=======================================================================
 // function: FillImagesFaces1
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Builder::FillImagesFaces1()
 {
-  Standard_Integer i, aNb, iSense;
+  Standard_Integer i, aNb, iSense, aNbLFx;
   TopoDS_Face aF, aFSp, aFSD;
   TopTools_ListOfShape aLFx;
   TopTools_ListIteratorOfListOfShape aIt;
@@ -547,34 +625,43 @@ static
       continue;
     }
     //
-    aF=TopoDS::Face(aS);
+    aF=*((TopoDS_Face*)&aS);
     //
     aLFx.Clear();
     const TopTools_ListOfShape& aLF=mySplitFaces.Image(aF);
     aIt.Initialize(aLF);
     for (; aIt.More(); aIt.Next()) {
-      aFSp=TopoDS::Face(aIt.Value());
+      aFSp=*((TopoDS_Face*)(&aIt.Value()));
       if (!mySameDomainShapes.Contains(aFSp)) {
-       aLFx.Append(aFSp);
+        aLFx.Append(aFSp);
       }
       else {
-       const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
-       aFSD=TopoDS::Face(aSx);
-       iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
-       if (iSense<0) {
-         aFSD.Reverse();
-       }
-       aLFx.Append(aFSD);
+        const TopoDS_Shape& aSx=mySameDomainShapes.FindFromKey(aFSp);
+        aFSD=*((TopoDS_Face*)(&aSx));
+        iSense=GEOMAlgo_Tools3D::Sense(aFSp, aFSD);
+        if (iSense<0) {
+          aFSD.Reverse();
+        }
+        aLFx.Append(aFSD);
       }
     }
-    if (!myImages.HasImage(aF)) {//XX
+    //
+    if (!myImages.HasImage(aF)) {
+      aNbLFx=aLFx.Extent();
+      if (aNbLFx==1) {
+        const TopoDS_Shape& aFx=aLFx.First();
+        if (aF.IsSame(aFx)) {
+          continue;
+        }
+      }
       myImages.Bind(aF, aLFx);
     }
   }
 }
+
 //=======================================================================
 // function: FillInternalVertices
-// purpose: 
+// purpose:
 //=======================================================================
   void GEOMAlgo_Builder::FillInternalVertices()
 {
@@ -583,13 +670,13 @@ static
   NMTDS_InterfPool* pIP=pPF->IP();
   IntTools_Context& aCtx= pPF->ChangeContext();
   //
-  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
+  /*BOPTools_CArray1OfSSInterference& aFFs=*/pIP->SSInterferences();
   BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences();
   BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences();
   const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices();
   //
-  Standard_Boolean bHasImage; 
-  Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag; 
+  Standard_Boolean bHasImage;
+  Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag;
   Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV;
   Standard_Real aU1, aU2, aTol;
   NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV;
@@ -659,13 +746,13 @@ static
       const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF);
       aNbAVF=aMAVF.Extent();
       for (j=1; j<=aNbAVF; ++j) {
-       nV=aMAVF(j); 
-       nVSD=pPF->FindSDVertex(nV);
-       if (nVSD) {
-         nV=nVSD;
-       }
-       //
-       UpdateCandidates(nF, nV, aMFMV);
+        nV=aMAVF(j);
+        nVSD=pPF->FindSDVertex(nV);
+        if (nVSD) {
+          nV=nVSD;
+        }
+        //
+        UpdateCandidates(nF, nV, aMFMV);
       }
     }
     //
@@ -676,12 +763,12 @@ static
       nV=aExp.Current();
       const TopoDS_Shape& aV=aDS.Shape(nV);
       if (aV.Orientation()==TopAbs_INTERNAL) {
-       nVSD=pPF->FindSDVertex(nV);
-       if (nVSD) {
-         nV=nVSD;
-       }
-       //
-       UpdateCandidates(nF, nV, aMFMV);
+        nVSD=pPF->FindSDVertex(nV);
+        if (nVSD) {
+          nV=nVSD;
+        }
+        //
+        UpdateCandidates(nF, nV, aMFMV);
       }
     }
     //
@@ -705,25 +792,25 @@ static
       const TopTools_ListOfShape& aLFx=myImages.Image(aF);
       aIt.Initialize(aLFx);
       for (; aIt.More(); aIt.Next()) {
-       const TopoDS_Shape& aFx=aIt.Value();
-       TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
+        const TopoDS_Shape& aFx=aIt.Value();
+        TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
       }
     }
-    else {     
+    else {
       Standard_Boolean bFaceToProcess;
       //
       TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
       bFaceToProcess=Standard_False;
       for (j=1; j<=aNbVC; ++j) {
-       nV=aMVC(j);
-       const TopoDS_Shape& aV=aDS.Shape(nV);
-       if (!aMVE.Contains(aV)) {
-         bFaceToProcess=!bFaceToProcess;
-         break;
-       }
+        nV=aMVC(j);
+        const TopoDS_Shape& aV=aDS.Shape(nV);
+        if (!aMVE.Contains(aV)) {
+          bFaceToProcess=!bFaceToProcess;
+          break;
+        }
       }
       if (!bFaceToProcess) {
-       continue;
+        continue;
       }
     }// else
     //
@@ -731,11 +818,11 @@ static
       nV=aMVC(j);
       const TopoDS_Shape& aV=aDS.Shape(nV);
       if (aMVE.Contains(aV)) {
-       const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
-       aNbE=aLE.Extent();
-       if (aNbE) {
-         continue;
-       }
+        const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
+        aNbE=aLE.Extent();
+        if (aNbE) {
+          continue;
+        }
       }
       aLV.Append(aV);
     }
@@ -745,52 +832,53 @@ static
       //  3. Try to put vertices into the face(s)
       aItV.Initialize(aLV);
       for (; aItV.More(); aItV.Next()) {
-       TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
-       aV.Orientation(TopAbs_INTERNAL);
-       //
-       bHasImage=myImages.HasImage(aF);
-       if (bHasImage) {
-         const TopTools_ListOfShape& aLFx=myImages.Image(aF);
-         aIt.Initialize(aLFx);
-         for (; aIt.More(); aIt.Next()) {
-           TopoDS_Face aFx=TopoDS::Face(aIt.Value());
-           // update classifier
-           IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
-           aClsf.Init(aFx, aTol);
-           //
-           iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
-           if (!iFlag) {
-             aBB.Add(aFx, aV);
-             break;
-           }
-         }
-       }
-       else {  
-         const TopoDS_Face& aFx=TopoDS::Face(aF);
-         // update classifier
-         IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
-         aClsf.Init(aFx, aTol);
-         //
-         iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
-         if (!iFlag) {
-           TopoDS_Face aFz;
-           //
-           GEOMAlgo_Tools3D::CopyFace(aFx, aFz); 
-           aBB.Add(aFz, aV);
-           myImages.Bind(aF, aFz);
-         }
-       }
+        TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
+        aV.Orientation(TopAbs_INTERNAL);
+        //
+        bHasImage=myImages.HasImage(aF);
+        if (bHasImage) {
+          const TopTools_ListOfShape& aLFx=myImages.Image(aF);
+          aIt.Initialize(aLFx);
+          for (; aIt.More(); aIt.Next()) {
+            TopoDS_Face aFx=TopoDS::Face(aIt.Value());
+            // update classifier
+            IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
+            aClsf.Init(aFx, aTol);
+            //
+            iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
+            if (!iFlag) {
+              aBB.Add(aFx, aV);
+              break;
+            }
+          }
+        }
+        else {
+          const TopoDS_Face& aFx=TopoDS::Face(aF);
+          // update classifier
+          IntTools_FClass2d& aClsf=aCtx.FClass2d(aFx);
+          aClsf.Init(aFx, aTol);
+          //
+          iFlag=aCtx.ComputeVS (aV, aFx, aU1, aU2);
+          if (!iFlag) {
+            TopoDS_Face aFz;
+            //
+            GEOMAlgo_Tools3D::CopyFace(aFx, aFz);
+            aBB.Add(aFz, aV);
+            myImages.Bind(aF, aFz);
+          }
+        }
       }// for (; aItV.More(); aItV.Next()) {
     }// if (aNbV) {
   }// for (nF=1; nF<=aNb; ++nF) {
 }
+
 //=======================================================================
 // function: UpdateCandidates
-// purpose: 
+// purpose:
 //=======================================================================
 void UpdateCandidates(const Standard_Integer theNF,
-                     const Standard_Integer theNV,
-                      NMTTools_IndexedDataMapOfIndexedMapOfInteger& theMFMV)
+                      const Standard_Integer theNV,
+                       NMTTools_IndexedDataMapOfIndexedMapOfInteger& theMFMV)
 {
   if (theMFMV.Contains(theNF)) {
     TColStd_IndexedMapOfInteger& aMV=theMFMV.ChangeFromKey(theNF);
@@ -802,3 +890,20 @@ void UpdateCandidates(const Standard_Integer theNF,
     theMFMV.Add(theNF, aMV);
   }
 }
+
+/*
+    {
+      TopoDS_Compound aCx;
+      BRep_Builder aBBx;
+      TopTools_ListIteratorOfListOfShape aItx;
+      //
+      aBBx.MakeCompound(aCx);
+      aBBx.Add(aCx, aFF);
+      aItx.Initialize(aSE);
+      for (; aItx.More(); aItx.Next()) {
+        TopoDS_Shape& aEx=aItx.Value();
+        aBBx.Add(aCx, aEx);
+      }
+      int a=0;
+    }
+    */