+ delete myNodePool;
+ delete myVolumePool;
+ delete myFacePool;
+ delete myEdgePool;
+ delete myBallPool;
+}
+
+//================================================================================
+/*!
+ * \brief Clear all data
+ */
+//================================================================================
+
+void SMDS_Mesh::Clear()
+{
+ MESSAGE("SMDS_Mesh::Clear");
+ if (myParent!=NULL)
+ {
+ SMDS_ElemIteratorPtr eIt = elementsIterator();
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement *elem = eIt->next();
+ myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
+ }
+ SMDS_NodeIteratorPtr itn = nodesIterator();
+ while (itn->more())
+ {
+ const SMDS_MeshNode *node = itn->next();
+ myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
+ }
+ }
+ else
+ {
+ myNodeIDFactory->Clear();
+ myElementIDFactory->Clear();
+ }
+
+ // SMDS_ElemIteratorPtr itv = elementsIterator();
+ // while (itv->more())
+ // {
+ // SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
+ // SMDSAbs_ElementType aType = elem->GetType();
+ // switch (aType)
+ // {
+ // case SMDSAbs_0DElement:
+ // delete elem;
+ // break;
+ // case SMDSAbs_Edge:
+ // myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
+ // break;
+ // case SMDSAbs_Face:
+ // myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
+ // break;
+ // case SMDSAbs_Volume:
+ // myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
+ // break;
+ // case SMDSAbs_Ball:
+ // myBallPool->destroy(static_cast<SMDS_BallElement*>(elem));
+ // break;
+ // default:
+ // break;
+ // }
+ // }
+ myVolumePool->clear();
+ myFacePool->clear();
+ myEdgePool->clear();
+ myBallPool->clear();
+
+ clearVector( myCells );
+ clearVector( myCellIdVtkToSmds );
+
+ SMDS_NodeIteratorPtr itn = nodesIterator();
+ while (itn->more())
+ {
+ SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
+ node->SetPosition(SMDS_SpacePosition::originSpacePosition());
+ //myNodePool->destroy(node);
+ }
+ myNodePool->clear();
+ clearVector( myNodes );
+
+ list<SMDS_Mesh*>::iterator itc=myChildren.begin();
+ while(itc!=myChildren.end())
+ (*itc)->Clear();
+
+ myModified = false;
+ myModifTime++;
+ xmin = 0; xmax = 0;
+ ymin = 0; ymax = 0;
+ zmin = 0; zmax = 0;
+
+ myInfo.Clear();
+
+ myGrid->Initialize();
+ myGrid->Allocate();
+ vtkPoints* points = vtkPoints::New();
+ // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
+ // using double type for storing coordinates of nodes instead float.
+ points->SetDataType(VTK_DOUBLE);
+ points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
+ myGrid->SetPoints( points );
+ points->Delete();
+ myGrid->BuildLinks();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// 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");
+ myHasInverseElements=b;
+}
+
+namespace {
+
+ //================================================================================
+ /*!
+ * \brief Iterator on elements in id increasing order
+ */
+ //================================================================================
+
+ template <typename ELEM=const SMDS_MeshElement*>
+ class IdSortedIterator : public SMDS_Iterator<ELEM>
+ {
+ SMDS_MeshElementIDFactory& myIDFact;
+ int myID, myMaxID, myNbFound, myTotalNb;
+ SMDSAbs_ElementType myType;
+ ELEM myElem;
+
+ public:
+ IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
+ const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!!
+ const int totalNb)
+ :myIDFact( fact ),
+ myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
+ myType( type ),
+ myElem(0)
+ {
+ next();
+ }
+ bool more()
+ {
+ return myElem;
+ }
+ ELEM next()
+ {
+ ELEM current = myElem;
+
+ for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
+ if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
+ && myElem->GetType() != myType )
+ myElem = 0;
+
+ myNbFound += bool(myElem);
+
+ return current;
+ }
+ };
+
+ //================================================================================
+ /*!
+ * \brief Iterator on vector of elements, possibly being resized while iteration
+ */
+ //================================================================================
+
+ template<typename RETURN_VALUE,
+ typename VECTOR_VALUE=SMDS_MeshCell*,
+ typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
+ class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
+ {
+ const std::vector<VECTOR_VALUE>& _vector;
+ size_t _index;
+ bool _more;
+ VALUE_FILTER _filter;
+ public:
+ ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
+ const VALUE_FILTER& filter=VALUE_FILTER() )
+ :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
+ {
+ if ( _more && !_filter( _vector[ _index ]))
+ next();
+ }
+ virtual bool more()
+ {
+ return _more;
+ }
+ virtual RETURN_VALUE next()
+ {
+ if ( !_more ) return NULL;
+ VECTOR_VALUE current = _vector[ _index ];
+ _more = 0;
+ while ( !_more && ++_index < _vector.size() )
+ _more = _filter( _vector[ _index ]);
+ return (RETURN_VALUE) current;
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on nodes of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
+{
+ // naturally always sorted by ID
+ typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
+ return SMDS_NodeIteratorPtr( new TIterator(myNodes));
+}
+
+SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
+{
+ // naturally always sorted by ID
+ typedef ElemVecIterator
+ < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
+ return SMDS_ElemIteratorPtr
+ (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
+}
+
+SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
+{
+ if ( type == SMDSEntity_Node )
+ {
+ typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
+ return SMDS_ElemIteratorPtr( new TIterator(myNodes));
+ }
+ // naturally always sorted by ID
+ typedef ElemVecIterator
+ < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
+ return SMDS_ElemIteratorPtr
+ (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on elements of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
+{
+ // naturally always sorted by ID
+ switch ( type ) {
+
+ case SMDSAbs_All:
+ return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
+
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr
+ ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
+
+ default:
+ typedef ElemVecIterator
+ < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+ return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
+ }
+ return SMDS_ElemIteratorPtr();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on edges of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
+{
+ // naturally always sorted by ID
+ typedef ElemVecIterator
+ < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+ return SMDS_EdgeIteratorPtr
+ (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on faces of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
+{
+ // naturally always sorted by ID
+ typedef ElemVecIterator
+ < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+ return SMDS_FaceIteratorPtr
+ (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on volumes of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
+{
+ // naturally always sorted by ID
+ typedef ElemVecIterator
+ < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
+ return SMDS_VolumeIteratorPtr
+ (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Do intersection of sets (more than 2)
+///////////////////////////////////////////////////////////////////////////////
+static 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 finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
+///////////////////////////////////////////////////////////////////////////////
+static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
+{
+ int numberOfSets=element->NbNodes();
+ set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
+
+ SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+
+ int i=0;
+ while(itNodes->more())
+ {
+ const SMDS_MeshElement* node = itNodes->next();
+ MYASSERT(node);
+ const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
+ SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+
+ //initSet[i]=set<const SMDS_MeshElement*>();
+ while(itFe->more())
+ {
+ const SMDS_MeshElement* elem = itFe->next();
+ MYASSERT(elem);
+ initSet[i].insert(elem);
+
+ }
+
+ i++;
+ }
+ set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+// MESSAGE("nb elems " << i << " intersection " << retSet->size());
+ delete [] initSet;
+ return retSet;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the list of nodes used only by the given elements
+///////////////////////////////////////////////////////////////////////////////
+static 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_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
+ itElements++;
+
+ while(itNodes->more())
+ {
+ const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+ SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+ set<const SMDS_MeshElement*> s;
+ while(itFe->more())
+ s.insert(itFe->next());
+ if(s==elements) toReturn->insert(n);
+ }
+ }
+ 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 happen");
+ break;
+ case SMDSAbs_0DElement:
+ {
+ }
+ break;
+ case SMDSAbs_Edge:
+ {
+ SMDS_ElemIteratorPtr itn=element->nodesIterator();
+ while(itn->more())
+ {
+ const SMDS_MeshElement * e=itn->next();
+ if(nodes.find(e)!=nodes.end())
+ {
+ setOfChildren.insert(element);
+ break;
+ }
+ }
+ } break;
+ case SMDSAbs_Face:
+ {
+ SMDS_ElemIteratorPtr itn=element->nodesIterator();
+ while(itn->more())
+ {
+ const SMDS_MeshElement * e=itn->next();
+ if(nodes.find(e)!=nodes.end())
+ {
+ setOfChildren.insert(element);
+ break;
+ }
+ }
+ if(hasConstructionEdges())
+ {
+ SMDS_ElemIteratorPtr ite=element->edgesIterator();
+ while(ite->more())
+ addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+ }
+ } break;
+ case SMDSAbs_Volume:
+ {
+ if(hasConstructionFaces())
+ {
+ SMDS_ElemIteratorPtr ite=element->facesIterator();
+ while(ite->more())
+ addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+ }
+ else if(hasConstructionEdges())
+ {
+ SMDS_ElemIteratorPtr ite=element->edgesIterator();
+ while(ite->more())
+ addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+ }
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///@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)
+{
+ list<const SMDS_MeshElement *> removedElems;
+ list<const SMDS_MeshElement *> removedNodes;
+ RemoveElement( elem, removedElems, removedNodes, removenodes );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
+///@param removenodes if true remaining nodes will be removed
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
+ list<const SMDS_MeshElement *>& removedElems,
+ list<const SMDS_MeshElement *>& removedNodes,
+ bool removenodes)
+{
+ //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
+ // get finite elements built on elem
+ set<const SMDS_MeshElement*> * s1;
+ if ( (elem->GetType() == SMDSAbs_0DElement)
+ || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
+ || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
+ || (elem->GetType() == SMDSAbs_Volume) )
+ {
+ s1 = new set<const SMDS_MeshElement*> ();
+ s1->insert(elem);
+ }
+ else
+ s1 = getFinitElements(elem);
+
+ // get exclusive nodes (which would become free afterwards)
+ set<const SMDS_MeshElement*> * s2;
+ if (elem->GetType() == SMDSAbs_Node) // a node is removed
+ {
+ // do not remove nodes except elem
+ s2 = new set<const SMDS_MeshElement*> ();
+ s2->insert(elem);
+ removenodes = true;
+ }
+ else
+ s2 = getExclusiveNodes(*s1);
+
+ // form the set of finite and construction elements to remove
+ 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);
+
+ // remove finite and construction elements
+ it = s3.begin();
+ while (it != s3.end())
+ {
+ // Remove element from <InverseElements> of its nodes
+ SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
+ while (itn->more())
+ {
+ SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
+ n->RemoveInverseElement((*it));
+ }
+ int IdToRemove = (*it)->GetID();
+ int vtkid = (*it)->getVtkId();
+ //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
+ // " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
+ switch ((*it)->GetType())
+ {
+ case SMDSAbs_Node:
+ MYASSERT("Internal Error: This should not happen")
+ ;
+ break;
+ case SMDSAbs_0DElement:
+ if (IdToRemove >= 0)
+ {
+ myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
+ myInfo.remove(*it);
+ }
+ removedElems.push_back((*it));
+ myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+ delete (*it);
+ break;
+ case SMDSAbs_Edge:
+ if (IdToRemove >= 0)
+ {
+ myCells[IdToRemove] = 0;
+ myInfo.RemoveEdge(*it);
+ }
+ removedElems.push_back((*it));
+ myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+ if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
+ myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
+ else
+ delete (*it);
+ break;
+ case SMDSAbs_Face:
+ if (IdToRemove >= 0)
+ {
+ myCells[IdToRemove] = 0;
+ myInfo.RemoveFace(*it);
+ }
+ removedElems.push_back((*it));
+ myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+ if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
+ myFacePool->destroy((SMDS_VtkFace*) vtkElem);
+ else
+ delete (*it);
+ break;
+ case SMDSAbs_Volume:
+ if (IdToRemove >= 0)
+ {
+ myCells[IdToRemove] = 0;
+ myInfo.RemoveVolume(*it);
+ }
+ removedElems.push_back((*it));
+ myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+ if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
+ myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
+ else
+ delete (*it);
+ break;
+ case SMDSAbs_Ball:
+ if (IdToRemove >= 0)
+ {
+ myCells[IdToRemove] = 0;
+ myInfo.remove(*it);
+ }
+ removedElems.push_back((*it));
+ myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+ if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
+ myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
+ else
+ delete (*it);
+ break;
+ }
+ if (vtkid >= 0)
+ {
+ //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
+ this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+ }
+ it++;
+ }
+
+ // remove exclusive (free) nodes
+ if (removenodes)
+ {
+ it = s2->begin();
+ while (it != s2->end())
+ {
+ int IdToRemove = (*it)->GetID();
+ //MESSAGE( "SMDS: RM node " << IdToRemove);
+ if (IdToRemove >= 0)
+ {
+ myNodes[IdToRemove] = 0;
+ myInfo.myNbNodes--;
+ }
+ myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
+ removedNodes.push_back((*it));
+ if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
+ {
+ ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
+ myNodePool->destroy((SMDS_MeshNode*) vtkElem);
+ }
+ else
+ delete (*it);
+ it++;
+ }
+ }
+
+ delete s2;
+ delete s1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
+{
+ int elemId = elem->GetID();
+ int vtkId = elem->getVtkId();
+ //MESSAGE("RemoveFreeElement " << elemId);
+ SMDSAbs_ElementType aType = elem->GetType();
+ SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
+ if (aType == SMDSAbs_Node) {
+ //MESSAGE("Remove free node " << elemId);
+ // only free node can be removed by this method
+ const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
+ SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+ if (!itFe->more()) { // free node
+ myNodes[elemId] = 0;
+ myInfo.myNbNodes--;
+ ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
+ ((SMDS_MeshNode*) n)->SMDS_MeshElement::init( -1, -1, -1 ); // avoid reuse
+ myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+ myNodeIDFactory->ReleaseID(elemId, vtkId);
+ }
+ } else {
+ if (hasConstructionEdges() || hasConstructionFaces())
+ // this methods is only for meshes without descendants
+ return;
+
+ //MESSAGE("Remove free element " << elemId);
+ // Remove element from <InverseElements> of its nodes
+ SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+ while (itn->more()) {
+ SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>