X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMDS%2FSMDS_Mesh.cxx;h=e8d8af69741b1a6fca138db954aaab98cda10f2c;hb=aa5c100cf71c5a37f71c1ed3b66215e00fa95973;hp=93c4cf56832050cd9ba9b2691bd81d08dc316a69;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8;p=modules%2Fsmesh.git diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 93c4cf568..e8d8af697 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1,41 +1,110 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// // 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 +#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 "SMDS_QuadraticEdge.hxx" +#include "SMDS_QuadraticFaceOfNodes.hxx" +#include "SMDS_QuadraticVolumeOfNodes.hxx" #include +#include using namespace std; +#ifndef WIN32 +#include +#endif + +// number of added entitis to check memory after +#define CHECKMEMORY_INTERVAL 1000 + +//================================================================================ +/*! + * \brief Raise an exception if free memory (ram+swap) too low + * \param doNotRaise - if true, suppres exception, just return free memory size + * \retval int - amount of available memory in MB or negative number in failure case + */ +//================================================================================ + +int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) +{ +#ifndef WIN32 + struct sysinfo si; + int err = sysinfo( &si ); + if ( err ) + return -1; + + static int limit = -1; + if ( limit < 0 ) { + int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM + if (status >= 0 ) { + limit = WEXITSTATUS(status); + } + if ( limit < 20 ) + limit = 20; + else + limit = int( limit * 1.5 ); +#ifdef _DEBUG_ + MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" ); +#endif + } + + const unsigned long Mbyte = 1024 * 1024; + // compute separately to avoid overflow + int freeMb = + ( si.freeram * si.mem_unit ) / Mbyte + + ( si.freeswap * si.mem_unit ) / Mbyte; + + if ( freeMb > limit ) + return freeMb - limit; + + if ( doNotRaise ) + return 0; +#ifdef _DEBUG_ + MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" ); +#endif + throw std::bad_alloc(); +#else + return -1; +#endif +} + /////////////////////////////////////////////////////////////////////////////// /// 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) @@ -87,9 +156,11 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) // find the MeshNode corresponding to ID const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID); if(!node){ + if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z); - myNodes.insert(node); + myNodes.Add(node); myNodeIDFactory->BindID(ID,node); + myInfo.myNbNodes++; return node; }else return NULL; @@ -132,6 +203,10 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n2, int ID) { + if ( !n1 || !n2 ) return 0; + + if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2); if(myElementIDFactory->BindID(ID, edge)) { SMDS_MeshNode *node1,*node2; @@ -139,7 +214,8 @@ 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); + myInfo.myNbEdges++; return edge; } else { @@ -184,7 +260,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, { SMDS_MeshFace * face=createTriangle(n1, n2, n3); - if (!registerElement(ID, face)) { + if (face && !registerElement(ID, face)) { RemoveElement(face, false); face = NULL; } @@ -235,7 +311,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, { SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4); - if (!registerElement(ID, face)) { + if (face && !registerElement(ID, face)) { RemoveElement(face, false); face = NULL; } @@ -267,8 +343,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; + if ( !e1 || !e2 || !e3 ) return 0; + + if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); - myFaces.insert(face); + myFaces.Add(face); + myInfo.myNbTriangles++; if (!registerElement(ID, face)) { RemoveElement(face, false); @@ -304,8 +385,11 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, { if (!hasConstructionEdges()) return NULL; + if ( !e1 || !e2 || !e3 || !e4 ) return 0; + if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); - myFaces.insert(face); + myFaces.Add(face); + myInfo.myNbQuadrangles++; if (!registerElement(ID, face)) { @@ -365,14 +449,17 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n4, int ID) { - SMDS_MeshVolume* volume; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4) return volume; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); 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); + myInfo.myNbTetras++; } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -380,7 +467,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, } else { volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4); - myVolumes.insert(volume); + myVolumes.Add(volume); + myInfo.myNbTetras++; } if (!registerElement(ID, volume)) { @@ -447,14 +535,17 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n5, int ID) { - SMDS_MeshVolume* volume; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); 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); + myInfo.myNbPyramids++; } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -462,7 +553,8 @@ 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); + myInfo.myNbPyramids++; } if (!registerElement(ID, volume)) { @@ -533,7 +625,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n6, int ID) { - SMDS_MeshVolume* volume; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); @@ -541,7 +635,8 @@ 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); + myInfo.myNbPrisms++; } else if(hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -549,7 +644,8 @@ 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); + myInfo.myNbPrisms++; } if (!registerElement(ID, volume)) { @@ -631,7 +727,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8, int ID) { - SMDS_MeshVolume* volume; + SMDS_MeshVolume* volume = 0; + if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); @@ -640,15 +738,18 @@ 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); + myInfo.myNbHexas++; } 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); + myInfo.myNbHexas++; } if (!registerElement(ID, volume)) { @@ -687,8 +788,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, { if (!hasConstructionFaces()) return NULL; + if ( !f1 || !f2 || !f3 || !f4) return 0; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); - myVolumes.insert(volume); + myVolumes.Add(volume); + myInfo.myNbTetras++; if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -728,8 +832,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, { if (!hasConstructionFaces()) return NULL; + if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); - myVolumes.insert(volume); + myVolumes.Add(volume); + myInfo.myNbPyramids++; if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -771,8 +878,124 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, { if (!hasConstructionFaces()) return NULL; + if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0; + if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); - myVolumes.insert(volume); + myVolumes.Add(volume); + myInfo.myNbPrisms++; + + 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 ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if (hasConstructionEdges()) + { + MESSAGE("Error : Not implemented"); + return NULL; + } + else + { + for ( int i = 0; i < nodes.size(); ++i ) + if ( !nodes[ i ] ) return 0; + face = new SMDS_PolygonalFaceOfNodes(nodes); + myFaces.Add(face); + myInfo.myNbPolygons++; + } + + 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 ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if (hasConstructionFaces()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else if (hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } else { + for ( int i = 0; i < nodes.size(); ++i ) + if ( !nodes[ i ] ) return 0; + volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities); + myVolumes.Add(volume); + myInfo.myNbPolyhedrons++; + } if (!registerElement(ID, volume)) { RemoveElement(volume, false); @@ -781,6 +1004,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 /////////////////////////////////////////////////////////////////////////////// @@ -814,23 +1052,27 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2, const SMDS_MeshNode * node3) { - if(hasConstructionEdges()) - { - SMDS_MeshEdge *edge1, *edge2, *edge3; - edge1=FindEdgeOrCreate(node1,node2); - edge2=FindEdgeOrCreate(node2,node3); - edge3=FindEdgeOrCreate(node3,node1); - - SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); - myFaces.insert(face); - return face; - } - else - { - SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3); - myFaces.insert(face); - return face; - } + if ( !node1 || !node2 || !node3) return 0; + if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node1); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3); + myFaces.Add(face); + myInfo.myNbTriangles++; + return face; + } + else + { + SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3); + myFaces.Add(face); + myInfo.myNbTriangles++; + return face; + } } /////////////////////////////////////////////////////////////////////////////// @@ -842,24 +1084,28 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, const SMDS_MeshNode * node3, const SMDS_MeshNode * node4) { - if(hasConstructionEdges()) - { - SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; - edge1=FindEdgeOrCreate(node1,node2); - edge2=FindEdgeOrCreate(node2,node3); - edge3=FindEdgeOrCreate(node3,node4); - edge4=FindEdgeOrCreate(node4,node1); - - SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); - myFaces.insert(face); - return face; - } - else - { - SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); - myFaces.insert(face); - return face; - } + if ( !node1 || !node2 || !node3 || !node4 ) return 0; + if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionEdges()) + { + SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4; + edge1=FindEdgeOrCreate(node1,node2); + edge2=FindEdgeOrCreate(node2,node3); + edge3=FindEdgeOrCreate(node3,node4); + edge4=FindEdgeOrCreate(node4,node1); + + SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4); + myFaces.Add(face); + myInfo.myNbQuadrangles++; + return face; + } + else + { + SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4); + myFaces.Add(face); + myInfo.myNbQuadrangles++; + return face; + } } /////////////////////////////////////////////////////////////////////////////// @@ -932,6 +1178,149 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) return found; } +//======================================================================= +//function : ChangeElementNodes +//purpose : +//======================================================================= + +bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, + const SMDS_MeshNode * nodes[], + const int nbnodes) +{ + // keep current nodes of elem + set oldNodes; + SMDS_ElemIteratorPtr itn = element->nodesIterator(); + while(itn->more()) + oldNodes.insert( itn->next() ); + + if ( !element->IsPoly() ) + myInfo.remove( element ); // element may change type + + // change nodes + bool Ok = false; + SMDS_MeshElement* elem = const_cast(element); + switch ( elem->GetType() ) + { + case SMDSAbs_Edge: { + if ( nbnodes == 2 ) { + if ( SMDS_MeshEdge* edge = dynamic_cast( elem )) + Ok = edge->ChangeNodes( nodes[0], nodes[1] ); + } + else if ( nbnodes == 3 ) { + if ( SMDS_QuadraticEdge* edge = dynamic_cast( elem )) + Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] ); + } + break; + } + case SMDSAbs_Face: { + if ( SMDS_FaceOfNodes* face = dynamic_cast( elem )) + Ok = face->ChangeNodes( nodes, nbnodes ); + else + if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast( elem )) + Ok = QF->ChangeNodes( nodes, nbnodes ); + else + if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast(elem)) + Ok = face->ChangeNodes(nodes, nbnodes); + break; + } + case SMDSAbs_Volume: { + if ( SMDS_VolumeOfNodes* vol = dynamic_cast( elem )) + Ok = vol->ChangeNodes( nodes, nbnodes ); + else + if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast( elem )) + Ok = QV->ChangeNodes( nodes, nbnodes ); + break; + } + default: + MESSAGE ( "WRONG ELEM TYPE"); + } + + if ( Ok ) { // update InverseElements + + set::iterator it; + + // AddInverseElement to new nodes + for ( int i = 0; i < nbnodes; i++ ) { + it = oldNodes.find( nodes[i] ); + if ( it == oldNodes.end() ) + // new node + const_cast( nodes[i] )->AddInverseElement( elem ); + else + // remove from oldNodes a node that remains in elem + oldNodes.erase( it ); + } + // RemoveInverseElement from the nodes removed from elem + for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) + { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement( elem ); + } + } + + if ( !element->IsPoly() ) + myInfo.add( element ); // element may change type + + return Ok; +} + +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : to change nodes of polyhedral volume +//======================================================================= +bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + const vector& nodes, + const 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(); + set::iterator it; + for (int i = 0; i < nbnodes; i++) { + it = oldNodes.find(nodes[i]); + if (it == oldNodes.end()) { + // new node + const_cast(nodes[i])->AddInverseElement(elem); + } else { + // remove from oldNodes a node that remains in elem + oldNodes.erase(it); + } + } + + // RemoveInverseElement from the nodes removed from elem + for (it = oldNodes.begin(); it != oldNodes.end(); it++) { + SMDS_MeshNode * n = static_cast + (const_cast( *it )); + n->RemoveInverseElement(elem); + } + + return Ok; +} + //======================================================================= //function : FindEdge @@ -940,54 +1329,98 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - if((node1==NULL)||(node2==NULL)) return NULL; - return FindEdge(node1,node2); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + if((node1==NULL)||(node2==NULL)) return NULL; + return FindEdge(node1,node2); } //#include "Profiler.h" const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) const -{ - const SMDS_MeshEdge * toReturn=NULL; - //PROFILER_Init(); - //PROFILER_Set(); - SMDS_ElemIteratorPtr it1=node1->edgesIterator(); - //PROFILER_Get(0); - //PROFILER_Set(); - while(it1->more()) - { - const SMDS_MeshEdge * e=static_cast - (it1->next()); - SMDS_ElemIteratorPtr it2=e->nodesIterator(); - while(it2->more()) - { - if(it2->next()->GetID()==node2->GetID()) - { - toReturn=e; - break; - } - } - } - //PROFILER_Get(1); - return toReturn; + const SMDS_MeshNode * node2) +{ + if ( !node1 ) return 0; + const SMDS_MeshEdge * toReturn=NULL; + //PROFILER_Init(); + //PROFILER_Set(); + SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge); + //PROFILER_Get(0); + //PROFILER_Set(); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) { + toReturn = static_cast( e ); + break; + } + } + //PROFILER_Get(1); + return toReturn; } +//======================================================================= +//function : FindEdgeOrCreate +//purpose : +//======================================================================= + SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, - const SMDS_MeshNode * node2) + const SMDS_MeshNode * node2) +{ + if ( !node1 || !node2) return 0; + SMDS_MeshEdge * toReturn=NULL; + toReturn=const_cast(FindEdge(node1,node2)); + if(toReturn==NULL) { + if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + toReturn=new SMDS_MeshEdge(node1,node2); + myEdges.Add(toReturn); + myInfo.myNbEdges++; + } + return toReturn; +} + + +//======================================================================= +//function : FindEdge +//purpose : +//======================================================================= + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2, + int idnode3) const { - SMDS_MeshEdge * toReturn=NULL; - toReturn=const_cast(FindEdge(node1,node2)); - if(toReturn==NULL) - { - toReturn=new SMDS_MeshEdge(node1,node2); - myEdges.insert(toReturn); - } - return toReturn; + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + return FindEdge(node1,node2,node3); +} + +const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1, + const SMDS_MeshNode * node2, + const SMDS_MeshNode * node3) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 3 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); + } + } + return 0; } + //======================================================================= //function : FindFace //purpose : @@ -996,118 +1429,221 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3) const { - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL; - return FindFace(node1, node2, node3); + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + return FindFace(node1, node2, node3); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 3 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); + } + } + return 0; } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) const +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found; - - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=3) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - } - if(node2found&&node3found) - return face; - } - return NULL; + SMDS_MeshFace * toReturn=NULL; + toReturn = const_cast(FindFace(node1,node2,node3)); + if(toReturn==NULL) { + toReturn = createTriangle(node1,node2,node3); + } + return toReturn; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3) -{ - SMDS_MeshFace * toReturn=NULL; - toReturn=const_cast(FindFace(node1,node2,node3)); - if(toReturn==NULL) - { - toReturn=createTriangle(node1,node2,node3); - } - return toReturn; -} //======================================================================= //function : FindFace //purpose : //======================================================================= -const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3, - int idnode4) const -{ - const SMDS_MeshNode * node1=FindNode(idnode1); - const SMDS_MeshNode * node2=FindNode(idnode2); - const SMDS_MeshNode * node3=FindNode(idnode3); - const SMDS_MeshNode * node4=FindNode(idnode4); - if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL; - return FindFace(node1, node2, node3, node4); +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4) const +{ + const SMDS_MeshNode * node1=FindNode(idnode1); + const SMDS_MeshNode * node2=FindNode(idnode2); + const SMDS_MeshNode * node3=FindNode(idnode3); + const SMDS_MeshNode * node4=FindNode(idnode4); + return FindFace(node1, node2, node3, node4); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 4 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); + } + } + return 0; } -const SMDS_MeshFace* SMDS_Mesh::FindFace( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) const +SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4) { - const SMDS_MeshFace * face; - const SMDS_MeshElement * node; - bool node2found, node3found, node4found; - SMDS_ElemIteratorPtr it1=node1->facesIterator(); - while(it1->more()) - { - face=static_cast(it1->next()); - if(face->NbNodes()!=4) continue; - SMDS_ElemIteratorPtr it2=face->nodesIterator(); - node2found=false; - node3found=false; - node4found=false; - while(it2->more()) - { - node=it2->next(); - if(node->GetID()==node2->GetID()) node2found=true; - if(node->GetID()==node3->GetID()) node3found=true; - if(node->GetID()==node4->GetID()) node4found=true; - } - if(node2found&&node3found&&node4found) - return face; - } - return NULL; + SMDS_MeshFace * toReturn=NULL; + toReturn=const_cast(FindFace(node1,node2,node3,node4)); + if(toReturn==NULL) { + toReturn=createQuadrangle(node1,node2,node3,node4); + } + return toReturn; } -SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( - const SMDS_MeshNode *node1, - const SMDS_MeshNode *node2, - const SMDS_MeshNode *node3, - const SMDS_MeshNode *node4) -{ - SMDS_MeshFace * toReturn=NULL; - toReturn=const_cast(FindFace(node1,node2,node3,node4)); - if(toReturn==NULL) - { - toReturn=createQuadrangle(node1,node2,node3,node4); - } - return toReturn; + +//======================================================================= +//function : FindFace +//purpose :quadratic triangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + return FindFace(node1, node2, node3, node4, node5, node6); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 6 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 && + n!=node5 && + n!=node6 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); + } + } + return 0; +} + + +//======================================================================= +//function : FindFace +//purpose : quadratic quadrangle +//======================================================================= + +const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, + int idnode3, int idnode4, + int idnode5, int idnode6, + int idnode7, int idnode8) const +{ + const SMDS_MeshNode * node1 = FindNode(idnode1); + const SMDS_MeshNode * node2 = FindNode(idnode2); + const SMDS_MeshNode * node3 = FindNode(idnode3); + const SMDS_MeshNode * node4 = FindNode(idnode4); + const SMDS_MeshNode * node5 = FindNode(idnode5); + const SMDS_MeshNode * node6 = FindNode(idnode6); + const SMDS_MeshNode * node7 = FindNode(idnode7); + const SMDS_MeshNode * node8 = FindNode(idnode8); + return FindFace(node1, node2, node3, node4, node5, node6, node7, node8); +} + +const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1, + const SMDS_MeshNode *node2, + const SMDS_MeshNode *node3, + const SMDS_MeshNode *node4, + const SMDS_MeshNode *node5, + const SMDS_MeshNode *node6, + const SMDS_MeshNode *node7, + const SMDS_MeshNode *node8) +{ + if ( !node1 ) return 0; + SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face); + while(it1->more()) { + const SMDS_MeshElement * e = it1->next(); + if ( e->NbNodes() == 8 ) { + SMDS_ElemIteratorPtr it2 = e->nodesIterator(); + while(it2->more()) { + const SMDS_MeshElement* n = it2->next(); + if( n!=node1 && + n!=node2 && + n!=node3 && + n!=node4 && + n!=node5 && + n!=node6 && + n!=node7 && + n!=node8 ) + { + e = 0; + break; + } + } + if ( e ) + return static_cast (e); + } + } + return 0; } + //======================================================================= //function : FindElement //purpose : @@ -1115,7 +1651,45 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate( const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const { - return myElementIDFactory->MeshElement(IDelem); + 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) +{ + if ( nodes.size() > 2 && nodes[0] ) { + SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face); + while (itF->more()) { + const SMDS_MeshElement* f = itF->next(); + if ( f->NbNodes() == nodes.size() ) { + SMDS_ElemIteratorPtr it2 = f->nodesIterator(); + while(it2->more()) { + if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) { + f = 0; + break; + } + } + if ( f ) + return static_cast (f); + } + } + } + return NULL; } //======================================================================= @@ -1221,7 +1795,7 @@ void SMDS_Mesh::DebugStats() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbNodes() const { - return myNodes.size(); + return myNodes.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1229,7 +1803,7 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myEdges.size(); + return myEdges.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1237,7 +1811,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myFaces.size(); + return myFaces.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1245,7 +1819,7 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myVolumes.size(); + return myVolumes.Size(); } /////////////////////////////////////////////////////////////////////////////// @@ -1264,45 +1838,99 @@ 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(); - } + if(myParent==NULL) + { + delete myNodeIDFactory; + delete myElementIDFactory; + } + else + { + SMDS_ElemIteratorPtr eIt = elementsIterator(); + while ( eIt->more() ) + myElementIDFactory->ReleaseID(eIt->next()->GetID()); + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + myNodeIDFactory->ReleaseID(itn->next()->GetID()); + } + 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(); + 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(); + 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(); + delete elem; + } + +} + +//================================================================================ +/*! + * \brief Clear all data + */ +//================================================================================ + +void SMDS_Mesh::Clear() +{ + if (myParent!=NULL) { + SMDS_ElemIteratorPtr eIt = elementsIterator(); + while ( eIt->more() ) + myElementIDFactory->ReleaseID(eIt->next()->GetID()); + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + myNodeIDFactory->ReleaseID(itn->next()->GetID()); + } + else { + myNodeIDFactory->Clear(); + myElementIDFactory->Clear(); + } + SMDS_VolumeIteratorPtr itv = volumesIterator(); + while (itv->more()) + delete itv->next(); + myVolumes.Clear(); + + SMDS_FaceIteratorPtr itf = facesIterator(); + while (itf->more()) + delete itf->next(); + myFaces.Clear(); + + SMDS_EdgeIteratorPtr ite = edgesIterator(); + while (ite->more()) + delete ite->next(); + myEdges.Clear(); + + SMDS_NodeIteratorPtr itn = nodesIterator(); + while (itn->more()) + delete itn->next(); + myNodes.Clear(); + + list::iterator itc=myChildren.begin(); + while(itc!=myChildren.end()) + (*itc)->Clear(); + + myInfo.Clear(); } /////////////////////////////////////////////////////////////////////////////// @@ -1365,71 +1993,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 +2063,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 +2098,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 +2154,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 +2170,9 @@ static set * getFinitElements(const SMDS_MeshElement * i++; } - - return intersectionOfSets(initSet, numberOfSets); + set *retSet=intersectionOfSets(initSet, numberOfSets); + delete [] initSet; + return retSet; } /////////////////////////////////////////////////////////////////////////////// @@ -1670,12 +2288,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 +2304,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,16 +2344,19 @@ 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))); + myInfo.RemoveEdge(*it); break; case SMDSAbs_Face: - myFaces.erase(static_cast + myFaces.Remove(static_cast (const_cast(*it))); + myInfo.RemoveFace(*it); break; case SMDSAbs_Volume: - myVolumes.erase(static_cast + myVolumes.Remove(static_cast (const_cast(*it))); + myInfo.RemoveVolume(*it); break; } //MESSAGE( "SMDS: RM elem " << (*it)->GetID() ); @@ -1749,8 +2373,9 @@ 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))); + myInfo.myNbNodes--; myNodeIDFactory->ReleaseID((*it)->GetID()); removedNodes.push_back( (*it) ); delete *it; @@ -1762,6 +2387,61 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, delete s1; } + +/////////////////////////////////////////////////////////////////////////////// +///@param elem The element to delete +/////////////////////////////////////////////////////////////////////////////// +void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) +{ + SMDSAbs_ElementType aType = elem->GetType(); + if (aType == SMDSAbs_Node) { + // only free node can be removed by this method + const SMDS_MeshNode* n = static_cast(elem); + SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); + if (!itFe->more()) { // free node + myNodes.Remove(const_cast(n)); + myInfo.myNbNodes--; + myNodeIDFactory->ReleaseID(elem->GetID()); + delete elem; + } + } else { + if (hasConstructionEdges() || hasConstructionFaces()) + // this methods is only for meshes without descendants + return; + + // Remove element from of its nodes + SMDS_ElemIteratorPtr itn = elem->nodesIterator(); + while (itn->more()) { + SMDS_MeshNode * n = static_cast + (const_cast(itn->next())); + n->RemoveInverseElement(elem); + } + + // in meshes without descendants elements are always free + switch (aType) { + case SMDSAbs_Edge: + myEdges.Remove(static_cast + (const_cast(elem))); + myInfo.RemoveEdge(elem); + break; + case SMDSAbs_Face: + myFaces.Remove(static_cast + (const_cast(elem))); + myInfo.RemoveFace(elem); + break; + case SMDSAbs_Volume: + myVolumes.Remove(static_cast + (const_cast(elem))); + myInfo.RemoveVolume(elem); + break; + default: + break; + } + myElementIDFactory->ReleaseID(elem->GetID()); + delete elem; + } +} + /*! * Checks if the element is present in mesh. * Useful to determine dead pointers. @@ -1788,3 +2468,679 @@ 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(); + idFactory->Clear(); +// 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; + } +} + +//======================================================================= +//function : GetElementType +//purpose : Return type of element or node with id +//======================================================================= + +SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const +{ + SMDS_MeshElement* elem = 0; + if( iselem ) + elem = myElementIDFactory->MeshElement( id ); + else + elem = myNodeIDFactory->MeshElement( id ); + + if( !elem ) + { + //throw SALOME_Exception(LOCALIZED ("this element isn't exist")); + return SMDSAbs_All; + } + else + return elem->GetType(); +} + + + +//******************************************************************** +//******************************************************************** +//******** ********* +//***** Methods for addition of quadratic elements ****** +//******** ********* +//******************************************************************** +//******************************************************************** + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) +{ + return SMDS_Mesh::AddEdgeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + ID); +} + +//======================================================================= +//function : AddEdge +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n12) +{ + return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddEdgeWithID +//purpose : +//======================================================================= +SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n12, + int ID) +{ + if ( !n1 || !n2 || !n12 ) return 0; + SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12); + if(myElementIDFactory->BindID(ID, edge)) { + SMDS_MeshNode *node1,*node2, *node12; + node1 = const_cast(n1); + node2 = const_cast(n2); + node12 = const_cast(n12); + node1->AddInverseElement(edge); + node2->AddInverseElement(edge); + node12->AddInverseElement(edge); + myEdges.Add(edge); + myInfo.myNbQuadEdges++; + return edge; + } + else { + delete edge; + return NULL; + } +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, + int n12,int n23,int n31, int ID) +{ + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31), + ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0; + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31); + myFaces.Add(face); + myInfo.myNbQuadTriangles++; + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddFace +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41, + myElementIDFactory->GetFreeID()); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n34,int n41, int ID) +{ + return SMDS_Mesh::AddFaceWithID + ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41), + ID); +} + +//======================================================================= +//function : AddFaceWithID +//purpose : +//======================================================================= +SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0; + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + } + SMDS_QuadraticFaceOfNodes* face = + new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41); + myFaces.Add(face); + myInfo.myNbQuadQuadrangles++; + + if (!registerElement(ID, face)) { + RemoveElement(face, false); + face = NULL; + } + return face; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23, + n31, n14, n24, n34, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n12,int n23,int n31, + int n14,int n24,int n34, int ID) +{ + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order tetrahedron of 10 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n24, + const SMDS_MeshNode * n34, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34) + return 0; + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34); + myVolumes.Add(volume); + myInfo.myNbQuadTetras++; + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41, + n15, n25, n35, n45, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, + int n12,int n23,int n34,int n41, + int n15,int n25,int n35,int n45, int ID) +{ + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order pyramid of 13 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n35, + const SMDS_MeshNode * n45, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 || + !n34 || !n41 || !n15 || !n25 || !n35 || !n45) + return 0; + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23, + n34,n41,n15,n25,n35,n45); + myVolumes.Add(volume); + myInfo.myNbQuadPyramids++; + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31, + n45, n56, n64, n14, n25, n36, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, + int n4, int n5, int n6, + int n12,int n23,int n31, + int n45,int n56,int n64, + int n14,int n25,int n36, int ID) +{ + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) , + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Pentahedron with 15 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n31, + const SMDS_MeshNode * n45, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n64, + const SMDS_MeshNode * n14, + const SMDS_MeshNode * n25, + const SMDS_MeshNode * n36, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 || + !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36) + return 0; + if(hasConstructionFaces()) { + // creation quadratic faces - not implemented + return 0; + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31, + n45,n56,n64,n14,n25,n36); + myVolumes.Add(volume); + myInfo.myNbQuadPrisms++; + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +} + + +//======================================================================= +//function : AddVolume +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = + SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41, + n56, n67, n78, n85, n15, n26, n37, n48, ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, + int n5, int n6, int n7, int n8, + int n12,int n23,int n34,int n41, + int n56,int n67,int n78,int n85, + int n15,int n26,int n37,int n48, int ID) +{ + return SMDS_Mesh::AddVolumeWithID + ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48), + ID); +} + +//======================================================================= +//function : AddVolumeWithID +//purpose : 2d order Hexahedrons with 20 nodes +//======================================================================= +SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, + const SMDS_MeshNode * n2, + const SMDS_MeshNode * n3, + const SMDS_MeshNode * n4, + const SMDS_MeshNode * n5, + const SMDS_MeshNode * n6, + const SMDS_MeshNode * n7, + const SMDS_MeshNode * n8, + const SMDS_MeshNode * n12, + const SMDS_MeshNode * n23, + const SMDS_MeshNode * n34, + const SMDS_MeshNode * n41, + const SMDS_MeshNode * n56, + const SMDS_MeshNode * n67, + const SMDS_MeshNode * n78, + const SMDS_MeshNode * n85, + const SMDS_MeshNode * n15, + const SMDS_MeshNode * n26, + const SMDS_MeshNode * n37, + const SMDS_MeshNode * n48, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || + !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48) + return 0; + if(hasConstructionFaces()) { + return 0; + // creation quadratic faces - not implemented + } + SMDS_QuadraticVolumeOfNodes * volume = + new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41, + n56,n67,n78,n85,n15,n26,n37,n48); + myVolumes.Add(volume); + myInfo.myNbQuadHexas++; + + if (!registerElement(ID, volume)) { + RemoveElement(volume, false); + volume = NULL; + } + return volume; +}