]> OCCT Git - occt-copy.git/commitdiff
New classes for BOPAlgo for patch on boolean operations from OCC version 680
authorgka <gka@opencascade.com>
Mon, 24 Nov 2014 12:46:26 +0000 (15:46 +0300)
committermsv <msv@opencascade.com>
Tue, 3 Feb 2015 16:12:57 +0000 (19:12 +0300)
src/BOPAlgo/BOPAlgo_ShellSplitter.cdl [new file with mode: 0644]
src/BOPAlgo/BOPAlgo_ShellSplitter.cxx [new file with mode: 0644]

diff --git a/src/BOPAlgo/BOPAlgo_ShellSplitter.cdl b/src/BOPAlgo/BOPAlgo_ShellSplitter.cdl
new file mode 100644 (file)
index 0000000..1a960ec
--- /dev/null
@@ -0,0 +1,73 @@
+-- Created by: Peter KURNEV
+-- Copyright (c) 1999-2014 OPEN CASCADE SAS
+--
+-- This file is part of Open CASCADE Technology software library.
+--
+-- This library is free software; you can redistribute it and/or modify it under
+-- the terms of the GNU Lesser General Public License version 2.1 as published
+-- by the Free Software Foundation, with special exception defined in the file
+-- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+-- distribution for complete text of the license and disclaimer of any warranty.
+--
+-- Alternatively, this file may be used under the terms of Open CASCADE
+-- commercial license or contractual agreement.
+
+class ShellSplitter from BOPAlgo 
+       inherits Algo from BOPAlgo 
+        
+       ---Purpose:  
+        -- The class provides the splitting of the set of connected faces 
+       -- on separate loops    
+uses   
+    BaseAllocator from BOPCol, 
+    Shape from TopoDS,
+    ListOfShape from BOPCol, 
+    ConnexityBlock from BOPTools, 
+    ListOfConnexityBlock from BOPTools 
+    
+    
+--raises
+
+is 
+    Create 
+       returns ShellSplitter from BOPAlgo; 
+    ---C++: alias "Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();" 
+    ---Purpose: empty constructor
+     
+    Create(theAllocator: BaseAllocator from BOPCol)  
+       returns ShellSplitter from BOPAlgo; 
+    ---Purpose:  constructor 
+    
+    AddStartElement(me:out; 
+           theS: Shape from TopoDS); 
+    ---Purpose: adds a face <theS> to process             
+    
+    StartElements(me)  
+       returns ListOfShape from BOPCol;
+    ---C++: return const & 
+    ---Purpose: return the faces to process 
+    
+    Perform(me:out) 
+       is redefined;  
+    ---Purpose: performs the algorithm         
+         
+    Shells(me) 
+       returns ListOfShape from BOPCol; 
+    ---C++: return const &      
+    ---Purpose: returns the loops 
+     
+    MakeConnexityBlocks(me:out)  
+       is protected;  
+     
+    MakeShells (me:out)  
+       is protected;   
+       
+    SplitBlock(myclass; 
+           theCB:out ConnexityBlock from BOPTools);  
+        
+fields  
+    myStartShapes: ListOfShape from BOPCol is protected; 
+    myShells: ListOfShape from BOPCol is protected; 
+    myLCB   : ListOfConnexityBlock from BOPTools is protected; 
+   
+end ShellSplitter;
diff --git a/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx b/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
new file mode 100644 (file)
index 0000000..ecea30b
--- /dev/null
@@ -0,0 +1,612 @@
+// Created by: Peter KURNEV
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+// File: BOPAlgo_ShellSplitter.cxx
+// Created: Thu Jan 16 08:33:50 2014
+// <pkv@PETREX>
+
+#include <BOPAlgo_ShellSplitter.ixx>
+//
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Edge.hxx>
+
+#include <BRep_Builder.hxx>
+#include <TopExp_Explorer.hxx>
+//
+#include <BOPCol_IndexedMapOfShape.hxx>
+#include <BOPCol_MapOfShape.hxx>
+#include <BOPCol_MapOfOrientedShape.hxx>
+#include <BOPCol_NCVector.hxx>
+#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
+//
+#include <BOPInt_Context.hxx>
+//
+#include <BOPTools.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_CoupleOfShape.hxx>
+
+//
+static
+  void MakeShell(const BOPCol_ListOfShape& , 
+                 TopoDS_Shell& );
+//
+static
+  void RefineShell(TopoDS_Shell& theShell);
+//
+static
+  Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
+
+//=======================================================================
+//function : 
+//purpose  : 
+//=======================================================================
+BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter()
+:
+  BOPAlgo_Algo(),
+  myStartShapes(myAllocator),
+  myShells(myAllocator),
+  myLCB(myAllocator)
+{
+}
+//=======================================================================
+//function : 
+//purpose  : 
+//=======================================================================
+BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter
+  (const Handle(NCollection_BaseAllocator)& theAllocator)
+:
+  BOPAlgo_Algo(theAllocator),
+  myStartShapes(theAllocator),
+  myShells(theAllocator),
+  myLCB(myAllocator)
+{
+}
+//=======================================================================
+//function : ~
+//purpose  : 
+//=======================================================================
+BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter()
+{
+}
+//=======================================================================
+//function : AddStartElement
+//purpose  : 
+//=======================================================================
+void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE)
+{
+  myStartShapes.Append(aE);
+}
+//=======================================================================
+//function : StartElements
+//purpose  : 
+//=======================================================================
+const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const
+{
+  return myStartShapes;
+}
+//=======================================================================
+//function : Loops
+//purpose  : 
+//=======================================================================
+const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
+{
+  return myShells;
+}
+//=======================================================================
+//function : Perform
+//purpose  : 
+//=======================================================================
+void BOPAlgo_ShellSplitter::Perform()
+{
+  myErrorStatus=0;
+  //
+  MakeConnexityBlocks();
+  if (myErrorStatus) {
+    return;
+  }
+  //
+  MakeShells();
+}
+//=======================================================================
+//function : MakeConnexityBlocks
+//purpose  : 
+//=======================================================================
+void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
+{
+  Standard_Boolean bRegular;
+  Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
+  TopoDS_Shape aFR;
+  TopExp_Explorer aExpF;
+  BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
+  BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
+  BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
+  BOPCol_MapOfShape aMER(100, myAllocator);
+  BOPCol_MapOfShape aMFP(100, myAllocator);
+  BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
+  BOPCol_MapOfShape aMES(100, myAllocator);
+  BOPCol_ListIteratorOfListOfShape aIt;
+  //
+  myErrorStatus=0;
+  //
+  myLCB.Clear();
+  //
+  const BOPCol_ListOfShape& aLSE=myStartShapes;
+  aIt.Initialize(aLSE);
+  for (i=1; aIt.More(); aIt.Next(), ++i) {
+    const TopoDS_Shape& aSE=aIt.Value();
+    if (!aMEP.Contains(aSE)) {
+      aMEP.Add(aSE);
+      BOPTools::MapShapesAndAncestors(aSE, 
+                                      TopAbs_EDGE, 
+                                      TopAbs_FACE, 
+                                      aMEF);
+    }
+    else {
+      aMER.Add(aSE);
+    }
+  }
+  //
+  // 2
+  aNbE=aMEF.Extent();
+  for (i=1; i<=aNbE; ++i) {
+    aNbES=aMES.Extent();
+    if (aNbES==aNbE) {
+      break;
+    }
+    //
+    const TopoDS_Shape& aE=aMEF.FindKey(i);
+    //
+    if (!aMES.Add(aE)) {
+      continue;
+    }
+    // aMES - globally processed edges
+    //
+    //------------------------------------- goal: aMEC
+    aMFC.Clear();    // aMEC - edges of CB
+    aMEP.Clear();    // aMVP - edges to process right now 
+    aMEAdd.Clear();  // aMVAdd edges to process on next step of for(;;) {
+    //
+    aMEP.Add(aE);
+    //
+    for(;;) {
+      aNbEP=aMEP.Extent();
+      for (k=1; k<=aNbEP; ++k) {
+        const TopoDS_Shape& aEP=aMEP(k);
+        const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
+        aIt.Initialize(aLF);
+        for (; aIt.More(); aIt.Next()) {
+          const TopoDS_Shape& aF=aIt.Value();
+          if (aMFC.Add(aF)) {
+            aExpF.Init(aF, TopAbs_EDGE);
+            for (; aExpF.More(); aExpF.Next()) {
+              const TopoDS_Shape& aEF=aExpF.Current();
+              if (aMES.Add(aEF)) {
+                aMEAdd.Add(aEF);
+              }
+            }
+          }
+        }
+      }
+      //
+      aNbEP=aMEAdd.Extent();
+      if (!aNbEP) {
+        break; // from for(;;) {
+      }
+      //
+      aMEP.Clear();
+      //
+      for (k=1; k<=aNbEP; ++k) {
+        const TopoDS_Shape& aEF=aMEAdd(k);
+        aMEP.Add(aEF);
+      }
+      aMEAdd.Clear();
+    }// for(;;) {
+    //
+    //-------------------------------------
+    BOPTools_ConnexityBlock aCB(myAllocator);
+    //
+    BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
+    BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
+    //
+    bRegular=Standard_True;
+    aNbCB = aMFC.Extent();
+    for (j=1; j<=aNbCB; ++j) {
+      aFR = aMFC(j);
+      //
+      if (aMER.Contains(aFR)) {
+        aFR.Orientation(TopAbs_FORWARD);
+        aLECB.Append(aFR);
+        aFR.Orientation(TopAbs_REVERSED);
+        aLECB.Append(aFR);
+        bRegular=Standard_False;
+      }
+      else {
+        aLECB.Append(aFR);
+      }
+      //
+      if (bRegular) {
+        BOPTools::MapShapesAndAncestors(aFR,
+                                        TopAbs_EDGE, 
+                                        TopAbs_FACE, 
+                                        aMEFR);
+      }
+    }
+    //
+    if (bRegular) {
+      Standard_Integer aNbER, aNbFR; 
+      //
+      aNbER=aMEFR.Extent();
+      for (k=1; k<=aNbER; ++k) {
+        const BOPCol_ListOfShape& aLFR=aMEFR(k);
+        aNbFR=aLFR.Extent();
+        if (aNbFR>2) {
+          bRegular=!bRegular;
+          break;
+        }
+      }
+    }
+    //
+    aCB.SetRegular(bRegular);
+    myLCB.Append(aCB);
+  }
+}
+//=======================================================================
+//function : SplitBlock
+//purpose  : 
+//=======================================================================
+void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
+{
+  Standard_Integer aNbLF, aNbOff, aNbFP;
+  Standard_Integer i;
+  TopAbs_Orientation anOr;
+  TopoDS_Edge aEL;
+  BRep_Builder aBB;
+  TopoDS_Iterator aItS;
+  TopExp_Explorer aExp;
+  BOPCol_ListIteratorOfListOfShape aItF;
+  BOPTools_CoupleOfShape aCSOff;
+  BOPCol_MapOfOrientedShape AddedFacesMap;
+  BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
+  // 
+  Handle (BOPInt_Context) aContext=new BOPInt_Context;
+  //
+  const BOPCol_ListOfShape& myShapes=aCB.Shapes();
+  //
+  BOPCol_ListOfShape& myLoops=aCB.ChangeLoops();
+  myLoops.Clear();
+  //
+  // 1. Shells Usual
+  aItF.Initialize (myShapes);
+  for (; aItF.More(); aItF.Next()) {
+    const TopoDS_Shape& aFF = aItF.Value();
+    BOPTools::MapShapesAndAncestors (aFF, 
+                                     TopAbs_EDGE, 
+                                     TopAbs_FACE, 
+                                     aEFMap);
+  }
+  //
+  aItF.Initialize (myShapes);
+  for (i=1; aItF.More(); aItF.Next(), ++i) {
+    const TopoDS_Shape& aFF = aItF.Value();
+    if (!AddedFacesMap.Add(aFF)) {
+      continue;
+    }
+    //
+    // make a new shell
+    TopoDS_Shell aShell;
+    aBB.MakeShell(aShell);
+    aBB.Add(aShell, aFF);
+    //
+    aMEFP.Clear();
+    BOPTools::MapShapesAndAncestors(aFF, 
+                                    TopAbs_EDGE, 
+                                    TopAbs_FACE, 
+                                    aMEFP);
+    //
+    // loop on faces added to Shell; 
+    // add their neighbor faces to Shell and so on
+    aItS.Initialize (aShell);
+    for (; aItS.More(); aItS.Next()) {
+      const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
+      //
+      // loop on edges of aF; find a good neighbor face of aF by aE
+      aExp.Init(aF, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
+        //
+        //1
+        if (aMEFP.Contains(aE)) {
+          const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
+          aNbFP=aLFP.Extent();
+          if (aNbFP>1) { 
+            continue;
+          }
+        }
+        //2
+        anOr=aE.Orientation();
+        if (anOr==TopAbs_INTERNAL) {
+          continue;
+        }
+        //3
+        if (BRep_Tool::Degenerated(aE)) {
+          continue;
+        }
+        //
+        // candidate faces list
+        const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
+        aNbLF=aLF.Extent();
+        if (!aNbLF) {
+          continue;
+        }
+        //
+        // try to select one of neighbors
+        // check if a face already added to Shell shares E
+        Standard_Boolean bFound;
+        BOPCol_ListIteratorOfListOfShape aItLF;
+        BOPTools_ListOfCoupleOfShape aLCSOff;
+        //
+        aItLF.Initialize(aLF);
+        for (; aItLF.More(); aItLF.Next()) { 
+          const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
+          if (aF.IsSame(aFL)) {
+            continue;
+          } 
+          if (AddedFacesMap.Contains(aFL)){
+            continue;
+          }
+          //
+          bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
+          if (!bFound) {
+            continue;
+          }
+          //
+          aCSOff.SetShape1(aEL);
+          aCSOff.SetShape2(aFL);
+          aLCSOff.Append(aCSOff);
+        }//for (; aItLF.More(); aItLF.Next()) { 
+        //
+        aNbOff=aLCSOff.Extent();
+        if (!aNbOff){
+          continue;
+        }
+        //
+        TopoDS_Face aSelF;
+        if (aNbOff==1) {
+          aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
+        }
+        else if (aNbOff>1){
+          BOPTools_AlgoTools::GetFaceOff(aE, 
+                                         aF, 
+                                         aLCSOff, 
+                                         aSelF, 
+                                         aContext);
+        }
+        //
+        if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { 
+          aBB.Add(aShell, aSelF);
+          BOPTools::MapShapesAndAncestors(aSelF, 
+                                          TopAbs_EDGE, 
+                                          TopAbs_FACE, 
+                                          aMEFP);
+        }
+      } // for (; aExp.More(); aExp.Next()) {
+    } // for (; aItS.More(); aItS.Next()) {
+    //
+    if (IsClosedShell(aShell)) {
+      aShell.Closed (Standard_True);
+      myLoops.Append(aShell);
+    }
+    else {
+      RefineShell(aShell);
+      if (IsClosedShell(aShell)) {
+        aShell.Closed (Standard_True);
+        myLoops.Append(aShell);
+      }
+    }
+  } // for (; aItF.More(); aItF.Next()) {
+}
+//=======================================================================
+//function : RefineShell
+//purpose  : 
+//=======================================================================
+void RefineShell(TopoDS_Shell& theShell)
+{
+  TopoDS_Iterator aIt;
+  //
+  aIt.Initialize(theShell);
+  if(!aIt.More()) {
+    return;
+  }
+  //
+  Standard_Integer i, aNbMEF, aNbF;
+  BOPCol_IndexedDataMapOfShapeListOfShape aMEF; 
+  TopoDS_Builder aBB;
+  TopExp_Explorer aExp;
+  BOPCol_MapOfShape aMEStop, aMFB;
+  BOPCol_MapIteratorOfMapOfShape aItM;
+  BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
+  BOPCol_ListOfShape aLFP, aLFP1;
+  //
+  // Branch points
+  BOPTools::MapShapesAndAncestors (theShell, 
+                                   TopAbs_EDGE, 
+                                   TopAbs_FACE, 
+                                   aMEF);
+  aNbMEF=aMEF.Extent();
+  for (i=1; i<=aNbMEF; ++i) {
+    const TopoDS_Shape& aE=aMEF.FindKey(i);
+    const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
+    aNbF=aLF.Extent();
+    if (aNbF>2) {
+      aMEStop.Add(aE);
+    }
+  }
+  //
+  if (aMEStop.IsEmpty()) {
+    return;
+  }
+  //
+  // The first Face 
+  const TopoDS_Shape& aF1=aIt.Value();
+  aMFB.Add(aF1);
+  aLFP.Append(aF1);
+  //
+  // Trying to reach the branch point
+  for (;;)  {
+    aItLFP.Initialize(aLFP);
+    for (; aItLFP.More(); aItLFP.Next()) { 
+      const TopoDS_Shape& aFP=aItLFP.Value();
+      //
+      aExp.Init(aFP, TopAbs_EDGE);
+      for (; aExp.More(); aExp.Next()) {
+        const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
+        if (aMEStop.Contains(aE)) {
+          continue;
+        }
+        //
+        if (BRep_Tool::Degenerated(aE)) {
+          continue;
+        }
+        //
+        const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
+        //
+        aItLF.Initialize(aLF);
+        for (; aItLF.More(); aItLF.Next()) { 
+          const TopoDS_Shape& aFP1=aItLF.Value();
+          if (aFP1.IsSame(aFP)) {
+            continue;
+          }
+          if (aMFB.Contains(aFP1)) {
+            continue;
+          }
+          aMFB.Add(aFP1);
+          aLFP1.Append(aFP1);
+        }// for (; aItLF.More(); aItLF.Next()) { 
+      }// for (; aExp.More(); aExp.Next()) {
+    }// for (; aItLFP.More(); aItLFP.Next()) { 
+    //
+    //
+    if (aLFP1.IsEmpty()) {
+      break;
+    }
+    //
+    aLFP.Clear();
+    aItLF.Initialize(aLFP1);
+    for (; aItLF.More(); aItLF.Next()) { 
+      const TopoDS_Shape& aFP1=aItLF.Value();
+      aLFP.Append(aFP1);
+    }
+    aLFP1.Clear();
+  }// for (;;)  {
+  //
+  // Remove all faces before the branch point
+  aItM.Initialize(aMFB);
+  for (; aItM.More(); aItM.Next()) { 
+    const TopoDS_Shape& aFB=aItM.Value();
+    aBB.Remove(theShell, aFB);
+  }
+}
+
+//=======================================================================
+//function : MakeShells
+//purpose  : 
+//=======================================================================
+void BOPAlgo_ShellSplitter::MakeShells()
+{
+  Standard_Boolean bIsRegular;
+  BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  //
+  myErrorStatus=0;
+  myShells.Clear();
+  //
+  aItCB.Initialize(myLCB);
+  for (; aItCB.More(); aItCB.Next()) {
+    BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
+    bIsRegular=aCB.IsRegular();
+    if (bIsRegular) {
+      TopoDS_Shell aShell;
+      //
+      const BOPCol_ListOfShape& aLF=aCB.Shapes();
+      MakeShell(aLF, aShell);
+      aShell.Closed(Standard_True);
+      myShells.Append(aShell);
+    }
+    else {
+      SplitBlock(aCB);
+      const BOPCol_ListOfShape& aLS=aCB.Loops();
+      aIt.Initialize(aLS);
+      for (; aIt.More(); aIt.Next()) {
+        TopoDS_Shape& aShell=aIt.ChangeValue();
+        aShell.Closed(Standard_True);
+        myShells.Append(aShell);
+      }
+    }
+  }
+}
+//=======================================================================
+//function : MakeShell
+//purpose  : 
+//=======================================================================
+void MakeShell(const BOPCol_ListOfShape& aLS, 
+               TopoDS_Shell& aShell)
+{
+  BRep_Builder aBB;
+  BOPCol_ListIteratorOfListOfShape aIt;
+  //
+  aBB.MakeShell(aShell);
+  //
+  aIt.Initialize(aLS);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aF=aIt.Value();
+    aBB.Add(aShell, aF);
+  }
+}
+//=======================================================================
+//function : IsClosedShell
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
+{
+  Standard_Integer aNbE;
+  Standard_Boolean bRet;
+  TopoDS_Iterator aIt;
+  TopExp_Explorer aExp;
+  BOPCol_MapOfShape aM;
+  // 
+  aIt.Initialize(theShell);
+  for(; aIt.More(); aIt.Next()) {
+    const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
+    aExp.Init(aF, TopAbs_EDGE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
+      if (BRep_Tool::Degenerated(aE)) {
+        continue;
+      }
+      //
+      if (aE.Orientation()==TopAbs_INTERNAL) {
+        continue;
+      }
+      //
+      if (!aM.Add(aE)) {
+        aM.Remove(aE);
+      }
+    }
+  }
+  //
+  aNbE = aM.Extent();
+  bRet = (aNbE > 0) ? Standard_False : Standard_True;
+  return bRet;
+}