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