Salome HOME
Fix/implement removeNode, removeEdge, removeFace, removeVolume and removeElement
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index c25456840afa7cf61172621d9607c150edb8aadd..07385dc9062eae6641fe131e6a71ea4abaa154fe 100644 (file)
@@ -24,6 +24,8 @@
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_VolumeOfFaces.hxx"
 #include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_Tria3OfNodes.hxx"
+#include "SMDS_HexahedronOfNodes.hxx"
 #include "SMDS_FaceOfEdges.hxx"
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -38,6 +40,9 @@ SMDS_Mesh::SMDS_Mesh()
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+/// Create a new child mesh
+/// Note that the tree structure of SMDS_Mesh seems to be unused in this version
+/// (2003-09-08) of SMESH
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
        :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
@@ -60,6 +65,7 @@ SMDS_Mesh *SMDS_Mesh::AddSubMesh()
 
 ///////////////////////////////////////////////////////////////////////////////
 ///create a MeshNode and add it to the current Mesh
+///An ID is automatically assigned to the node.
 ///@return : The created node
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -90,8 +96,8 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///create a MeshEdge and add it to the current Mesh
-///@return : The created MeshEdge
+/// create a MeshEdge and add it to the current Mesh
+/// @return : The created MeshEdge
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
@@ -102,18 +108,24 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
        return AddEdgeWithID(node1, node2, ID);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// create a MeshEdge and add it to the current Mesh
+/// @return : The created MeshEdge
+///////////////////////////////////////////////////////////////////////////////
+
 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
        const SMDS_MeshNode * node2)
 {
        return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
 }
+
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new edge and at it to the mesh
-///@param idnode1 ID of the first node
-///@param idnode2 ID of the second node
-///@param ID ID of the edge to create
-///@return The created edge or NULL if an edge with this ID already exists or
-///if input nodes are not found.
+/// Create a new edge and at it to the mesh
+/// @param idnode1 ID of the first node
+/// @param idnode2 ID of the second node
+/// @param ID ID of the edge to create
+/// @return The created edge or NULL if an edge with this ID already exists or
+/// if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
@@ -202,7 +214,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
        const SMDS_MeshNode * n3,
        const SMDS_MeshNode * n4)
 {
-       return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
+       return AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -253,8 +265,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new tetrahedron and add it to the mesh. 
-///@return The created tetrahedron or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created tetrahedron 
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
@@ -289,8 +300,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new tetrahedron and add it to the mesh. 
 ///@param ID The ID of the new volume
-///@return The created tetrahedron or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created tetrahedron 
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
@@ -321,8 +331,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
        }
        else
        {
-               MESSAGE("Error : Not implemented");
-               return NULL;
+               volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4);
+               myVolumes.insert(volume);
        }
 
        if(myElementIDFactory->BindID(ID, volume))
@@ -343,8 +353,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new pyramid and add it to the mesh. 
 ///Nodes 1,2,3 and 4 define the base of the pyramid
-///@return The created pyramid or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created pyramid 
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
@@ -361,7 +370,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///Create a new pyramid and add it to the mesh. 
 ///Nodes 1,2,3 and 4 define the base of the pyramid
 ///@param ID The ID of the new volume
-///@return The created pyramid or NULL if an edge with this ID already exists
+///@return The created pyramid or NULL if a pyramid with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -384,8 +393,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
 ///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
 ///@param ID The ID of the new volume
-///@return The created pyramid or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created pyramid
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
@@ -418,8 +426,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
        }
        else
        {
-               MESSAGE("Error : Not implemented");
-               return NULL;
+               volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5);
+               myVolumes.insert(volume);
        }
 
        if(myElementIDFactory->BindID(ID, volume))
@@ -441,8 +449,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new prism and add it to the mesh. 
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
-///@return The created prism or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created prism 
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
@@ -460,7 +467,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///Create a new prism and add it to the mesh. 
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
 ///@param ID The ID of the new volume
-///@return The created prism or NULL if an edge with this ID already exists
+///@return The created prism or NULL if a prism with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -484,8 +491,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
 ///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
 ///@param ID The ID of the new volume
-///@return The created prism or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created prism
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
@@ -521,8 +527,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
        }
        else
        {
-               MESSAGE("Error : Not implemented");
-               return NULL;
+               volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6);
+               myVolumes.insert(volume);
        }
 
        if(myElementIDFactory->BindID(ID, volume))
@@ -545,8 +551,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new hexahedron and add it to the mesh. 
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
-///@return The created hexahedron or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created hexahedron 
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
@@ -565,8 +570,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///Create a new hexahedron and add it to the mesh. 
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
 ///@param ID The ID of the new volume
-///@return The created hexahedron or NULL if an edge with this ID already exists
-///or if input nodes are not found.
+///@return The created hexahedron or NULL if an hexahedron with this ID already
+///exists or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
@@ -590,10 +595,10 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
 }
        
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new prism and add it to the mesh.
+///Create a new hexahedron and add it to the mesh.
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
 ///@param ID The ID of the new volume
-///@return The created prism or NULL if an edge with this ID already exists
+///@return The created prism or NULL if an hexadron with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -635,7 +640,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
        }
        else
        {
-               volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6,
+               volume=new SMDS_HexahedronOfNodes(node1,node2,node3,node4,node5,node6,
                        node7,node8);
                myVolumes.insert(volume);
        }
@@ -659,11 +664,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
        }
 }
 
-//=======================================================================
-//function : FindNode
-//purpose  :
-//=======================================================================
-
+///////////////////////////////////////////////////////////////////////////////
+/// Return the node whose ID is 'ID'.
+///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
        return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
@@ -689,7 +692,7 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
        }
        else
        {
-               SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+               SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3);
                myFaces.insert(face);
                return face;
        }
@@ -722,110 +725,40 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
        }
 }
 
-
-//=======================================================================
-//function : RemoveNode
-//purpose  :
-//=======================================================================
+///////////////////////////////////////////////////////////////////////////////
+/// Remove a node and all the elements which own this node
+///////////////////////////////////////////////////////////////////////////////
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
-       SMDS_Iterator<const SMDS_MeshElement *> * it=
-               node->GetInverseElementIterator();
-       while(it->more()) RemoveElement(it->next(),true);
-       myNodeIDFactory->ReleaseID(node->GetID());
-       myNodes.erase(const_cast<SMDS_MeshNode*>(node));
+       RemoveElement(node, true);
 }
 
-//=======================================================================
-//function : RemoveEdge
-//purpose  :
-//=======================================================================
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an edge and all the elements which own this edge
+///////////////////////////////////////////////////////////////////////////////
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
-       /** @todo to be fix */
-       myEdges.erase(const_cast<SMDS_MeshEdge*>(edge));
-       //removeElementDependencies(edge);
-       delete edge;
+       RemoveElement(edge,true);
 }
 
-//=======================================================================
-//function : RemoveFace
-//purpose  :
-//=======================================================================
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an face and all the elements which own this face
+///////////////////////////////////////////////////////////////////////////////
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
-       /** @todo to be fix */
-       myFaces.erase(const_cast<SMDS_MeshFace*>(face));
-       //removeElementDependencies(face);
-       delete face;
+       RemoveElement(face, true);
 }
 
-//=======================================================================
-//function : RemoveVolume
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
-{
-       /** @todo to be fix */
-       myVolumes.erase(const_cast<SMDS_MeshVolume*>(volume));
-       //removeElementDependencies(volume);
-       delete volume;
-}
 ///////////////////////////////////////////////////////////////////////////////
-/// Remove no longer used sub element of an element. Unbind the element ID
+/// Remove a volume
 ///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::removeElementDependencies(SMDS_MeshElement * element)
-{
-       /** @todo to be fix */
-       myElementIDFactory->ReleaseID(element->GetID());
-       SMDS_Iterator<const SMDS_MeshElement*> * it=element->nodesIterator();
-       while(it->more())
-       {
-               SMDS_MeshNode * node=static_cast<SMDS_MeshNode*>(
-                       const_cast<SMDS_MeshElement*>(it->next()));
-               node->RemoveInverseElement(element);
-               if(node->emptyInverseElements()) RemoveNode(node);
-       }
-}
-
-//=======================================================================
-//function : RemoveElement
-//purpose  :
-//=======================================================================
 
-void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
-       const bool removenodes)
+void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
-       /** @todo to be fix */
-       switch(elem->GetType())
-       {
-    case SMDSAbs_Node:
-               RemoveNode((const SMDS_MeshNode*)elem);
-               return;
-    case SMDSAbs_Edge:
-               RemoveEdge((const SMDS_MeshEdge*)elem);
-               break;
-    case SMDSAbs_Face:
-               RemoveFace((const SMDS_MeshFace*)elem);
-               break;
-    case SMDSAbs_Volume:
-               RemoveVolume((const SMDS_MeshVolume*)elem);
-               break;
-    default :
-               MESSAGE("remove function : unknown type");
-               return;
-       }
-/*     
-       SMDS_Iterator<const SMDS_MeshNode*> * it=elem->nodesIterator();
-       while(it->more())
-       {
-               const SMDS_MeshNode * node=it->next();
-               
-       }*/
+       RemoveElement(volume, true);
 }
 
 //=======================================================================
@@ -1153,31 +1086,52 @@ void SMDS_Mesh::DebugStats() const
 
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of nodes
+///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbNodes() const
 {
        return myNodes.size();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of edges (including construction edges)
+///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbEdges() const
 {
        return myEdges.size();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of faces (including construction faces)
+///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbFaces() const
 {
        return myFaces.size();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of volumes
+///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbVolumes() const
 {
        return myVolumes.size();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of child mesh of this mesh.
+/// Note that the tree structure of SMDS_Mesh seems to be unused in this version
+/// (2003-09-08) of SMESH
+///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbSubMesh() const
 {
        return myChildren.size();
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Destroy the mesh and all its elements
+/// All pointer on elements owned by this mesh become illegals.
+///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::~SMDS_Mesh()
 {
        if(myParent==NULL)
@@ -1223,31 +1177,59 @@ SMDS_Mesh::~SMDS_Mesh()
 
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if this mesh create faces with edges.
+/// A false returned value mean that faces are created with nodes. A concequence
+/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
+///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionEdges()
 {
        return myHasConstructionEdges;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if this mesh create volumes with faces
+/// A false returned value mean that volumes are created with nodes or edges.
+/// (see hasConstructionEdges)
+/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
+/// unavailable.
+///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionFaces()
 {
        return myHasConstructionFaces;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if nodes are linked to the finit elements, they are belonging to.
+/// Currently, It always return true.
+///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasInverseElements()
 {
        return myHasInverseElements;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating construction edges (see hasConstructionEdges)
+/// @param b true to have construction edges, else false.
+///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionEdges(bool b)
 {
        myHasConstructionEdges=b;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating construction faces (see hasConstructionFaces)
+/// @param b true to have construction faces, else false.
+///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionFaces(bool b)
 {
         myHasConstructionFaces=b;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating link from nodes to elements (see hasInverseElements)
+/// @param b true to link nodes to elements, else false.
+///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setInverseElements(bool b)
 {
        if(!b) MESSAGE("Error : inverseElement=false not implemented");
@@ -1255,8 +1237,8 @@ void SMDS_Mesh::setInverseElements(bool b)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Return an iterator on nodes of the current mesh. Once used this iterator
-///must be free by the caller
+/// Return an iterator on nodes of the current mesh. Once used this iterator
+/// must be free by the caller
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
 {
@@ -1391,3 +1373,201 @@ SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
        return new MyIterator(myVolumes);
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Do intersection of sets (more than 2)
+///////////////////////////////////////////////////////////////////////////////
+set<const SMDS_MeshElement*> * intersectionOfSets(
+       set<const SMDS_MeshElement*> vs[], int numberOfSets)
+{
+       set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
+       set<const SMDS_MeshElement*>* rsetB;
+
+       for(int i=0; i<numberOfSets-1; i++)
+       {
+               rsetB=new set<const SMDS_MeshElement*>();
+               set_intersection(
+                       rsetA->begin(), rsetA->end(),
+                       vs[i+1].begin(), vs[i+1].end(),
+                       inserter(*rsetB, rsetB->begin()));
+               delete rsetA;
+               rsetA=rsetB;
+       }
+       return rsetA;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the list of finit elements owning the given element
+///////////////////////////////////////////////////////////////////////////////
+set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
+{
+       int numberOfSets=element->NbNodes();
+       set<const SMDS_MeshElement*> initSet[numberOfSets];
+
+       SMDS_Iterator<const SMDS_MeshElement*> * itNodes=element->nodesIterator();
+
+       int i=0;
+       while(itNodes->more())
+       {
+               const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+               SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
+
+               //initSet[i]=set<const SMDS_MeshElement*>();
+               while(itFe->more()) initSet[i].insert(itFe->next());
+
+               i++;
+               delete itFe;
+       }
+       delete itNodes;
+       
+       return intersectionOfSets(initSet, numberOfSets);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the list of nodes used only by the given elements
+///////////////////////////////////////////////////////////////////////////////
+set<const SMDS_MeshElement*> * getExclusiveNodes(
+       set<const SMDS_MeshElement*>& elements)
+{
+       set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
+       set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
+
+       while(itElements!=elements.end())
+       {
+               SMDS_Iterator<const SMDS_MeshElement*> * itNodes=
+                       (*itElements)->nodesIterator();
+               itElements++;
+       
+               while(itNodes->more())
+               {
+                       const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+                       SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
+                       set<const SMDS_MeshElement*> s;
+                       while(itFe->more()) s.insert(itFe->next());
+                       delete itFe;
+                       if(s==elements) toReturn->insert(n);
+               }
+               delete itNodes;
+       }
+       return toReturn;        
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Find the children of an element that are made of given nodes 
+///@param setOfChildren The set in which matching children will be inserted
+///@param element The element were to search matching children
+///@param nodes The nodes that the children must have to be selected
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&     setOfChildren, 
+       const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
+{
+       
+       switch(element->GetType())
+       {
+       case SMDSAbs_Node:
+               MESSAGE("Internal Error: This should not append");
+               break;
+       case SMDSAbs_Edge:
+       {
+               SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
+               while(itn->more())
+               {
+                       const SMDS_MeshElement * e=itn->next();
+                       if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
+               }
+               delete itn;
+       } break;        
+       case SMDSAbs_Face:
+       {
+               SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
+               while(itn->more())
+               {
+                       const SMDS_MeshElement * e=itn->next();
+                       if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
+               }
+               delete itn;
+               if(hasConstructionEdges())
+               {
+                       SMDS_Iterator<const SMDS_MeshElement*>* ite=element->edgesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                       delete ite;
+               }
+       } break;        
+       case SMDSAbs_Volume:
+       {
+               if(hasConstructionFaces())
+               {
+                       SMDS_Iterator<const SMDS_MeshElement*> * ite=element->facesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                       delete ite;
+               }
+               else if(hasConstructionEdges())
+               {
+                       SMDS_Iterator<const SMDS_MeshElement*> * ite=element->edgesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                       delete ite;
+               }
+       }
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///@param removenodes if true remaining nodes will be removed
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
+       const bool removenodes)
+{
+       set<const SMDS_MeshElement*> * s1=getFinitElements(elem);
+       
+       set<const SMDS_MeshElement*> * s2=getExclusiveNodes(*s1);
+       set<const SMDS_MeshElement*> s3;
+       set<const SMDS_MeshElement*>::iterator it=s1->begin();
+       while(it!=s1->end())
+       {
+               addChildrenWithNodes(s3, *it ,*s2);
+               s3.insert(*it);
+               it++;
+       }
+       if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);      
+       it=s3.begin();
+       while(it!=s3.end())
+       {
+               switch((*it)->GetType())
+               {
+               case SMDSAbs_Node:
+                       MESSAGE("Internal Error: This should not happen");
+                       break;
+               case SMDSAbs_Edge:
+                       myEdges.erase(static_cast<SMDS_MeshEdge*>(
+                               const_cast<SMDS_MeshElement*>(*it)));   
+                       break;
+               case SMDSAbs_Face:
+                       myFaces.erase(static_cast<SMDS_MeshFace*>(
+                               const_cast<SMDS_MeshElement*>(*it)));
+                       break;
+               case SMDSAbs_Volume:
+                       myVolumes.erase(static_cast<SMDS_MeshVolume*>(
+                               const_cast<SMDS_MeshElement*>(*it)));   
+                       break;
+               }
+               delete (*it);
+               it++;
+       }       
+       if(removenodes)
+       {
+               it=s2->begin();
+               while(it!=s2->end())
+               {
+                       myNodes.erase(static_cast<SMDS_MeshNode*>(
+                               const_cast<SMDS_MeshElement*>(*it)));
+                       delete *it;
+                       it++;
+               }
+       }
+               
+       delete s2;
+       delete s1;
+}