Version: 6.3.1

src/SMDS/SMDS_Mesh.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  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 
00869 
00870 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
00871                                       const SMDS_MeshNode * n2,
00872                                       const SMDS_MeshNode * n3,
00873                                       const SMDS_MeshNode * n4,
00874                                       const SMDS_MeshNode * n5,
00875                                       const SMDS_MeshNode * n6,
00876                                       const SMDS_MeshNode * n7,
00877                                       const SMDS_MeshNode * n8)
00878 {
00879   int ID = myElementIDFactory->GetFreeID();
00880      //MESSAGE("AddVolumeWithID " << ID);
00881  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
00882   if(v==NULL) myElementIDFactory->ReleaseID(ID);
00883   return v;
00884 }
00885 
00893 
00894 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
00895                                              int idnode2,
00896                                              int idnode3,
00897                                              int idnode4,
00898                                              int idnode5,
00899                                              int idnode6,
00900                                              int idnode7,
00901                                              int idnode8,
00902                                              int ID)
00903 {
00904     //MESSAGE("AddVolumeWithID " << ID);
00905   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
00906   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
00907   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
00908   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
00909   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
00910   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
00911   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
00912   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
00913   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
00914   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
00915     return NULL;
00916   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
00917                                     node7, node8, ID);
00918 }
00919 
00927 
00928 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
00929                                             const SMDS_MeshNode * n2,
00930                                             const SMDS_MeshNode * n3,
00931                                             const SMDS_MeshNode * n4,
00932                                             const SMDS_MeshNode * n5,
00933                                             const SMDS_MeshNode * n6,
00934                                             const SMDS_MeshNode * n7,
00935                                             const SMDS_MeshNode * n8,
00936                                             int ID)
00937 {
00938     //MESSAGE("AddVolumeWithID " << ID);
00939   SMDS_MeshVolume* volume = 0;
00940   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
00941   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
00942   if(hasConstructionFaces()) {
00943     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
00944     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
00945     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
00946     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
00947     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
00948     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
00949     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
00950     adjustmyCellsCapacity(ID);
00951     myCells[ID] = volume;
00952     myInfo.myNbHexas++;
00953   }
00954   else if(hasConstructionEdges()) {
00955     MESSAGE("Error : Not implemented");
00956     return NULL;
00957   }
00958   else {
00959     // --- retrieve nodes ID
00960     vector<vtkIdType> nodeIds;
00961     nodeIds.clear();
00962     nodeIds.push_back(n1->getVtkId());
00963     nodeIds.push_back(n4->getVtkId());
00964     nodeIds.push_back(n3->getVtkId());
00965     nodeIds.push_back(n2->getVtkId());
00966     nodeIds.push_back(n5->getVtkId());
00967     nodeIds.push_back(n8->getVtkId());
00968     nodeIds.push_back(n7->getVtkId());
00969     nodeIds.push_back(n6->getVtkId());
00970 
00971     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
00972     volvtk->init(nodeIds, this);
00973     if (!this->registerElement(ID,volvtk))
00974       {
00975         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
00976         myVolumePool->destroy(volvtk);
00977         return 0;
00978       }
00979     volume = volvtk;
00980     adjustmyCellsCapacity(ID);
00981     myCells[ID] = volume;
00982     myInfo.myNbHexas++;
00983   }
00984  
00985 //  if (!registerElement(ID, volume)) {
00986 //    RemoveElement(volume, false);
00987 //    volume = NULL;
00988 //  }
00989   return volume;
00990 }
00991 
00996 
00997 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
00998                                       const SMDS_MeshFace * f2,
00999                                       const SMDS_MeshFace * f3,
01000                                       const SMDS_MeshFace * f4)
01001 {
01002     //MESSAGE("AddVolumeWithID");
01003   if (!hasConstructionFaces())
01004     return NULL;
01005   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
01006 }
01007 
01013 
01014 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01015                                             const SMDS_MeshFace * f2,
01016                                             const SMDS_MeshFace * f3,
01017                                             const SMDS_MeshFace * f4,
01018                                             int ID)
01019 {
01020   MESSAGE("AddVolumeWithID" << ID);
01021   if (!hasConstructionFaces())
01022     return NULL;
01023   if ( !f1 || !f2 || !f3 || !f4) return 0;
01024   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01025   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
01026   adjustmyCellsCapacity(ID);
01027   myCells[ID] = volume;
01028   myInfo.myNbTetras++;
01029 
01030   if (!registerElement(ID, volume)) {
01031     registerElement(myElementIDFactory->GetFreeID(), volume);
01032     //RemoveElement(volume, false);
01033     //volume = NULL;
01034   }
01035   return volume;
01036 }
01037 
01042 
01043 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
01044                                       const SMDS_MeshFace * f2,
01045                                       const SMDS_MeshFace * f3,
01046                                       const SMDS_MeshFace * f4,
01047                                       const SMDS_MeshFace * f5)
01048 {
01049      //MESSAGE("AddVolumeWithID");
01050  if (!hasConstructionFaces())
01051     return NULL;
01052   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
01053 }
01054 
01060 
01061 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01062                                             const SMDS_MeshFace * f2,
01063                                             const SMDS_MeshFace * f3,
01064                                             const SMDS_MeshFace * f4,
01065                                             const SMDS_MeshFace * f5,
01066                                             int ID)
01067 {
01068   MESSAGE("AddVolumeWithID" << ID);
01069   if (!hasConstructionFaces())
01070     return NULL;
01071   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
01072   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01073   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
01074   adjustmyCellsCapacity(ID);
01075   myCells[ID] = volume;
01076   myInfo.myNbPyramids++;
01077 
01078   if (!registerElement(ID, volume)) {
01079     registerElement(myElementIDFactory->GetFreeID(), volume);
01080     //RemoveElement(volume, false);
01081     //volume = NULL;
01082   }
01083   return volume;
01084 }
01085 
01090 
01091 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
01092                                       const SMDS_MeshFace * f2,
01093                                       const SMDS_MeshFace * f3,
01094                                       const SMDS_MeshFace * f4,
01095                                       const SMDS_MeshFace * f5,
01096                                       const SMDS_MeshFace * f6)
01097 {
01098      //MESSAGE("AddVolumeWithID" );
01099  if (!hasConstructionFaces())
01100     return NULL;
01101   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
01102 }
01103 
01109 
01110 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
01111                                             const SMDS_MeshFace * f2,
01112                                             const SMDS_MeshFace * f3,
01113                                             const SMDS_MeshFace * f4,
01114                                             const SMDS_MeshFace * f5,
01115                                             const SMDS_MeshFace * f6,
01116                                             int ID)
01117 {
01118   MESSAGE("AddVolumeWithID" << ID);
01119   if (!hasConstructionFaces())
01120     return NULL;
01121   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
01122   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01123   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
01124   adjustmyCellsCapacity(ID);
01125   myCells[ID] = volume;
01126   myInfo.myNbPrisms++;
01127 
01128   if (!registerElement(ID, volume)) {
01129     registerElement(myElementIDFactory->GetFreeID(), volume);
01130     //RemoveElement(volume, false);
01131     //volume = NULL;
01132   }
01133   return volume;
01134 }
01135 
01139 
01140 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (vector<int> nodes_ids,
01141                                                   const int        ID)
01142 {
01143   int nbNodes = nodes_ids.size();
01144   vector<const SMDS_MeshNode*> nodes (nbNodes);
01145   for (int i = 0; i < nbNodes; i++) {
01146     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
01147     if (!nodes[i]) return NULL;
01148   }
01149   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
01150 }
01151 
01155 
01156 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
01157                           (vector<const SMDS_MeshNode*> nodes,
01158                            const int                         ID)
01159 {
01160   SMDS_MeshFace * face;
01161 
01162   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01163   if (hasConstructionEdges())
01164     {
01165       MESSAGE("Error : Not implemented");
01166       return NULL;
01167     }
01168   else
01169     {
01170 //#ifdef VTK_HAVE_POLYHEDRON
01171     //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
01172     vector<vtkIdType> nodeIds;
01173     nodeIds.clear();
01174     vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
01175     for ( ; it != nodes.end(); ++it)
01176       nodeIds.push_back((*it)->getVtkId());
01177 
01178     SMDS_VtkFace *facevtk = myFacePool->getNew();
01179     facevtk->initPoly(nodeIds, this);
01180     if (!this->registerElement(ID,facevtk))
01181       {
01182         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01183         myFacePool->destroy(facevtk);
01184         return 0;
01185       }
01186     face = facevtk;
01187 //#else
01188 //    MESSAGE("AddPolygonalFaceWithID smds " << ID);
01189 //     for ( int i = 0; i < nodes.size(); ++i )
01190 //      if ( !nodes[ i ] ) return 0;
01191 //      face = new SMDS_PolygonalFaceOfNodes(nodes);
01192 //#endif
01193       adjustmyCellsCapacity(ID);
01194       myCells[ID] = face;
01195       myInfo.myNbPolygons++;
01196     }
01197 
01198 //#ifndef VTK_HAVE_POLYHEDRON
01199 //  if (!registerElement(ID, face))
01200 //    {
01201 //      registerElement(myElementIDFactory->GetFreeID(), face);
01202 //      //RemoveElement(face, false);
01203 //      //face = NULL;
01204 //    }
01205 //#endif
01206  return face;
01207 }
01208 
01213 
01214 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (vector<const SMDS_MeshNode*> nodes)
01215 {
01216   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
01217 }
01218 
01225 
01226 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
01227                              (vector<int> nodes_ids,
01228                               vector<int> quantities,
01229                               const int        ID)
01230 {
01231   int nbNodes = nodes_ids.size();
01232   vector<const SMDS_MeshNode*> nodes (nbNodes);
01233   for (int i = 0; i < nbNodes; i++) {
01234     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
01235     if (!nodes[i]) return NULL;
01236   }
01237   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
01238 }
01239 
01245 
01246 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
01247                             (vector<const SMDS_MeshNode*> nodes,
01248                              vector<int>                  quantities,
01249                              const int                    ID)
01250 {
01251   SMDS_MeshVolume* volume;
01252   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01253   if (hasConstructionFaces())
01254     {
01255       MESSAGE("Error : Not implemented");
01256       return NULL;
01257     }
01258   else if (hasConstructionEdges())
01259     {
01260       MESSAGE("Error : Not implemented");
01261       return NULL;
01262     }
01263   else
01264     {
01265 //#ifdef VTK_HAVE_POLYHEDRON
01266       //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
01267       vector<vtkIdType> nodeIds;
01268       nodeIds.clear();
01269       vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
01270       for (; it != nodes.end(); ++it)
01271         nodeIds.push_back((*it)->getVtkId());
01272 
01273       SMDS_VtkVolume *volvtk = myVolumePool->getNew();
01274       volvtk->initPoly(nodeIds, quantities, this);
01275       if (!this->registerElement(ID, volvtk))
01276         {
01277           this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
01278           myVolumePool->destroy(volvtk);
01279           return 0;
01280         }
01281       volume = volvtk;
01282 //#else
01283 //      MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
01284 //      for ( int i = 0; i < nodes.size(); ++i )
01285 //      if ( !nodes[ i ] ) return 0;
01286 //      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
01287 //#endif
01288       adjustmyCellsCapacity(ID);
01289       myCells[ID] = volume;
01290       myInfo.myNbPolyhedrons++;
01291     }
01292 
01293 //#ifndef VTK_HAVE_POLYHEDRON
01294 //  if (!registerElement(ID, volume))
01295 //    {
01296 //      registerElement(myElementIDFactory->GetFreeID(), volume);
01297 //      //RemoveElement(volume, false);
01298 //      //volume = NULL;
01299 //    }
01300 //#endif
01301   return volume;
01302 }
01303 
01308 
01309 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
01310                             (vector<const SMDS_MeshNode*> nodes,
01311                              vector<int>                  quantities)
01312 {
01313   int ID = myElementIDFactory->GetFreeID();
01314   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
01315   if (v == NULL) myElementIDFactory->ReleaseID(ID);
01316   return v;
01317 }
01318 
01319 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
01320 {
01321   int ID = myElementIDFactory->GetFreeID();
01322   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
01323   if (v == NULL) myElementIDFactory->ReleaseID(ID);
01324   return v;
01325 }
01326 
01327 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
01328 {
01329   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
01330   volvtk->init(vtkNodeIds, this);
01331   if (!this->registerElement(ID,volvtk))
01332     {
01333       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
01334       myVolumePool->destroy(volvtk);
01335       return 0;
01336     }
01337   adjustmyCellsCapacity(ID);
01338   myCells[ID] = volvtk;
01339   vtkIdType aVtkType = volvtk->GetVtkType();
01340   switch (aVtkType)
01341   {
01342     case VTK_TETRA:
01343       myInfo.myNbTetras++;
01344       break;
01345     case VTK_PYRAMID:
01346       myInfo.myNbPyramids++;
01347       break;
01348     case VTK_WEDGE:
01349       myInfo.myNbPrisms++;
01350       break;
01351     case VTK_HEXAHEDRON:
01352       myInfo.myNbHexas++;
01353       break;
01354     case VTK_QUADRATIC_TETRA:
01355       myInfo.myNbQuadTetras++;
01356       break;
01357     case VTK_QUADRATIC_PYRAMID:
01358       myInfo.myNbQuadPyramids++;
01359       break;
01360     case VTK_QUADRATIC_WEDGE:
01361       myInfo.myNbQuadPrisms++;
01362       break;
01363     case VTK_QUADRATIC_HEXAHEDRON:
01364       myInfo.myNbQuadHexas++;
01365       break;
01366 //#ifdef VTK_HAVE_POLYHEDRON
01367     case VTK_POLYHEDRON:
01368       myInfo.myNbPolyhedrons++;
01369       break;
01370 //#endif
01371     default:
01372       myInfo.myNbPolyhedrons++;
01373       break;
01374   }
01375   return volvtk;
01376 }
01377 
01381 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
01382 {
01383   //MESSAGE("registerElement " << ID);
01384   if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
01385   {
01386     MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
01387     return false;
01388   }
01389 
01390   element->myID = ID;
01391   element->myMeshId = myMeshId;
01392 
01393   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
01394   MYASSERT(cell);
01395   int vtkId = cell->getVtkId();  
01396   if (vtkId == -1)
01397     vtkId = myElementIDFactory->SetInVtkGrid(element);
01398 
01399   if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
01400   {
01401     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
01402     myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
01403   }
01404   myCellIdVtkToSmds[vtkId] = ID;
01405 
01406   myElementIDFactory->updateMinMax(ID);
01407   return true;
01408 }
01409 
01413 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
01414 {
01415   if (ID < 1 || ID >= myNodes.size())
01416   {
01417     MESSAGE("------------------------------------------------------------------------- ");
01418     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
01419     MESSAGE("------------------------------------------------------------------------- ");
01420     return 0;
01421   }
01422   return (const SMDS_MeshNode *)myNodes[ID];
01423 }
01424 
01428 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
01429 {
01430   // TODO if needed use mesh->nodeIdFromVtkToSmds
01431   if (vtkId < 0 || vtkId >= (myNodes.size() -1))
01432   {
01433     MESSAGE("------------------------------------------------------------------------- ");
01434     MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
01435     MESSAGE("------------------------------------------------------------------------- ");
01436     return 0;
01437   }
01438   return (const SMDS_MeshNode *)myNodes[vtkId+1];
01439 }
01440 
01445 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
01446                                           const SMDS_MeshNode * node2,
01447                                           const SMDS_MeshNode * node3,
01448                                           int ID)
01449 {
01450   if ( !node1 || !node2 || !node3) return 0;
01451   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01452   if(hasConstructionEdges())
01453   {
01454     SMDS_MeshEdge *edge1, *edge2, *edge3;
01455     edge1=FindEdgeOrCreate(node1,node2);
01456     edge2=FindEdgeOrCreate(node2,node3);
01457     edge3=FindEdgeOrCreate(node3,node1);
01458 
01459     //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
01460     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
01461     adjustmyCellsCapacity(ID);
01462     myCells[ID] = face;
01463     myInfo.myNbTriangles++;
01464     return face;
01465   }
01466   else
01467   {
01468     // --- retrieve nodes ID
01469     vector<vtkIdType> nodeIds;
01470     nodeIds.clear();
01471     nodeIds.push_back(node1->getVtkId());
01472     nodeIds.push_back(node2->getVtkId());
01473     nodeIds.push_back(node3->getVtkId());
01474 
01475     SMDS_MeshFace * face = 0;
01476     SMDS_VtkFace *facevtk = myFacePool->getNew();
01477     facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
01478     if (!this->registerElement(ID,facevtk))
01479       {
01480         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01481         myFacePool->destroy(facevtk);
01482         return 0;
01483       }
01484     face = facevtk;
01485     adjustmyCellsCapacity(ID);
01486     myCells[ID] = face;
01487     //MESSAGE("createTriangle " << ID << " " << face);
01488     myInfo.myNbTriangles++;
01489     return face;
01490   }
01491 }
01492 
01497 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
01498                                             const SMDS_MeshNode * node2,
01499                                             const SMDS_MeshNode * node3,
01500                                             const SMDS_MeshNode * node4,
01501                                             int ID)
01502 {
01503   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
01504   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01505   if(hasConstructionEdges())
01506   {
01507       //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
01508     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
01509     edge1=FindEdgeOrCreate(node1,node2);
01510     edge2=FindEdgeOrCreate(node2,node3);
01511     edge3=FindEdgeOrCreate(node3,node4);
01512     edge4=FindEdgeOrCreate(node4,node1);
01513 
01514     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
01515     adjustmyCellsCapacity(ID);
01516     myCells[ID] = face;
01517     myInfo.myNbQuadrangles++;
01518     return face;
01519   }
01520   else
01521   {
01522     // --- retrieve nodes ID
01523     vector<vtkIdType> nodeIds;
01524     nodeIds.clear();
01525     nodeIds.push_back(node1->getVtkId());
01526     nodeIds.push_back(node2->getVtkId());
01527     nodeIds.push_back(node3->getVtkId());
01528     nodeIds.push_back(node4->getVtkId());
01529 
01530     SMDS_MeshFace * face = 0;
01531     SMDS_VtkFace *facevtk = myFacePool->getNew();
01532     facevtk->init(nodeIds, this);
01533     if (!this->registerElement(ID,facevtk))
01534       {
01535         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
01536         myFacePool->destroy(facevtk);
01537         return 0;
01538       }
01539     face = facevtk;
01540     adjustmyCellsCapacity(ID);
01541     myCells[ID] = face;
01542     myInfo.myNbQuadrangles++;
01543     return face;
01544   }
01545 }
01546 
01550 
01551 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
01552 {
01553     MESSAGE("RemoveNode");
01554         RemoveElement(node, true);
01555 }
01556 
01560 
01561 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
01562 {
01563     MESSAGE("Remove0DElement");
01564   RemoveElement(elem0d,true);
01565 }
01566 
01570 
01571 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
01572 {
01573     MESSAGE("RemoveEdge");
01574         RemoveElement(edge,true);
01575 }
01576 
01580 
01581 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
01582 {
01583     MESSAGE("RemoveFace");
01584         RemoveElement(face, true);
01585 }
01586 
01590 
01591 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
01592 {
01593     MESSAGE("RemoveVolume");
01594         RemoveElement(volume, true);
01595 }
01596 
01597 //=======================================================================
01598 //function : RemoveFromParent
01599 //purpose  :
01600 //=======================================================================
01601 
01602 bool SMDS_Mesh::RemoveFromParent()
01603 {
01604         if (myParent==NULL) return false;
01605         else return (myParent->RemoveSubMesh(this));
01606 }
01607 
01608 //=======================================================================
01609 //function : RemoveSubMesh
01610 //purpose  :
01611 //=======================================================================
01612 
01613 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
01614 {
01615         bool found = false;
01616 
01617         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
01618         for (; itmsh!=myChildren.end() && !found; itmsh++)
01619         {
01620                 SMDS_Mesh * submesh = *itmsh;
01621                 if (submesh == aMesh)
01622                 {
01623                         found = true;
01624                         myChildren.erase(itmsh);
01625                 }
01626         }
01627 
01628         return found;
01629 }
01630 
01631 //=======================================================================
01632 //function : ChangeElementNodes
01633 //purpose  :
01634 //=======================================================================
01635 
01636 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
01637                                    const SMDS_MeshNode    * nodes[],
01638                                    const int                nbnodes)
01639 {
01640   MESSAGE("SMDS_Mesh::ChangeElementNodes");
01641   // keep current nodes of elem
01642   set<const SMDS_MeshElement*> oldNodes;
01643   SMDS_ElemIteratorPtr itn = element->nodesIterator();
01644   while(itn->more())
01645     oldNodes.insert(itn->next());
01646 
01647   // change nodes
01648   bool Ok = false;
01649   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
01650   if (cell)
01651     {
01652       Ok = cell->vtkOrder(nodes, nbnodes);
01653       Ok = cell->ChangeNodes(nodes, nbnodes);
01654     }
01655 
01656   if ( Ok ) { // update InverseElements
01657 
01658     set<const SMDS_MeshElement*>::iterator it;
01659 
01660     // AddInverseElement to new nodes
01661     for ( int i = 0; i < nbnodes; i++ ) {
01662       it = oldNodes.find( nodes[i] );
01663       if ( it == oldNodes.end() )
01664         // new node
01665         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
01666       else
01667         // remove from oldNodes a node that remains in elem
01668         oldNodes.erase( it );
01669     }
01670     // RemoveInverseElement from the nodes removed from elem
01671     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
01672     {
01673       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
01674         (const_cast<SMDS_MeshElement *>( *it ));
01675       n->RemoveInverseElement( cell );
01676     }
01677   }
01678 
01679   return Ok;
01680 }
01681 
01682 //=======================================================================
01683 //function : ChangePolyhedronNodes
01684 //purpose  : to change nodes of polyhedral volume
01685 //=======================================================================
01686 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
01687                                        const vector<const SMDS_MeshNode*>& nodes,
01688                                        const vector<int>                 & quantities)
01689 {
01690   if (elem->GetType() != SMDSAbs_Volume) {
01691     MESSAGE("WRONG ELEM TYPE");
01692     return false;
01693   }
01694 
01695   const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
01696   if (!vol) {
01697     return false;
01698   }
01699 
01700   // keep current nodes of elem
01701   set<const SMDS_MeshElement*> oldNodes;
01702   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
01703   while (itn->more()) {
01704     oldNodes.insert(itn->next());
01705   }
01706 
01707   // change nodes
01708   // TODO remove this function
01709   //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
01710   bool Ok = false;
01711   if (!Ok) {
01712     return false;
01713   }
01714 
01715   // update InverseElements
01716 
01717   // AddInverseElement to new nodes
01718   int nbnodes = nodes.size();
01719   set<const SMDS_MeshElement*>::iterator it;
01720   for (int i = 0; i < nbnodes; i++) {
01721     it = oldNodes.find(nodes[i]);
01722     if (it == oldNodes.end()) {
01723       // new node
01724       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
01725     } else {
01726       // remove from oldNodes a node that remains in elem
01727       oldNodes.erase(it);
01728     }
01729   }
01730 
01731   // RemoveInverseElement from the nodes removed from elem
01732   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
01733     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
01734       (const_cast<SMDS_MeshElement *>( *it ));
01735     n->RemoveInverseElement(elem);
01736   }
01737 
01738   return Ok;
01739 }
01740 
01741 
01742 //=======================================================================
01743 //function : Find0DElement
01744 //purpose  :
01745 //=======================================================================
01746 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
01747 {
01748   const SMDS_MeshNode * node = FindNode(idnode);
01749   if(node == NULL) return NULL;
01750   return Find0DElement(node);
01751 }
01752 
01753 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
01754 {
01755   if (!node) return 0;
01756   const SMDS_Mesh0DElement* toReturn = NULL;
01757   SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
01758   while (it1->more() && (toReturn == NULL)) {
01759     const SMDS_MeshElement* e = it1->next();
01760     if (e->NbNodes() == 1) {
01761       toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
01762     }
01763   }
01764   return toReturn;
01765 }
01766 
01767 //=======================================================================
01768 //function : Find0DElementOrCreate
01769 //purpose  :
01770 //=======================================================================
01771 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
01772 //{
01773 //  if (!node) return 0;
01774 //  SMDS_Mesh0DElement * toReturn = NULL;
01775 //  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
01776 //  if (toReturn == NULL) {
01777 //    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
01778 //    toReturn = new SMDS_Mesh0DElement(node);
01779 //    my0DElements.Add(toReturn);
01780 //    myInfo.myNb0DElements++;
01781 //  }
01782 //  return toReturn;
01783 //}
01784 
01785 
01786 //=======================================================================
01787 //function : FindEdge
01788 //purpose  :
01789 //=======================================================================
01790 
01791 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
01792 {
01793   const SMDS_MeshNode * node1=FindNode(idnode1);
01794   const SMDS_MeshNode * node2=FindNode(idnode2);
01795   if((node1==NULL)||(node2==NULL)) return NULL;
01796   return FindEdge(node1,node2);
01797 }
01798 
01799 //#include "Profiler.h"
01800 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
01801                                          const SMDS_MeshNode * node2)
01802 {
01803   if ( !node1 ) return 0;
01804   const SMDS_MeshEdge * toReturn=NULL;
01805   //PROFILER_Init();
01806   //PROFILER_Set();
01807   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
01808   //PROFILER_Get(0);
01809   //PROFILER_Set();
01810   while(it1->more()) {
01811     const SMDS_MeshElement * e = it1->next();
01812     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
01813       toReturn = static_cast<const SMDS_MeshEdge*>( e );
01814       break;
01815     }
01816   }
01817   //PROFILER_Get(1);
01818   return toReturn;
01819 }
01820 
01821 
01822 //=======================================================================
01823 //function : FindEdgeOrCreate
01824 //purpose  :
01825 //=======================================================================
01826 
01827 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
01828                                            const SMDS_MeshNode * node2)
01829 {
01830   if ( !node1 || !node2) return 0;
01831   SMDS_MeshEdge * toReturn=NULL;
01832   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
01833   if(toReturn==NULL) {
01834     if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
01835     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
01836     adjustmyCellsCapacity(ID);
01837     vector<vtkIdType> nodeIds;
01838     nodeIds.clear();
01839     nodeIds.push_back(node1->getVtkId());
01840     nodeIds.push_back(node2->getVtkId());
01841 
01842     SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
01843     edgevtk->init(nodeIds, this);
01844     if (!this->registerElement(ID,edgevtk))
01845       {
01846         this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
01847         myEdgePool->destroy(edgevtk);
01848         return 0;
01849       }
01850     toReturn = edgevtk;
01851     myCells[ID] = toReturn;
01852     myInfo.myNbEdges++;
01853   }
01854   return toReturn;
01855 }
01856 
01857 
01858 //=======================================================================
01859 //function : FindEdge
01860 //purpose  :
01861 //=======================================================================
01862 
01863 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
01864                                          int idnode3) const
01865 {
01866   const SMDS_MeshNode * node1=FindNode(idnode1);
01867   const SMDS_MeshNode * node2=FindNode(idnode2);
01868   const SMDS_MeshNode * node3=FindNode(idnode3);
01869   return FindEdge(node1,node2,node3);
01870 }
01871 
01872 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
01873                                          const SMDS_MeshNode * node2,
01874                                          const SMDS_MeshNode * node3)
01875 {
01876   if ( !node1 ) return 0;
01877   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
01878   while(it1->more()) {
01879     const SMDS_MeshElement * e = it1->next();
01880     if ( e->NbNodes() == 3 ) {
01881       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
01882       while(it2->more()) {
01883         const SMDS_MeshElement* n = it2->next();
01884         if( n!=node1 &&
01885             n!=node2 &&
01886             n!=node3 )
01887         {
01888           e = 0;
01889           break;
01890         }
01891       }
01892       if ( e )
01893         return static_cast<const SMDS_MeshEdge *> (e);
01894     }
01895   }
01896   return 0;
01897 }
01898 
01899 
01900 //=======================================================================
01901 //function : FindFace
01902 //purpose  :
01903 //=======================================================================
01904 
01905 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
01906         int idnode3) const
01907 {
01908   const SMDS_MeshNode * node1=FindNode(idnode1);
01909   const SMDS_MeshNode * node2=FindNode(idnode2);
01910   const SMDS_MeshNode * node3=FindNode(idnode3);
01911   return FindFace(node1, node2, node3);
01912 }
01913 
01914 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
01915                                          const SMDS_MeshNode *node2,
01916                                          const SMDS_MeshNode *node3)
01917 {
01918   if ( !node1 ) return 0;
01919   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
01920   while(it1->more()) {
01921     const SMDS_MeshElement * e = it1->next();
01922     if ( e->NbNodes() == 3 ) {
01923       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
01924       while(it2->more()) {
01925         const SMDS_MeshElement* n = it2->next();
01926         if( n!=node1 &&
01927             n!=node2 &&
01928             n!=node3 )
01929         {
01930           e = 0;
01931           break;
01932         }
01933       }
01934       if ( e )
01935         return static_cast<const SMDS_MeshFace *> (e);
01936     }
01937   }
01938   return 0;
01939 }
01940 
01941 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
01942                                            const SMDS_MeshNode *node2,
01943                                            const SMDS_MeshNode *node3)
01944 {
01945   SMDS_MeshFace * toReturn=NULL;
01946   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
01947   if(toReturn==NULL) {
01948     int ID = myElementIDFactory->GetFreeID();
01949     toReturn = createTriangle(node1,node2,node3, ID);
01950   }
01951   return toReturn;
01952 }
01953 
01954 
01955 //=======================================================================
01956 //function : FindFace
01957 //purpose  :
01958 //=======================================================================
01959 
01960 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
01961                                          int idnode3, int idnode4) const
01962 {
01963   const SMDS_MeshNode * node1=FindNode(idnode1);
01964   const SMDS_MeshNode * node2=FindNode(idnode2);
01965   const SMDS_MeshNode * node3=FindNode(idnode3);
01966   const SMDS_MeshNode * node4=FindNode(idnode4);
01967   return FindFace(node1, node2, node3, node4);
01968 }
01969 
01970 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
01971                                          const SMDS_MeshNode *node2,
01972                                          const SMDS_MeshNode *node3,
01973                                          const SMDS_MeshNode *node4)
01974 {
01975   if ( !node1 ) return 0;
01976   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
01977   while(it1->more()) {
01978     const SMDS_MeshElement * e = it1->next();
01979     if ( e->NbNodes() == 4 ) {
01980       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
01981       while(it2->more()) {
01982         const SMDS_MeshElement* n = it2->next();
01983         if( n!=node1 &&
01984             n!=node2 &&
01985             n!=node3 &&
01986             n!=node4 )
01987         {
01988           e = 0;
01989           break;
01990         }
01991       }
01992       if ( e )
01993         return static_cast<const SMDS_MeshFace *> (e);
01994     }
01995   }
01996   return 0;
01997 }
01998 
01999 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
02000                                            const SMDS_MeshNode *node2,
02001                                            const SMDS_MeshNode *node3,
02002                                            const SMDS_MeshNode *node4)
02003 {
02004   SMDS_MeshFace * toReturn=NULL;
02005   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
02006   if(toReturn==NULL) {
02007     int ID = myElementIDFactory->GetFreeID();
02008     toReturn=createQuadrangle(node1,node2,node3,node4,ID);
02009   }
02010   return toReturn;
02011 }
02012 
02013 
02014 //=======================================================================
02015 //function : FindFace
02016 //purpose  :quadratic triangle
02017 //=======================================================================
02018 
02019 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02020                                          int idnode3, int idnode4,
02021                                          int idnode5, int idnode6) const
02022 {
02023   const SMDS_MeshNode * node1 = FindNode(idnode1);
02024   const SMDS_MeshNode * node2 = FindNode(idnode2);
02025   const SMDS_MeshNode * node3 = FindNode(idnode3);
02026   const SMDS_MeshNode * node4 = FindNode(idnode4);
02027   const SMDS_MeshNode * node5 = FindNode(idnode5);
02028   const SMDS_MeshNode * node6 = FindNode(idnode6);
02029   return FindFace(node1, node2, node3, node4, node5, node6);
02030 }
02031 
02032 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02033                                          const SMDS_MeshNode *node2,
02034                                          const SMDS_MeshNode *node3,
02035                                          const SMDS_MeshNode *node4,
02036                                          const SMDS_MeshNode *node5,
02037                                          const SMDS_MeshNode *node6)
02038 {
02039   if ( !node1 ) return 0;
02040   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02041   while(it1->more()) {
02042     const SMDS_MeshElement * e = it1->next();
02043     if ( e->NbNodes() == 6 ) {
02044       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02045       while(it2->more()) {
02046         const SMDS_MeshElement* n = it2->next();
02047         if( n!=node1 &&
02048             n!=node2 &&
02049             n!=node3 &&
02050             n!=node4 &&
02051             n!=node5 &&
02052             n!=node6 )
02053         {
02054           e = 0;
02055           break;
02056         }
02057       }
02058       if ( e )
02059         return static_cast<const SMDS_MeshFace *> (e);
02060     }
02061   }
02062   return 0;
02063 }
02064 
02065 
02066 //=======================================================================
02067 //function : FindFace
02068 //purpose  : quadratic quadrangle
02069 //=======================================================================
02070 
02071 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
02072                                          int idnode3, int idnode4,
02073                                          int idnode5, int idnode6,
02074                                          int idnode7, int idnode8) const
02075 {
02076   const SMDS_MeshNode * node1 = FindNode(idnode1);
02077   const SMDS_MeshNode * node2 = FindNode(idnode2);
02078   const SMDS_MeshNode * node3 = FindNode(idnode3);
02079   const SMDS_MeshNode * node4 = FindNode(idnode4);
02080   const SMDS_MeshNode * node5 = FindNode(idnode5);
02081   const SMDS_MeshNode * node6 = FindNode(idnode6);
02082   const SMDS_MeshNode * node7 = FindNode(idnode7);
02083   const SMDS_MeshNode * node8 = FindNode(idnode8);
02084   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
02085 }
02086 
02087 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
02088                                          const SMDS_MeshNode *node2,
02089                                          const SMDS_MeshNode *node3,
02090                                          const SMDS_MeshNode *node4,
02091                                          const SMDS_MeshNode *node5,
02092                                          const SMDS_MeshNode *node6,
02093                                          const SMDS_MeshNode *node7,
02094                                          const SMDS_MeshNode *node8)
02095 {
02096   if ( !node1 ) return 0;
02097   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
02098   while(it1->more()) {
02099     const SMDS_MeshElement * e = it1->next();
02100     if ( e->NbNodes() == 8 ) {
02101       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
02102       while(it2->more()) {
02103         const SMDS_MeshElement* n = it2->next();
02104         if( n!=node1 &&
02105             n!=node2 &&
02106             n!=node3 &&
02107             n!=node4 &&
02108             n!=node5 &&
02109             n!=node6 &&
02110             n!=node7 &&
02111             n!=node8 )
02112         {
02113           e = 0;
02114           break;
02115         }
02116       }
02117       if ( e )
02118         return static_cast<const SMDS_MeshFace *> (e);
02119     }
02120   }
02121   return 0;
02122 }
02123 
02124 
02125 //=======================================================================
02126 //function : FindElement
02127 //purpose  :
02128 //=======================================================================
02129 
02130 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
02131 {
02132   if ((IDelem <= 0) || IDelem >= myCells.size())
02133   {
02134     MESSAGE("--------------------------------------------------------------------------------- ");
02135     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
02136     MESSAGE("--------------------------------------------------------------------------------- ");
02137     // TODO raise an exception
02138     //assert(0);
02139     return 0;
02140   }
02141   return myCells[IDelem];
02142 }
02143 
02144 //=======================================================================
02145 //function : FindFace
02146 //purpose  : find polygon
02147 //=======================================================================
02148 
02149 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
02150 {
02151   int nbnodes = nodes_ids.size();
02152   vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
02153   for (int inode = 0; inode < nbnodes; inode++) {
02154     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
02155     if (node == NULL) return NULL;
02156     poly_nodes[inode] = node;
02157   }
02158   return FindFace(poly_nodes);
02159 }
02160 
02161 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
02162 {
02163   return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
02164 }
02165 
02166 
02167 //================================================================================
02175 //================================================================================
02176 
02177 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
02178                                                 const SMDSAbs_ElementType            type,
02179                                                 const bool                           noMedium)
02180 {
02181   if ( nodes.size() > 0 && nodes[0] )
02182   {
02183     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
02184     while (itF->more())
02185     {
02186       const SMDS_MeshElement* e = itF->next();
02187       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
02188       if ( nbNodesToCheck == nodes.size() )
02189       {
02190         for ( int i = 1; e && i < nodes.size(); ++ i )
02191         {
02192           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
02193           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
02194             e = 0;
02195         }
02196         if ( e )
02197           return static_cast<const SMDS_MeshFace *> (e);
02198       }
02199     }
02200   }
02201   return NULL;
02202 }
02203 
02204 //=======================================================================
02205 //function : DumpNodes
02206 //purpose  :
02207 //=======================================================================
02208 
02209 void SMDS_Mesh::DumpNodes() const
02210 {
02211         MESSAGE("dump nodes of mesh : ");
02212         SMDS_NodeIteratorPtr itnode=nodesIterator();
02213         while(itnode->more()) ; //MESSAGE(itnode->next());
02214 }
02215 
02216 //=======================================================================
02217 //function : Dump0DElements
02218 //purpose  :
02219 //=======================================================================
02220 void SMDS_Mesh::Dump0DElements() const
02221 {
02222   MESSAGE("dump 0D elements of mesh : ");
02223   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
02224   while(it0d->more()) ; //MESSAGE(it0d->next());
02225 }
02226 
02227 //=======================================================================
02228 //function : DumpEdges
02229 //purpose  :
02230 //=======================================================================
02231 
02232 void SMDS_Mesh::DumpEdges() const
02233 {
02234         MESSAGE("dump edges of mesh : ");
02235         SMDS_EdgeIteratorPtr itedge=edgesIterator();
02236         while(itedge->more()) ; //MESSAGE(itedge->next());
02237 }
02238 
02239 //=======================================================================
02240 //function : DumpFaces
02241 //purpose  :
02242 //=======================================================================
02243 
02244 void SMDS_Mesh::DumpFaces() const
02245 {
02246         MESSAGE("dump faces of mesh : ");
02247         SMDS_FaceIteratorPtr itface=facesIterator();
02248         while(itface->more()) ; //MESSAGE(itface->next());
02249 }
02250 
02251 //=======================================================================
02252 //function : DumpVolumes
02253 //purpose  :
02254 //=======================================================================
02255 
02256 void SMDS_Mesh::DumpVolumes() const
02257 {
02258         MESSAGE("dump volumes of mesh : ");
02259         SMDS_VolumeIteratorPtr itvol=volumesIterator();
02260         while(itvol->more()) ; //MESSAGE(itvol->next());
02261 }
02262 
02263 //=======================================================================
02264 //function : DebugStats
02265 //purpose  :
02266 //=======================================================================
02267 
02268 void SMDS_Mesh::DebugStats() const
02269 {
02270   MESSAGE("Debug stats of mesh : ");
02271 
02272   MESSAGE("===== NODES ====="<<NbNodes());
02273   MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
02274   MESSAGE("===== EDGES ====="<<NbEdges());
02275   MESSAGE("===== FACES ====="<<NbFaces());
02276   MESSAGE("===== VOLUMES ====="<<NbVolumes());
02277 
02278   MESSAGE("End Debug stats of mesh ");
02279 
02280   //#ifdef DEB
02281 
02282   SMDS_NodeIteratorPtr itnode=nodesIterator();
02283   int sizeofnodes = 0;
02284   int sizeoffaces = 0;
02285 
02286   while(itnode->more())
02287   {
02288     const SMDS_MeshNode *node = itnode->next();
02289 
02290     sizeofnodes += sizeof(*node);
02291 
02292     SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
02293     while(it->more())
02294     {
02295       const SMDS_MeshElement *me = it->next();
02296       sizeofnodes += sizeof(me);
02297     }
02298   }
02299 
02300   SMDS_FaceIteratorPtr itface=facesIterator();
02301   while(itface->more())
02302   {
02303     const SMDS_MeshElement *face = itface->next();
02304     sizeoffaces += sizeof(*face);
02305   }
02306 
02307   MESSAGE("total size of node elements = " << sizeofnodes);;
02308   MESSAGE("total size of face elements = " << sizeoffaces);;
02309 
02310   //#endif
02311 }
02312 
02316 int SMDS_Mesh::NbNodes() const
02317 {
02318         //MESSAGE(myGrid->GetNumberOfPoints());
02319         //MESSAGE(myInfo.NbNodes());
02320         //MESSAGE(myNodeMax);
02321     return myInfo.NbNodes();
02322 }
02323 
02327 int SMDS_Mesh::Nb0DElements() const
02328 {
02329   return myInfo.Nb0DElements(); // -PR- a verfier
02330 }
02331 
02335 int SMDS_Mesh::NbEdges() const
02336 {
02337         return myInfo.NbEdges(); // -PR- a verfier
02338 }
02339 
02343 int SMDS_Mesh::NbFaces() const
02344 {
02345         return myInfo.NbFaces();  // -PR- a verfier
02346 }
02347 
02351 int SMDS_Mesh::NbVolumes() const
02352 {
02353         return myInfo.NbVolumes(); // -PR- a verfier
02354 }
02355 
02361 int SMDS_Mesh::NbSubMesh() const
02362 {
02363         return myChildren.size();
02364 }
02365 
02370 SMDS_Mesh::~SMDS_Mesh()
02371 {
02372   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
02373   while(itc!=myChildren.end())
02374   {
02375     delete *itc;
02376     itc++;
02377   }
02378 
02379   if(myParent==NULL)
02380   {
02381     delete myNodeIDFactory;
02382     delete myElementIDFactory;
02383   }
02384   else
02385   {
02386     SMDS_ElemIteratorPtr eIt = elementsIterator();
02387     while ( eIt->more() )
02388       {
02389         const SMDS_MeshElement *elem = eIt->next();
02390         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
02391       }
02392     SMDS_NodeIteratorPtr itn = nodesIterator();
02393     while (itn->more())
02394       {
02395         const SMDS_MeshNode *node = itn->next();
02396         ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
02397         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
02398       }
02399   }
02400 
02401 //   SetOfNodes::Iterator itn(myNodes);
02402 //   for (; itn.More(); itn.Next())
02403 //     delete itn.Value();
02404 
02405 //   SetOf0DElements::Iterator it0d (my0DElements);
02406 //   for (; it0d.More(); it0d.Next())
02407 //   {
02408 //     SMDS_MeshElement* elem = it0d.Value();
02409 //     delete elem;
02410 //   }
02411 
02412 //   SetOfEdges::Iterator ite(myEdges);
02413 //   for (; ite.More(); ite.Next())
02414 //   {
02415 //     SMDS_MeshElement* elem = ite.Value();
02416 //     delete elem;
02417 //   }
02418 
02419 //   SetOfFaces::Iterator itf(myFaces);
02420 //   for (; itf.More(); itf.Next())
02421 //   {
02422 //     SMDS_MeshElement* elem = itf.Value();
02423 //     delete elem;
02424 //   }
02425 
02426 //   SetOfVolumes::Iterator itv(myVolumes);
02427 //   for (; itv.More(); itv.Next())
02428 //   {
02429 //     SMDS_MeshElement* elem = itv.Value();
02430 //     delete elem;
02431 //   }
02432 }
02433 
02434 //================================================================================
02438 //================================================================================
02439 
02440 void SMDS_Mesh::Clear()
02441 {
02442   MESSAGE("SMDS_Mesh::Clear");
02443   if (myParent!=NULL)
02444     {
02445     SMDS_ElemIteratorPtr eIt = elementsIterator();
02446     while ( eIt->more() )
02447       {
02448         const SMDS_MeshElement *elem = eIt->next();
02449         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
02450       }
02451     SMDS_NodeIteratorPtr itn = nodesIterator();
02452     while (itn->more())
02453       {
02454         const SMDS_MeshNode *node = itn->next();
02455         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
02456       }
02457     }
02458   else
02459     {
02460     myNodeIDFactory->Clear();
02461     myElementIDFactory->Clear();
02462     }
02463 
02464   SMDS_ElemIteratorPtr itv = elementsIterator();
02465   while (itv->more())
02466     {
02467       SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
02468       SMDSAbs_ElementType aType = elem->GetType();
02469       switch (aType)
02470       {
02471         case SMDSAbs_0DElement:
02472           delete elem;
02473           break;
02474         case SMDSAbs_Edge:
02475            myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
02476           break;
02477         case SMDSAbs_Face:
02478           myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
02479           break;
02480         case SMDSAbs_Volume:
02481           myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
02482           break;
02483         default:
02484           break;
02485       }
02486     }
02487   myCells.clear();
02488   myCellIdVtkToSmds.clear();
02489   //myCellIdSmdsToVtk.clear();
02490 
02491   SMDS_NodeIteratorPtr itn = nodesIterator();
02492   while (itn->more())
02493     {
02494       SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
02495       node->SetPosition(SMDS_SpacePosition::originSpacePosition());
02496       myNodePool->destroy(node);
02497     }
02498   myNodes.clear();
02499 
02500   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
02501   while(itc!=myChildren.end())
02502     (*itc)->Clear();
02503 
02504   myModified = false;
02505   xmin = 0; xmax = 0;
02506   ymin = 0; ymax = 0;
02507   zmin = 0; zmax = 0;
02508 
02509   myInfo.Clear();
02510 
02511   myGrid->Initialize();
02512   myGrid->Allocate();
02513   vtkPoints* points = vtkPoints::New();
02514   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
02515   // using double type for storing coordinates of nodes instead float.
02516   points->SetDataType(VTK_DOUBLE);
02517   points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
02518   myGrid->SetPoints( points );
02519   points->Delete();
02520   myGrid->BuildLinks();
02521 }
02522 
02528 bool SMDS_Mesh::hasConstructionEdges()
02529 {
02530         return myHasConstructionEdges;
02531 }
02532 
02540 bool SMDS_Mesh::hasConstructionFaces()
02541 {
02542         return myHasConstructionFaces;
02543 }
02544 
02549 bool SMDS_Mesh::hasInverseElements()
02550 {
02551         return myHasInverseElements;
02552 }
02553 
02558 void SMDS_Mesh::setConstructionEdges(bool b)
02559 {
02560         myHasConstructionEdges=b;
02561 }
02562 
02567 void SMDS_Mesh::setConstructionFaces(bool b)
02568 {
02569          myHasConstructionFaces=b;
02570 }
02571 
02576 void SMDS_Mesh::setInverseElements(bool b)
02577 {
02578   if(!b) MESSAGE("Error : inverseElement=false not implemented");
02579   myHasInverseElements=b;
02580 }
02581 
02582 namespace {
02583 
02587 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
02588 struct MYNode_Map_Iterator: public FATHER
02589 {
02590   int _ctr;
02591   const MAP& _map;
02592   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
02593   {
02594       _ctr = 0;
02595   }
02596 
02597   bool more()
02598   {
02599       while (_ctr < _map.size())
02600       {
02601           if (_map[_ctr])
02602               return true;
02603           _ctr++;
02604       }
02605           return false;
02606   }
02607 
02608   ELEM next()
02609   {
02610     ELEM current = _map[_ctr];
02611     _ctr++;
02612     return current;
02613   }
02614 };
02615 
02616 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
02617 struct MYElem_Map_Iterator: public FATHER
02618 {
02619   int _ctr;
02620   int _type;
02621   const MAP& _map;
02622   MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
02623   {
02624       _ctr = 0;
02625       _type = typ;
02626       while (_ctr < _map.size()) // go to the first valid element
02627       {
02628           if (_map[_ctr])
02629             if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
02630               break;
02631           _ctr++;
02632       }
02633   }
02634 
02635 bool more()
02636   {
02637       while (_ctr < _map.size())
02638       {
02639           if (_map[_ctr])
02640             if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
02641               return true;
02642           _ctr++;
02643       }
02644           return false;
02645   }
02646 
02647   ELEM next()
02648   {
02649     ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
02650     _ctr++;
02651     return current;
02652   }
02653 };
02654 
02655 //================================================================================
02659   //================================================================================
02660 
02661   template <typename ELEM=const SMDS_MeshElement*>
02662   class IdSortedIterator : public SMDS_Iterator<ELEM>
02663   {
02664     const SMDS_MeshElementIDFactory& myIDFact;
02665     int                              myID, myMaxID, myNbFound, myTotalNb;
02666     SMDSAbs_ElementType              myType;
02667     ELEM                             myElem;
02668 
02669   public:
02670     IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
02671                      const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
02672                      const int                        totalNb)
02673       :myIDFact( fact ),
02674        myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
02675        myType( type ),
02676        myElem(0)
02677     {
02678       next();
02679     }
02680     bool more()
02681     {
02682       return myElem;
02683     }
02684     ELEM next()
02685     {
02686       ELEM current = myElem;
02687 
02688       for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
02689         if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
02690             && myElem->GetType() != myType )
02691           myElem = 0;
02692 
02693       myNbFound += bool(myElem);
02694 
02695       return current;
02696     }
02697   };
02698 }
02699 
02703 
02704 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
02705 {
02706   typedef MYNode_Map_Iterator
02707     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
02708   return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
02709 
02710 //  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
02711 //  return ( idInceasingOrder ?
02712 //           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
02713 //           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
02714 }
02715 
02719 
02720 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
02721 {
02722   typedef MYElem_Map_Iterator
02723     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
02724   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
02725 
02726 //  typedef MYNCollection_Map_Iterator
02727 //    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
02728 //  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
02729 //  return ( idInceasingOrder ?
02730 //           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
02731 //                                                           SMDSAbs_0DElement,
02732 //                                                           Nb0DElements() )) :
02733 //           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
02734 }
02735 
02739 
02740 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
02741 {
02742   typedef MYElem_Map_Iterator
02743     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
02744   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
02745 
02746 //  typedef MYNCollection_Map_Iterator
02747 //    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
02748 //  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
02749 //  return ( idInceasingOrder ?
02750 //           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
02751 //                                                      SMDSAbs_Edge,
02752 //                                                      NbEdges() )) :
02753 //           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
02754 }
02755 
02759 
02760 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
02761 {
02762   typedef MYElem_Map_Iterator
02763     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
02764   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
02765 
02766 //  typedef MYNCollection_Map_Iterator
02767 //    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
02768 //  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
02769 //  return ( idInceasingOrder ?
02770 //           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
02771 //                                                      SMDSAbs_Face,
02772 //                                                      NbFaces() )) :
02773 //           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
02774 }
02775 
02779 
02780 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
02781 {
02782   typedef MYElem_Map_Iterator
02783     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
02784   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
02785 
02786   //  typedef MYNCollection_Map_Iterator
02787 //    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
02788 //  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
02789 //  return ( idInceasingOrder ?
02790 //           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
02791 //                                                        SMDSAbs_Volume,
02792 //                                                        NbVolumes() )) :
02793 //           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
02794 }
02795 
02799 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
02800 {
02801   switch (type) {
02802   case SMDSAbs_All:
02803     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
02804     break;
02805   case SMDSAbs_Volume:
02806     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
02807   case SMDSAbs_Face:
02808     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
02809   case SMDSAbs_Edge:
02810     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
02811   case SMDSAbs_0DElement:
02812     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
02813   case SMDSAbs_Node:
02814     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
02815     //return myNodeIDFactory->elementsIterator();
02816   default:;
02817   }
02818   return myElementIDFactory->elementsIterator();
02819 }
02820 
02824 static set<const SMDS_MeshElement*> * intersectionOfSets(
02825         set<const SMDS_MeshElement*> vs[], int numberOfSets)
02826 {
02827         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
02828         set<const SMDS_MeshElement*>* rsetB;
02829 
02830         for(int i=0; i<numberOfSets-1; i++)
02831         {
02832                 rsetB=new set<const SMDS_MeshElement*>();
02833                 set_intersection(
02834                         rsetA->begin(), rsetA->end(),
02835                         vs[i+1].begin(), vs[i+1].end(),
02836                         inserter(*rsetB, rsetB->begin()));
02837                 delete rsetA;
02838                 rsetA=rsetB;
02839         }
02840         return rsetA;
02841 }
02842 
02848 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
02849 {
02850         int numberOfSets=element->NbNodes();
02851         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
02852 
02853         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
02854 
02855         int i=0;
02856         while(itNodes->more())
02857         {
02858           const SMDS_MeshElement* node = itNodes->next();
02859           MYASSERT(node);
02860                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
02861                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
02862 
02863                 //initSet[i]=set<const SMDS_MeshElement*>();
02864                 while(itFe->more())
02865                 {
02866                   const SMDS_MeshElement* elem = itFe->next();
02867                   MYASSERT(elem);
02868                   initSet[i].insert(elem);
02869 
02870                 }
02871 
02872                 i++;
02873         }
02874         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
02875         MESSAGE("nb elems " << i << " intersection " << retSet->size());
02876         delete [] initSet;
02877         return retSet;
02878 }
02879 
02883 static set<const SMDS_MeshElement*> * getExclusiveNodes(
02884         set<const SMDS_MeshElement*>& elements)
02885 {
02886         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
02887         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
02888 
02889         while(itElements!=elements.end())
02890         {
02891                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
02892                 itElements++;
02893 
02894                 while(itNodes->more())
02895                 {
02896                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
02897                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
02898                         set<const SMDS_MeshElement*> s;
02899                         while(itFe->more())
02900                           s.insert(itFe->next());
02901                         if(s==elements) toReturn->insert(n);
02902                 }
02903         }
02904         return toReturn;
02905 }
02906 
02913 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
02914                                      const SMDS_MeshElement *      element,
02915                                      set<const SMDS_MeshElement*>& nodes)
02916 {
02917   switch(element->GetType())
02918     {
02919     case SMDSAbs_Node:
02920       MESSAGE("Internal Error: This should not happen");
02921       break;
02922     case SMDSAbs_0DElement:
02923       {
02924       }
02925       break;
02926     case SMDSAbs_Edge:
02927         {
02928                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
02929                 while(itn->more())
02930                 {
02931                         const SMDS_MeshElement * e=itn->next();
02932                         if(nodes.find(e)!=nodes.end())
02933                         {
02934                           setOfChildren.insert(element);
02935                           break;
02936                         }
02937                 }
02938         } break;
02939     case SMDSAbs_Face:
02940         {
02941                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
02942                 while(itn->more())
02943                 {
02944                         const SMDS_MeshElement * e=itn->next();
02945                         if(nodes.find(e)!=nodes.end())
02946                         {
02947                           setOfChildren.insert(element);
02948                           break;
02949                         }
02950                 }
02951                 if(hasConstructionEdges())
02952                 {
02953                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
02954                         while(ite->more())
02955                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
02956                 }
02957         } break;
02958     case SMDSAbs_Volume:
02959         {
02960                 if(hasConstructionFaces())
02961                 {
02962                         SMDS_ElemIteratorPtr ite=element->facesIterator();
02963                         while(ite->more())
02964                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
02965                 }
02966                 else if(hasConstructionEdges())
02967                 {
02968                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
02969                         while(ite->more())
02970                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
02971                 }
02972         }
02973     }
02974 }
02975 
02980 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
02981                               const bool removenodes)
02982 {
02983   list<const SMDS_MeshElement *> removedElems;
02984   list<const SMDS_MeshElement *> removedNodes;
02985   RemoveElement( elem, removedElems, removedNodes, removenodes );
02986 }
02987 
02994 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
02995                               list<const SMDS_MeshElement *>& removedElems,
02996                               list<const SMDS_MeshElement *>& removedNodes,
02997                               bool                            removenodes)
02998 {
02999   //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
03000   // get finite elements built on elem
03001   set<const SMDS_MeshElement*> * s1;
03002   if (    (elem->GetType() == SMDSAbs_0DElement)
03003       || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
03004       || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
03005       ||  (elem->GetType() == SMDSAbs_Volume) )
03006     {
03007       s1 = new set<const SMDS_MeshElement*> ();
03008       s1->insert(elem);
03009     }
03010   else
03011     s1 = getFinitElements(elem);
03012 
03013   // get exclusive nodes (which would become free afterwards)
03014   set<const SMDS_MeshElement*> * s2;
03015   if (elem->GetType() == SMDSAbs_Node) // a node is removed
03016     {
03017       // do not remove nodes except elem
03018       s2 = new set<const SMDS_MeshElement*> ();
03019       s2->insert(elem);
03020       removenodes = true;
03021     }
03022   else
03023     s2 = getExclusiveNodes(*s1);
03024 
03025   // form the set of finite and construction elements to remove
03026   set<const SMDS_MeshElement*> s3;
03027   set<const SMDS_MeshElement*>::iterator it = s1->begin();
03028   while (it != s1->end())
03029     {
03030       addChildrenWithNodes(s3, *it, *s2);
03031       s3.insert(*it);
03032       it++;
03033     }
03034   if (elem->GetType() != SMDSAbs_Node)
03035     s3.insert(elem);
03036 
03037   // remove finite and construction elements
03038   it = s3.begin();
03039   while (it != s3.end())
03040     {
03041       // Remove element from <InverseElements> of its nodes
03042       SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
03043       while (itn->more())
03044         {
03045           SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
03046           n->RemoveInverseElement((*it));
03047         }
03048       int IdToRemove = (*it)->GetID();
03049       int vtkid = (*it)->getVtkId();
03050       //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
03051       //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
03052       switch ((*it)->GetType())
03053       {
03054         case SMDSAbs_Node:
03055           MYASSERT("Internal Error: This should not happen")
03056           ;
03057           break;
03058         case SMDSAbs_0DElement:
03059           if (IdToRemove >= 0)
03060             {
03061               myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
03062               myInfo.remove(*it);
03063             }
03064           removedElems.push_back((*it));
03065           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03066           delete (*it);
03067           break;
03068         case SMDSAbs_Edge:
03069           if (IdToRemove >= 0)
03070             {
03071               myCells[IdToRemove] = 0;
03072               myInfo.RemoveEdge(*it);
03073             }
03074           removedElems.push_back((*it));
03075           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03076           if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
03077             myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
03078           else
03079             delete (*it);
03080           break;
03081         case SMDSAbs_Face:
03082           if (IdToRemove >= 0)
03083             {
03084               myCells[IdToRemove] = 0;
03085               myInfo.RemoveFace(*it);
03086             }
03087           removedElems.push_back((*it));
03088           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03089           if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
03090             myFacePool->destroy((SMDS_VtkFace*) vtkElem);
03091           else
03092             delete (*it);
03093           break;
03094         case SMDSAbs_Volume:
03095           if (IdToRemove >= 0)
03096             {
03097               myCells[IdToRemove] = 0;
03098               myInfo.RemoveVolume(*it);
03099             }
03100           removedElems.push_back((*it));
03101           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
03102           if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
03103             myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
03104           else
03105             delete (*it);
03106           break;
03107       }
03108       if (vtkid >= 0)
03109         {
03110           //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
03111           this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
03112         }
03113       it++;
03114     }
03115 
03116   // remove exclusive (free) nodes
03117   if (removenodes)
03118     {
03119       it = s2->begin();
03120       while (it != s2->end())
03121         {
03122           int IdToRemove = (*it)->GetID();
03123           //MESSAGE( "SMDS: RM node " << IdToRemove);
03124           if (IdToRemove >= 0)
03125             {
03126               myNodes[IdToRemove] = 0;
03127               myInfo.myNbNodes--;
03128             }
03129           myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
03130           removedNodes.push_back((*it));
03131           if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
03132           {
03133             ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
03134             myNodePool->destroy((SMDS_MeshNode*) vtkElem);
03135           }
03136           else
03137             delete (*it);
03138           it++;
03139         }
03140     }
03141 
03142   delete s2;
03143   delete s1;
03144 }
03145 
03146 
03150 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
03151 {
03152   int elemId = elem->GetID();
03153   int vtkId = elem->getVtkId();
03154   //MESSAGE("RemoveFreeElement " << elemId);
03155   SMDSAbs_ElementType aType = elem->GetType();
03156   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
03157   if (aType == SMDSAbs_Node) {
03158     //MESSAGE("Remove free node " << elemId);
03159     // only free node can be removed by this method
03160     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
03161     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
03162     if (!itFe->more()) { // free node
03163       myNodes[elemId] = 0;
03164       myInfo.myNbNodes--;
03165       ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
03166       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
03167       myNodeIDFactory->ReleaseID(elemId, vtkId);
03168     }
03169   } else {
03170     if (hasConstructionEdges() || hasConstructionFaces())
03171       // this methods is only for meshes without descendants
03172       return;
03173 
03174     //MESSAGE("Remove free element " << elemId);
03175     // Remove element from <InverseElements> of its nodes
03176     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
03177     while (itn->more()) {
03178       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
03179         (const_cast<SMDS_MeshElement *>(itn->next()));
03180       n->RemoveInverseElement(elem);
03181     }
03182 
03183     // in meshes without descendants elements are always free
03184      switch (aType) {
03185     case SMDSAbs_0DElement:
03186       myCells[elemId] = 0;
03187       myInfo.remove(elem);
03188       delete elem;
03189       break;
03190     case SMDSAbs_Edge:
03191       myCells[elemId] = 0;
03192       myInfo.RemoveEdge(elem);
03193       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
03194       break;
03195     case SMDSAbs_Face:
03196       myCells[elemId] = 0;
03197       myInfo.RemoveFace(elem);
03198       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
03199       break;
03200     case SMDSAbs_Volume:
03201       myCells[elemId] = 0;
03202       myInfo.RemoveVolume(elem);
03203       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
03204       break;
03205     default:
03206       break;
03207     }
03208     myElementIDFactory->ReleaseID(elemId, vtkId);
03209 
03210     this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
03211     // --- to do: keep vtkid in a list of reusable cells
03212   }
03213 }
03214 
03219 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
03220 {
03221   // we should not imply on validity of *elem, so iterate on containers
03222   // of all types in the hope of finding <elem> somewhere there
03223   SMDS_NodeIteratorPtr itn = nodesIterator();
03224   while (itn->more())
03225     if (elem == itn->next())
03226       return true;
03227   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
03228   while (it0d->more())
03229     if (elem == it0d->next())
03230       return true;
03231   SMDS_EdgeIteratorPtr ite = edgesIterator();
03232   while (ite->more())
03233     if (elem == ite->next())
03234       return true;
03235   SMDS_FaceIteratorPtr itf = facesIterator();
03236   while (itf->more())
03237     if (elem == itf->next())
03238       return true;
03239   SMDS_VolumeIteratorPtr itv = volumesIterator();
03240   while (itv->more())
03241     if (elem == itv->next())
03242       return true;
03243   return false;
03244 }
03245 
03246 //=======================================================================
03247 //function : MaxNodeID
03248 //purpose  :
03249 //=======================================================================
03250 
03251 int SMDS_Mesh::MaxNodeID() const
03252 {
03253   return myNodeMax;
03254 }
03255 
03256 //=======================================================================
03257 //function : MinNodeID
03258 //purpose  :
03259 //=======================================================================
03260 
03261 int SMDS_Mesh::MinNodeID() const
03262 {
03263   return myNodeMin;
03264 }
03265 
03266 //=======================================================================
03267 //function : MaxElementID
03268 //purpose  :
03269 //=======================================================================
03270 
03271 int SMDS_Mesh::MaxElementID() const
03272 {
03273   return myElementIDFactory->GetMaxID();
03274 }
03275 
03276 //=======================================================================
03277 //function : MinElementID
03278 //purpose  :
03279 //=======================================================================
03280 
03281 int SMDS_Mesh::MinElementID() const
03282 {
03283   return myElementIDFactory->GetMinID();
03284 }
03285 
03286 //=======================================================================
03287 //function : Renumber
03288 //purpose  : Renumber all nodes or elements.
03289 //=======================================================================
03290 
03291 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
03292 {
03293     MESSAGE("Renumber");
03294   if ( deltaID == 0 )
03295     return;
03296 
03297   SMDS_MeshNodeIDFactory * idFactory =
03298     isNodes ? myNodeIDFactory : myElementIDFactory;
03299 
03300   // get existing elements in the order of ID increasing
03301   map<int,SMDS_MeshElement*> elemMap;
03302   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
03303   while ( idElemIt->more() ) {
03304     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
03305     int id = elem->GetID();
03306     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
03307   }
03308   // release their ids
03309   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
03310   idFactory->Clear();
03311 //   for ( ; elemIt != elemMap.end(); elemIt++ )
03312 //   {
03313 //     int id = (*elemIt).first;
03314 //     idFactory->ReleaseID( id );
03315 //   }
03316   // set new IDs
03317   int ID = startID;
03318   elemIt = elemMap.begin();
03319   for ( ; elemIt != elemMap.end(); elemIt++ )
03320   {
03321     idFactory->BindID( ID, (*elemIt).second );
03322     ID += deltaID;
03323   }
03324 }
03325 
03326 //=======================================================================
03327 //function : GetElementType
03328 //purpose  : Return type of element or node with id
03329 //=======================================================================
03330 
03331 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
03332 {
03333   SMDS_MeshElement* elem = 0;
03334   if( iselem )
03335     elem = myElementIDFactory->MeshElement( id );
03336   else
03337     elem = myNodeIDFactory->MeshElement( id );
03338 
03339   if( !elem )
03340   {
03341     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
03342     return SMDSAbs_All;
03343   }
03344   else
03345     return elem->GetType();
03346 }
03347 
03348 
03349 
03350 //********************************************************************
03351 //********************************************************************
03352 //********                                                   *********
03353 //*****       Methods for addition of quadratic elements        ******
03354 //********                                                   *********
03355 //********************************************************************
03356 //********************************************************************
03357 
03358 //=======================================================================
03359 //function : AddEdgeWithID
03360 //purpose  :
03361 //=======================================================================
03362 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
03363 {
03364   return SMDS_Mesh::AddEdgeWithID
03365     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
03366      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
03367      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03368      ID);
03369 }
03370 
03371 //=======================================================================
03372 //function : AddEdge
03373 //purpose  :
03374 //=======================================================================
03375 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
03376                                   const SMDS_MeshNode* n2,
03377                                   const SMDS_MeshNode* n12)
03378 {
03379   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
03380 }
03381 
03382 //=======================================================================
03383 //function : AddEdgeWithID
03384 //purpose  :
03385 //=======================================================================
03386 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
03387                                         const SMDS_MeshNode * n2,
03388                                         const SMDS_MeshNode * n12,
03389                                         int ID)
03390 {
03391   if ( !n1 || !n2 || !n12 ) return 0;
03392 
03393   // --- retrieve nodes ID
03394   vector<vtkIdType> nodeIds;
03395   nodeIds.clear();
03396   nodeIds.push_back(n1->getVtkId());
03397   nodeIds.push_back(n2->getVtkId());
03398   nodeIds.push_back(n12->getVtkId());
03399 
03400   SMDS_MeshEdge * edge = 0;
03401   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
03402   edgevtk->init(nodeIds, this);
03403   if (!this->registerElement(ID,edgevtk))
03404     {
03405       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
03406       myEdgePool->destroy(edgevtk);
03407       return 0;
03408     }
03409   edge = edgevtk;
03410   adjustmyCellsCapacity(ID);
03411   myCells[ID] = edge;
03412   myInfo.myNbQuadEdges++;
03413 
03414 //  if (!registerElement(ID, edge)) {
03415 //        RemoveElement(edge, false);
03416 //        edge = NULL;
03417 //  }
03418   return edge;
03419 
03420 }
03421 
03422 
03423 //=======================================================================
03424 //function : AddFace
03425 //purpose  :
03426 //=======================================================================
03427 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
03428                                   const SMDS_MeshNode * n2,
03429                                   const SMDS_MeshNode * n3,
03430                                   const SMDS_MeshNode * n12,
03431                                   const SMDS_MeshNode * n23,
03432                                   const SMDS_MeshNode * n31)
03433 {
03434   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
03435                                   myElementIDFactory->GetFreeID());
03436 }
03437 
03438 //=======================================================================
03439 //function : AddFaceWithID
03440 //purpose  :
03441 //=======================================================================
03442 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
03443                                         int n12,int n23,int n31, int ID)
03444 {
03445   return SMDS_Mesh::AddFaceWithID
03446     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
03447      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
03448      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
03449      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
03450      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
03451      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
03452      ID);
03453 }
03454 
03455 //=======================================================================
03456 //function : AddFaceWithID
03457 //purpose  :
03458 //=======================================================================
03459 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
03460                                         const SMDS_MeshNode * n2,
03461                                         const SMDS_MeshNode * n3,
03462                                         const SMDS_MeshNode * n12,
03463                                         const SMDS_MeshNode * n23,
03464                                         const SMDS_MeshNode * n31,
03465                                         int ID)
03466 {
03467   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
03468   if(hasConstructionEdges()) {
03469     // creation quadratic edges - not implemented
03470     return 0;
03471   }
03472   else
03473   {
03474     // --- retrieve nodes ID
03475     vector<vtkIdType> nodeIds;
03476     nodeIds.clear();
03477     nodeIds.push_back(n1->getVtkId());
03478     nodeIds.push_back(n2->getVtkId());
03479     nodeIds.push_back(n3->getVtkId());
03480     nodeIds.push_back(n12->getVtkId());
03481     nodeIds.push_back(n23->getVtkId());
03482     nodeIds.push_back(n31->getVtkId());
03483 
03484     SMDS_MeshFace * face = 0;
03485     SMDS_VtkFace *facevtk = myFacePool->getNew();
03486     facevtk->init(nodeIds, this);
03487     if (!this->registerElement(ID,facevtk))
03488       {
03489         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
03490         myFacePool->destroy(facevtk);
03491         return 0;
03492       }
03493     face = facevtk;
03494     adjustmyCellsCapacity(ID);
03495     myCells[ID] = face;
03496     myInfo.myNbQuadTriangles++;
03497 
03498 //    if (!registerElement(ID, face)) {
03499 //      RemoveElement(face, false);
03500 //      face = NULL;
03501 //    }
03502     return face;
03503   }
03504 }
03505 
03506 
03507 //=======================================================================
03508 //function : AddFace
03509 //purpose  :
03510 //=======================================================================
03511 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
03512                                   const SMDS_MeshNode * n2,
03513                                   const SMDS_MeshNode * n3,
03514                                   const SMDS_MeshNode * n4,
03515                                   const SMDS_MeshNode * n12,
03516                                   const SMDS_MeshNode * n23,
03517                                   const SMDS_MeshNode * n34,
03518                                   const SMDS_MeshNode * n41)
03519 {
03520   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
03521                                   myElementIDFactory->GetFreeID());
03522 }
03523 
03524 //=======================================================================
03525 //function : AddFaceWithID
03526 //purpose  :
03527 //=======================================================================
03528 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
03529                                         int n12,int n23,int n34,int n41, int ID)
03530 {
03531   return SMDS_Mesh::AddFaceWithID
03532     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
03533      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
03534      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
03535      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
03536      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
03537      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
03538      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
03539      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
03540      ID);
03541 }
03542 
03543 //=======================================================================
03544 //function : AddFaceWithID
03545 //purpose  :
03546 //=======================================================================
03547 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
03548                                         const SMDS_MeshNode * n2,
03549                                         const SMDS_MeshNode * n3,
03550                                         const SMDS_MeshNode * n4,
03551                                         const SMDS_MeshNode * n12,
03552                                         const SMDS_MeshNode * n23,
03553                                         const SMDS_MeshNode * n34,
03554                                         const SMDS_MeshNode * n41,
03555                                         int ID)
03556 {
03557   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
03558   if(hasConstructionEdges()) {
03559     // creation quadratic edges - not implemented
03560         return 0;
03561   }
03562   else
03563   {
03564     // --- retrieve nodes ID
03565     vector<vtkIdType> nodeIds;
03566     nodeIds.clear();
03567     nodeIds.push_back(n1->getVtkId());
03568     nodeIds.push_back(n2->getVtkId());
03569     nodeIds.push_back(n3->getVtkId());
03570     nodeIds.push_back(n4->getVtkId());
03571     nodeIds.push_back(n12->getVtkId());
03572     nodeIds.push_back(n23->getVtkId());
03573     nodeIds.push_back(n34->getVtkId());
03574     nodeIds.push_back(n41->getVtkId());
03575 
03576     SMDS_MeshFace * face = 0;
03577     SMDS_VtkFace *facevtk = myFacePool->getNew();
03578     facevtk->init(nodeIds, this);
03579     if (!this->registerElement(ID,facevtk))
03580       {
03581         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
03582         myFacePool->destroy(facevtk);
03583         return 0;
03584       }
03585     face = facevtk;
03586     adjustmyCellsCapacity(ID);
03587     myCells[ID] = face;
03588     myInfo.myNbQuadQuadrangles++;
03589 
03590 //    if (!registerElement(ID, face)) {
03591 //      RemoveElement(face, false);
03592 //      face = NULL;
03593 //    }
03594     return face;
03595   }
03596 }
03597 
03598 
03599 //=======================================================================
03600 //function : AddVolume
03601 //purpose  :
03602 //=======================================================================
03603 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03604                                       const SMDS_MeshNode * n2,
03605                                       const SMDS_MeshNode * n3,
03606                                       const SMDS_MeshNode * n4,
03607                                       const SMDS_MeshNode * n12,
03608                                       const SMDS_MeshNode * n23,
03609                                       const SMDS_MeshNode * n31,
03610                                       const SMDS_MeshNode * n14,
03611                                       const SMDS_MeshNode * n24,
03612                                       const SMDS_MeshNode * n34)
03613 {
03614   int ID = myElementIDFactory->GetFreeID();
03615   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
03616                                                    n31, n14, n24, n34, ID);
03617   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03618   return v;
03619 }
03620 
03621 //=======================================================================
03622 //function : AddVolumeWithID
03623 //purpose  :
03624 //=======================================================================
03625 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
03626                                             int n12,int n23,int n31,
03627                                             int n14,int n24,int n34, int ID)
03628 {
03629   return SMDS_Mesh::AddVolumeWithID
03630     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
03631      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
03632      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
03633      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
03634      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03635      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
03636      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
03637      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
03638      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
03639      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
03640      ID);
03641 }
03642 
03643 //=======================================================================
03644 //function : AddVolumeWithID
03645 //purpose  : 2d order tetrahedron of 10 nodes
03646 //=======================================================================
03647 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
03648                                             const SMDS_MeshNode * n2,
03649                                             const SMDS_MeshNode * n3,
03650                                             const SMDS_MeshNode * n4,
03651                                             const SMDS_MeshNode * n12,
03652                                             const SMDS_MeshNode * n23,
03653                                             const SMDS_MeshNode * n31,
03654                                             const SMDS_MeshNode * n14,
03655                                             const SMDS_MeshNode * n24,
03656                                             const SMDS_MeshNode * n34,
03657                                             int ID)
03658 {
03659   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
03660     return 0;
03661   if(hasConstructionFaces()) {
03662     // creation quadratic faces - not implemented
03663     return 0;
03664   }
03665   // --- retrieve nodes ID
03666   vector<vtkIdType> nodeIds;
03667   nodeIds.clear();
03668   nodeIds.push_back(n1->getVtkId());
03669   nodeIds.push_back(n3->getVtkId());
03670   nodeIds.push_back(n2->getVtkId());
03671   nodeIds.push_back(n4->getVtkId());
03672 
03673   nodeIds.push_back(n31->getVtkId());
03674   nodeIds.push_back(n23->getVtkId());
03675   nodeIds.push_back(n12->getVtkId());
03676 
03677   nodeIds.push_back(n14->getVtkId());
03678   nodeIds.push_back(n34->getVtkId());
03679   nodeIds.push_back(n24->getVtkId());
03680 
03681   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
03682   volvtk->init(nodeIds, this);
03683   if (!this->registerElement(ID,volvtk))
03684     {
03685       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
03686       myVolumePool->destroy(volvtk);
03687       return 0;
03688     }
03689   adjustmyCellsCapacity(ID);
03690   myCells[ID] = volvtk;
03691   myInfo.myNbQuadTetras++;
03692 
03693 //  if (!registerElement(ID, volvtk)) {
03694 //    RemoveElement(volvtk, false);
03695 //    volvtk = NULL;
03696 //  }
03697   return volvtk;
03698 }
03699 
03700 
03701 //=======================================================================
03702 //function : AddVolume
03703 //purpose  :
03704 //=======================================================================
03705 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03706                                       const SMDS_MeshNode * n2,
03707                                       const SMDS_MeshNode * n3,
03708                                       const SMDS_MeshNode * n4,
03709                                       const SMDS_MeshNode * n5,
03710                                       const SMDS_MeshNode * n12,
03711                                       const SMDS_MeshNode * n23,
03712                                       const SMDS_MeshNode * n34,
03713                                       const SMDS_MeshNode * n41,
03714                                       const SMDS_MeshNode * n15,
03715                                       const SMDS_MeshNode * n25,
03716                                       const SMDS_MeshNode * n35,
03717                                       const SMDS_MeshNode * n45)
03718 {
03719   int ID = myElementIDFactory->GetFreeID();
03720   SMDS_MeshVolume * v =
03721     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
03722                                n15, n25, n35, n45, ID);
03723   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03724   return v;
03725 }
03726 
03727 //=======================================================================
03728 //function : AddVolumeWithID
03729 //purpose  :
03730 //=======================================================================
03731 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
03732                                             int n12,int n23,int n34,int n41,
03733                                             int n15,int n25,int n35,int n45, int ID)
03734 {
03735   return SMDS_Mesh::AddVolumeWithID
03736     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
03737      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
03738      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
03739      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
03740      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
03741      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03742      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
03743      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
03744      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
03745      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
03746      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
03747      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
03748      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
03749      ID);
03750 }
03751 
03752 //=======================================================================
03753 //function : AddVolumeWithID
03754 //purpose  : 2d order pyramid of 13 nodes
03755 //=======================================================================
03756 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
03757                                             const SMDS_MeshNode * n2,
03758                                             const SMDS_MeshNode * n3,
03759                                             const SMDS_MeshNode * n4,
03760                                             const SMDS_MeshNode * n5,
03761                                             const SMDS_MeshNode * n12,
03762                                             const SMDS_MeshNode * n23,
03763                                             const SMDS_MeshNode * n34,
03764                                             const SMDS_MeshNode * n41,
03765                                             const SMDS_MeshNode * n15,
03766                                             const SMDS_MeshNode * n25,
03767                                             const SMDS_MeshNode * n35,
03768                                             const SMDS_MeshNode * n45,
03769                                             int ID)
03770 {
03771   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
03772       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
03773     return 0;
03774   if(hasConstructionFaces()) {
03775     // creation quadratic faces - not implemented
03776     return 0;
03777   }
03778   // --- retrieve nodes ID
03779   vector<vtkIdType> nodeIds;
03780   nodeIds.clear();
03781   nodeIds.push_back(n1->getVtkId());
03782   nodeIds.push_back(n4->getVtkId());
03783   nodeIds.push_back(n3->getVtkId());
03784   nodeIds.push_back(n2->getVtkId());
03785   nodeIds.push_back(n5->getVtkId());
03786 
03787   nodeIds.push_back(n41->getVtkId());
03788   nodeIds.push_back(n34->getVtkId());
03789   nodeIds.push_back(n23->getVtkId());
03790   nodeIds.push_back(n12->getVtkId());
03791 
03792   nodeIds.push_back(n15->getVtkId());
03793   nodeIds.push_back(n45->getVtkId());
03794   nodeIds.push_back(n35->getVtkId());
03795   nodeIds.push_back(n25->getVtkId());
03796 
03797   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
03798   volvtk->init(nodeIds, this);
03799   if (!this->registerElement(ID,volvtk))
03800     {
03801       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
03802       myVolumePool->destroy(volvtk);
03803       return 0;
03804     }
03805   adjustmyCellsCapacity(ID);
03806   myCells[ID] = volvtk;
03807   myInfo.myNbQuadPyramids++;
03808 
03809 //  if (!registerElement(ID, volvtk)) {
03810 //    RemoveElement(volvtk, false);
03811 //    volvtk = NULL;
03812 //  }
03813   return volvtk;
03814 }
03815 
03816 
03817 //=======================================================================
03818 //function : AddVolume
03819 //purpose  :
03820 //=======================================================================
03821 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03822                                       const SMDS_MeshNode * n2,
03823                                       const SMDS_MeshNode * n3,
03824                                       const SMDS_MeshNode * n4,
03825                                       const SMDS_MeshNode * n5,
03826                                       const SMDS_MeshNode * n6,
03827                                       const SMDS_MeshNode * n12,
03828                                       const SMDS_MeshNode * n23,
03829                                       const SMDS_MeshNode * n31,
03830                                       const SMDS_MeshNode * n45,
03831                                       const SMDS_MeshNode * n56,
03832                                       const SMDS_MeshNode * n64,
03833                                       const SMDS_MeshNode * n14,
03834                                       const SMDS_MeshNode * n25,
03835                                       const SMDS_MeshNode * n36)
03836 {
03837   int ID = myElementIDFactory->GetFreeID();
03838   SMDS_MeshVolume * v =
03839     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
03840                                n45, n56, n64, n14, n25, n36, ID);
03841   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03842   return v;
03843 }
03844 
03845 //=======================================================================
03846 //function : AddVolumeWithID
03847 //purpose  :
03848 //=======================================================================
03849 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
03850                                             int n4, int n5, int n6,
03851                                             int n12,int n23,int n31,
03852                                             int n45,int n56,int n64,
03853                                             int n14,int n25,int n36, int ID)
03854 {
03855   return SMDS_Mesh::AddVolumeWithID
03856     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
03857      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
03858      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
03859      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
03860      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
03861      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
03862      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03863      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
03864      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
03865      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
03866      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
03867      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
03868      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
03869      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
03870      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
03871      ID);
03872 }
03873 
03874 //=======================================================================
03875 //function : AddVolumeWithID
03876 //purpose  : 2d order Pentahedron with 15 nodes
03877 //=======================================================================
03878 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
03879                                             const SMDS_MeshNode * n2,
03880                                             const SMDS_MeshNode * n3,
03881                                             const SMDS_MeshNode * n4,
03882                                             const SMDS_MeshNode * n5,
03883                                             const SMDS_MeshNode * n6,
03884                                             const SMDS_MeshNode * n12,
03885                                             const SMDS_MeshNode * n23,
03886                                             const SMDS_MeshNode * n31,
03887                                             const SMDS_MeshNode * n45,
03888                                             const SMDS_MeshNode * n56,
03889                                             const SMDS_MeshNode * n64,
03890                                             const SMDS_MeshNode * n14,
03891                                             const SMDS_MeshNode * n25,
03892                                             const SMDS_MeshNode * n36,
03893                                             int ID)
03894 {
03895   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
03896       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
03897     return 0;
03898   if(hasConstructionFaces()) {
03899     // creation quadratic faces - not implemented
03900     return 0;
03901   }
03902   // --- retrieve nodes ID
03903   vector<vtkIdType> nodeIds;
03904   nodeIds.clear();
03905   nodeIds.push_back(n1->getVtkId());
03906   nodeIds.push_back(n2->getVtkId());
03907   nodeIds.push_back(n3->getVtkId());
03908 
03909   nodeIds.push_back(n4->getVtkId());
03910   nodeIds.push_back(n5->getVtkId());
03911   nodeIds.push_back(n6->getVtkId());
03912 
03913   nodeIds.push_back(n12->getVtkId());
03914   nodeIds.push_back(n23->getVtkId());
03915   nodeIds.push_back(n31->getVtkId());
03916 
03917   nodeIds.push_back(n45->getVtkId());
03918   nodeIds.push_back(n56->getVtkId());
03919   nodeIds.push_back(n64->getVtkId());
03920 
03921   nodeIds.push_back(n14->getVtkId());
03922   nodeIds.push_back(n25->getVtkId());
03923   nodeIds.push_back(n36->getVtkId());
03924 
03925   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
03926   volvtk->init(nodeIds, this);
03927   if (!this->registerElement(ID,volvtk))
03928     {
03929       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
03930       myVolumePool->destroy(volvtk);
03931       return 0;
03932     }
03933   adjustmyCellsCapacity(ID);
03934   myCells[ID] = volvtk;
03935   myInfo.myNbQuadPrisms++;
03936 
03937 //  if (!registerElement(ID, volvtk)) {
03938 //    RemoveElement(volvtk, false);
03939 //    volvtk = NULL;
03940 //  }
03941   return volvtk;
03942 }
03943 
03944 
03945 //=======================================================================
03946 //function : AddVolume
03947 //purpose  :
03948 //=======================================================================
03949 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
03950                                       const SMDS_MeshNode * n2,
03951                                       const SMDS_MeshNode * n3,
03952                                       const SMDS_MeshNode * n4,
03953                                       const SMDS_MeshNode * n5,
03954                                       const SMDS_MeshNode * n6,
03955                                       const SMDS_MeshNode * n7,
03956                                       const SMDS_MeshNode * n8,
03957                                       const SMDS_MeshNode * n12,
03958                                       const SMDS_MeshNode * n23,
03959                                       const SMDS_MeshNode * n34,
03960                                       const SMDS_MeshNode * n41,
03961                                       const SMDS_MeshNode * n56,
03962                                       const SMDS_MeshNode * n67,
03963                                       const SMDS_MeshNode * n78,
03964                                       const SMDS_MeshNode * n85,
03965                                       const SMDS_MeshNode * n15,
03966                                       const SMDS_MeshNode * n26,
03967                                       const SMDS_MeshNode * n37,
03968                                       const SMDS_MeshNode * n48)
03969 {
03970   int ID = myElementIDFactory->GetFreeID();
03971   SMDS_MeshVolume * v =
03972     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
03973                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
03974   if(v==NULL) myElementIDFactory->ReleaseID(ID);
03975   return v;
03976 }
03977 
03978 //=======================================================================
03979 //function : AddVolumeWithID
03980 //purpose  :
03981 //=======================================================================
03982 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
03983                                             int n5, int n6, int n7, int n8,
03984                                             int n12,int n23,int n34,int n41,
03985                                             int n56,int n67,int n78,int n85,
03986                                             int n15,int n26,int n37,int n48, int ID)
03987 {
03988   return SMDS_Mesh::AddVolumeWithID
03989     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
03990      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
03991      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
03992      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
03993      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
03994      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
03995      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
03996      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
03997      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
03998      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
03999      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
04000      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
04001      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
04002      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
04003      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
04004      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
04005      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
04006      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
04007      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
04008      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
04009      ID);
04010 }
04011 
04012 //=======================================================================
04013 //function : AddVolumeWithID
04014 //purpose  : 2d order Hexahedrons with 20 nodes
04015 //=======================================================================
04016 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
04017                                             const SMDS_MeshNode * n2,
04018                                             const SMDS_MeshNode * n3,
04019                                             const SMDS_MeshNode * n4,
04020                                             const SMDS_MeshNode * n5,
04021                                             const SMDS_MeshNode * n6,
04022                                             const SMDS_MeshNode * n7,
04023                                             const SMDS_MeshNode * n8,
04024                                             const SMDS_MeshNode * n12,
04025                                             const SMDS_MeshNode * n23,
04026                                             const SMDS_MeshNode * n34,
04027                                             const SMDS_MeshNode * n41,
04028                                             const SMDS_MeshNode * n56,
04029                                             const SMDS_MeshNode * n67,
04030                                             const SMDS_MeshNode * n78,
04031                                             const SMDS_MeshNode * n85,
04032                                             const SMDS_MeshNode * n15,
04033                                             const SMDS_MeshNode * n26,
04034                                             const SMDS_MeshNode * n37,
04035                                             const SMDS_MeshNode * n48,
04036                                             int ID)
04037 {
04038   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
04039       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
04040     return 0;
04041   if(hasConstructionFaces()) {
04042     return 0;
04043     // creation quadratic faces - not implemented
04044   }
04045   // --- retrieve nodes ID
04046   vector<vtkIdType> nodeIds;
04047   nodeIds.clear();
04048   nodeIds.push_back(n1->getVtkId());
04049   nodeIds.push_back(n4->getVtkId());
04050   nodeIds.push_back(n3->getVtkId());
04051   nodeIds.push_back(n2->getVtkId());
04052 
04053   nodeIds.push_back(n5->getVtkId());
04054   nodeIds.push_back(n8->getVtkId());
04055   nodeIds.push_back(n7->getVtkId());
04056   nodeIds.push_back(n6->getVtkId());
04057 
04058   nodeIds.push_back(n41->getVtkId());
04059   nodeIds.push_back(n34->getVtkId());
04060   nodeIds.push_back(n23->getVtkId());
04061   nodeIds.push_back(n12->getVtkId());
04062 
04063   nodeIds.push_back(n85->getVtkId());
04064   nodeIds.push_back(n78->getVtkId());
04065   nodeIds.push_back(n67->getVtkId());
04066   nodeIds.push_back(n56->getVtkId());
04067 
04068   nodeIds.push_back(n15->getVtkId());
04069   nodeIds.push_back(n48->getVtkId());
04070   nodeIds.push_back(n37->getVtkId());
04071   nodeIds.push_back(n26->getVtkId());
04072 
04073   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
04074   volvtk->init(nodeIds, this);
04075   if (!this->registerElement(ID,volvtk))
04076     {
04077       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
04078       myVolumePool->destroy(volvtk);
04079       return 0;
04080     }
04081   adjustmyCellsCapacity(ID);
04082   myCells[ID] = volvtk;
04083   myInfo.myNbQuadHexas++;
04084 
04085 //  if (!registerElement(ID, volvtk)) {
04086 //    RemoveElement(volvtk, false);
04087 //    volvtk = NULL;
04088 //  }
04089   return volvtk;
04090 }
04091 
04092 void SMDS_Mesh::updateNodeMinMax()
04093 {
04094   myNodeMin = 0;
04095   if (myNodes.size() == 0)
04096   {
04097         myNodeMax=0;
04098         return;
04099   }
04100   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
04101     myNodeMin++;
04102   myNodeMax=myNodes.size()-1;
04103   while (!myNodes[myNodeMax] && (myNodeMin>=0))
04104     myNodeMin--;
04105 }
04106 
04107 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
04108 {
04109 //  int val = myCellIdSmdsToVtk.size();
04110 //  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
04111 //  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
04112   int val = myNodes.size();
04113   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
04114   myNodes.resize(val +nbNodes, 0);
04115 }
04116 
04117 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
04118 {
04119   int val = myCellIdVtkToSmds.size();
04120   MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
04121   myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
04122   val = myCells.size();
04123   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
04124   myNodes.resize(val +nbCells, 0);
04125 }
04126 
04127 void SMDS_Mesh::adjustStructure()
04128 {
04129   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
04130 }
04131 
04132 void SMDS_Mesh::dumpGrid(string ficdump)
04133 {
04134         MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
04135 //  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
04136 //  aWriter->SetFileName(ficdump.c_str());
04137 //  aWriter->SetInput(myGrid);
04138 //  if(myGrid->GetNumberOfCells())
04139 //  {
04140 //    aWriter->Write();
04141 //  }
04142 //  aWriter->Delete();
04143   ficdump = ficdump + "_connectivity";
04144   ofstream ficcon(ficdump.c_str(), ios::out);
04145   int nbPoints = myGrid->GetNumberOfPoints();
04146   ficcon << "-------------------------------- points " <<  nbPoints << endl;
04147   for (int i=0; i<nbPoints; i++)
04148   {
04149         ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
04150   }
04151   int nbCells = myGrid->GetNumberOfCells();
04152   ficcon << "-------------------------------- cells " <<  nbCells << endl;
04153   for (int i=0; i<nbCells; i++)
04154   {
04155 //      MESSAGE(i << " " << myGrid->GetCell(i));
04156 //      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
04157         ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
04158         int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
04159         vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
04160         for (int j=0; j<nbptcell; j++)
04161         {
04162                 ficcon << " " <<  listid->GetId(j);
04163         }
04164         ficcon << endl;
04165   }
04166   ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
04167         vtkCellLinks *links = myGrid->GetCellLinks();
04168   for (int i=0; i<nbPoints; i++)
04169   {
04170         int ncells = links->GetNcells(i);
04171         vtkIdType *cells = links->GetCells(i);
04172         ficcon << i << " - " << ncells << " -";
04173         for (int j=0; j<ncells; j++)
04174         {
04175                 ficcon << " " << cells[j];
04176         }
04177         ficcon << endl;
04178   }
04179   ficcon.close();
04180 
04181 }
04182 
04183 void SMDS_Mesh::compactMesh()
04184 {
04185   MESSAGE("SMDS_Mesh::compactMesh do nothing!");
04186 }
04187 
04188 int SMDS_Mesh::fromVtkToSmds(int vtkid)
04189 {
04190   if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
04191     return myCellIdVtkToSmds[vtkid];
04192   throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
04193 }
04194 
04195 void SMDS_Mesh::updateBoundingBox()
04196 {
04197   xmin = 0; xmax = 0;
04198   ymin = 0; ymax = 0;
04199   zmin = 0; zmax = 0;
04200   vtkPoints *points = myGrid->GetPoints();
04201   int myNodesSize = this->myNodes.size();
04202   for (int i = 0; i < myNodesSize; i++)
04203     {
04204       if (SMDS_MeshNode *n = myNodes[i])
04205         {
04206           double coords[3];
04207           points->GetPoint(n->myVtkID, coords);
04208           if (coords[0] < xmin) xmin = coords[0];
04209           else if (coords[0] > xmax) xmax = coords[0];
04210           if (coords[1] < ymin) ymin = coords[1];
04211           else if (coords[1] > ymax) ymax = coords[1];
04212           if (coords[2] < zmin) zmin = coords[2];
04213           else if (coords[2] > zmax) zmax = coords[2];
04214         }
04215     }
04216 }
04217 
04218 double SMDS_Mesh::getMaxDim()
04219 {
04220   double dmax = 1.e-3;
04221   if ((xmax - xmin) > dmax) dmax = xmax -xmin;
04222   if ((ymax - ymin) > dmax) dmax = ymax -ymin;
04223   if ((zmax - zmin) > dmax) dmax = zmax -zmin;
04224   MESSAGE("getMaxDim " << dmax);
04225   return dmax;
04226 }
04227 
04229 void SMDS_Mesh::Modified()
04230 {
04231   if (this->myModified)
04232     {
04233       this->myModifTime++;
04234       MESSAGE("modified");
04235       myModified = false;
04236     }
04237 }
04238 
04240 unsigned long SMDS_Mesh::GetMTime()
04241 {
04242   return this->myModifTime;
04243 }
04244 
04245 bool SMDS_Mesh::isCompacted()
04246 {
04247   if (this->myModifTime > this->myCompactTime)
04248     {
04249       MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
04250       this->myCompactTime = this->myModifTime;
04251       return false;
04252     }
04253   return true;
04254 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS