// SMESH SMDS : implementaion of Salome mesh data structure // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org // // // // File : SMDS_Mesh.cxx // Author : Jean-Michel BOULCOURT // Module : SMESH using namespace std; #include "SMDS_Mesh.ixx" #include "SMDS_MapIteratorOfExtendedOrientedMap.hxx" #include "SMDS_ListOfMeshElement.hxx" #include "SMDS_ListIteratorOfListOfMeshElement.hxx" #include "SMDS_MeshNode.hxx" #include "SMDS_MeshEdge.hxx" #include "SMDS_MeshFace.hxx" #include "SMDS_MeshTriangle.hxx" #include "SMDS_MeshQuadrangle.hxx" #include "SMDS_MeshVolume.hxx" #include "SMDS_MeshTetrahedron.hxx" #include "SMDS_MeshPyramid.hxx" #include "SMDS_MeshPrism.hxx" #include "SMDS_MeshHexahedron.hxx" #include "SMDS_ListOfMesh.hxx" #include "SMDS_ListIteratorOfListOfMesh.hxx" #include #include #include "utilities.h" //======================================================================= //function : SMDS_Mesh //purpose : creation of a new mesh object //======================================================================= SMDS_Mesh::SMDS_Mesh(const Standard_Integer nbnodes, const Standard_Integer nbedges, const Standard_Integer nbfaces, const Standard_Integer nbvolumes) :myNodes(nbnodes),myEdges(nbedges),myFaces(nbfaces),myVolumes(nbvolumes), myNodeIDFactory(new SMDS_MeshNodeIDFactory()), myElementIDFactory(new SMDS_MeshElementIDFactory()),myHasInverse(Standard_False) { } //======================================================================= //function : SMDS_Mesh //purpose : //======================================================================= SMDS_Mesh::SMDS_Mesh(const Handle(SMDS_Mesh)& parent, const Standard_Integer nbnodes) :myNodes(nbnodes),myParent(parent),myNodeIDFactory(parent->myNodeIDFactory), myElementIDFactory(parent->myElementIDFactory), myHasInverse(Standard_False) { } //======================================================================= //function : AddSubMesh //purpose : create an submesh //======================================================================= Handle(SMDS_Mesh) SMDS_Mesh::AddSubMesh() { Handle(SMDS_Mesh) submesh = new SMDS_Mesh(this); if (!submesh.IsNull()) { myChildren.Append(submesh); } return submesh; } //======================================================================= //function : AddNode //purpose : create a MeshNode and returns an ID //======================================================================= Standard_Integer SMDS_Mesh::AddNode(const Standard_Real x, const Standard_Real y, const Standard_Real z) { Standard_Integer ID = myNodeIDFactory->GetFreeID(); Handle(SMDS_MeshElement) node = new SMDS_MeshNode(ID,x,y,z); AddNode(node); return ID; } //======================================================================= //function : AddNode //purpose : create a MeshNode. Returns False if the ID already exists //======================================================================= Standard_Boolean SMDS_Mesh::AddNodeWithID(const Standard_Real x, const Standard_Real y, const Standard_Real z, const Standard_Integer ID) { // find the MeshNode corresponding to ID Handle(SMDS_MeshElement) node; node = GetNode(ID); if (node.IsNull()) { node = new SMDS_MeshNode(ID,x,y,z); AddNode(node); return Standard_True; } else return Standard_False; } //======================================================================= //function : AddNode //purpose : add an existing node in the mesh (useful for submesh) //======================================================================= Standard_Boolean SMDS_Mesh::AddNode(const Standard_Integer ID) { // find the MeshNode corresponding to ID Handle(SMDS_MeshElement) node; node = GetNode(ID); if (!node.IsNull()) { myNodes.Add(node); return Standard_True;; } else return Standard_False; } //======================================================================= //function : AddNode //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::AddNode(const Handle(SMDS_MeshElement)& node) { if (!node.IsNull()) { myNodes.Add(node); if (!myParent.IsNull()) { myParent->AddNode(node); } return Standard_True; } else return Standard_False; } //======================================================================= //function : AddEdge //purpose : //======================================================================= Standard_Integer SMDS_Mesh::AddEdge(const Standard_Integer idnode1, const Standard_Integer idnode2) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddEdgeWithID(idnode1,idnode2,ID)) return ID; else return 0; } //======================================================================= //function : AddEdge //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::AddEdgeWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer ID) { Handle(SMDS_MeshElement) edge,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { elem = CreateEdge(ID,idnode1,idnode2); edge = FindEdge(elem); if (edge.IsNull()) { edge = elem; myEdges.Add(edge); } successAdd = myElementIDFactory->BindID(ID,edge); } } return successAdd; } //======================================================================= //function : AddFace //purpose : //======================================================================= Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddFaceWithID(idnode1,idnode2,idnode3,ID)) return ID; else return 0; } //======================================================================= //function : AddFace //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer ID) { Handle(SMDS_MeshElement) face,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { elem = CreateFace(ID,idnode1,idnode2,idnode3); face = FindFace(elem); if (face.IsNull()) { face = elem; myFaces.Add(face); } successAdd = myElementIDFactory->BindID(ID,face); } } } return successAdd; } //======================================================================= //function : AddFace //purpose : //======================================================================= Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddFaceWithID(idnode1,idnode2,idnode3,idnode4,ID)) return ID; else return 0; } //======================================================================= //function : AddFace //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer ID) { Handle(SMDS_MeshElement) face,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { // find the MeshNode corresponding to idnode4 if (AddNode(idnode4)) { elem = CreateFace(ID,idnode1,idnode2,idnode3,idnode4); face = FindFace(elem); if (face.IsNull()) { face = elem; myFaces.Add(face); } successAdd = myElementIDFactory->BindID(ID,face); } } } } return successAdd; } //======================================================================= //function : AddVolume //purpose : Tetrahedra //======================================================================= Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,ID)) return ID; else return 0; } //======================================================================= //function : AddVolume //purpose : Tetrahedra //======================================================================= Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer ID) { Handle(SMDS_MeshElement) volume,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { // find the MeshNode corresponding to idnode4 if (AddNode(idnode4)) { elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4); volume = FindVolume(elem); if (volume.IsNull()) { volume = elem; myVolumes.Add(volume); } successAdd = myElementIDFactory->BindID(ID,volume); } } } } return successAdd; } //======================================================================= //function : AddVolume //purpose : Pyramid //======================================================================= Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,idnode5,ID)) return ID; else return 0; } //======================================================================= //function : AddVolume //purpose : Pyramid //======================================================================= Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer ID) { Handle(SMDS_MeshElement) volume,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { // find the MeshNode corresponding to idnode4 if (AddNode(idnode4)) { // find the MeshNode corresponding to idnode5 if (AddNode(idnode5)) { elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5); volume = FindVolume(elem); if (volume.IsNull()) { volume = elem; myVolumes.Add(volume); } successAdd = myElementIDFactory->BindID(ID,volume); } } } } } return successAdd; } //======================================================================= //function : AddVolume //purpose : Prism //======================================================================= Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4, idnode5,idnode6,ID)) return ID; else return 0; } //======================================================================= //function : AddVolume //purpose : Prism //======================================================================= Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6, const Standard_Integer ID) { Handle(SMDS_MeshElement) volume,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { // find the MeshNode corresponding to idnode4 if (AddNode(idnode4)) { // find the MeshNode corresponding to idnode5 if (AddNode(idnode5)) { // find the MeshNode corresponding to idnode6 if (AddNode(idnode6)) { elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6); volume = FindVolume(elem); if (volume.IsNull()) { volume = elem; myVolumes.Add(volume); } successAdd = myElementIDFactory->BindID(ID,volume); } } } } } } return successAdd; } //======================================================================= //function : AddVolume //purpose : Hexahedra //======================================================================= Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6, const Standard_Integer idnode7, const Standard_Integer idnode8) { Standard_Integer ID = myElementIDFactory->GetFreeID(); if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4, idnode5,idnode6,idnode7,idnode8,ID)) return ID; else return 0; } //======================================================================= //function : AddVolume //purpose : Hexahedra //======================================================================= Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6, const Standard_Integer idnode7, const Standard_Integer idnode8, const Standard_Integer ID) { Handle(SMDS_MeshElement) volume,elem; Standard_Boolean successAdd = Standard_False; // find the MeshNode corresponding to idnode1 if (AddNode(idnode1)) { // find the MeshNode corresponding to idnode2 if (AddNode(idnode2)) { // find the MeshNode corresponding to idnode3 if (AddNode(idnode3)) { // find the MeshNode corresponding to idnode4 if (AddNode(idnode4)) { // find the MeshNode corresponding to idnode5 if (AddNode(idnode5)) { // find the MeshNode corresponding to idnode6 if (AddNode(idnode6)) { // find the MeshNode corresponding to idnode7 if (AddNode(idnode7)) { // find the MeshNode corresponding to idnode8 if (AddNode(idnode8)) { elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5, idnode6,idnode7,idnode8); volume = FindVolume(elem); if (volume.IsNull()) { volume = elem; myVolumes.Add(volume); } successAdd = myElementIDFactory->BindID(ID,volume); } } } } } } } } return successAdd; } //======================================================================= //function : GetNode //purpose : returns the MeshNode corresponding to the ID //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::GetNode(const Standard_Integer idnode) const { Handle(SMDS_MeshElement) node; Handle(SMDS_MeshElement) elem = FindNode(idnode); if (!elem.IsNull()) { // found one correspondance node = elem; } else { if (!myParent.IsNull()) node = myParent->GetNode(idnode); } return node; } //======================================================================= //function : FindNode //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Standard_Integer ID) const { Handle(SMDS_MeshElement) elem; if (myNodes.ContainsID(ID)) elem = myNodes.FindID(ID); return elem; } //======================================================================= //function : FindNode //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Handle(SMDS_MeshElement)& node) const { Handle(SMDS_MeshElement) elem; if (myNodes.Contains(node)) elem = myNodes.Find(node); return elem; } //======================================================================= //function : CreateEdge //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateEdge(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2) const { Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(ID,idnode1,idnode2); return edge; } //======================================================================= //function : CreateFace //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3) const { Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(ID,idnode1,idnode2,idnode3); return face; } //======================================================================= //function : CreateFace //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4) const { Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(ID,idnode1,idnode2,idnode3,idnode4); return face; } //======================================================================= //function : CreateVolume //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4) const { Handle(SMDS_MeshVolume) volume = new SMDS_MeshTetrahedron(ID,idnode1,idnode2,idnode3,idnode4); return volume; } //======================================================================= //function : CreateVolume //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5) const { Handle(SMDS_MeshVolume) volume = new SMDS_MeshPyramid(ID,idnode1,idnode2,idnode3,idnode4,idnode5); return volume; } //======================================================================= //function : CreateVolume //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6) const { Handle(SMDS_MeshVolume) volume = new SMDS_MeshPrism(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6); return volume; } //======================================================================= //function : CreateVolume //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID, const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4, const Standard_Integer idnode5, const Standard_Integer idnode6, const Standard_Integer idnode7, const Standard_Integer idnode8) const { Handle(SMDS_MeshVolume) volume = new SMDS_MeshHexahedron(ID,idnode1,idnode2,idnode3,idnode4, idnode5,idnode6,idnode7,idnode8); return volume; } //======================================================================= //function : Contains //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::Contains(const Handle(SMDS_MeshElement)& elem) const { Standard_Boolean isinmesh = Standard_False; if (myNodes.Contains(elem)) isinmesh = Standard_True; else if (myEdges.Contains(elem)) isinmesh = Standard_True; else if (myFaces.Contains(elem)) isinmesh = Standard_True; else if (myVolumes.Contains(elem)) isinmesh = Standard_True; return isinmesh; } //======================================================================= //function : FindEdge //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Handle(SMDS_MeshElement)& edge) const { Handle(SMDS_MeshElement) elem; if (myEdges.Contains(edge)) elem = myEdges.Find(edge); return elem; } //======================================================================= //function : FindFace //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Handle(SMDS_MeshElement)& face) const { Handle(SMDS_MeshElement) elem; if (myFaces.Contains(face)) elem = myFaces.Find(face); return elem; } //======================================================================= //function : FindVolume //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindVolume(const Handle(SMDS_MeshElement)& volume) const { Handle(SMDS_MeshElement) elem; if (myVolumes.Contains(volume)) elem = myVolumes.Find(volume); return elem; } //======================================================================= //function : FreeNode //purpose : //======================================================================= void SMDS_Mesh::FreeNode(const Handle(SMDS_MeshElement)& node) { myNodes.Remove(node); SMDS_ListIteratorOfListOfMesh itmsh(myChildren); for (;itmsh.More(); itmsh.Next()) { const Handle(SMDS_Mesh)& submesh = itmsh.Value(); submesh->RemoveNode(node->GetID()); } } //======================================================================= //function : RemoveNode //purpose : //======================================================================= void SMDS_Mesh::RemoveNode(const Standard_Integer IDnode) { // find the MeshNode corresponding to IDnode Handle(SMDS_MeshElement) node = FindNode(IDnode); if (RemoveNode(node)) { if (myParent.IsNull()) { // if no parent we can release the ID myNodeIDFactory->ReleaseID(IDnode); } } } //======================================================================= //function : RemoveNode //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::RemoveNode(const Handle(SMDS_MeshElement)& node) { Standard_Boolean successRemove = Standard_False; if (!node.IsNull()) { if (myHasInverse && myNodes.Contains(node)) { SMDS_MapOfMeshOrientedElement map(1); BuildMapNodeAncestors(node,map); RemoveAncestors(node,map); } FreeNode(node); successRemove = Standard_True; } return successRemove; } //======================================================================= //function : RemoveEdge //purpose : //======================================================================= void SMDS_Mesh::RemoveEdge(const Standard_Integer idnode1, const Standard_Integer idnode2) { Handle(SMDS_MeshElement) edge = FindEdge(idnode1,idnode2); RemoveEdge(edge); } //======================================================================= //function : RemoveEdge //purpose : //======================================================================= void SMDS_Mesh::RemoveEdge(const Handle(SMDS_MeshElement)& edge) { if (!edge.IsNull()) { myEdges.Remove(edge); myElementIDFactory->ReleaseID(edge->GetID()); } } //======================================================================= //function : RemoveFace //purpose : //======================================================================= void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3) { Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3); RemoveFace(face); } //======================================================================= //function : RemoveFace //purpose : //======================================================================= void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4) { Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3,idnode4); RemoveFace(face); } //======================================================================= //function : RemoveFace //purpose : //======================================================================= void SMDS_Mesh::RemoveFace(const Handle(SMDS_MeshElement)& face) { if (!face.IsNull()) { myFaces.Remove(face); myElementIDFactory->ReleaseID(face->GetID()); } } //======================================================================= //function : RemoveVolume //purpose : //======================================================================= void SMDS_Mesh::RemoveVolume(const Handle(SMDS_MeshElement)& volume) { if (myVolumes.Contains(volume)) { myVolumes.Remove(volume); myElementIDFactory->ReleaseID(volume->GetID()); } } //======================================================================= //function : RemoveElement //purpose : //======================================================================= void SMDS_Mesh::RemoveElement(const Standard_Integer IDelem,const Standard_Boolean removenodes) { Handle(SMDS_MeshElement) elem = myElementIDFactory->MeshElement(IDelem); RemoveElement(elem,removenodes); } //======================================================================= //function : RemoveElement //purpose : //======================================================================= void SMDS_Mesh::RemoveElement(const Handle(SMDS_MeshElement)& elem,const Standard_Boolean removenodes) { if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) ) { RemoveEdge(elem); } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshNode))) { RemoveNode(elem); return; } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshFace))) { RemoveFace(elem); } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshVolume))) { RemoveVolume(elem); } else { MESSAGE( "remove function : unknown type" ); return; } Standard_Integer nbcnx = elem->NbNodes(); Standard_Integer i; for (i=1; i <= nbcnx; ++i) { RemoveInverseElement(GetNode(i,elem),elem); } if (removenodes) { for (i=1; i <= nbcnx; ++i) { if (GetNode(i,elem)->InverseElements().IsEmpty()) FreeNode(GetNode(i,elem)); } } } //======================================================================= //function : RemoveFromParent //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::RemoveFromParent() { if (myParent.IsNull()) return Standard_False; return (myParent->RemoveSubMesh(this)); } //======================================================================= //function : RemoveSubMesh //purpose : //======================================================================= Standard_Boolean SMDS_Mesh::RemoveSubMesh(const Handle(SMDS_Mesh)& aMesh) { Standard_Boolean found = Standard_False; SMDS_ListIteratorOfListOfMesh itmsh(myChildren); for (;itmsh.More() && !found; itmsh.Next()) { Handle(SMDS_Mesh) submesh; submesh = itmsh.Value(); if (submesh == aMesh) { found = Standard_True; myChildren.Remove(itmsh); } } return found; } //======================================================================= //function : RemoveInverseElement //purpose : //======================================================================= void SMDS_Mesh::RemoveInverseElement(const Handle(SMDS_MeshElement)& elem, const Handle(SMDS_MeshElement)& parent) const { if (!myHasInverse) return; Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem); node->RemoveInverseElement(parent); } //======================================================================= //function : RemoveAncestors //purpose : //======================================================================= void SMDS_Mesh::RemoveAncestors(const Handle(SMDS_MeshElement)& elem, const SMDS_MapOfMeshOrientedElement& map) { if (!myHasInverse) return; SMDS_MapIteratorOfExtendedOrientedMap itAnc(map); for (;itAnc.More();itAnc.Next()) { const Handle(SMDS_MeshElement)& ME = itAnc.Key(); Standard_Integer nbcnx = ME->NbNodes(); for (Standard_Integer i=1; i <= nbcnx; ++i) { RemoveInverseElement(GetNode(i,ME),ME); } } SMDS_MapIteratorOfExtendedOrientedMap itAnc2(map); for (;itAnc2.More();itAnc2.Next()) { const Handle(SMDS_MeshElement)& ME = itAnc2.Key(); RemoveElement(ME); } } //======================================================================= //function : BuildMapNodeAncestors //purpose : //======================================================================= void SMDS_Mesh::BuildMapNodeAncestors(const Handle(SMDS_MeshElement)& ME, SMDS_MapOfMeshOrientedElement& map) const { if (!myHasInverse) return; Standard_Integer nbcnx = ME->NbNodes(); for (Standard_Integer i=1; i <= nbcnx; ++i) { const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); for (;it.More();it.Next()) { const Handle(SMDS_MeshElement)& meParent = it.Value(); if (Contains(meParent)) map.Add(meParent); } } } //======================================================================= //function : BuildMapEdgeAncestors //purpose : //======================================================================= void SMDS_Mesh::BuildMapEdgeAncestors(const Handle(SMDS_MeshElement)& ME, SMDS_MapOfMeshOrientedElement& map) const { if (!myHasInverse) return; Standard_Integer nbcnx = ME->NbNodes(); for (Standard_Integer i=1; i <= nbcnx; ++i) { const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); for (;it.More();it.Next()) { const Handle(SMDS_MeshElement)& meParent = it.Value(); if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) && Contains(meParent)) map.Add(meParent); } } } //======================================================================= //function : BuildMapFaceAncestors //purpose : //======================================================================= void SMDS_Mesh::BuildMapFaceAncestors(const Handle(SMDS_MeshElement)& ME, SMDS_MapOfMeshOrientedElement& map) const { if (!myHasInverse) return; Standard_Integer nbcnx = ME->NbNodes(); for (Standard_Integer i=1; i <= nbcnx; ++i) { const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements(); SMDS_ListIteratorOfListOfMeshElement it(lstInvElements); for (;it.More();it.Next()) { const Handle(SMDS_MeshElement)& meParent = it.Value(); if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) && ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshFace))) && Contains(meParent) ) map.Add(meParent); } } } //======================================================================= //function : FindEdge //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Standard_Integer idnode1, const Standard_Integer idnode2 ) const { Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(0,idnode1,idnode2); return FindEdge(edge); } //======================================================================= //function : FindFace //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3 ) const { Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(0,idnode1,idnode2,idnode3); return FindFace(face); } //======================================================================= //function : FindFace //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1, const Standard_Integer idnode2, const Standard_Integer idnode3, const Standard_Integer idnode4 ) const { Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(0,idnode1,idnode2,idnode3,idnode4); return FindFace(face); } //======================================================================= //function : FindElement //purpose : //======================================================================= Handle(SMDS_MeshElement) SMDS_Mesh::FindElement(const Standard_Integer IDelem) const { return myElementIDFactory->MeshElement(IDelem); } //======================================================================= //function : GetNode //purpose : //======================================================================= Handle(SMDS_MeshNode) SMDS_Mesh::GetNode(const Standard_Integer rank, const Handle(SMDS_MeshElement)& ME) const { const Standard_Integer idnode = ME->GetConnection(rank); // take care, no control of bounds Handle(SMDS_MeshElement) elem = FindNode(idnode); Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem); return node; } //======================================================================= //function : DumpNodes //purpose : //======================================================================= void SMDS_Mesh::DumpNodes() const { MESSAGE( "dump nodes of mesh : " ); SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); for (;itnode.More();itnode.Next()) { const Handle(SMDS_MeshElement)& node = itnode.Key(); MESSAGE( node); } } //======================================================================= //function : DumpEdges //purpose : //======================================================================= void SMDS_Mesh::DumpEdges() const { MESSAGE( "dump edges of mesh : " ); SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges); for (;itedge.More();itedge.Next()) { const Handle(SMDS_MeshElement)& edge = itedge.Key(); MESSAGE( edge); } } //======================================================================= //function : DumpFaces //purpose : //======================================================================= void SMDS_Mesh::DumpFaces() const { MESSAGE( "dump faces of mesh : " ); SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces); for (;itface.More();itface.Next()) { const Handle(SMDS_MeshElement)& face = itface.Key(); MESSAGE( face); } } //======================================================================= //function : DumpVolumes //purpose : //======================================================================= void SMDS_Mesh::DumpVolumes() const { MESSAGE( "dump volumes of mesh : " ); SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes); for (;itvol.More();itvol.Next()) { const Handle(SMDS_MeshElement)& volume = itvol.Key(); MESSAGE( volume); } } //======================================================================= //function : DebugStats //purpose : //======================================================================= void SMDS_Mesh::DebugStats() const { //VRV: T2.4 impossible to use Logger server MESSAGE( "Debug stats of mesh : " ); MESSAGE( "===== NODES =====" ); myNodes.Statistics(cout); MESSAGE( "===== EDGES =====" ); myEdges.Statistics(cout); MESSAGE( "===== FACES =====" ); myFaces.Statistics(cout); MESSAGE( "===== VOLUMES =====" ); myVolumes.Statistics(cout); //VRV: T2.4 impossible to use Logger server MESSAGE( "End Debug stats of mesh " ); //#ifdef DEB SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); Standard_Integer sizeofnodes = 0; Standard_Integer sizeoffaces = 0; for (;itnode.More();itnode.Next()) { const Handle(SMDS_MeshElement)& node = itnode.Key(); Standard_Transient *p = node->This(); sizeofnodes += sizeof( *((SMDS_MeshNode *)p) ); SMDS_ListIteratorOfListOfMeshElement it(node->InverseElements()); for (;it.More();it.Next()) { const Handle(SMDS_MeshElement)& me = it.Value(); sizeofnodes += sizeof(me); } } SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces); for (;itface.More();itface.Next()) { const Handle(SMDS_MeshElement)& face = itface.Key(); Standard_Transient *p = face->This(); sizeoffaces += sizeof( *((SMDS_MeshFace *)p) ); } MESSAGE( "total size of node elements = " << sizeofnodes );; MESSAGE( "total size of face elements = " << sizeoffaces );; //#endif } //======================================================================= //function : RebuildAllInverseConnections //purpose : //======================================================================= void SMDS_Mesh::RebuildAllInverseConnections() { if (!myParent.IsNull()) myParent->RebuildAllInverseConnections(); else { // Clear all inverseconnections from nodes SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes); for (;itnode.More();itnode.Next()) { const Handle(SMDS_MeshElement)& elem = itnode.Key(); elem->ClearInverseElements(); } RebuildInverseConnections(); SMDS_ListIteratorOfListOfMesh itmsh(myChildren); for (;itmsh.More(); itmsh.Next()) { Handle(SMDS_Mesh) submesh; submesh = itmsh.Value(); submesh->RebuildInverseConnections(); } } } //======================================================================= //function : RebuildInverseConnections //purpose : //======================================================================= void SMDS_Mesh::RebuildInverseConnections() { // rebuld inverse connections to volumes SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes); for (;itvol.More();itvol.Next()) { const Handle(SMDS_MeshElement)& vol = itvol.Key(); Standard_Integer nbcnx = vol->NbNodes(); for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { Standard_Integer idnode = vol->GetConnection(inode); Handle(SMDS_MeshElement) node = FindNode(idnode); if (!node.IsNull()) node->AddInverseElement(vol); } } // rebuld inverse connections to faces SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces); for (;itface.More();itface.Next()) { const Handle(SMDS_MeshElement)& face = itface.Key(); Standard_Integer nbcnx = face->NbNodes(); for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { Standard_Integer idnode = face->GetConnection(inode); Handle(SMDS_MeshElement) node = FindNode(idnode); if (!node.IsNull()) node->AddInverseElement(face); } } // rebuld inverse connections to edges SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges); for (;itedge.More();itedge.Next()) { const Handle(SMDS_MeshElement)& edge = itedge.Key(); Standard_Integer nbcnx = edge->NbNodes(); for (Standard_Integer inode=1; inode<=nbcnx; ++inode) { Standard_Integer idnode = edge->GetConnection(inode); Handle(SMDS_MeshElement) node = FindNode(idnode); if (!node.IsNull()) node->AddInverseElement(edge); } } myHasInverse = Standard_True; } //======================================================================= //function : SubMeshIterator //purpose : returns the ith SubMesh //======================================================================= void SMDS_Mesh::SubMeshIterator(SMDS_ListIteratorOfListOfMesh& itmsh) const { itmsh.Initialize(myChildren); }