X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMDS%2FSMDS_Mesh.cxx;h=0058da87809121f013470ed8cc9ec0f88e86e49c;hb=ebc64f68bf3d4005762eebc43354d101670dcaed;hp=93c4cf56832050cd9ba9b2691bd81d08dc316a69;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8;p=modules%2Fsmesh.git diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 93c4cf568..0058da878 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -19,23 +19,29 @@ // // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif + #include "utilities.h" #include "SMDS_Mesh.hxx" #include "SMDS_VolumeOfNodes.hxx" #include "SMDS_VolumeOfFaces.hxx" #include "SMDS_FaceOfNodes.hxx" -#include "SMDS_Tria3OfNodes.hxx" -#include "SMDS_HexahedronOfNodes.hxx" #include "SMDS_FaceOfEdges.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_PolygonalFaceOfNodes.hxx" #include +#include using namespace std; /////////////////////////////////////////////////////////////////////////////// /// Create a new mesh object /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::SMDS_Mesh() - :myNodeIDFactory(new SMDS_MeshElementIDFactory()), + :myParent(NULL), + myNodeIDFactory(new SMDS_MeshElementIDFactory()), myElementIDFactory(new SMDS_MeshElementIDFactory()), myHasConstructionEdges(false), myHasConstructionFaces(false), myHasInverseElements(true) @@ -88,7 +94,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); if(!node){ SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.insert(node); + myNodes.Add(node); myNodeIDFactory->BindID(ID,node); return node; }else @@ -139,7 +145,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, node2=const_cast(n2); node1->AddInverseElement(edge); node2->AddInverseElement(edge); - myEdges.insert(edge); + myEdges.Add(edge); return edge; } else { @@ -268,7 +274,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, if (!hasConstructionEdges()) return NULL; SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); - myFaces.insert(face); + myFaces.Add(face); if (!registerElement(ID, face)) { RemoveElement(face, false); @@ -305,7 +311,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, if (!hasConstructionEdges()) return NULL; SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); - myFaces.insert(face); + myFaces.Add(face); if (!registerElement(ID, face)) { @@ -372,7 +378,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4); SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); + myVolumes.Add(volume); } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -380,7 +386,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, } else { volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); - myVolumes.insert(volume); + myVolumes.Add(volume); } if (!registerElement(ID, volume)) { @@ -454,7 +460,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5); SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); + myVolumes.Add(volume); } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -462,7 +468,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, } else { volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5); - myVolumes.insert(volume); + myVolumes.Add(volume); } if (!registerElement(ID, volume)) { @@ -541,7 +547,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3); SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.insert(volume); + myVolumes.Add(volume); } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -549,7 +555,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, } else { volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6); - myVolumes.insert(volume); + myVolumes.Add(volume); } if (!registerElement(ID, volume)) { @@ -640,15 +646,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6); SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7); volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.insert(volume); + myVolumes.Add(volume); } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); return NULL; } else { - volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); - myVolumes.insert(volume); +// volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); + volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8); + myVolumes.Add(volume); } if (!registerElement(ID, volume)) { @@ -688,7 +695,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); + myVolumes.Add(volume); if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -729,7 +736,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.insert(volume); + myVolumes.Add(volume); if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -772,7 +779,112 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, if (!hasConstructionFaces()) return NULL; SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.insert(volume); + myVolumes.Add(volume); + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes IDs +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, + const int ID) +{ + int nbNodes = nodes_ids.size(); + std::vector nodes (nbNodes); + for (int i = 0; i < nbNodes; i++) { + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + if (!nodes[i]) return NULL; + } + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID + (std::vector nodes, + const int ID) +{ + SMDS_MeshFace * face; + + if (hasConstructionEdges()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else + { + face = new SMDS_PolygonalFaceOfNodes(nodes); + myFaces.Add(face); + } + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + +/////////////////////////////////////////////////////////////////////////////// +/// Add a polygon defined by its nodes. +/// An ID is automatically affected to the created face. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector nodes) +{ + return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @param ID The ID of the new volume +/// @return The created volume or NULL if an element with this ID already exists +/// or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID + (std::vector nodes_ids, + std::vector quantities, + const int ID) +{ + int nbNodes = nodes_ids.size(); + std::vector nodes (nbNodes); + for (int i = 0; i < nbNodes; i++) { + nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]); + if (!nodes[i]) return NULL; + } + return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @param ID The ID of the new volume +/// @return The created volume +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID + (std::vector nodes, + std::vector quantities, + const int ID) +{ + SMDS_MeshVolume* volume; + if (hasConstructionFaces()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else if (hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else { + volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); + myVolumes.Add(volume); + } if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -781,6 +893,21 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, return volume; } +/////////////////////////////////////////////////////////////////////////////// +/// Create a new polyhedral volume and add it to the mesh. +/// @return The created volume +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume + (std::vector nodes, + std::vector quantities) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); + if (v == NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + /////////////////////////////////////////////////////////////////////////////// /// Registers element with the given ID, maintains inverse connections /////////////////////////////////////////////////////////////////////////////// @@ -822,13 +949,13 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, edge3=FindEdgeOrCreate(node3,node1); SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); - myFaces.insert(face); + myFaces.Add(face); return face; } else { - SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3); - myFaces.insert(face); + SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); + myFaces.Add(face); return face; } } @@ -851,13 +978,13 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, edge4=FindEdgeOrCreate(node4,node1); SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); - myFaces.insert(face); + myFaces.Add(face); return face; } else { SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); - myFaces.insert(face); + myFaces.Add(face); return face; } } @@ -932,6 +1059,146 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) return found; } +//======================================================================= +//function : ChangeElementNodes +//purpose : +//======================================================================= + +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem, + const SMDS_MeshNode * nodes[], + const int nbnodes) +{ + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while(itn->more()) + oldNodes.insert( itn->next() ); + + // change nodes + bool Ok = false; + switch ( elem->GetType() ) + { + case SMDSAbs_Edge: { + if ( nbnodes == 2 ) { + const SMDS_MeshEdge* edge = dynamic_cast( elem ); + if ( edge ) + Ok = const_cast( edge )->ChangeNodes( nodes[0], nodes[1] ); + } + break; + } + case SMDSAbs_Face: { + const SMDS_FaceOfNodes* face = dynamic_cast( elem ); + if ( face ) { + Ok = const_cast( face )->ChangeNodes( nodes, nbnodes ); + } else { + /// ??? begin + const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + if (face) { + Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + } + /// ??? end + } + break; + } + //case SMDSAbs_PolygonalFace: { + // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem); + // if (face) { + // Ok = const_cast(face)->ChangeNodes(nodes, nbnodes); + // } + // break; + //} + case SMDSAbs_Volume: { + const SMDS_VolumeOfNodes* vol = dynamic_cast( elem ); + if ( vol ) + Ok = const_cast( vol )->ChangeNodes( nodes, nbnodes ); + break; + } + default: + MESSAGE ( "WRONG ELEM TYPE"); + } + + if ( Ok ) { // update InverseElements + + // AddInverseElement to new nodes + for ( int i = 0; i < nbnodes; i++ ) + if ( oldNodes.find( nodes[i] ) == oldNodes.end() ) + // new node + const_cast( nodes[i] )->AddInverseElement( elem ); + else + // remove from oldNodes a node that remains in elem + oldNodes.erase( nodes[i] ); + + + // RemoveInverseElement from the nodes removed from elem + set::iterator it; + for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) + { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement( elem ); + } + } + + //MESSAGE ( "::ChangeNodes() Ok = " << Ok); + + return Ok; +} + +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : to change nodes of polyhedral volume +//======================================================================= +bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + std::vector nodes, + std::vector quantities) +{ + if (elem->GetType() != SMDSAbs_Volume) { + MESSAGE("WRONG ELEM TYPE"); + return false; + } + + const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast(elem); + if (!vol) { + return false; + } + + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + oldNodes.insert(itn->next()); + } + + // change nodes + bool Ok = const_cast(vol)->ChangeNodes(nodes, quantities); + if (!Ok) { + return false; + } + + // update InverseElements + + // AddInverseElement to new nodes + int nbnodes = nodes.size(); + for (int i = 0; i < nbnodes; i++) { + if (oldNodes.find(nodes[i]) == oldNodes.end()) { + // new node + const_cast(nodes[i])->AddInverseElement(elem); + } else { + // remove from oldNodes a node that remains in elem + oldNodes.erase(nodes[i]); + } + } + + // RemoveInverseElement from the nodes removed from elem + set::iterator it; + for (it = oldNodes.begin(); it != oldNodes.end(); it++) { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement(elem); + } + + return Ok; +} //======================================================================= //function : FindEdge @@ -948,7 +1215,7 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const //#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) const + const SMDS_MeshNode * node2) { const SMDS_MeshEdge * toReturn=NULL; //PROFILER_Init(); @@ -983,7 +1250,7 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, if(toReturn==NULL) { toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.insert(toReturn); + myEdges.Add(toReturn); } return toReturn; } @@ -1006,7 +1273,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, const SMDS_MeshFace* SMDS_Mesh::FindFace( const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) const + const SMDS_MeshNode *node3) { const SMDS_MeshFace * face; const SMDS_MeshElement * node; @@ -1066,7 +1333,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace( const SMDS_MeshNode *node1, const SMDS_MeshNode *node2, const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) const + const SMDS_MeshNode *node4) { const SMDS_MeshFace * face; const SMDS_MeshElement * node; @@ -1118,6 +1385,55 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const return myElementIDFactory->MeshElement(IDelem); } +//======================================================================= +//function : FindFace +//purpose : find polygon +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes_ids) const +{ + int nbnodes = nodes_ids.size(); + std::vector poly_nodes (nbnodes); + for (int inode = 0; inode < nbnodes; inode++) { + const SMDS_MeshNode * node = FindNode(nodes_ids[inode]); + if (node == NULL) return NULL; + } + return FindFace(poly_nodes); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector nodes) +{ + int nbNodes = nodes.size(); + if (nbNodes < 1) return NULL; + + bool isFound = true; + const SMDS_MeshFace * face; + set faces; + + for (int inode = 0; inode < nbNodes && isFound; inode++) { + set new_faces; + + SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator(); + while (itF->more()) { + face = static_cast(itF->next()); + if (face->NbNodes() == nbNodes) { + if (inode == 0 || faces.find(face) != faces.end()) { + new_faces.insert(face); + } + } + } + faces = new_faces; + if (new_faces.size() == 0) { + isFound = false; + } + } + + if (isFound) + return face; + + return NULL; +} + //======================================================================= //function : DumpNodes //purpose : @@ -1221,7 +1537,7 @@ void SMDS_Mesh::DebugStats() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbNodes() const { - return myNodes.size(); + return myNodes.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1229,7 +1545,7 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myEdges.size(); + return myEdges.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1237,7 +1553,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myFaces.size(); + return myFaces.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1245,7 +1561,7 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myVolumes.size(); + return myVolumes.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1264,45 +1580,49 @@ int SMDS_Mesh::NbSubMesh() const /////////////////////////////////////////////////////////////////////////////// SMDS_Mesh::~SMDS_Mesh() { - if(myParent==NULL) - { - delete myNodeIDFactory; - delete myElementIDFactory; - } + list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + { + delete *itc; + itc++; + } - list::iterator itc=myChildren.begin(); - while(itc!=myChildren.end()) - { - delete *itc; - itc++; - } - - SMDS_NodeIteratorPtr itn=nodesIterator(); - while(itn->more()) - { - delete itn->next(); - } + SetOfNodes::Iterator itn(myNodes); + for (; itn.More(); itn.Next()) + delete itn.Value(); - set::iterator ite=myEdges.begin(); - while(ite!=myEdges.end()) - { - delete *ite; - ite++; - } + SetOfEdges::Iterator ite(myEdges); + for (; ite.More(); ite.Next()) + { + SMDS_MeshElement* elem = ite.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } - set::iterator itf=myFaces.begin(); - while(itf!=myFaces.end()) - { - delete *itf; - itf++; - } + SetOfFaces::Iterator itf(myFaces); + for (; itf.More(); itf.Next()) + { + SMDS_MeshElement* elem = itf.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } - set::iterator itv=myVolumes.begin(); - while(itv!=myVolumes.end()) - { - delete *itv; - itv++; - } + SetOfVolumes::Iterator itv(myVolumes); + for (; itv.More(); itv.Next()) + { + SMDS_MeshElement* elem = itv.Value(); + if(myParent!=NULL) + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + + if(myParent==NULL) + { + delete myNodeIDFactory; + delete myElementIDFactory; + } } /////////////////////////////////////////////////////////////////////////////// @@ -1365,71 +1685,68 @@ 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 factory /////////////////////////////////////////////////////////////////////////////// class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator { - typedef SMDS_Mesh::SetOfNodes SetOfNodes; - const SetOfNodes& mySet; - SetOfNodes::iterator myIterator; + SMDS_ElemIteratorPtr myIterator; public: - SMDS_Mesh_MyNodeIterator(const SetOfNodes& s):mySet(s) - { - myIterator=mySet.begin(); - } + SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it) + {} bool more() { - return myIterator!=mySet.end(); + return myIterator->more(); } const SMDS_MeshNode* next() { - const SMDS_MeshNode* current=*myIterator; - myIterator++; - return current; - } + return static_cast(myIterator->next()); + } }; SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const { - return SMDS_NodeIteratorPtr(new SMDS_Mesh_MyNodeIterator(myNodes)); + return SMDS_NodeIteratorPtr + (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator())); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return an iterator on elements of the current mesh factory +/////////////////////////////////////////////////////////////////////////////// +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const +{ + return myElementIDFactory->elementsIterator(); } /////////////////////////////////////////////////////////////////////////////// -///Return an iterator on volumes of the current mesh. Once used this iterator -///must be free by the caller +///Return an iterator on edges of the current mesh. /////////////////////////////////////////////////////////////////////////////// class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator { typedef SMDS_Mesh::SetOfEdges SetOfEdges; - const SetOfEdges& mySet; - const SMDS_MeshEdge * myEdge; - SetOfEdges::iterator myIterator; + SetOfEdges::Iterator myIterator; public: - SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s) - { - myIterator=mySet.begin(); - } + SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s) + {} bool more() { - while((myIterator!=mySet.end())) + while(myIterator.More()) { - if((*myIterator)->GetID()!=-1) + if(myIterator.Value()->GetID()!=-1) return true; - myIterator++; + myIterator.Next(); } return false; } const SMDS_MeshEdge* next() { - const SMDS_MeshEdge* current=*myIterator; - myIterator++; - return current; - } + const SMDS_MeshEdge* current = myIterator.Value(); + myIterator.Next(); + return current; + } }; SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const @@ -1438,37 +1755,33 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const } /////////////////////////////////////////////////////////////////////////////// -///Return an iterator on faces of the current mesh. Once used this iterator -///must be free by the caller +///Return an iterator on faces of the current mesh. /////////////////////////////////////////////////////////////////////////////// class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator { typedef SMDS_Mesh::SetOfFaces SetOfFaces; - const SetOfFaces& mySet; - SetOfFaces::iterator myIterator; + SetOfFaces::Iterator myIterator; public: - SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s) - { - myIterator=mySet.begin(); - } + SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s) + {} bool more() { - while((myIterator!=mySet.end())) + while(myIterator.More()) { - if((*myIterator)->GetID()!=-1) + if(myIterator.Value()->GetID()!=-1) return true; - myIterator++; + myIterator.Next(); } return false; } const SMDS_MeshFace* next() { - const SMDS_MeshFace* current=*myIterator; - myIterator++; - return current; - } + const SMDS_MeshFace* current = myIterator.Value(); + myIterator.Next(); + return current; + } }; SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const @@ -1477,31 +1790,27 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const } /////////////////////////////////////////////////////////////////////////////// -///Return an iterator on volumes of the current mesh. Once used this iterator -///must be free by the caller +///Return an iterator on volumes of the current mesh. /////////////////////////////////////////////////////////////////////////////// class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator { typedef SMDS_Mesh::SetOfVolumes SetOfVolumes; - const SetOfVolumes& mySet; - SetOfVolumes::iterator myIterator; + SetOfVolumes::Iterator myIterator; public: - SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s) - { - myIterator=mySet.begin(); - } + SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s) + {} bool more() { - return myIterator!=mySet.end(); + return myIterator.More() != Standard_False; } const SMDS_MeshVolume* next() { - const SMDS_MeshVolume* current=*myIterator; - myIterator++; - return current; - } + const SMDS_MeshVolume* current = myIterator.Value(); + myIterator.Next(); + return current; + } }; SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const @@ -1537,7 +1846,7 @@ static set * intersectionOfSets( static set * getFinitElements(const SMDS_MeshElement * element) { int numberOfSets=element->NbNodes(); - set initSet[numberOfSets]; + set *initSet = new set[numberOfSets]; SMDS_ElemIteratorPtr itNodes=element->nodesIterator(); @@ -1553,8 +1862,9 @@ static set * getFinitElements(const SMDS_MeshElement * i++; } - - return intersectionOfSets(initSet, numberOfSets); + set *retSet=intersectionOfSets(initSet, numberOfSets); + delete [] initSet; + return retSet; } /////////////////////////////////////////////////////////////////////////////// @@ -1670,12 +1980,13 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, list& removedElems, list& removedNodes, - const bool removenodes) + bool removenodes) { // get finite elements built on elem set * s1; if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || - !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face) + !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face || + elem->GetType() == SMDSAbs_Volume) { s1 = new set(); s1->insert(elem); @@ -1685,10 +1996,12 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, // get exclusive nodes (which would become free afterwards) set * s2; - if (s1->empty() && elem->GetType() == SMDSAbs_Node) + if (elem->GetType() == SMDSAbs_Node) // a node is removed { + // do not remove nodes except elem s2 = new set(); s2->insert(elem); + removenodes = true; } else s2 = getExclusiveNodes(*s1); @@ -1723,15 +2036,15 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, MESSAGE("Internal Error: This should not happen"); break; case SMDSAbs_Edge: - myEdges.erase(static_cast + myEdges.Remove(static_cast (const_cast(*it))); break; case SMDSAbs_Face: - myFaces.erase(static_cast + myFaces.Remove(static_cast (const_cast(*it))); break; case SMDSAbs_Volume: - myVolumes.erase(static_cast + myVolumes.Remove(static_cast (const_cast(*it))); break; } @@ -1749,7 +2062,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, while(it!=s2->end()) { //MESSAGE( "SMDS: RM node " << (*it)->GetID() ); - myNodes.erase(static_cast + myNodes.Remove(static_cast (const_cast(*it))); myNodeIDFactory->ReleaseID((*it)->GetID()); removedNodes.push_back( (*it) ); @@ -1788,3 +2101,81 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const return true; return false; } + +//======================================================================= +//function : MaxNodeID +//purpose : +//======================================================================= + +int SMDS_Mesh::MaxNodeID() const +{ + return myNodeIDFactory->GetMaxID(); +} + +//======================================================================= +//function : MinNodeID +//purpose : +//======================================================================= + +int SMDS_Mesh::MinNodeID() const +{ + return myNodeIDFactory->GetMinID(); +} + +//======================================================================= +//function : MaxElementID +//purpose : +//======================================================================= + +int SMDS_Mesh::MaxElementID() const +{ + return myElementIDFactory->GetMaxID(); +} + +//======================================================================= +//function : MinElementID +//purpose : +//======================================================================= + +int SMDS_Mesh::MinElementID() const +{ + return myElementIDFactory->GetMinID(); +} + +//======================================================================= +//function : Renumber +//purpose : Renumber all nodes or elements. +//======================================================================= + +void SMDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) +{ + if ( deltaID == 0 ) + return; + + SMDS_MeshElementIDFactory * idFactory = + isNodes ? myNodeIDFactory : myElementIDFactory; + + // get existing elements in the order of ID increasing + map elemMap; + SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator(); + while ( idElemIt->more() ) { + SMDS_MeshElement* elem = const_cast(idElemIt->next()); + int id = elem->GetID(); + elemMap.insert(map::value_type(id, elem)); + } + // release their ids + map::iterator elemIt = elemMap.begin(); + for ( ; elemIt != elemMap.end(); elemIt++ ) + { + int id = (*elemIt).first; + idFactory->ReleaseID( id ); + } + // set new IDs + int ID = startID; + elemIt = elemMap.begin(); + for ( ; elemIt != elemMap.end(); elemIt++ ) + { + idFactory->BindID( ID, (*elemIt).second ); + ID += deltaID; + } +}