Back to index

salome-smesh  6.5.0
SMDS_Mesh.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH SMDS : implementation of Salome mesh data structure
00024 //
00025 #ifdef _MSC_VER
00026 #pragma warning(disable:4786)
00027 #endif
00028 
00029 #include "utilities.h"
00030 #include "SMDS_Mesh.hxx"
00031 #include "SMDS_VolumeOfNodes.hxx"
00032 #include "SMDS_VolumeOfFaces.hxx"
00033 #include "SMDS_FaceOfNodes.hxx"
00034 #include "SMDS_FaceOfEdges.hxx"
00035 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
00036 #include "SMDS_PolygonalFaceOfNodes.hxx"
00037 #include "SMDS_QuadraticEdge.hxx"
00038 #include "SMDS_QuadraticFaceOfNodes.hxx"
00039 #include "SMDS_QuadraticVolumeOfNodes.hxx"
00040 #include "SMDS_SpacePosition.hxx"
00041 #include "SMDS_UnstructuredGrid.hxx"
00042 
00043 #include <vtkUnstructuredGrid.h>
00044 #include <vtkUnstructuredGridWriter.h>
00045 #include <vtkUnsignedCharArray.h>
00046 #include <vtkCell.h>
00047 #include <vtkCellLinks.h>
00048 #include <vtkIdList.h>
00049 
00050 #include <algorithm>
00051 #include <map>
00052 #include <iostream>
00053 #include <fstream>
00054 using namespace std;
00055 
00056 #ifndef WIN32
00057 #include <sys/sysinfo.h>
00058 #endif
00059 
00060 // number of added entities to check memory after
00061 #define CHECKMEMORY_INTERVAL 100000
00062 
00063 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
00064 int SMDS_Mesh::chunkSize = 1024;
00065 
00066 
00067 //================================================================================
00073 //================================================================================
00074 
00075 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
00076 {
00077 #ifndef WIN32
00078   struct sysinfo si;
00079   int err = sysinfo( &si );
00080   if ( err )
00081     return -1;
00082 
00083   const unsigned long Mbyte = 1024 * 1024;
00084 
00085   static int limit = -1;
00086   if ( limit < 0 ) {
00087     int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
00088     if (status >= 0 ) {
00089       limit = WEXITSTATUS(status);
00090     }
00091     else {
00092       double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
00093       limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
00094     }
00095     if ( limit < 20 )
00096       limit = 20;
00097     else
00098       limit = int ( limit * 1.5 );
00099     MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
00100   }
00101 
00102   // compute separately to avoid overflow
00103   int freeMb =
00104     ( si.freeram  * si.mem_unit ) / Mbyte +
00105     ( si.freeswap * si.mem_unit ) / Mbyte;
00106   //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
00107 
00108   if ( freeMb > limit )
00109     return freeMb - limit;
00110 
00111   if ( doNotRaise )
00112     return 0;
00113 
00114   MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
00115   throw std::bad_alloc();
00116 #else
00117   return -1;
00118 #endif
00119 }
00120 
00124 SMDS_Mesh::SMDS_Mesh()
00125         :myParent(NULL),
00126          myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
00127          myElementIDFactory(new SMDS_MeshElementIDFactory()),
00128          myHasConstructionEdges(false), myHasConstructionFaces(false),
00129          myHasInverseElements(true),
00130          myNodeMin(0), myNodeMax(0),
00131          myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),
00132          myModified(false), myModifTime(0), myCompactTime(0),
00133          xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
00134 {
00135   myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
00136   MESSAGE("myMeshId=" << myMeshId);
00137   MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
00138   MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
00139   MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
00140   MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
00141   MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
00142   MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
00143   myNodeIDFactory->SetMesh(this);
00144   myElementIDFactory->SetMesh(this);
00145   _meshList.push_back(this);
00146   myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
00147   myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
00148   myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
00149   myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
00150 
00151   myNodes.clear();
00152   myCells.clear();
00153   //myCellIdSmdsToVtk.clear();
00154   myCellIdVtkToSmds.clear();
00155   myGrid = SMDS_UnstructuredGrid::New();
00156   myGrid->setSMDS_mesh(this);
00157   myGrid->Initialize();
00158   myGrid->Allocate();
00159   vtkPoints* points = vtkPoints::New();
00160   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
00161   // using double type for storing coordinates of nodes instead float.
00162   points->SetDataType(VTK_DOUBLE);
00163   points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
00164   myGrid->SetPoints( points );
00165   points->Delete();
00166   myGrid->BuildLinks();
00167   this->Modified();
00168 }
00169 
00175 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
00176         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
00177          myElementIDFactory(parent->myElementIDFactory),
00178          myHasConstructionEdges(false), myHasConstructionFaces(false),
00179          myHasInverseElements(true),
00180          myNodePool(parent->myNodePool),
00181          myEdgePool(parent->myEdgePool),
00182          myFacePool(parent->myFacePool),
00183          myVolumePool(parent->myVolumePool)
00184 {
00185 }
00186 
00190 
00191 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
00192 {
00193         SMDS_Mesh *submesh = new SMDS_Mesh(this);
00194         myChildren.insert(myChildren.end(), submesh);
00195         return submesh;
00196 }
00197 
00203 
00204 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
00205 {
00206   return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
00207 }
00208 
00214 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
00215 {
00216   // find the MeshNode corresponding to ID
00217   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
00218   if(!node){
00219     if (ID < 1)
00220       {
00221         MESSAGE("=============>  Bad Node Id: " << ID);
00222         ID = myNodeIDFactory->GetFreeID();
00223       }
00224     myNodeIDFactory->adjustMaxId(ID);
00225     SMDS_MeshNode * node = myNodePool->getNew();
00226     node->init(ID, myMeshId, 0, x, y, z);
00227 
00228     if (ID >= myNodes.size())
00229     {
00230         myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
00231 //         MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
00232     }
00233     myNodes[ID] = node;
00234     myNodeIDFactory->BindID(ID,node);
00235     myInfo.myNbNodes++;
00236     myModified = true;
00237     this->adjustBoundingBox(x, y, z);
00238     return node;
00239   }else
00240     return NULL;
00241 }
00242 
00247 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
00248 {
00249   SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
00250   if (!node) return NULL;
00251   return SMDS_Mesh::Add0DElementWithID(node, ID);
00252 }
00253 
00258 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
00259 {
00260   return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
00261 }
00262 
00270 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
00271 {
00272   if (!n) return 0;
00273 
00274   if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
00275   //MESSAGE("Add0DElementWithID" << ID)
00276   SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
00277   if (myElementIDFactory->BindID(ID, el0d)) {
00278     //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
00279     //node->AddInverseElement(el0d);// --- fait avec BindID
00280     adjustmyCellsCapacity(ID);
00281     myCells[ID] = el0d;
00282     myInfo.myNb0DElements++;
00283     return el0d;
00284   }
00285 
00286   delete el0d;
00287   return NULL;
00288 }
00289 
00294 
00295 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
00296 {
00297   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00298   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00299   if(!node1 || !node2) return NULL;
00300   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
00301 }
00302 
00307 
00308 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
00309                                   const SMDS_MeshNode * node2)
00310 {
00311   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
00312 }
00313 
00322 
00323 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
00324                                         const SMDS_MeshNode * n2,
00325                                         int ID)
00326 {
00327   if ( !n1 || !n2 ) return 0;
00328   SMDS_MeshEdge * edge = 0;
00329 
00330   // --- retreive nodes ID
00331   vector<vtkIdType> nodeIds;
00332   nodeIds.clear();
00333   nodeIds.push_back(n1->getVtkId());
00334   nodeIds.push_back(n2->getVtkId());
00335 
00336   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
00337   edgevtk->init(nodeIds, this);
00338   if (!this->registerElement(ID,edgevtk))
00339     {
00340       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
00341       myEdgePool->destroy(edgevtk);
00342       return 0;
00343     }
00344   edge = edgevtk;
00345   adjustmyCellsCapacity(ID);
00346   myCells[ID] = edge;
00347   myInfo.myNbEdges++;
00348 
00349 //  if (edge && !registerElement(ID, edge))
00350 //  {
00351 //    RemoveElement(edge, false);
00352 //    edge = NULL;
00353 //  }
00354   return edge;
00355 }
00356 
00361 
00362 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
00363                                   const SMDS_MeshNode * n2,
00364                                   const SMDS_MeshNode * n3)
00365 {
00366   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
00367 }
00368 
00372 
00373 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
00374 {
00375   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00376   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00377   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00378   if(!node1 || !node2 || !node3) return NULL;
00379   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
00380 }
00381 
00385 
00386 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
00387                                         const SMDS_MeshNode * n2,
00388                                         const SMDS_MeshNode * n3,
00389                                         int ID)
00390 {
00391   //MESSAGE("AddFaceWithID " << ID)
00392   SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
00393 
00394 //  if (face && !registerElement(ID, face)) {
00395 //    RemoveElement(face, false);
00396 //    face = NULL;
00397 //  }
00398   return face;
00399 }
00400 
00405 
00406 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
00407                                   const SMDS_MeshNode * n2,
00408                                   const SMDS_MeshNode * n3,
00409                                   const SMDS_MeshNode * n4)
00410 {
00411   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
00412 }
00413 
00417 
00418 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
00419                                         int idnode2,
00420                                         int idnode3,
00421                                         int idnode4,
00422                                         int ID)
00423 {
00424   SMDS_MeshNode *node1, *node2, *node3, *node4;
00425   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00426   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00427   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00428   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00429   if(!node1 || !node2 || !node3 || !node4) return NULL;
00430   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
00431 }
00432 
00436 
00437 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
00438                                         const SMDS_MeshNode * n2,
00439                                         const SMDS_MeshNode * n3,
00440                                         const SMDS_MeshNode * n4,
00441                                         int ID)
00442 {
00443   //MESSAGE("AddFaceWithID " << ID);
00444   SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
00445 
00446 //  if (face && !registerElement(ID, face)) {
00447 //    RemoveElement(face, false);
00448 //    face = NULL;
00449 //  }
00450   return face;
00451 }
00452 
00457 
00458 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
00459                                   const SMDS_MeshEdge * e2,
00460                                   const SMDS_MeshEdge * e3)
00461 {
00462   if (!hasConstructionEdges())
00463     return NULL;
00464      //MESSAGE("AddFaceWithID");
00465  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
00466 }
00467 
00471 
00472 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
00473                                         const SMDS_MeshEdge * e2,
00474                                         const SMDS_MeshEdge * e3,
00475                                         int ID)
00476 {
00477   if (!hasConstructionEdges())
00478     return NULL;
00479   if ( !e1 || !e2 || !e3 ) return 0;
00480 
00481   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00482   MESSAGE("AddFaceWithID" << ID);
00483 
00484   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
00485   adjustmyCellsCapacity(ID);
00486   myCells[ID] = face;
00487   myInfo.myNbTriangles++;
00488 
00489   if (!registerElement(ID, face)) {
00490     registerElement(myElementIDFactory->GetFreeID(), face);
00491     //RemoveElement(face, false);
00492     //face = NULL;
00493   }
00494   return face;
00495 }
00496 
00501 
00502 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
00503                                   const SMDS_MeshEdge * e2,
00504                                   const SMDS_MeshEdge * e3,
00505                                   const SMDS_MeshEdge * e4)
00506 {
00507   if (!hasConstructionEdges())
00508     return NULL;
00509      //MESSAGE("AddFaceWithID" );
00510  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
00511 }
00512 
00516 
00517 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
00518                                         const SMDS_MeshEdge * e2,
00519                                         const SMDS_MeshEdge * e3,
00520                                         const SMDS_MeshEdge * e4,
00521                                         int ID)
00522 {
00523   if (!hasConstructionEdges())
00524     return NULL;
00525   MESSAGE("AddFaceWithID" << ID);
00526   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
00527   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00528   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
00529   adjustmyCellsCapacity(ID);
00530   myCells[ID] = face;
00531   myInfo.myNbQuadrangles++;
00532 
00533   if (!registerElement(ID, face))
00534   {
00535     registerElement(myElementIDFactory->GetFreeID(), face);
00536     //RemoveElement(face, false);
00537     //face = NULL;
00538   }
00539   return face;
00540 }
00541 
00546 
00547 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
00548                                       const SMDS_MeshNode * n2,
00549                                       const SMDS_MeshNode * n3,
00550                                       const SMDS_MeshNode * n4)
00551 {
00552   int ID = myElementIDFactory->GetFreeID();
00553     //MESSAGE("AddVolumeWithID " << ID);
00554   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
00555   if(v==NULL) myElementIDFactory->ReleaseID(ID);
00556   return v;
00557 }
00558 
00565 
00566 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
00567                                              int idnode2,
00568                                              int idnode3,
00569                                              int idnode4,
00570                                              int ID)
00571 {
00572     //MESSAGE("AddVolumeWithID" << ID);
00573   SMDS_MeshNode *node1, *node2, *node3, *node4;
00574   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00575   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00576   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00577   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00578   if(!node1 || !node2 || !node3 || !node4) return NULL;
00579   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
00580 }
00581 
00587 
00588 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
00589                                             const SMDS_MeshNode * n2,
00590                                             const SMDS_MeshNode * n3,
00591                                             const SMDS_MeshNode * n4,
00592                                             int ID)
00593 {
00594     //MESSAGE("AddVolumeWithID " << ID);
00595   SMDS_MeshVolume* volume = 0;
00596   if ( !n1 || !n2 || !n3 || !n4) return volume;
00597   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00598   if(hasConstructionFaces()) {
00599     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
00600     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
00601     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
00602     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
00603     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
00604     adjustmyCellsCapacity(ID);
00605     myCells[ID] = volume;
00606     myInfo.myNbTetras++;
00607   }
00608   else if(hasConstructionEdges()) {
00609     MESSAGE("Error : Not implemented");
00610     return NULL;
00611   }
00612   else {
00613     // --- retrieve nodes ID
00614     vector<vtkIdType> nodeIds;
00615     nodeIds.clear();
00616     nodeIds.push_back(n1->getVtkId());
00617     nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
00618     nodeIds.push_back(n2->getVtkId());
00619     nodeIds.push_back(n4->getVtkId());
00620 
00621     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
00622     volvtk->init(nodeIds, this);
00623     if (!this->registerElement(ID,volvtk))
00624       {
00625         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
00626         myVolumePool->destroy(volvtk);
00627         return 0;
00628       }
00629     volume = volvtk;
00630     adjustmyCellsCapacity(ID);
00631     myCells[ID] = volume;
00632     myInfo.myNbTetras++;
00633   }
00634 
00635 //  if (!registerElement(ID, volume)) {
00636 //    RemoveElement(volume, false);
00637 //    volume = NULL;
00638 //  }
00639   return volume;
00640 }
00641 
00647 
00648 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
00649                                       const SMDS_MeshNode * n2,
00650                                       const SMDS_MeshNode * n3,
00651                                       const SMDS_MeshNode * n4,
00652                                       const SMDS_MeshNode * n5)
00653 {
00654   int ID = myElementIDFactory->GetFreeID();
00655     //MESSAGE("AddVolumeWithID " << ID);
00656   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
00657   if(v==NULL) myElementIDFactory->ReleaseID(ID);
00658   return v;
00659 }
00660 
00668 
00669 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
00670                                              int idnode2,
00671                                              int idnode3,
00672                                              int idnode4,
00673                                              int idnode5,
00674                                              int ID)
00675 {
00676     //MESSAGE("AddVolumeWithID " << ID);
00677   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
00678   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00679   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00680   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00681   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00682   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
00683   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
00684   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
00685 }
00686 
00693 
00694 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
00695                                             const SMDS_MeshNode * n2,
00696                                             const SMDS_MeshNode * n3,
00697                                             const SMDS_MeshNode * n4,
00698                                             const SMDS_MeshNode * n5,
00699                                             int ID)
00700 {
00701     //MESSAGE("AddVolumeWithID " << ID);
00702   SMDS_MeshVolume* volume = 0;
00703   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
00704   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00705   if(hasConstructionFaces()) {
00706     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
00707     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
00708     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
00709     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
00710     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
00711     adjustmyCellsCapacity(ID);
00712     myCells[ID] = volume;
00713     myInfo.myNbPyramids++;
00714   }
00715   else if(hasConstructionEdges()) {
00716     MESSAGE("Error : Not implemented");
00717     return NULL;
00718   }
00719   else {
00720     // --- retrieve nodes ID
00721     vector<vtkIdType> nodeIds;
00722     nodeIds.clear();
00723     nodeIds.push_back(n1->getVtkId());
00724     nodeIds.push_back(n4->getVtkId());
00725     nodeIds.push_back(n3->getVtkId());
00726     nodeIds.push_back(n2->getVtkId());
00727     nodeIds.push_back(n5->getVtkId());
00728 
00729     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
00730     volvtk->init(nodeIds, this);
00731     if (!this->registerElement(ID,volvtk))
00732       {
00733         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
00734         myVolumePool->destroy(volvtk);
00735         return 0;
00736       }
00737     volume = volvtk;
00738     adjustmyCellsCapacity(ID);
00739     myCells[ID] = volume;
00740     myInfo.myNbPyramids++;
00741   }
00742 
00743 //  if (!registerElement(ID, volume)) {
00744 //    RemoveElement(volume, false);
00745 //    volume = NULL;
00746 //  }
00747   return volume;
00748 }
00749 
00755 
00756 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
00757                                       const SMDS_MeshNode * n2,
00758                                       const SMDS_MeshNode * n3,
00759                                       const SMDS_MeshNode * n4,
00760                                       const SMDS_MeshNode * n5,
00761                                       const SMDS_MeshNode * n6)
00762 {
00763   int ID = myElementIDFactory->GetFreeID();
00764     //MESSAGE("AddVolumeWithID " << ID);
00765   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
00766   if(v==NULL) myElementIDFactory->ReleaseID(ID);
00767   return v;
00768 }
00769 
00777 
00778 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
00779                                              int idnode2,
00780                                              int idnode3,
00781                                              int idnode4,
00782                                              int idnode5,
00783                                              int idnode6,
00784                                              int ID)
00785 {
00786     //MESSAGE("AddVolumeWithID " << ID);
00787   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
00788   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00789   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00790   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00791   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00792   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
00793   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
00794   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
00795   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
00796 }
00797 
00804 
00805 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
00806                                             const SMDS_MeshNode * n2,
00807                                             const SMDS_MeshNode * n3,
00808                                             const SMDS_MeshNode * n4,
00809                                             const SMDS_MeshNode * n5,
00810                                             const SMDS_MeshNode * n6,
00811                                             int ID)
00812 {
00813     //MESSAGE("AddVolumeWithID " << ID);
00814   SMDS_MeshVolume* volume = 0;
00815   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
00816   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00817   if(hasConstructionFaces()) {
00818     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
00819     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
00820     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
00821     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
00822     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
00823     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
00824     adjustmyCellsCapacity(ID);
00825     myCells[ID] = volume;
00826     myInfo.myNbPrisms++;
00827   }
00828   else if(hasConstructionEdges()) {
00829     MESSAGE("Error : Not implemented");
00830     return NULL;
00831   }
00832   else {
00833     // --- retrieve nodes ID
00834     vector<vtkIdType> nodeIds;
00835     nodeIds.clear();
00836     nodeIds.push_back(n1->getVtkId());
00837     nodeIds.push_back(n2->getVtkId());
00838     nodeIds.push_back(n3->getVtkId());
00839     nodeIds.push_back(n4->getVtkId());
00840     nodeIds.push_back(n5->getVtkId());
00841     nodeIds.push_back(n6->getVtkId());
00842 
00843     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
00844     volvtk->init(nodeIds, this);
00845     if (!this->registerElement(ID,volvtk))
00846       {
00847         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
00848         myVolumePool->destroy(volvtk);
00849         return 0;
00850       }
00851     volume = volvtk;
00852     adjustmyCellsCapacity(ID);
00853     myCells[ID] = volume;
00854     myInfo.myNbPrisms++;
00855   }
00856 
00857 //  if (!registerElement(ID, volume)) {
00858 //    RemoveElement(volume, false);
00859 //    volume = NULL;
00860 //  }
00861   return volume;
00862 }
00863 
00868 
00869 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
00870                                       const SMDS_MeshNode * n2,
00871                                       const SMDS_MeshNode * n3,
00872                                       const SMDS_MeshNode * n4,
00873                                       const SMDS_MeshNode * n5,
00874                                       const SMDS_MeshNode * n6,
00875                                       const SMDS_MeshNode * n7,
00876                                       const SMDS_MeshNode * n8,
00877                                       const SMDS_MeshNode * n9,
00878                                       const SMDS_MeshNode * n10,
00879                                       const SMDS_MeshNode * n11,
00880                                       const SMDS_MeshNode * n12)
00881 {
00882   int ID = myElementIDFactory->GetFreeID();
00883   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
00884                                                    n7, n8, n9, n10, n11, n12,
00885                                                    ID);
00886   if(v==NULL) myElementIDFactory->ReleaseID(ID);
00887   return v;
00888 }
00889 
00896 
00897 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
00898                                              int idnode2,
00899                                              int idnode3,
00900                                              int idnode4,
00901                                              int idnode5,
00902                                              int idnode6,
00903                                              int idnode7,
00904                                              int idnode8,
00905                                              int idnode9,
00906                                              int idnode10,
00907                                              int idnode11,
00908                                              int idnode12,
00909                                              int ID)
00910 {
00911   SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00912   SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00913   SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00914   SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00915   SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
00916   SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
00917   SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
00918   SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
00919   SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
00920   SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
00921   SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
00922   SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
00923   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
00924                                     node7, node8, node9, node10, node11, node12,
00925                                     ID);
00926 }
00927 
00933 
00934 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
00935                                             const SMDS_MeshNode * n2,
00936                                             const SMDS_MeshNode * n3,
00937                                             const SMDS_MeshNode * n4,
00938                                             const SMDS_MeshNode * n5,
00939                                             const SMDS_MeshNode * n6,
00940                                             const SMDS_MeshNode * n7,
00941                                             const SMDS_MeshNode * n8,
00942                                             const SMDS_MeshNode * n9,
00943                                             const SMDS_MeshNode * n10,
00944                                             const SMDS_MeshNode * n11,
00945                                             const SMDS_MeshNode * n12,
00946                                             int ID)
00947 {
00948   SMDS_MeshVolume* volume = 0;
00949   if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
00950      !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
00951     return volume;
00952   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00953   if(hasConstructionFaces()) {
00954     MESSAGE("Error : Not implemented");
00955     return NULL;
00956   }
00957   else if(hasConstructionEdges()) {
00958     MESSAGE("Error : Not implemented");
00959     return NULL;
00960   }
00961   else {
00962     // --- retrieve nodes ID
00963     vector<vtkIdType> nodeIds;
00964     nodeIds.push_back(n1->getVtkId());
00965     nodeIds.push_back(n6->getVtkId());
00966     nodeIds.push_back(n5->getVtkId());
00967     nodeIds.push_back(n4->getVtkId());
00968     nodeIds.push_back(n3->getVtkId());
00969     nodeIds.push_back(n2->getVtkId());
00970 
00971     nodeIds.push_back(n7->getVtkId());
00972     nodeIds.push_back(n12->getVtkId());
00973     nodeIds.push_back(n11->getVtkId());
00974     nodeIds.push_back(n10->getVtkId());
00975     nodeIds.push_back(n9->getVtkId());
00976     nodeIds.push_back(n8->getVtkId());
00977 
00978     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
00979     volvtk->init(nodeIds, this);
00980     if (!this->registerElement(ID,volvtk))
00981       {
00982         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
00983         myVolumePool->destroy(volvtk);
00984         return 0;
00985       }
00986     volume = volvtk;
00987     adjustmyCellsCapacity(ID);
00988     myCells[ID] = volume;
00989     myInfo.myNbHexPrism++;
00990   }
00991 
00992   return volume;
00993 }
00994 
01000 
01001 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
01002                                       const SMDS_MeshNode * n2,
01003                                       const SMDS_MeshNode * n3,
01004                                       const SMDS_MeshNode * n4,
01005                                       const SMDS_MeshNode * n5,
01006                                       const SMDS_MeshNode * n6,
01007                                       const SMDS_MeshNode * n7,
01008                                       const SMDS_MeshNode * n8)
01009 {
01010   int ID = myElementIDFactory->GetFreeID();
01011  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
01012   if(v==NULL) myElementIDFactory->ReleaseID(ID);
01013   return v;
01014 }
01015 
01023 
01024 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
01025                                              int idnode2,
01026                                              int idnode3,
01027                                              int idnode4,
01028                                              int idnode5,
01029                                              int idnode6,
01030                                              int idnode7,
01031                                              int idnode8,
01032                                              int ID)
01033 {
01034     //MESSAGE("AddVolumeWithID " << ID);
01035   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
01036   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
01037   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
01038   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
01039   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
01040   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
01041   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
01042   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
01043   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
01044   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
01045     return NULL;
01046   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
01047                                     node7, node8, ID);
01048 }
01049 
01057 
01058 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
01059                                             const SMDS_MeshNode * n2,
01060                                             const SMDS_MeshNode * n3,
01061                                             const SMDS_MeshNode * n4,
01062                                             const SMDS_MeshNode * n5,
01063                                             const SMDS_MeshNode * n6,
01064                                             const SMDS_MeshNode * n7,
01065                                             const SMDS_MeshNode * n8,
01066                                             int ID)
01067 {
01068     //MESSAGE("AddVolumeWithID " << ID);
01069   SMDS_MeshVolume* volume = 0;
01070   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
01071   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01072   if(hasConstructionFaces()) {
01073     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
01074     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
01075     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
01076     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
01077     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
01078     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
01079     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
01080     adjustmyCellsCapacity(ID);
01081     myCells[ID] = volume;
01082     myInfo.myNbHexas++;
01083   }
01084   else if(hasConstructionEdges()) {
01085     MESSAGE("Error : Not implemented");
01086     return NULL;
01087   }
01088   else {
01089     // --- retrieve nodes ID
01090     vector<vtkIdType> nodeIds;
01091     nodeIds.clear();
01092     nodeIds.push_back(n1->getVtkId());
01093     nodeIds.push_back(n4->getVtkId());
01094     nodeIds.push_back(n3->getVtkId());
01095     nodeIds.push_back(n2->getVtkId());
01096     nodeIds.push_back(n5->getVtkId());
01097     nodeIds.push_back(n8->getVtkId());
01098     nodeIds.push_back(n7->getVtkId());
01099     nodeIds.push_back(n6->getVtkId());
01100 
01101     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
01102     volvtk->init(nodeIds, this);
01103     if (!this->registerElement(ID,volvtk))
01104       {
01105         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
01106         myVolumePool->destroy(volvtk);
01107         return 0;
01108       }
01109     volume = volvtk;
01110     adjustmyCellsCapacity(ID);
01111     myCells[ID] = volume;
01112     myInfo.myNbHexas++;
01113   }
01114  
01115 //  if (!registerElement(ID, volume)) {
01116 //    RemoveElement(volume, false);
01117 //    volume = NULL;
01118 //  }
01119   return volume;
01120 }
01121 
01126 
01127 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
01128                                       const SMDS_MeshFace * f2,
01129                                       const SMDS_MeshFace * f3,
01130                                       const SMDS_MeshFace * f4)
01131 {
01132     //MESSAGE("AddVolumeWithID");
01133   if (!hasConstructionFaces())
01134     return NULL;
01135   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
01136 }
01137 
01143 
01144 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01145                                             const SMDS_MeshFace * f2,
01146                                             const SMDS_MeshFace * f3,
01147                                             const SMDS_MeshFace * f4,
01148                                             int ID)
01149 {
01150   MESSAGE("AddVolumeWithID" << ID);
01151   if (!hasConstructionFaces())
01152     return NULL;
01153   if ( !f1 || !f2 || !f3 || !f4) return 0;
01154   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01155   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
01156   adjustmyCellsCapacity(ID);
01157   myCells[ID] = volume;
01158   myInfo.myNbTetras++;
01159 
01160   if (!registerElement(ID, volume)) {
01161     registerElement(myElementIDFactory->GetFreeID(), volume);
01162     //RemoveElement(volume, false);
01163     //volume = NULL;
01164   }
01165   return volume;
01166 }
01167 
01172 
01173 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
01174                                       const SMDS_MeshFace * f2,
01175                                       const SMDS_MeshFace * f3,
01176                                       const SMDS_MeshFace * f4,
01177                                       const SMDS_MeshFace * f5)
01178 {
01179      //MESSAGE("AddVolumeWithID");
01180  if (!hasConstructionFaces())
01181     return NULL;
01182   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
01183 }
01184 
01190 
01191 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01192                                             const SMDS_MeshFace * f2,
01193                                             const SMDS_MeshFace * f3,
01194                                             const SMDS_MeshFace * f4,
01195                                             const SMDS_MeshFace * f5,
01196                                             int ID)
01197 {
01198   MESSAGE("AddVolumeWithID" << ID);
01199   if (!hasConstructionFaces())
01200     return NULL;
01201   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
01202   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01203   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
01204   adjustmyCellsCapacity(ID);
01205   myCells[ID] = volume;
01206   myInfo.myNbPyramids++;
01207 
01208   if (!registerElement(ID, volume)) {
01209     registerElement(myElementIDFactory->GetFreeID(), volume);
01210     //RemoveElement(volume, false);
01211     //volume = NULL;
01212   }
01213   return volume;
01214 }
01215 
01220 
01221 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
01222                                       const SMDS_MeshFace * f2,
01223                                       const SMDS_MeshFace * f3,
01224                                       const SMDS_MeshFace * f4,
01225                                       const SMDS_MeshFace * f5,
01226                                       const SMDS_MeshFace * f6)
01227 {
01228      //MESSAGE("AddVolumeWithID" );
01229  if (!hasConstructionFaces())
01230     return NULL;
01231   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
01232 }
01233 
01239 
01240 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01241                                             const SMDS_MeshFace * f2,
01242                                             const SMDS_MeshFace * f3,
01243                                             const SMDS_MeshFace * f4,
01244                                             const SMDS_MeshFace * f5,
01245                                             const SMDS_MeshFace * f6,
01246                                             int ID)
01247 {
01248   MESSAGE("AddVolumeWithID" << ID);
01249   if (!hasConstructionFaces())
01250     return NULL;
01251   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
01252   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01253   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
01254   adjustmyCellsCapacity(ID);
01255   myCells[ID] = volume;
01256   myInfo.myNbPrisms++;
01257 
01258   if (!registerElement(ID, volume)) {
01259     registerElement(myElementIDFactory->GetFreeID(), volume);
01260     //RemoveElement(volume, false);
01261     //volume = NULL;
01262   }
01263   return volume;
01264 }
01265 
01269 
01270 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
01271                                                   const int           ID)
01272 {
01273   int nbNodes = nodes_ids.size();
01274   vector<const SMDS_MeshNode*> nodes (nbNodes);
01275   for (int i = 0; i < nbNodes; i++) {
01276     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
01277     if (!nodes[i]) return NULL;
01278   }
01279   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
01280 }
01281 
01285 
01286 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
01287                           (const vector<const SMDS_MeshNode*> & nodes,
01288                            const int                            ID)
01289 {
01290   SMDS_MeshFace * face;
01291 
01292   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01293   if (hasConstructionEdges())
01294     {
01295       MESSAGE("Error : Not implemented");
01296       return NULL;
01297     }
01298   else
01299     {
01300 //#ifdef VTK_HAVE_POLYHEDRON
01301     //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
01302     vector<vtkIdType> nodeIds;
01303     nodeIds.clear();
01304     vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
01305     for ( ; it != nodes.end(); ++it)
01306       nodeIds.push_back((*it)->getVtkId());
01307 
01308     SMDS_VtkFace *facevtk = myFacePool->getNew();
01309     facevtk->initPoly(nodeIds, this);
01310     if (!this->registerElement(ID,facevtk))
01311       {
01312         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01313         myFacePool->destroy(facevtk);
01314         return 0;
01315       }
01316     face = facevtk;
01317 //#else
01318 //    MESSAGE("AddPolygonalFaceWithID smds " << ID);
01319 //     for ( int i = 0; i < nodes.size(); ++i )
01320 //      if ( !nodes[ i ] ) return 0;
01321 //      face = new SMDS_PolygonalFaceOfNodes(nodes);
01322 //#endif
01323       adjustmyCellsCapacity(ID);
01324       myCells[ID] = face;
01325       myInfo.myNbPolygons++;
01326     }
01327 
01328 //#ifndef VTK_HAVE_POLYHEDRON
01329 //  if (!registerElement(ID, face))
01330 //    {
01331 //      registerElement(myElementIDFactory->GetFreeID(), face);
01332 //      //RemoveElement(face, false);
01333 //      //face = NULL;
01334 //    }
01335 //#endif
01336  return face;
01337 }
01338 
01343 
01344 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
01345 {
01346   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
01347 }
01348 
01355 
01356 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
01357                              (const vector<int> & nodes_ids,
01358                               const vector<int> & quantities,
01359                               const int           ID)
01360 {
01361   int nbNodes = nodes_ids.size();
01362   vector<const SMDS_MeshNode*> nodes (nbNodes);
01363   for (int i = 0; i < nbNodes; i++) {
01364     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
01365     if (!nodes[i]) return NULL;
01366   }
01367   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
01368 }
01369 
01375 
01376 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
01377                             (const vector<const SMDS_MeshNode*>& nodes,
01378                              const vector<int>                 & quantities,
01379                              const int                           ID)
01380 {
01381   SMDS_MeshVolume* volume = 0;
01382   if ( nodes.empty() || quantities.empty() )
01383     return NULL;
01384   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01385   if (hasConstructionFaces())
01386     {
01387       MESSAGE("Error : Not implemented");
01388       return NULL;
01389     }
01390   else if (hasConstructionEdges())
01391     {
01392       MESSAGE("Error : Not implemented");
01393       return NULL;
01394     }
01395   else
01396     {
01397 //#ifdef VTK_HAVE_POLYHEDRON
01398       //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
01399       vector<vtkIdType> nodeIds;
01400       nodeIds.clear();
01401       vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
01402       for (; it != nodes.end(); ++it)
01403         nodeIds.push_back((*it)->getVtkId());
01404 
01405       SMDS_VtkVolume *volvtk = myVolumePool->getNew();
01406       volvtk->initPoly(nodeIds, quantities, this);
01407       if (!this->registerElement(ID, volvtk))
01408         {
01409           this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
01410           myVolumePool->destroy(volvtk);
01411           return 0;
01412         }
01413       volume = volvtk;
01414 //#else
01415 //      MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
01416 //      for ( int i = 0; i < nodes.size(); ++i )
01417 //      if ( !nodes[ i ] ) return 0;
01418 //      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
01419 //#endif
01420       adjustmyCellsCapacity(ID);
01421       myCells[ID] = volume;
01422       myInfo.myNbPolyhedrons++;
01423     }
01424 
01425 //#ifndef VTK_HAVE_POLYHEDRON
01426 //  if (!registerElement(ID, volume))
01427 //    {
01428 //      registerElement(myElementIDFactory->GetFreeID(), volume);
01429 //      //RemoveElement(volume, false);
01430 //      //volume = NULL;
01431 //    }
01432 //#endif
01433   return volume;
01434 }
01435 
01440 
01441 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
01442                             (const vector<const SMDS_MeshNode*> & nodes,
01443                              const vector<int>                  & quantities)
01444 {
01445   int ID = myElementIDFactory->GetFreeID();
01446   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
01447   if (v == NULL) myElementIDFactory->ReleaseID(ID);
01448   return v;
01449 }
01450 
01451 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
01452 {
01453   int ID = myElementIDFactory->GetFreeID();
01454   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
01455   if (v == NULL) myElementIDFactory->ReleaseID(ID);
01456   return v;
01457 }
01458 
01459 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
01460 {
01461   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
01462   volvtk->init(vtkNodeIds, this);
01463   if (!this->registerElement(ID,volvtk))
01464     {
01465       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
01466       myVolumePool->destroy(volvtk);
01467       return 0;
01468     }
01469   adjustmyCellsCapacity(ID);
01470   myCells[ID] = volvtk;
01471   vtkIdType aVtkType = volvtk->GetVtkType();
01472   switch (aVtkType)
01473   {
01474     case VTK_TETRA:
01475       myInfo.myNbTetras++;
01476       break;
01477     case VTK_PYRAMID:
01478       myInfo.myNbPyramids++;
01479       break;
01480     case VTK_WEDGE:
01481       myInfo.myNbPrisms++;
01482       break;
01483     case VTK_HEXAHEDRON:
01484       myInfo.myNbHexas++;
01485       break;
01486     case VTK_QUADRATIC_TETRA:
01487       myInfo.myNbQuadTetras++;
01488       break;
01489     case VTK_QUADRATIC_PYRAMID:
01490       myInfo.myNbQuadPyramids++;
01491       break;
01492     case VTK_QUADRATIC_WEDGE:
01493       myInfo.myNbQuadPrisms++;
01494       break;
01495     case VTK_QUADRATIC_HEXAHEDRON:
01496       myInfo.myNbQuadHexas++;
01497       break;
01498 //#ifdef VTK_HAVE_POLYHEDRON
01499     case VTK_POLYHEDRON:
01500       myInfo.myNbPolyhedrons++;
01501       break;
01502 //#endif
01503     default:
01504       myInfo.myNbPolyhedrons++;
01505       break;
01506   }
01507   return volvtk;
01508 }
01509 
01510 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
01511 {
01512   int ID = myElementIDFactory->GetFreeID();
01513   SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
01514   if (f == NULL) myElementIDFactory->ReleaseID(ID);
01515   return f;
01516 }
01517 
01518 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
01519 {
01520   SMDS_VtkFace *facevtk = myFacePool->getNew();
01521   facevtk->init(vtkNodeIds, this);
01522   if (!this->registerElement(ID,facevtk))
01523     {
01524       this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01525       myFacePool->destroy(facevtk);
01526       return 0;
01527     }
01528   adjustmyCellsCapacity(ID);
01529   myCells[ID] = facevtk;
01530   vtkIdType aVtkType = facevtk->GetVtkType();
01531   switch (aVtkType)
01532   {
01533     case VTK_TRIANGLE:
01534       myInfo.myNbTriangles++;
01535       break;
01536     case VTK_QUAD:
01537       myInfo.myNbQuadrangles++;
01538       break;
01539     case VTK_QUADRATIC_TRIANGLE:
01540       myInfo.myNbQuadTriangles++;
01541       break;
01542     case VTK_QUADRATIC_QUAD:
01543       myInfo.myNbQuadQuadrangles++;
01544       break;
01545     case VTK_BIQUADRATIC_QUAD:
01546       myInfo.myNbBiQuadQuadrangles++;
01547       break;
01548     case VTK_POLYGON:
01549       myInfo.myNbPolygons++;
01550       break;
01551      default:
01552       myInfo.myNbPolygons++;
01553   }
01554   return facevtk;
01555 }
01556 
01560 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
01561 {
01562   //MESSAGE("registerElement " << ID);
01563   if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
01564   {
01565     MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
01566     return false;
01567   }
01568 
01569   element->myID = ID;
01570   element->myMeshId = myMeshId;
01571 
01572   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
01573   MYASSERT(cell);
01574   int vtkId = cell->getVtkId();  
01575   if (vtkId == -1)
01576     vtkId = myElementIDFactory->SetInVtkGrid(element);
01577 
01578   if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
01579   {
01580 //     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
01581     myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
01582   }
01583   myCellIdVtkToSmds[vtkId] = ID;
01584 
01585   myElementIDFactory->updateMinMax(ID);
01586   return true;
01587 }
01588 
01592 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
01593 {
01594   if (ID < 1 || ID >= myNodes.size())
01595   {
01596 //     MESSAGE("------------------------------------------------------------------------- ");
01597 //     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
01598 //     MESSAGE("------------------------------------------------------------------------- ");
01599     return 0;
01600   }
01601   return (const SMDS_MeshNode *)myNodes[ID];
01602 }
01603 
01607 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
01608 {
01609   // TODO if needed use mesh->nodeIdFromVtkToSmds
01610   if (vtkId < 0 || vtkId >= (myNodes.size() -1))
01611   {
01612     MESSAGE("------------------------------------------------------------------------- ");
01613     MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
01614     MESSAGE("------------------------------------------------------------------------- ");
01615     return 0;
01616   }
01617   return (const SMDS_MeshNode *)myNodes[vtkId+1];
01618 }
01619 
01624 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
01625                                           const SMDS_MeshNode * node2,
01626                                           const SMDS_MeshNode * node3,
01627                                           int ID)
01628 {
01629   if ( !node1 || !node2 || !node3) return 0;
01630   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01631   if(hasConstructionEdges())
01632   {
01633     SMDS_MeshEdge *edge1, *edge2, *edge3;
01634     edge1=FindEdgeOrCreate(node1,node2);
01635     edge2=FindEdgeOrCreate(node2,node3);
01636     edge3=FindEdgeOrCreate(node3,node1);
01637 
01638     //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
01639     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
01640     adjustmyCellsCapacity(ID);
01641     myCells[ID] = face;
01642     myInfo.myNbTriangles++;
01643     return face;
01644   }
01645   else
01646   {
01647     // --- retrieve nodes ID
01648     vector<vtkIdType> nodeIds;
01649     nodeIds.clear();
01650     nodeIds.push_back(node1->getVtkId());
01651     nodeIds.push_back(node2->getVtkId());
01652     nodeIds.push_back(node3->getVtkId());
01653 
01654     SMDS_MeshFace * face = 0;
01655     SMDS_VtkFace *facevtk = myFacePool->getNew();
01656     facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
01657     if (!this->registerElement(ID,facevtk))
01658       {
01659         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01660         myFacePool->destroy(facevtk);
01661         return 0;
01662       }
01663     face = facevtk;
01664     adjustmyCellsCapacity(ID);
01665     myCells[ID] = face;
01666     //MESSAGE("createTriangle " << ID << " " << face);
01667     myInfo.myNbTriangles++;
01668     return face;
01669   }
01670 }
01671 
01676 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
01677                                             const SMDS_MeshNode * node2,
01678                                             const SMDS_MeshNode * node3,
01679                                             const SMDS_MeshNode * node4,
01680                                             int ID)
01681 {
01682   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
01683   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01684   if(hasConstructionEdges())
01685   {
01686       //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
01687     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
01688     edge1=FindEdgeOrCreate(node1,node2);
01689     edge2=FindEdgeOrCreate(node2,node3);
01690     edge3=FindEdgeOrCreate(node3,node4);
01691     edge4=FindEdgeOrCreate(node4,node1);
01692 
01693     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
01694     adjustmyCellsCapacity(ID);
01695     myCells[ID] = face;
01696     myInfo.myNbQuadrangles++;
01697     return face;
01698   }
01699   else
01700   {
01701     // --- retrieve nodes ID
01702     vector<vtkIdType> nodeIds;
01703     nodeIds.clear();
01704     nodeIds.push_back(node1->getVtkId());
01705     nodeIds.push_back(node2->getVtkId());
01706     nodeIds.push_back(node3->getVtkId());
01707     nodeIds.push_back(node4->getVtkId());
01708 
01709     SMDS_MeshFace * face = 0;
01710     SMDS_VtkFace *facevtk = myFacePool->getNew();
01711     facevtk->init(nodeIds, this);
01712     if (!this->registerElement(ID,facevtk))
01713       {
01714         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01715         myFacePool->destroy(facevtk);
01716         return 0;
01717       }
01718     face = facevtk;
01719     adjustmyCellsCapacity(ID);
01720     myCells[ID] = face;
01721     myInfo.myNbQuadrangles++;
01722     return face;
01723   }
01724 }
01725 
01729 
01730 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
01731 {
01732     MESSAGE("RemoveNode");
01733         RemoveElement(node, true);
01734 }
01735 
01739 
01740 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
01741 {
01742     MESSAGE("Remove0DElement");
01743   RemoveElement(elem0d,true);
01744 }
01745 
01749 
01750 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
01751 {
01752     MESSAGE("RemoveEdge");
01753         RemoveElement(edge,true);
01754 }
01755 
01759 
01760 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
01761 {
01762     MESSAGE("RemoveFace");
01763         RemoveElement(face, true);
01764 }
01765 
01769 
01770 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
01771 {
01772     MESSAGE("RemoveVolume");
01773         RemoveElement(volume, true);
01774 }
01775 
01776 //=======================================================================
01777 //function : RemoveFromParent
01778 //purpose  :
01779 //=======================================================================
01780 
01781 bool SMDS_Mesh::RemoveFromParent()
01782 {
01783         if (myParent==NULL) return false;
01784         else return (myParent->RemoveSubMesh(this));
01785 }
01786 
01787 //=======================================================================
01788 //function : RemoveSubMesh
01789 //purpose  :
01790 //=======================================================================
01791 
01792 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
01793 {
01794         bool found = false;
01795 
01796         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
01797         for (; itmsh!=myChildren.end() && !found; itmsh++)
01798         {
01799                 SMDS_Mesh * submesh = *itmsh;
01800                 if (submesh == aMesh)
01801                 {
01802                         found = true;
01803                         myChildren.erase(itmsh);
01804                 }
01805         }
01806 
01807         return found;
01808 }
01809 
01810 //=======================================================================
01811 //function : ChangeElementNodes
01812 //purpose  :
01813 //=======================================================================
01814 
01815 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
01816                                    const SMDS_MeshNode    * nodes[],
01817                                    const int                nbnodes)
01818 {
01819   MESSAGE("SMDS_Mesh::ChangeElementNodes");
01820   // keep current nodes of elem
01821   set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
01822 
01823   // change nodes
01824   bool Ok = false;
01825   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
01826   if (cell)
01827     {
01828       Ok = cell->vtkOrder(nodes, nbnodes);
01829       Ok = cell->ChangeNodes(nodes, nbnodes);
01830     }
01831 
01832   if ( Ok ) { // update InverseElements
01833 
01834     set<const SMDS_MeshNode*>::iterator it;
01835 
01836     // AddInverseElement to new nodes
01837     for ( int i = 0; i < nbnodes; i++ ) {
01838       it = oldNodes.find( nodes[i] );
01839       if ( it == oldNodes.end() )
01840         // new node
01841         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
01842       else
01843         // remove from oldNodes a node that remains in elem
01844         oldNodes.erase( it );
01845     }
01846     // RemoveInverseElement from the nodes removed from elem
01847     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
01848     {
01849       SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
01850       n->RemoveInverseElement( cell );
01851     }
01852   }
01853 
01854   return Ok;
01855 }
01856 
01857 //=======================================================================
01858 //function : ChangePolyhedronNodes
01859 //purpose  : to change nodes of polyhedral volume
01860 //=======================================================================
01861 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
01862                                        const vector<const SMDS_MeshNode*>& nodes,
01863                                        const vector<int>                 & quantities)
01864 {
01865   if (elem->GetType() != SMDSAbs_Volume) {
01866     MESSAGE("WRONG ELEM TYPE");
01867     return false;
01868   }
01869 
01870   const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
01871   if (!vol) {
01872     return false;
01873   }
01874 
01875   // keep current nodes of elem
01876   set<const SMDS_MeshElement*> oldNodes;
01877   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
01878   while (itn->more()) {
01879     oldNodes.insert(itn->next());
01880   }
01881 
01882   // change nodes
01883   // TODO remove this function
01884   //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
01885   bool Ok = false;
01886   if (!Ok) {
01887     return false;
01888   }
01889 
01890   // update InverseElements
01891 
01892   // AddInverseElement to new nodes
01893   int nbnodes = nodes.size();
01894   set<const SMDS_MeshElement*>::iterator it;
01895   for (int i = 0; i < nbnodes; i++) {
01896     it = oldNodes.find(nodes[i]);
01897     if (it == oldNodes.end()) {
01898       // new node
01899       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
01900     } else {
01901       // remove from oldNodes a node that remains in elem
01902       oldNodes.erase(it);
01903     }
01904   }
01905 
01906   // RemoveInverseElement from the nodes removed from elem
01907   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
01908     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
01909       (const_cast<SMDS_MeshElement *>( *it ));
01910     n->RemoveInverseElement(elem);
01911   }
01912 
01913   return Ok;
01914 }
01915 
01916 
01917 //=======================================================================
01918 //function : Find0DElement
01919 //purpose  :
01920 //=======================================================================
01921 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
01922 {
01923   const SMDS_MeshNode * node = FindNode(idnode);
01924   if(node == NULL) return NULL;
01925   return Find0DElement(node);
01926 }
01927 
01928 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
01929 {
01930   if (!node) return 0;
01931   const SMDS_Mesh0DElement* toReturn = NULL;
01932   SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
01933   while (it1->more() && (toReturn == NULL)) {
01934     const SMDS_MeshElement* e = it1->next();
01935     if (e->NbNodes() == 1) {
01936       toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
01937     }
01938   }
01939   return toReturn;
01940 }
01941 
01942 //=======================================================================
01943 //function : Find0DElementOrCreate
01944 //purpose  :
01945 //=======================================================================
01946 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
01947 //{
01948 //  if (!node) return 0;
01949 //  SMDS_Mesh0DElement * toReturn = NULL;
01950 //  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
01951 //  if (toReturn == NULL) {
01952 //    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
01953 //    toReturn = new SMDS_Mesh0DElement(node);
01954 //    my0DElements.Add(toReturn);
01955 //    myInfo.myNb0DElements++;
01956 //  }
01957 //  return toReturn;
01958 //}
01959 
01960 
01961 //=======================================================================
01962 //function : FindEdge
01963 //purpose  :
01964 //=======================================================================
01965 
01966 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
01967 {
01968   const SMDS_MeshNode * node1=FindNode(idnode1);
01969   const SMDS_MeshNode * node2=FindNode(idnode2);
01970   if((node1==NULL)||(node2==NULL)) return NULL;
01971   return FindEdge(node1,node2);
01972 }
01973 
01974 //#include "Profiler.h"
01975 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
01976                                          const SMDS_MeshNode * node2)
01977 {
01978   if ( !node1 ) return 0;
01979   const SMDS_MeshEdge * toReturn=NULL;
01980   //PROFILER_Init();
01981   //PROFILER_Set();
01982   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
01983   //PROFILER_Get(0);
01984   //PROFILER_Set();
01985   while(it1->more()) {
01986     const SMDS_MeshElement * e = it1->next();
01987     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
01988       toReturn = static_cast<const SMDS_MeshEdge*>( e );
01989       break;
01990     }
01991   }
01992   //PROFILER_Get(1);
01993   return toReturn;
01994 }
01995 
01996 
01997 //=======================================================================
01998 //function : FindEdgeOrCreate
01999 //purpose  :
02000 //=======================================================================
02001 
02002 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
02003                                            const SMDS_MeshNode * node2)
02004 {
02005   if ( !node1 || !node2) return 0;
02006   SMDS_MeshEdge * toReturn=NULL;
02007   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
02008   if(toReturn==NULL) {
02009     if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
02010     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
02011     adjustmyCellsCapacity(ID);
02012     vector<vtkIdType> nodeIds;
02013     nodeIds.clear();
02014     nodeIds.push_back(node1->getVtkId());
02015     nodeIds.push_back(node2->getVtkId());
02016 
02017     SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
02018     edgevtk->init(nodeIds, this);
02019     if (!this->registerElement(ID,edgevtk))
02020       {
02021         this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
02022         myEdgePool->destroy(edgevtk);
02023         return 0;
02024       }
02025     toReturn = edgevtk;
02026     myCells[ID] = toReturn;
02027     myInfo.myNbEdges++;
02028   }
02029   return toReturn;
02030 }
02031 
02032 
02033 //=======================================================================
02034 //function : FindEdge
02035 //purpose  :
02036 //=======================================================================
02037 
02038 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
02039                                          int idnode3) const
02040 {
02041   const SMDS_MeshNode * node1=FindNode(idnode1);
02042   const SMDS_MeshNode * node2=FindNode(idnode2);
02043   const SMDS_MeshNode * node3=FindNode(idnode3);
02044   return FindEdge(node1,node2,node3);
02045 }
02046 
02047 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
02048                                          const SMDS_MeshNode * node2,
02049                                          const SMDS_MeshNode * node3)
02050 {
02051   if ( !node1 ) return 0;
02052   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
02053   while(it1->more()) {
02054     const SMDS_MeshElement * e = it1->next();
02055     if ( e->NbNodes() == 3 ) {
02056       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02057       while(it2->more()) {
02058         const SMDS_MeshElement* n = it2->next();
02059         if( n!=node1 &&
02060             n!=node2 &&
02061             n!=node3 )
02062         {
02063           e = 0;
02064           break;
02065         }
02066       }
02067       if ( e )
02068         return static_cast<const SMDS_MeshEdge *> (e);
02069     }
02070   }
02071   return 0;
02072 }
02073 
02074 
02075 //=======================================================================
02076 //function : FindFace
02077 //purpose  :
02078 //=======================================================================
02079 
02080 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02081         int idnode3) const
02082 {
02083   const SMDS_MeshNode * node1=FindNode(idnode1);
02084   const SMDS_MeshNode * node2=FindNode(idnode2);
02085   const SMDS_MeshNode * node3=FindNode(idnode3);
02086   return FindFace(node1, node2, node3);
02087 }
02088 
02089 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02090                                          const SMDS_MeshNode *node2,
02091                                          const SMDS_MeshNode *node3)
02092 {
02093   if ( !node1 ) return 0;
02094   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02095   while(it1->more()) {
02096     const SMDS_MeshElement * e = it1->next();
02097     if ( e->NbNodes() == 3 ) {
02098       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02099       while(it2->more()) {
02100         const SMDS_MeshElement* n = it2->next();
02101         if( n!=node1 &&
02102             n!=node2 &&
02103             n!=node3 )
02104         {
02105           e = 0;
02106           break;
02107         }
02108       }
02109       if ( e )
02110         return static_cast<const SMDS_MeshFace *> (e);
02111     }
02112   }
02113   return 0;
02114 }
02115 
02116 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
02117                                            const SMDS_MeshNode *node2,
02118                                            const SMDS_MeshNode *node3)
02119 {
02120   SMDS_MeshFace * toReturn=NULL;
02121   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
02122   if(toReturn==NULL) {
02123     int ID = myElementIDFactory->GetFreeID();
02124     toReturn = createTriangle(node1,node2,node3, ID);
02125   }
02126   return toReturn;
02127 }
02128 
02129 
02130 //=======================================================================
02131 //function : FindFace
02132 //purpose  :
02133 //=======================================================================
02134 
02135 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02136                                          int idnode3, int idnode4) const
02137 {
02138   const SMDS_MeshNode * node1=FindNode(idnode1);
02139   const SMDS_MeshNode * node2=FindNode(idnode2);
02140   const SMDS_MeshNode * node3=FindNode(idnode3);
02141   const SMDS_MeshNode * node4=FindNode(idnode4);
02142   return FindFace(node1, node2, node3, node4);
02143 }
02144 
02145 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02146                                          const SMDS_MeshNode *node2,
02147                                          const SMDS_MeshNode *node3,
02148                                          const SMDS_MeshNode *node4)
02149 {
02150   if ( !node1 ) return 0;
02151   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02152   while(it1->more()) {
02153     const SMDS_MeshElement * e = it1->next();
02154     if ( e->NbNodes() == 4 ) {
02155       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02156       while(it2->more()) {
02157         const SMDS_MeshElement* n = it2->next();
02158         if( n!=node1 &&
02159             n!=node2 &&
02160             n!=node3 &&
02161             n!=node4 )
02162         {
02163           e = 0;
02164           break;
02165         }
02166       }
02167       if ( e )
02168         return static_cast<const SMDS_MeshFace *> (e);
02169     }
02170   }
02171   return 0;
02172 }
02173 
02174 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
02175                                            const SMDS_MeshNode *node2,
02176                                            const SMDS_MeshNode *node3,
02177                                            const SMDS_MeshNode *node4)
02178 {
02179   SMDS_MeshFace * toReturn=NULL;
02180   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
02181   if(toReturn==NULL) {
02182     int ID = myElementIDFactory->GetFreeID();
02183     toReturn=createQuadrangle(node1,node2,node3,node4,ID);
02184   }
02185   return toReturn;
02186 }
02187 
02188 
02189 //=======================================================================
02190 //function : FindFace
02191 //purpose  :quadratic triangle
02192 //=======================================================================
02193 
02194 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02195                                          int idnode3, int idnode4,
02196                                          int idnode5, int idnode6) const
02197 {
02198   const SMDS_MeshNode * node1 = FindNode(idnode1);
02199   const SMDS_MeshNode * node2 = FindNode(idnode2);
02200   const SMDS_MeshNode * node3 = FindNode(idnode3);
02201   const SMDS_MeshNode * node4 = FindNode(idnode4);
02202   const SMDS_MeshNode * node5 = FindNode(idnode5);
02203   const SMDS_MeshNode * node6 = FindNode(idnode6);
02204   return FindFace(node1, node2, node3, node4, node5, node6);
02205 }
02206 
02207 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02208                                          const SMDS_MeshNode *node2,
02209                                          const SMDS_MeshNode *node3,
02210                                          const SMDS_MeshNode *node4,
02211                                          const SMDS_MeshNode *node5,
02212                                          const SMDS_MeshNode *node6)
02213 {
02214   if ( !node1 ) return 0;
02215   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02216   while(it1->more()) {
02217     const SMDS_MeshElement * e = it1->next();
02218     if ( e->NbNodes() == 6 ) {
02219       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02220       while(it2->more()) {
02221         const SMDS_MeshElement* n = it2->next();
02222         if( n!=node1 &&
02223             n!=node2 &&
02224             n!=node3 &&
02225             n!=node4 &&
02226             n!=node5 &&
02227             n!=node6 )
02228         {
02229           e = 0;
02230           break;
02231         }
02232       }
02233       if ( e )
02234         return static_cast<const SMDS_MeshFace *> (e);
02235     }
02236   }
02237   return 0;
02238 }
02239 
02240 
02241 //=======================================================================
02242 //function : FindFace
02243 //purpose  : quadratic quadrangle
02244 //=======================================================================
02245 
02246 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02247                                          int idnode3, int idnode4,
02248                                          int idnode5, int idnode6,
02249                                          int idnode7, int idnode8) const
02250 {
02251   const SMDS_MeshNode * node1 = FindNode(idnode1);
02252   const SMDS_MeshNode * node2 = FindNode(idnode2);
02253   const SMDS_MeshNode * node3 = FindNode(idnode3);
02254   const SMDS_MeshNode * node4 = FindNode(idnode4);
02255   const SMDS_MeshNode * node5 = FindNode(idnode5);
02256   const SMDS_MeshNode * node6 = FindNode(idnode6);
02257   const SMDS_MeshNode * node7 = FindNode(idnode7);
02258   const SMDS_MeshNode * node8 = FindNode(idnode8);
02259   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
02260 }
02261 
02262 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02263                                          const SMDS_MeshNode *node2,
02264                                          const SMDS_MeshNode *node3,
02265                                          const SMDS_MeshNode *node4,
02266                                          const SMDS_MeshNode *node5,
02267                                          const SMDS_MeshNode *node6,
02268                                          const SMDS_MeshNode *node7,
02269                                          const SMDS_MeshNode *node8)
02270 {
02271   if ( !node1 ) return 0;
02272   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02273   while(it1->more()) {
02274     const SMDS_MeshElement * e = it1->next();
02275     if ( e->NbNodes() == 8 ) {
02276       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02277       while(it2->more()) {
02278         const SMDS_MeshElement* n = it2->next();
02279         if( n!=node1 &&
02280             n!=node2 &&
02281             n!=node3 &&
02282             n!=node4 &&
02283             n!=node5 &&
02284             n!=node6 &&
02285             n!=node7 &&
02286             n!=node8 )
02287         {
02288           e = 0;
02289           break;
02290         }
02291       }
02292       if ( e )
02293         return static_cast<const SMDS_MeshFace *> (e);
02294     }
02295   }
02296   return 0;
02297 }
02298 
02299 
02300 //=======================================================================
02301 //function : FindElement
02302 //purpose  :
02303 //=======================================================================
02304 
02305 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
02306 {
02307   if ((IDelem <= 0) || IDelem >= myCells.size())
02308   {
02309     MESSAGE("--------------------------------------------------------------------------------- ");
02310     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
02311     MESSAGE("--------------------------------------------------------------------------------- ");
02312     // TODO raise an exception
02313     //assert(0);
02314     return 0;
02315   }
02316   return myCells[IDelem];
02317 }
02318 
02319 //=======================================================================
02320 //function : FindFace
02321 //purpose  : find polygon
02322 //=======================================================================
02323 
02324 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
02325 {
02326   int nbnodes = nodes_ids.size();
02327   vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
02328   for (int inode = 0; inode < nbnodes; inode++) {
02329     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
02330     if (node == NULL) return NULL;
02331     poly_nodes[inode] = node;
02332   }
02333   return FindFace(poly_nodes);
02334 }
02335 
02336 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
02337 {
02338   return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
02339 }
02340 
02341 
02342 //================================================================================
02350 //================================================================================
02351 
02352 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
02353                                                 const SMDSAbs_ElementType            type,
02354                                                 const bool                           noMedium)
02355 {
02356   if ( nodes.size() > 0 && nodes[0] )
02357   {
02358     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
02359     while (itF->more())
02360     {
02361       const SMDS_MeshElement* e = itF->next();
02362       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
02363       if ( nbNodesToCheck == nodes.size() )
02364       {
02365         for ( int i = 1; e && i < nodes.size(); ++ i )
02366         {
02367           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
02368           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
02369             e = 0;
02370         }
02371         if ( e )
02372           return static_cast<const SMDS_MeshFace *> (e);
02373       }
02374     }
02375   }
02376   return NULL;
02377 }
02378 
02379 //=======================================================================
02380 //function : DumpNodes
02381 //purpose  :
02382 //=======================================================================
02383 
02384 void SMDS_Mesh::DumpNodes() const
02385 {
02386         MESSAGE("dump nodes of mesh : ");
02387         SMDS_NodeIteratorPtr itnode=nodesIterator();
02388         while(itnode->more()) ; //MESSAGE(itnode->next());
02389 }
02390 
02391 //=======================================================================
02392 //function : Dump0DElements
02393 //purpose  :
02394 //=======================================================================
02395 void SMDS_Mesh::Dump0DElements() const
02396 {
02397   MESSAGE("dump 0D elements of mesh : ");
02398   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
02399   while(it0d->more()) ; //MESSAGE(it0d->next());
02400 }
02401 
02402 //=======================================================================
02403 //function : DumpEdges
02404 //purpose  :
02405 //=======================================================================
02406 
02407 void SMDS_Mesh::DumpEdges() const
02408 {
02409         MESSAGE("dump edges of mesh : ");
02410         SMDS_EdgeIteratorPtr itedge=edgesIterator();
02411         while(itedge->more()) ; //MESSAGE(itedge->next());
02412 }
02413 
02414 //=======================================================================
02415 //function : DumpFaces
02416 //purpose  :
02417 //=======================================================================
02418 
02419 void SMDS_Mesh::DumpFaces() const
02420 {
02421         MESSAGE("dump faces of mesh : ");
02422         SMDS_FaceIteratorPtr itface=facesIterator();
02423         while(itface->more()) ; //MESSAGE(itface->next());
02424 }
02425 
02426 //=======================================================================
02427 //function : DumpVolumes
02428 //purpose  :
02429 //=======================================================================
02430 
02431 void SMDS_Mesh::DumpVolumes() const
02432 {
02433         MESSAGE("dump volumes of mesh : ");
02434         SMDS_VolumeIteratorPtr itvol=volumesIterator();
02435         while(itvol->more()) ; //MESSAGE(itvol->next());
02436 }
02437 
02438 //=======================================================================
02439 //function : DebugStats
02440 //purpose  :
02441 //=======================================================================
02442 
02443 void SMDS_Mesh::DebugStats() const
02444 {
02445   MESSAGE("Debug stats of mesh : ");
02446 
02447   MESSAGE("===== NODES ====="<<NbNodes());
02448   MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
02449   MESSAGE("===== EDGES ====="<<NbEdges());
02450   MESSAGE("===== FACES ====="<<NbFaces());
02451   MESSAGE("===== VOLUMES ====="<<NbVolumes());
02452 
02453   MESSAGE("End Debug stats of mesh ");
02454 
02455   //#ifdef DEB
02456 
02457   SMDS_NodeIteratorPtr itnode=nodesIterator();
02458   int sizeofnodes = 0;
02459   int sizeoffaces = 0;
02460 
02461   while(itnode->more())
02462   {
02463     const SMDS_MeshNode *node = itnode->next();
02464 
02465     sizeofnodes += sizeof(*node);
02466 
02467     SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
02468     while(it->more())
02469     {
02470       const SMDS_MeshElement *me = it->next();
02471       sizeofnodes += sizeof(me);
02472     }
02473   }
02474 
02475   SMDS_FaceIteratorPtr itface=facesIterator();
02476   while(itface->more())
02477   {
02478     const SMDS_MeshElement *face = itface->next();
02479     sizeoffaces += sizeof(*face);
02480   }
02481 
02482   MESSAGE("total size of node elements = " << sizeofnodes);;
02483   MESSAGE("total size of face elements = " << sizeoffaces);;
02484 
02485   //#endif
02486 }
02487 
02491 int SMDS_Mesh::NbNodes() const
02492 {
02493         //MESSAGE(myGrid->GetNumberOfPoints());
02494         //MESSAGE(myInfo.NbNodes());
02495         //MESSAGE(myNodeMax);
02496     return myInfo.NbNodes();
02497 }
02498 
02502 int SMDS_Mesh::Nb0DElements() const
02503 {
02504   return myInfo.Nb0DElements(); // -PR- a verfier
02505 }
02506 
02510 int SMDS_Mesh::NbEdges() const
02511 {
02512         return myInfo.NbEdges(); // -PR- a verfier
02513 }
02514 
02518 int SMDS_Mesh::NbFaces() const
02519 {
02520         return myInfo.NbFaces();  // -PR- a verfier
02521 }
02522 
02526 int SMDS_Mesh::NbVolumes() const
02527 {
02528         return myInfo.NbVolumes(); // -PR- a verfier
02529 }
02530 
02536 int SMDS_Mesh::NbSubMesh() const
02537 {
02538         return myChildren.size();
02539 }
02540 
02545 SMDS_Mesh::~SMDS_Mesh()
02546 {
02547   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
02548   while(itc!=myChildren.end())
02549   {
02550     delete *itc;
02551     itc++;
02552   }
02553 
02554   if(myParent==NULL)
02555   {
02556     delete myNodeIDFactory;
02557     delete myElementIDFactory;
02558   }
02559   else
02560   {
02561     SMDS_ElemIteratorPtr eIt = elementsIterator();
02562     while ( eIt->more() )
02563       {
02564         const SMDS_MeshElement *elem = eIt->next();
02565         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
02566       }
02567     SMDS_NodeIteratorPtr itn = nodesIterator();
02568     while (itn->more())
02569       {
02570         const SMDS_MeshNode *node = itn->next();
02571         ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
02572         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
02573       }
02574   }
02575 
02576 //   SetOfNodes::Iterator itn(myNodes);
02577 //   for (; itn.More(); itn.Next())
02578 //     delete itn.Value();
02579 
02580 //   SetOf0DElements::Iterator it0d (my0DElements);
02581 //   for (; it0d.More(); it0d.Next())
02582 //   {
02583 //     SMDS_MeshElement* elem = it0d.Value();
02584 //     delete elem;
02585 //   }
02586 
02587 //   SetOfEdges::Iterator ite(myEdges);
02588 //   for (; ite.More(); ite.Next())
02589 //   {
02590 //     SMDS_MeshElement* elem = ite.Value();
02591 //     delete elem;
02592 //   }
02593 
02594 //   SetOfFaces::Iterator itf(myFaces);
02595 //   for (; itf.More(); itf.Next())
02596 //   {
02597 //     SMDS_MeshElement* elem = itf.Value();
02598 //     delete elem;
02599 //   }
02600 
02601 //   SetOfVolumes::Iterator itv(myVolumes);
02602 //   for (; itv.More(); itv.Next())
02603 //   {
02604 //     SMDS_MeshElement* elem = itv.Value();
02605 //     delete elem;
02606 //   }
02607 }
02608 
02609 //================================================================================
02613 //================================================================================
02614 
02615 void SMDS_Mesh::Clear()
02616 {
02617   MESSAGE("SMDS_Mesh::Clear");
02618   if (myParent!=NULL)
02619     {
02620     SMDS_ElemIteratorPtr eIt = elementsIterator();
02621     while ( eIt->more() )
02622       {
02623         const SMDS_MeshElement *elem = eIt->next();
02624         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
02625       }
02626     SMDS_NodeIteratorPtr itn = nodesIterator();
02627     while (itn->more())
02628       {
02629         const SMDS_MeshNode *node = itn->next();
02630         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
02631       }
02632     }
02633   else
02634     {
02635     myNodeIDFactory->Clear();
02636     myElementIDFactory->Clear();
02637     }
02638 
02639   SMDS_ElemIteratorPtr itv = elementsIterator();
02640   while (itv->more())
02641     {
02642       SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
02643       SMDSAbs_ElementType aType = elem->GetType();
02644       switch (aType)
02645       {
02646         case SMDSAbs_0DElement:
02647           delete elem;
02648           break;
02649         case SMDSAbs_Edge:
02650            myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
02651           break;
02652         case SMDSAbs_Face:
02653           myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
02654           break;
02655         case SMDSAbs_Volume:
02656           myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
02657           break;
02658         default:
02659           break;
02660       }
02661     }
02662   myCells.clear();
02663   myCellIdVtkToSmds.clear();
02664   //myCellIdSmdsToVtk.clear();
02665 
02666   SMDS_NodeIteratorPtr itn = nodesIterator();
02667   while (itn->more())
02668     {
02669       SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
02670       node->SetPosition(SMDS_SpacePosition::originSpacePosition());
02671       myNodePool->destroy(node);
02672     }
02673   myNodes.clear();
02674 
02675   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
02676   while(itc!=myChildren.end())
02677     (*itc)->Clear();
02678 
02679   myModified = false;
02680   xmin = 0; xmax = 0;
02681   ymin = 0; ymax = 0;
02682   zmin = 0; zmax = 0;
02683 
02684   myInfo.Clear();
02685 
02686   myGrid->Initialize();
02687   myGrid->Allocate();
02688   vtkPoints* points = vtkPoints::New();
02689   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
02690   // using double type for storing coordinates of nodes instead float.
02691   points->SetDataType(VTK_DOUBLE);
02692   points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
02693   myGrid->SetPoints( points );
02694   points->Delete();
02695   myGrid->BuildLinks();
02696 }
02697 
02703 bool SMDS_Mesh::hasConstructionEdges()
02704 {
02705         return myHasConstructionEdges;
02706 }
02707 
02715 bool SMDS_Mesh::hasConstructionFaces()
02716 {
02717         return myHasConstructionFaces;
02718 }
02719 
02724 bool SMDS_Mesh::hasInverseElements()
02725 {
02726         return myHasInverseElements;
02727 }
02728 
02733 void SMDS_Mesh::setConstructionEdges(bool b)
02734 {
02735         myHasConstructionEdges=b;
02736 }
02737 
02742 void SMDS_Mesh::setConstructionFaces(bool b)
02743 {
02744          myHasConstructionFaces=b;
02745 }
02746 
02751 void SMDS_Mesh::setInverseElements(bool b)
02752 {
02753   if(!b) MESSAGE("Error : inverseElement=false not implemented");
02754   myHasInverseElements=b;
02755 }
02756 
02757 namespace {
02758 
02762 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
02763 struct MYNode_Map_Iterator: public FATHER
02764 {
02765   int _ctr;
02766   const MAP& _map;
02767   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
02768   {
02769       _ctr = 0;
02770   }
02771 
02772   bool more()
02773   {
02774       while (_ctr < _map.size())
02775       {
02776           if (_map[_ctr])
02777               return true;
02778           _ctr++;
02779       }
02780           return false;
02781   }
02782 
02783   ELEM next()
02784   {
02785     ELEM current = _map[_ctr];
02786     _ctr++;
02787     return current;
02788   }
02789 };
02790 
02791   template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
02792   struct MYElem_Map_Iterator: public FATHER
02793   {
02794     size_t _ctr;
02795     int _type, _more;
02796     const MAP& _map;
02797     MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
02798     {
02799       _ctr = 0;
02800       _type = typ;
02801       _more = _ctr < _map.size();
02802       if ( _more && ( !_map[_ctr] || ( _type != SMDSAbs_All && _map[_ctr]->GetType() != _type)))
02803         next();
02804     }
02805 
02806     bool more()
02807     {
02808       return _more;
02809     }
02810 
02811     ELEM next()
02812     {
02813       if ( !_more ) return NULL;
02814       ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
02815       _more = 0;
02816       while ( !_more && ++_ctr < _map.size() )
02817         _more = ( _map[_ctr] && (_type == SMDSAbs_All || _map[_ctr]->GetType() == _type));
02818       return current;
02819     }
02820   };
02821 
02822   //================================================================================
02826   //================================================================================
02827 
02828   template <typename ELEM=const SMDS_MeshElement*>
02829   class IdSortedIterator : public SMDS_Iterator<ELEM>
02830   {
02831     const SMDS_MeshElementIDFactory& myIDFact;
02832     int                              myID, myMaxID, myNbFound, myTotalNb;
02833     SMDSAbs_ElementType              myType;
02834     ELEM                             myElem;
02835 
02836   public:
02837     IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
02838                      const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
02839                      const int                        totalNb)
02840       :myIDFact( fact ),
02841        myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
02842        myType( type ),
02843        myElem(0)
02844     {
02845       next();
02846     }
02847     bool more()
02848     {
02849       return myElem;
02850     }
02851     ELEM next()
02852     {
02853       ELEM current = myElem;
02854 
02855       for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
02856         if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
02857             && myElem->GetType() != myType )
02858           myElem = 0;
02859 
02860       myNbFound += bool(myElem);
02861 
02862       return current;
02863     }
02864   };
02865 }
02866 
02870 
02871 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
02872 {
02873   typedef MYNode_Map_Iterator
02874     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
02875   return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
02876 
02877 //  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
02878 //  return ( idInceasingOrder ?
02879 //           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
02880 //           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
02881 }
02882 
02886 
02887 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
02888 {
02889   typedef MYElem_Map_Iterator
02890     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
02891   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
02892 
02893 //  typedef MYNCollection_Map_Iterator
02894 //    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
02895 //  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
02896 //  return ( idInceasingOrder ?
02897 //           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
02898 //                                                           SMDSAbs_0DElement,
02899 //                                                           Nb0DElements() )) :
02900 //           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
02901 }
02902 
02906 
02907 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
02908 {
02909   typedef MYElem_Map_Iterator
02910     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
02911   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
02912 
02913 //  typedef MYNCollection_Map_Iterator
02914 //    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
02915 //  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
02916 //  return ( idInceasingOrder ?
02917 //           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
02918 //                                                      SMDSAbs_Edge,
02919 //                                                      NbEdges() )) :
02920 //           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
02921 }
02922 
02926 
02927 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
02928 {
02929   typedef MYElem_Map_Iterator
02930     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
02931   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
02932 
02933 //  typedef MYNCollection_Map_Iterator
02934 //    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
02935 //  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
02936 //  return ( idInceasingOrder ?
02937 //           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
02938 //                                                      SMDSAbs_Face,
02939 //                                                      NbFaces() )) :
02940 //           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
02941 }
02942 
02946 
02947 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
02948 {
02949   typedef MYElem_Map_Iterator
02950     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
02951   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
02952 
02953   //  typedef MYNCollection_Map_Iterator
02954 //    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
02955 //  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
02956 //  return ( idInceasingOrder ?
02957 //           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
02958 //                                                        SMDSAbs_Volume,
02959 //                                                        NbVolumes() )) :
02960 //           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
02961 }
02962 
02966 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
02967 {
02968   switch (type) {
02969   case SMDSAbs_All:
02970     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
02971     break;
02972   case SMDSAbs_Volume:
02973     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
02974   case SMDSAbs_Face:
02975     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
02976   case SMDSAbs_Edge:
02977     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
02978   case SMDSAbs_0DElement:
02979     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
02980   case SMDSAbs_Node:
02981     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
02982     //return myNodeIDFactory->elementsIterator();
02983   default:;
02984   }
02985   return myElementIDFactory->elementsIterator();
02986 }
02987 
02991 static set<const SMDS_MeshElement*> * intersectionOfSets(
02992         set<const SMDS_MeshElement*> vs[], int numberOfSets)
02993 {
02994         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
02995         set<const SMDS_MeshElement*>* rsetB;
02996 
02997         for(int i=0; i<numberOfSets-1; i++)
02998         {
02999                 rsetB=new set<const SMDS_MeshElement*>();
03000                 set_intersection(
03001                         rsetA->begin(), rsetA->end(),
03002                         vs[i+1].begin(), vs[i+1].end(),
03003                         inserter(*rsetB, rsetB->begin()));
03004                 delete rsetA;
03005                 rsetA=rsetB;
03006         }
03007         return rsetA;
03008 }
03009 
03015 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
03016 {
03017         int numberOfSets=element->NbNodes();
03018         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
03019 
03020         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
03021 
03022         int i=0;
03023         while(itNodes->more())
03024         {
03025           const SMDS_MeshElement* node = itNodes->next();
03026           MYASSERT(node);
03027                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
03028                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
03029 
03030                 //initSet[i]=set<const SMDS_MeshElement*>();
03031                 while(itFe->more())
03032                 {
03033                   const SMDS_MeshElement* elem = itFe->next();
03034                   MYASSERT(elem);
03035                   initSet[i].insert(elem);
03036 
03037                 }
03038 
03039                 i++;
03040         }
03041         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
03042 //         MESSAGE("nb elems " << i << " intersection " << retSet->size());
03043         delete [] initSet;
03044         return retSet;
03045 }
03046 
03050 static set<const SMDS_MeshElement*> * getExclusiveNodes(
03051         set<const SMDS_MeshElement*>& elements)
03052 {
03053         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
03054         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
03055 
03056         while(itElements!=elements.end())
03057         {
03058                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
03059                 itElements++;
03060 
03061                 while(itNodes->more())
03062                 {
03063                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
03064                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
03065                         set<const SMDS_MeshElement*> s;
03066                         while(itFe->more())
03067                           s.insert(itFe->next());
03068                         if(s==elements) toReturn->insert(n);
03069                 }
03070         }
03071         return toReturn;
03072 }
03073 
03080 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
03081                                      const SMDS_MeshElement *      element,
03082                                      set<const SMDS_MeshElement*>& nodes)
03083 {
03084   switch(element->GetType())
03085     {
03086     case SMDSAbs_Node:
03087       MESSAGE("Internal Error: This should not happen");
03088       break;
03089     case SMDSAbs_0DElement:
03090       {
03091       }
03092       break;
03093     case SMDSAbs_Edge:
03094         {
03095                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
03096                 while(itn->more())
03097                 {
03098                         const SMDS_MeshElement * e=itn->next();
03099                         if(nodes.find(e)!=nodes.end())
03100                         {
03101                           setOfChildren.insert(element);
03102                           break;
03103                         }
03104                 }
03105         } break;
03106     case SMDSAbs_Face:
03107         {
03108                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
03109                 while(itn->more())
03110                 {
03111                         const SMDS_MeshElement * e=itn->next();
03112                         if(nodes.find(e)!=nodes.end())
03113                         {
03114                           setOfChildren.insert(element);
03115                           break;
03116                         }
03117                 }
03118                 if(hasConstructionEdges())
03119                 {
03120                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
03121                         while(ite->more())
03122                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
03123                 }
03124         } break;
03125     case SMDSAbs_Volume:
03126         {
03127                 if(hasConstructionFaces())
03128                 {
03129                         SMDS_ElemIteratorPtr ite=element->facesIterator();
03130                         while(ite->more())
03131                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
03132                 }
03133                 else if(hasConstructionEdges())
03134                 {
03135                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
03136                         while(ite->more())
03137                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
03138                 }
03139         }
03140     }
03141 }
03142 
03147 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
03148                               const bool removenodes)
03149 {
03150   list<const SMDS_MeshElement *> removedElems;
03151   list<const SMDS_MeshElement *> removedNodes;
03152   RemoveElement( elem, removedElems, removedNodes, removenodes );
03153 }
03154 
03161 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
03162                               list<const SMDS_MeshElement *>& removedElems,
03163                               list<const SMDS_MeshElement *>& removedNodes,
03164                               bool                            removenodes)
03165 {
03166   //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
03167   // get finite elements built on elem
03168   set<const SMDS_MeshElement*> * s1;
03169   if (    (elem->GetType() == SMDSAbs_0DElement)
03170       || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
03171       || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
03172       ||  (elem->GetType() == SMDSAbs_Volume) )
03173     {
03174       s1 = new set<const SMDS_MeshElement*> ();
03175       s1->insert(elem);
03176     }
03177   else
03178     s1 = getFinitElements(elem);
03179 
03180   // get exclusive nodes (which would become free afterwards)
03181   set<const SMDS_MeshElement*> * s2;
03182   if (elem->GetType() == SMDSAbs_Node) // a node is removed
03183     {
03184       // do not remove nodes except elem
03185       s2 = new set<const SMDS_MeshElement*> ();
03186       s2->insert(elem);
03187       removenodes = true;
03188     }
03189   else
03190     s2 = getExclusiveNodes(*s1);
03191 
03192   // form the set of finite and construction elements to remove
03193   set<const SMDS_MeshElement*> s3;
03194   set<const SMDS_MeshElement*>::iterator it = s1->begin();
03195   while (it != s1->end())
03196     {
03197       addChildrenWithNodes(s3, *it, *s2);
03198       s3.insert(*it);
03199       it++;
03200     }
03201   if (elem->GetType() != SMDSAbs_Node)
03202     s3.insert(elem);
03203 
03204   // remove finite and construction elements
03205   it = s3.begin();
03206   while (it != s3.end())
03207     {
03208       // Remove element from <InverseElements> of its nodes
03209       SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
03210       while (itn->more())
03211         {
03212           SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
03213           n->RemoveInverseElement((*it));
03214         }
03215       int IdToRemove = (*it)->GetID();
03216       int vtkid = (*it)->getVtkId();
03217       //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
03218       //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
03219       switch ((*it)->GetType())
03220       {
03221         case SMDSAbs_Node:
03222           MYASSERT("Internal Error: This should not happen")
03223           ;
03224           break;
03225         case SMDSAbs_0DElement:
03226           if (IdToRemove >= 0)
03227             {
03228               myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
03229               myInfo.remove(*it);
03230             }
03231           removedElems.push_back((*it));
03232           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03233           delete (*it);
03234           break;
03235         case SMDSAbs_Edge:
03236           if (IdToRemove >= 0)
03237             {
03238               myCells[IdToRemove] = 0;
03239               myInfo.RemoveEdge(*it);
03240             }
03241           removedElems.push_back((*it));
03242           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03243           if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
03244             myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
03245           else
03246             delete (*it);
03247           break;
03248         case SMDSAbs_Face:
03249           if (IdToRemove >= 0)
03250             {
03251               myCells[IdToRemove] = 0;
03252               myInfo.RemoveFace(*it);
03253             }
03254           removedElems.push_back((*it));
03255           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03256           if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
03257             myFacePool->destroy((SMDS_VtkFace*) vtkElem);
03258           else
03259             delete (*it);
03260           break;
03261         case SMDSAbs_Volume:
03262           if (IdToRemove >= 0)
03263             {
03264               myCells[IdToRemove] = 0;
03265               myInfo.RemoveVolume(*it);
03266             }
03267           removedElems.push_back((*it));
03268           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03269           if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
03270             myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
03271           else
03272             delete (*it);
03273           break;
03274       }
03275       if (vtkid >= 0)
03276         {
03277           //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
03278           this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
03279         }
03280       it++;
03281     }
03282 
03283   // remove exclusive (free) nodes
03284   if (removenodes)
03285     {
03286       it = s2->begin();
03287       while (it != s2->end())
03288         {
03289           int IdToRemove = (*it)->GetID();
03290           //MESSAGE( "SMDS: RM node " << IdToRemove);
03291           if (IdToRemove >= 0)
03292             {
03293               myNodes[IdToRemove] = 0;
03294               myInfo.myNbNodes--;
03295             }
03296           myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
03297           removedNodes.push_back((*it));
03298           if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
03299           {
03300             ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
03301             myNodePool->destroy((SMDS_MeshNode*) vtkElem);
03302           }
03303           else
03304             delete (*it);
03305           it++;
03306         }
03307     }
03308 
03309   delete s2;
03310   delete s1;
03311 }
03312 
03313 
03317 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
03318 {
03319   int elemId = elem->GetID();
03320   int vtkId = elem->getVtkId();
03321   //MESSAGE("RemoveFreeElement " << elemId);
03322   SMDSAbs_ElementType aType = elem->GetType();
03323   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
03324   if (aType == SMDSAbs_Node) {
03325     //MESSAGE("Remove free node " << elemId);
03326     // only free node can be removed by this method
03327     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
03328     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
03329     if (!itFe->more()) { // free node
03330       myNodes[elemId] = 0;
03331       myInfo.myNbNodes--;
03332       ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
03333       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
03334       myNodeIDFactory->ReleaseID(elemId, vtkId);
03335     }
03336   } else {
03337     if (hasConstructionEdges() || hasConstructionFaces())
03338       // this methods is only for meshes without descendants
03339       return;
03340 
03341     //MESSAGE("Remove free element " << elemId);
03342     // Remove element from <InverseElements> of its nodes
03343     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
03344     while (itn->more()) {
03345       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
03346         (const_cast<SMDS_MeshElement *>(itn->next()));
03347       n->RemoveInverseElement(elem);
03348     }
03349 
03350     // in meshes without descendants elements are always free
03351      switch (aType) {
03352     case SMDSAbs_0DElement:
03353       myCells[elemId] = 0;
03354       myInfo.remove(elem);
03355       delete elem;
03356       break;
03357     case SMDSAbs_Edge:
03358       myCells[elemId] = 0;
03359       myInfo.RemoveEdge(elem);
03360       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
03361       break;
03362     case SMDSAbs_Face:
03363       myCells[elemId] = 0;
03364       myInfo.RemoveFace(elem);
03365       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
03366       break;
03367     case SMDSAbs_Volume:
03368       myCells[elemId] = 0;
03369       myInfo.RemoveVolume(elem);
03370       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
03371       break;
03372     default:
03373       break;
03374     }
03375     myElementIDFactory->ReleaseID(elemId, vtkId);
03376 
03377     this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
03378     // --- to do: keep vtkid in a list of reusable cells
03379   }
03380 }
03381 
03386 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
03387 {
03388   // we should not imply on validity of *elem, so iterate on containers
03389   // of all types in the hope of finding <elem> somewhere there
03390   SMDS_NodeIteratorPtr itn = nodesIterator();
03391   while (itn->more())
03392     if (elem == itn->next())
03393       return true;
03394   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
03395   while (it0d->more())
03396     if (elem == it0d->next())
03397       return true;
03398   SMDS_EdgeIteratorPtr ite = edgesIterator();
03399   while (ite->more())
03400     if (elem == ite->next())
03401       return true;
03402   SMDS_FaceIteratorPtr itf = facesIterator();
03403   while (itf->more())
03404     if (elem == itf->next())
03405       return true;
03406   SMDS_VolumeIteratorPtr itv = volumesIterator();
03407   while (itv->more())
03408     if (elem == itv->next())
03409       return true;
03410   return false;
03411 }
03412 
03413 //=======================================================================
03414 //function : MaxNodeID
03415 //purpose  :
03416 //=======================================================================
03417 
03418 int SMDS_Mesh::MaxNodeID() const
03419 {
03420   return myNodeMax;
03421 }
03422 
03423 //=======================================================================
03424 //function : MinNodeID
03425 //purpose  :
03426 //=======================================================================
03427 
03428 int SMDS_Mesh::MinNodeID() const
03429 {
03430   return myNodeMin;
03431 }
03432 
03433 //=======================================================================
03434 //function : MaxElementID
03435 //purpose  :
03436 //=======================================================================
03437 
03438 int SMDS_Mesh::MaxElementID() const
03439 {
03440   return myElementIDFactory->GetMaxID();
03441 }
03442 
03443 //=======================================================================
03444 //function : MinElementID
03445 //purpose  :
03446 //=======================================================================
03447 
03448 int SMDS_Mesh::MinElementID() const
03449 {
03450   return myElementIDFactory->GetMinID();
03451 }
03452 
03453 //=======================================================================
03454 //function : Renumber
03455 //purpose  : Renumber all nodes or elements.
03456 //=======================================================================
03457 
03458 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
03459 {
03460     MESSAGE("Renumber");
03461   if ( deltaID == 0 )
03462     return;
03463 
03464   SMDS_MeshNodeIDFactory * idFactory =
03465     isNodes ? myNodeIDFactory : myElementIDFactory;
03466 
03467   // get existing elements in the order of ID increasing
03468   map<int,SMDS_MeshElement*> elemMap;
03469   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
03470   while ( idElemIt->more() ) {
03471     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
03472     int id = elem->GetID();
03473     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
03474   }
03475   // release their ids
03476   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
03477   idFactory->Clear();
03478 //   for ( ; elemIt != elemMap.end(); elemIt++ )
03479 //   {
03480 //     int id = (*elemIt).first;
03481 //     idFactory->ReleaseID( id );
03482 //   }
03483   // set new IDs
03484   int ID = startID;
03485   elemIt = elemMap.begin();
03486   for ( ; elemIt != elemMap.end(); elemIt++ )
03487   {
03488     idFactory->BindID( ID, (*elemIt).second );
03489     ID += deltaID;
03490   }
03491 }
03492 
03493 //=======================================================================
03494 //function : GetElementType
03495 //purpose  : Return type of element or node with id
03496 //=======================================================================
03497 
03498 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
03499 {
03500   SMDS_MeshElement* elem = 0;
03501   if( iselem )
03502     elem = myElementIDFactory->MeshElement( id );
03503   else
03504     elem = myNodeIDFactory->MeshElement( id );
03505 
03506   if( !elem )
03507   {
03508     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
03509     return SMDSAbs_All;
03510   }
03511   else
03512     return elem->GetType();
03513 }
03514 
03515 
03516 
03517 //********************************************************************
03518 //********************************************************************
03519 //********                                                   *********
03520 //*****       Methods for addition of quadratic elements        ******
03521 //********                                                   *********
03522 //********************************************************************
03523 //********************************************************************
03524 
03525 //=======================================================================
03526 //function : AddEdgeWithID
03527 //purpose  :
03528 //=======================================================================
03529 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
03530 {
03531   return SMDS_Mesh::AddEdgeWithID
03532     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
03533      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
03534      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03535      ID);
03536 }
03537 
03538 //=======================================================================
03539 //function : AddEdge
03540 //purpose  :
03541 //=======================================================================
03542 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
03543                                   const SMDS_MeshNode* n2,
03544                                   const SMDS_MeshNode* n12)
03545 {
03546   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
03547 }
03548 
03549 //=======================================================================
03550 //function : AddEdgeWithID
03551 //purpose  :
03552 //=======================================================================
03553 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
03554                                         const SMDS_MeshNode * n2,
03555                                         const SMDS_MeshNode * n12,
03556                                         int ID)
03557 {
03558   if ( !n1 || !n2 || !n12 ) return 0;
03559 
03560   // --- retrieve nodes ID
03561   vector<vtkIdType> nodeIds;
03562   nodeIds.clear();
03563   nodeIds.push_back(n1->getVtkId());
03564   nodeIds.push_back(n2->getVtkId());
03565   nodeIds.push_back(n12->getVtkId());
03566 
03567   SMDS_MeshEdge * edge = 0;
03568   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
03569   edgevtk->init(nodeIds, this);
03570   if (!this->registerElement(ID,edgevtk))
03571     {
03572       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
03573       myEdgePool->destroy(edgevtk);
03574       return 0;
03575     }
03576   edge = edgevtk;
03577   adjustmyCellsCapacity(ID);
03578   myCells[ID] = edge;
03579   myInfo.myNbQuadEdges++;
03580 
03581 //  if (!registerElement(ID, edge)) {
03582 //        RemoveElement(edge, false);
03583 //        edge = NULL;
03584 //  }
03585   return edge;
03586 
03587 }
03588 
03589 
03590 //=======================================================================
03591 //function : AddFace
03592 //purpose  :
03593 //=======================================================================
03594 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
03595                                   const SMDS_MeshNode * n2,
03596                                   const SMDS_MeshNode * n3,
03597                                   const SMDS_MeshNode * n12,
03598                                   const SMDS_MeshNode * n23,
03599                                   const SMDS_MeshNode * n31)
03600 {
03601   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
03602                                   myElementIDFactory->GetFreeID());
03603 }
03604 
03605 //=======================================================================
03606 //function : AddFaceWithID
03607 //purpose  :
03608 //=======================================================================
03609 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
03610                                         int n12,int n23,int n31, int ID)
03611 {
03612   return SMDS_Mesh::AddFaceWithID
03613     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
03614      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
03615      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
03616      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
03617      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
03618      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
03619      ID);
03620 }
03621 
03622 //=======================================================================
03623 //function : AddFaceWithID
03624 //purpose  :
03625 //=======================================================================
03626 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
03627                                         const SMDS_MeshNode * n2,
03628                                         const SMDS_MeshNode * n3,
03629                                         const SMDS_MeshNode * n12,
03630                                         const SMDS_MeshNode * n23,
03631                                         const SMDS_MeshNode * n31,
03632                                         int ID)
03633 {
03634   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
03635   if(hasConstructionEdges()) {
03636     // creation quadratic edges - not implemented
03637     return 0;
03638   }
03639   else
03640   {
03641     // --- retrieve nodes ID
03642     vector<vtkIdType> nodeIds;
03643     nodeIds.clear();
03644     nodeIds.push_back(n1->getVtkId());
03645     nodeIds.push_back(n2->getVtkId());
03646     nodeIds.push_back(n3->getVtkId());
03647     nodeIds.push_back(n12->getVtkId());
03648     nodeIds.push_back(n23->getVtkId());
03649     nodeIds.push_back(n31->getVtkId());
03650 
03651     SMDS_MeshFace * face = 0;
03652     SMDS_VtkFace *facevtk = myFacePool->getNew();
03653     facevtk->init(nodeIds, this);
03654     if (!this->registerElement(ID,facevtk))
03655       {
03656         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
03657         myFacePool->destroy(facevtk);
03658         return 0;
03659       }
03660     face = facevtk;
03661     adjustmyCellsCapacity(ID);
03662     myCells[ID] = face;
03663     myInfo.myNbQuadTriangles++;
03664 
03665 //    if (!registerElement(ID, face)) {
03666 //      RemoveElement(face, false);
03667 //      face = NULL;
03668 //    }
03669     return face;
03670   }
03671 }
03672 
03673 
03674 //=======================================================================
03675 //function : AddFace
03676 //purpose  :
03677 //=======================================================================
03678 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
03679                                   const SMDS_MeshNode * n2,
03680                                   const SMDS_MeshNode * n3,
03681                                   const SMDS_MeshNode * n4,
03682                                   const SMDS_MeshNode * n12,
03683                                   const SMDS_MeshNode * n23,
03684                                   const SMDS_MeshNode * n34,
03685                                   const SMDS_MeshNode * n41)
03686 {
03687   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
03688                                   myElementIDFactory->GetFreeID());
03689 }
03690 
03691 //=======================================================================
03692 //function : AddFaceWithID
03693 //purpose  :
03694 //=======================================================================
03695 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
03696                                         int n12,int n23,int n34,int n41, int ID)
03697 {
03698   return SMDS_Mesh::AddFaceWithID
03699     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
03700      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
03701      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
03702      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
03703      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
03704      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
03705      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
03706      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
03707      ID);
03708 }
03709 
03710 //=======================================================================
03711 //function : AddFaceWithID
03712 //purpose  :
03713 //=======================================================================
03714 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
03715                                         const SMDS_MeshNode * n2,
03716                                         const SMDS_MeshNode * n3,
03717                                         const SMDS_MeshNode * n4,
03718                                         const SMDS_MeshNode * n12,
03719                                         const SMDS_MeshNode * n23,
03720                                         const SMDS_MeshNode * n34,
03721                                         const SMDS_MeshNode * n41,
03722                                         int ID)
03723 {
03724   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
03725   if(hasConstructionEdges()) {
03726     // creation quadratic edges - not implemented
03727         return 0;
03728   }
03729   else
03730   {
03731     // --- retrieve nodes ID
03732     vector<vtkIdType> nodeIds;
03733     nodeIds.clear();
03734     nodeIds.push_back(n1->getVtkId());
03735     nodeIds.push_back(n2->getVtkId());
03736     nodeIds.push_back(n3->getVtkId());
03737     nodeIds.push_back(n4->getVtkId());
03738     nodeIds.push_back(n12->getVtkId());
03739     nodeIds.push_back(n23->getVtkId());
03740     nodeIds.push_back(n34->getVtkId());
03741     nodeIds.push_back(n41->getVtkId());
03742 
03743     SMDS_MeshFace * face = 0;
03744     SMDS_VtkFace *facevtk = myFacePool->getNew();
03745     facevtk->init(nodeIds, this);
03746     if (!this->registerElement(ID,facevtk))
03747       {
03748         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
03749         myFacePool->destroy(facevtk);
03750         return 0;
03751       }
03752     face = facevtk;
03753     adjustmyCellsCapacity(ID);
03754     myCells[ID] = face;
03755     myInfo.myNbQuadQuadrangles++;
03756 
03757 //    if (!registerElement(ID, face)) {
03758 //      RemoveElement(face, false);
03759 //      face = NULL;
03760 //    }
03761     return face;
03762   }
03763 }
03764 
03765 //=======================================================================
03766 //function : AddFace
03767 //purpose  :
03768 //=======================================================================
03769 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
03770                                   const SMDS_MeshNode * n2,
03771                                   const SMDS_MeshNode * n3,
03772                                   const SMDS_MeshNode * n4,
03773                                   const SMDS_MeshNode * n12,
03774                                   const SMDS_MeshNode * n23,
03775                                   const SMDS_MeshNode * n34,
03776                                   const SMDS_MeshNode * n41,
03777                                   const SMDS_MeshNode * nCenter)
03778 {
03779   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
03780                                   myElementIDFactory->GetFreeID());
03781 }
03782 
03783 //=======================================================================
03784 //function : AddFaceWithID
03785 //purpose  :
03786 //=======================================================================
03787 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
03788                                         int n12,int n23,int n34,int n41, int nCenter, int ID)
03789 {
03790   return SMDS_Mesh::AddFaceWithID
03791     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
03792      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
03793      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
03794      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
03795      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
03796      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
03797      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
03798      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
03799      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
03800      ID);
03801 }
03802 
03803 //=======================================================================
03804 //function : AddFaceWithID
03805 //purpose  :
03806 //=======================================================================
03807 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
03808                                         const SMDS_MeshNode * n2,
03809                                         const SMDS_MeshNode * n3,
03810                                         const SMDS_MeshNode * n4,
03811                                         const SMDS_MeshNode * n12,
03812                                         const SMDS_MeshNode * n23,
03813                                         const SMDS_MeshNode * n34,
03814                                         const SMDS_MeshNode * n41,
03815                                         const SMDS_MeshNode * nCenter,
03816                                         int ID)
03817 {
03818   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
03819   if(hasConstructionEdges()) {
03820     // creation quadratic edges - not implemented
03821         return 0;
03822   }
03823   else
03824   {
03825     // --- retrieve nodes ID
03826     vector<vtkIdType> nodeIds;
03827     nodeIds.clear();
03828     nodeIds.push_back(n1->getVtkId());
03829     nodeIds.push_back(n2->getVtkId());
03830     nodeIds.push_back(n3->getVtkId());
03831     nodeIds.push_back(n4->getVtkId());
03832     nodeIds.push_back(n12->getVtkId());
03833     nodeIds.push_back(n23->getVtkId());
03834     nodeIds.push_back(n34->getVtkId());
03835     nodeIds.push_back(n41->getVtkId());
03836     nodeIds.push_back(nCenter->getVtkId());
03837 
03838     SMDS_MeshFace * face = 0;
03839     SMDS_VtkFace *facevtk = myFacePool->getNew();
03840     facevtk->init(nodeIds, this);
03841     if (!this->registerElement(ID,facevtk))
03842       {
03843         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
03844         myFacePool->destroy(facevtk);
03845         return 0;
03846       }
03847     face = facevtk;
03848     adjustmyCellsCapacity(ID);
03849     myCells[ID] = face;
03850     myInfo.myNbBiQuadQuadrangles++;
03851 
03852 //    if (!registerElement(ID, face)) {
03853 //      RemoveElement(face, false);
03854 //      face = NULL;
03855 //    }
03856     return face;
03857   }
03858 }
03859 
03860 
03861 //=======================================================================
03862 //function : AddVolume
03863 //purpose  :
03864 //=======================================================================
03865 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03866                                       const SMDS_MeshNode * n2,
03867                                       const SMDS_MeshNode * n3,
03868                                       const SMDS_MeshNode * n4,
03869                                       const SMDS_MeshNode * n12,
03870                                       const SMDS_MeshNode * n23,
03871                                       const SMDS_MeshNode * n31,
03872                                       const SMDS_MeshNode * n14,
03873                                       const SMDS_MeshNode * n24,
03874                                       const SMDS_MeshNode * n34)
03875 {
03876   int ID = myElementIDFactory->GetFreeID();
03877   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
03878                                                    n31, n14, n24, n34, ID);
03879   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03880   return v;
03881 }
03882 
03883 //=======================================================================
03884 //function : AddVolumeWithID
03885 //purpose  :
03886 //=======================================================================
03887 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
03888                                             int n12,int n23,int n31,
03889                                             int n14,int n24,int n34, int ID)
03890 {
03891   return SMDS_Mesh::AddVolumeWithID
03892     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
03893      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
03894      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
03895      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
03896      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03897      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
03898      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
03899      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
03900      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
03901      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
03902      ID);
03903 }
03904 
03905 //=======================================================================
03906 //function : AddVolumeWithID
03907 //purpose  : 2d order tetrahedron of 10 nodes
03908 //=======================================================================
03909 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
03910                                             const SMDS_MeshNode * n2,
03911                                             const SMDS_MeshNode * n3,
03912                                             const SMDS_MeshNode * n4,
03913                                             const SMDS_MeshNode * n12,
03914                                             const SMDS_MeshNode * n23,
03915                                             const SMDS_MeshNode * n31,
03916                                             const SMDS_MeshNode * n14,
03917                                             const SMDS_MeshNode * n24,
03918                                             const SMDS_MeshNode * n34,
03919                                             int ID)
03920 {
03921   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
03922     return 0;
03923   if(hasConstructionFaces()) {
03924     // creation quadratic faces - not implemented
03925     return 0;
03926   }
03927   // --- retrieve nodes ID
03928   vector<vtkIdType> nodeIds;
03929   nodeIds.clear();
03930   nodeIds.push_back(n1->getVtkId());
03931   nodeIds.push_back(n3->getVtkId());
03932   nodeIds.push_back(n2->getVtkId());
03933   nodeIds.push_back(n4->getVtkId());
03934 
03935   nodeIds.push_back(n31->getVtkId());
03936   nodeIds.push_back(n23->getVtkId());
03937   nodeIds.push_back(n12->getVtkId());
03938 
03939   nodeIds.push_back(n14->getVtkId());
03940   nodeIds.push_back(n34->getVtkId());
03941   nodeIds.push_back(n24->getVtkId());
03942 
03943   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
03944   volvtk->init(nodeIds, this);
03945   if (!this->registerElement(ID,volvtk))
03946     {
03947       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
03948       myVolumePool->destroy(volvtk);
03949       return 0;
03950     }
03951   adjustmyCellsCapacity(ID);
03952   myCells[ID] = volvtk;
03953   myInfo.myNbQuadTetras++;
03954 
03955 //  if (!registerElement(ID, volvtk)) {
03956 //    RemoveElement(volvtk, false);
03957 //    volvtk = NULL;
03958 //  }
03959   return volvtk;
03960 }
03961 
03962 
03963 //=======================================================================
03964 //function : AddVolume
03965 //purpose  :
03966 //=======================================================================
03967 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03968                                       const SMDS_MeshNode * n2,
03969                                       const SMDS_MeshNode * n3,
03970                                       const SMDS_MeshNode * n4,
03971                                       const SMDS_MeshNode * n5,
03972                                       const SMDS_MeshNode * n12,
03973                                       const SMDS_MeshNode * n23,
03974                                       const SMDS_MeshNode * n34,
03975                                       const SMDS_MeshNode * n41,
03976                                       const SMDS_MeshNode * n15,
03977                                       const SMDS_MeshNode * n25,
03978                                       const SMDS_MeshNode * n35,
03979                                       const SMDS_MeshNode * n45)
03980 {
03981   int ID = myElementIDFactory->GetFreeID();
03982   SMDS_MeshVolume * v =
03983     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
03984                                n15, n25, n35, n45, ID);
03985   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03986   return v;
03987 }
03988 
03989 //=======================================================================
03990 //function : AddVolumeWithID
03991 //purpose  :
03992 //=======================================================================
03993 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
03994                                             int n12,int n23,int n34,int n41,
03995                                             int n15,int n25,int n35,int n45, int ID)
03996 {
03997   return SMDS_Mesh::AddVolumeWithID
03998     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
03999      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
04000      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
04001      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
04002      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
04003      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
04004      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
04005      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
04006      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
04007      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
04008      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
04009      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
04010      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
04011      ID);
04012 }
04013 
04014 //=======================================================================
04015 //function : AddVolumeWithID
04016 //purpose  : 2d order pyramid of 13 nodes
04017 //=======================================================================
04018 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
04019                                             const SMDS_MeshNode * n2,
04020                                             const SMDS_MeshNode * n3,
04021                                             const SMDS_MeshNode * n4,
04022                                             const SMDS_MeshNode * n5,
04023                                             const SMDS_MeshNode * n12,
04024                                             const SMDS_MeshNode * n23,
04025                                             const SMDS_MeshNode * n34,
04026                                             const SMDS_MeshNode * n41,
04027                                             const SMDS_MeshNode * n15,
04028                                             const SMDS_MeshNode * n25,
04029                                             const SMDS_MeshNode * n35,
04030                                             const SMDS_MeshNode * n45,
04031                                             int ID)
04032 {
04033   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
04034       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
04035     return 0;
04036   if(hasConstructionFaces()) {
04037     // creation quadratic faces - not implemented
04038     return 0;
04039   }
04040   // --- retrieve nodes ID
04041   vector<vtkIdType> nodeIds;
04042   nodeIds.clear();
04043   nodeIds.push_back(n1->getVtkId());
04044   nodeIds.push_back(n4->getVtkId());
04045   nodeIds.push_back(n3->getVtkId());
04046   nodeIds.push_back(n2->getVtkId());
04047   nodeIds.push_back(n5->getVtkId());
04048 
04049   nodeIds.push_back(n41->getVtkId());
04050   nodeIds.push_back(n34->getVtkId());
04051   nodeIds.push_back(n23->getVtkId());
04052   nodeIds.push_back(n12->getVtkId());
04053 
04054   nodeIds.push_back(n15->getVtkId());
04055   nodeIds.push_back(n45->getVtkId());
04056   nodeIds.push_back(n35->getVtkId());
04057   nodeIds.push_back(n25->getVtkId());
04058 
04059   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
04060   volvtk->init(nodeIds, this);
04061   if (!this->registerElement(ID,volvtk))
04062     {
04063       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
04064       myVolumePool->destroy(volvtk);
04065       return 0;
04066     }
04067   adjustmyCellsCapacity(ID);
04068   myCells[ID] = volvtk;
04069   myInfo.myNbQuadPyramids++;
04070 
04071 //  if (!registerElement(ID, volvtk)) {
04072 //    RemoveElement(volvtk, false);
04073 //    volvtk = NULL;
04074 //  }
04075   return volvtk;
04076 }
04077 
04078 
04079 //=======================================================================
04080 //function : AddVolume
04081 //purpose  :
04082 //=======================================================================
04083 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
04084                                       const SMDS_MeshNode * n2,
04085                                       const SMDS_MeshNode * n3,
04086                                       const SMDS_MeshNode * n4,
04087                                       const SMDS_MeshNode * n5,
04088                                       const SMDS_MeshNode * n6,
04089                                       const SMDS_MeshNode * n12,
04090                                       const SMDS_MeshNode * n23,
04091                                       const SMDS_MeshNode * n31,
04092                                       const SMDS_MeshNode * n45,
04093                                       const SMDS_MeshNode * n56,
04094                                       const SMDS_MeshNode * n64,
04095                                       const SMDS_MeshNode * n14,
04096                                       const SMDS_MeshNode * n25,
04097                                       const SMDS_MeshNode * n36)
04098 {
04099   int ID = myElementIDFactory->GetFreeID();
04100   SMDS_MeshVolume * v =
04101     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
04102                                n45, n56, n64, n14, n25, n36, ID);
04103   if(v==NULL) myElementIDFactory->ReleaseID(ID);
04104   return v;
04105 }
04106 
04107 //=======================================================================
04108 //function : AddVolumeWithID
04109 //purpose  :
04110 //=======================================================================
04111 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
04112                                             int n4, int n5, int n6,
04113                                             int n12,int n23,int n31,
04114                                             int n45,int n56,int n64,
04115                                             int n14,int n25,int n36, int ID)
04116 {
04117   return SMDS_Mesh::AddVolumeWithID
04118     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
04119      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
04120      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
04121      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
04122      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
04123      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
04124      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
04125      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
04126      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
04127      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
04128      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
04129      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
04130      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
04131      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
04132      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
04133      ID);
04134 }
04135 
04136 //=======================================================================
04137 //function : AddVolumeWithID
04138 //purpose  : 2d order Pentahedron with 15 nodes
04139 //=======================================================================
04140 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
04141                                             const SMDS_MeshNode * n2,
04142                                             const SMDS_MeshNode * n3,
04143                                             const SMDS_MeshNode * n4,
04144                                             const SMDS_MeshNode * n5,
04145                                             const SMDS_MeshNode * n6,
04146                                             const SMDS_MeshNode * n12,
04147                                             const SMDS_MeshNode * n23,
04148                                             const SMDS_MeshNode * n31,
04149                                             const SMDS_MeshNode * n45,
04150                                             const SMDS_MeshNode * n56,
04151                                             const SMDS_MeshNode * n64,
04152                                             const SMDS_MeshNode * n14,
04153                                             const SMDS_MeshNode * n25,
04154                                             const SMDS_MeshNode * n36,
04155                                             int ID)
04156 {
04157   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
04158       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
04159     return 0;
04160   if(hasConstructionFaces()) {
04161     // creation quadratic faces - not implemented
04162     return 0;
04163   }
04164   // --- retrieve nodes ID
04165   vector<vtkIdType> nodeIds;
04166   nodeIds.clear();
04167   nodeIds.push_back(n1->getVtkId());
04168   nodeIds.push_back(n2->getVtkId());
04169   nodeIds.push_back(n3->getVtkId());
04170 
04171   nodeIds.push_back(n4->getVtkId());
04172   nodeIds.push_back(n5->getVtkId());
04173   nodeIds.push_back(n6->getVtkId());
04174 
04175   nodeIds.push_back(n12->getVtkId());
04176   nodeIds.push_back(n23->getVtkId());
04177   nodeIds.push_back(n31->getVtkId());
04178 
04179   nodeIds.push_back(n45->getVtkId());
04180   nodeIds.push_back(n56->getVtkId());
04181   nodeIds.push_back(n64->getVtkId());
04182 
04183   nodeIds.push_back(n14->getVtkId());
04184   nodeIds.push_back(n25->getVtkId());
04185   nodeIds.push_back(n36->getVtkId());
04186 
04187   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
04188   volvtk->init(nodeIds, this);
04189   if (!this->registerElement(ID,volvtk))
04190     {
04191       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
04192       myVolumePool->destroy(volvtk);
04193       return 0;
04194     }
04195   adjustmyCellsCapacity(ID);
04196   myCells[ID] = volvtk;
04197   myInfo.myNbQuadPrisms++;
04198 
04199 //  if (!registerElement(ID, volvtk)) {
04200 //    RemoveElement(volvtk, false);
04201 //    volvtk = NULL;
04202 //  }
04203   return volvtk;
04204 }
04205 
04206 
04207 //=======================================================================
04208 //function : AddVolume
04209 //purpose  :
04210 //=======================================================================
04211 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
04212                                       const SMDS_MeshNode * n2,
04213                                       const SMDS_MeshNode * n3,
04214                                       const SMDS_MeshNode * n4,
04215                                       const SMDS_MeshNode * n5,
04216                                       const SMDS_MeshNode * n6,
04217                                       const SMDS_MeshNode * n7,
04218                                       const SMDS_MeshNode * n8,
04219                                       const SMDS_MeshNode * n12,
04220                                       const SMDS_MeshNode * n23,
04221                                       const SMDS_MeshNode * n34,
04222                                       const SMDS_MeshNode * n41,
04223                                       const SMDS_MeshNode * n56,
04224                                       const SMDS_MeshNode * n67,
04225                                       const SMDS_MeshNode * n78,
04226                                       const SMDS_MeshNode * n85,
04227                                       const SMDS_MeshNode * n15,
04228                                       const SMDS_MeshNode * n26,
04229                                       const SMDS_MeshNode * n37,
04230                                       const SMDS_MeshNode * n48)
04231 {
04232   int ID = myElementIDFactory->GetFreeID();
04233   SMDS_MeshVolume * v =
04234     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
04235                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
04236   if(v==NULL) myElementIDFactory->ReleaseID(ID);
04237   return v;
04238 }
04239 
04240 //=======================================================================
04241 //function : AddVolumeWithID
04242 //purpose  :
04243 //=======================================================================
04244 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
04245                                             int n5, int n6, int n7, int n8,
04246                                             int n12,int n23,int n34,int n41,
04247                                             int n56,int n67,int n78,int n85,
04248                                             int n15,int n26,int n37,int n48, int ID)
04249 {
04250   return SMDS_Mesh::AddVolumeWithID
04251     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
04252      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
04253      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
04254      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
04255      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
04256      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
04257      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
04258      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
04259      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
04260      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
04261      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
04262      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
04263      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
04264      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
04265      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
04266      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
04267      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
04268      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
04269      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
04270      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
04271      ID);
04272 }
04273 
04274 //=======================================================================
04275 //function : AddVolumeWithID
04276 //purpose  : 2d order Hexahedrons with 20 nodes
04277 //=======================================================================
04278 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
04279                                             const SMDS_MeshNode * n2,
04280                                             const SMDS_MeshNode * n3,
04281                                             const SMDS_MeshNode * n4,
04282                                             const SMDS_MeshNode * n5,
04283                                             const SMDS_MeshNode * n6,
04284                                             const SMDS_MeshNode * n7,
04285                                             const SMDS_MeshNode * n8,
04286                                             const SMDS_MeshNode * n12,
04287                                             const SMDS_MeshNode * n23,
04288                                             const SMDS_MeshNode * n34,
04289                                             const SMDS_MeshNode * n41,
04290                                             const SMDS_MeshNode * n56,
04291                                             const SMDS_MeshNode * n67,
04292                                             const SMDS_MeshNode * n78,
04293                                             const SMDS_MeshNode * n85,
04294                                             const SMDS_MeshNode * n15,
04295                                             const SMDS_MeshNode * n26,
04296                                             const SMDS_MeshNode * n37,
04297                                             const SMDS_MeshNode * n48,
04298                                             int ID)
04299 {
04300   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
04301       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
04302     return 0;
04303   if(hasConstructionFaces()) {
04304     return 0;
04305     // creation quadratic faces - not implemented
04306   }
04307   // --- retrieve nodes ID
04308   vector<vtkIdType> nodeIds;
04309   nodeIds.clear();
04310   nodeIds.push_back(n1->getVtkId());
04311   nodeIds.push_back(n4->getVtkId());
04312   nodeIds.push_back(n3->getVtkId());
04313   nodeIds.push_back(n2->getVtkId());
04314 
04315   nodeIds.push_back(n5->getVtkId());
04316   nodeIds.push_back(n8->getVtkId());
04317   nodeIds.push_back(n7->getVtkId());
04318   nodeIds.push_back(n6->getVtkId());
04319 
04320   nodeIds.push_back(n41->getVtkId());
04321   nodeIds.push_back(n34->getVtkId());
04322   nodeIds.push_back(n23->getVtkId());
04323   nodeIds.push_back(n12->getVtkId());
04324 
04325   nodeIds.push_back(n85->getVtkId());
04326   nodeIds.push_back(n78->getVtkId());
04327   nodeIds.push_back(n67->getVtkId());
04328   nodeIds.push_back(n56->getVtkId());
04329 
04330   nodeIds.push_back(n15->getVtkId());
04331   nodeIds.push_back(n48->getVtkId());
04332   nodeIds.push_back(n37->getVtkId());
04333   nodeIds.push_back(n26->getVtkId());
04334 
04335   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
04336   volvtk->init(nodeIds, this);
04337   if (!this->registerElement(ID,volvtk))
04338     {
04339       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
04340       myVolumePool->destroy(volvtk);
04341       return 0;
04342     }
04343   adjustmyCellsCapacity(ID);
04344   myCells[ID] = volvtk;
04345   myInfo.myNbQuadHexas++;
04346 
04347 //  if (!registerElement(ID, volvtk)) {
04348 //    RemoveElement(volvtk, false);
04349 //    volvtk = NULL;
04350 //  }
04351   return volvtk;
04352 }
04353 
04354 //=======================================================================
04355 //function : AddVolume
04356 //purpose  :
04357 //=======================================================================
04358 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
04359                                       const SMDS_MeshNode * n2,
04360                                       const SMDS_MeshNode * n3,
04361                                       const SMDS_MeshNode * n4,
04362                                       const SMDS_MeshNode * n5,
04363                                       const SMDS_MeshNode * n6,
04364                                       const SMDS_MeshNode * n7,
04365                                       const SMDS_MeshNode * n8,
04366                                       const SMDS_MeshNode * n12,
04367                                       const SMDS_MeshNode * n23,
04368                                       const SMDS_MeshNode * n34,
04369                                       const SMDS_MeshNode * n41,
04370                                       const SMDS_MeshNode * n56,
04371                                       const SMDS_MeshNode * n67,
04372                                       const SMDS_MeshNode * n78,
04373                                       const SMDS_MeshNode * n85,
04374                                       const SMDS_MeshNode * n15,
04375                                       const SMDS_MeshNode * n26,
04376                                       const SMDS_MeshNode * n37,
04377                                       const SMDS_MeshNode * n48,
04378                                       const SMDS_MeshNode * n1234,
04379                                       const SMDS_MeshNode * n1256,
04380                                       const SMDS_MeshNode * n2367,
04381                                       const SMDS_MeshNode * n3478,
04382                                       const SMDS_MeshNode * n1458,
04383                                       const SMDS_MeshNode * n5678,
04384                                       const SMDS_MeshNode * nCenter)
04385 {
04386   int ID = myElementIDFactory->GetFreeID();
04387   SMDS_MeshVolume * v =
04388     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
04389                                n56, n67, n78, n85, n15, n26, n37, n48,
04390                                n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
04391                                ID);
04392   if(v==NULL) myElementIDFactory->ReleaseID(ID);
04393   return v;
04394 }
04395 
04396 //=======================================================================
04397 //function : AddVolumeWithID
04398 //purpose  :
04399 //=======================================================================
04400 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
04401                                             int n5, int n6, int n7, int n8,
04402                                             int n12,int n23,int n34,int n41,
04403                                             int n56,int n67,int n78,int n85,
04404                                             int n15,int n26,int n37,int n48,
04405                                             int n1234,int n1256,int n2367,int n3478,
04406                                             int n1458,int n5678,int nCenter, int ID)
04407 {
04408   return SMDS_Mesh::AddVolumeWithID
04409     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
04410      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
04411      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
04412      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
04413      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
04414      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
04415      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
04416      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
04417      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
04418      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
04419      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
04420      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
04421      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
04422      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
04423      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
04424      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
04425      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
04426      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
04427      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
04428      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
04429      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
04430      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
04431      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
04432      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
04433      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
04434      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
04435      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
04436      ID);
04437 }
04438 
04439 //=======================================================================
04440 //function : AddVolumeWithID
04441 //purpose  : 2d order Hexahedrons with 20 nodes
04442 //=======================================================================
04443 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
04444                                             const SMDS_MeshNode * n2,
04445                                             const SMDS_MeshNode * n3,
04446                                             const SMDS_MeshNode * n4,
04447                                             const SMDS_MeshNode * n5,
04448                                             const SMDS_MeshNode * n6,
04449                                             const SMDS_MeshNode * n7,
04450                                             const SMDS_MeshNode * n8,
04451                                             const SMDS_MeshNode * n12,
04452                                             const SMDS_MeshNode * n23,
04453                                             const SMDS_MeshNode * n34,
04454                                             const SMDS_MeshNode * n41,
04455                                             const SMDS_MeshNode * n56,
04456                                             const SMDS_MeshNode * n67,
04457                                             const SMDS_MeshNode * n78,
04458                                             const SMDS_MeshNode * n85,
04459                                             const SMDS_MeshNode * n15,
04460                                             const SMDS_MeshNode * n26,
04461                                             const SMDS_MeshNode * n37,
04462                                             const SMDS_MeshNode * n48,
04463                                             const SMDS_MeshNode * n1234,
04464                                             const SMDS_MeshNode * n1256,
04465                                             const SMDS_MeshNode * n2367,
04466                                             const SMDS_MeshNode * n3478,
04467                                             const SMDS_MeshNode * n1458,
04468                                             const SMDS_MeshNode * n5678,
04469                                             const SMDS_MeshNode * nCenter,
04470                                             int ID)
04471 {
04472   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
04473       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
04474       !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
04475     return 0;
04476   if(hasConstructionFaces()) {
04477     return 0;
04478     // creation quadratic faces - not implemented
04479   }
04480   // --- retrieve nodes ID
04481   vector<vtkIdType> nodeIds;
04482   nodeIds.clear();
04483   nodeIds.push_back(n1->getVtkId());
04484   nodeIds.push_back(n4->getVtkId());
04485   nodeIds.push_back(n3->getVtkId());
04486   nodeIds.push_back(n2->getVtkId());
04487 
04488   nodeIds.push_back(n5->getVtkId());
04489   nodeIds.push_back(n8->getVtkId());
04490   nodeIds.push_back(n7->getVtkId());
04491   nodeIds.push_back(n6->getVtkId());
04492 
04493   nodeIds.push_back(n41->getVtkId());
04494   nodeIds.push_back(n34->getVtkId());
04495   nodeIds.push_back(n23->getVtkId());
04496   nodeIds.push_back(n12->getVtkId());
04497 
04498   nodeIds.push_back(n85->getVtkId());
04499   nodeIds.push_back(n78->getVtkId());
04500   nodeIds.push_back(n67->getVtkId());
04501   nodeIds.push_back(n56->getVtkId());
04502 
04503   nodeIds.push_back(n15->getVtkId());
04504   nodeIds.push_back(n48->getVtkId());
04505   nodeIds.push_back(n37->getVtkId());
04506   nodeIds.push_back(n26->getVtkId());
04507 
04508   nodeIds.push_back(n1256->getVtkId());
04509   nodeIds.push_back(n3478->getVtkId());
04510   nodeIds.push_back(n1458->getVtkId());
04511   nodeIds.push_back(n2367->getVtkId());
04512   nodeIds.push_back(n1234->getVtkId());
04513   nodeIds.push_back(n5678->getVtkId());
04514   nodeIds.push_back(nCenter->getVtkId());
04515 
04516   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
04517   volvtk->init(nodeIds, this);
04518   if (!this->registerElement(ID,volvtk))
04519     {
04520       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
04521       myVolumePool->destroy(volvtk);
04522       return 0;
04523     }
04524   adjustmyCellsCapacity(ID);
04525   myCells[ID] = volvtk;
04526   myInfo.myNbTriQuadHexas++;
04527 
04528   return volvtk;
04529 }
04530 
04531 
04532 void SMDS_Mesh::updateNodeMinMax()
04533 {
04534   myNodeMin = 0;
04535   if (myNodes.size() == 0)
04536   {
04537         myNodeMax=0;
04538         return;
04539   }
04540   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
04541     myNodeMin++;
04542   myNodeMax=myNodes.size()-1;
04543   while (!myNodes[myNodeMax] && (myNodeMin>=0))
04544     myNodeMin--;
04545 }
04546 
04547 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
04548 {
04549 //  int val = myCellIdSmdsToVtk.size();
04550 //  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
04551 //  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
04552   int val = myNodes.size();
04553   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
04554   myNodes.resize(val +nbNodes, 0);
04555 }
04556 
04557 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
04558 {
04559   int val = myCellIdVtkToSmds.size();
04560   MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
04561   myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
04562   val = myCells.size();
04563   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
04564   myNodes.resize(val +nbCells, 0);
04565 }
04566 
04567 void SMDS_Mesh::adjustStructure()
04568 {
04569   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
04570 }
04571 
04572 void SMDS_Mesh::dumpGrid(string ficdump)
04573 {
04574         MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
04575 //  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
04576 //  aWriter->SetFileName(ficdump.c_str());
04577 //  aWriter->SetInput(myGrid);
04578 //  if(myGrid->GetNumberOfCells())
04579 //  {
04580 //    aWriter->Write();
04581 //  }
04582 //  aWriter->Delete();
04583   ficdump = ficdump + "_connectivity";
04584   ofstream ficcon(ficdump.c_str(), ios::out);
04585   int nbPoints = myGrid->GetNumberOfPoints();
04586   ficcon << "-------------------------------- points " <<  nbPoints << endl;
04587   for (int i=0; i<nbPoints; i++)
04588   {
04589         ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
04590   }
04591   int nbCells = myGrid->GetNumberOfCells();
04592   ficcon << "-------------------------------- cells " <<  nbCells << endl;
04593   for (int i=0; i<nbCells; i++)
04594   {
04595 //      MESSAGE(i << " " << myGrid->GetCell(i));
04596 //      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
04597         ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
04598         int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
04599         vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
04600         for (int j=0; j<nbptcell; j++)
04601         {
04602                 ficcon << " " <<  listid->GetId(j);
04603         }
04604         ficcon << endl;
04605   }
04606   ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
04607         vtkCellLinks *links = myGrid->GetCellLinks();
04608   for (int i=0; i<nbPoints; i++)
04609   {
04610         int ncells = links->GetNcells(i);
04611         vtkIdType *cells = links->GetCells(i);
04612         ficcon << i << " - " << ncells << " -";
04613         for (int j=0; j<ncells; j++)
04614         {
04615                 ficcon << " " << cells[j];
04616         }
04617         ficcon << endl;
04618   }
04619   ficcon.close();
04620 
04621 }
04622 
04623 void SMDS_Mesh::compactMesh()
04624 {
04625   MESSAGE("SMDS_Mesh::compactMesh do nothing!");
04626 }
04627 
04628 int SMDS_Mesh::fromVtkToSmds(int vtkid)
04629 {
04630   if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
04631     return myCellIdVtkToSmds[vtkid];
04632   throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
04633 }
04634 
04635 void SMDS_Mesh::updateBoundingBox()
04636 {
04637   xmin = 0; xmax = 0;
04638   ymin = 0; ymax = 0;
04639   zmin = 0; zmax = 0;
04640   vtkPoints *points = myGrid->GetPoints();
04641   int myNodesSize = this->myNodes.size();
04642   for (int i = 0; i < myNodesSize; i++)
04643     {
04644       if (SMDS_MeshNode *n = myNodes[i])
04645         {
04646           double coords[3];
04647           points->GetPoint(n->myVtkID, coords);
04648           if (coords[0] < xmin) xmin = coords[0];
04649           else if (coords[0] > xmax) xmax = coords[0];
04650           if (coords[1] < ymin) ymin = coords[1];
04651           else if (coords[1] > ymax) ymax = coords[1];
04652           if (coords[2] < zmin) zmin = coords[2];
04653           else if (coords[2] > zmax) zmax = coords[2];
04654         }
04655     }
04656 }
04657 
04658 double SMDS_Mesh::getMaxDim()
04659 {
04660   double dmax = 1.e-3;
04661   if ((xmax - xmin) > dmax) dmax = xmax -xmin;
04662   if ((ymax - ymin) > dmax) dmax = ymax -ymin;
04663   if ((zmax - zmin) > dmax) dmax = zmax -zmin;
04664   MESSAGE("getMaxDim " << dmax);
04665   return dmax;
04666 }
04667 
04669 void SMDS_Mesh::Modified()
04670 {
04671   if (this->myModified)
04672     {
04673       this->myModifTime++;
04674       MESSAGE("modified");
04675       myModified = false;
04676     }
04677 }
04678 
04680 unsigned long SMDS_Mesh::GetMTime() const
04681 {
04682   return this->myModifTime;
04683 }
04684 
04685 bool SMDS_Mesh::isCompacted()
04686 {
04687   if (this->myModifTime > this->myCompactTime)
04688     {
04689       MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
04690       this->myCompactTime = this->myModifTime;
04691       return false;
04692     }
04693   return true;
04694 }