X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMDS%2FSMDS_Mesh.cxx;h=fe6f186e496b9b33a9f76da95648fa5b9a0a5598;hb=c84ff91c3981488e5a5ae5c6661899f48872290d;hp=c1d16d8c8c1e5ce762d630c1278ef6485730073c;hpb=6e58f2fb40b4095058c60f3bd538772fb85a3c23;p=modules%2Fsmesh.git diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index c1d16d8c8..fe6f186e4 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1,23 +1,23 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 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 +// 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 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // SMESH SMDS : implementation of Salome mesh data structure @@ -26,19 +26,21 @@ #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_FaceOfEdges.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_FaceOfNodes.hxx" +#include "SMDS_Mesh.hxx" #include "SMDS_PolygonalFaceOfNodes.hxx" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_QuadraticEdge.hxx" #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_QuadraticVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" #include "SMDS_UnstructuredGrid.hxx" +#include "SMDS_VolumeOfFaces.hxx" +#include "SMDS_VolumeOfNodes.hxx" + +#include "utilities.h" #include #include @@ -58,7 +60,7 @@ using namespace std; #endif // number of added entities to check memory after -#define CHECKMEMORY_INTERVAL 1000 +#define CHECKMEMORY_INTERVAL 100000 vector SMDS_Mesh::_meshList = vector(); int SMDS_Mesh::chunkSize = 1024; @@ -80,35 +82,38 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc) if ( err ) return -1; + const unsigned long Mbyte = 1024 * 1024; + 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); } + else { + double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2; + limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte ); + } if ( limit < 20 ) limit = 20; else - limit = int( limit * 1.5 ); -#ifdef _DEBUG_ + limit = int ( limit * 1.5 ); 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; + //cout << "freeMb = " << freeMb << " limit = " << limit << endl; 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; @@ -125,7 +130,7 @@ SMDS_Mesh::SMDS_Mesh() myHasConstructionEdges(false), myHasConstructionFaces(false), myHasInverseElements(true), myNodeMin(0), myNodeMax(0), - myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0), + myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),myBallPool(0), myModified(false), myModifTime(0), myCompactTime(0), xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) { @@ -144,6 +149,7 @@ SMDS_Mesh::SMDS_Mesh() myEdgePool = new ObjectPool(SMDS_Mesh::chunkSize); myFacePool = new ObjectPool(SMDS_Mesh::chunkSize); myVolumePool = new ObjectPool(SMDS_Mesh::chunkSize); + myBallPool = new ObjectPool(SMDS_Mesh::chunkSize); myNodes.clear(); myCells.clear(); @@ -177,7 +183,8 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent) myNodePool(parent->myNodePool), myEdgePool(parent->myEdgePool), myFacePool(parent->myFacePool), - myVolumePool(parent->myVolumePool) + myVolumePool(parent->myVolumePool), + myBallPool(parent->myBallPool) { } @@ -213,8 +220,7 @@ 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){ - // TODO ID < 1 - if (ID <= 0) + if (ID < 1) { MESSAGE("=============> Bad Node Id: " << ID); ID = myNodeIDFactory->GetFreeID(); @@ -226,7 +232,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID) if (ID >= myNodes.size()) { myNodes.resize(ID+SMDS_Mesh::chunkSize, 0); - MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize); +// MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize); } myNodes[ID] = node; myNodeIDFactory->BindID(ID,node); @@ -269,7 +275,7 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I { if (!n) return 0; - //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); //MESSAGE("Add0DElementWithID" << ID) SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n); if (myElementIDFactory->BindID(ID, el0d)) { @@ -285,6 +291,54 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I return NULL; } +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID) +{ + SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode); + if (!node) return NULL; + return SMDS_Mesh::AddBallWithID(node, diameter, ID); +} + +/////////////////////////////////////////////////////////////////////////////// +/// create a Ball and add it to the current Mesh +/// @return : The created Ball +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter) +{ + return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Create a new Ball and at it to the mesh +/// @param idnode ID of the node +// @param diameter ball diameter +/// @param ID ID of the 0D element to create +/// @return The created 0D element or NULL if an element with this +/// ID already exists or if input node is not found. +/////////////////////////////////////////////////////////////////////////////// +SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID) +{ + if (!n) return 0; + + if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory(); + + SMDS_BallElement *ball = myBallPool->getNew(); + ball->init(n->getVtkId(), diameter, this); + if (!this->registerElement(ID,ball)) + { + this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL); + myBallPool->destroy(ball); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = ball; + myInfo.myNbBalls++; + return ball; +} + /////////////////////////////////////////////////////////////////////////////// /// create a MeshEdge and add it to the current Mesh /// @return : The created MeshEdge @@ -476,7 +530,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, return NULL; if ( !e1 || !e2 || !e3 ) return 0; - //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); MESSAGE("AddFaceWithID" << ID); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3); @@ -522,7 +576,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1, return NULL; MESSAGE("AddFaceWithID" << ID); if ( !e1 || !e2 || !e3 || !e4 ) return 0; - //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4); adjustmyCellsCapacity(ID); myCells[ID] = face; @@ -592,7 +646,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4) return volume; - //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4); @@ -699,7 +753,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume; - //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5); @@ -811,7 +865,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume; - //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3); SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6); @@ -859,6 +913,137 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return volume; } +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +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 * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, + n7, n8, n9, n10, n11, n12, + ID); + if(v==NULL) myElementIDFactory->ReleaseID(ID); + return v; +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism or NULL if an element with this ID already exists +///or if input nodes are not found. +/////////////////////////////////////////////////////////////////////////////// + +SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, + int idnode2, + int idnode3, + int idnode4, + int idnode5, + int idnode6, + int idnode7, + int idnode8, + int idnode9, + int idnode10, + int idnode11, + int idnode12, + int ID) +{ + SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1); + SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2); + SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3); + SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4); + SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5); + SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6); + SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7); + SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8); + SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9); + SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10); + SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11); + SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12); + return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, + node7, node8, node9, node10, node11, node12, + ID); +} + +/////////////////////////////////////////////////////////////////////////////// +///Create a new hexagonal prism and add it to the mesh. +///@param ID The ID of the new volume +///@return The created prism +/////////////////////////////////////////////////////////////////////////////// + +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 * n9, + const SMDS_MeshNode * n10, + const SMDS_MeshNode * n11, + const SMDS_MeshNode * n12, + int ID) +{ + SMDS_MeshVolume* volume = 0; + if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || + !n7 || !n8 || !n9 || !n10 || !n11 || !n12 ) + return volume; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if(hasConstructionFaces()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else if(hasConstructionEdges()) { + MESSAGE("Error : Not implemented"); + return NULL; + } + else { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n11->getVtkId()); + nodeIds.push_back(n10->getVtkId()); + nodeIds.push_back(n9->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + volume = volvtk; + adjustmyCellsCapacity(ID); + myCells[ID] = volume; + myInfo.myNbHexPrism++; + } + + return volume; +} + /////////////////////////////////////////////////////////////////////////////// ///Create a new hexahedron and add it to the mesh. ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges. @@ -875,7 +1060,6 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1, const SMDS_MeshNode * n8) { int ID = myElementIDFactory->GetFreeID(); - //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID); if(v==NULL) myElementIDFactory->ReleaseID(ID); return v; @@ -936,7 +1120,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, //MESSAGE("AddVolumeWithID " << ID); SMDS_MeshVolume* volume = 0; if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume; - //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionFaces()) { SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4); SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8); @@ -1019,7 +1203,7 @@ 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(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4); adjustmyCellsCapacity(ID); myCells[ID] = volume; @@ -1067,7 +1251,7 @@ 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(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5); adjustmyCellsCapacity(ID); myCells[ID] = volume; @@ -1117,7 +1301,7 @@ 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(); + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6); adjustmyCellsCapacity(ID); myCells[ID] = volume; @@ -1135,8 +1319,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1, /// Add a polygon defined by its nodes IDs /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector nodes_ids, - const int ID) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector & nodes_ids, + const int ID) { int nbNodes = nodes_ids.size(); vector nodes (nbNodes); @@ -1152,12 +1336,12 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector nodes_ids, /////////////////////////////////////////////////////////////////////////////// SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID - (vector nodes, - const int ID) + (const vector & nodes, + const int ID) { SMDS_MeshFace * face; - //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if (hasConstructionEdges()) { MESSAGE("Error : Not implemented"); @@ -1169,7 +1353,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID //MESSAGE("AddPolygonalFaceWithID vtk " << ID); vector nodeIds; nodeIds.clear(); - vector::iterator it = nodes.begin(); + vector::const_iterator it = nodes.begin(); for ( ; it != nodes.end(); ++it) nodeIds.push_back((*it)->getVtkId()); @@ -1209,7 +1393,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID /// An ID is automatically affected to the created face. /////////////////////////////////////////////////////////////////////////////// -SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector nodes) +SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector & nodes) { return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID()); } @@ -1222,9 +1406,9 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector nodes) /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID - (vector nodes_ids, - vector quantities, - const int ID) + (const vector & nodes_ids, + const vector & quantities, + const int ID) { int nbNodes = nodes_ids.size(); vector nodes (nbNodes); @@ -1242,12 +1426,14 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID - (vector nodes, - vector quantities, - const int ID) + (const vector& nodes, + const vector & quantities, + const int ID) { - SMDS_MeshVolume* volume; - //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + SMDS_MeshVolume* volume = 0; + if ( nodes.empty() || quantities.empty() ) + return NULL; + if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if (hasConstructionFaces()) { MESSAGE("Error : Not implemented"); @@ -1264,7 +1450,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID); vector nodeIds; nodeIds.clear(); - vector::iterator it = nodes.begin(); + vector::const_iterator it = nodes.begin(); for (; it != nodes.end(); ++it) nodeIds.push_back((*it)->getVtkId()); @@ -1305,8 +1491,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID /////////////////////////////////////////////////////////////////////////////// SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume - (vector nodes, - vector quantities) + (const vector & nodes, + const vector & quantities) { int ID = myElementIDFactory->GetFreeID(); SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); @@ -1373,6 +1559,53 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector& vtkNodeIds) +{ + int ID = myElementIDFactory->GetFreeID(); + SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID); + if (f == NULL) myElementIDFactory->ReleaseID(ID); + return f; +} + +SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector& vtkNodeIds, const int ID) +{ + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(vtkNodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = facevtk; + vtkIdType aVtkType = facevtk->GetVtkType(); + switch (aVtkType) + { + case VTK_TRIANGLE: + myInfo.myNbTriangles++; + break; + case VTK_QUAD: + myInfo.myNbQuadrangles++; + break; + case VTK_QUADRATIC_TRIANGLE: + myInfo.myNbQuadTriangles++; + break; + case VTK_QUADRATIC_QUAD: + myInfo.myNbQuadQuadrangles++; + break; + case VTK_BIQUADRATIC_QUAD: + myInfo.myNbBiQuadQuadrangles++; + break; + case VTK_POLYGON: + myInfo.myNbPolygons++; + break; + default: + myInfo.myNbPolygons++; + } + return facevtk; +} + /////////////////////////////////////////////////////////////////////////////// /// Registers element with the given ID, maintains inverse connections /////////////////////////////////////////////////////////////////////////////// @@ -1396,7 +1629,7 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element) if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector { - MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize); +// MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize); myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1); } myCellIdVtkToSmds[vtkId] = ID; @@ -1412,9 +1645,9 @@ const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const { if (ID < 1 || ID >= myNodes.size()) { - MESSAGE("------------------------------------------------------------------------- "); - MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size()); - MESSAGE("------------------------------------------------------------------------- "); +// MESSAGE("------------------------------------------------------------------------- "); +// MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size()); +// MESSAGE("------------------------------------------------------------------------- "); return 0; } return (const SMDS_MeshNode *)myNodes[ID]; @@ -1446,7 +1679,7 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1, int ID) { if ( !node1 || !node2 || !node3) return 0; -// if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { SMDS_MeshEdge *edge1, *edge2, *edge3; @@ -1499,7 +1732,7 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1, int ID) { if ( !node1 || !node2 || !node3 || !node4 ) return 0; -// if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); if(hasConstructionEdges()) { //MESSAGE("createQuadrangle hasConstructionEdges "<< ID); @@ -1637,10 +1870,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, { MESSAGE("SMDS_Mesh::ChangeElementNodes"); // keep current nodes of elem - set oldNodes; - SMDS_ElemIteratorPtr itn = element->nodesIterator(); - while(itn->more()) - oldNodes.insert(itn->next()); + set oldNodes( element->begin_nodes(), element->end_nodes() ); // change nodes bool Ok = false; @@ -1653,7 +1883,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, if ( Ok ) { // update InverseElements - set::iterator it; + set::iterator it; // AddInverseElement to new nodes for ( int i = 0; i < nbnodes; i++ ) { @@ -1668,8 +1898,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, // RemoveInverseElement from the nodes removed from elem for ( it = oldNodes.begin(); it != oldNodes.end(); it++ ) { - SMDS_MeshNode * n = static_cast - (const_cast( *it )); + SMDS_MeshNode * n = const_cast( *it ); n->RemoveInverseElement( cell ); } } @@ -1762,6 +1991,31 @@ const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) return toReturn; } +//======================================================================= +//function : FindBall +//purpose : +//======================================================================= + +const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const +{ + const SMDS_MeshNode * node = FindNode(idnode); + if(node == NULL) return NULL; + return FindBall(node); +} + +const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node) +{ + if (!node) return 0; + const SMDS_BallElement* toReturn = NULL; + SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_Ball); + while (it1->more() && (toReturn == NULL)) { + const SMDS_MeshElement* e = it1->next(); + if (e->GetGeomType() == SMDSGeom_BALL) + toReturn = static_cast(e); + } + return toReturn; +} + //======================================================================= //function : Find0DElementOrCreate //purpose : @@ -1829,7 +2083,7 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1, SMDS_MeshEdge * toReturn=NULL; toReturn=const_cast(FindEdge(node1,node2)); if(toReturn==NULL) { - //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); + if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory(); int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element adjustmyCellsCapacity(ID); vector nodeIds; @@ -2218,7 +2472,7 @@ void SMDS_Mesh::DumpNodes() const void SMDS_Mesh::Dump0DElements() const { MESSAGE("dump 0D elements of mesh : "); - SMDS_0DElementIteratorPtr it0d = elements0dIterator(); + SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement); while(it0d->more()) ; //MESSAGE(it0d->next()); } @@ -2324,7 +2578,15 @@ int SMDS_Mesh::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::Nb0DElements() const { - return myInfo.Nb0DElements(); // -PR- a verfier + return myInfo.Nb0DElements(); +} + +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of 0D elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbBalls() const +{ + return myInfo.NbBalls(); } /////////////////////////////////////////////////////////////////////////////// @@ -2332,7 +2594,7 @@ int SMDS_Mesh::Nb0DElements() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbEdges() const { - return myInfo.NbEdges(); // -PR- a verfier + return myInfo.NbEdges(); } /////////////////////////////////////////////////////////////////////////////// @@ -2340,7 +2602,7 @@ int SMDS_Mesh::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbFaces() const { - return myInfo.NbFaces(); // -PR- a verfier + return myInfo.NbFaces(); } /////////////////////////////////////////////////////////////////////////////// @@ -2348,17 +2610,16 @@ int SMDS_Mesh::NbFaces() const /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbVolumes() const { - return myInfo.NbVolumes(); // -PR- a verfier + return myInfo.NbVolumes(); } /////////////////////////////////////////////////////////////////////////////// /// Return the number of child mesh of this mesh. -/// Note that the tree structure of SMDS_Mesh seems to be unused in this version -/// (2003-09-08) of SMESH +/// Note that the tree structure of SMDS_Mesh is unused in SMESH /////////////////////////////////////////////////////////////////////////////// int SMDS_Mesh::NbSubMesh() const { - return myChildren.size(); + return myChildren.size(); } /////////////////////////////////////////////////////////////////////////////// @@ -2395,38 +2656,6 @@ SMDS_Mesh::~SMDS_Mesh() myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); } } - -// SetOfNodes::Iterator itn(myNodes); -// for (; itn.More(); itn.Next()) -// delete itn.Value(); - -// SetOf0DElements::Iterator it0d (my0DElements); -// for (; it0d.More(); it0d.Next()) -// { -// SMDS_MeshElement* elem = it0d.Value(); -// delete elem; -// } - -// SetOfEdges::Iterator ite(myEdges); -// for (; ite.More(); ite.Next()) -// { -// SMDS_MeshElement* elem = ite.Value(); -// delete elem; -// } - -// SetOfFaces::Iterator itf(myFaces); -// for (; itf.More(); itf.Next()) -// { -// SMDS_MeshElement* elem = itf.Value(); -// delete elem; -// } - -// SetOfVolumes::Iterator itv(myVolumes); -// for (; itv.More(); itv.Next()) -// { -// SMDS_MeshElement* elem = itv.Value(); -// delete elem; -// } } //================================================================================ @@ -2478,6 +2707,9 @@ void SMDS_Mesh::Clear() case SMDSAbs_Volume: myVolumePool->destroy(static_cast(elem)); break; + case SMDSAbs_Ball: + myBallPool->destroy(static_cast(elem)); + break; default: break; } @@ -2512,7 +2744,7 @@ void SMDS_Mesh::Clear() // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" // using double type for storing coordinates of nodes instead float. points->SetDataType(VTK_DOUBLE); - points->SetNumberOfPoints(SMDS_Mesh::chunkSize); + points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/); myGrid->SetPoints( points ); points->Delete(); myGrid->BuildLinks(); @@ -2579,78 +2811,7 @@ void SMDS_Mesh::setInverseElements(bool b) namespace { -/////////////////////////////////////////////////////////////////////////////// -///Iterator on NCollection_Map -/////////////////////////////////////////////////////////////////////////////// -template -struct MYNode_Map_Iterator: public FATHER -{ - int _ctr; - const MAP& _map; - MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector - { - _ctr = 0; - } - - bool more() - { - while (_ctr < _map.size()) - { - if (_map[_ctr]) - return true; - _ctr++; - } - return false; - } - - ELEM next() - { - ELEM current = _map[_ctr]; - _ctr++; - return current; - } -}; - -template -struct MYElem_Map_Iterator: public FATHER -{ - int _ctr; - int _type; - const MAP& _map; - MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector - { - _ctr = 0; - _type = typ; - while (_ctr < _map.size()) // go to the first valid element - { - if (_map[_ctr]) - if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type)) - break; - _ctr++; - } - } - -bool more() - { - while (_ctr < _map.size()) - { - if (_map[_ctr]) - if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type)) - return true; - _ctr++; - } - return false; - } - - ELEM next() - { - ELEM current = dynamic_cast (_map[_ctr]); - _ctr++; - return current; - } -}; - -//================================================================================ + //================================================================================ /*! * \brief Iterator on elements in id increasing order */ @@ -2659,7 +2820,7 @@ bool more() template class IdSortedIterator : public SMDS_Iterator { - const SMDS_MeshElementIDFactory& myIDFact; + SMDS_MeshElementIDFactory& myIDFact; int myID, myMaxID, myNbFound, myTotalNb; SMDSAbs_ElementType myType; ELEM myElem; @@ -2693,6 +2854,44 @@ bool more() return current; } }; + + //================================================================================ + /*! + * \brief Iterator on vector of elements, possibly being resized while iteration + */ + //================================================================================ + + template > + class ElemVecIterator: public SMDS_Iterator + { + const std::vector& _vector; + size_t _index; + bool _more; + VALUE_FILTER _filter; + public: + ElemVecIterator(const std::vector& vec, + const VALUE_FILTER& filter=VALUE_FILTER() ) + :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter ) + { + if ( _more && !_filter( _vector[ _index ])) + next(); + } + virtual bool more() + { + return _more; + } + virtual RETURN_VALUE next() + { + if ( !_more ) return NULL; + VECTOR_VALUE current = _vector[ _index ]; + _more = 0; + while ( !_more && ++_index < _vector.size() ) + _more = _filter( _vector[ _index ]); + return (RETURN_VALUE) current; + } + }; } /////////////////////////////////////////////////////////////////////////////// @@ -2701,34 +2900,50 @@ bool more() SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const { - typedef MYNode_Map_Iterator - < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator; - return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID + // naturally always sorted by ID + typedef ElemVecIterator TIterator; + return SMDS_NodeIteratorPtr( new TIterator(myNodes)); +} -// typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator; -// return ( idInceasingOrder ? -// SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) : -// SMDS_NodeIteratorPtr( new TIterator(myNodes))); +SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const +{ + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type ))); +} + +SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const +{ + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator; + return SMDS_ElemIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type ))); } /////////////////////////////////////////////////////////////////////////////// -///Return an iterator on 0D elements of the current mesh. +/// Return an iterator on elements of the current mesh factory /////////////////////////////////////////////////////////////////////////////// - -SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const +SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const { - typedef MYElem_Map_Iterator - < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; - return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID + // naturally always sorted by ID + switch ( type ) { + + case SMDSAbs_All: + return SMDS_ElemIteratorPtr (new ElemVecIterator(myCells)); -// typedef MYNCollection_Map_Iterator -// < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; -// typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator; -// return ( idInceasingOrder ? -// SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory, -// SMDSAbs_0DElement, -// Nb0DElements() )) : -// SMDS_0DElementIteratorPtr( new TIterator(my0DElements))); + case SMDSAbs_Node: + return SMDS_ElemIteratorPtr + ( new ElemVecIterator( myNodes )); + + default: + typedef ElemVecIterator + < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type ))); + } + return SMDS_ElemIteratorPtr(); } /////////////////////////////////////////////////////////////////////////////// @@ -2737,18 +2952,11 @@ SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) c SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const { - typedef MYElem_Map_Iterator - < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; - return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID - -// typedef MYNCollection_Map_Iterator -// < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; -// typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator; -// return ( idInceasingOrder ? -// SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory, -// SMDSAbs_Edge, -// NbEdges() )) : -// SMDS_EdgeIteratorPtr(new TIterator(myEdges))); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_EdgeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ))); } /////////////////////////////////////////////////////////////////////////////// @@ -2757,18 +2965,11 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const { - typedef MYElem_Map_Iterator - < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; - return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID - -// typedef MYNCollection_Map_Iterator -// < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; -// typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator; -// return ( idInceasingOrder ? -// SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory, -// SMDSAbs_Face, -// NbFaces() )) : -// SMDS_FaceIteratorPtr(new TIterator(myFaces))); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_FaceIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face ))); } /////////////////////////////////////////////////////////////////////////////// @@ -2777,43 +2978,11 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const { - typedef MYElem_Map_Iterator - < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; - return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID - - // typedef MYNCollection_Map_Iterator -// < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; -// typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator; -// return ( idInceasingOrder ? -// SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory, -// SMDSAbs_Volume, -// NbVolumes() )) : -// SMDS_VolumeIteratorPtr(new TIterator(myVolumes))); -} - -/////////////////////////////////////////////////////////////////////////////// -/// Return an iterator on elements of the current mesh factory -/////////////////////////////////////////////////////////////////////////////// -SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const -{ - switch (type) { - case SMDSAbs_All: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All)); - break; - case SMDSAbs_Volume: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume)); - case SMDSAbs_Face: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face)); - case SMDSAbs_Edge: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge)); - case SMDSAbs_0DElement: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement)); - case SMDSAbs_Node: - return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All)); - //return myNodeIDFactory->elementsIterator(); - default:; - } - return myElementIDFactory->elementsIterator(); + // naturally always sorted by ID + typedef ElemVecIterator + < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator; + return SMDS_VolumeIteratorPtr + (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ))); } /////////////////////////////////////////////////////////////////////////////// @@ -2870,7 +3039,7 @@ static set * getFinitElements(const SMDS_MeshElement * i++; } set *retSet=intersectionOfSets(initSet, numberOfSets); - MESSAGE("nb elems " << i << " intersection " << retSet->size()); +// MESSAGE("nb elems " << i << " intersection " << retSet->size()); delete [] initSet; return retSet; } @@ -3102,6 +3271,19 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, else delete (*it); break; + case SMDSAbs_Ball: + if (IdToRemove >= 0) + { + myCells[IdToRemove] = 0; + myInfo.remove(*it); + } + removedElems.push_back((*it)); + myElementIDFactory->ReleaseID(IdToRemove, vtkid); + if (const SMDS_BallElement* vtkElem = dynamic_cast(*it)) + myBallPool->destroy(const_cast( vtkElem )); + else + delete (*it); + break; } if (vtkid >= 0) { @@ -3200,6 +3382,11 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) myInfo.RemoveVolume(elem); myVolumePool->destroy(static_cast(todest)); break; + case SMDSAbs_Ball: + myCells[elemId] = 0; + myInfo.remove(elem); + myBallPool->destroy(static_cast(todest)); + break; default: break; } @@ -3222,22 +3409,10 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const while (itn->more()) if (elem == itn->next()) return true; - SMDS_0DElementIteratorPtr it0d = elements0dIterator(); - while (it0d->more()) - if (elem == it0d->next()) - return true; - SMDS_EdgeIteratorPtr ite = edgesIterator(); + SMDS_ElemIteratorPtr ite = elementsIterator(); while (ite->more()) if (elem == ite->next()) return true; - SMDS_FaceIteratorPtr itf = facesIterator(); - while (itf->more()) - if (elem == itf->next()) - return true; - SMDS_VolumeIteratorPtr itv = volumesIterator(); - while (itv->more()) - if (elem == itv->next()) - return true; return false; } @@ -3593,6 +3768,101 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1, } } +//======================================================================= +//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, + const SMDS_MeshNode * nCenter) +{ + return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter, + 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 nCenter, 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), + (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter), + 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, + const SMDS_MeshNode * nCenter, + int ID) +{ + if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0; + if(hasConstructionEdges()) { + // creation quadratic edges - not implemented + return 0; + } + else + { + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(nCenter->getVtkId()); + + SMDS_MeshFace * face = 0; + SMDS_VtkFace *facevtk = myFacePool->getNew(); + facevtk->init(nodeIds, this); + if (!this->registerElement(ID,facevtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL); + myFacePool->destroy(facevtk); + return 0; + } + face = facevtk; + adjustmyCellsCapacity(ID); + myCells[ID] = face; + myInfo.myNbBiQuadQuadrangles++; + +// if (!registerElement(ID, face)) { +// RemoveElement(face, false); +// face = NULL; +// } + return face; + } +} + //======================================================================= //function : AddVolume @@ -4087,6 +4357,184 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return volvtk; } +//======================================================================= +//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, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter) +{ + 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, + n1234, n1256, n2367, n3478, n1458, n5678, nCenter, + 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 n1234,int n1256,int n2367,int n3478, + int n1458,int n5678,int nCenter, 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), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678), + (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter), + 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, + const SMDS_MeshNode * n1234, + const SMDS_MeshNode * n1256, + const SMDS_MeshNode * n2367, + const SMDS_MeshNode * n3478, + const SMDS_MeshNode * n1458, + const SMDS_MeshNode * n5678, + const SMDS_MeshNode * nCenter, + int ID) +{ + if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 || + !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 || + !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter ) + return 0; + if(hasConstructionFaces()) { + return 0; + // creation quadratic faces - not implemented + } + // --- retrieve nodes ID + vector nodeIds; + nodeIds.clear(); + nodeIds.push_back(n1->getVtkId()); + nodeIds.push_back(n4->getVtkId()); + nodeIds.push_back(n3->getVtkId()); + nodeIds.push_back(n2->getVtkId()); + + nodeIds.push_back(n5->getVtkId()); + nodeIds.push_back(n8->getVtkId()); + nodeIds.push_back(n7->getVtkId()); + nodeIds.push_back(n6->getVtkId()); + + nodeIds.push_back(n41->getVtkId()); + nodeIds.push_back(n34->getVtkId()); + nodeIds.push_back(n23->getVtkId()); + nodeIds.push_back(n12->getVtkId()); + + nodeIds.push_back(n85->getVtkId()); + nodeIds.push_back(n78->getVtkId()); + nodeIds.push_back(n67->getVtkId()); + nodeIds.push_back(n56->getVtkId()); + + nodeIds.push_back(n15->getVtkId()); + nodeIds.push_back(n48->getVtkId()); + nodeIds.push_back(n37->getVtkId()); + nodeIds.push_back(n26->getVtkId()); + + nodeIds.push_back(n1256->getVtkId()); + nodeIds.push_back(n3478->getVtkId()); + nodeIds.push_back(n1458->getVtkId()); + nodeIds.push_back(n2367->getVtkId()); + nodeIds.push_back(n1234->getVtkId()); + nodeIds.push_back(n5678->getVtkId()); + nodeIds.push_back(nCenter->getVtkId()); + + SMDS_VtkVolume *volvtk = myVolumePool->getNew(); + volvtk->init(nodeIds, this); + if (!this->registerElement(ID,volvtk)) + { + this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL); + myVolumePool->destroy(volvtk); + return 0; + } + adjustmyCellsCapacity(ID); + myCells[ID] = volvtk; + myInfo.myNbTriQuadHexas++; + + return volvtk; +} + + void SMDS_Mesh::updateNodeMinMax() { myNodeMin = 0; @@ -4235,7 +4683,7 @@ void SMDS_Mesh::Modified() } //! get last modification timeStamp -unsigned long SMDS_Mesh::GetMTime() +unsigned long SMDS_Mesh::GetMTime() const { return this->myModifTime; }