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