Salome HOME
Merge from V6_5_BR 05/06/2012
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
1 // Copyright (C) 2007-2012  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
23 //  SMESH SMDS : implementation of Salome mesh data structure
24 //
25 #ifdef _MSC_VER
26 #pragma warning(disable:4786)
27 #endif
28
29 #include "utilities.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_VolumeOfNodes.hxx"
32 #include "SMDS_VolumeOfFaces.hxx"
33 #include "SMDS_FaceOfNodes.hxx"
34 #include "SMDS_FaceOfEdges.hxx"
35 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
36 #include "SMDS_PolygonalFaceOfNodes.hxx"
37 #include "SMDS_QuadraticEdge.hxx"
38 #include "SMDS_QuadraticFaceOfNodes.hxx"
39 #include "SMDS_QuadraticVolumeOfNodes.hxx"
40 #include "SMDS_SpacePosition.hxx"
41 #include "SMDS_UnstructuredGrid.hxx"
42
43 #include <vtkUnstructuredGrid.h>
44 #include <vtkUnstructuredGridWriter.h>
45 #include <vtkUnsignedCharArray.h>
46 #include <vtkCell.h>
47 #include <vtkCellLinks.h>
48 #include <vtkIdList.h>
49
50 #include <algorithm>
51 #include <map>
52 #include <iostream>
53 #include <fstream>
54 using namespace std;
55
56 #ifndef WIN32
57 #include <sys/sysinfo.h>
58 #endif
59
60 // number of added entities to check memory after
61 #define CHECKMEMORY_INTERVAL 100000
62
63 vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
64 int SMDS_Mesh::chunkSize = 1024;
65
66
67 //================================================================================
68 /*!
69  * \brief Raise an exception if free memory (ram+swap) too low
70  * \param doNotRaise - if true, suppres exception, just return free memory size
71  * \retval int - amount of available memory in MB or negative number in failure case
72  */
73 //================================================================================
74
75 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
76 {
77 #ifndef WIN32
78   struct sysinfo si;
79   int err = sysinfo( &si );
80   if ( err )
81     return -1;
82
83   const unsigned long Mbyte = 1024 * 1024;
84
85   static int limit = -1;
86   if ( limit < 0 ) {
87     int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
88     if (status >= 0 ) {
89       limit = WEXITSTATUS(status);
90     }
91     else {
92       double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
93       limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
94     }
95     if ( limit < 20 )
96       limit = 20;
97     else
98       limit = int ( limit * 1.5 );
99     MESSAGE ( "SMDS_Mesh::CheckMemory() memory limit = " << limit << " MB" );
100   }
101
102   // compute separately to avoid overflow
103   int freeMb =
104     ( si.freeram  * si.mem_unit ) / Mbyte +
105     ( si.freeswap * si.mem_unit ) / Mbyte;
106   //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
107
108   if ( freeMb > limit )
109     return freeMb - limit;
110
111   if ( doNotRaise )
112     return 0;
113
114   MESSAGE ("SMDS_Mesh::CheckMemory() throws as free memory too low: " << freeMb <<" MB" );
115   throw std::bad_alloc();
116 #else
117   return -1;
118 #endif
119 }
120
121 ///////////////////////////////////////////////////////////////////////////////
122 /// Create a new mesh object
123 ///////////////////////////////////////////////////////////////////////////////
124 SMDS_Mesh::SMDS_Mesh()
125         :myParent(NULL),
126          myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
127          myElementIDFactory(new SMDS_MeshElementIDFactory()),
128          myHasConstructionEdges(false), myHasConstructionFaces(false),
129          myHasInverseElements(true),
130          myNodeMin(0), myNodeMax(0),
131          myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),
132          myModified(false), myModifTime(0), myCompactTime(0),
133          xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
134 {
135   myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
136   MESSAGE("myMeshId=" << myMeshId);
137   MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
138   MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
139   MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
140   MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
141   MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
142   MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
143   myNodeIDFactory->SetMesh(this);
144   myElementIDFactory->SetMesh(this);
145   _meshList.push_back(this);
146   myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
147   myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
148   myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
149   myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
150
151   myNodes.clear();
152   myCells.clear();
153   //myCellIdSmdsToVtk.clear();
154   myCellIdVtkToSmds.clear();
155   myGrid = SMDS_UnstructuredGrid::New();
156   myGrid->setSMDS_mesh(this);
157   myGrid->Initialize();
158   myGrid->Allocate();
159   vtkPoints* points = vtkPoints::New();
160   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
161   // using double type for storing coordinates of nodes instead float.
162   points->SetDataType(VTK_DOUBLE);
163   points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
164   myGrid->SetPoints( points );
165   points->Delete();
166   myGrid->BuildLinks();
167   this->Modified();
168 }
169
170 ///////////////////////////////////////////////////////////////////////////////
171 /// Create a new child mesh
172 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
173 /// (2003-09-08) of SMESH
174 ///////////////////////////////////////////////////////////////////////////////
175 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
176         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
177          myElementIDFactory(parent->myElementIDFactory),
178          myHasConstructionEdges(false), myHasConstructionFaces(false),
179          myHasInverseElements(true),
180          myNodePool(parent->myNodePool),
181          myEdgePool(parent->myEdgePool),
182          myFacePool(parent->myFacePool),
183          myVolumePool(parent->myVolumePool)
184 {
185 }
186
187 ///////////////////////////////////////////////////////////////////////////////
188 ///Create a submesh and add it to the current mesh
189 ///////////////////////////////////////////////////////////////////////////////
190
191 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
192 {
193         SMDS_Mesh *submesh = new SMDS_Mesh(this);
194         myChildren.insert(myChildren.end(), submesh);
195         return submesh;
196 }
197
198 ///////////////////////////////////////////////////////////////////////////////
199 ///create a MeshNode and add it to the current Mesh
200 ///An ID is automatically assigned to the node.
201 ///@return : The created node
202 ///////////////////////////////////////////////////////////////////////////////
203
204 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
205 {
206   return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
207 }
208
209 ///////////////////////////////////////////////////////////////////////////////
210 ///create a MeshNode and add it to the current Mesh
211 ///@param ID : The ID of the MeshNode to create
212 ///@return : The created node or NULL if a node with this ID already exists
213 ///////////////////////////////////////////////////////////////////////////////
214 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
215 {
216   // find the MeshNode corresponding to ID
217   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
218   if(!node){
219     if (ID < 1)
220       {
221         MESSAGE("=============>  Bad Node Id: " << ID);
222         ID = myNodeIDFactory->GetFreeID();
223       }
224     myNodeIDFactory->adjustMaxId(ID);
225     SMDS_MeshNode * node = myNodePool->getNew();
226     node->init(ID, myMeshId, 0, x, y, z);
227
228     if (ID >= myNodes.size())
229     {
230         myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
231 //         MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
232     }
233     myNodes[ID] = node;
234     myNodeIDFactory->BindID(ID,node);
235     myInfo.myNbNodes++;
236     myModified = true;
237     this->adjustBoundingBox(x, y, z);
238     return node;
239   }else
240     return NULL;
241 }
242
243 ///////////////////////////////////////////////////////////////////////////////
244 /// create a Mesh0DElement and add it to the current Mesh
245 /// @return : The created Mesh0DElement
246 ///////////////////////////////////////////////////////////////////////////////
247 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
248 {
249   SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
250   if (!node) return NULL;
251   return SMDS_Mesh::Add0DElementWithID(node, ID);
252 }
253
254 ///////////////////////////////////////////////////////////////////////////////
255 /// create a Mesh0DElement and add it to the current Mesh
256 /// @return : The created Mesh0DElement
257 ///////////////////////////////////////////////////////////////////////////////
258 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
259 {
260   return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
261 }
262
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Create a new Mesh0DElement and at it to the mesh
265 /// @param idnode ID of the node
266 /// @param ID ID of the 0D element to create
267 /// @return The created 0D element or NULL if an element with this
268 ///         ID already exists or if input node is not found.
269 ///////////////////////////////////////////////////////////////////////////////
270 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
271 {
272   if (!n) return 0;
273
274   if (Nb0DElements() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
275   //MESSAGE("Add0DElementWithID" << ID)
276   SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
277   if (myElementIDFactory->BindID(ID, el0d)) {
278     //SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
279     //node->AddInverseElement(el0d);// --- fait avec BindID
280     adjustmyCellsCapacity(ID);
281     myCells[ID] = el0d;
282     myInfo.myNb0DElements++;
283     return el0d;
284   }
285
286   delete el0d;
287   return NULL;
288 }
289
290 ///////////////////////////////////////////////////////////////////////////////
291 /// create a MeshEdge and add it to the current Mesh
292 /// @return : The created MeshEdge
293 ///////////////////////////////////////////////////////////////////////////////
294
295 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
296 {
297   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
298   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
299   if(!node1 || !node2) return NULL;
300   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
301 }
302
303 ///////////////////////////////////////////////////////////////////////////////
304 /// create a MeshEdge and add it to the current Mesh
305 /// @return : The created MeshEdge
306 ///////////////////////////////////////////////////////////////////////////////
307
308 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
309                                   const SMDS_MeshNode * node2)
310 {
311   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
312 }
313
314 ///////////////////////////////////////////////////////////////////////////////
315 /// Create a new edge and at it to the mesh
316 /// @param idnode1 ID of the first node
317 /// @param idnode2 ID of the second node
318 /// @param ID ID of the edge to create
319 /// @return The created edge or NULL if an element with this ID already exists or
320 /// if input nodes are not found.
321 ///////////////////////////////////////////////////////////////////////////////
322
323 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
324                                         const SMDS_MeshNode * n2,
325                                         int ID)
326 {
327   if ( !n1 || !n2 ) return 0;
328   SMDS_MeshEdge * edge = 0;
329
330   // --- retreive nodes ID
331   vector<vtkIdType> nodeIds;
332   nodeIds.clear();
333   nodeIds.push_back(n1->getVtkId());
334   nodeIds.push_back(n2->getVtkId());
335
336   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
337   edgevtk->init(nodeIds, this);
338   if (!this->registerElement(ID,edgevtk))
339     {
340       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
341       myEdgePool->destroy(edgevtk);
342       return 0;
343     }
344   edge = edgevtk;
345   adjustmyCellsCapacity(ID);
346   myCells[ID] = edge;
347   myInfo.myNbEdges++;
348
349 //  if (edge && !registerElement(ID, edge))
350 //  {
351 //    RemoveElement(edge, false);
352 //    edge = NULL;
353 //  }
354   return edge;
355 }
356
357 ///////////////////////////////////////////////////////////////////////////////
358 /// Add a triangle defined by its nodes. An ID is automatically affected to the
359 /// Created face
360 ///////////////////////////////////////////////////////////////////////////////
361
362 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
363                                   const SMDS_MeshNode * n2,
364                                   const SMDS_MeshNode * n3)
365 {
366   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
367 }
368
369 ///////////////////////////////////////////////////////////////////////////////
370 /// Add a triangle defined by its nodes IDs
371 ///////////////////////////////////////////////////////////////////////////////
372
373 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
374 {
375   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
376   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
377   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
378   if(!node1 || !node2 || !node3) return NULL;
379   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
380 }
381
382 ///////////////////////////////////////////////////////////////////////////////
383 /// Add a triangle defined by its nodes
384 ///////////////////////////////////////////////////////////////////////////////
385
386 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
387                                         const SMDS_MeshNode * n2,
388                                         const SMDS_MeshNode * n3,
389                                         int ID)
390 {
391   //MESSAGE("AddFaceWithID " << ID)
392   SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
393
394 //  if (face && !registerElement(ID, face)) {
395 //    RemoveElement(face, false);
396 //    face = NULL;
397 //  }
398   return face;
399 }
400
401 ///////////////////////////////////////////////////////////////////////////////
402 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
403 /// created face
404 ///////////////////////////////////////////////////////////////////////////////
405
406 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
407                                   const SMDS_MeshNode * n2,
408                                   const SMDS_MeshNode * n3,
409                                   const SMDS_MeshNode * n4)
410 {
411   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
412 }
413
414 ///////////////////////////////////////////////////////////////////////////////
415 /// Add a quadrangle defined by its nodes IDs
416 ///////////////////////////////////////////////////////////////////////////////
417
418 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
419                                         int idnode2,
420                                         int idnode3,
421                                         int idnode4,
422                                         int ID)
423 {
424   SMDS_MeshNode *node1, *node2, *node3, *node4;
425   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
426   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
427   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
428   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
429   if(!node1 || !node2 || !node3 || !node4) return NULL;
430   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
431 }
432
433 ///////////////////////////////////////////////////////////////////////////////
434 /// Add a quadrangle defined by its nodes
435 ///////////////////////////////////////////////////////////////////////////////
436
437 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
438                                         const SMDS_MeshNode * n2,
439                                         const SMDS_MeshNode * n3,
440                                         const SMDS_MeshNode * n4,
441                                         int ID)
442 {
443   //MESSAGE("AddFaceWithID " << ID);
444   SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
445
446 //  if (face && !registerElement(ID, face)) {
447 //    RemoveElement(face, false);
448 //    face = NULL;
449 //  }
450   return face;
451 }
452
453 ///////////////////////////////////////////////////////////////////////////////
454 /// Add a triangle defined by its edges. An ID is automatically assigned to the
455 /// Created face
456 ///////////////////////////////////////////////////////////////////////////////
457
458 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
459                                   const SMDS_MeshEdge * e2,
460                                   const SMDS_MeshEdge * e3)
461 {
462   if (!hasConstructionEdges())
463     return NULL;
464      //MESSAGE("AddFaceWithID");
465  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
466 }
467
468 ///////////////////////////////////////////////////////////////////////////////
469 /// Add a triangle defined by its edges
470 ///////////////////////////////////////////////////////////////////////////////
471
472 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
473                                         const SMDS_MeshEdge * e2,
474                                         const SMDS_MeshEdge * e3,
475                                         int ID)
476 {
477   if (!hasConstructionEdges())
478     return NULL;
479   if ( !e1 || !e2 || !e3 ) return 0;
480
481   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
482   MESSAGE("AddFaceWithID" << ID);
483
484   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
485   adjustmyCellsCapacity(ID);
486   myCells[ID] = face;
487   myInfo.myNbTriangles++;
488
489   if (!registerElement(ID, face)) {
490     registerElement(myElementIDFactory->GetFreeID(), face);
491     //RemoveElement(face, false);
492     //face = NULL;
493   }
494   return face;
495 }
496
497 ///////////////////////////////////////////////////////////////////////////////
498 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
499 /// Created face
500 ///////////////////////////////////////////////////////////////////////////////
501
502 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
503                                   const SMDS_MeshEdge * e2,
504                                   const SMDS_MeshEdge * e3,
505                                   const SMDS_MeshEdge * e4)
506 {
507   if (!hasConstructionEdges())
508     return NULL;
509      //MESSAGE("AddFaceWithID" );
510  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
511 }
512
513 ///////////////////////////////////////////////////////////////////////////////
514 /// Add a quadrangle defined by its edges
515 ///////////////////////////////////////////////////////////////////////////////
516
517 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
518                                         const SMDS_MeshEdge * e2,
519                                         const SMDS_MeshEdge * e3,
520                                         const SMDS_MeshEdge * e4,
521                                         int ID)
522 {
523   if (!hasConstructionEdges())
524     return NULL;
525   MESSAGE("AddFaceWithID" << ID);
526   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
527   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
528   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
529   adjustmyCellsCapacity(ID);
530   myCells[ID] = face;
531   myInfo.myNbQuadrangles++;
532
533   if (!registerElement(ID, face))
534   {
535     registerElement(myElementIDFactory->GetFreeID(), face);
536     //RemoveElement(face, false);
537     //face = NULL;
538   }
539   return face;
540 }
541
542 ///////////////////////////////////////////////////////////////////////////////
543 ///Create a new tetrahedron and add it to the mesh.
544 ///@return The created tetrahedron
545 ///////////////////////////////////////////////////////////////////////////////
546
547 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
548                                       const SMDS_MeshNode * n2,
549                                       const SMDS_MeshNode * n3,
550                                       const SMDS_MeshNode * n4)
551 {
552   int ID = myElementIDFactory->GetFreeID();
553     //MESSAGE("AddVolumeWithID " << ID);
554   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
555   if(v==NULL) myElementIDFactory->ReleaseID(ID);
556   return v;
557 }
558
559 ///////////////////////////////////////////////////////////////////////////////
560 ///Create a new tetrahedron and add it to the mesh.
561 ///@param ID The ID of the new volume
562 ///@return The created tetrahedron or NULL if an element with this ID already exists
563 ///or if input nodes are not found.
564 ///////////////////////////////////////////////////////////////////////////////
565
566 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
567                                              int idnode2,
568                                              int idnode3,
569                                              int idnode4,
570                                              int ID)
571 {
572     //MESSAGE("AddVolumeWithID" << ID);
573   SMDS_MeshNode *node1, *node2, *node3, *node4;
574   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
575   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
576   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
577   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
578   if(!node1 || !node2 || !node3 || !node4) return NULL;
579   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
580 }
581
582 ///////////////////////////////////////////////////////////////////////////////
583 ///Create a new tetrahedron and add it to the mesh.
584 ///@param ID The ID of the new volume
585 ///@return The created tetrahedron
586 ///////////////////////////////////////////////////////////////////////////////
587
588 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
589                                             const SMDS_MeshNode * n2,
590                                             const SMDS_MeshNode * n3,
591                                             const SMDS_MeshNode * n4,
592                                             int ID)
593 {
594     //MESSAGE("AddVolumeWithID " << ID);
595   SMDS_MeshVolume* volume = 0;
596   if ( !n1 || !n2 || !n3 || !n4) return volume;
597   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
598   if(hasConstructionFaces()) {
599     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
600     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
601     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
602     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
603     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
604     adjustmyCellsCapacity(ID);
605     myCells[ID] = volume;
606     myInfo.myNbTetras++;
607   }
608   else if(hasConstructionEdges()) {
609     MESSAGE("Error : Not implemented");
610     return NULL;
611   }
612   else {
613     // --- retrieve nodes ID
614     vector<vtkIdType> nodeIds;
615     nodeIds.clear();
616     nodeIds.push_back(n1->getVtkId());
617     nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
618     nodeIds.push_back(n2->getVtkId());
619     nodeIds.push_back(n4->getVtkId());
620
621     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
622     volvtk->init(nodeIds, this);
623     if (!this->registerElement(ID,volvtk))
624       {
625         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
626         myVolumePool->destroy(volvtk);
627         return 0;
628       }
629     volume = volvtk;
630     adjustmyCellsCapacity(ID);
631     myCells[ID] = volume;
632     myInfo.myNbTetras++;
633   }
634
635 //  if (!registerElement(ID, volume)) {
636 //    RemoveElement(volume, false);
637 //    volume = NULL;
638 //  }
639   return volume;
640 }
641
642 ///////////////////////////////////////////////////////////////////////////////
643 ///Create a new pyramid and add it to the mesh.
644 ///Nodes 1,2,3 and 4 define the base of the pyramid
645 ///@return The created pyramid
646 ///////////////////////////////////////////////////////////////////////////////
647
648 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
649                                       const SMDS_MeshNode * n2,
650                                       const SMDS_MeshNode * n3,
651                                       const SMDS_MeshNode * n4,
652                                       const SMDS_MeshNode * n5)
653 {
654   int ID = myElementIDFactory->GetFreeID();
655     //MESSAGE("AddVolumeWithID " << ID);
656   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
657   if(v==NULL) myElementIDFactory->ReleaseID(ID);
658   return v;
659 }
660
661 ///////////////////////////////////////////////////////////////////////////////
662 ///Create a new pyramid and add it to the mesh.
663 ///Nodes 1,2,3 and 4 define the base of the pyramid
664 ///@param ID The ID of the new volume
665 ///@return The created pyramid or NULL if an element with this ID already exists
666 ///or if input nodes are not found.
667 ///////////////////////////////////////////////////////////////////////////////
668
669 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
670                                              int idnode2,
671                                              int idnode3,
672                                              int idnode4,
673                                              int idnode5,
674                                              int ID)
675 {
676     //MESSAGE("AddVolumeWithID " << ID);
677   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
678   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
679   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
680   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
681   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
682   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
683   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
684   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
685 }
686
687 ///////////////////////////////////////////////////////////////////////////////
688 ///Create a new pyramid and add it to the mesh.
689 ///Nodes 1,2,3 and 4 define the base of the pyramid
690 ///@param ID The ID of the new volume
691 ///@return The created pyramid
692 ///////////////////////////////////////////////////////////////////////////////
693
694 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
695                                             const SMDS_MeshNode * n2,
696                                             const SMDS_MeshNode * n3,
697                                             const SMDS_MeshNode * n4,
698                                             const SMDS_MeshNode * n5,
699                                             int ID)
700 {
701     //MESSAGE("AddVolumeWithID " << ID);
702   SMDS_MeshVolume* volume = 0;
703   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
704   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
705   if(hasConstructionFaces()) {
706     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
707     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
708     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
709     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
710     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
711     adjustmyCellsCapacity(ID);
712     myCells[ID] = volume;
713     myInfo.myNbPyramids++;
714   }
715   else if(hasConstructionEdges()) {
716     MESSAGE("Error : Not implemented");
717     return NULL;
718   }
719   else {
720     // --- retrieve nodes ID
721     vector<vtkIdType> nodeIds;
722     nodeIds.clear();
723     nodeIds.push_back(n1->getVtkId());
724     nodeIds.push_back(n4->getVtkId());
725     nodeIds.push_back(n3->getVtkId());
726     nodeIds.push_back(n2->getVtkId());
727     nodeIds.push_back(n5->getVtkId());
728
729     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
730     volvtk->init(nodeIds, this);
731     if (!this->registerElement(ID,volvtk))
732       {
733         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
734         myVolumePool->destroy(volvtk);
735         return 0;
736       }
737     volume = volvtk;
738     adjustmyCellsCapacity(ID);
739     myCells[ID] = volume;
740     myInfo.myNbPyramids++;
741   }
742
743 //  if (!registerElement(ID, volume)) {
744 //    RemoveElement(volume, false);
745 //    volume = NULL;
746 //  }
747   return volume;
748 }
749
750 ///////////////////////////////////////////////////////////////////////////////
751 ///Create a new prism and add it to the mesh.
752 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
753 ///@return The created prism
754 ///////////////////////////////////////////////////////////////////////////////
755
756 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
757                                       const SMDS_MeshNode * n2,
758                                       const SMDS_MeshNode * n3,
759                                       const SMDS_MeshNode * n4,
760                                       const SMDS_MeshNode * n5,
761                                       const SMDS_MeshNode * n6)
762 {
763   int ID = myElementIDFactory->GetFreeID();
764     //MESSAGE("AddVolumeWithID " << ID);
765   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
766   if(v==NULL) myElementIDFactory->ReleaseID(ID);
767   return v;
768 }
769
770 ///////////////////////////////////////////////////////////////////////////////
771 ///Create a new prism and add it to the mesh.
772 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
773 ///@param ID The ID of the new volume
774 ///@return The created prism or NULL if an element with this ID already exists
775 ///or if input nodes are not found.
776 ///////////////////////////////////////////////////////////////////////////////
777
778 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
779                                              int idnode2,
780                                              int idnode3,
781                                              int idnode4,
782                                              int idnode5,
783                                              int idnode6,
784                                              int ID)
785 {
786     //MESSAGE("AddVolumeWithID " << ID);
787   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
788   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
789   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
790   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
791   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
792   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
793   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
794   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
795   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
796 }
797
798 ///////////////////////////////////////////////////////////////////////////////
799 ///Create a new prism and add it to the mesh.
800 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
801 ///@param ID The ID of the new volume
802 ///@return The created prism
803 ///////////////////////////////////////////////////////////////////////////////
804
805 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
806                                             const SMDS_MeshNode * n2,
807                                             const SMDS_MeshNode * n3,
808                                             const SMDS_MeshNode * n4,
809                                             const SMDS_MeshNode * n5,
810                                             const SMDS_MeshNode * n6,
811                                             int ID)
812 {
813     //MESSAGE("AddVolumeWithID " << ID);
814   SMDS_MeshVolume* volume = 0;
815   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
816   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
817   if(hasConstructionFaces()) {
818     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
819     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
820     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
821     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
822     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
823     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
824     adjustmyCellsCapacity(ID);
825     myCells[ID] = volume;
826     myInfo.myNbPrisms++;
827   }
828   else if(hasConstructionEdges()) {
829     MESSAGE("Error : Not implemented");
830     return NULL;
831   }
832   else {
833     // --- retrieve nodes ID
834     vector<vtkIdType> nodeIds;
835     nodeIds.clear();
836     nodeIds.push_back(n1->getVtkId());
837     nodeIds.push_back(n2->getVtkId());
838     nodeIds.push_back(n3->getVtkId());
839     nodeIds.push_back(n4->getVtkId());
840     nodeIds.push_back(n5->getVtkId());
841     nodeIds.push_back(n6->getVtkId());
842
843     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
844     volvtk->init(nodeIds, this);
845     if (!this->registerElement(ID,volvtk))
846       {
847         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
848         myVolumePool->destroy(volvtk);
849         return 0;
850       }
851     volume = volvtk;
852     adjustmyCellsCapacity(ID);
853     myCells[ID] = volume;
854     myInfo.myNbPrisms++;
855   }
856
857 //  if (!registerElement(ID, volume)) {
858 //    RemoveElement(volume, false);
859 //    volume = NULL;
860 //  }
861   return volume;
862 }
863
864 ///////////////////////////////////////////////////////////////////////////////
865 ///Create a new hexagonal prism and add it to the mesh.
866 ///@return The created prism
867 ///////////////////////////////////////////////////////////////////////////////
868
869 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
870                                       const SMDS_MeshNode * n2,
871                                       const SMDS_MeshNode * n3,
872                                       const SMDS_MeshNode * n4,
873                                       const SMDS_MeshNode * n5,
874                                       const SMDS_MeshNode * n6,
875                                       const SMDS_MeshNode * n7,
876                                       const SMDS_MeshNode * n8,
877                                       const SMDS_MeshNode * n9,
878                                       const SMDS_MeshNode * n10,
879                                       const SMDS_MeshNode * n11,
880                                       const SMDS_MeshNode * n12)
881 {
882   int ID = myElementIDFactory->GetFreeID();
883   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
884                                                    n7, n8, n9, n10, n11, n12,
885                                                    ID);
886   if(v==NULL) myElementIDFactory->ReleaseID(ID);
887   return v;
888 }
889
890 ///////////////////////////////////////////////////////////////////////////////
891 ///Create a new hexagonal prism and add it to the mesh.
892 ///@param ID The ID of the new volume
893 ///@return The created prism or NULL if an element with this ID already exists
894 ///or if input nodes are not found.
895 ///////////////////////////////////////////////////////////////////////////////
896
897 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
898                                              int idnode2,
899                                              int idnode3,
900                                              int idnode4,
901                                              int idnode5,
902                                              int idnode6,
903                                              int idnode7,
904                                              int idnode8,
905                                              int idnode9,
906                                              int idnode10,
907                                              int idnode11,
908                                              int idnode12,
909                                              int ID)
910 {
911   SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
912   SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
913   SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
914   SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
915   SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
916   SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
917   SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
918   SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
919   SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
920   SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
921   SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
922   SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
923   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
924                                     node7, node8, node9, node10, node11, node12,
925                                     ID);
926 }
927
928 ///////////////////////////////////////////////////////////////////////////////
929 ///Create a new hexagonal prism and add it to the mesh.
930 ///@param ID The ID of the new volume
931 ///@return The created prism
932 ///////////////////////////////////////////////////////////////////////////////
933
934 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
935                                             const SMDS_MeshNode * n2,
936                                             const SMDS_MeshNode * n3,
937                                             const SMDS_MeshNode * n4,
938                                             const SMDS_MeshNode * n5,
939                                             const SMDS_MeshNode * n6,
940                                             const SMDS_MeshNode * n7,
941                                             const SMDS_MeshNode * n8,
942                                             const SMDS_MeshNode * n9,
943                                             const SMDS_MeshNode * n10,
944                                             const SMDS_MeshNode * n11,
945                                             const SMDS_MeshNode * n12,
946                                             int ID)
947 {
948   SMDS_MeshVolume* volume = 0;
949   if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
950      !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
951     return volume;
952   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
953   if(hasConstructionFaces()) {
954     MESSAGE("Error : Not implemented");
955     return NULL;
956   }
957   else if(hasConstructionEdges()) {
958     MESSAGE("Error : Not implemented");
959     return NULL;
960   }
961   else {
962     // --- retrieve nodes ID
963     vector<vtkIdType> nodeIds;
964     nodeIds.push_back(n1->getVtkId());
965     nodeIds.push_back(n6->getVtkId());
966     nodeIds.push_back(n5->getVtkId());
967     nodeIds.push_back(n4->getVtkId());
968     nodeIds.push_back(n3->getVtkId());
969     nodeIds.push_back(n2->getVtkId());
970
971     nodeIds.push_back(n7->getVtkId());
972     nodeIds.push_back(n12->getVtkId());
973     nodeIds.push_back(n11->getVtkId());
974     nodeIds.push_back(n10->getVtkId());
975     nodeIds.push_back(n9->getVtkId());
976     nodeIds.push_back(n8->getVtkId());
977
978     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
979     volvtk->init(nodeIds, this);
980     if (!this->registerElement(ID,volvtk))
981       {
982         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
983         myVolumePool->destroy(volvtk);
984         return 0;
985       }
986     volume = volvtk;
987     adjustmyCellsCapacity(ID);
988     myCells[ID] = volume;
989     myInfo.myNbHexPrism++;
990   }
991
992   return volume;
993 }
994
995 ///////////////////////////////////////////////////////////////////////////////
996 ///Create a new hexahedron and add it to the mesh.
997 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
998 ///@return The created hexahedron
999 ///////////////////////////////////////////////////////////////////////////////
1000
1001 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
1002                                       const SMDS_MeshNode * n2,
1003                                       const SMDS_MeshNode * n3,
1004                                       const SMDS_MeshNode * n4,
1005                                       const SMDS_MeshNode * n5,
1006                                       const SMDS_MeshNode * n6,
1007                                       const SMDS_MeshNode * n7,
1008                                       const SMDS_MeshNode * n8)
1009 {
1010   int ID = myElementIDFactory->GetFreeID();
1011  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
1012   if(v==NULL) myElementIDFactory->ReleaseID(ID);
1013   return v;
1014 }
1015
1016 ///////////////////////////////////////////////////////////////////////////////
1017 ///Create a new hexahedron and add it to the mesh.
1018 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1019 ///@param ID The ID of the new volume
1020 ///@return The created hexahedron or NULL if an element with this ID already
1021 ///exists or if input nodes are not found.
1022 ///////////////////////////////////////////////////////////////////////////////
1023
1024 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
1025                                              int idnode2,
1026                                              int idnode3,
1027                                              int idnode4,
1028                                              int idnode5,
1029                                              int idnode6,
1030                                              int idnode7,
1031                                              int idnode8,
1032                                              int ID)
1033 {
1034     //MESSAGE("AddVolumeWithID " << ID);
1035   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
1036   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
1037   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
1038   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
1039   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
1040   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
1041   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
1042   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
1043   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
1044   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
1045     return NULL;
1046   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
1047                                     node7, node8, ID);
1048 }
1049
1050 ///////////////////////////////////////////////////////////////////////////////
1051 ///Create a new hexahedron and add it to the mesh.
1052 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
1053 ///@param ID The ID of the new volume
1054 ///@return The created prism or NULL if an element with this ID already exists
1055 ///or if input nodes are not found.
1056 ///////////////////////////////////////////////////////////////////////////////
1057
1058 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
1059                                             const SMDS_MeshNode * n2,
1060                                             const SMDS_MeshNode * n3,
1061                                             const SMDS_MeshNode * n4,
1062                                             const SMDS_MeshNode * n5,
1063                                             const SMDS_MeshNode * n6,
1064                                             const SMDS_MeshNode * n7,
1065                                             const SMDS_MeshNode * n8,
1066                                             int ID)
1067 {
1068     //MESSAGE("AddVolumeWithID " << ID);
1069   SMDS_MeshVolume* volume = 0;
1070   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
1071   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1072   if(hasConstructionFaces()) {
1073     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
1074     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
1075     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
1076     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
1077     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
1078     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
1079     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1080     adjustmyCellsCapacity(ID);
1081     myCells[ID] = volume;
1082     myInfo.myNbHexas++;
1083   }
1084   else if(hasConstructionEdges()) {
1085     MESSAGE("Error : Not implemented");
1086     return NULL;
1087   }
1088   else {
1089     // --- retrieve nodes ID
1090     vector<vtkIdType> nodeIds;
1091     nodeIds.clear();
1092     nodeIds.push_back(n1->getVtkId());
1093     nodeIds.push_back(n4->getVtkId());
1094     nodeIds.push_back(n3->getVtkId());
1095     nodeIds.push_back(n2->getVtkId());
1096     nodeIds.push_back(n5->getVtkId());
1097     nodeIds.push_back(n8->getVtkId());
1098     nodeIds.push_back(n7->getVtkId());
1099     nodeIds.push_back(n6->getVtkId());
1100
1101     SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1102     volvtk->init(nodeIds, this);
1103     if (!this->registerElement(ID,volvtk))
1104       {
1105         this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1106         myVolumePool->destroy(volvtk);
1107         return 0;
1108       }
1109     volume = volvtk;
1110     adjustmyCellsCapacity(ID);
1111     myCells[ID] = volume;
1112     myInfo.myNbHexas++;
1113   }
1114  
1115 //  if (!registerElement(ID, volume)) {
1116 //    RemoveElement(volume, false);
1117 //    volume = NULL;
1118 //  }
1119   return volume;
1120 }
1121
1122 ///////////////////////////////////////////////////////////////////////////////
1123 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1124 ///@return The created tetrahedron
1125 ///////////////////////////////////////////////////////////////////////////////
1126
1127 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1128                                       const SMDS_MeshFace * f2,
1129                                       const SMDS_MeshFace * f3,
1130                                       const SMDS_MeshFace * f4)
1131 {
1132     //MESSAGE("AddVolumeWithID");
1133   if (!hasConstructionFaces())
1134     return NULL;
1135   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
1136 }
1137
1138 ///////////////////////////////////////////////////////////////////////////////
1139 ///Create a new tetrahedron defined by its faces and add it to the mesh.
1140 ///@param ID The ID of the new volume
1141 ///@return The created tetrahedron
1142 ///////////////////////////////////////////////////////////////////////////////
1143
1144 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1145                                             const SMDS_MeshFace * f2,
1146                                             const SMDS_MeshFace * f3,
1147                                             const SMDS_MeshFace * f4,
1148                                             int ID)
1149 {
1150   MESSAGE("AddVolumeWithID" << ID);
1151   if (!hasConstructionFaces())
1152     return NULL;
1153   if ( !f1 || !f2 || !f3 || !f4) return 0;
1154   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1155   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
1156   adjustmyCellsCapacity(ID);
1157   myCells[ID] = volume;
1158   myInfo.myNbTetras++;
1159
1160   if (!registerElement(ID, volume)) {
1161     registerElement(myElementIDFactory->GetFreeID(), volume);
1162     //RemoveElement(volume, false);
1163     //volume = NULL;
1164   }
1165   return volume;
1166 }
1167
1168 ///////////////////////////////////////////////////////////////////////////////
1169 ///Create a new pyramid defined by its faces and add it to the mesh.
1170 ///@return The created pyramid
1171 ///////////////////////////////////////////////////////////////////////////////
1172
1173 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1174                                       const SMDS_MeshFace * f2,
1175                                       const SMDS_MeshFace * f3,
1176                                       const SMDS_MeshFace * f4,
1177                                       const SMDS_MeshFace * f5)
1178 {
1179      //MESSAGE("AddVolumeWithID");
1180  if (!hasConstructionFaces())
1181     return NULL;
1182   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
1183 }
1184
1185 ///////////////////////////////////////////////////////////////////////////////
1186 ///Create a new pyramid defined by its faces and add it to the mesh.
1187 ///@param ID The ID of the new volume
1188 ///@return The created pyramid
1189 ///////////////////////////////////////////////////////////////////////////////
1190
1191 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1192                                             const SMDS_MeshFace * f2,
1193                                             const SMDS_MeshFace * f3,
1194                                             const SMDS_MeshFace * f4,
1195                                             const SMDS_MeshFace * f5,
1196                                             int ID)
1197 {
1198   MESSAGE("AddVolumeWithID" << ID);
1199   if (!hasConstructionFaces())
1200     return NULL;
1201   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
1202   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1203   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
1204   adjustmyCellsCapacity(ID);
1205   myCells[ID] = volume;
1206   myInfo.myNbPyramids++;
1207
1208   if (!registerElement(ID, volume)) {
1209     registerElement(myElementIDFactory->GetFreeID(), volume);
1210     //RemoveElement(volume, false);
1211     //volume = NULL;
1212   }
1213   return volume;
1214 }
1215
1216 ///////////////////////////////////////////////////////////////////////////////
1217 ///Create a new prism defined by its faces and add it to the mesh.
1218 ///@return The created prism
1219 ///////////////////////////////////////////////////////////////////////////////
1220
1221 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
1222                                       const SMDS_MeshFace * f2,
1223                                       const SMDS_MeshFace * f3,
1224                                       const SMDS_MeshFace * f4,
1225                                       const SMDS_MeshFace * f5,
1226                                       const SMDS_MeshFace * f6)
1227 {
1228      //MESSAGE("AddVolumeWithID" );
1229  if (!hasConstructionFaces())
1230     return NULL;
1231   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
1232 }
1233
1234 ///////////////////////////////////////////////////////////////////////////////
1235 ///Create a new prism defined by its faces and add it to the mesh.
1236 ///@param ID The ID of the new volume
1237 ///@return The created prism
1238 ///////////////////////////////////////////////////////////////////////////////
1239
1240 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
1241                                             const SMDS_MeshFace * f2,
1242                                             const SMDS_MeshFace * f3,
1243                                             const SMDS_MeshFace * f4,
1244                                             const SMDS_MeshFace * f5,
1245                                             const SMDS_MeshFace * f6,
1246                                             int ID)
1247 {
1248   MESSAGE("AddVolumeWithID" << ID);
1249   if (!hasConstructionFaces())
1250     return NULL;
1251   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
1252   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1253   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
1254   adjustmyCellsCapacity(ID);
1255   myCells[ID] = volume;
1256   myInfo.myNbPrisms++;
1257
1258   if (!registerElement(ID, volume)) {
1259     registerElement(myElementIDFactory->GetFreeID(), volume);
1260     //RemoveElement(volume, false);
1261     //volume = NULL;
1262   }
1263   return volume;
1264 }
1265
1266 ///////////////////////////////////////////////////////////////////////////////
1267 /// Add a polygon defined by its nodes IDs
1268 ///////////////////////////////////////////////////////////////////////////////
1269
1270 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
1271                                                   const int           ID)
1272 {
1273   int nbNodes = nodes_ids.size();
1274   vector<const SMDS_MeshNode*> nodes (nbNodes);
1275   for (int i = 0; i < nbNodes; i++) {
1276     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1277     if (!nodes[i]) return NULL;
1278   }
1279   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
1280 }
1281
1282 ///////////////////////////////////////////////////////////////////////////////
1283 /// Add a polygon defined by its nodes
1284 ///////////////////////////////////////////////////////////////////////////////
1285
1286 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
1287                           (const vector<const SMDS_MeshNode*> & nodes,
1288                            const int                            ID)
1289 {
1290   SMDS_MeshFace * face;
1291
1292   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1293   if (hasConstructionEdges())
1294     {
1295       MESSAGE("Error : Not implemented");
1296       return NULL;
1297     }
1298   else
1299     {
1300 //#ifdef VTK_HAVE_POLYHEDRON
1301     //MESSAGE("AddPolygonalFaceWithID vtk " << ID);
1302     vector<vtkIdType> nodeIds;
1303     nodeIds.clear();
1304     vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
1305     for ( ; it != nodes.end(); ++it)
1306       nodeIds.push_back((*it)->getVtkId());
1307
1308     SMDS_VtkFace *facevtk = myFacePool->getNew();
1309     facevtk->initPoly(nodeIds, this);
1310     if (!this->registerElement(ID,facevtk))
1311       {
1312         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1313         myFacePool->destroy(facevtk);
1314         return 0;
1315       }
1316     face = facevtk;
1317 //#else
1318 //    MESSAGE("AddPolygonalFaceWithID smds " << ID);
1319 //     for ( int i = 0; i < nodes.size(); ++i )
1320 //      if ( !nodes[ i ] ) return 0;
1321 //      face = new SMDS_PolygonalFaceOfNodes(nodes);
1322 //#endif
1323       adjustmyCellsCapacity(ID);
1324       myCells[ID] = face;
1325       myInfo.myNbPolygons++;
1326     }
1327
1328 //#ifndef VTK_HAVE_POLYHEDRON
1329 //  if (!registerElement(ID, face))
1330 //    {
1331 //      registerElement(myElementIDFactory->GetFreeID(), face);
1332 //      //RemoveElement(face, false);
1333 //      //face = NULL;
1334 //    }
1335 //#endif
1336  return face;
1337 }
1338
1339 ///////////////////////////////////////////////////////////////////////////////
1340 /// Add a polygon defined by its nodes.
1341 /// An ID is automatically affected to the created face.
1342 ///////////////////////////////////////////////////////////////////////////////
1343
1344 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
1345 {
1346   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
1347 }
1348
1349 ///////////////////////////////////////////////////////////////////////////////
1350 /// Create a new polyhedral volume and add it to the mesh.
1351 /// @param ID The ID of the new volume
1352 /// @return The created volume or NULL if an element with this ID already exists
1353 /// or if input nodes are not found.
1354 ///////////////////////////////////////////////////////////////////////////////
1355
1356 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
1357                              (const vector<int> & nodes_ids,
1358                               const vector<int> & quantities,
1359                               const int           ID)
1360 {
1361   int nbNodes = nodes_ids.size();
1362   vector<const SMDS_MeshNode*> nodes (nbNodes);
1363   for (int i = 0; i < nbNodes; i++) {
1364     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
1365     if (!nodes[i]) return NULL;
1366   }
1367   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1368 }
1369
1370 ///////////////////////////////////////////////////////////////////////////////
1371 /// Create a new polyhedral volume and add it to the mesh.
1372 /// @param ID The ID of the new volume
1373 /// @return The created  volume
1374 ///////////////////////////////////////////////////////////////////////////////
1375
1376 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
1377                             (const vector<const SMDS_MeshNode*>& nodes,
1378                              const vector<int>                 & quantities,
1379                              const int                           ID)
1380 {
1381   SMDS_MeshVolume* volume = 0;
1382   if ( nodes.empty() || quantities.empty() )
1383     return NULL;
1384   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1385   if (hasConstructionFaces())
1386     {
1387       MESSAGE("Error : Not implemented");
1388       return NULL;
1389     }
1390   else if (hasConstructionEdges())
1391     {
1392       MESSAGE("Error : Not implemented");
1393       return NULL;
1394     }
1395   else
1396     {
1397 //#ifdef VTK_HAVE_POLYHEDRON
1398       //MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
1399       vector<vtkIdType> nodeIds;
1400       nodeIds.clear();
1401       vector<const SMDS_MeshNode*>::const_iterator it = nodes.begin();
1402       for (; it != nodes.end(); ++it)
1403         nodeIds.push_back((*it)->getVtkId());
1404
1405       SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1406       volvtk->initPoly(nodeIds, quantities, this);
1407       if (!this->registerElement(ID, volvtk))
1408         {
1409           this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1410           myVolumePool->destroy(volvtk);
1411           return 0;
1412         }
1413       volume = volvtk;
1414 //#else
1415 //      MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
1416 //      for ( int i = 0; i < nodes.size(); ++i )
1417 //      if ( !nodes[ i ] ) return 0;
1418 //      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
1419 //#endif
1420       adjustmyCellsCapacity(ID);
1421       myCells[ID] = volume;
1422       myInfo.myNbPolyhedrons++;
1423     }
1424
1425 //#ifndef VTK_HAVE_POLYHEDRON
1426 //  if (!registerElement(ID, volume))
1427 //    {
1428 //      registerElement(myElementIDFactory->GetFreeID(), volume);
1429 //      //RemoveElement(volume, false);
1430 //      //volume = NULL;
1431 //    }
1432 //#endif
1433   return volume;
1434 }
1435
1436 ///////////////////////////////////////////////////////////////////////////////
1437 /// Create a new polyhedral volume and add it to the mesh.
1438 /// @return The created  volume
1439 ///////////////////////////////////////////////////////////////////////////////
1440
1441 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
1442                             (const vector<const SMDS_MeshNode*> & nodes,
1443                              const vector<int>                  & quantities)
1444 {
1445   int ID = myElementIDFactory->GetFreeID();
1446   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
1447   if (v == NULL) myElementIDFactory->ReleaseID(ID);
1448   return v;
1449 }
1450
1451 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1452 {
1453   int ID = myElementIDFactory->GetFreeID();
1454   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
1455   if (v == NULL) myElementIDFactory->ReleaseID(ID);
1456   return v;
1457 }
1458
1459 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1460 {
1461   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
1462   volvtk->init(vtkNodeIds, this);
1463   if (!this->registerElement(ID,volvtk))
1464     {
1465       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
1466       myVolumePool->destroy(volvtk);
1467       return 0;
1468     }
1469   adjustmyCellsCapacity(ID);
1470   myCells[ID] = volvtk;
1471   vtkIdType aVtkType = volvtk->GetVtkType();
1472   switch (aVtkType)
1473   {
1474     case VTK_TETRA:
1475       myInfo.myNbTetras++;
1476       break;
1477     case VTK_PYRAMID:
1478       myInfo.myNbPyramids++;
1479       break;
1480     case VTK_WEDGE:
1481       myInfo.myNbPrisms++;
1482       break;
1483     case VTK_HEXAHEDRON:
1484       myInfo.myNbHexas++;
1485       break;
1486     case VTK_QUADRATIC_TETRA:
1487       myInfo.myNbQuadTetras++;
1488       break;
1489     case VTK_QUADRATIC_PYRAMID:
1490       myInfo.myNbQuadPyramids++;
1491       break;
1492     case VTK_QUADRATIC_WEDGE:
1493       myInfo.myNbQuadPrisms++;
1494       break;
1495     case VTK_QUADRATIC_HEXAHEDRON:
1496       myInfo.myNbQuadHexas++;
1497       break;
1498 //#ifdef VTK_HAVE_POLYHEDRON
1499     case VTK_POLYHEDRON:
1500       myInfo.myNbPolyhedrons++;
1501       break;
1502 //#endif
1503     default:
1504       myInfo.myNbPolyhedrons++;
1505       break;
1506   }
1507   return volvtk;
1508 }
1509
1510 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
1511 {
1512   int ID = myElementIDFactory->GetFreeID();
1513   SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
1514   if (f == NULL) myElementIDFactory->ReleaseID(ID);
1515   return f;
1516 }
1517
1518 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
1519 {
1520   SMDS_VtkFace *facevtk = myFacePool->getNew();
1521   facevtk->init(vtkNodeIds, this);
1522   if (!this->registerElement(ID,facevtk))
1523     {
1524       this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1525       myFacePool->destroy(facevtk);
1526       return 0;
1527     }
1528   adjustmyCellsCapacity(ID);
1529   myCells[ID] = facevtk;
1530   vtkIdType aVtkType = facevtk->GetVtkType();
1531   switch (aVtkType)
1532   {
1533     case VTK_TRIANGLE:
1534       myInfo.myNbTriangles++;
1535       break;
1536     case VTK_QUAD:
1537       myInfo.myNbQuadrangles++;
1538       break;
1539     case VTK_QUADRATIC_TRIANGLE:
1540       myInfo.myNbQuadTriangles++;
1541       break;
1542     case VTK_QUADRATIC_QUAD:
1543       myInfo.myNbQuadQuadrangles++;
1544       break;
1545     case VTK_BIQUADRATIC_QUAD:
1546       myInfo.myNbBiQuadQuadrangles++;
1547       break;
1548     case VTK_POLYGON:
1549       myInfo.myNbPolygons++;
1550       break;
1551      default:
1552       myInfo.myNbPolygons++;
1553   }
1554   return facevtk;
1555 }
1556
1557 ///////////////////////////////////////////////////////////////////////////////
1558 /// Registers element with the given ID, maintains inverse connections
1559 ///////////////////////////////////////////////////////////////////////////////
1560 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1561 {
1562   //MESSAGE("registerElement " << ID);
1563   if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1564   {
1565     MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1566     return false;
1567   }
1568
1569   element->myID = ID;
1570   element->myMeshId = myMeshId;
1571
1572   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1573   MYASSERT(cell);
1574   int vtkId = cell->getVtkId();  
1575   if (vtkId == -1)
1576     vtkId = myElementIDFactory->SetInVtkGrid(element);
1577
1578   if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1579   {
1580 //     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1581     myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1582   }
1583   myCellIdVtkToSmds[vtkId] = ID;
1584
1585   myElementIDFactory->updateMinMax(ID);
1586   return true;
1587 }
1588
1589 ///////////////////////////////////////////////////////////////////////////////
1590 /// Return the node whose SMDS ID is 'ID'.
1591 ///////////////////////////////////////////////////////////////////////////////
1592 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1593 {
1594   if (ID < 1 || ID >= myNodes.size())
1595   {
1596 //     MESSAGE("------------------------------------------------------------------------- ");
1597 //     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1598 //     MESSAGE("------------------------------------------------------------------------- ");
1599     return 0;
1600   }
1601   return (const SMDS_MeshNode *)myNodes[ID];
1602 }
1603
1604 ///////////////////////////////////////////////////////////////////////////////
1605 /// Return the node whose VTK ID is 'vtkId'.
1606 ///////////////////////////////////////////////////////////////////////////////
1607 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1608 {
1609   // TODO if needed use mesh->nodeIdFromVtkToSmds
1610   if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1611   {
1612     MESSAGE("------------------------------------------------------------------------- ");
1613     MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1614     MESSAGE("------------------------------------------------------------------------- ");
1615     return 0;
1616   }
1617   return (const SMDS_MeshNode *)myNodes[vtkId+1];
1618 }
1619
1620 ///////////////////////////////////////////////////////////////////////////////
1621 ///Create a triangle and add it to the current mesh. This method do not bind an
1622 ///ID to the create triangle.
1623 ///////////////////////////////////////////////////////////////////////////////
1624 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1625                                           const SMDS_MeshNode * node2,
1626                                           const SMDS_MeshNode * node3,
1627                                           int ID)
1628 {
1629   if ( !node1 || !node2 || !node3) return 0;
1630   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1631   if(hasConstructionEdges())
1632   {
1633     SMDS_MeshEdge *edge1, *edge2, *edge3;
1634     edge1=FindEdgeOrCreate(node1,node2);
1635     edge2=FindEdgeOrCreate(node2,node3);
1636     edge3=FindEdgeOrCreate(node3,node1);
1637
1638     //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1639     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1640     adjustmyCellsCapacity(ID);
1641     myCells[ID] = face;
1642     myInfo.myNbTriangles++;
1643     return face;
1644   }
1645   else
1646   {
1647     // --- retrieve nodes ID
1648     vector<vtkIdType> nodeIds;
1649     nodeIds.clear();
1650     nodeIds.push_back(node1->getVtkId());
1651     nodeIds.push_back(node2->getVtkId());
1652     nodeIds.push_back(node3->getVtkId());
1653
1654     SMDS_MeshFace * face = 0;
1655     SMDS_VtkFace *facevtk = myFacePool->getNew();
1656     facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1657     if (!this->registerElement(ID,facevtk))
1658       {
1659         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1660         myFacePool->destroy(facevtk);
1661         return 0;
1662       }
1663     face = facevtk;
1664     adjustmyCellsCapacity(ID);
1665     myCells[ID] = face;
1666     //MESSAGE("createTriangle " << ID << " " << face);
1667     myInfo.myNbTriangles++;
1668     return face;
1669   }
1670 }
1671
1672 ///////////////////////////////////////////////////////////////////////////////
1673 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1674 ///a ID to the create triangle.
1675 ///////////////////////////////////////////////////////////////////////////////
1676 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1677                                             const SMDS_MeshNode * node2,
1678                                             const SMDS_MeshNode * node3,
1679                                             const SMDS_MeshNode * node4,
1680                                             int ID)
1681 {
1682   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1683   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1684   if(hasConstructionEdges())
1685   {
1686       //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1687     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1688     edge1=FindEdgeOrCreate(node1,node2);
1689     edge2=FindEdgeOrCreate(node2,node3);
1690     edge3=FindEdgeOrCreate(node3,node4);
1691     edge4=FindEdgeOrCreate(node4,node1);
1692
1693     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1694     adjustmyCellsCapacity(ID);
1695     myCells[ID] = face;
1696     myInfo.myNbQuadrangles++;
1697     return face;
1698   }
1699   else
1700   {
1701     // --- retrieve nodes ID
1702     vector<vtkIdType> nodeIds;
1703     nodeIds.clear();
1704     nodeIds.push_back(node1->getVtkId());
1705     nodeIds.push_back(node2->getVtkId());
1706     nodeIds.push_back(node3->getVtkId());
1707     nodeIds.push_back(node4->getVtkId());
1708
1709     SMDS_MeshFace * face = 0;
1710     SMDS_VtkFace *facevtk = myFacePool->getNew();
1711     facevtk->init(nodeIds, this);
1712     if (!this->registerElement(ID,facevtk))
1713       {
1714         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1715         myFacePool->destroy(facevtk);
1716         return 0;
1717       }
1718     face = facevtk;
1719     adjustmyCellsCapacity(ID);
1720     myCells[ID] = face;
1721     myInfo.myNbQuadrangles++;
1722     return face;
1723   }
1724 }
1725
1726 ///////////////////////////////////////////////////////////////////////////////
1727 /// Remove a node and all the elements which own this node
1728 ///////////////////////////////////////////////////////////////////////////////
1729
1730 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1731 {
1732     MESSAGE("RemoveNode");
1733         RemoveElement(node, true);
1734 }
1735
1736 ///////////////////////////////////////////////////////////////////////////////
1737 /// Remove an edge and all the elements which own this edge
1738 ///////////////////////////////////////////////////////////////////////////////
1739
1740 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1741 {
1742     MESSAGE("Remove0DElement");
1743   RemoveElement(elem0d,true);
1744 }
1745
1746 ///////////////////////////////////////////////////////////////////////////////
1747 /// Remove an edge and all the elements which own this edge
1748 ///////////////////////////////////////////////////////////////////////////////
1749
1750 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1751 {
1752     MESSAGE("RemoveEdge");
1753         RemoveElement(edge,true);
1754 }
1755
1756 ///////////////////////////////////////////////////////////////////////////////
1757 /// Remove an face and all the elements which own this face
1758 ///////////////////////////////////////////////////////////////////////////////
1759
1760 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1761 {
1762     MESSAGE("RemoveFace");
1763         RemoveElement(face, true);
1764 }
1765
1766 ///////////////////////////////////////////////////////////////////////////////
1767 /// Remove a volume
1768 ///////////////////////////////////////////////////////////////////////////////
1769
1770 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1771 {
1772     MESSAGE("RemoveVolume");
1773         RemoveElement(volume, true);
1774 }
1775
1776 //=======================================================================
1777 //function : RemoveFromParent
1778 //purpose  :
1779 //=======================================================================
1780
1781 bool SMDS_Mesh::RemoveFromParent()
1782 {
1783         if (myParent==NULL) return false;
1784         else return (myParent->RemoveSubMesh(this));
1785 }
1786
1787 //=======================================================================
1788 //function : RemoveSubMesh
1789 //purpose  :
1790 //=======================================================================
1791
1792 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1793 {
1794         bool found = false;
1795
1796         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1797         for (; itmsh!=myChildren.end() && !found; itmsh++)
1798         {
1799                 SMDS_Mesh * submesh = *itmsh;
1800                 if (submesh == aMesh)
1801                 {
1802                         found = true;
1803                         myChildren.erase(itmsh);
1804                 }
1805         }
1806
1807         return found;
1808 }
1809
1810 //=======================================================================
1811 //function : ChangeElementNodes
1812 //purpose  :
1813 //=======================================================================
1814
1815 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1816                                    const SMDS_MeshNode    * nodes[],
1817                                    const int                nbnodes)
1818 {
1819   MESSAGE("SMDS_Mesh::ChangeElementNodes");
1820   // keep current nodes of elem
1821   set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1822
1823   // change nodes
1824   bool Ok = false;
1825   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1826   if (cell)
1827     {
1828       Ok = cell->vtkOrder(nodes, nbnodes);
1829       Ok = cell->ChangeNodes(nodes, nbnodes);
1830     }
1831
1832   if ( Ok ) { // update InverseElements
1833
1834     set<const SMDS_MeshNode*>::iterator it;
1835
1836     // AddInverseElement to new nodes
1837     for ( int i = 0; i < nbnodes; i++ ) {
1838       it = oldNodes.find( nodes[i] );
1839       if ( it == oldNodes.end() )
1840         // new node
1841         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1842       else
1843         // remove from oldNodes a node that remains in elem
1844         oldNodes.erase( it );
1845     }
1846     // RemoveInverseElement from the nodes removed from elem
1847     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1848     {
1849       SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1850       n->RemoveInverseElement( cell );
1851     }
1852   }
1853
1854   return Ok;
1855 }
1856
1857 //=======================================================================
1858 //function : ChangePolyhedronNodes
1859 //purpose  : to change nodes of polyhedral volume
1860 //=======================================================================
1861 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
1862                                        const vector<const SMDS_MeshNode*>& nodes,
1863                                        const vector<int>                 & quantities)
1864 {
1865   if (elem->GetType() != SMDSAbs_Volume) {
1866     MESSAGE("WRONG ELEM TYPE");
1867     return false;
1868   }
1869
1870   const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1871   if (!vol) {
1872     return false;
1873   }
1874
1875   // keep current nodes of elem
1876   set<const SMDS_MeshElement*> oldNodes;
1877   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1878   while (itn->more()) {
1879     oldNodes.insert(itn->next());
1880   }
1881
1882   // change nodes
1883   // TODO remove this function
1884   //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1885   bool Ok = false;
1886   if (!Ok) {
1887     return false;
1888   }
1889
1890   // update InverseElements
1891
1892   // AddInverseElement to new nodes
1893   int nbnodes = nodes.size();
1894   set<const SMDS_MeshElement*>::iterator it;
1895   for (int i = 0; i < nbnodes; i++) {
1896     it = oldNodes.find(nodes[i]);
1897     if (it == oldNodes.end()) {
1898       // new node
1899       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1900     } else {
1901       // remove from oldNodes a node that remains in elem
1902       oldNodes.erase(it);
1903     }
1904   }
1905
1906   // RemoveInverseElement from the nodes removed from elem
1907   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1908     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1909       (const_cast<SMDS_MeshElement *>( *it ));
1910     n->RemoveInverseElement(elem);
1911   }
1912
1913   return Ok;
1914 }
1915
1916
1917 //=======================================================================
1918 //function : Find0DElement
1919 //purpose  :
1920 //=======================================================================
1921 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1922 {
1923   const SMDS_MeshNode * node = FindNode(idnode);
1924   if(node == NULL) return NULL;
1925   return Find0DElement(node);
1926 }
1927
1928 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1929 {
1930   if (!node) return 0;
1931   const SMDS_Mesh0DElement* toReturn = NULL;
1932   SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1933   while (it1->more() && (toReturn == NULL)) {
1934     const SMDS_MeshElement* e = it1->next();
1935     if (e->NbNodes() == 1) {
1936       toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1937     }
1938   }
1939   return toReturn;
1940 }
1941
1942 //=======================================================================
1943 //function : Find0DElementOrCreate
1944 //purpose  :
1945 //=======================================================================
1946 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1947 //{
1948 //  if (!node) return 0;
1949 //  SMDS_Mesh0DElement * toReturn = NULL;
1950 //  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1951 //  if (toReturn == NULL) {
1952 //    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1953 //    toReturn = new SMDS_Mesh0DElement(node);
1954 //    my0DElements.Add(toReturn);
1955 //    myInfo.myNb0DElements++;
1956 //  }
1957 //  return toReturn;
1958 //}
1959
1960
1961 //=======================================================================
1962 //function : FindEdge
1963 //purpose  :
1964 //=======================================================================
1965
1966 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1967 {
1968   const SMDS_MeshNode * node1=FindNode(idnode1);
1969   const SMDS_MeshNode * node2=FindNode(idnode2);
1970   if((node1==NULL)||(node2==NULL)) return NULL;
1971   return FindEdge(node1,node2);
1972 }
1973
1974 //#include "Profiler.h"
1975 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1976                                          const SMDS_MeshNode * node2)
1977 {
1978   if ( !node1 ) return 0;
1979   const SMDS_MeshEdge * toReturn=NULL;
1980   //PROFILER_Init();
1981   //PROFILER_Set();
1982   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1983   //PROFILER_Get(0);
1984   //PROFILER_Set();
1985   while(it1->more()) {
1986     const SMDS_MeshElement * e = it1->next();
1987     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1988       toReturn = static_cast<const SMDS_MeshEdge*>( e );
1989       break;
1990     }
1991   }
1992   //PROFILER_Get(1);
1993   return toReturn;
1994 }
1995
1996
1997 //=======================================================================
1998 //function : FindEdgeOrCreate
1999 //purpose  :
2000 //=======================================================================
2001
2002 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
2003                                            const SMDS_MeshNode * node2)
2004 {
2005   if ( !node1 || !node2) return 0;
2006   SMDS_MeshEdge * toReturn=NULL;
2007   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
2008   if(toReturn==NULL) {
2009     if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
2010     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
2011     adjustmyCellsCapacity(ID);
2012     vector<vtkIdType> nodeIds;
2013     nodeIds.clear();
2014     nodeIds.push_back(node1->getVtkId());
2015     nodeIds.push_back(node2->getVtkId());
2016
2017     SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
2018     edgevtk->init(nodeIds, this);
2019     if (!this->registerElement(ID,edgevtk))
2020       {
2021         this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
2022         myEdgePool->destroy(edgevtk);
2023         return 0;
2024       }
2025     toReturn = edgevtk;
2026     myCells[ID] = toReturn;
2027     myInfo.myNbEdges++;
2028   }
2029   return toReturn;
2030 }
2031
2032
2033 //=======================================================================
2034 //function : FindEdge
2035 //purpose  :
2036 //=======================================================================
2037
2038 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
2039                                          int idnode3) const
2040 {
2041   const SMDS_MeshNode * node1=FindNode(idnode1);
2042   const SMDS_MeshNode * node2=FindNode(idnode2);
2043   const SMDS_MeshNode * node3=FindNode(idnode3);
2044   return FindEdge(node1,node2,node3);
2045 }
2046
2047 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2048                                          const SMDS_MeshNode * node2,
2049                                          const SMDS_MeshNode * node3)
2050 {
2051   if ( !node1 ) return 0;
2052   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
2053   while(it1->more()) {
2054     const SMDS_MeshElement * e = it1->next();
2055     if ( e->NbNodes() == 3 ) {
2056       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2057       while(it2->more()) {
2058         const SMDS_MeshElement* n = it2->next();
2059         if( n!=node1 &&
2060             n!=node2 &&
2061             n!=node3 )
2062         {
2063           e = 0;
2064           break;
2065         }
2066       }
2067       if ( e )
2068         return static_cast<const SMDS_MeshEdge *> (e);
2069     }
2070   }
2071   return 0;
2072 }
2073
2074
2075 //=======================================================================
2076 //function : FindFace
2077 //purpose  :
2078 //=======================================================================
2079
2080 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2081         int idnode3) const
2082 {
2083   const SMDS_MeshNode * node1=FindNode(idnode1);
2084   const SMDS_MeshNode * node2=FindNode(idnode2);
2085   const SMDS_MeshNode * node3=FindNode(idnode3);
2086   return FindFace(node1, node2, node3);
2087 }
2088
2089 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2090                                          const SMDS_MeshNode *node2,
2091                                          const SMDS_MeshNode *node3)
2092 {
2093   if ( !node1 ) return 0;
2094   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2095   while(it1->more()) {
2096     const SMDS_MeshElement * e = it1->next();
2097     if ( e->NbNodes() == 3 ) {
2098       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2099       while(it2->more()) {
2100         const SMDS_MeshElement* n = it2->next();
2101         if( n!=node1 &&
2102             n!=node2 &&
2103             n!=node3 )
2104         {
2105           e = 0;
2106           break;
2107         }
2108       }
2109       if ( e )
2110         return static_cast<const SMDS_MeshFace *> (e);
2111     }
2112   }
2113   return 0;
2114 }
2115
2116 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2117                                            const SMDS_MeshNode *node2,
2118                                            const SMDS_MeshNode *node3)
2119 {
2120   SMDS_MeshFace * toReturn=NULL;
2121   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
2122   if(toReturn==NULL) {
2123     int ID = myElementIDFactory->GetFreeID();
2124     toReturn = createTriangle(node1,node2,node3, ID);
2125   }
2126   return toReturn;
2127 }
2128
2129
2130 //=======================================================================
2131 //function : FindFace
2132 //purpose  :
2133 //=======================================================================
2134
2135 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2136                                          int idnode3, int idnode4) const
2137 {
2138   const SMDS_MeshNode * node1=FindNode(idnode1);
2139   const SMDS_MeshNode * node2=FindNode(idnode2);
2140   const SMDS_MeshNode * node3=FindNode(idnode3);
2141   const SMDS_MeshNode * node4=FindNode(idnode4);
2142   return FindFace(node1, node2, node3, node4);
2143 }
2144
2145 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2146                                          const SMDS_MeshNode *node2,
2147                                          const SMDS_MeshNode *node3,
2148                                          const SMDS_MeshNode *node4)
2149 {
2150   if ( !node1 ) return 0;
2151   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2152   while(it1->more()) {
2153     const SMDS_MeshElement * e = it1->next();
2154     if ( e->NbNodes() == 4 ) {
2155       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2156       while(it2->more()) {
2157         const SMDS_MeshElement* n = it2->next();
2158         if( n!=node1 &&
2159             n!=node2 &&
2160             n!=node3 &&
2161             n!=node4 )
2162         {
2163           e = 0;
2164           break;
2165         }
2166       }
2167       if ( e )
2168         return static_cast<const SMDS_MeshFace *> (e);
2169     }
2170   }
2171   return 0;
2172 }
2173
2174 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2175                                            const SMDS_MeshNode *node2,
2176                                            const SMDS_MeshNode *node3,
2177                                            const SMDS_MeshNode *node4)
2178 {
2179   SMDS_MeshFace * toReturn=NULL;
2180   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2181   if(toReturn==NULL) {
2182     int ID = myElementIDFactory->GetFreeID();
2183     toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2184   }
2185   return toReturn;
2186 }
2187
2188
2189 //=======================================================================
2190 //function : FindFace
2191 //purpose  :quadratic triangle
2192 //=======================================================================
2193
2194 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2195                                          int idnode3, int idnode4,
2196                                          int idnode5, int idnode6) const
2197 {
2198   const SMDS_MeshNode * node1 = FindNode(idnode1);
2199   const SMDS_MeshNode * node2 = FindNode(idnode2);
2200   const SMDS_MeshNode * node3 = FindNode(idnode3);
2201   const SMDS_MeshNode * node4 = FindNode(idnode4);
2202   const SMDS_MeshNode * node5 = FindNode(idnode5);
2203   const SMDS_MeshNode * node6 = FindNode(idnode6);
2204   return FindFace(node1, node2, node3, node4, node5, node6);
2205 }
2206
2207 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2208                                          const SMDS_MeshNode *node2,
2209                                          const SMDS_MeshNode *node3,
2210                                          const SMDS_MeshNode *node4,
2211                                          const SMDS_MeshNode *node5,
2212                                          const SMDS_MeshNode *node6)
2213 {
2214   if ( !node1 ) return 0;
2215   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2216   while(it1->more()) {
2217     const SMDS_MeshElement * e = it1->next();
2218     if ( e->NbNodes() == 6 ) {
2219       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2220       while(it2->more()) {
2221         const SMDS_MeshElement* n = it2->next();
2222         if( n!=node1 &&
2223             n!=node2 &&
2224             n!=node3 &&
2225             n!=node4 &&
2226             n!=node5 &&
2227             n!=node6 )
2228         {
2229           e = 0;
2230           break;
2231         }
2232       }
2233       if ( e )
2234         return static_cast<const SMDS_MeshFace *> (e);
2235     }
2236   }
2237   return 0;
2238 }
2239
2240
2241 //=======================================================================
2242 //function : FindFace
2243 //purpose  : quadratic quadrangle
2244 //=======================================================================
2245
2246 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2247                                          int idnode3, int idnode4,
2248                                          int idnode5, int idnode6,
2249                                          int idnode7, int idnode8) const
2250 {
2251   const SMDS_MeshNode * node1 = FindNode(idnode1);
2252   const SMDS_MeshNode * node2 = FindNode(idnode2);
2253   const SMDS_MeshNode * node3 = FindNode(idnode3);
2254   const SMDS_MeshNode * node4 = FindNode(idnode4);
2255   const SMDS_MeshNode * node5 = FindNode(idnode5);
2256   const SMDS_MeshNode * node6 = FindNode(idnode6);
2257   const SMDS_MeshNode * node7 = FindNode(idnode7);
2258   const SMDS_MeshNode * node8 = FindNode(idnode8);
2259   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2260 }
2261
2262 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2263                                          const SMDS_MeshNode *node2,
2264                                          const SMDS_MeshNode *node3,
2265                                          const SMDS_MeshNode *node4,
2266                                          const SMDS_MeshNode *node5,
2267                                          const SMDS_MeshNode *node6,
2268                                          const SMDS_MeshNode *node7,
2269                                          const SMDS_MeshNode *node8)
2270 {
2271   if ( !node1 ) return 0;
2272   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2273   while(it1->more()) {
2274     const SMDS_MeshElement * e = it1->next();
2275     if ( e->NbNodes() == 8 ) {
2276       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2277       while(it2->more()) {
2278         const SMDS_MeshElement* n = it2->next();
2279         if( n!=node1 &&
2280             n!=node2 &&
2281             n!=node3 &&
2282             n!=node4 &&
2283             n!=node5 &&
2284             n!=node6 &&
2285             n!=node7 &&
2286             n!=node8 )
2287         {
2288           e = 0;
2289           break;
2290         }
2291       }
2292       if ( e )
2293         return static_cast<const SMDS_MeshFace *> (e);
2294     }
2295   }
2296   return 0;
2297 }
2298
2299
2300 //=======================================================================
2301 //function : FindElement
2302 //purpose  :
2303 //=======================================================================
2304
2305 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2306 {
2307   if ((IDelem <= 0) || IDelem >= myCells.size())
2308   {
2309     MESSAGE("--------------------------------------------------------------------------------- ");
2310     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2311     MESSAGE("--------------------------------------------------------------------------------- ");
2312     // TODO raise an exception
2313     //assert(0);
2314     return 0;
2315   }
2316   return myCells[IDelem];
2317 }
2318
2319 //=======================================================================
2320 //function : FindFace
2321 //purpose  : find polygon
2322 //=======================================================================
2323
2324 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2325 {
2326   int nbnodes = nodes_ids.size();
2327   vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2328   for (int inode = 0; inode < nbnodes; inode++) {
2329     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2330     if (node == NULL) return NULL;
2331     poly_nodes[inode] = node;
2332   }
2333   return FindFace(poly_nodes);
2334 }
2335
2336 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2337 {
2338   return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2339 }
2340
2341
2342 //================================================================================
2343 /*!
2344  * \brief Return element based on all given nodes
2345  *  \param nodes - node of element
2346  *  \param type - type of element
2347  *  \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2348  *  \retval const SMDS_MeshElement* - found element or NULL
2349  */
2350 //================================================================================
2351
2352 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2353                                                 const SMDSAbs_ElementType            type,
2354                                                 const bool                           noMedium)
2355 {
2356   if ( nodes.size() > 0 && nodes[0] )
2357   {
2358     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2359     while (itF->more())
2360     {
2361       const SMDS_MeshElement* e = itF->next();
2362       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2363       if ( nbNodesToCheck == nodes.size() )
2364       {
2365         for ( int i = 1; e && i < nodes.size(); ++ i )
2366         {
2367           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2368           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2369             e = 0;
2370         }
2371         if ( e )
2372           return static_cast<const SMDS_MeshFace *> (e);
2373       }
2374     }
2375   }
2376   return NULL;
2377 }
2378
2379 //=======================================================================
2380 //function : DumpNodes
2381 //purpose  :
2382 //=======================================================================
2383
2384 void SMDS_Mesh::DumpNodes() const
2385 {
2386         MESSAGE("dump nodes of mesh : ");
2387         SMDS_NodeIteratorPtr itnode=nodesIterator();
2388         while(itnode->more()) ; //MESSAGE(itnode->next());
2389 }
2390
2391 //=======================================================================
2392 //function : Dump0DElements
2393 //purpose  :
2394 //=======================================================================
2395 void SMDS_Mesh::Dump0DElements() const
2396 {
2397   MESSAGE("dump 0D elements of mesh : ");
2398   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2399   while(it0d->more()) ; //MESSAGE(it0d->next());
2400 }
2401
2402 //=======================================================================
2403 //function : DumpEdges
2404 //purpose  :
2405 //=======================================================================
2406
2407 void SMDS_Mesh::DumpEdges() const
2408 {
2409         MESSAGE("dump edges of mesh : ");
2410         SMDS_EdgeIteratorPtr itedge=edgesIterator();
2411         while(itedge->more()) ; //MESSAGE(itedge->next());
2412 }
2413
2414 //=======================================================================
2415 //function : DumpFaces
2416 //purpose  :
2417 //=======================================================================
2418
2419 void SMDS_Mesh::DumpFaces() const
2420 {
2421         MESSAGE("dump faces of mesh : ");
2422         SMDS_FaceIteratorPtr itface=facesIterator();
2423         while(itface->more()) ; //MESSAGE(itface->next());
2424 }
2425
2426 //=======================================================================
2427 //function : DumpVolumes
2428 //purpose  :
2429 //=======================================================================
2430
2431 void SMDS_Mesh::DumpVolumes() const
2432 {
2433         MESSAGE("dump volumes of mesh : ");
2434         SMDS_VolumeIteratorPtr itvol=volumesIterator();
2435         while(itvol->more()) ; //MESSAGE(itvol->next());
2436 }
2437
2438 //=======================================================================
2439 //function : DebugStats
2440 //purpose  :
2441 //=======================================================================
2442
2443 void SMDS_Mesh::DebugStats() const
2444 {
2445   MESSAGE("Debug stats of mesh : ");
2446
2447   MESSAGE("===== NODES ====="<<NbNodes());
2448   MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2449   MESSAGE("===== EDGES ====="<<NbEdges());
2450   MESSAGE("===== FACES ====="<<NbFaces());
2451   MESSAGE("===== VOLUMES ====="<<NbVolumes());
2452
2453   MESSAGE("End Debug stats of mesh ");
2454
2455   //#ifdef DEB
2456
2457   SMDS_NodeIteratorPtr itnode=nodesIterator();
2458   int sizeofnodes = 0;
2459   int sizeoffaces = 0;
2460
2461   while(itnode->more())
2462   {
2463     const SMDS_MeshNode *node = itnode->next();
2464
2465     sizeofnodes += sizeof(*node);
2466
2467     SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2468     while(it->more())
2469     {
2470       const SMDS_MeshElement *me = it->next();
2471       sizeofnodes += sizeof(me);
2472     }
2473   }
2474
2475   SMDS_FaceIteratorPtr itface=facesIterator();
2476   while(itface->more())
2477   {
2478     const SMDS_MeshElement *face = itface->next();
2479     sizeoffaces += sizeof(*face);
2480   }
2481
2482   MESSAGE("total size of node elements = " << sizeofnodes);;
2483   MESSAGE("total size of face elements = " << sizeoffaces);;
2484
2485   //#endif
2486 }
2487
2488 ///////////////////////////////////////////////////////////////////////////////
2489 /// Return the number of nodes
2490 ///////////////////////////////////////////////////////////////////////////////
2491 int SMDS_Mesh::NbNodes() const
2492 {
2493         //MESSAGE(myGrid->GetNumberOfPoints());
2494         //MESSAGE(myInfo.NbNodes());
2495         //MESSAGE(myNodeMax);
2496     return myInfo.NbNodes();
2497 }
2498
2499 ///////////////////////////////////////////////////////////////////////////////
2500 /// Return the number of 0D elements
2501 ///////////////////////////////////////////////////////////////////////////////
2502 int SMDS_Mesh::Nb0DElements() const
2503 {
2504   return myInfo.Nb0DElements(); // -PR- a verfier
2505 }
2506
2507 ///////////////////////////////////////////////////////////////////////////////
2508 /// Return the number of edges (including construction edges)
2509 ///////////////////////////////////////////////////////////////////////////////
2510 int SMDS_Mesh::NbEdges() const
2511 {
2512         return myInfo.NbEdges(); // -PR- a verfier
2513 }
2514
2515 ///////////////////////////////////////////////////////////////////////////////
2516 /// Return the number of faces (including construction faces)
2517 ///////////////////////////////////////////////////////////////////////////////
2518 int SMDS_Mesh::NbFaces() const
2519 {
2520         return myInfo.NbFaces();  // -PR- a verfier
2521 }
2522
2523 ///////////////////////////////////////////////////////////////////////////////
2524 /// Return the number of volumes
2525 ///////////////////////////////////////////////////////////////////////////////
2526 int SMDS_Mesh::NbVolumes() const
2527 {
2528         return myInfo.NbVolumes(); // -PR- a verfier
2529 }
2530
2531 ///////////////////////////////////////////////////////////////////////////////
2532 /// Return the number of child mesh of this mesh.
2533 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2534 /// (2003-09-08) of SMESH
2535 ///////////////////////////////////////////////////////////////////////////////
2536 int SMDS_Mesh::NbSubMesh() const
2537 {
2538         return myChildren.size();
2539 }
2540
2541 ///////////////////////////////////////////////////////////////////////////////
2542 /// Destroy the mesh and all its elements
2543 /// All pointer on elements owned by this mesh become illegals.
2544 ///////////////////////////////////////////////////////////////////////////////
2545 SMDS_Mesh::~SMDS_Mesh()
2546 {
2547   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2548   while(itc!=myChildren.end())
2549   {
2550     delete *itc;
2551     itc++;
2552   }
2553
2554   if(myParent==NULL)
2555   {
2556     delete myNodeIDFactory;
2557     delete myElementIDFactory;
2558   }
2559   else
2560   {
2561     SMDS_ElemIteratorPtr eIt = elementsIterator();
2562     while ( eIt->more() )
2563       {
2564         const SMDS_MeshElement *elem = eIt->next();
2565         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2566       }
2567     SMDS_NodeIteratorPtr itn = nodesIterator();
2568     while (itn->more())
2569       {
2570         const SMDS_MeshNode *node = itn->next();
2571         ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2572         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2573       }
2574   }
2575
2576 //   SetOfNodes::Iterator itn(myNodes);
2577 //   for (; itn.More(); itn.Next())
2578 //     delete itn.Value();
2579
2580 //   SetOf0DElements::Iterator it0d (my0DElements);
2581 //   for (; it0d.More(); it0d.Next())
2582 //   {
2583 //     SMDS_MeshElement* elem = it0d.Value();
2584 //     delete elem;
2585 //   }
2586
2587 //   SetOfEdges::Iterator ite(myEdges);
2588 //   for (; ite.More(); ite.Next())
2589 //   {
2590 //     SMDS_MeshElement* elem = ite.Value();
2591 //     delete elem;
2592 //   }
2593
2594 //   SetOfFaces::Iterator itf(myFaces);
2595 //   for (; itf.More(); itf.Next())
2596 //   {
2597 //     SMDS_MeshElement* elem = itf.Value();
2598 //     delete elem;
2599 //   }
2600
2601 //   SetOfVolumes::Iterator itv(myVolumes);
2602 //   for (; itv.More(); itv.Next())
2603 //   {
2604 //     SMDS_MeshElement* elem = itv.Value();
2605 //     delete elem;
2606 //   }
2607 }
2608
2609 //================================================================================
2610 /*!
2611  * \brief Clear all data
2612  */
2613 //================================================================================
2614
2615 void SMDS_Mesh::Clear()
2616 {
2617   MESSAGE("SMDS_Mesh::Clear");
2618   if (myParent!=NULL)
2619     {
2620     SMDS_ElemIteratorPtr eIt = elementsIterator();
2621     while ( eIt->more() )
2622       {
2623         const SMDS_MeshElement *elem = eIt->next();
2624         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2625       }
2626     SMDS_NodeIteratorPtr itn = nodesIterator();
2627     while (itn->more())
2628       {
2629         const SMDS_MeshNode *node = itn->next();
2630         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2631       }
2632     }
2633   else
2634     {
2635     myNodeIDFactory->Clear();
2636     myElementIDFactory->Clear();
2637     }
2638
2639   SMDS_ElemIteratorPtr itv = elementsIterator();
2640   while (itv->more())
2641     {
2642       SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2643       SMDSAbs_ElementType aType = elem->GetType();
2644       switch (aType)
2645       {
2646         case SMDSAbs_0DElement:
2647           delete elem;
2648           break;
2649         case SMDSAbs_Edge:
2650            myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2651           break;
2652         case SMDSAbs_Face:
2653           myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2654           break;
2655         case SMDSAbs_Volume:
2656           myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2657           break;
2658         default:
2659           break;
2660       }
2661     }
2662   myCells.clear();
2663   myCellIdVtkToSmds.clear();
2664   //myCellIdSmdsToVtk.clear();
2665
2666   SMDS_NodeIteratorPtr itn = nodesIterator();
2667   while (itn->more())
2668     {
2669       SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2670       node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2671       myNodePool->destroy(node);
2672     }
2673   myNodes.clear();
2674
2675   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2676   while(itc!=myChildren.end())
2677     (*itc)->Clear();
2678
2679   myModified = false;
2680   xmin = 0; xmax = 0;
2681   ymin = 0; ymax = 0;
2682   zmin = 0; zmax = 0;
2683
2684   myInfo.Clear();
2685
2686   myGrid->Initialize();
2687   myGrid->Allocate();
2688   vtkPoints* points = vtkPoints::New();
2689   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2690   // using double type for storing coordinates of nodes instead float.
2691   points->SetDataType(VTK_DOUBLE);
2692   points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2693   myGrid->SetPoints( points );
2694   points->Delete();
2695   myGrid->BuildLinks();
2696 }
2697
2698 ///////////////////////////////////////////////////////////////////////////////
2699 /// Return true if this mesh create faces with edges.
2700 /// A false returned value mean that faces are created with nodes. A concequence
2701 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2702 ///////////////////////////////////////////////////////////////////////////////
2703 bool SMDS_Mesh::hasConstructionEdges()
2704 {
2705         return myHasConstructionEdges;
2706 }
2707
2708 ///////////////////////////////////////////////////////////////////////////////
2709 /// Return true if this mesh create volumes with faces
2710 /// A false returned value mean that volumes are created with nodes or edges.
2711 /// (see hasConstructionEdges)
2712 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2713 /// unavailable.
2714 ///////////////////////////////////////////////////////////////////////////////
2715 bool SMDS_Mesh::hasConstructionFaces()
2716 {
2717         return myHasConstructionFaces;
2718 }
2719
2720 ///////////////////////////////////////////////////////////////////////////////
2721 /// Return true if nodes are linked to the finit elements, they are belonging to.
2722 /// Currently, It always return true.
2723 ///////////////////////////////////////////////////////////////////////////////
2724 bool SMDS_Mesh::hasInverseElements()
2725 {
2726         return myHasInverseElements;
2727 }
2728
2729 ///////////////////////////////////////////////////////////////////////////////
2730 /// Make this mesh creating construction edges (see hasConstructionEdges)
2731 /// @param b true to have construction edges, else false.
2732 ///////////////////////////////////////////////////////////////////////////////
2733 void SMDS_Mesh::setConstructionEdges(bool b)
2734 {
2735         myHasConstructionEdges=b;
2736 }
2737
2738 ///////////////////////////////////////////////////////////////////////////////
2739 /// Make this mesh creating construction faces (see hasConstructionFaces)
2740 /// @param b true to have construction faces, else false.
2741 ///////////////////////////////////////////////////////////////////////////////
2742 void SMDS_Mesh::setConstructionFaces(bool b)
2743 {
2744          myHasConstructionFaces=b;
2745 }
2746
2747 ///////////////////////////////////////////////////////////////////////////////
2748 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2749 /// @param b true to link nodes to elements, else false.
2750 ///////////////////////////////////////////////////////////////////////////////
2751 void SMDS_Mesh::setInverseElements(bool b)
2752 {
2753   if(!b) MESSAGE("Error : inverseElement=false not implemented");
2754   myHasInverseElements=b;
2755 }
2756
2757 namespace {
2758
2759 ///////////////////////////////////////////////////////////////////////////////
2760 ///Iterator on NCollection_Map
2761 ///////////////////////////////////////////////////////////////////////////////
2762 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2763 struct MYNode_Map_Iterator: public FATHER
2764 {
2765   int _ctr;
2766   const MAP& _map;
2767   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2768   {
2769       _ctr = 0;
2770   }
2771
2772   bool more()
2773   {
2774       while (_ctr < _map.size())
2775       {
2776           if (_map[_ctr])
2777               return true;
2778           _ctr++;
2779       }
2780           return false;
2781   }
2782
2783   ELEM next()
2784   {
2785     ELEM current = _map[_ctr];
2786     _ctr++;
2787     return current;
2788   }
2789 };
2790
2791   template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2792   struct MYElem_Map_Iterator: public FATHER
2793   {
2794     size_t _ctr;
2795     int _type, _more;
2796     const MAP& _map;
2797     MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2798     {
2799       _ctr = 0;
2800       _type = typ;
2801       _more = _ctr < _map.size();
2802       if ( _more && ( !_map[_ctr] || ( _type != SMDSAbs_All && _map[_ctr]->GetType() != _type)))
2803         next();
2804     }
2805
2806     bool more()
2807     {
2808       return _more;
2809     }
2810
2811     ELEM next()
2812     {
2813       if ( !_more ) return NULL;
2814       ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2815       _more = 0;
2816       while ( !_more && ++_ctr < _map.size() )
2817         _more = ( _map[_ctr] && (_type == SMDSAbs_All || _map[_ctr]->GetType() == _type));
2818       return current;
2819     }
2820   };
2821
2822   //================================================================================
2823   /*!
2824    * \brief Iterator on elements in id increasing order
2825    */
2826   //================================================================================
2827
2828   template <typename ELEM=const SMDS_MeshElement*>
2829   class IdSortedIterator : public SMDS_Iterator<ELEM>
2830   {
2831     const SMDS_MeshElementIDFactory& myIDFact;
2832     int                              myID, myMaxID, myNbFound, myTotalNb;
2833     SMDSAbs_ElementType              myType;
2834     ELEM                             myElem;
2835
2836   public:
2837     IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2838                      const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
2839                      const int                        totalNb)
2840       :myIDFact( fact ),
2841        myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2842        myType( type ),
2843        myElem(0)
2844     {
2845       next();
2846     }
2847     bool more()
2848     {
2849       return myElem;
2850     }
2851     ELEM next()
2852     {
2853       ELEM current = myElem;
2854
2855       for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2856         if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2857             && myElem->GetType() != myType )
2858           myElem = 0;
2859
2860       myNbFound += bool(myElem);
2861
2862       return current;
2863     }
2864   };
2865 }
2866
2867 ///////////////////////////////////////////////////////////////////////////////
2868 /// Return an iterator on nodes of the current mesh factory
2869 ///////////////////////////////////////////////////////////////////////////////
2870
2871 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2872 {
2873   typedef MYNode_Map_Iterator
2874     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2875   return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2876
2877 //  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
2878 //  return ( idInceasingOrder ?
2879 //           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2880 //           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2881 }
2882
2883 ///////////////////////////////////////////////////////////////////////////////
2884 ///Return an iterator on 0D elements of the current mesh.
2885 ///////////////////////////////////////////////////////////////////////////////
2886
2887 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2888 {
2889   typedef MYElem_Map_Iterator
2890     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2891   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2892
2893 //  typedef MYNCollection_Map_Iterator
2894 //    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2895 //  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
2896 //  return ( idInceasingOrder ?
2897 //           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2898 //                                                           SMDSAbs_0DElement,
2899 //                                                           Nb0DElements() )) :
2900 //           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2901 }
2902
2903 ///////////////////////////////////////////////////////////////////////////////
2904 ///Return an iterator on edges of the current mesh.
2905 ///////////////////////////////////////////////////////////////////////////////
2906
2907 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2908 {
2909   typedef MYElem_Map_Iterator
2910     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2911   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2912
2913 //  typedef MYNCollection_Map_Iterator
2914 //    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2915 //  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
2916 //  return ( idInceasingOrder ?
2917 //           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2918 //                                                      SMDSAbs_Edge,
2919 //                                                      NbEdges() )) :
2920 //           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2921 }
2922
2923 ///////////////////////////////////////////////////////////////////////////////
2924 ///Return an iterator on faces of the current mesh.
2925 ///////////////////////////////////////////////////////////////////////////////
2926
2927 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2928 {
2929   typedef MYElem_Map_Iterator
2930     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2931   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2932
2933 //  typedef MYNCollection_Map_Iterator
2934 //    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2935 //  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
2936 //  return ( idInceasingOrder ?
2937 //           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2938 //                                                      SMDSAbs_Face,
2939 //                                                      NbFaces() )) :
2940 //           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2941 }
2942
2943 ///////////////////////////////////////////////////////////////////////////////
2944 ///Return an iterator on volumes of the current mesh.
2945 ///////////////////////////////////////////////////////////////////////////////
2946
2947 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2948 {
2949   typedef MYElem_Map_Iterator
2950     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2951   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2952
2953   //  typedef MYNCollection_Map_Iterator
2954 //    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2955 //  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
2956 //  return ( idInceasingOrder ?
2957 //           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2958 //                                                        SMDSAbs_Volume,
2959 //                                                        NbVolumes() )) :
2960 //           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2961 }
2962
2963 ///////////////////////////////////////////////////////////////////////////////
2964 /// Return an iterator on elements of the current mesh factory
2965 ///////////////////////////////////////////////////////////////////////////////
2966 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2967 {
2968   switch (type) {
2969   case SMDSAbs_All:
2970     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2971     break;
2972   case SMDSAbs_Volume:
2973     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2974   case SMDSAbs_Face:
2975     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2976   case SMDSAbs_Edge:
2977     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2978   case SMDSAbs_0DElement:
2979     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2980   case SMDSAbs_Node:
2981     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2982     //return myNodeIDFactory->elementsIterator();
2983   default:;
2984   }
2985   return myElementIDFactory->elementsIterator();
2986 }
2987
2988 ///////////////////////////////////////////////////////////////////////////////
2989 /// Do intersection of sets (more than 2)
2990 ///////////////////////////////////////////////////////////////////////////////
2991 static set<const SMDS_MeshElement*> * intersectionOfSets(
2992         set<const SMDS_MeshElement*> vs[], int numberOfSets)
2993 {
2994         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2995         set<const SMDS_MeshElement*>* rsetB;
2996
2997         for(int i=0; i<numberOfSets-1; i++)
2998         {
2999                 rsetB=new set<const SMDS_MeshElement*>();
3000                 set_intersection(
3001                         rsetA->begin(), rsetA->end(),
3002                         vs[i+1].begin(), vs[i+1].end(),
3003                         inserter(*rsetB, rsetB->begin()));
3004                 delete rsetA;
3005                 rsetA=rsetB;
3006         }
3007         return rsetA;
3008 }
3009
3010 ///////////////////////////////////////////////////////////////////////////////
3011 /// Return the list of finite elements owning the given element: elements
3012 /// containing all the nodes of the given element, for instance faces and
3013 /// volumes containing a given edge.
3014 ///////////////////////////////////////////////////////////////////////////////
3015 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
3016 {
3017         int numberOfSets=element->NbNodes();
3018         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
3019
3020         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
3021
3022         int i=0;
3023         while(itNodes->more())
3024         {
3025           const SMDS_MeshElement* node = itNodes->next();
3026           MYASSERT(node);
3027                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
3028                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3029
3030                 //initSet[i]=set<const SMDS_MeshElement*>();
3031                 while(itFe->more())
3032                 {
3033                   const SMDS_MeshElement* elem = itFe->next();
3034                   MYASSERT(elem);
3035                   initSet[i].insert(elem);
3036
3037                 }
3038
3039                 i++;
3040         }
3041         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
3042 //         MESSAGE("nb elems " << i << " intersection " << retSet->size());
3043         delete [] initSet;
3044         return retSet;
3045 }
3046
3047 ///////////////////////////////////////////////////////////////////////////////
3048 /// Return the list of nodes used only by the given elements
3049 ///////////////////////////////////////////////////////////////////////////////
3050 static set<const SMDS_MeshElement*> * getExclusiveNodes(
3051         set<const SMDS_MeshElement*>& elements)
3052 {
3053         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
3054         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
3055
3056         while(itElements!=elements.end())
3057         {
3058                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
3059                 itElements++;
3060
3061                 while(itNodes->more())
3062                 {
3063                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
3064                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3065                         set<const SMDS_MeshElement*> s;
3066                         while(itFe->more())
3067                           s.insert(itFe->next());
3068                         if(s==elements) toReturn->insert(n);
3069                 }
3070         }
3071         return toReturn;
3072 }
3073
3074 ///////////////////////////////////////////////////////////////////////////////
3075 ///Find the children of an element that are made of given nodes
3076 ///@param setOfChildren The set in which matching children will be inserted
3077 ///@param element The element were to search matching children
3078 ///@param nodes The nodes that the children must have to be selected
3079 ///////////////////////////////////////////////////////////////////////////////
3080 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
3081                                      const SMDS_MeshElement *      element,
3082                                      set<const SMDS_MeshElement*>& nodes)
3083 {
3084   switch(element->GetType())
3085     {
3086     case SMDSAbs_Node:
3087       MESSAGE("Internal Error: This should not happen");
3088       break;
3089     case SMDSAbs_0DElement:
3090       {
3091       }
3092       break;
3093     case SMDSAbs_Edge:
3094         {
3095                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3096                 while(itn->more())
3097                 {
3098                         const SMDS_MeshElement * e=itn->next();
3099                         if(nodes.find(e)!=nodes.end())
3100                         {
3101                           setOfChildren.insert(element);
3102                           break;
3103                         }
3104                 }
3105         } break;
3106     case SMDSAbs_Face:
3107         {
3108                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3109                 while(itn->more())
3110                 {
3111                         const SMDS_MeshElement * e=itn->next();
3112                         if(nodes.find(e)!=nodes.end())
3113                         {
3114                           setOfChildren.insert(element);
3115                           break;
3116                         }
3117                 }
3118                 if(hasConstructionEdges())
3119                 {
3120                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
3121                         while(ite->more())
3122                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3123                 }
3124         } break;
3125     case SMDSAbs_Volume:
3126         {
3127                 if(hasConstructionFaces())
3128                 {
3129                         SMDS_ElemIteratorPtr ite=element->facesIterator();
3130                         while(ite->more())
3131                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3132                 }
3133                 else if(hasConstructionEdges())
3134                 {
3135                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
3136                         while(ite->more())
3137                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3138                 }
3139         }
3140     }
3141 }
3142
3143 ///////////////////////////////////////////////////////////////////////////////
3144 ///@param elem The element to delete
3145 ///@param removenodes if true remaining nodes will be removed
3146 ///////////////////////////////////////////////////////////////////////////////
3147 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3148                               const bool removenodes)
3149 {
3150   list<const SMDS_MeshElement *> removedElems;
3151   list<const SMDS_MeshElement *> removedNodes;
3152   RemoveElement( elem, removedElems, removedNodes, removenodes );
3153 }
3154
3155 ///////////////////////////////////////////////////////////////////////////////
3156 ///@param elem The element to delete
3157 ///@param removedElems to be filled with all removed elements
3158 ///@param removedNodes to be filled with all removed nodes
3159 ///@param removenodes if true remaining nodes will be removed
3160 ///////////////////////////////////////////////////////////////////////////////
3161 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
3162                               list<const SMDS_MeshElement *>& removedElems,
3163                               list<const SMDS_MeshElement *>& removedNodes,
3164                               bool                            removenodes)
3165 {
3166   //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
3167   // get finite elements built on elem
3168   set<const SMDS_MeshElement*> * s1;
3169   if (    (elem->GetType() == SMDSAbs_0DElement)
3170       || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3171       || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3172       ||  (elem->GetType() == SMDSAbs_Volume) )
3173     {
3174       s1 = new set<const SMDS_MeshElement*> ();
3175       s1->insert(elem);
3176     }
3177   else
3178     s1 = getFinitElements(elem);
3179
3180   // get exclusive nodes (which would become free afterwards)
3181   set<const SMDS_MeshElement*> * s2;
3182   if (elem->GetType() == SMDSAbs_Node) // a node is removed
3183     {
3184       // do not remove nodes except elem
3185       s2 = new set<const SMDS_MeshElement*> ();
3186       s2->insert(elem);
3187       removenodes = true;
3188     }
3189   else
3190     s2 = getExclusiveNodes(*s1);
3191
3192   // form the set of finite and construction elements to remove
3193   set<const SMDS_MeshElement*> s3;
3194   set<const SMDS_MeshElement*>::iterator it = s1->begin();
3195   while (it != s1->end())
3196     {
3197       addChildrenWithNodes(s3, *it, *s2);
3198       s3.insert(*it);
3199       it++;
3200     }
3201   if (elem->GetType() != SMDSAbs_Node)
3202     s3.insert(elem);
3203
3204   // remove finite and construction elements
3205   it = s3.begin();
3206   while (it != s3.end())
3207     {
3208       // Remove element from <InverseElements> of its nodes
3209       SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3210       while (itn->more())
3211         {
3212           SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3213           n->RemoveInverseElement((*it));
3214         }
3215       int IdToRemove = (*it)->GetID();
3216       int vtkid = (*it)->getVtkId();
3217       //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3218       //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3219       switch ((*it)->GetType())
3220       {
3221         case SMDSAbs_Node:
3222           MYASSERT("Internal Error: This should not happen")
3223           ;
3224           break;
3225         case SMDSAbs_0DElement:
3226           if (IdToRemove >= 0)
3227             {
3228               myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3229               myInfo.remove(*it);
3230             }
3231           removedElems.push_back((*it));
3232           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3233           delete (*it);
3234           break;
3235         case SMDSAbs_Edge:
3236           if (IdToRemove >= 0)
3237             {
3238               myCells[IdToRemove] = 0;
3239               myInfo.RemoveEdge(*it);
3240             }
3241           removedElems.push_back((*it));
3242           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3243           if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3244             myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3245           else
3246             delete (*it);
3247           break;
3248         case SMDSAbs_Face:
3249           if (IdToRemove >= 0)
3250             {
3251               myCells[IdToRemove] = 0;
3252               myInfo.RemoveFace(*it);
3253             }
3254           removedElems.push_back((*it));
3255           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3256           if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3257             myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3258           else
3259             delete (*it);
3260           break;
3261         case SMDSAbs_Volume:
3262           if (IdToRemove >= 0)
3263             {
3264               myCells[IdToRemove] = 0;
3265               myInfo.RemoveVolume(*it);
3266             }
3267           removedElems.push_back((*it));
3268           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3269           if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3270             myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3271           else
3272             delete (*it);
3273           break;
3274       }
3275       if (vtkid >= 0)
3276         {
3277           //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3278           this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3279         }
3280       it++;
3281     }
3282
3283   // remove exclusive (free) nodes
3284   if (removenodes)
3285     {
3286       it = s2->begin();
3287       while (it != s2->end())
3288         {
3289           int IdToRemove = (*it)->GetID();
3290           //MESSAGE( "SMDS: RM node " << IdToRemove);
3291           if (IdToRemove >= 0)
3292             {
3293               myNodes[IdToRemove] = 0;
3294               myInfo.myNbNodes--;
3295             }
3296           myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3297           removedNodes.push_back((*it));
3298           if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3299           {
3300             ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3301             myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3302           }
3303           else
3304             delete (*it);
3305           it++;
3306         }
3307     }
3308
3309   delete s2;
3310   delete s1;
3311 }
3312
3313
3314 ///////////////////////////////////////////////////////////////////////////////
3315 ///@param elem The element to delete
3316 ///////////////////////////////////////////////////////////////////////////////
3317 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3318 {
3319   int elemId = elem->GetID();
3320   int vtkId = elem->getVtkId();
3321   //MESSAGE("RemoveFreeElement " << elemId);
3322   SMDSAbs_ElementType aType = elem->GetType();
3323   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3324   if (aType == SMDSAbs_Node) {
3325     //MESSAGE("Remove free node " << elemId);
3326     // only free node can be removed by this method
3327     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3328     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3329     if (!itFe->more()) { // free node
3330       myNodes[elemId] = 0;
3331       myInfo.myNbNodes--;
3332       ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3333       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3334       myNodeIDFactory->ReleaseID(elemId, vtkId);
3335     }
3336   } else {
3337     if (hasConstructionEdges() || hasConstructionFaces())
3338       // this methods is only for meshes without descendants
3339       return;
3340
3341     //MESSAGE("Remove free element " << elemId);
3342     // Remove element from <InverseElements> of its nodes
3343     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3344     while (itn->more()) {
3345       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3346         (const_cast<SMDS_MeshElement *>(itn->next()));
3347       n->RemoveInverseElement(elem);
3348     }
3349
3350     // in meshes without descendants elements are always free
3351      switch (aType) {
3352     case SMDSAbs_0DElement:
3353       myCells[elemId] = 0;
3354       myInfo.remove(elem);
3355       delete elem;
3356       break;
3357     case SMDSAbs_Edge:
3358       myCells[elemId] = 0;
3359       myInfo.RemoveEdge(elem);
3360       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3361       break;
3362     case SMDSAbs_Face:
3363       myCells[elemId] = 0;
3364       myInfo.RemoveFace(elem);
3365       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3366       break;
3367     case SMDSAbs_Volume:
3368       myCells[elemId] = 0;
3369       myInfo.RemoveVolume(elem);
3370       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3371       break;
3372     default:
3373       break;
3374     }
3375     myElementIDFactory->ReleaseID(elemId, vtkId);
3376
3377     this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3378     // --- to do: keep vtkid in a list of reusable cells
3379   }
3380 }
3381
3382 /*!
3383  * Checks if the element is present in mesh.
3384  * Useful to determine dead pointers.
3385  */
3386 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3387 {
3388   // we should not imply on validity of *elem, so iterate on containers
3389   // of all types in the hope of finding <elem> somewhere there
3390   SMDS_NodeIteratorPtr itn = nodesIterator();
3391   while (itn->more())
3392     if (elem == itn->next())
3393       return true;
3394   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3395   while (it0d->more())
3396     if (elem == it0d->next())
3397       return true;
3398   SMDS_EdgeIteratorPtr ite = edgesIterator();
3399   while (ite->more())
3400     if (elem == ite->next())
3401       return true;
3402   SMDS_FaceIteratorPtr itf = facesIterator();
3403   while (itf->more())
3404     if (elem == itf->next())
3405       return true;
3406   SMDS_VolumeIteratorPtr itv = volumesIterator();
3407   while (itv->more())
3408     if (elem == itv->next())
3409       return true;
3410   return false;
3411 }
3412
3413 //=======================================================================
3414 //function : MaxNodeID
3415 //purpose  :
3416 //=======================================================================
3417
3418 int SMDS_Mesh::MaxNodeID() const
3419 {
3420   return myNodeMax;
3421 }
3422
3423 //=======================================================================
3424 //function : MinNodeID
3425 //purpose  :
3426 //=======================================================================
3427
3428 int SMDS_Mesh::MinNodeID() const
3429 {
3430   return myNodeMin;
3431 }
3432
3433 //=======================================================================
3434 //function : MaxElementID
3435 //purpose  :
3436 //=======================================================================
3437
3438 int SMDS_Mesh::MaxElementID() const
3439 {
3440   return myElementIDFactory->GetMaxID();
3441 }
3442
3443 //=======================================================================
3444 //function : MinElementID
3445 //purpose  :
3446 //=======================================================================
3447
3448 int SMDS_Mesh::MinElementID() const
3449 {
3450   return myElementIDFactory->GetMinID();
3451 }
3452
3453 //=======================================================================
3454 //function : Renumber
3455 //purpose  : Renumber all nodes or elements.
3456 //=======================================================================
3457
3458 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
3459 {
3460     MESSAGE("Renumber");
3461   if ( deltaID == 0 )
3462     return;
3463
3464   SMDS_MeshNodeIDFactory * idFactory =
3465     isNodes ? myNodeIDFactory : myElementIDFactory;
3466
3467   // get existing elements in the order of ID increasing
3468   map<int,SMDS_MeshElement*> elemMap;
3469   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3470   while ( idElemIt->more() ) {
3471     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3472     int id = elem->GetID();
3473     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3474   }
3475   // release their ids
3476   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3477   idFactory->Clear();
3478 //   for ( ; elemIt != elemMap.end(); elemIt++ )
3479 //   {
3480 //     int id = (*elemIt).first;
3481 //     idFactory->ReleaseID( id );
3482 //   }
3483   // set new IDs
3484   int ID = startID;
3485   elemIt = elemMap.begin();
3486   for ( ; elemIt != elemMap.end(); elemIt++ )
3487   {
3488     idFactory->BindID( ID, (*elemIt).second );
3489     ID += deltaID;
3490   }
3491 }
3492
3493 //=======================================================================
3494 //function : GetElementType
3495 //purpose  : Return type of element or node with id
3496 //=======================================================================
3497
3498 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3499 {
3500   SMDS_MeshElement* elem = 0;
3501   if( iselem )
3502     elem = myElementIDFactory->MeshElement( id );
3503   else
3504     elem = myNodeIDFactory->MeshElement( id );
3505
3506   if( !elem )
3507   {
3508     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3509     return SMDSAbs_All;
3510   }
3511   else
3512     return elem->GetType();
3513 }
3514
3515
3516
3517 //********************************************************************
3518 //********************************************************************
3519 //********                                                   *********
3520 //*****       Methods for addition of quadratic elements        ******
3521 //********                                                   *********
3522 //********************************************************************
3523 //********************************************************************
3524
3525 //=======================================================================
3526 //function : AddEdgeWithID
3527 //purpose  :
3528 //=======================================================================
3529 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3530 {
3531   return SMDS_Mesh::AddEdgeWithID
3532     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3533      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3534      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3535      ID);
3536 }
3537
3538 //=======================================================================
3539 //function : AddEdge
3540 //purpose  :
3541 //=======================================================================
3542 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3543                                   const SMDS_MeshNode* n2,
3544                                   const SMDS_MeshNode* n12)
3545 {
3546   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3547 }
3548
3549 //=======================================================================
3550 //function : AddEdgeWithID
3551 //purpose  :
3552 //=======================================================================
3553 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3554                                         const SMDS_MeshNode * n2,
3555                                         const SMDS_MeshNode * n12,
3556                                         int ID)
3557 {
3558   if ( !n1 || !n2 || !n12 ) return 0;
3559
3560   // --- retrieve nodes ID
3561   vector<vtkIdType> nodeIds;
3562   nodeIds.clear();
3563   nodeIds.push_back(n1->getVtkId());
3564   nodeIds.push_back(n2->getVtkId());
3565   nodeIds.push_back(n12->getVtkId());
3566
3567   SMDS_MeshEdge * edge = 0;
3568   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3569   edgevtk->init(nodeIds, this);
3570   if (!this->registerElement(ID,edgevtk))
3571     {
3572       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3573       myEdgePool->destroy(edgevtk);
3574       return 0;
3575     }
3576   edge = edgevtk;
3577   adjustmyCellsCapacity(ID);
3578   myCells[ID] = edge;
3579   myInfo.myNbQuadEdges++;
3580
3581 //  if (!registerElement(ID, edge)) {
3582 //        RemoveElement(edge, false);
3583 //        edge = NULL;
3584 //  }
3585   return edge;
3586
3587 }
3588
3589
3590 //=======================================================================
3591 //function : AddFace
3592 //purpose  :
3593 //=======================================================================
3594 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3595                                   const SMDS_MeshNode * n2,
3596                                   const SMDS_MeshNode * n3,
3597                                   const SMDS_MeshNode * n12,
3598                                   const SMDS_MeshNode * n23,
3599                                   const SMDS_MeshNode * n31)
3600 {
3601   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3602                                   myElementIDFactory->GetFreeID());
3603 }
3604
3605 //=======================================================================
3606 //function : AddFaceWithID
3607 //purpose  :
3608 //=======================================================================
3609 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3610                                         int n12,int n23,int n31, int ID)
3611 {
3612   return SMDS_Mesh::AddFaceWithID
3613     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3614      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3615      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3616      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3617      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3618      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3619      ID);
3620 }
3621
3622 //=======================================================================
3623 //function : AddFaceWithID
3624 //purpose  :
3625 //=======================================================================
3626 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3627                                         const SMDS_MeshNode * n2,
3628                                         const SMDS_MeshNode * n3,
3629                                         const SMDS_MeshNode * n12,
3630                                         const SMDS_MeshNode * n23,
3631                                         const SMDS_MeshNode * n31,
3632                                         int ID)
3633 {
3634   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3635   if(hasConstructionEdges()) {
3636     // creation quadratic edges - not implemented
3637     return 0;
3638   }
3639   else
3640   {
3641     // --- retrieve nodes ID
3642     vector<vtkIdType> nodeIds;
3643     nodeIds.clear();
3644     nodeIds.push_back(n1->getVtkId());
3645     nodeIds.push_back(n2->getVtkId());
3646     nodeIds.push_back(n3->getVtkId());
3647     nodeIds.push_back(n12->getVtkId());
3648     nodeIds.push_back(n23->getVtkId());
3649     nodeIds.push_back(n31->getVtkId());
3650
3651     SMDS_MeshFace * face = 0;
3652     SMDS_VtkFace *facevtk = myFacePool->getNew();
3653     facevtk->init(nodeIds, this);
3654     if (!this->registerElement(ID,facevtk))
3655       {
3656         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3657         myFacePool->destroy(facevtk);
3658         return 0;
3659       }
3660     face = facevtk;
3661     adjustmyCellsCapacity(ID);
3662     myCells[ID] = face;
3663     myInfo.myNbQuadTriangles++;
3664
3665 //    if (!registerElement(ID, face)) {
3666 //      RemoveElement(face, false);
3667 //      face = NULL;
3668 //    }
3669     return face;
3670   }
3671 }
3672
3673
3674 //=======================================================================
3675 //function : AddFace
3676 //purpose  :
3677 //=======================================================================
3678 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3679                                   const SMDS_MeshNode * n2,
3680                                   const SMDS_MeshNode * n3,
3681                                   const SMDS_MeshNode * n4,
3682                                   const SMDS_MeshNode * n12,
3683                                   const SMDS_MeshNode * n23,
3684                                   const SMDS_MeshNode * n34,
3685                                   const SMDS_MeshNode * n41)
3686 {
3687   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3688                                   myElementIDFactory->GetFreeID());
3689 }
3690
3691 //=======================================================================
3692 //function : AddFaceWithID
3693 //purpose  :
3694 //=======================================================================
3695 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3696                                         int n12,int n23,int n34,int n41, int ID)
3697 {
3698   return SMDS_Mesh::AddFaceWithID
3699     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3700      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3701      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3702      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3703      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3704      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3705      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3706      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3707      ID);
3708 }
3709
3710 //=======================================================================
3711 //function : AddFaceWithID
3712 //purpose  :
3713 //=======================================================================
3714 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3715                                         const SMDS_MeshNode * n2,
3716                                         const SMDS_MeshNode * n3,
3717                                         const SMDS_MeshNode * n4,
3718                                         const SMDS_MeshNode * n12,
3719                                         const SMDS_MeshNode * n23,
3720                                         const SMDS_MeshNode * n34,
3721                                         const SMDS_MeshNode * n41,
3722                                         int ID)
3723 {
3724   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3725   if(hasConstructionEdges()) {
3726     // creation quadratic edges - not implemented
3727         return 0;
3728   }
3729   else
3730   {
3731     // --- retrieve nodes ID
3732     vector<vtkIdType> nodeIds;
3733     nodeIds.clear();
3734     nodeIds.push_back(n1->getVtkId());
3735     nodeIds.push_back(n2->getVtkId());
3736     nodeIds.push_back(n3->getVtkId());
3737     nodeIds.push_back(n4->getVtkId());
3738     nodeIds.push_back(n12->getVtkId());
3739     nodeIds.push_back(n23->getVtkId());
3740     nodeIds.push_back(n34->getVtkId());
3741     nodeIds.push_back(n41->getVtkId());
3742
3743     SMDS_MeshFace * face = 0;
3744     SMDS_VtkFace *facevtk = myFacePool->getNew();
3745     facevtk->init(nodeIds, this);
3746     if (!this->registerElement(ID,facevtk))
3747       {
3748         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3749         myFacePool->destroy(facevtk);
3750         return 0;
3751       }
3752     face = facevtk;
3753     adjustmyCellsCapacity(ID);
3754     myCells[ID] = face;
3755     myInfo.myNbQuadQuadrangles++;
3756
3757 //    if (!registerElement(ID, face)) {
3758 //      RemoveElement(face, false);
3759 //      face = NULL;
3760 //    }
3761     return face;
3762   }
3763 }
3764
3765 //=======================================================================
3766 //function : AddFace
3767 //purpose  :
3768 //=======================================================================
3769 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3770                                   const SMDS_MeshNode * n2,
3771                                   const SMDS_MeshNode * n3,
3772                                   const SMDS_MeshNode * n4,
3773                                   const SMDS_MeshNode * n12,
3774                                   const SMDS_MeshNode * n23,
3775                                   const SMDS_MeshNode * n34,
3776                                   const SMDS_MeshNode * n41,
3777                                   const SMDS_MeshNode * nCenter)
3778 {
3779   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
3780                                   myElementIDFactory->GetFreeID());
3781 }
3782
3783 //=======================================================================
3784 //function : AddFaceWithID
3785 //purpose  :
3786 //=======================================================================
3787 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3788                                         int n12,int n23,int n34,int n41, int nCenter, int ID)
3789 {
3790   return SMDS_Mesh::AddFaceWithID
3791     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3792      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3793      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3794      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3795      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3796      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3797      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3798      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3799      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3800      ID);
3801 }
3802
3803 //=======================================================================
3804 //function : AddFaceWithID
3805 //purpose  :
3806 //=======================================================================
3807 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3808                                         const SMDS_MeshNode * n2,
3809                                         const SMDS_MeshNode * n3,
3810                                         const SMDS_MeshNode * n4,
3811                                         const SMDS_MeshNode * n12,
3812                                         const SMDS_MeshNode * n23,
3813                                         const SMDS_MeshNode * n34,
3814                                         const SMDS_MeshNode * n41,
3815                                         const SMDS_MeshNode * nCenter,
3816                                         int ID)
3817 {
3818   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
3819   if(hasConstructionEdges()) {
3820     // creation quadratic edges - not implemented
3821         return 0;
3822   }
3823   else
3824   {
3825     // --- retrieve nodes ID
3826     vector<vtkIdType> nodeIds;
3827     nodeIds.clear();
3828     nodeIds.push_back(n1->getVtkId());
3829     nodeIds.push_back(n2->getVtkId());
3830     nodeIds.push_back(n3->getVtkId());
3831     nodeIds.push_back(n4->getVtkId());
3832     nodeIds.push_back(n12->getVtkId());
3833     nodeIds.push_back(n23->getVtkId());
3834     nodeIds.push_back(n34->getVtkId());
3835     nodeIds.push_back(n41->getVtkId());
3836     nodeIds.push_back(nCenter->getVtkId());
3837
3838     SMDS_MeshFace * face = 0;
3839     SMDS_VtkFace *facevtk = myFacePool->getNew();
3840     facevtk->init(nodeIds, this);
3841     if (!this->registerElement(ID,facevtk))
3842       {
3843         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3844         myFacePool->destroy(facevtk);
3845         return 0;
3846       }
3847     face = facevtk;
3848     adjustmyCellsCapacity(ID);
3849     myCells[ID] = face;
3850     myInfo.myNbBiQuadQuadrangles++;
3851
3852 //    if (!registerElement(ID, face)) {
3853 //      RemoveElement(face, false);
3854 //      face = NULL;
3855 //    }
3856     return face;
3857   }
3858 }
3859
3860
3861 //=======================================================================
3862 //function : AddVolume
3863 //purpose  :
3864 //=======================================================================
3865 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3866                                       const SMDS_MeshNode * n2,
3867                                       const SMDS_MeshNode * n3,
3868                                       const SMDS_MeshNode * n4,
3869                                       const SMDS_MeshNode * n12,
3870                                       const SMDS_MeshNode * n23,
3871                                       const SMDS_MeshNode * n31,
3872                                       const SMDS_MeshNode * n14,
3873                                       const SMDS_MeshNode * n24,
3874                                       const SMDS_MeshNode * n34)
3875 {
3876   int ID = myElementIDFactory->GetFreeID();
3877   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3878                                                    n31, n14, n24, n34, ID);
3879   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3880   return v;
3881 }
3882
3883 //=======================================================================
3884 //function : AddVolumeWithID
3885 //purpose  :
3886 //=======================================================================
3887 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3888                                             int n12,int n23,int n31,
3889                                             int n14,int n24,int n34, int ID)
3890 {
3891   return SMDS_Mesh::AddVolumeWithID
3892     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3893      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3894      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3895      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3896      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3897      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3898      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3899      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3900      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3901      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3902      ID);
3903 }
3904
3905 //=======================================================================
3906 //function : AddVolumeWithID
3907 //purpose  : 2d order tetrahedron of 10 nodes
3908 //=======================================================================
3909 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3910                                             const SMDS_MeshNode * n2,
3911                                             const SMDS_MeshNode * n3,
3912                                             const SMDS_MeshNode * n4,
3913                                             const SMDS_MeshNode * n12,
3914                                             const SMDS_MeshNode * n23,
3915                                             const SMDS_MeshNode * n31,
3916                                             const SMDS_MeshNode * n14,
3917                                             const SMDS_MeshNode * n24,
3918                                             const SMDS_MeshNode * n34,
3919                                             int ID)
3920 {
3921   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3922     return 0;
3923   if(hasConstructionFaces()) {
3924     // creation quadratic faces - not implemented
3925     return 0;
3926   }
3927   // --- retrieve nodes ID
3928   vector<vtkIdType> nodeIds;
3929   nodeIds.clear();
3930   nodeIds.push_back(n1->getVtkId());
3931   nodeIds.push_back(n3->getVtkId());
3932   nodeIds.push_back(n2->getVtkId());
3933   nodeIds.push_back(n4->getVtkId());
3934
3935   nodeIds.push_back(n31->getVtkId());
3936   nodeIds.push_back(n23->getVtkId());
3937   nodeIds.push_back(n12->getVtkId());
3938
3939   nodeIds.push_back(n14->getVtkId());
3940   nodeIds.push_back(n34->getVtkId());
3941   nodeIds.push_back(n24->getVtkId());
3942
3943   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3944   volvtk->init(nodeIds, this);
3945   if (!this->registerElement(ID,volvtk))
3946     {
3947       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3948       myVolumePool->destroy(volvtk);
3949       return 0;
3950     }
3951   adjustmyCellsCapacity(ID);
3952   myCells[ID] = volvtk;
3953   myInfo.myNbQuadTetras++;
3954
3955 //  if (!registerElement(ID, volvtk)) {
3956 //    RemoveElement(volvtk, false);
3957 //    volvtk = NULL;
3958 //  }
3959   return volvtk;
3960 }
3961
3962
3963 //=======================================================================
3964 //function : AddVolume
3965 //purpose  :
3966 //=======================================================================
3967 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3968                                       const SMDS_MeshNode * n2,
3969                                       const SMDS_MeshNode * n3,
3970                                       const SMDS_MeshNode * n4,
3971                                       const SMDS_MeshNode * n5,
3972                                       const SMDS_MeshNode * n12,
3973                                       const SMDS_MeshNode * n23,
3974                                       const SMDS_MeshNode * n34,
3975                                       const SMDS_MeshNode * n41,
3976                                       const SMDS_MeshNode * n15,
3977                                       const SMDS_MeshNode * n25,
3978                                       const SMDS_MeshNode * n35,
3979                                       const SMDS_MeshNode * n45)
3980 {
3981   int ID = myElementIDFactory->GetFreeID();
3982   SMDS_MeshVolume * v =
3983     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3984                                n15, n25, n35, n45, ID);
3985   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3986   return v;
3987 }
3988
3989 //=======================================================================
3990 //function : AddVolumeWithID
3991 //purpose  :
3992 //=======================================================================
3993 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3994                                             int n12,int n23,int n34,int n41,
3995                                             int n15,int n25,int n35,int n45, int ID)
3996 {
3997   return SMDS_Mesh::AddVolumeWithID
3998     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3999      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4000      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4001      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4002      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4003      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4004      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4005      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4006      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4007      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4008      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4009      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
4010      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4011      ID);
4012 }
4013
4014 //=======================================================================
4015 //function : AddVolumeWithID
4016 //purpose  : 2d order pyramid of 13 nodes
4017 //=======================================================================
4018 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4019                                             const SMDS_MeshNode * n2,
4020                                             const SMDS_MeshNode * n3,
4021                                             const SMDS_MeshNode * n4,
4022                                             const SMDS_MeshNode * n5,
4023                                             const SMDS_MeshNode * n12,
4024                                             const SMDS_MeshNode * n23,
4025                                             const SMDS_MeshNode * n34,
4026                                             const SMDS_MeshNode * n41,
4027                                             const SMDS_MeshNode * n15,
4028                                             const SMDS_MeshNode * n25,
4029                                             const SMDS_MeshNode * n35,
4030                                             const SMDS_MeshNode * n45,
4031                                             int ID)
4032 {
4033   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
4034       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
4035     return 0;
4036   if(hasConstructionFaces()) {
4037     // creation quadratic faces - not implemented
4038     return 0;
4039   }
4040   // --- retrieve nodes ID
4041   vector<vtkIdType> nodeIds;
4042   nodeIds.clear();
4043   nodeIds.push_back(n1->getVtkId());
4044   nodeIds.push_back(n4->getVtkId());
4045   nodeIds.push_back(n3->getVtkId());
4046   nodeIds.push_back(n2->getVtkId());
4047   nodeIds.push_back(n5->getVtkId());
4048
4049   nodeIds.push_back(n41->getVtkId());
4050   nodeIds.push_back(n34->getVtkId());
4051   nodeIds.push_back(n23->getVtkId());
4052   nodeIds.push_back(n12->getVtkId());
4053
4054   nodeIds.push_back(n15->getVtkId());
4055   nodeIds.push_back(n45->getVtkId());
4056   nodeIds.push_back(n35->getVtkId());
4057   nodeIds.push_back(n25->getVtkId());
4058
4059   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4060   volvtk->init(nodeIds, this);
4061   if (!this->registerElement(ID,volvtk))
4062     {
4063       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4064       myVolumePool->destroy(volvtk);
4065       return 0;
4066     }
4067   adjustmyCellsCapacity(ID);
4068   myCells[ID] = volvtk;
4069   myInfo.myNbQuadPyramids++;
4070
4071 //  if (!registerElement(ID, volvtk)) {
4072 //    RemoveElement(volvtk, false);
4073 //    volvtk = NULL;
4074 //  }
4075   return volvtk;
4076 }
4077
4078
4079 //=======================================================================
4080 //function : AddVolume
4081 //purpose  :
4082 //=======================================================================
4083 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4084                                       const SMDS_MeshNode * n2,
4085                                       const SMDS_MeshNode * n3,
4086                                       const SMDS_MeshNode * n4,
4087                                       const SMDS_MeshNode * n5,
4088                                       const SMDS_MeshNode * n6,
4089                                       const SMDS_MeshNode * n12,
4090                                       const SMDS_MeshNode * n23,
4091                                       const SMDS_MeshNode * n31,
4092                                       const SMDS_MeshNode * n45,
4093                                       const SMDS_MeshNode * n56,
4094                                       const SMDS_MeshNode * n64,
4095                                       const SMDS_MeshNode * n14,
4096                                       const SMDS_MeshNode * n25,
4097                                       const SMDS_MeshNode * n36)
4098 {
4099   int ID = myElementIDFactory->GetFreeID();
4100   SMDS_MeshVolume * v =
4101     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4102                                n45, n56, n64, n14, n25, n36, ID);
4103   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4104   return v;
4105 }
4106
4107 //=======================================================================
4108 //function : AddVolumeWithID
4109 //purpose  :
4110 //=======================================================================
4111 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4112                                             int n4, int n5, int n6,
4113                                             int n12,int n23,int n31,
4114                                             int n45,int n56,int n64,
4115                                             int n14,int n25,int n36, int ID)
4116 {
4117   return SMDS_Mesh::AddVolumeWithID
4118     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4119      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4120      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4121      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4122      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4123      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4124      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4125      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4126      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4127      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4128      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4129      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4130      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4131      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4132      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4133      ID);
4134 }
4135
4136 //=======================================================================
4137 //function : AddVolumeWithID
4138 //purpose  : 2d order Pentahedron with 15 nodes
4139 //=======================================================================
4140 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4141                                             const SMDS_MeshNode * n2,
4142                                             const SMDS_MeshNode * n3,
4143                                             const SMDS_MeshNode * n4,
4144                                             const SMDS_MeshNode * n5,
4145                                             const SMDS_MeshNode * n6,
4146                                             const SMDS_MeshNode * n12,
4147                                             const SMDS_MeshNode * n23,
4148                                             const SMDS_MeshNode * n31,
4149                                             const SMDS_MeshNode * n45,
4150                                             const SMDS_MeshNode * n56,
4151                                             const SMDS_MeshNode * n64,
4152                                             const SMDS_MeshNode * n14,
4153                                             const SMDS_MeshNode * n25,
4154                                             const SMDS_MeshNode * n36,
4155                                             int ID)
4156 {
4157   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4158       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
4159     return 0;
4160   if(hasConstructionFaces()) {
4161     // creation quadratic faces - not implemented
4162     return 0;
4163   }
4164   // --- retrieve nodes ID
4165   vector<vtkIdType> nodeIds;
4166   nodeIds.clear();
4167   nodeIds.push_back(n1->getVtkId());
4168   nodeIds.push_back(n2->getVtkId());
4169   nodeIds.push_back(n3->getVtkId());
4170
4171   nodeIds.push_back(n4->getVtkId());
4172   nodeIds.push_back(n5->getVtkId());
4173   nodeIds.push_back(n6->getVtkId());
4174
4175   nodeIds.push_back(n12->getVtkId());
4176   nodeIds.push_back(n23->getVtkId());
4177   nodeIds.push_back(n31->getVtkId());
4178
4179   nodeIds.push_back(n45->getVtkId());
4180   nodeIds.push_back(n56->getVtkId());
4181   nodeIds.push_back(n64->getVtkId());
4182
4183   nodeIds.push_back(n14->getVtkId());
4184   nodeIds.push_back(n25->getVtkId());
4185   nodeIds.push_back(n36->getVtkId());
4186
4187   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4188   volvtk->init(nodeIds, this);
4189   if (!this->registerElement(ID,volvtk))
4190     {
4191       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4192       myVolumePool->destroy(volvtk);
4193       return 0;
4194     }
4195   adjustmyCellsCapacity(ID);
4196   myCells[ID] = volvtk;
4197   myInfo.myNbQuadPrisms++;
4198
4199 //  if (!registerElement(ID, volvtk)) {
4200 //    RemoveElement(volvtk, false);
4201 //    volvtk = NULL;
4202 //  }
4203   return volvtk;
4204 }
4205
4206
4207 //=======================================================================
4208 //function : AddVolume
4209 //purpose  :
4210 //=======================================================================
4211 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4212                                       const SMDS_MeshNode * n2,
4213                                       const SMDS_MeshNode * n3,
4214                                       const SMDS_MeshNode * n4,
4215                                       const SMDS_MeshNode * n5,
4216                                       const SMDS_MeshNode * n6,
4217                                       const SMDS_MeshNode * n7,
4218                                       const SMDS_MeshNode * n8,
4219                                       const SMDS_MeshNode * n12,
4220                                       const SMDS_MeshNode * n23,
4221                                       const SMDS_MeshNode * n34,
4222                                       const SMDS_MeshNode * n41,
4223                                       const SMDS_MeshNode * n56,
4224                                       const SMDS_MeshNode * n67,
4225                                       const SMDS_MeshNode * n78,
4226                                       const SMDS_MeshNode * n85,
4227                                       const SMDS_MeshNode * n15,
4228                                       const SMDS_MeshNode * n26,
4229                                       const SMDS_MeshNode * n37,
4230                                       const SMDS_MeshNode * n48)
4231 {
4232   int ID = myElementIDFactory->GetFreeID();
4233   SMDS_MeshVolume * v =
4234     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4235                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
4236   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4237   return v;
4238 }
4239
4240 //=======================================================================
4241 //function : AddVolumeWithID
4242 //purpose  :
4243 //=======================================================================
4244 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4245                                             int n5, int n6, int n7, int n8,
4246                                             int n12,int n23,int n34,int n41,
4247                                             int n56,int n67,int n78,int n85,
4248                                             int n15,int n26,int n37,int n48, int ID)
4249 {
4250   return SMDS_Mesh::AddVolumeWithID
4251     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4252      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4253      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4254      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4255      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4256      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4257      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4258      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4259      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4260      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4261      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4262      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4263      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4264      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4265      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4266      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4267      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4268      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4269      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4270      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4271      ID);
4272 }
4273
4274 //=======================================================================
4275 //function : AddVolumeWithID
4276 //purpose  : 2d order Hexahedrons with 20 nodes
4277 //=======================================================================
4278 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4279                                             const SMDS_MeshNode * n2,
4280                                             const SMDS_MeshNode * n3,
4281                                             const SMDS_MeshNode * n4,
4282                                             const SMDS_MeshNode * n5,
4283                                             const SMDS_MeshNode * n6,
4284                                             const SMDS_MeshNode * n7,
4285                                             const SMDS_MeshNode * n8,
4286                                             const SMDS_MeshNode * n12,
4287                                             const SMDS_MeshNode * n23,
4288                                             const SMDS_MeshNode * n34,
4289                                             const SMDS_MeshNode * n41,
4290                                             const SMDS_MeshNode * n56,
4291                                             const SMDS_MeshNode * n67,
4292                                             const SMDS_MeshNode * n78,
4293                                             const SMDS_MeshNode * n85,
4294                                             const SMDS_MeshNode * n15,
4295                                             const SMDS_MeshNode * n26,
4296                                             const SMDS_MeshNode * n37,
4297                                             const SMDS_MeshNode * n48,
4298                                             int ID)
4299 {
4300   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4301       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4302     return 0;
4303   if(hasConstructionFaces()) {
4304     return 0;
4305     // creation quadratic faces - not implemented
4306   }
4307   // --- retrieve nodes ID
4308   vector<vtkIdType> nodeIds;
4309   nodeIds.clear();
4310   nodeIds.push_back(n1->getVtkId());
4311   nodeIds.push_back(n4->getVtkId());
4312   nodeIds.push_back(n3->getVtkId());
4313   nodeIds.push_back(n2->getVtkId());
4314
4315   nodeIds.push_back(n5->getVtkId());
4316   nodeIds.push_back(n8->getVtkId());
4317   nodeIds.push_back(n7->getVtkId());
4318   nodeIds.push_back(n6->getVtkId());
4319
4320   nodeIds.push_back(n41->getVtkId());
4321   nodeIds.push_back(n34->getVtkId());
4322   nodeIds.push_back(n23->getVtkId());
4323   nodeIds.push_back(n12->getVtkId());
4324
4325   nodeIds.push_back(n85->getVtkId());
4326   nodeIds.push_back(n78->getVtkId());
4327   nodeIds.push_back(n67->getVtkId());
4328   nodeIds.push_back(n56->getVtkId());
4329
4330   nodeIds.push_back(n15->getVtkId());
4331   nodeIds.push_back(n48->getVtkId());
4332   nodeIds.push_back(n37->getVtkId());
4333   nodeIds.push_back(n26->getVtkId());
4334
4335   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4336   volvtk->init(nodeIds, this);
4337   if (!this->registerElement(ID,volvtk))
4338     {
4339       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4340       myVolumePool->destroy(volvtk);
4341       return 0;
4342     }
4343   adjustmyCellsCapacity(ID);
4344   myCells[ID] = volvtk;
4345   myInfo.myNbQuadHexas++;
4346
4347 //  if (!registerElement(ID, volvtk)) {
4348 //    RemoveElement(volvtk, false);
4349 //    volvtk = NULL;
4350 //  }
4351   return volvtk;
4352 }
4353
4354 //=======================================================================
4355 //function : AddVolume
4356 //purpose  :
4357 //=======================================================================
4358 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4359                                       const SMDS_MeshNode * n2,
4360                                       const SMDS_MeshNode * n3,
4361                                       const SMDS_MeshNode * n4,
4362                                       const SMDS_MeshNode * n5,
4363                                       const SMDS_MeshNode * n6,
4364                                       const SMDS_MeshNode * n7,
4365                                       const SMDS_MeshNode * n8,
4366                                       const SMDS_MeshNode * n12,
4367                                       const SMDS_MeshNode * n23,
4368                                       const SMDS_MeshNode * n34,
4369                                       const SMDS_MeshNode * n41,
4370                                       const SMDS_MeshNode * n56,
4371                                       const SMDS_MeshNode * n67,
4372                                       const SMDS_MeshNode * n78,
4373                                       const SMDS_MeshNode * n85,
4374                                       const SMDS_MeshNode * n15,
4375                                       const SMDS_MeshNode * n26,
4376                                       const SMDS_MeshNode * n37,
4377                                       const SMDS_MeshNode * n48,
4378                                       const SMDS_MeshNode * n1234,
4379                                       const SMDS_MeshNode * n1256,
4380                                       const SMDS_MeshNode * n2367,
4381                                       const SMDS_MeshNode * n3478,
4382                                       const SMDS_MeshNode * n1458,
4383                                       const SMDS_MeshNode * n5678,
4384                                       const SMDS_MeshNode * nCenter)
4385 {
4386   int ID = myElementIDFactory->GetFreeID();
4387   SMDS_MeshVolume * v =
4388     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4389                                n56, n67, n78, n85, n15, n26, n37, n48,
4390                                n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
4391                                ID);
4392   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4393   return v;
4394 }
4395
4396 //=======================================================================
4397 //function : AddVolumeWithID
4398 //purpose  :
4399 //=======================================================================
4400 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4401                                             int n5, int n6, int n7, int n8,
4402                                             int n12,int n23,int n34,int n41,
4403                                             int n56,int n67,int n78,int n85,
4404                                             int n15,int n26,int n37,int n48,
4405                                             int n1234,int n1256,int n2367,int n3478,
4406                                             int n1458,int n5678,int nCenter, int ID)
4407 {
4408   return SMDS_Mesh::AddVolumeWithID
4409     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4410      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4411      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4412      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4413      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4414      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4415      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4416      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4417      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4418      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4419      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4420      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4421      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4422      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4423      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4424      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4425      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4426      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4427      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4428      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4429      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
4430      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
4431      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
4432      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
4433      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
4434      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
4435      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
4436      ID);
4437 }
4438
4439 //=======================================================================
4440 //function : AddVolumeWithID
4441 //purpose  : 2d order Hexahedrons with 20 nodes
4442 //=======================================================================
4443 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4444                                             const SMDS_MeshNode * n2,
4445                                             const SMDS_MeshNode * n3,
4446                                             const SMDS_MeshNode * n4,
4447                                             const SMDS_MeshNode * n5,
4448                                             const SMDS_MeshNode * n6,
4449                                             const SMDS_MeshNode * n7,
4450                                             const SMDS_MeshNode * n8,
4451                                             const SMDS_MeshNode * n12,
4452                                             const SMDS_MeshNode * n23,
4453                                             const SMDS_MeshNode * n34,
4454                                             const SMDS_MeshNode * n41,
4455                                             const SMDS_MeshNode * n56,
4456                                             const SMDS_MeshNode * n67,
4457                                             const SMDS_MeshNode * n78,
4458                                             const SMDS_MeshNode * n85,
4459                                             const SMDS_MeshNode * n15,
4460                                             const SMDS_MeshNode * n26,
4461                                             const SMDS_MeshNode * n37,
4462                                             const SMDS_MeshNode * n48,
4463                                             const SMDS_MeshNode * n1234,
4464                                             const SMDS_MeshNode * n1256,
4465                                             const SMDS_MeshNode * n2367,
4466                                             const SMDS_MeshNode * n3478,
4467                                             const SMDS_MeshNode * n1458,
4468                                             const SMDS_MeshNode * n5678,
4469                                             const SMDS_MeshNode * nCenter,
4470                                             int ID)
4471 {
4472   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4473       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
4474       !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
4475     return 0;
4476   if(hasConstructionFaces()) {
4477     return 0;
4478     // creation quadratic faces - not implemented
4479   }
4480   // --- retrieve nodes ID
4481   vector<vtkIdType> nodeIds;
4482   nodeIds.clear();
4483   nodeIds.push_back(n1->getVtkId());
4484   nodeIds.push_back(n4->getVtkId());
4485   nodeIds.push_back(n3->getVtkId());
4486   nodeIds.push_back(n2->getVtkId());
4487
4488   nodeIds.push_back(n5->getVtkId());
4489   nodeIds.push_back(n8->getVtkId());
4490   nodeIds.push_back(n7->getVtkId());
4491   nodeIds.push_back(n6->getVtkId());
4492
4493   nodeIds.push_back(n41->getVtkId());
4494   nodeIds.push_back(n34->getVtkId());
4495   nodeIds.push_back(n23->getVtkId());
4496   nodeIds.push_back(n12->getVtkId());
4497
4498   nodeIds.push_back(n85->getVtkId());
4499   nodeIds.push_back(n78->getVtkId());
4500   nodeIds.push_back(n67->getVtkId());
4501   nodeIds.push_back(n56->getVtkId());
4502
4503   nodeIds.push_back(n15->getVtkId());
4504   nodeIds.push_back(n48->getVtkId());
4505   nodeIds.push_back(n37->getVtkId());
4506   nodeIds.push_back(n26->getVtkId());
4507
4508   nodeIds.push_back(n1256->getVtkId());
4509   nodeIds.push_back(n3478->getVtkId());
4510   nodeIds.push_back(n1458->getVtkId());
4511   nodeIds.push_back(n2367->getVtkId());
4512   nodeIds.push_back(n1234->getVtkId());
4513   nodeIds.push_back(n5678->getVtkId());
4514   nodeIds.push_back(nCenter->getVtkId());
4515
4516   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4517   volvtk->init(nodeIds, this);
4518   if (!this->registerElement(ID,volvtk))
4519     {
4520       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4521       myVolumePool->destroy(volvtk);
4522       return 0;
4523     }
4524   adjustmyCellsCapacity(ID);
4525   myCells[ID] = volvtk;
4526   myInfo.myNbTriQuadHexas++;
4527
4528   return volvtk;
4529 }
4530
4531
4532 void SMDS_Mesh::updateNodeMinMax()
4533 {
4534   myNodeMin = 0;
4535   if (myNodes.size() == 0)
4536   {
4537         myNodeMax=0;
4538         return;
4539   }
4540   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4541     myNodeMin++;
4542   myNodeMax=myNodes.size()-1;
4543   while (!myNodes[myNodeMax] && (myNodeMin>=0))
4544     myNodeMin--;
4545 }
4546
4547 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4548 {
4549 //  int val = myCellIdSmdsToVtk.size();
4550 //  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4551 //  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4552   int val = myNodes.size();
4553   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4554   myNodes.resize(val +nbNodes, 0);
4555 }
4556
4557 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4558 {
4559   int val = myCellIdVtkToSmds.size();
4560   MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4561   myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4562   val = myCells.size();
4563   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4564   myNodes.resize(val +nbCells, 0);
4565 }
4566
4567 void SMDS_Mesh::adjustStructure()
4568 {
4569   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4570 }
4571
4572 void SMDS_Mesh::dumpGrid(string ficdump)
4573 {
4574         MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4575 //  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4576 //  aWriter->SetFileName(ficdump.c_str());
4577 //  aWriter->SetInput(myGrid);
4578 //  if(myGrid->GetNumberOfCells())
4579 //  {
4580 //    aWriter->Write();
4581 //  }
4582 //  aWriter->Delete();
4583   ficdump = ficdump + "_connectivity";
4584   ofstream ficcon(ficdump.c_str(), ios::out);
4585   int nbPoints = myGrid->GetNumberOfPoints();
4586   ficcon << "-------------------------------- points " <<  nbPoints << endl;
4587   for (int i=0; i<nbPoints; i++)
4588   {
4589         ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4590   }
4591   int nbCells = myGrid->GetNumberOfCells();
4592   ficcon << "-------------------------------- cells " <<  nbCells << endl;
4593   for (int i=0; i<nbCells; i++)
4594   {
4595 //      MESSAGE(i << " " << myGrid->GetCell(i));
4596 //      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
4597         ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4598         int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4599         vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4600         for (int j=0; j<nbptcell; j++)
4601         {
4602                 ficcon << " " <<  listid->GetId(j);
4603         }
4604         ficcon << endl;
4605   }
4606   ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
4607         vtkCellLinks *links = myGrid->GetCellLinks();
4608   for (int i=0; i<nbPoints; i++)
4609   {
4610         int ncells = links->GetNcells(i);
4611         vtkIdType *cells = links->GetCells(i);
4612         ficcon << i << " - " << ncells << " -";
4613         for (int j=0; j<ncells; j++)
4614         {
4615                 ficcon << " " << cells[j];
4616         }
4617         ficcon << endl;
4618   }
4619   ficcon.close();
4620
4621 }
4622
4623 void SMDS_Mesh::compactMesh()
4624 {
4625   MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4626 }
4627
4628 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4629 {
4630   if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4631     return myCellIdVtkToSmds[vtkid];
4632   throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4633 }
4634
4635 void SMDS_Mesh::updateBoundingBox()
4636 {
4637   xmin = 0; xmax = 0;
4638   ymin = 0; ymax = 0;
4639   zmin = 0; zmax = 0;
4640   vtkPoints *points = myGrid->GetPoints();
4641   int myNodesSize = this->myNodes.size();
4642   for (int i = 0; i < myNodesSize; i++)
4643     {
4644       if (SMDS_MeshNode *n = myNodes[i])
4645         {
4646           double coords[3];
4647           points->GetPoint(n->myVtkID, coords);
4648           if (coords[0] < xmin) xmin = coords[0];
4649           else if (coords[0] > xmax) xmax = coords[0];
4650           if (coords[1] < ymin) ymin = coords[1];
4651           else if (coords[1] > ymax) ymax = coords[1];
4652           if (coords[2] < zmin) zmin = coords[2];
4653           else if (coords[2] > zmax) zmax = coords[2];
4654         }
4655     }
4656 }
4657
4658 double SMDS_Mesh::getMaxDim()
4659 {
4660   double dmax = 1.e-3;
4661   if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4662   if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4663   if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4664   MESSAGE("getMaxDim " << dmax);
4665   return dmax;
4666 }
4667
4668 //! modification that needs compact structure and redraw
4669 void SMDS_Mesh::Modified()
4670 {
4671   if (this->myModified)
4672     {
4673       this->myModifTime++;
4674       MESSAGE("modified");
4675       myModified = false;
4676     }
4677 }
4678
4679 //! get last modification timeStamp
4680 unsigned long SMDS_Mesh::GetMTime() const
4681 {
4682   return this->myModifTime;
4683 }
4684
4685 bool SMDS_Mesh::isCompacted()
4686 {
4687   if (this->myModifTime > this->myCompactTime)
4688     {
4689       MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4690       this->myCompactTime = this->myModifTime;
4691       return false;
4692     }
4693   return true;
4694 }