]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMDS/SMDS_Mesh.cxx
Salome HOME
1fbe8d3242dfeed12b3baa2fd118fe8fd394c99e
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  SMESH SMDS : implementaion of Salome mesh data structure
23
24 #ifdef _MSC_VER
25 #pragma warning(disable:4786)
26 #endif
27
28 #include "utilities.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SMDS_VolumeOfNodes.hxx"
31 #include "SMDS_VolumeOfFaces.hxx"
32 #include "SMDS_FaceOfNodes.hxx"
33 #include "SMDS_FaceOfEdges.hxx"
34 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
35 #include "SMDS_PolygonalFaceOfNodes.hxx"
36 #include "SMDS_QuadraticEdge.hxx"
37 #include "SMDS_QuadraticFaceOfNodes.hxx"
38 #include "SMDS_QuadraticVolumeOfNodes.hxx"
39 #include "SMDS_SpacePosition.hxx"
40
41 #include <vtkUnstructuredGrid.h>
42 #include <vtkUnsignedCharArray.h>
43
44 #include <algorithm>
45 #include <map>
46 using namespace std;
47
48 #ifndef WIN32
49 #include <sys/sysinfo.h>
50 #endif
51
52 // number of added entities to check memory after
53 #define CHECKMEMORY_INTERVAL 1000
54
55 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
56 int SMDS_Mesh::chunkSize = 1024;
57
58
59 //================================================================================
60 /*!
61  * \brief Raise an exception if free memory (ram+swap) too low
62  * \param doNotRaise - if true, suppres exception, just return free memory size
63  * \retval int - amount of available memory in MB or negative number in failure case
64  */
65 //================================================================================
66
67 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
68 {
69 #ifndef WIN32
70   struct sysinfo si;
71   int err = sysinfo( &si );
72   if ( err )
73     return -1;
74
75   static int limit = -1;
76   if ( limit < 0 ) {
77     int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
78     if (status >= 0 ) {
79       limit = WEXITSTATUS(status);
80     }
81     if ( limit < 20 )
82       limit = 20;
83     else
84       limit = int( limit * 1.5 );
85 #ifdef _DEBUG_
86     MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
87 #endif
88   }
89
90   const unsigned long Mbyte = 1024 * 1024;
91   // compute separately to avoid overflow
92   int freeMb =
93     ( si.freeram  * si.mem_unit ) / Mbyte +
94     ( si.freeswap * si.mem_unit ) / Mbyte;
95
96   if ( freeMb > limit )
97     return freeMb - limit;
98
99   if ( doNotRaise )
100     return 0;
101 #ifdef _DEBUG_
102   MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
103 #endif
104   throw std::bad_alloc();
105 #else
106   return -1;
107 #endif
108 }
109
110 ///////////////////////////////////////////////////////////////////////////////
111 /// Create a new mesh object
112 ///////////////////////////////////////////////////////////////////////////////
113 SMDS_Mesh::SMDS_Mesh()
114         :myParent(NULL),
115          myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
116          myElementIDFactory(new SMDS_MeshElementIDFactory()),
117          myHasConstructionEdges(false), myHasConstructionFaces(false),
118          myHasInverseElements(true),
119          myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
120          myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
121 {
122   myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
123   MESSAGE("myMeshId=" << myMeshId);
124   MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
125   MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
126   MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
127   MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
128   MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
129   MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
130   myNodeIDFactory->SetMesh(this);
131   myElementIDFactory->SetMesh(this);
132   _meshList.push_back(this);
133   myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
134   myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
135   myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
136   myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
137
138   myNodes.clear();
139   myCells.clear();
140   myIDElements.clear();
141   myVtkIndex.clear();
142   myGrid = vtkUnstructuredGrid::New();
143   myGrid->Initialize();
144   myGrid->Allocate();
145   vtkPoints* points = vtkPoints::New();
146   points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
147   myGrid->SetPoints( points );
148   points->Delete();
149   myGrid->BuildLinks();
150 }
151
152 ///////////////////////////////////////////////////////////////////////////////
153 /// Create a new child mesh
154 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
155 /// (2003-09-08) of SMESH
156 ///////////////////////////////////////////////////////////////////////////////
157 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
158         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
159          myElementIDFactory(parent->myElementIDFactory),
160          myHasConstructionEdges(false), myHasConstructionFaces(false),
161          myHasInverseElements(true),
162          myNodePool(parent->myNodePool),
163          myEdgePool(parent->myEdgePool),
164          myFacePool(parent->myFacePool),
165          myVolumePool(parent->myVolumePool)
166 {
167 }
168
169 ///////////////////////////////////////////////////////////////////////////////
170 ///Create a submesh and add it to the current mesh
171 ///////////////////////////////////////////////////////////////////////////////
172
173 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
174 {
175         SMDS_Mesh *submesh = new SMDS_Mesh(this);
176         myChildren.insert(myChildren.end(), submesh);
177         return submesh;
178 }
179
180 ///////////////////////////////////////////////////////////////////////////////
181 ///create a MeshNode and add it to the current Mesh
182 ///An ID is automatically assigned to the node.
183 ///@return : The created node
184 ///////////////////////////////////////////////////////////////////////////////
185
186 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
187 {
188   return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
189 }
190
191 ///////////////////////////////////////////////////////////////////////////////
192 ///create a MeshNode and add it to the current Mesh
193 ///@param ID : The ID of the MeshNode to create
194 ///@return : The created node or NULL if a node with this ID already exists
195 ///////////////////////////////////////////////////////////////////////////////
196 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
197 {
198   // find the MeshNode corresponding to ID
199   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
200   if(!node){
201     //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
202     //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
203     SMDS_MeshNode * node = myNodePool->getNew();
204     node->init(ID, myMeshId, -1, x, y, z);
205     if (ID >= myNodes.size())
206     {
207         myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
208         //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
209     }
210     myNodes[ID] = node;
211     myNodeIDFactory->BindID(ID,node);
212     myInfo.myNbNodes++;
213     return node;
214   }else
215     return NULL;
216 }
217
218 ///////////////////////////////////////////////////////////////////////////////
219 /// create a Mesh0DElement and add it to the current Mesh
220 /// @return : The created Mesh0DElement
221 ///////////////////////////////////////////////////////////////////////////////
222 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
223 {
224   SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
225   if (!node) return NULL;
226   return SMDS_Mesh::Add0DElementWithID(node, ID);
227 }
228
229 ///////////////////////////////////////////////////////////////////////////////
230 /// create a Mesh0DElement and add it to the current Mesh
231 /// @return : The created Mesh0DElement
232 ///////////////////////////////////////////////////////////////////////////////
233 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
234 {
235   return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
236 }
237
238 ///////////////////////////////////////////////////////////////////////////////
239 /// Create a new Mesh0DElement and at it to the mesh
240 /// @param idnode ID of the node
241 /// @param ID ID of the 0D element to create
242 /// @return The created 0D element or NULL if an element with this
243 ///         ID already exists or if input node is not found.
244 ///////////////////////////////////////////////////////////////////////////////
245 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
246 {
247   if (!n) return 0;
248
249   //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
250   //MESSAGE("Add0DElementWithID" << ID)
251   SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
252   if (myElementIDFactory->BindID(ID, el0d)) {
253     SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
254     //node->AddInverseElement(el0d);// --- fait avec BindID
255     adjustmyCellsCapacity(ID);
256     myCells[ID] = el0d;
257     myInfo.myNb0DElements++;
258     return el0d;
259   }
260
261   delete el0d;
262   return NULL;
263 }
264
265 ///////////////////////////////////////////////////////////////////////////////
266 /// create a MeshEdge and add it to the current Mesh
267 /// @return : The created MeshEdge
268 ///////////////////////////////////////////////////////////////////////////////
269
270 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
271 {
272   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
273   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
274   if(!node1 || !node2) return NULL;
275   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
276 }
277
278 ///////////////////////////////////////////////////////////////////////////////
279 /// create a MeshEdge and add it to the current Mesh
280 /// @return : The created MeshEdge
281 ///////////////////////////////////////////////////////////////////////////////
282
283 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
284                                   const SMDS_MeshNode * node2)
285 {
286   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
287 }
288
289 ///////////////////////////////////////////////////////////////////////////////
290 /// Create a new edge and at it to the mesh
291 /// @param idnode1 ID of the first node
292 /// @param idnode2 ID of the second node
293 /// @param ID ID of the edge to create
294 /// @return The created edge or NULL if an element with this ID already exists or
295 /// if input nodes are not found.
296 ///////////////////////////////////////////////////////////////////////////////
297
298 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
299                                         const SMDS_MeshNode * n2,
300                                         int ID)
301 {
302   if ( !n1 || !n2 ) return 0;
303   SMDS_MeshEdge * edge = 0;
304
305   // --- retreive nodes ID
306   vector<vtkIdType> nodeIds;
307   nodeIds.clear();
308   nodeIds.push_back(n1->getId());
309   nodeIds.push_back(n2->getId());
310
311   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
312   edgevtk->init(nodeIds, this);
313   edge = edgevtk;
314   adjustmyCellsCapacity(ID);
315   myCells[ID] = edge;
316   myInfo.myNbEdges++;
317
318   if (edge && !registerElement(ID, edge))
319   {
320     RemoveElement(edge, false);
321     edge = NULL;
322   }
323   return edge;
324 }
325
326 ///////////////////////////////////////////////////////////////////////////////
327 /// Add a triangle defined by its nodes. An ID is automatically affected to the
328 /// Created face
329 ///////////////////////////////////////////////////////////////////////////////
330
331 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
332                                   const SMDS_MeshNode * n2,
333                                   const SMDS_MeshNode * n3)
334 {
335   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
336 }
337
338 ///////////////////////////////////////////////////////////////////////////////
339 /// Add a triangle defined by its nodes IDs
340 ///////////////////////////////////////////////////////////////////////////////
341
342 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
343 {
344   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
345   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
346   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
347   if(!node1 || !node2 || !node3) return NULL;
348   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
349 }
350
351 ///////////////////////////////////////////////////////////////////////////////
352 /// Add a triangle defined by its nodes
353 ///////////////////////////////////////////////////////////////////////////////
354
355 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
356                                         const SMDS_MeshNode * n2,
357                                         const SMDS_MeshNode * n3,
358                                         int ID)
359 {
360     //MESSAGE("AddFaceWithID " << ID)
361   SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
362
363   if (face && !registerElement(ID, face)) {
364     RemoveElement(face, false);
365     face = NULL;
366   }
367   return face;
368 }
369
370 ///////////////////////////////////////////////////////////////////////////////
371 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
372 /// created face
373 ///////////////////////////////////////////////////////////////////////////////
374
375 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
376                                   const SMDS_MeshNode * n2,
377                                   const SMDS_MeshNode * n3,
378                                   const SMDS_MeshNode * n4)
379 {
380   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
381 }
382
383 ///////////////////////////////////////////////////////////////////////////////
384 /// Add a quadrangle defined by its nodes IDs
385 ///////////////////////////////////////////////////////////////////////////////
386
387 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
388                                         int idnode2,
389                                         int idnode3,
390                                         int idnode4,
391                                         int ID)
392 {
393   SMDS_MeshNode *node1, *node2, *node3, *node4;
394   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
395   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
396   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
397   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
398   if(!node1 || !node2 || !node3 || !node4) return NULL;
399   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
400 }
401
402 ///////////////////////////////////////////////////////////////////////////////
403 /// Add a quadrangle defined by its nodes
404 ///////////////////////////////////////////////////////////////////////////////
405
406 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
407                                         const SMDS_MeshNode * n2,
408                                         const SMDS_MeshNode * n3,
409                                         const SMDS_MeshNode * n4,
410                                         int ID)
411 {
412   //MESSAGE("AddFaceWithID " << ID);
413   SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
414
415   if (face && !registerElement(ID, face)) {
416     RemoveElement(face, false);
417     face = NULL;
418   }
419   return face;
420 }
421
422 ///////////////////////////////////////////////////////////////////////////////
423 /// Add a triangle defined by its edges. An ID is automatically assigned to the
424 /// Created face
425 ///////////////////////////////////////////////////////////////////////////////
426
427 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
428                                   const SMDS_MeshEdge * e2,
429                                   const SMDS_MeshEdge * e3)
430 {
431   if (!hasConstructionEdges())
432     return NULL;
433      //MESSAGE("AddFaceWithID");
434  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
435 }
436
437 ///////////////////////////////////////////////////////////////////////////////
438 /// Add a triangle defined by its edges
439 ///////////////////////////////////////////////////////////////////////////////
440
441 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
442                                         const SMDS_MeshEdge * e2,
443                                         const SMDS_MeshEdge * e3,
444                                         int ID)
445 {
446   if (!hasConstructionEdges())
447     return NULL;
448   if ( !e1 || !e2 || !e3 ) return 0;
449
450   //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
451     //MESSAGE("AddFaceWithID" << ID);
452
453   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
454   adjustmyCellsCapacity(ID);
455   myCells[ID] = face;
456   myInfo.myNbTriangles++;
457
458   if (!registerElement(ID, face)) {
459     RemoveElement(face, false);
460     face = NULL;
461   }
462   return face;
463 }
464
465 ///////////////////////////////////////////////////////////////////////////////
466 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
467 /// Created face
468 ///////////////////////////////////////////////////////////////////////////////
469
470 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
471                                   const SMDS_MeshEdge * e2,
472                                   const SMDS_MeshEdge * e3,
473                                   const SMDS_MeshEdge * e4)
474 {
475   if (!hasConstructionEdges())
476     return NULL;
477      //MESSAGE("AddFaceWithID" );
478  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
479 }
480
481 ///////////////////////////////////////////////////////////////////////////////
482 /// Add a quadrangle defined by its edges
483 ///////////////////////////////////////////////////////////////////////////////
484
485 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
486                                         const SMDS_MeshEdge * e2,
487                                         const SMDS_MeshEdge * e3,
488                                         const SMDS_MeshEdge * e4,
489                                         int ID)
490 {
491   if (!hasConstructionEdges())
492     return NULL;
493     //MESSAGE("AddFaceWithID" << ID);
494   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
495   //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
496   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
497   adjustmyCellsCapacity(ID);
498   myCells[ID] = face;
499   myInfo.myNbQuadrangles++;
500
501   if (!registerElement(ID, face))
502   {
503     RemoveElement(face, false);
504     face = NULL;
505   }
506   return face;
507 }
508
509 ///////////////////////////////////////////////////////////////////////////////
510 ///Create a new tetrahedron and add it to the mesh.
511 ///@return The created tetrahedron
512 ///////////////////////////////////////////////////////////////////////////////
513
514 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
515                                       const SMDS_MeshNode * n2,
516                                       const SMDS_MeshNode * n3,
517                                       const SMDS_MeshNode * n4)
518 {
519   int ID = myElementIDFactory->GetFreeID();
520     //MESSAGE("AddVolumeWithID " << ID);
521   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
522   if(v==NULL) myElementIDFactory->ReleaseID(ID);
523   return v;
524 }
525
526 ///////////////////////////////////////////////////////////////////////////////
527 ///Create a new tetrahedron and add it to the mesh.
528 ///@param ID The ID of the new volume
529 ///@return The created tetrahedron or NULL if an element with this ID already exists
530 ///or if input nodes are not found.
531 ///////////////////////////////////////////////////////////////////////////////
532
533 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
534                                              int idnode2,
535                                              int idnode3,
536                                              int idnode4,
537                                              int ID)
538 {
539     //MESSAGE("AddVolumeWithID" << ID);
540   SMDS_MeshNode *node1, *node2, *node3, *node4;
541   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
542   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
543   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
544   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
545   if(!node1 || !node2 || !node3 || !node4) return NULL;
546   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
547 }
548
549 ///////////////////////////////////////////////////////////////////////////////
550 ///Create a new tetrahedron and add it to the mesh.
551 ///@param ID The ID of the new volume
552 ///@return The created tetrahedron
553 ///////////////////////////////////////////////////////////////////////////////
554
555 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
556                                             const SMDS_MeshNode * n2,
557                                             const SMDS_MeshNode * n3,
558                                             const SMDS_MeshNode * n4,
559                                             int ID)
560 {
561     //MESSAGE("AddVolumeWithID " << ID);
562   SMDS_MeshVolume* volume = 0;
563   if ( !n1 || !n2 || !n3 || !n4) return volume;
564   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
565   if(hasConstructionFaces()) {
566     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
567     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
568     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
569     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
570     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
571     adjustmyCellsCapacity(ID);
572     myCells[ID] = volume;
573     myInfo.myNbTetras++;
574   }
575   else if(hasConstructionEdges()) {
576     MESSAGE("Error : Not implemented");
577     return NULL;
578   }
579   else {
580     // --- retrieve nodes ID
581     vector<vtkIdType> nodeIds;
582     nodeIds.clear();
583     nodeIds.push_back(n1->getId());
584     nodeIds.push_back(n3->getId()); // order SMDS-->VTK
585     nodeIds.push_back(n2->getId());
586     nodeIds.push_back(n4->getId());
587
588     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
589     volvtk->init(nodeIds, this);
590     volume = volvtk;
591     adjustmyCellsCapacity(ID);
592     myCells[ID] = volume;
593     myInfo.myNbTetras++;
594   }
595
596   if (!registerElement(ID, volume)) {
597     RemoveElement(volume, false);
598     volume = NULL;
599   }
600   return volume;
601 }
602
603 ///////////////////////////////////////////////////////////////////////////////
604 ///Create a new pyramid and add it to the mesh.
605 ///Nodes 1,2,3 and 4 define the base of the pyramid
606 ///@return The created pyramid
607 ///////////////////////////////////////////////////////////////////////////////
608
609 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
610                                       const SMDS_MeshNode * n2,
611                                       const SMDS_MeshNode * n3,
612                                       const SMDS_MeshNode * n4,
613                                       const SMDS_MeshNode * n5)
614 {
615   int ID = myElementIDFactory->GetFreeID();
616     //MESSAGE("AddVolumeWithID " << ID);
617   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
618   if(v==NULL) myElementIDFactory->ReleaseID(ID);
619   return v;
620 }
621
622 ///////////////////////////////////////////////////////////////////////////////
623 ///Create a new pyramid and add it to the mesh.
624 ///Nodes 1,2,3 and 4 define the base of the pyramid
625 ///@param ID The ID of the new volume
626 ///@return The created pyramid or NULL if an element with this ID already exists
627 ///or if input nodes are not found.
628 ///////////////////////////////////////////////////////////////////////////////
629
630 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
631                                              int idnode2,
632                                              int idnode3,
633                                              int idnode4,
634                                              int idnode5,
635                                              int ID)
636 {
637     //MESSAGE("AddVolumeWithID " << ID);
638   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
639   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
640   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
641   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
642   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
643   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
644   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
645   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
646 }
647
648 ///////////////////////////////////////////////////////////////////////////////
649 ///Create a new pyramid and add it to the mesh.
650 ///Nodes 1,2,3 and 4 define the base of the pyramid
651 ///@param ID The ID of the new volume
652 ///@return The created pyramid
653 ///////////////////////////////////////////////////////////////////////////////
654
655 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
656                                             const SMDS_MeshNode * n2,
657                                             const SMDS_MeshNode * n3,
658                                             const SMDS_MeshNode * n4,
659                                             const SMDS_MeshNode * n5,
660                                             int ID)
661 {
662     //MESSAGE("AddVolumeWithID " << ID);
663   SMDS_MeshVolume* volume = 0;
664   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
665   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
666   if(hasConstructionFaces()) {
667     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
668     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
669     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
670     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
671     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
672     adjustmyCellsCapacity(ID);
673     myCells[ID] = volume;
674     myInfo.myNbPyramids++;
675   }
676   else if(hasConstructionEdges()) {
677     MESSAGE("Error : Not implemented");
678     return NULL;
679   }
680   else {
681     // --- retrieve nodes ID
682     vector<vtkIdType> nodeIds;
683     nodeIds.clear();
684     nodeIds.push_back(n1->getId());
685     nodeIds.push_back(n4->getId());
686     nodeIds.push_back(n3->getId());
687     nodeIds.push_back(n2->getId());
688     nodeIds.push_back(n5->getId());
689
690     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
691     volvtk->init(nodeIds, this);
692     volume = volvtk;
693     adjustmyCellsCapacity(ID);
694     myCells[ID] = volume;
695     myInfo.myNbPyramids++;
696   }
697
698   if (!registerElement(ID, volume)) {
699     RemoveElement(volume, false);
700     volume = NULL;
701   }
702   return volume;
703 }
704
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new prism and add it to the mesh.
707 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
708 ///@return The created prism
709 ///////////////////////////////////////////////////////////////////////////////
710
711 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
712                                       const SMDS_MeshNode * n2,
713                                       const SMDS_MeshNode * n3,
714                                       const SMDS_MeshNode * n4,
715                                       const SMDS_MeshNode * n5,
716                                       const SMDS_MeshNode * n6)
717 {
718   int ID = myElementIDFactory->GetFreeID();
719     //MESSAGE("AddVolumeWithID " << ID);
720   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
721   if(v==NULL) myElementIDFactory->ReleaseID(ID);
722   return v;
723 }
724
725 ///////////////////////////////////////////////////////////////////////////////
726 ///Create a new prism and add it to the mesh.
727 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
728 ///@param ID The ID of the new volume
729 ///@return The created prism or NULL if an element with this ID already exists
730 ///or if input nodes are not found.
731 ///////////////////////////////////////////////////////////////////////////////
732
733 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
734                                              int idnode2,
735                                              int idnode3,
736                                              int idnode4,
737                                              int idnode5,
738                                              int idnode6,
739                                              int ID)
740 {
741     //MESSAGE("AddVolumeWithID " << ID);
742   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
743   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
744   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
745   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
746   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
747   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
748   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
749   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
750   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
751 }
752
753 ///////////////////////////////////////////////////////////////////////////////
754 ///Create a new prism and add it to the mesh.
755 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
756 ///@param ID The ID of the new volume
757 ///@return The created prism
758 ///////////////////////////////////////////////////////////////////////////////
759
760 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
761                                             const SMDS_MeshNode * n2,
762                                             const SMDS_MeshNode * n3,
763                                             const SMDS_MeshNode * n4,
764                                             const SMDS_MeshNode * n5,
765                                             const SMDS_MeshNode * n6,
766                                             int ID)
767 {
768     //MESSAGE("AddVolumeWithID " << ID);
769   SMDS_MeshVolume* volume = 0;
770   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
771   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
772   if(hasConstructionFaces()) {
773     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
774     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
775     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
776     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
777     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
778     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
779     adjustmyCellsCapacity(ID);
780     myCells[ID] = volume;
781     myInfo.myNbPrisms++;
782   }
783   else if(hasConstructionEdges()) {
784     MESSAGE("Error : Not implemented");
785     return NULL;
786   }
787   else {
788     // --- retrieve nodes ID
789     vector<vtkIdType> nodeIds;
790     nodeIds.clear();
791     nodeIds.push_back(n1->getId());
792     nodeIds.push_back(n3->getId());
793     nodeIds.push_back(n2->getId());
794     nodeIds.push_back(n4->getId());
795     nodeIds.push_back(n6->getId());
796     nodeIds.push_back(n5->getId());
797
798     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
799     volvtk->init(nodeIds, this);
800     volume = volvtk;
801     adjustmyCellsCapacity(ID);
802     myCells[ID] = volume;
803     myInfo.myNbPrisms++;
804   }
805
806   if (!registerElement(ID, volume)) {
807     RemoveElement(volume, false);
808     volume = NULL;
809   }
810   return volume;
811 }
812
813 ///////////////////////////////////////////////////////////////////////////////
814 ///Create a new hexahedron and add it to the mesh.
815 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
816 ///@return The created hexahedron
817 ///////////////////////////////////////////////////////////////////////////////
818
819 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
820                                       const SMDS_MeshNode * n2,
821                                       const SMDS_MeshNode * n3,
822                                       const SMDS_MeshNode * n4,
823                                       const SMDS_MeshNode * n5,
824                                       const SMDS_MeshNode * n6,
825                                       const SMDS_MeshNode * n7,
826                                       const SMDS_MeshNode * n8)
827 {
828   int ID = myElementIDFactory->GetFreeID();
829      //MESSAGE("AddVolumeWithID " << ID);
830  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
831   if(v==NULL) myElementIDFactory->ReleaseID(ID);
832   return v;
833 }
834
835 ///////////////////////////////////////////////////////////////////////////////
836 ///Create a new hexahedron and add it to the mesh.
837 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
838 ///@param ID The ID of the new volume
839 ///@return The created hexahedron or NULL if an element with this ID already
840 ///exists or if input nodes are not found.
841 ///////////////////////////////////////////////////////////////////////////////
842
843 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
844                                              int idnode2,
845                                              int idnode3,
846                                              int idnode4,
847                                              int idnode5,
848                                              int idnode6,
849                                              int idnode7,
850                                              int idnode8,
851                                              int ID)
852 {
853     //MESSAGE("AddVolumeWithID " << ID);
854   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
855   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
856   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
857   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
858   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
859   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
860   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
861   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
862   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
863   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
864     return NULL;
865   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
866                                     node7, node8, ID);
867 }
868
869 ///////////////////////////////////////////////////////////////////////////////
870 ///Create a new hexahedron and add it to the mesh.
871 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
872 ///@param ID The ID of the new volume
873 ///@return The created prism or NULL if an element with this ID already exists
874 ///or if input nodes are not found.
875 ///////////////////////////////////////////////////////////////////////////////
876
877 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
878                                             const SMDS_MeshNode * n2,
879                                             const SMDS_MeshNode * n3,
880                                             const SMDS_MeshNode * n4,
881                                             const SMDS_MeshNode * n5,
882                                             const SMDS_MeshNode * n6,
883                                             const SMDS_MeshNode * n7,
884                                             const SMDS_MeshNode * n8,
885                                             int ID)
886 {
887     //MESSAGE("AddVolumeWithID " << ID);
888   SMDS_MeshVolume* volume = 0;
889   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
890   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
891   if(hasConstructionFaces()) {
892     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
893     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
894     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
895     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
896     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
897     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
898     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
899     adjustmyCellsCapacity(ID);
900     myCells[ID] = volume;
901     myInfo.myNbHexas++;
902   }
903   else if(hasConstructionEdges()) {
904     MESSAGE("Error : Not implemented");
905     return NULL;
906   }
907   else {
908     // --- retrieve nodes ID
909     vector<vtkIdType> nodeIds;
910     nodeIds.clear();
911     nodeIds.push_back(n1->getId());
912     nodeIds.push_back(n4->getId());
913     nodeIds.push_back(n3->getId());
914     nodeIds.push_back(n2->getId());
915     nodeIds.push_back(n5->getId());
916     nodeIds.push_back(n8->getId());
917     nodeIds.push_back(n7->getId());
918     nodeIds.push_back(n6->getId());
919
920     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
921     volvtk->init(nodeIds, this);
922     volume = volvtk;
923     adjustmyCellsCapacity(ID);
924     myCells[ID] = volume;
925     myInfo.myNbHexas++;
926   }
927  
928   if (!registerElement(ID, volume)) {
929     RemoveElement(volume, false);
930     volume = NULL;
931   }
932   return volume;
933 }
934
935 ///////////////////////////////////////////////////////////////////////////////
936 ///Create a new tetrahedron defined by its faces and add it to the mesh.
937 ///@return The created tetrahedron
938 ///////////////////////////////////////////////////////////////////////////////
939
940 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
941                                       const SMDS_MeshFace * f2,
942                                       const SMDS_MeshFace * f3,
943                                       const SMDS_MeshFace * f4)
944 {
945     //MESSAGE("AddVolumeWithID");
946   if (!hasConstructionFaces())
947     return NULL;
948   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
949 }
950
951 ///////////////////////////////////////////////////////////////////////////////
952 ///Create a new tetrahedron defined by its faces and add it to the mesh.
953 ///@param ID The ID of the new volume
954 ///@return The created tetrahedron
955 ///////////////////////////////////////////////////////////////////////////////
956
957 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
958                                             const SMDS_MeshFace * f2,
959                                             const SMDS_MeshFace * f3,
960                                             const SMDS_MeshFace * f4,
961                                             int ID)
962 {
963     //MESSAGE("AddVolumeWithID" << ID);
964   if (!hasConstructionFaces())
965     return NULL;
966   if ( !f1 || !f2 || !f3 || !f4) return 0;
967   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
968   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
969   adjustmyCellsCapacity(ID);
970   myCells[ID] = volume;
971   myInfo.myNbTetras++;
972
973   if (!registerElement(ID, volume)) {
974     RemoveElement(volume, false);
975     volume = NULL;
976   }
977   return volume;
978 }
979
980 ///////////////////////////////////////////////////////////////////////////////
981 ///Create a new pyramid defined by its faces and add it to the mesh.
982 ///@return The created pyramid
983 ///////////////////////////////////////////////////////////////////////////////
984
985 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
986                                       const SMDS_MeshFace * f2,
987                                       const SMDS_MeshFace * f3,
988                                       const SMDS_MeshFace * f4,
989                                       const SMDS_MeshFace * f5)
990 {
991      //MESSAGE("AddVolumeWithID");
992  if (!hasConstructionFaces())
993     return NULL;
994   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
995 }
996
997 ///////////////////////////////////////////////////////////////////////////////
998 ///Create a new pyramid defined by its faces and add it to the mesh.
999 ///@param ID The ID of the new volume
1000 ///@return The created pyramid
1001 ///////////////////////////////////////////////////////////////////////////////
1002
1003 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1004                                             const SMDS_MeshFace * f2,
1005                                             const SMDS_MeshFace * f3,
1006                                             const SMDS_MeshFace * f4,
1007                                             const SMDS_MeshFace * f5,
1008                                             int ID)
1009 {
1010     //MESSAGE("AddVolumeWithID" << ID);
1011   if (!hasConstructionFaces())
1012     return NULL;
1013   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1014   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1015   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1016   adjustmyCellsCapacity(ID);
1017   myCells[ID] = volume;
1018   myInfo.myNbPyramids++;
1019
1020   if (!registerElement(ID, volume)) {
1021     RemoveElement(volume, false);
1022     volume = NULL;
1023   }
1024   return volume;
1025 }
1026
1027 ///////////////////////////////////////////////////////////////////////////////
1028 ///Create a new prism defined by its faces and add it to the mesh.
1029 ///@return The created prism
1030 ///////////////////////////////////////////////////////////////////////////////
1031
1032 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1033                                       const SMDS_MeshFace * f2,
1034                                       const SMDS_MeshFace * f3,
1035                                       const SMDS_MeshFace * f4,
1036                                       const SMDS_MeshFace * f5,
1037                                       const SMDS_MeshFace * f6)
1038 {
1039      //MESSAGE("AddVolumeWithID" );
1040  if (!hasConstructionFaces())
1041     return NULL;
1042   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1043 }
1044
1045 ///////////////////////////////////////////////////////////////////////////////
1046 ///Create a new prism defined by its faces and add it to the mesh.
1047 ///@param ID The ID of the new volume
1048 ///@return The created prism
1049 ///////////////////////////////////////////////////////////////////////////////
1050
1051 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1052                                             const SMDS_MeshFace * f2,
1053                                             const SMDS_MeshFace * f3,
1054                                             const SMDS_MeshFace * f4,
1055                                             const SMDS_MeshFace * f5,
1056                                             const SMDS_MeshFace * f6,
1057                                             int ID)
1058 {
1059      //MESSAGE("AddVolumeWithID" << ID);
1060   if (!hasConstructionFaces())
1061     return NULL;
1062   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1063   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1064   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1065   adjustmyCellsCapacity(ID);
1066   myCells[ID] = volume;
1067   myInfo.myNbPrisms++;
1068
1069   if (!registerElement(ID, volume)) {
1070     RemoveElement(volume, false);
1071     volume = NULL;
1072   }
1073   return volume;
1074 }
1075
1076 ///////////////////////////////////////////////////////////////////////////////
1077 /// Add a polygon defined by its nodes IDs
1078 ///////////////////////////////////////////////////////////////////////////////
1079
1080 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
1081                                                   const int        ID)
1082 {
1083   int nbNodes = nodes_ids.size();
1084   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1085   for (int i = 0; i < nbNodes; i++) {
1086     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1087     if (!nodes[i]) return NULL;
1088   }
1089   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1090 }
1091
1092 ///////////////////////////////////////////////////////////////////////////////
1093 /// Add a polygon defined by its nodes
1094 ///////////////////////////////////////////////////////////////////////////////
1095
1096 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1097                           (std::vector<const SMDS_MeshNode*> nodes,
1098                            const int                         ID)
1099 {
1100   SMDS_MeshFace * face;
1101
1102   //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1103   if (hasConstructionEdges())
1104   {
1105     MESSAGE("Error : Not implemented");
1106     return NULL;
1107   }
1108   else
1109   {
1110     for ( int i = 0; i < nodes.size(); ++i )
1111       if ( !nodes[ i ] ) return 0;
1112     face = new SMDS_PolygonalFaceOfNodes(nodes);
1113     adjustmyCellsCapacity(ID);
1114     myCells[ID] = face;
1115     myInfo.myNbPolygons++;
1116   }
1117
1118   if (!registerElement(ID, face)) {
1119     RemoveElement(face, false);
1120     face = NULL;
1121   }
1122   return face;
1123 }
1124
1125 ///////////////////////////////////////////////////////////////////////////////
1126 /// Add a polygon defined by its nodes.
1127 /// An ID is automatically affected to the created face.
1128 ///////////////////////////////////////////////////////////////////////////////
1129
1130 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
1131 {
1132   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1133 }
1134
1135 ///////////////////////////////////////////////////////////////////////////////
1136 /// Create a new polyhedral volume and add it to the mesh.
1137 /// @param ID The ID of the new volume
1138 /// @return The created volume or NULL if an element with this ID already exists
1139 /// or if input nodes are not found.
1140 ///////////////////////////////////////////////////////////////////////////////
1141
1142 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1143                              (std::vector<int> nodes_ids,
1144                               std::vector<int> quantities,
1145                               const int        ID)
1146 {
1147   int nbNodes = nodes_ids.size();
1148   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
1149   for (int i = 0; i < nbNodes; i++) {
1150     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1151     if (!nodes[i]) return NULL;
1152   }
1153   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1154 }
1155
1156 ///////////////////////////////////////////////////////////////////////////////
1157 /// Create a new polyhedral volume and add it to the mesh.
1158 /// @param ID The ID of the new volume
1159 /// @return The created  volume
1160 ///////////////////////////////////////////////////////////////////////////////
1161
1162 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1163                             (std::vector<const SMDS_MeshNode*> nodes,
1164                              std::vector<int>                  quantities,
1165                              const int                         ID)
1166 {
1167   SMDS_MeshVolume* volume;
1168   //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1169   if (hasConstructionFaces()) {
1170     MESSAGE("Error : Not implemented");
1171     return NULL;
1172   } else if (hasConstructionEdges()) {
1173     MESSAGE("Error : Not implemented");
1174     return NULL;
1175   } else {
1176     for ( int i = 0; i < nodes.size(); ++i )
1177       if ( !nodes[ i ] ) return 0;
1178     volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1179     adjustmyCellsCapacity(ID);
1180     myCells[ID] = volume;
1181     myInfo.myNbPolyhedrons++;
1182   }
1183
1184   if (!registerElement(ID, volume)) {
1185     RemoveElement(volume, false);
1186     volume = NULL;
1187   }
1188   return volume;
1189 }
1190
1191 ///////////////////////////////////////////////////////////////////////////////
1192 /// Create a new polyhedral volume and add it to the mesh.
1193 /// @return The created  volume
1194 ///////////////////////////////////////////////////////////////////////////////
1195
1196 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1197                             (std::vector<const SMDS_MeshNode*> nodes,
1198                              std::vector<int>                  quantities)
1199 {
1200   int ID = myElementIDFactory->GetFreeID();
1201   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1202   if (v == NULL) myElementIDFactory->ReleaseID(ID);
1203   return v;
1204 }
1205
1206 ///////////////////////////////////////////////////////////////////////////////
1207 /// Registers element with the given ID, maintains inverse connections
1208 ///////////////////////////////////////////////////////////////////////////////
1209 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1210 {
1211   //MESSAGE("registerElement " << ID)
1212   if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
1213   {
1214     MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
1215     return false;
1216   }
1217
1218   element->myID = ID;
1219   element->myMeshId = myMeshId;
1220
1221   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1222   MYASSERT(cell);
1223   int vtkId = cell->getVtkId();  
1224   if (vtkId == -1)
1225     vtkId = myElementIDFactory->SetInVtkGrid(element);
1226   
1227   if (ID >= myIDElements.size()) // --- resize local vector
1228   {
1229     MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
1230     myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
1231   }
1232
1233   myIDElements[ID] = vtkId;
1234   //MESSAGE("smds:" << ID << " vtk:" << cellId );
1235
1236   if (vtkId >= myVtkIndex.size()) // --- resize local vector
1237   {
1238     MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1239     myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1240   }
1241   myVtkIndex[vtkId] = ID;
1242
1243   myElementIDFactory->updateMinMax(ID);
1244   return true;
1245 }
1246
1247 ///////////////////////////////////////////////////////////////////////////////
1248 /// Return the node whose ID is 'ID'.
1249 ///////////////////////////////////////////////////////////////////////////////
1250 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1251 {
1252   if (ID < 0 || ID >= myNodes.size())
1253   {
1254     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1255     return 0;
1256   }
1257   return (const SMDS_MeshNode *)myNodes[ID];
1258 }
1259
1260 ///////////////////////////////////////////////////////////////////////////////
1261 ///Create a triangle and add it to the current mesh. This method do not bind an
1262 ///ID to the create triangle.
1263 ///////////////////////////////////////////////////////////////////////////////
1264 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1265                                           const SMDS_MeshNode * node2,
1266                                           const SMDS_MeshNode * node3,
1267                                           int ID)
1268 {
1269   if ( !node1 || !node2 || !node3) return 0;
1270 //  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1271   if(hasConstructionEdges())
1272   {
1273     SMDS_MeshEdge *edge1, *edge2, *edge3;
1274     edge1=FindEdgeOrCreate(node1,node2);
1275     edge2=FindEdgeOrCreate(node2,node3);
1276     edge3=FindEdgeOrCreate(node3,node1);
1277
1278     //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1279     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1280     adjustmyCellsCapacity(ID);
1281     myCells[ID] = face;
1282     myInfo.myNbTriangles++;
1283     return face;
1284   }
1285   else
1286   {
1287     // --- retrieve nodes ID
1288     vector<vtkIdType> nodeIds;
1289     nodeIds.clear();
1290     nodeIds.push_back(node1->getId());
1291     nodeIds.push_back(node2->getId());
1292     nodeIds.push_back(node3->getId());
1293
1294     SMDS_MeshFace * face = 0;
1295     SMDS_VtkFace *facevtk = myFacePool->getNew();
1296     facevtk->init(nodeIds, this);
1297     face = facevtk;
1298     adjustmyCellsCapacity(ID);
1299     myCells[ID] = face;
1300     myInfo.myNbTriangles++;
1301     return face;
1302   }
1303 }
1304
1305 ///////////////////////////////////////////////////////////////////////////////
1306 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1307 ///a ID to the create triangle.
1308 ///////////////////////////////////////////////////////////////////////////////
1309 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1310                                             const SMDS_MeshNode * node2,
1311                                             const SMDS_MeshNode * node3,
1312                                             const SMDS_MeshNode * node4,
1313                                             int ID)
1314 {
1315   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1316 //  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1317   if(hasConstructionEdges())
1318   {
1319       //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1320     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1321     edge1=FindEdgeOrCreate(node1,node2);
1322     edge2=FindEdgeOrCreate(node2,node3);
1323     edge3=FindEdgeOrCreate(node3,node4);
1324     edge4=FindEdgeOrCreate(node4,node1);
1325
1326     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1327     adjustmyCellsCapacity(ID);
1328     myCells[ID] = face;
1329     myInfo.myNbQuadrangles++;
1330     return face;
1331   }
1332   else
1333   {
1334     // --- retrieve nodes ID
1335     vector<vtkIdType> nodeIds;
1336     nodeIds.clear();
1337     nodeIds.push_back(node1->getId());
1338     nodeIds.push_back(node2->getId());
1339     nodeIds.push_back(node3->getId());
1340     nodeIds.push_back(node4->getId());
1341
1342     SMDS_MeshFace * face = 0;
1343     SMDS_VtkFace *facevtk = myFacePool->getNew();
1344     facevtk->init(nodeIds, this);
1345     face = facevtk;
1346     adjustmyCellsCapacity(ID);
1347     myCells[ID] = face;
1348     myInfo.myNbQuadrangles++;
1349     return face;
1350   }
1351 }
1352
1353 ///////////////////////////////////////////////////////////////////////////////
1354 /// Remove a node and all the elements which own this node
1355 ///////////////////////////////////////////////////////////////////////////////
1356
1357 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1358 {
1359     MESSAGE("RemoveNode");
1360         RemoveElement(node, true);
1361 }
1362
1363 ///////////////////////////////////////////////////////////////////////////////
1364 /// Remove an edge and all the elements which own this edge
1365 ///////////////////////////////////////////////////////////////////////////////
1366
1367 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1368 {
1369     MESSAGE("Remove0DElement");
1370   RemoveElement(elem0d,true);
1371 }
1372
1373 ///////////////////////////////////////////////////////////////////////////////
1374 /// Remove an edge and all the elements which own this edge
1375 ///////////////////////////////////////////////////////////////////////////////
1376
1377 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1378 {
1379     MESSAGE("RemoveEdge");
1380         RemoveElement(edge,true);
1381 }
1382
1383 ///////////////////////////////////////////////////////////////////////////////
1384 /// Remove an face and all the elements which own this face
1385 ///////////////////////////////////////////////////////////////////////////////
1386
1387 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1388 {
1389     MESSAGE("RemoveFace");
1390         RemoveElement(face, true);
1391 }
1392
1393 ///////////////////////////////////////////////////////////////////////////////
1394 /// Remove a volume
1395 ///////////////////////////////////////////////////////////////////////////////
1396
1397 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1398 {
1399     MESSAGE("RemoveVolume");
1400         RemoveElement(volume, true);
1401 }
1402
1403 //=======================================================================
1404 //function : RemoveFromParent
1405 //purpose  :
1406 //=======================================================================
1407
1408 bool SMDS_Mesh::RemoveFromParent()
1409 {
1410         if (myParent==NULL) return false;
1411         else return (myParent->RemoveSubMesh(this));
1412 }
1413
1414 //=======================================================================
1415 //function : RemoveSubMesh
1416 //purpose  :
1417 //=======================================================================
1418
1419 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1420 {
1421         bool found = false;
1422
1423         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1424         for (; itmsh!=myChildren.end() && !found; itmsh++)
1425         {
1426                 SMDS_Mesh * submesh = *itmsh;
1427                 if (submesh == aMesh)
1428                 {
1429                         found = true;
1430                         myChildren.erase(itmsh);
1431                 }
1432         }
1433
1434         return found;
1435 }
1436
1437 //=======================================================================
1438 //function : ChangeElementNodes
1439 //purpose  :
1440 //=======================================================================
1441
1442 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1443                                    const SMDS_MeshNode    * nodes[],
1444                                    const int                nbnodes)
1445 {
1446   MYASSERT(0); // REVOIR LES TYPES
1447   // keep current nodes of elem
1448   set<const SMDS_MeshElement*> oldNodes;
1449   SMDS_ElemIteratorPtr itn = element->nodesIterator();
1450   while(itn->more())
1451     oldNodes.insert(  itn->next() );
1452
1453   if ( !element->IsPoly() )
1454     myInfo.remove( element ); // element may change type
1455
1456   // change nodes
1457   bool Ok = false;
1458   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
1459   switch ( elem->GetType() )
1460   {
1461   case SMDSAbs_0DElement: {
1462     if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
1463       Ok = elem0d->ChangeNode( nodes[0] );
1464     break;
1465   }
1466   case SMDSAbs_Edge: {
1467     if ( nbnodes == 2 ) {
1468       if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
1469         Ok = edge->ChangeNodes( nodes[0], nodes[1] );
1470     }
1471     else if ( nbnodes == 3 ) {
1472       if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
1473         Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1474     }
1475     break;
1476   }
1477   case SMDSAbs_Face: {
1478     if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
1479       Ok = face->ChangeNodes( nodes, nbnodes );
1480     else
1481       if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
1482         Ok = QF->ChangeNodes( nodes, nbnodes );
1483       else
1484         if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
1485           Ok = face->ChangeNodes(nodes, nbnodes);
1486     break;
1487   }
1488   case SMDSAbs_Volume: {
1489     if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
1490       Ok = vol->ChangeNodes( nodes, nbnodes );
1491     else
1492       if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
1493         Ok = QV->ChangeNodes( nodes, nbnodes );
1494     break;
1495   }
1496   default:
1497     MESSAGE ( "WRONG ELEM TYPE");
1498   }
1499
1500   if ( Ok ) { // update InverseElements
1501
1502     set<const SMDS_MeshElement*>::iterator it;
1503
1504     // AddInverseElement to new nodes
1505     for ( int i = 0; i < nbnodes; i++ ) {
1506       it = oldNodes.find( nodes[i] );
1507       if ( it == oldNodes.end() )
1508         // new node
1509         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1510       else
1511         // remove from oldNodes a node that remains in elem
1512         oldNodes.erase( it );
1513     }
1514     // RemoveInverseElement from the nodes removed from elem
1515     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1516     {
1517       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1518         (const_cast<SMDS_MeshElement *>( *it ));
1519       n->RemoveInverseElement( elem );
1520     }
1521   }
1522
1523   if ( !element->IsPoly() )
1524     myInfo.add( element ); // element may change type
1525
1526   return Ok;
1527 }
1528
1529 //=======================================================================
1530 //function : ChangePolyhedronNodes
1531 //purpose  : to change nodes of polyhedral volume
1532 //=======================================================================
1533 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
1534                                        const vector<const SMDS_MeshNode*>& nodes,
1535                                        const vector<int>                 & quantities)
1536 {
1537   if (elem->GetType() != SMDSAbs_Volume) {
1538     MESSAGE("WRONG ELEM TYPE");
1539     return false;
1540   }
1541
1542   const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1543   if (!vol) {
1544     return false;
1545   }
1546
1547   // keep current nodes of elem
1548   set<const SMDS_MeshElement*> oldNodes;
1549   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1550   while (itn->more()) {
1551     oldNodes.insert(itn->next());
1552   }
1553
1554   // change nodes
1555   bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1556   if (!Ok) {
1557     return false;
1558   }
1559
1560   // update InverseElements
1561
1562   // AddInverseElement to new nodes
1563   int nbnodes = nodes.size();
1564   set<const SMDS_MeshElement*>::iterator it;
1565   for (int i = 0; i < nbnodes; i++) {
1566     it = oldNodes.find(nodes[i]);
1567     if (it == oldNodes.end()) {
1568       // new node
1569       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1570     } else {
1571       // remove from oldNodes a node that remains in elem
1572       oldNodes.erase(it);
1573     }
1574   }
1575
1576   // RemoveInverseElement from the nodes removed from elem
1577   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1578     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1579       (const_cast<SMDS_MeshElement *>( *it ));
1580     n->RemoveInverseElement(elem);
1581   }
1582
1583   return Ok;
1584 }
1585
1586
1587 //=======================================================================
1588 //function : Find0DElement
1589 //purpose  :
1590 //=======================================================================
1591 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1592 {
1593   const SMDS_MeshNode * node = FindNode(idnode);
1594   if(node == NULL) return NULL;
1595   return Find0DElement(node);
1596 }
1597
1598 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1599 {
1600   if (!node) return 0;
1601   const SMDS_Mesh0DElement* toReturn = NULL;
1602   SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1603   while (it1->more() && (toReturn == NULL)) {
1604     const SMDS_MeshElement* e = it1->next();
1605     if (e->NbNodes() == 1) {
1606       toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1607     }
1608   }
1609   return toReturn;
1610 }
1611
1612 //=======================================================================
1613 //function : Find0DElementOrCreate
1614 //purpose  :
1615 //=======================================================================
1616 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1617 //{
1618 //  if (!node) return 0;
1619 //  SMDS_Mesh0DElement * toReturn = NULL;
1620 //  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1621 //  if (toReturn == NULL) {
1622 //    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1623 //    toReturn = new SMDS_Mesh0DElement(node);
1624 //    my0DElements.Add(toReturn);
1625 //    myInfo.myNb0DElements++;
1626 //  }
1627 //  return toReturn;
1628 //}
1629
1630
1631 //=======================================================================
1632 //function : FindEdge
1633 //purpose  :
1634 //=======================================================================
1635
1636 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1637 {
1638   const SMDS_MeshNode * node1=FindNode(idnode1);
1639   const SMDS_MeshNode * node2=FindNode(idnode2);
1640   if((node1==NULL)||(node2==NULL)) return NULL;
1641   return FindEdge(node1,node2);
1642 }
1643
1644 //#include "Profiler.h"
1645 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1646                                          const SMDS_MeshNode * node2)
1647 {
1648   if ( !node1 ) return 0;
1649   const SMDS_MeshEdge * toReturn=NULL;
1650   //PROFILER_Init();
1651   //PROFILER_Set();
1652   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1653   //PROFILER_Get(0);
1654   //PROFILER_Set();
1655   while(it1->more()) {
1656     const SMDS_MeshElement * e = it1->next();
1657     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1658       toReturn = static_cast<const SMDS_MeshEdge*>( e );
1659       break;
1660     }
1661   }
1662   //PROFILER_Get(1);
1663   return toReturn;
1664 }
1665
1666
1667 //=======================================================================
1668 //function : FindEdgeOrCreate
1669 //purpose  :
1670 //=======================================================================
1671
1672 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1673                                            const SMDS_MeshNode * node2)
1674 {
1675   if ( !node1 || !node2) return 0;
1676   SMDS_MeshEdge * toReturn=NULL;
1677   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1678   if(toReturn==NULL) {
1679     //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1680     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1681     adjustmyCellsCapacity(ID);
1682     vector<vtkIdType> nodeIds;
1683     nodeIds.clear();
1684     nodeIds.push_back(node1->getId());
1685     nodeIds.push_back(node2->getId());
1686
1687     SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1688     edgevtk->init(nodeIds, this);
1689     toReturn = edgevtk;
1690     myCells[ID] = toReturn;
1691     myInfo.myNbEdges++;
1692   }
1693   return toReturn;
1694 }
1695
1696
1697 //=======================================================================
1698 //function : FindEdge
1699 //purpose  :
1700 //=======================================================================
1701
1702 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1703                                          int idnode3) const
1704 {
1705   const SMDS_MeshNode * node1=FindNode(idnode1);
1706   const SMDS_MeshNode * node2=FindNode(idnode2);
1707   const SMDS_MeshNode * node3=FindNode(idnode3);
1708   return FindEdge(node1,node2,node3);
1709 }
1710
1711 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1712                                          const SMDS_MeshNode * node2,
1713                                          const SMDS_MeshNode * node3)
1714 {
1715   if ( !node1 ) return 0;
1716   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1717   while(it1->more()) {
1718     const SMDS_MeshElement * e = it1->next();
1719     if ( e->NbNodes() == 3 ) {
1720       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1721       while(it2->more()) {
1722         const SMDS_MeshElement* n = it2->next();
1723         if( n!=node1 &&
1724             n!=node2 &&
1725             n!=node3 )
1726         {
1727           e = 0;
1728           break;
1729         }
1730       }
1731       if ( e )
1732         return static_cast<const SMDS_MeshEdge *> (e);
1733     }
1734   }
1735   return 0;
1736 }
1737
1738
1739 //=======================================================================
1740 //function : FindFace
1741 //purpose  :
1742 //=======================================================================
1743
1744 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1745         int idnode3) const
1746 {
1747   const SMDS_MeshNode * node1=FindNode(idnode1);
1748   const SMDS_MeshNode * node2=FindNode(idnode2);
1749   const SMDS_MeshNode * node3=FindNode(idnode3);
1750   return FindFace(node1, node2, node3);
1751 }
1752
1753 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1754                                          const SMDS_MeshNode *node2,
1755                                          const SMDS_MeshNode *node3)
1756 {
1757   if ( !node1 ) return 0;
1758   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1759   while(it1->more()) {
1760     const SMDS_MeshElement * e = it1->next();
1761     if ( e->NbNodes() == 3 ) {
1762       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1763       while(it2->more()) {
1764         const SMDS_MeshElement* n = it2->next();
1765         if( n!=node1 &&
1766             n!=node2 &&
1767             n!=node3 )
1768         {
1769           e = 0;
1770           break;
1771         }
1772       }
1773       if ( e )
1774         return static_cast<const SMDS_MeshFace *> (e);
1775     }
1776   }
1777   return 0;
1778 }
1779
1780 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1781                                            const SMDS_MeshNode *node2,
1782                                            const SMDS_MeshNode *node3)
1783 {
1784   SMDS_MeshFace * toReturn=NULL;
1785   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1786   if(toReturn==NULL) {
1787     int ID = myElementIDFactory->GetFreeID();
1788     toReturn = createTriangle(node1,node2,node3, ID);
1789   }
1790   return toReturn;
1791 }
1792
1793
1794 //=======================================================================
1795 //function : FindFace
1796 //purpose  :
1797 //=======================================================================
1798
1799 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1800                                          int idnode3, int idnode4) const
1801 {
1802   const SMDS_MeshNode * node1=FindNode(idnode1);
1803   const SMDS_MeshNode * node2=FindNode(idnode2);
1804   const SMDS_MeshNode * node3=FindNode(idnode3);
1805   const SMDS_MeshNode * node4=FindNode(idnode4);
1806   return FindFace(node1, node2, node3, node4);
1807 }
1808
1809 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1810                                          const SMDS_MeshNode *node2,
1811                                          const SMDS_MeshNode *node3,
1812                                          const SMDS_MeshNode *node4)
1813 {
1814   if ( !node1 ) return 0;
1815   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1816   while(it1->more()) {
1817     const SMDS_MeshElement * e = it1->next();
1818     if ( e->NbNodes() == 4 ) {
1819       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1820       while(it2->more()) {
1821         const SMDS_MeshElement* n = it2->next();
1822         if( n!=node1 &&
1823             n!=node2 &&
1824             n!=node3 &&
1825             n!=node4 )
1826         {
1827           e = 0;
1828           break;
1829         }
1830       }
1831       if ( e )
1832         return static_cast<const SMDS_MeshFace *> (e);
1833     }
1834   }
1835   return 0;
1836 }
1837
1838 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1839                                            const SMDS_MeshNode *node2,
1840                                            const SMDS_MeshNode *node3,
1841                                            const SMDS_MeshNode *node4)
1842 {
1843   SMDS_MeshFace * toReturn=NULL;
1844   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1845   if(toReturn==NULL) {
1846     int ID = myElementIDFactory->GetFreeID();
1847     toReturn=createQuadrangle(node1,node2,node3,node4,ID);
1848   }
1849   return toReturn;
1850 }
1851
1852
1853 //=======================================================================
1854 //function : FindFace
1855 //purpose  :quadratic triangle
1856 //=======================================================================
1857
1858 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1859                                          int idnode3, int idnode4,
1860                                          int idnode5, int idnode6) const
1861 {
1862   const SMDS_MeshNode * node1 = FindNode(idnode1);
1863   const SMDS_MeshNode * node2 = FindNode(idnode2);
1864   const SMDS_MeshNode * node3 = FindNode(idnode3);
1865   const SMDS_MeshNode * node4 = FindNode(idnode4);
1866   const SMDS_MeshNode * node5 = FindNode(idnode5);
1867   const SMDS_MeshNode * node6 = FindNode(idnode6);
1868   return FindFace(node1, node2, node3, node4, node5, node6);
1869 }
1870
1871 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1872                                          const SMDS_MeshNode *node2,
1873                                          const SMDS_MeshNode *node3,
1874                                          const SMDS_MeshNode *node4,
1875                                          const SMDS_MeshNode *node5,
1876                                          const SMDS_MeshNode *node6)
1877 {
1878   if ( !node1 ) return 0;
1879   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1880   while(it1->more()) {
1881     const SMDS_MeshElement * e = it1->next();
1882     if ( e->NbNodes() == 6 ) {
1883       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1884       while(it2->more()) {
1885         const SMDS_MeshElement* n = it2->next();
1886         if( n!=node1 &&
1887             n!=node2 &&
1888             n!=node3 &&
1889             n!=node4 &&
1890             n!=node5 &&
1891             n!=node6 )
1892         {
1893           e = 0;
1894           break;
1895         }
1896       }
1897       if ( e )
1898         return static_cast<const SMDS_MeshFace *> (e);
1899     }
1900   }
1901   return 0;
1902 }
1903
1904
1905 //=======================================================================
1906 //function : FindFace
1907 //purpose  : quadratic quadrangle
1908 //=======================================================================
1909
1910 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1911                                          int idnode3, int idnode4,
1912                                          int idnode5, int idnode6,
1913                                          int idnode7, int idnode8) const
1914 {
1915   const SMDS_MeshNode * node1 = FindNode(idnode1);
1916   const SMDS_MeshNode * node2 = FindNode(idnode2);
1917   const SMDS_MeshNode * node3 = FindNode(idnode3);
1918   const SMDS_MeshNode * node4 = FindNode(idnode4);
1919   const SMDS_MeshNode * node5 = FindNode(idnode5);
1920   const SMDS_MeshNode * node6 = FindNode(idnode6);
1921   const SMDS_MeshNode * node7 = FindNode(idnode7);
1922   const SMDS_MeshNode * node8 = FindNode(idnode8);
1923   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1924 }
1925
1926 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1927                                          const SMDS_MeshNode *node2,
1928                                          const SMDS_MeshNode *node3,
1929                                          const SMDS_MeshNode *node4,
1930                                          const SMDS_MeshNode *node5,
1931                                          const SMDS_MeshNode *node6,
1932                                          const SMDS_MeshNode *node7,
1933                                          const SMDS_MeshNode *node8)
1934 {
1935   if ( !node1 ) return 0;
1936   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1937   while(it1->more()) {
1938     const SMDS_MeshElement * e = it1->next();
1939     if ( e->NbNodes() == 8 ) {
1940       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1941       while(it2->more()) {
1942         const SMDS_MeshElement* n = it2->next();
1943         if( n!=node1 &&
1944             n!=node2 &&
1945             n!=node3 &&
1946             n!=node4 &&
1947             n!=node5 &&
1948             n!=node6 &&
1949             n!=node7 &&
1950             n!=node8 )
1951         {
1952           e = 0;
1953           break;
1954         }
1955       }
1956       if ( e )
1957         return static_cast<const SMDS_MeshFace *> (e);
1958     }
1959   }
1960   return 0;
1961 }
1962
1963
1964 //=======================================================================
1965 //function : FindElement
1966 //purpose  :
1967 //=======================================================================
1968
1969 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1970 {
1971   if ((IDelem < 0) || IDelem >= myCells.size())
1972   {
1973     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
1974     return 0;
1975   }
1976   return myCells[IDelem];
1977 }
1978
1979 //=======================================================================
1980 //function : FindFace
1981 //purpose  : find polygon
1982 //=======================================================================
1983
1984 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1985 {
1986   int nbnodes = nodes_ids.size();
1987   std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1988   for (int inode = 0; inode < nbnodes; inode++) {
1989     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1990     if (node == NULL) return NULL;
1991     poly_nodes[inode] = node;
1992   }
1993   return FindFace(poly_nodes);
1994 }
1995
1996 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1997 {
1998   if ( nodes.size() > 2 && nodes[0] ) {
1999     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
2000     while (itF->more()) {
2001       const SMDS_MeshElement* f = itF->next();
2002       if ( f->NbNodes() == nodes.size() ) {
2003         SMDS_ElemIteratorPtr it2 = f->nodesIterator();
2004         while(it2->more()) {
2005           if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
2006             f = 0;
2007             break;
2008           }
2009         }
2010         if ( f )
2011           return static_cast<const SMDS_MeshFace *> (f);
2012       }
2013     }
2014   }
2015   return NULL;
2016 }
2017
2018 //=======================================================================
2019 //function : DumpNodes
2020 //purpose  :
2021 //=======================================================================
2022
2023 void SMDS_Mesh::DumpNodes() const
2024 {
2025         MESSAGE("dump nodes of mesh : ");
2026         SMDS_NodeIteratorPtr itnode=nodesIterator();
2027         while(itnode->more()) ; //MESSAGE(itnode->next());
2028 }
2029
2030 //=======================================================================
2031 //function : Dump0DElements
2032 //purpose  :
2033 //=======================================================================
2034 void SMDS_Mesh::Dump0DElements() const
2035 {
2036   MESSAGE("dump 0D elements of mesh : ");
2037   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2038   while(it0d->more()) ; //MESSAGE(it0d->next());
2039 }
2040
2041 //=======================================================================
2042 //function : DumpEdges
2043 //purpose  :
2044 //=======================================================================
2045
2046 void SMDS_Mesh::DumpEdges() const
2047 {
2048         MESSAGE("dump edges of mesh : ");
2049         SMDS_EdgeIteratorPtr itedge=edgesIterator();
2050         while(itedge->more()) ; //MESSAGE(itedge->next());
2051 }
2052
2053 //=======================================================================
2054 //function : DumpFaces
2055 //purpose  :
2056 //=======================================================================
2057
2058 void SMDS_Mesh::DumpFaces() const
2059 {
2060         MESSAGE("dump faces of mesh : ");
2061         SMDS_FaceIteratorPtr itface=facesIterator();
2062         while(itface->more()) ; //MESSAGE(itface->next());
2063 }
2064
2065 //=======================================================================
2066 //function : DumpVolumes
2067 //purpose  :
2068 //=======================================================================
2069
2070 void SMDS_Mesh::DumpVolumes() const
2071 {
2072         MESSAGE("dump volumes of mesh : ");
2073         SMDS_VolumeIteratorPtr itvol=volumesIterator();
2074         while(itvol->more()) ; //MESSAGE(itvol->next());
2075 }
2076
2077 //=======================================================================
2078 //function : DebugStats
2079 //purpose  :
2080 //=======================================================================
2081
2082 void SMDS_Mesh::DebugStats() const
2083 {
2084   MESSAGE("Debug stats of mesh : ");
2085
2086   MESSAGE("===== NODES ====="<<NbNodes());
2087   MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2088   MESSAGE("===== EDGES ====="<<NbEdges());
2089   MESSAGE("===== FACES ====="<<NbFaces());
2090   MESSAGE("===== VOLUMES ====="<<NbVolumes());
2091
2092   MESSAGE("End Debug stats of mesh ");
2093
2094   //#ifdef DEB
2095
2096   SMDS_NodeIteratorPtr itnode=nodesIterator();
2097   int sizeofnodes = 0;
2098   int sizeoffaces = 0;
2099
2100   while(itnode->more())
2101   {
2102     const SMDS_MeshNode *node = itnode->next();
2103
2104     sizeofnodes += sizeof(*node);
2105
2106     SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2107     while(it->more())
2108     {
2109       const SMDS_MeshElement *me = it->next();
2110       sizeofnodes += sizeof(me);
2111     }
2112   }
2113
2114   SMDS_FaceIteratorPtr itface=facesIterator();
2115   while(itface->more())
2116   {
2117     const SMDS_MeshElement *face = itface->next();
2118     sizeoffaces += sizeof(*face);
2119   }
2120
2121   MESSAGE("total size of node elements = " << sizeofnodes);;
2122   MESSAGE("total size of face elements = " << sizeoffaces);;
2123
2124   //#endif
2125 }
2126
2127 ///////////////////////////////////////////////////////////////////////////////
2128 /// Return the number of nodes
2129 ///////////////////////////////////////////////////////////////////////////////
2130 int SMDS_Mesh::NbNodes() const
2131 {
2132         return myNodes.size();
2133 }
2134
2135 ///////////////////////////////////////////////////////////////////////////////
2136 /// Return the number of 0D elements
2137 ///////////////////////////////////////////////////////////////////////////////
2138 int SMDS_Mesh::Nb0DElements() const
2139 {
2140   return myInfo.Nb0DElements(); // -PR- a verfier
2141 }
2142
2143 ///////////////////////////////////////////////////////////////////////////////
2144 /// Return the number of edges (including construction edges)
2145 ///////////////////////////////////////////////////////////////////////////////
2146 int SMDS_Mesh::NbEdges() const
2147 {
2148         return myInfo.NbEdges(); // -PR- a verfier
2149 }
2150
2151 ///////////////////////////////////////////////////////////////////////////////
2152 /// Return the number of faces (including construction faces)
2153 ///////////////////////////////////////////////////////////////////////////////
2154 int SMDS_Mesh::NbFaces() const
2155 {
2156         return myInfo.NbFaces();  // -PR- a verfier
2157 }
2158
2159 ///////////////////////////////////////////////////////////////////////////////
2160 /// Return the number of volumes
2161 ///////////////////////////////////////////////////////////////////////////////
2162 int SMDS_Mesh::NbVolumes() const
2163 {
2164         return myInfo.NbVolumes(); // -PR- a verfier
2165 }
2166
2167 ///////////////////////////////////////////////////////////////////////////////
2168 /// Return the number of child mesh of this mesh.
2169 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2170 /// (2003-09-08) of SMESH
2171 ///////////////////////////////////////////////////////////////////////////////
2172 int SMDS_Mesh::NbSubMesh() const
2173 {
2174         return myChildren.size();
2175 }
2176
2177 ///////////////////////////////////////////////////////////////////////////////
2178 /// Destroy the mesh and all its elements
2179 /// All pointer on elements owned by this mesh become illegals.
2180 ///////////////////////////////////////////////////////////////////////////////
2181 SMDS_Mesh::~SMDS_Mesh()
2182 {
2183   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2184   while(itc!=myChildren.end())
2185   {
2186     delete *itc;
2187     itc++;
2188   }
2189
2190   if(myParent==NULL)
2191   {
2192     delete myNodeIDFactory;
2193     delete myElementIDFactory;
2194   }
2195   else
2196   {
2197     SMDS_ElemIteratorPtr eIt = elementsIterator();
2198     while ( eIt->more() )
2199       myElementIDFactory->ReleaseID(eIt->next()->GetID());
2200     SMDS_NodeIteratorPtr itn = nodesIterator();
2201     while (itn->more())
2202       myNodeIDFactory->ReleaseID(itn->next()->GetID());
2203   }
2204
2205 //   SetOfNodes::Iterator itn(myNodes);
2206 //   for (; itn.More(); itn.Next())
2207 //     delete itn.Value();
2208
2209 //   SetOf0DElements::Iterator it0d (my0DElements);
2210 //   for (; it0d.More(); it0d.Next())
2211 //   {
2212 //     SMDS_MeshElement* elem = it0d.Value();
2213 //     delete elem;
2214 //   }
2215
2216 //   SetOfEdges::Iterator ite(myEdges);
2217 //   for (; ite.More(); ite.Next())
2218 //   {
2219 //     SMDS_MeshElement* elem = ite.Value();
2220 //     delete elem;
2221 //   }
2222
2223 //   SetOfFaces::Iterator itf(myFaces);
2224 //   for (; itf.More(); itf.Next())
2225 //   {
2226 //     SMDS_MeshElement* elem = itf.Value();
2227 //     delete elem;
2228 //   }
2229
2230 //   SetOfVolumes::Iterator itv(myVolumes);
2231 //   for (; itv.More(); itv.Next())
2232 //   {
2233 //     SMDS_MeshElement* elem = itv.Value();
2234 //     delete elem;
2235 //   }
2236 }
2237
2238 //================================================================================
2239 /*!
2240  * \brief Clear all data
2241  */
2242 //================================================================================
2243
2244 void SMDS_Mesh::Clear()
2245 {
2246   if (myParent!=NULL) {
2247     SMDS_ElemIteratorPtr eIt = elementsIterator();
2248     while ( eIt->more() )
2249       myElementIDFactory->ReleaseID(eIt->next()->GetID());
2250     SMDS_NodeIteratorPtr itn = nodesIterator();
2251     while (itn->more())
2252       myNodeIDFactory->ReleaseID(itn->next()->GetID());
2253   }
2254   else {
2255     myNodeIDFactory->Clear();
2256     myElementIDFactory->Clear();
2257   }
2258
2259   SMDS_ElemIteratorPtr itv = elementsIterator();
2260   while (itv->more())
2261     delete itv->next();
2262   myCells.clear();
2263
2264 //  SMDS_VolumeIteratorPtr itv = volumesIterator();
2265 //  while (itv->more())
2266 //    delete itv->next();
2267 //  myVolumes.Clear();
2268 //
2269 //  SMDS_FaceIteratorPtr itf = facesIterator();
2270 //  while (itf->more())
2271 //    delete itf->next();
2272 //  myFaces.Clear();
2273 //
2274 //  SMDS_EdgeIteratorPtr ite = edgesIterator();
2275 //  while (ite->more())
2276 //    delete ite->next();
2277 //  myEdges.Clear();
2278 //
2279 //  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2280 //  while (it0d->more())
2281 //    delete it0d->next();
2282 //  my0DElements.Clear();
2283
2284   SMDS_NodeIteratorPtr itn = nodesIterator();
2285   while (itn->more())
2286     delete itn->next();
2287   myNodes.clear();
2288
2289   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2290   while(itc!=myChildren.end())
2291     (*itc)->Clear();
2292
2293   myInfo.Clear();
2294 }
2295
2296 ///////////////////////////////////////////////////////////////////////////////
2297 /// Return true if this mesh create faces with edges.
2298 /// A false returned value mean that faces are created with nodes. A concequence
2299 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2300 ///////////////////////////////////////////////////////////////////////////////
2301 bool SMDS_Mesh::hasConstructionEdges()
2302 {
2303         return myHasConstructionEdges;
2304 }
2305
2306 ///////////////////////////////////////////////////////////////////////////////
2307 /// Return true if this mesh create volumes with faces
2308 /// A false returned value mean that volumes are created with nodes or edges.
2309 /// (see hasConstructionEdges)
2310 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2311 /// unavailable.
2312 ///////////////////////////////////////////////////////////////////////////////
2313 bool SMDS_Mesh::hasConstructionFaces()
2314 {
2315         return myHasConstructionFaces;
2316 }
2317
2318 ///////////////////////////////////////////////////////////////////////////////
2319 /// Return true if nodes are linked to the finit elements, they are belonging to.
2320 /// Currently, It always return true.
2321 ///////////////////////////////////////////////////////////////////////////////
2322 bool SMDS_Mesh::hasInverseElements()
2323 {
2324         return myHasInverseElements;
2325 }
2326
2327 ///////////////////////////////////////////////////////////////////////////////
2328 /// Make this mesh creating construction edges (see hasConstructionEdges)
2329 /// @param b true to have construction edges, else false.
2330 ///////////////////////////////////////////////////////////////////////////////
2331 void SMDS_Mesh::setConstructionEdges(bool b)
2332 {
2333         myHasConstructionEdges=b;
2334 }
2335
2336 ///////////////////////////////////////////////////////////////////////////////
2337 /// Make this mesh creating construction faces (see hasConstructionFaces)
2338 /// @param b true to have construction faces, else false.
2339 ///////////////////////////////////////////////////////////////////////////////
2340 void SMDS_Mesh::setConstructionFaces(bool b)
2341 {
2342          myHasConstructionFaces=b;
2343 }
2344
2345 ///////////////////////////////////////////////////////////////////////////////
2346 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2347 /// @param b true to link nodes to elements, else false.
2348 ///////////////////////////////////////////////////////////////////////////////
2349 void SMDS_Mesh::setInverseElements(bool b)
2350 {
2351         if(!b) MESSAGE("Error : inverseElement=false not implemented");
2352         myHasInverseElements=b;
2353 }
2354
2355 ///////////////////////////////////////////////////////////////////////////////
2356 ///Iterator on NCollection_Map
2357 ///////////////////////////////////////////////////////////////////////////////
2358 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2359 struct MYNode_Map_Iterator: public FATHER
2360 {
2361   int _ctr;
2362   const MAP& _map;
2363   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2364   {
2365       _ctr = 0;
2366   }
2367
2368   bool more()
2369   {
2370       while (_ctr < _map.size())
2371       {
2372           if (_map[_ctr])
2373               return true;
2374           _ctr++;
2375       }
2376           return false;
2377   }
2378
2379   ELEM next()
2380   {
2381     ELEM current = _map[_ctr];
2382     _ctr++;
2383     return current;
2384   }
2385 };
2386
2387 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2388 struct MYElem_Map_Iterator: public FATHER
2389 {
2390   int _ctr;
2391   int _type;
2392   const MAP& _map;
2393   MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2394   {
2395       _ctr = 0;
2396       _type = typ;
2397   }
2398
2399   bool more()
2400   {
2401       while (_ctr < _map.size())
2402       {
2403           if (_map[_ctr])
2404             if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2405               return true;
2406           _ctr++;
2407       }
2408           return false;
2409   }
2410
2411   ELEM next()
2412   {
2413     ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2414     _ctr++;
2415     return current;
2416   }
2417 };
2418
2419 ///////////////////////////////////////////////////////////////////////////////
2420 /// Return an iterator on nodes of the current mesh factory
2421 ///////////////////////////////////////////////////////////////////////////////
2422
2423 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2424 {
2425   //return SMDS_NodeIteratorPtr
2426   //  (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2427   typedef MYNode_Map_Iterator
2428     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2429   return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2430 }
2431
2432 ///////////////////////////////////////////////////////////////////////////////
2433 ///Return an iterator on 0D elements of the current mesh.
2434 ///////////////////////////////////////////////////////////////////////////////
2435
2436 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2437 {
2438   typedef MYElem_Map_Iterator
2439     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2440   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2441 }
2442
2443 ///////////////////////////////////////////////////////////////////////////////
2444 ///Return an iterator on edges of the current mesh.
2445 ///////////////////////////////////////////////////////////////////////////////
2446
2447 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2448 {
2449   typedef MYElem_Map_Iterator
2450     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2451   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2452 }
2453
2454 ///////////////////////////////////////////////////////////////////////////////
2455 ///Return an iterator on faces of the current mesh.
2456 ///////////////////////////////////////////////////////////////////////////////
2457
2458 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2459 {
2460   typedef MYElem_Map_Iterator
2461     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2462   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2463 }
2464
2465 ///////////////////////////////////////////////////////////////////////////////
2466 ///Return an iterator on volumes of the current mesh.
2467 ///////////////////////////////////////////////////////////////////////////////
2468
2469 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2470 {
2471   typedef MYElem_Map_Iterator
2472     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2473   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2474 }
2475
2476 ///////////////////////////////////////////////////////////////////////////////
2477 /// Return an iterator on elements of the current mesh factory
2478 ///////////////////////////////////////////////////////////////////////////////
2479 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2480 {
2481   switch (type) {
2482   case SMDSAbs_All:
2483     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2484     break;
2485   case SMDSAbs_Volume:
2486     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2487   case SMDSAbs_Face:
2488     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2489   case SMDSAbs_Edge:
2490     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2491   case SMDSAbs_0DElement:
2492     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2493   case SMDSAbs_Node:
2494     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2495     //return myNodeIDFactory->elementsIterator();
2496   default:;
2497   }
2498   return myElementIDFactory->elementsIterator();
2499 }
2500
2501 ///////////////////////////////////////////////////////////////////////////////
2502 /// Do intersection of sets (more than 2)
2503 ///////////////////////////////////////////////////////////////////////////////
2504 static set<const SMDS_MeshElement*> * intersectionOfSets(
2505         set<const SMDS_MeshElement*> vs[], int numberOfSets)
2506 {
2507         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2508         set<const SMDS_MeshElement*>* rsetB;
2509
2510         for(int i=0; i<numberOfSets-1; i++)
2511         {
2512                 rsetB=new set<const SMDS_MeshElement*>();
2513                 set_intersection(
2514                         rsetA->begin(), rsetA->end(),
2515                         vs[i+1].begin(), vs[i+1].end(),
2516                         inserter(*rsetB, rsetB->begin()));
2517                 delete rsetA;
2518                 rsetA=rsetB;
2519         }
2520         return rsetA;
2521 }
2522
2523 ///////////////////////////////////////////////////////////////////////////////
2524 /// Return the list of finite elements owning the given element: elements
2525 /// containing all the nodes of the given element, for instance faces and
2526 /// volumes containing a given edge.
2527 ///////////////////////////////////////////////////////////////////////////////
2528 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2529 {
2530         int numberOfSets=element->NbNodes();
2531         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2532
2533         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2534
2535         int i=0;
2536         while(itNodes->more())
2537         {
2538           const SMDS_MeshElement* node = itNodes->next();
2539           MYASSERT(node);
2540                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2541                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2542
2543                 //initSet[i]=set<const SMDS_MeshElement*>();
2544                 while(itFe->more())
2545                 {
2546                   const SMDS_MeshElement* elem = itFe->next();
2547                   MYASSERT(elem);
2548                   initSet[i].insert(elem);
2549
2550                 }
2551
2552                 i++;
2553         }
2554         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2555         MESSAGE("nb elems " << i << " intersection " << retSet->size());
2556         delete [] initSet;
2557         return retSet;
2558 }
2559
2560 ///////////////////////////////////////////////////////////////////////////////
2561 /// Return the list of nodes used only by the given elements
2562 ///////////////////////////////////////////////////////////////////////////////
2563 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2564         set<const SMDS_MeshElement*>& elements)
2565 {
2566         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2567         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2568
2569         while(itElements!=elements.end())
2570         {
2571                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2572                 itElements++;
2573
2574                 while(itNodes->more())
2575                 {
2576                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2577                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2578                         set<const SMDS_MeshElement*> s;
2579                         while(itFe->more())
2580                           s.insert(itFe->next());
2581                         if(s==elements) toReturn->insert(n);
2582                 }
2583         }
2584         return toReturn;
2585 }
2586
2587 ///////////////////////////////////////////////////////////////////////////////
2588 ///Find the children of an element that are made of given nodes
2589 ///@param setOfChildren The set in which matching children will be inserted
2590 ///@param element The element were to search matching children
2591 ///@param nodes The nodes that the children must have to be selected
2592 ///////////////////////////////////////////////////////////////////////////////
2593 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2594                                      const SMDS_MeshElement *      element,
2595                                      set<const SMDS_MeshElement*>& nodes)
2596 {
2597   switch(element->GetType())
2598     {
2599     case SMDSAbs_Node:
2600       MESSAGE("Internal Error: This should not happend");
2601       break;
2602     case SMDSAbs_0DElement:
2603       {
2604       }
2605       break;
2606     case SMDSAbs_Edge:
2607         {
2608                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2609                 while(itn->more())
2610                 {
2611                         const SMDS_MeshElement * e=itn->next();
2612                         if(nodes.find(e)!=nodes.end())
2613                         {
2614                           setOfChildren.insert(element);
2615                           break;
2616                         }
2617                 }
2618         } break;
2619     case SMDSAbs_Face:
2620         {
2621                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2622                 while(itn->more())
2623                 {
2624                         const SMDS_MeshElement * e=itn->next();
2625                         if(nodes.find(e)!=nodes.end())
2626                         {
2627                           setOfChildren.insert(element);
2628                           break;
2629                         }
2630                 }
2631                 if(hasConstructionEdges())
2632                 {
2633                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2634                         while(ite->more())
2635                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2636                 }
2637         } break;
2638     case SMDSAbs_Volume:
2639         {
2640                 if(hasConstructionFaces())
2641                 {
2642                         SMDS_ElemIteratorPtr ite=element->facesIterator();
2643                         while(ite->more())
2644                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2645                 }
2646                 else if(hasConstructionEdges())
2647                 {
2648                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2649                         while(ite->more())
2650                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2651                 }
2652         }
2653     }
2654 }
2655
2656 ///////////////////////////////////////////////////////////////////////////////
2657 ///@param elem The element to delete
2658 ///@param removenodes if true remaining nodes will be removed
2659 ///////////////////////////////////////////////////////////////////////////////
2660 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2661                               const bool removenodes)
2662 {
2663   list<const SMDS_MeshElement *> removedElems;
2664   list<const SMDS_MeshElement *> removedNodes;
2665   RemoveElement( elem, removedElems, removedNodes, removenodes );
2666 }
2667
2668 ///////////////////////////////////////////////////////////////////////////////
2669 ///@param elem The element to delete
2670 ///@param removedElems to be filled with all removed elements
2671 ///@param removedNodes to be filled with all removed nodes
2672 ///@param removenodes if true remaining nodes will be removed
2673 ///////////////////////////////////////////////////////////////////////////////
2674 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
2675                               list<const SMDS_MeshElement *>& removedElems,
2676                               list<const SMDS_MeshElement *>& removedNodes,
2677                               bool                            removenodes)
2678 {
2679   MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2680   // get finite elements built on elem
2681   set<const SMDS_MeshElement*> * s1;
2682   if (elem->GetType() == SMDSAbs_0DElement ||
2683       elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2684       elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2685       elem->GetType() == SMDSAbs_Volume)
2686   {
2687     s1 = new set<const SMDS_MeshElement*>();
2688     s1->insert(elem);
2689   }
2690   else
2691     s1 = getFinitElements(elem);
2692
2693   // get exclusive nodes (which would become free afterwards)
2694   set<const SMDS_MeshElement*> * s2;
2695   if (elem->GetType() == SMDSAbs_Node) // a node is removed
2696   {
2697     // do not remove nodes except elem
2698     s2 = new set<const SMDS_MeshElement*>();
2699     s2->insert(elem);
2700     removenodes = true;
2701   }
2702   else
2703     s2 = getExclusiveNodes(*s1);
2704
2705   // form the set of finite and construction elements to remove
2706   set<const SMDS_MeshElement*> s3;
2707   set<const SMDS_MeshElement*>::iterator it=s1->begin();
2708   while(it!=s1->end())
2709   {
2710     addChildrenWithNodes(s3, *it ,*s2);
2711     s3.insert(*it);
2712     it++;
2713   }
2714   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2715
2716   // remove finite and construction elements
2717   it=s3.begin();
2718   while(it!=s3.end())
2719   {
2720     // Remove element from <InverseElements> of its nodes
2721     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2722     while(itn->more())
2723     {
2724       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2725         (const_cast<SMDS_MeshElement *>(itn->next()));
2726       n->RemoveInverseElement( (*it) );
2727     }
2728
2729     switch((*it)->GetType())
2730     {
2731     case SMDSAbs_Node:
2732       MYASSERT("Internal Error: This should not happen");
2733       break;
2734     case SMDSAbs_0DElement:
2735       myCells[(*it)->GetID()] = 0;  // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2736       myInfo.remove(*it);
2737       break;
2738     case SMDSAbs_Edge:
2739       myCells[(*it)->GetID()] = 0;
2740       myInfo.RemoveEdge(*it);
2741       break;
2742     case SMDSAbs_Face:
2743       myCells[(*it)->GetID()] = 0;
2744       myInfo.RemoveFace(*it);
2745       break;
2746     case SMDSAbs_Volume:
2747       myCells[(*it)->GetID()] = 0;
2748       myInfo.RemoveVolume(*it);
2749       break;
2750     }
2751     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2752     removedElems.push_back( (*it) );
2753     myElementIDFactory->ReleaseID((*it)->GetID());
2754     MYASSERT("problem delete elem")
2755     delete (*it);
2756     it++;
2757   }
2758
2759   // remove exclusive (free) nodes
2760   if(removenodes)
2761   {
2762     it=s2->begin();
2763     while(it!=s2->end())
2764     {
2765       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2766       myNodes[(*it)->GetID()] = 0;
2767       myInfo.myNbNodes--;
2768       myNodeIDFactory->ReleaseID((*it)->GetID());
2769       removedNodes.push_back( (*it) );
2770       MYASSERT("problem delete node")
2771       delete *it;
2772       it++;
2773     }
2774   }
2775
2776   delete s2;
2777   delete s1;
2778 }
2779
2780
2781 ///////////////////////////////////////////////////////////////////////////////
2782 ///@param elem The element to delete
2783 ///////////////////////////////////////////////////////////////////////////////
2784 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2785 {
2786   int elemId = elem->GetID();
2787   MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2788   SMDSAbs_ElementType aType = elem->GetType();
2789   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2790   if (aType == SMDSAbs_Node) {
2791     // only free node can be removed by this method
2792     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2793     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2794     if (!itFe->more()) { // free node
2795       myNodes[elemId] = 0;
2796       myInfo.myNbNodes--;
2797       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2798       myNodeIDFactory->ReleaseID(elemId);
2799     }
2800   } else {
2801     if (hasConstructionEdges() || hasConstructionFaces())
2802       // this methods is only for meshes without descendants
2803       return;
2804
2805     int vtkid = this->fromSmdsToVtk(elemId);
2806
2807     // Remove element from <InverseElements> of its nodes
2808     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2809     while (itn->more()) {
2810       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2811         (const_cast<SMDS_MeshElement *>(itn->next()));
2812       n->RemoveInverseElement(elem);
2813     }
2814
2815     // in meshes without descendants elements are always free
2816      switch (aType) {
2817     case SMDSAbs_0DElement:
2818       myCells[elemId] = 0;
2819       myInfo.remove(elem);
2820       delete elem;
2821       break;
2822     case SMDSAbs_Edge:
2823       myCells[elemId] = 0;
2824       myInfo.RemoveEdge(elem);
2825       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2826       break;
2827     case SMDSAbs_Face:
2828       myCells[elemId] = 0;
2829       myInfo.RemoveFace(elem);
2830       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2831       break;
2832     case SMDSAbs_Volume:
2833       myCells[elemId] = 0;
2834       myInfo.RemoveVolume(elem);
2835       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2836       break;
2837     default:
2838       break;
2839     }
2840     myElementIDFactory->ReleaseID(elemId);
2841
2842     this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2843     // --- to do: keep vtkid in a list of reusable cells
2844   }
2845 }
2846
2847 /*!
2848  * Checks if the element is present in mesh.
2849  * Useful to determine dead pointers.
2850  */
2851 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2852 {
2853   // we should not imply on validity of *elem, so iterate on containers
2854   // of all types in the hope of finding <elem> somewhere there
2855   SMDS_NodeIteratorPtr itn = nodesIterator();
2856   while (itn->more())
2857     if (elem == itn->next())
2858       return true;
2859   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2860   while (it0d->more())
2861     if (elem == it0d->next())
2862       return true;
2863   SMDS_EdgeIteratorPtr ite = edgesIterator();
2864   while (ite->more())
2865     if (elem == ite->next())
2866       return true;
2867   SMDS_FaceIteratorPtr itf = facesIterator();
2868   while (itf->more())
2869     if (elem == itf->next())
2870       return true;
2871   SMDS_VolumeIteratorPtr itv = volumesIterator();
2872   while (itv->more())
2873     if (elem == itv->next())
2874       return true;
2875   return false;
2876 }
2877
2878 //=======================================================================
2879 //function : MaxNodeID
2880 //purpose  :
2881 //=======================================================================
2882
2883 int SMDS_Mesh::MaxNodeID() const
2884 {
2885   return myNodeMax;
2886 }
2887
2888 //=======================================================================
2889 //function : MinNodeID
2890 //purpose  :
2891 //=======================================================================
2892
2893 int SMDS_Mesh::MinNodeID() const
2894 {
2895   return myNodeMin;
2896 }
2897
2898 //=======================================================================
2899 //function : MaxElementID
2900 //purpose  :
2901 //=======================================================================
2902
2903 int SMDS_Mesh::MaxElementID() const
2904 {
2905   return myElementIDFactory->GetMaxID();
2906 }
2907
2908 //=======================================================================
2909 //function : MinElementID
2910 //purpose  :
2911 //=======================================================================
2912
2913 int SMDS_Mesh::MinElementID() const
2914 {
2915   return myElementIDFactory->GetMinID();
2916 }
2917
2918 //=======================================================================
2919 //function : Renumber
2920 //purpose  : Renumber all nodes or elements.
2921 //=======================================================================
2922
2923 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
2924 {
2925     MESSAGE("Renumber");
2926   if ( deltaID == 0 )
2927     return;
2928
2929   SMDS_MeshNodeIDFactory * idFactory =
2930     isNodes ? myNodeIDFactory : myElementIDFactory;
2931
2932   // get existing elements in the order of ID increasing
2933   map<int,SMDS_MeshElement*> elemMap;
2934   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2935   while ( idElemIt->more() ) {
2936     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2937     int id = elem->GetID();
2938     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2939   }
2940   // release their ids
2941   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2942   idFactory->Clear();
2943 //   for ( ; elemIt != elemMap.end(); elemIt++ )
2944 //   {
2945 //     int id = (*elemIt).first;
2946 //     idFactory->ReleaseID( id );
2947 //   }
2948   // set new IDs
2949   int ID = startID;
2950   elemIt = elemMap.begin();
2951   for ( ; elemIt != elemMap.end(); elemIt++ )
2952   {
2953     idFactory->BindID( ID, (*elemIt).second );
2954     ID += deltaID;
2955   }
2956 }
2957
2958 //=======================================================================
2959 //function : GetElementType
2960 //purpose  : Return type of element or node with id
2961 //=======================================================================
2962
2963 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2964 {
2965   SMDS_MeshElement* elem = 0;
2966   if( iselem )
2967     elem = myElementIDFactory->MeshElement( id );
2968   else
2969     elem = myNodeIDFactory->MeshElement( id );
2970
2971   if( !elem )
2972   {
2973     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2974     return SMDSAbs_All;
2975   }
2976   else
2977     return elem->GetType();
2978 }
2979
2980
2981
2982 //********************************************************************
2983 //********************************************************************
2984 //********                                                   *********
2985 //*****       Methods for addition of quadratic elements        ******
2986 //********                                                   *********
2987 //********************************************************************
2988 //********************************************************************
2989
2990 //=======================================================================
2991 //function : AddEdgeWithID
2992 //purpose  :
2993 //=======================================================================
2994 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
2995 {
2996   return SMDS_Mesh::AddEdgeWithID
2997     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2998      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2999      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3000      ID);
3001 }
3002
3003 //=======================================================================
3004 //function : AddEdge
3005 //purpose  :
3006 //=======================================================================
3007 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3008                                   const SMDS_MeshNode* n2,
3009                                   const SMDS_MeshNode* n12)
3010 {
3011   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3012 }
3013
3014 //=======================================================================
3015 //function : AddEdgeWithID
3016 //purpose  :
3017 //=======================================================================
3018 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3019                                         const SMDS_MeshNode * n2,
3020                                         const SMDS_MeshNode * n12,
3021                                         int ID)
3022 {
3023   if ( !n1 || !n2 || !n12 ) return 0;
3024   SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
3025   if(myElementIDFactory->BindID(ID, edge)) {
3026     SMDS_MeshNode *node1,*node2, *node12;
3027     //node1 = const_cast<SMDS_MeshNode*>(n1);
3028     //node2 = const_cast<SMDS_MeshNode*>(n2);
3029     //node12 = const_cast<SMDS_MeshNode*>(n12);
3030     //node1->AddInverseElement(edge); // --- fait avec BindID
3031     //node2->AddInverseElement(edge);
3032     //node12->AddInverseElement(edge);
3033     adjustmyCellsCapacity(ID);
3034     myCells[ID] = edge;
3035     myInfo.myNbQuadEdges++;
3036     return edge;
3037   }
3038   else {
3039     delete edge;
3040     return NULL;
3041   }
3042 }
3043
3044
3045 //=======================================================================
3046 //function : AddFace
3047 //purpose  :
3048 //=======================================================================
3049 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3050                                   const SMDS_MeshNode * n2,
3051                                   const SMDS_MeshNode * n3,
3052                                   const SMDS_MeshNode * n12,
3053                                   const SMDS_MeshNode * n23,
3054                                   const SMDS_MeshNode * n31)
3055 {
3056   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3057                                   myElementIDFactory->GetFreeID());
3058 }
3059
3060 //=======================================================================
3061 //function : AddFaceWithID
3062 //purpose  :
3063 //=======================================================================
3064 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3065                                         int n12,int n23,int n31, int ID)
3066 {
3067   return SMDS_Mesh::AddFaceWithID
3068     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3069      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3070      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3071      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3072      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3073      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3074      ID);
3075 }
3076
3077 //=======================================================================
3078 //function : AddFaceWithID
3079 //purpose  :
3080 //=======================================================================
3081 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3082                                         const SMDS_MeshNode * n2,
3083                                         const SMDS_MeshNode * n3,
3084                                         const SMDS_MeshNode * n12,
3085                                         const SMDS_MeshNode * n23,
3086                                         const SMDS_MeshNode * n31,
3087                                         int ID)
3088 {
3089   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3090   if(hasConstructionEdges()) {
3091     // creation quadratic edges - not implemented
3092     return 0;
3093   }
3094   SMDS_QuadraticFaceOfNodes* face =
3095     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
3096     adjustmyCellsCapacity(ID);
3097   myCells[ID] = face;
3098   myInfo.myNbQuadTriangles++;
3099
3100   if (!registerElement(ID, face)) {
3101     RemoveElement(face, false);
3102     face = NULL;
3103   }
3104   return face;
3105 }
3106
3107
3108 //=======================================================================
3109 //function : AddFace
3110 //purpose  :
3111 //=======================================================================
3112 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3113                                   const SMDS_MeshNode * n2,
3114                                   const SMDS_MeshNode * n3,
3115                                   const SMDS_MeshNode * n4,
3116                                   const SMDS_MeshNode * n12,
3117                                   const SMDS_MeshNode * n23,
3118                                   const SMDS_MeshNode * n34,
3119                                   const SMDS_MeshNode * n41)
3120 {
3121   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3122                                   myElementIDFactory->GetFreeID());
3123 }
3124
3125 //=======================================================================
3126 //function : AddFaceWithID
3127 //purpose  :
3128 //=======================================================================
3129 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3130                                         int n12,int n23,int n34,int n41, int ID)
3131 {
3132   return SMDS_Mesh::AddFaceWithID
3133     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3134      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3135      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3136      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3137      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3138      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3139      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3140      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3141      ID);
3142 }
3143
3144 //=======================================================================
3145 //function : AddFaceWithID
3146 //purpose  :
3147 //=======================================================================
3148 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3149                                         const SMDS_MeshNode * n2,
3150                                         const SMDS_MeshNode * n3,
3151                                         const SMDS_MeshNode * n4,
3152                                         const SMDS_MeshNode * n12,
3153                                         const SMDS_MeshNode * n23,
3154                                         const SMDS_MeshNode * n34,
3155                                         const SMDS_MeshNode * n41,
3156                                         int ID)
3157 {
3158   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3159   if(hasConstructionEdges()) {
3160     // creation quadratic edges - not implemented
3161   }
3162   SMDS_QuadraticFaceOfNodes* face =
3163     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
3164     adjustmyCellsCapacity(ID);
3165   myCells[ID] = face;
3166   myInfo.myNbQuadQuadrangles++;
3167
3168   if (!registerElement(ID, face)) {
3169     RemoveElement(face, false);
3170     face = NULL;
3171   }
3172   return face;
3173 }
3174
3175
3176 //=======================================================================
3177 //function : AddVolume
3178 //purpose  :
3179 //=======================================================================
3180 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3181                                       const SMDS_MeshNode * n2,
3182                                       const SMDS_MeshNode * n3,
3183                                       const SMDS_MeshNode * n4,
3184                                       const SMDS_MeshNode * n12,
3185                                       const SMDS_MeshNode * n23,
3186                                       const SMDS_MeshNode * n31,
3187                                       const SMDS_MeshNode * n14,
3188                                       const SMDS_MeshNode * n24,
3189                                       const SMDS_MeshNode * n34)
3190 {
3191   int ID = myElementIDFactory->GetFreeID();
3192   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3193                                                    n31, n14, n24, n34, ID);
3194   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3195   return v;
3196 }
3197
3198 //=======================================================================
3199 //function : AddVolumeWithID
3200 //purpose  :
3201 //=======================================================================
3202 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3203                                             int n12,int n23,int n31,
3204                                             int n14,int n24,int n34, int ID)
3205 {
3206   return SMDS_Mesh::AddVolumeWithID
3207     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3208      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3209      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3210      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3211      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3212      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3213      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3214      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3215      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3216      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3217      ID);
3218 }
3219
3220 //=======================================================================
3221 //function : AddVolumeWithID
3222 //purpose  : 2d order tetrahedron of 10 nodes
3223 //=======================================================================
3224 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3225                                             const SMDS_MeshNode * n2,
3226                                             const SMDS_MeshNode * n3,
3227                                             const SMDS_MeshNode * n4,
3228                                             const SMDS_MeshNode * n12,
3229                                             const SMDS_MeshNode * n23,
3230                                             const SMDS_MeshNode * n31,
3231                                             const SMDS_MeshNode * n14,
3232                                             const SMDS_MeshNode * n24,
3233                                             const SMDS_MeshNode * n34,
3234                                             int ID)
3235 {
3236   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3237     return 0;
3238   if(hasConstructionFaces()) {
3239     // creation quadratic faces - not implemented
3240     return 0;
3241   }
3242   SMDS_QuadraticVolumeOfNodes * volume =
3243     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
3244     adjustmyCellsCapacity(ID);
3245   myCells[ID] = volume;
3246   myInfo.myNbQuadTetras++;
3247
3248   if (!registerElement(ID, volume)) {
3249     RemoveElement(volume, false);
3250     volume = NULL;
3251   }
3252   return volume;
3253 }
3254
3255
3256 //=======================================================================
3257 //function : AddVolume
3258 //purpose  :
3259 //=======================================================================
3260 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3261                                       const SMDS_MeshNode * n2,
3262                                       const SMDS_MeshNode * n3,
3263                                       const SMDS_MeshNode * n4,
3264                                       const SMDS_MeshNode * n5,
3265                                       const SMDS_MeshNode * n12,
3266                                       const SMDS_MeshNode * n23,
3267                                       const SMDS_MeshNode * n34,
3268                                       const SMDS_MeshNode * n41,
3269                                       const SMDS_MeshNode * n15,
3270                                       const SMDS_MeshNode * n25,
3271                                       const SMDS_MeshNode * n35,
3272                                       const SMDS_MeshNode * n45)
3273 {
3274   int ID = myElementIDFactory->GetFreeID();
3275   SMDS_MeshVolume * v =
3276     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3277                                n15, n25, n35, n45, ID);
3278   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3279   return v;
3280 }
3281
3282 //=======================================================================
3283 //function : AddVolumeWithID
3284 //purpose  :
3285 //=======================================================================
3286 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3287                                             int n12,int n23,int n34,int n41,
3288                                             int n15,int n25,int n35,int n45, int ID)
3289 {
3290   return SMDS_Mesh::AddVolumeWithID
3291     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3292      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3293      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3294      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3295      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3296      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3297      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3298      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3299      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3300      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3301      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3302      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3303      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3304      ID);
3305 }
3306
3307 //=======================================================================
3308 //function : AddVolumeWithID
3309 //purpose  : 2d order pyramid of 13 nodes
3310 //=======================================================================
3311 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3312                                             const SMDS_MeshNode * n2,
3313                                             const SMDS_MeshNode * n3,
3314                                             const SMDS_MeshNode * n4,
3315                                             const SMDS_MeshNode * n5,
3316                                             const SMDS_MeshNode * n12,
3317                                             const SMDS_MeshNode * n23,
3318                                             const SMDS_MeshNode * n34,
3319                                             const SMDS_MeshNode * n41,
3320                                             const SMDS_MeshNode * n15,
3321                                             const SMDS_MeshNode * n25,
3322                                             const SMDS_MeshNode * n35,
3323                                             const SMDS_MeshNode * n45,
3324                                             int ID)
3325 {
3326   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3327       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3328     return 0;
3329   if(hasConstructionFaces()) {
3330     // creation quadratic faces - not implemented
3331     return 0;
3332   }
3333   SMDS_QuadraticVolumeOfNodes * volume =
3334     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
3335                                     n34,n41,n15,n25,n35,n45);
3336     adjustmyCellsCapacity(ID);
3337   myCells[ID] = volume;
3338   myInfo.myNbQuadPyramids++;
3339
3340   if (!registerElement(ID, volume)) {
3341     RemoveElement(volume, false);
3342     volume = NULL;
3343   }
3344   return volume;
3345 }
3346
3347
3348 //=======================================================================
3349 //function : AddVolume
3350 //purpose  :
3351 //=======================================================================
3352 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3353                                       const SMDS_MeshNode * n2,
3354                                       const SMDS_MeshNode * n3,
3355                                       const SMDS_MeshNode * n4,
3356                                       const SMDS_MeshNode * n5,
3357                                       const SMDS_MeshNode * n6,
3358                                       const SMDS_MeshNode * n12,
3359                                       const SMDS_MeshNode * n23,
3360                                       const SMDS_MeshNode * n31,
3361                                       const SMDS_MeshNode * n45,
3362                                       const SMDS_MeshNode * n56,
3363                                       const SMDS_MeshNode * n64,
3364                                       const SMDS_MeshNode * n14,
3365                                       const SMDS_MeshNode * n25,
3366                                       const SMDS_MeshNode * n36)
3367 {
3368   int ID = myElementIDFactory->GetFreeID();
3369   SMDS_MeshVolume * v =
3370     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3371                                n45, n56, n64, n14, n25, n36, ID);
3372   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3373   return v;
3374 }
3375
3376 //=======================================================================
3377 //function : AddVolumeWithID
3378 //purpose  :
3379 //=======================================================================
3380 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3381                                             int n4, int n5, int n6,
3382                                             int n12,int n23,int n31,
3383                                             int n45,int n56,int n64,
3384                                             int n14,int n25,int n36, int ID)
3385 {
3386   return SMDS_Mesh::AddVolumeWithID
3387     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3388      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3389      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3390      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3391      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3392      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3393      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3394      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3395      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3396      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3397      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3398      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3399      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3400      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3401      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3402      ID);
3403 }
3404
3405 //=======================================================================
3406 //function : AddVolumeWithID
3407 //purpose  : 2d order Pentahedron with 15 nodes
3408 //=======================================================================
3409 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3410                                             const SMDS_MeshNode * n2,
3411                                             const SMDS_MeshNode * n3,
3412                                             const SMDS_MeshNode * n4,
3413                                             const SMDS_MeshNode * n5,
3414                                             const SMDS_MeshNode * n6,
3415                                             const SMDS_MeshNode * n12,
3416                                             const SMDS_MeshNode * n23,
3417                                             const SMDS_MeshNode * n31,
3418                                             const SMDS_MeshNode * n45,
3419                                             const SMDS_MeshNode * n56,
3420                                             const SMDS_MeshNode * n64,
3421                                             const SMDS_MeshNode * n14,
3422                                             const SMDS_MeshNode * n25,
3423                                             const SMDS_MeshNode * n36,
3424                                             int ID)
3425 {
3426   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3427       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3428     return 0;
3429   if(hasConstructionFaces()) {
3430     // creation quadratic faces - not implemented
3431     return 0;
3432   }
3433   SMDS_QuadraticVolumeOfNodes * volume =
3434     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
3435                                     n45,n56,n64,n14,n25,n36);
3436     adjustmyCellsCapacity(ID);
3437   myCells[ID] = volume;
3438   myInfo.myNbQuadPrisms++;
3439
3440   if (!registerElement(ID, volume)) {
3441     RemoveElement(volume, false);
3442     volume = NULL;
3443   }
3444   return volume;
3445 }
3446
3447
3448 //=======================================================================
3449 //function : AddVolume
3450 //purpose  :
3451 //=======================================================================
3452 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3453                                       const SMDS_MeshNode * n2,
3454                                       const SMDS_MeshNode * n3,
3455                                       const SMDS_MeshNode * n4,
3456                                       const SMDS_MeshNode * n5,
3457                                       const SMDS_MeshNode * n6,
3458                                       const SMDS_MeshNode * n7,
3459                                       const SMDS_MeshNode * n8,
3460                                       const SMDS_MeshNode * n12,
3461                                       const SMDS_MeshNode * n23,
3462                                       const SMDS_MeshNode * n34,
3463                                       const SMDS_MeshNode * n41,
3464                                       const SMDS_MeshNode * n56,
3465                                       const SMDS_MeshNode * n67,
3466                                       const SMDS_MeshNode * n78,
3467                                       const SMDS_MeshNode * n85,
3468                                       const SMDS_MeshNode * n15,
3469                                       const SMDS_MeshNode * n26,
3470                                       const SMDS_MeshNode * n37,
3471                                       const SMDS_MeshNode * n48)
3472 {
3473   int ID = myElementIDFactory->GetFreeID();
3474   SMDS_MeshVolume * v =
3475     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3476                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
3477   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3478   return v;
3479 }
3480
3481 //=======================================================================
3482 //function : AddVolumeWithID
3483 //purpose  :
3484 //=======================================================================
3485 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3486                                             int n5, int n6, int n7, int n8,
3487                                             int n12,int n23,int n34,int n41,
3488                                             int n56,int n67,int n78,int n85,
3489                                             int n15,int n26,int n37,int n48, int ID)
3490 {
3491   return SMDS_Mesh::AddVolumeWithID
3492     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3493      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3494      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3495      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3496      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3497      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3498      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3499      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3500      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3501      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3502      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3503      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3504      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3505      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3506      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3507      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3508      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3509      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3510      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3511      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3512      ID);
3513 }
3514
3515 //=======================================================================
3516 //function : AddVolumeWithID
3517 //purpose  : 2d order Hexahedrons with 20 nodes
3518 //=======================================================================
3519 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3520                                             const SMDS_MeshNode * n2,
3521                                             const SMDS_MeshNode * n3,
3522                                             const SMDS_MeshNode * n4,
3523                                             const SMDS_MeshNode * n5,
3524                                             const SMDS_MeshNode * n6,
3525                                             const SMDS_MeshNode * n7,
3526                                             const SMDS_MeshNode * n8,
3527                                             const SMDS_MeshNode * n12,
3528                                             const SMDS_MeshNode * n23,
3529                                             const SMDS_MeshNode * n34,
3530                                             const SMDS_MeshNode * n41,
3531                                             const SMDS_MeshNode * n56,
3532                                             const SMDS_MeshNode * n67,
3533                                             const SMDS_MeshNode * n78,
3534                                             const SMDS_MeshNode * n85,
3535                                             const SMDS_MeshNode * n15,
3536                                             const SMDS_MeshNode * n26,
3537                                             const SMDS_MeshNode * n37,
3538                                             const SMDS_MeshNode * n48,
3539                                             int ID)
3540 {
3541   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3542       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3543     return 0;
3544   if(hasConstructionFaces()) {
3545     return 0;
3546     // creation quadratic faces - not implemented
3547   }
3548   SMDS_QuadraticVolumeOfNodes * volume =
3549     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3550                                     n56,n67,n78,n85,n15,n26,n37,n48);
3551     adjustmyCellsCapacity(ID);
3552   myCells[ID] = volume;
3553   myInfo.myNbQuadHexas++;
3554
3555   if (!registerElement(ID, volume)) {
3556     RemoveElement(volume, false);
3557     volume = NULL;
3558   }
3559   return volume;
3560 }
3561
3562 void SMDS_Mesh::updateNodeMinMax()
3563 {
3564   myNodeMin = 0;
3565   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3566     myNodeMin++;
3567   myNodeMax=myNodes.size()-1;
3568   while (!myNodes[myNodeMax] && (myNodeMin>=0))
3569     myNodeMin--;
3570 }
3571
3572 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3573 {
3574   int val = myIDElements.size();
3575   MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3576   myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3577   val = myNodes.size();
3578   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3579   myNodes.resize(val +nbNodes, 0);
3580 }
3581
3582 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3583 {
3584   int val = myVtkIndex.size();
3585   MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3586   myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3587   val = myCells.size();
3588   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3589   myNodes.resize(val +nbCells, 0);
3590 }
3591
3592 void SMDS_Mesh::adjustStructure()
3593 {
3594   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3595 }
3596