Salome HOME
0021347: [CEA 497] Visualisation into SMESH and VISU of hexagonal prism cells (MED_OC...
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
1 // Copyright (C) 2007-2011  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 ///////////////////////////////////////////////////////////////////////////////
1511 /// Registers element with the given ID, maintains inverse connections
1512 ///////////////////////////////////////////////////////////////////////////////
1513 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
1514 {
1515   //MESSAGE("registerElement " << ID);
1516   if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
1517   {
1518     MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
1519     return false;
1520   }
1521
1522   element->myID = ID;
1523   element->myMeshId = myMeshId;
1524
1525   SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
1526   MYASSERT(cell);
1527   int vtkId = cell->getVtkId();  
1528   if (vtkId == -1)
1529     vtkId = myElementIDFactory->SetInVtkGrid(element);
1530
1531   if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
1532   {
1533 //     MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
1534     myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
1535   }
1536   myCellIdVtkToSmds[vtkId] = ID;
1537
1538   myElementIDFactory->updateMinMax(ID);
1539   return true;
1540 }
1541
1542 ///////////////////////////////////////////////////////////////////////////////
1543 /// Return the node whose SMDS ID is 'ID'.
1544 ///////////////////////////////////////////////////////////////////////////////
1545 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1546 {
1547   if (ID < 1 || ID >= myNodes.size())
1548   {
1549 //     MESSAGE("------------------------------------------------------------------------- ");
1550 //     MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
1551 //     MESSAGE("------------------------------------------------------------------------- ");
1552     return 0;
1553   }
1554   return (const SMDS_MeshNode *)myNodes[ID];
1555 }
1556
1557 ///////////////////////////////////////////////////////////////////////////////
1558 /// Return the node whose VTK ID is 'vtkId'.
1559 ///////////////////////////////////////////////////////////////////////////////
1560 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
1561 {
1562   // TODO if needed use mesh->nodeIdFromVtkToSmds
1563   if (vtkId < 0 || vtkId >= (myNodes.size() -1))
1564   {
1565     MESSAGE("------------------------------------------------------------------------- ");
1566     MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
1567     MESSAGE("------------------------------------------------------------------------- ");
1568     return 0;
1569   }
1570   return (const SMDS_MeshNode *)myNodes[vtkId+1];
1571 }
1572
1573 ///////////////////////////////////////////////////////////////////////////////
1574 ///Create a triangle and add it to the current mesh. This method do not bind an
1575 ///ID to the create triangle.
1576 ///////////////////////////////////////////////////////////////////////////////
1577 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1578                                           const SMDS_MeshNode * node2,
1579                                           const SMDS_MeshNode * node3,
1580                                           int ID)
1581 {
1582   if ( !node1 || !node2 || !node3) return 0;
1583   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1584   if(hasConstructionEdges())
1585   {
1586     SMDS_MeshEdge *edge1, *edge2, *edge3;
1587     edge1=FindEdgeOrCreate(node1,node2);
1588     edge2=FindEdgeOrCreate(node2,node3);
1589     edge3=FindEdgeOrCreate(node3,node1);
1590
1591     //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1592     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1593     adjustmyCellsCapacity(ID);
1594     myCells[ID] = face;
1595     myInfo.myNbTriangles++;
1596     return face;
1597   }
1598   else
1599   {
1600     // --- retrieve nodes ID
1601     vector<vtkIdType> nodeIds;
1602     nodeIds.clear();
1603     nodeIds.push_back(node1->getVtkId());
1604     nodeIds.push_back(node2->getVtkId());
1605     nodeIds.push_back(node3->getVtkId());
1606
1607     SMDS_MeshFace * face = 0;
1608     SMDS_VtkFace *facevtk = myFacePool->getNew();
1609     facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
1610     if (!this->registerElement(ID,facevtk))
1611       {
1612         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1613         myFacePool->destroy(facevtk);
1614         return 0;
1615       }
1616     face = facevtk;
1617     adjustmyCellsCapacity(ID);
1618     myCells[ID] = face;
1619     //MESSAGE("createTriangle " << ID << " " << face);
1620     myInfo.myNbTriangles++;
1621     return face;
1622   }
1623 }
1624
1625 ///////////////////////////////////////////////////////////////////////////////
1626 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1627 ///a ID to the create triangle.
1628 ///////////////////////////////////////////////////////////////////////////////
1629 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1630                                             const SMDS_MeshNode * node2,
1631                                             const SMDS_MeshNode * node3,
1632                                             const SMDS_MeshNode * node4,
1633                                             int ID)
1634 {
1635   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1636   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1637   if(hasConstructionEdges())
1638   {
1639       //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
1640     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1641     edge1=FindEdgeOrCreate(node1,node2);
1642     edge2=FindEdgeOrCreate(node2,node3);
1643     edge3=FindEdgeOrCreate(node3,node4);
1644     edge4=FindEdgeOrCreate(node4,node1);
1645
1646     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1647     adjustmyCellsCapacity(ID);
1648     myCells[ID] = face;
1649     myInfo.myNbQuadrangles++;
1650     return face;
1651   }
1652   else
1653   {
1654     // --- retrieve nodes ID
1655     vector<vtkIdType> nodeIds;
1656     nodeIds.clear();
1657     nodeIds.push_back(node1->getVtkId());
1658     nodeIds.push_back(node2->getVtkId());
1659     nodeIds.push_back(node3->getVtkId());
1660     nodeIds.push_back(node4->getVtkId());
1661
1662     SMDS_MeshFace * face = 0;
1663     SMDS_VtkFace *facevtk = myFacePool->getNew();
1664     facevtk->init(nodeIds, this);
1665     if (!this->registerElement(ID,facevtk))
1666       {
1667         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
1668         myFacePool->destroy(facevtk);
1669         return 0;
1670       }
1671     face = facevtk;
1672     adjustmyCellsCapacity(ID);
1673     myCells[ID] = face;
1674     myInfo.myNbQuadrangles++;
1675     return face;
1676   }
1677 }
1678
1679 ///////////////////////////////////////////////////////////////////////////////
1680 /// Remove a node and all the elements which own this node
1681 ///////////////////////////////////////////////////////////////////////////////
1682
1683 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1684 {
1685     MESSAGE("RemoveNode");
1686         RemoveElement(node, true);
1687 }
1688
1689 ///////////////////////////////////////////////////////////////////////////////
1690 /// Remove an edge and all the elements which own this edge
1691 ///////////////////////////////////////////////////////////////////////////////
1692
1693 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
1694 {
1695     MESSAGE("Remove0DElement");
1696   RemoveElement(elem0d,true);
1697 }
1698
1699 ///////////////////////////////////////////////////////////////////////////////
1700 /// Remove an edge and all the elements which own this edge
1701 ///////////////////////////////////////////////////////////////////////////////
1702
1703 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1704 {
1705     MESSAGE("RemoveEdge");
1706         RemoveElement(edge,true);
1707 }
1708
1709 ///////////////////////////////////////////////////////////////////////////////
1710 /// Remove an face and all the elements which own this face
1711 ///////////////////////////////////////////////////////////////////////////////
1712
1713 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1714 {
1715     MESSAGE("RemoveFace");
1716         RemoveElement(face, true);
1717 }
1718
1719 ///////////////////////////////////////////////////////////////////////////////
1720 /// Remove a volume
1721 ///////////////////////////////////////////////////////////////////////////////
1722
1723 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1724 {
1725     MESSAGE("RemoveVolume");
1726         RemoveElement(volume, true);
1727 }
1728
1729 //=======================================================================
1730 //function : RemoveFromParent
1731 //purpose  :
1732 //=======================================================================
1733
1734 bool SMDS_Mesh::RemoveFromParent()
1735 {
1736         if (myParent==NULL) return false;
1737         else return (myParent->RemoveSubMesh(this));
1738 }
1739
1740 //=======================================================================
1741 //function : RemoveSubMesh
1742 //purpose  :
1743 //=======================================================================
1744
1745 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1746 {
1747         bool found = false;
1748
1749         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1750         for (; itmsh!=myChildren.end() && !found; itmsh++)
1751         {
1752                 SMDS_Mesh * submesh = *itmsh;
1753                 if (submesh == aMesh)
1754                 {
1755                         found = true;
1756                         myChildren.erase(itmsh);
1757                 }
1758         }
1759
1760         return found;
1761 }
1762
1763 //=======================================================================
1764 //function : ChangeElementNodes
1765 //purpose  :
1766 //=======================================================================
1767
1768 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
1769                                    const SMDS_MeshNode    * nodes[],
1770                                    const int                nbnodes)
1771 {
1772   MESSAGE("SMDS_Mesh::ChangeElementNodes");
1773   // keep current nodes of elem
1774   set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
1775
1776   // change nodes
1777   bool Ok = false;
1778   SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
1779   if (cell)
1780     {
1781       Ok = cell->vtkOrder(nodes, nbnodes);
1782       Ok = cell->ChangeNodes(nodes, nbnodes);
1783     }
1784
1785   if ( Ok ) { // update InverseElements
1786
1787     set<const SMDS_MeshNode*>::iterator it;
1788
1789     // AddInverseElement to new nodes
1790     for ( int i = 0; i < nbnodes; i++ ) {
1791       it = oldNodes.find( nodes[i] );
1792       if ( it == oldNodes.end() )
1793         // new node
1794         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
1795       else
1796         // remove from oldNodes a node that remains in elem
1797         oldNodes.erase( it );
1798     }
1799     // RemoveInverseElement from the nodes removed from elem
1800     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1801     {
1802       SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
1803       n->RemoveInverseElement( cell );
1804     }
1805   }
1806
1807   return Ok;
1808 }
1809
1810 //=======================================================================
1811 //function : ChangePolyhedronNodes
1812 //purpose  : to change nodes of polyhedral volume
1813 //=======================================================================
1814 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
1815                                        const vector<const SMDS_MeshNode*>& nodes,
1816                                        const vector<int>                 & quantities)
1817 {
1818   if (elem->GetType() != SMDSAbs_Volume) {
1819     MESSAGE("WRONG ELEM TYPE");
1820     return false;
1821   }
1822
1823   const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
1824   if (!vol) {
1825     return false;
1826   }
1827
1828   // keep current nodes of elem
1829   set<const SMDS_MeshElement*> oldNodes;
1830   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1831   while (itn->more()) {
1832     oldNodes.insert(itn->next());
1833   }
1834
1835   // change nodes
1836   // TODO remove this function
1837   //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
1838   bool Ok = false;
1839   if (!Ok) {
1840     return false;
1841   }
1842
1843   // update InverseElements
1844
1845   // AddInverseElement to new nodes
1846   int nbnodes = nodes.size();
1847   set<const SMDS_MeshElement*>::iterator it;
1848   for (int i = 0; i < nbnodes; i++) {
1849     it = oldNodes.find(nodes[i]);
1850     if (it == oldNodes.end()) {
1851       // new node
1852       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1853     } else {
1854       // remove from oldNodes a node that remains in elem
1855       oldNodes.erase(it);
1856     }
1857   }
1858
1859   // RemoveInverseElement from the nodes removed from elem
1860   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1861     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1862       (const_cast<SMDS_MeshElement *>( *it ));
1863     n->RemoveInverseElement(elem);
1864   }
1865
1866   return Ok;
1867 }
1868
1869
1870 //=======================================================================
1871 //function : Find0DElement
1872 //purpose  :
1873 //=======================================================================
1874 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
1875 {
1876   const SMDS_MeshNode * node = FindNode(idnode);
1877   if(node == NULL) return NULL;
1878   return Find0DElement(node);
1879 }
1880
1881 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
1882 {
1883   if (!node) return 0;
1884   const SMDS_Mesh0DElement* toReturn = NULL;
1885   SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
1886   while (it1->more() && (toReturn == NULL)) {
1887     const SMDS_MeshElement* e = it1->next();
1888     if (e->NbNodes() == 1) {
1889       toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
1890     }
1891   }
1892   return toReturn;
1893 }
1894
1895 //=======================================================================
1896 //function : Find0DElementOrCreate
1897 //purpose  :
1898 //=======================================================================
1899 //SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
1900 //{
1901 //  if (!node) return 0;
1902 //  SMDS_Mesh0DElement * toReturn = NULL;
1903 //  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
1904 //  if (toReturn == NULL) {
1905 //    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
1906 //    toReturn = new SMDS_Mesh0DElement(node);
1907 //    my0DElements.Add(toReturn);
1908 //    myInfo.myNb0DElements++;
1909 //  }
1910 //  return toReturn;
1911 //}
1912
1913
1914 //=======================================================================
1915 //function : FindEdge
1916 //purpose  :
1917 //=======================================================================
1918
1919 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1920 {
1921   const SMDS_MeshNode * node1=FindNode(idnode1);
1922   const SMDS_MeshNode * node2=FindNode(idnode2);
1923   if((node1==NULL)||(node2==NULL)) return NULL;
1924   return FindEdge(node1,node2);
1925 }
1926
1927 //#include "Profiler.h"
1928 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1929                                          const SMDS_MeshNode * node2)
1930 {
1931   if ( !node1 ) return 0;
1932   const SMDS_MeshEdge * toReturn=NULL;
1933   //PROFILER_Init();
1934   //PROFILER_Set();
1935   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1936   //PROFILER_Get(0);
1937   //PROFILER_Set();
1938   while(it1->more()) {
1939     const SMDS_MeshElement * e = it1->next();
1940     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1941       toReturn = static_cast<const SMDS_MeshEdge*>( e );
1942       break;
1943     }
1944   }
1945   //PROFILER_Get(1);
1946   return toReturn;
1947 }
1948
1949
1950 //=======================================================================
1951 //function : FindEdgeOrCreate
1952 //purpose  :
1953 //=======================================================================
1954
1955 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1956                                            const SMDS_MeshNode * node2)
1957 {
1958   if ( !node1 || !node2) return 0;
1959   SMDS_MeshEdge * toReturn=NULL;
1960   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1961   if(toReturn==NULL) {
1962     if ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
1963     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
1964     adjustmyCellsCapacity(ID);
1965     vector<vtkIdType> nodeIds;
1966     nodeIds.clear();
1967     nodeIds.push_back(node1->getVtkId());
1968     nodeIds.push_back(node2->getVtkId());
1969
1970     SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
1971     edgevtk->init(nodeIds, this);
1972     if (!this->registerElement(ID,edgevtk))
1973       {
1974         this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
1975         myEdgePool->destroy(edgevtk);
1976         return 0;
1977       }
1978     toReturn = edgevtk;
1979     myCells[ID] = toReturn;
1980     myInfo.myNbEdges++;
1981   }
1982   return toReturn;
1983 }
1984
1985
1986 //=======================================================================
1987 //function : FindEdge
1988 //purpose  :
1989 //=======================================================================
1990
1991 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1992                                          int idnode3) const
1993 {
1994   const SMDS_MeshNode * node1=FindNode(idnode1);
1995   const SMDS_MeshNode * node2=FindNode(idnode2);
1996   const SMDS_MeshNode * node3=FindNode(idnode3);
1997   return FindEdge(node1,node2,node3);
1998 }
1999
2000 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
2001                                          const SMDS_MeshNode * node2,
2002                                          const SMDS_MeshNode * node3)
2003 {
2004   if ( !node1 ) return 0;
2005   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
2006   while(it1->more()) {
2007     const SMDS_MeshElement * e = it1->next();
2008     if ( e->NbNodes() == 3 ) {
2009       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2010       while(it2->more()) {
2011         const SMDS_MeshElement* n = it2->next();
2012         if( n!=node1 &&
2013             n!=node2 &&
2014             n!=node3 )
2015         {
2016           e = 0;
2017           break;
2018         }
2019       }
2020       if ( e )
2021         return static_cast<const SMDS_MeshEdge *> (e);
2022     }
2023   }
2024   return 0;
2025 }
2026
2027
2028 //=======================================================================
2029 //function : FindFace
2030 //purpose  :
2031 //=======================================================================
2032
2033 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2034         int idnode3) const
2035 {
2036   const SMDS_MeshNode * node1=FindNode(idnode1);
2037   const SMDS_MeshNode * node2=FindNode(idnode2);
2038   const SMDS_MeshNode * node3=FindNode(idnode3);
2039   return FindFace(node1, node2, node3);
2040 }
2041
2042 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2043                                          const SMDS_MeshNode *node2,
2044                                          const SMDS_MeshNode *node3)
2045 {
2046   if ( !node1 ) return 0;
2047   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2048   while(it1->more()) {
2049     const SMDS_MeshElement * e = it1->next();
2050     if ( e->NbNodes() == 3 ) {
2051       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2052       while(it2->more()) {
2053         const SMDS_MeshElement* n = it2->next();
2054         if( n!=node1 &&
2055             n!=node2 &&
2056             n!=node3 )
2057         {
2058           e = 0;
2059           break;
2060         }
2061       }
2062       if ( e )
2063         return static_cast<const SMDS_MeshFace *> (e);
2064     }
2065   }
2066   return 0;
2067 }
2068
2069 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2070                                            const SMDS_MeshNode *node2,
2071                                            const SMDS_MeshNode *node3)
2072 {
2073   SMDS_MeshFace * toReturn=NULL;
2074   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
2075   if(toReturn==NULL) {
2076     int ID = myElementIDFactory->GetFreeID();
2077     toReturn = createTriangle(node1,node2,node3, ID);
2078   }
2079   return toReturn;
2080 }
2081
2082
2083 //=======================================================================
2084 //function : FindFace
2085 //purpose  :
2086 //=======================================================================
2087
2088 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2089                                          int idnode3, int idnode4) const
2090 {
2091   const SMDS_MeshNode * node1=FindNode(idnode1);
2092   const SMDS_MeshNode * node2=FindNode(idnode2);
2093   const SMDS_MeshNode * node3=FindNode(idnode3);
2094   const SMDS_MeshNode * node4=FindNode(idnode4);
2095   return FindFace(node1, node2, node3, node4);
2096 }
2097
2098 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2099                                          const SMDS_MeshNode *node2,
2100                                          const SMDS_MeshNode *node3,
2101                                          const SMDS_MeshNode *node4)
2102 {
2103   if ( !node1 ) return 0;
2104   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2105   while(it1->more()) {
2106     const SMDS_MeshElement * e = it1->next();
2107     if ( e->NbNodes() == 4 ) {
2108       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2109       while(it2->more()) {
2110         const SMDS_MeshElement* n = it2->next();
2111         if( n!=node1 &&
2112             n!=node2 &&
2113             n!=node3 &&
2114             n!=node4 )
2115         {
2116           e = 0;
2117           break;
2118         }
2119       }
2120       if ( e )
2121         return static_cast<const SMDS_MeshFace *> (e);
2122     }
2123   }
2124   return 0;
2125 }
2126
2127 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
2128                                            const SMDS_MeshNode *node2,
2129                                            const SMDS_MeshNode *node3,
2130                                            const SMDS_MeshNode *node4)
2131 {
2132   SMDS_MeshFace * toReturn=NULL;
2133   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
2134   if(toReturn==NULL) {
2135     int ID = myElementIDFactory->GetFreeID();
2136     toReturn=createQuadrangle(node1,node2,node3,node4,ID);
2137   }
2138   return toReturn;
2139 }
2140
2141
2142 //=======================================================================
2143 //function : FindFace
2144 //purpose  :quadratic triangle
2145 //=======================================================================
2146
2147 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2148                                          int idnode3, int idnode4,
2149                                          int idnode5, int idnode6) const
2150 {
2151   const SMDS_MeshNode * node1 = FindNode(idnode1);
2152   const SMDS_MeshNode * node2 = FindNode(idnode2);
2153   const SMDS_MeshNode * node3 = FindNode(idnode3);
2154   const SMDS_MeshNode * node4 = FindNode(idnode4);
2155   const SMDS_MeshNode * node5 = FindNode(idnode5);
2156   const SMDS_MeshNode * node6 = FindNode(idnode6);
2157   return FindFace(node1, node2, node3, node4, node5, node6);
2158 }
2159
2160 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2161                                          const SMDS_MeshNode *node2,
2162                                          const SMDS_MeshNode *node3,
2163                                          const SMDS_MeshNode *node4,
2164                                          const SMDS_MeshNode *node5,
2165                                          const SMDS_MeshNode *node6)
2166 {
2167   if ( !node1 ) return 0;
2168   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2169   while(it1->more()) {
2170     const SMDS_MeshElement * e = it1->next();
2171     if ( e->NbNodes() == 6 ) {
2172       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2173       while(it2->more()) {
2174         const SMDS_MeshElement* n = it2->next();
2175         if( n!=node1 &&
2176             n!=node2 &&
2177             n!=node3 &&
2178             n!=node4 &&
2179             n!=node5 &&
2180             n!=node6 )
2181         {
2182           e = 0;
2183           break;
2184         }
2185       }
2186       if ( e )
2187         return static_cast<const SMDS_MeshFace *> (e);
2188     }
2189   }
2190   return 0;
2191 }
2192
2193
2194 //=======================================================================
2195 //function : FindFace
2196 //purpose  : quadratic quadrangle
2197 //=======================================================================
2198
2199 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
2200                                          int idnode3, int idnode4,
2201                                          int idnode5, int idnode6,
2202                                          int idnode7, int idnode8) const
2203 {
2204   const SMDS_MeshNode * node1 = FindNode(idnode1);
2205   const SMDS_MeshNode * node2 = FindNode(idnode2);
2206   const SMDS_MeshNode * node3 = FindNode(idnode3);
2207   const SMDS_MeshNode * node4 = FindNode(idnode4);
2208   const SMDS_MeshNode * node5 = FindNode(idnode5);
2209   const SMDS_MeshNode * node6 = FindNode(idnode6);
2210   const SMDS_MeshNode * node7 = FindNode(idnode7);
2211   const SMDS_MeshNode * node8 = FindNode(idnode8);
2212   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
2213 }
2214
2215 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
2216                                          const SMDS_MeshNode *node2,
2217                                          const SMDS_MeshNode *node3,
2218                                          const SMDS_MeshNode *node4,
2219                                          const SMDS_MeshNode *node5,
2220                                          const SMDS_MeshNode *node6,
2221                                          const SMDS_MeshNode *node7,
2222                                          const SMDS_MeshNode *node8)
2223 {
2224   if ( !node1 ) return 0;
2225   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
2226   while(it1->more()) {
2227     const SMDS_MeshElement * e = it1->next();
2228     if ( e->NbNodes() == 8 ) {
2229       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
2230       while(it2->more()) {
2231         const SMDS_MeshElement* n = it2->next();
2232         if( n!=node1 &&
2233             n!=node2 &&
2234             n!=node3 &&
2235             n!=node4 &&
2236             n!=node5 &&
2237             n!=node6 &&
2238             n!=node7 &&
2239             n!=node8 )
2240         {
2241           e = 0;
2242           break;
2243         }
2244       }
2245       if ( e )
2246         return static_cast<const SMDS_MeshFace *> (e);
2247     }
2248   }
2249   return 0;
2250 }
2251
2252
2253 //=======================================================================
2254 //function : FindElement
2255 //purpose  :
2256 //=======================================================================
2257
2258 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
2259 {
2260   if ((IDelem <= 0) || IDelem >= myCells.size())
2261   {
2262     MESSAGE("--------------------------------------------------------------------------------- ");
2263     MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
2264     MESSAGE("--------------------------------------------------------------------------------- ");
2265     // TODO raise an exception
2266     //assert(0);
2267     return 0;
2268   }
2269   return myCells[IDelem];
2270 }
2271
2272 //=======================================================================
2273 //function : FindFace
2274 //purpose  : find polygon
2275 //=======================================================================
2276
2277 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
2278 {
2279   int nbnodes = nodes_ids.size();
2280   vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
2281   for (int inode = 0; inode < nbnodes; inode++) {
2282     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
2283     if (node == NULL) return NULL;
2284     poly_nodes[inode] = node;
2285   }
2286   return FindFace(poly_nodes);
2287 }
2288
2289 const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
2290 {
2291   return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
2292 }
2293
2294
2295 //================================================================================
2296 /*!
2297  * \brief Return element based on all given nodes
2298  *  \param nodes - node of element
2299  *  \param type - type of element
2300  *  \param noMedium - true if medium nodes of quadratic element are not included in <nodes>
2301  *  \retval const SMDS_MeshElement* - found element or NULL
2302  */
2303 //================================================================================
2304
2305 const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
2306                                                 const SMDSAbs_ElementType            type,
2307                                                 const bool                           noMedium)
2308 {
2309   if ( nodes.size() > 0 && nodes[0] )
2310   {
2311     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(type);
2312     while (itF->more())
2313     {
2314       const SMDS_MeshElement* e = itF->next();
2315       int nbNodesToCheck = noMedium ? e->NbCornerNodes() : e->NbNodes();
2316       if ( nbNodesToCheck == nodes.size() )
2317       {
2318         for ( int i = 1; e && i < nodes.size(); ++ i )
2319         {
2320           int nodeIndex = e->GetNodeIndex( nodes[ i ]);
2321           if ( nodeIndex < 0 || nodeIndex >= nbNodesToCheck )
2322             e = 0;
2323         }
2324         if ( e )
2325           return static_cast<const SMDS_MeshFace *> (e);
2326       }
2327     }
2328   }
2329   return NULL;
2330 }
2331
2332 //=======================================================================
2333 //function : DumpNodes
2334 //purpose  :
2335 //=======================================================================
2336
2337 void SMDS_Mesh::DumpNodes() const
2338 {
2339         MESSAGE("dump nodes of mesh : ");
2340         SMDS_NodeIteratorPtr itnode=nodesIterator();
2341         while(itnode->more()) ; //MESSAGE(itnode->next());
2342 }
2343
2344 //=======================================================================
2345 //function : Dump0DElements
2346 //purpose  :
2347 //=======================================================================
2348 void SMDS_Mesh::Dump0DElements() const
2349 {
2350   MESSAGE("dump 0D elements of mesh : ");
2351   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2352   while(it0d->more()) ; //MESSAGE(it0d->next());
2353 }
2354
2355 //=======================================================================
2356 //function : DumpEdges
2357 //purpose  :
2358 //=======================================================================
2359
2360 void SMDS_Mesh::DumpEdges() const
2361 {
2362         MESSAGE("dump edges of mesh : ");
2363         SMDS_EdgeIteratorPtr itedge=edgesIterator();
2364         while(itedge->more()) ; //MESSAGE(itedge->next());
2365 }
2366
2367 //=======================================================================
2368 //function : DumpFaces
2369 //purpose  :
2370 //=======================================================================
2371
2372 void SMDS_Mesh::DumpFaces() const
2373 {
2374         MESSAGE("dump faces of mesh : ");
2375         SMDS_FaceIteratorPtr itface=facesIterator();
2376         while(itface->more()) ; //MESSAGE(itface->next());
2377 }
2378
2379 //=======================================================================
2380 //function : DumpVolumes
2381 //purpose  :
2382 //=======================================================================
2383
2384 void SMDS_Mesh::DumpVolumes() const
2385 {
2386         MESSAGE("dump volumes of mesh : ");
2387         SMDS_VolumeIteratorPtr itvol=volumesIterator();
2388         while(itvol->more()) ; //MESSAGE(itvol->next());
2389 }
2390
2391 //=======================================================================
2392 //function : DebugStats
2393 //purpose  :
2394 //=======================================================================
2395
2396 void SMDS_Mesh::DebugStats() const
2397 {
2398   MESSAGE("Debug stats of mesh : ");
2399
2400   MESSAGE("===== NODES ====="<<NbNodes());
2401   MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
2402   MESSAGE("===== EDGES ====="<<NbEdges());
2403   MESSAGE("===== FACES ====="<<NbFaces());
2404   MESSAGE("===== VOLUMES ====="<<NbVolumes());
2405
2406   MESSAGE("End Debug stats of mesh ");
2407
2408   //#ifdef DEB
2409
2410   SMDS_NodeIteratorPtr itnode=nodesIterator();
2411   int sizeofnodes = 0;
2412   int sizeoffaces = 0;
2413
2414   while(itnode->more())
2415   {
2416     const SMDS_MeshNode *node = itnode->next();
2417
2418     sizeofnodes += sizeof(*node);
2419
2420     SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
2421     while(it->more())
2422     {
2423       const SMDS_MeshElement *me = it->next();
2424       sizeofnodes += sizeof(me);
2425     }
2426   }
2427
2428   SMDS_FaceIteratorPtr itface=facesIterator();
2429   while(itface->more())
2430   {
2431     const SMDS_MeshElement *face = itface->next();
2432     sizeoffaces += sizeof(*face);
2433   }
2434
2435   MESSAGE("total size of node elements = " << sizeofnodes);;
2436   MESSAGE("total size of face elements = " << sizeoffaces);;
2437
2438   //#endif
2439 }
2440
2441 ///////////////////////////////////////////////////////////////////////////////
2442 /// Return the number of nodes
2443 ///////////////////////////////////////////////////////////////////////////////
2444 int SMDS_Mesh::NbNodes() const
2445 {
2446         //MESSAGE(myGrid->GetNumberOfPoints());
2447         //MESSAGE(myInfo.NbNodes());
2448         //MESSAGE(myNodeMax);
2449     return myInfo.NbNodes();
2450 }
2451
2452 ///////////////////////////////////////////////////////////////////////////////
2453 /// Return the number of 0D elements
2454 ///////////////////////////////////////////////////////////////////////////////
2455 int SMDS_Mesh::Nb0DElements() const
2456 {
2457   return myInfo.Nb0DElements(); // -PR- a verfier
2458 }
2459
2460 ///////////////////////////////////////////////////////////////////////////////
2461 /// Return the number of edges (including construction edges)
2462 ///////////////////////////////////////////////////////////////////////////////
2463 int SMDS_Mesh::NbEdges() const
2464 {
2465         return myInfo.NbEdges(); // -PR- a verfier
2466 }
2467
2468 ///////////////////////////////////////////////////////////////////////////////
2469 /// Return the number of faces (including construction faces)
2470 ///////////////////////////////////////////////////////////////////////////////
2471 int SMDS_Mesh::NbFaces() const
2472 {
2473         return myInfo.NbFaces();  // -PR- a verfier
2474 }
2475
2476 ///////////////////////////////////////////////////////////////////////////////
2477 /// Return the number of volumes
2478 ///////////////////////////////////////////////////////////////////////////////
2479 int SMDS_Mesh::NbVolumes() const
2480 {
2481         return myInfo.NbVolumes(); // -PR- a verfier
2482 }
2483
2484 ///////////////////////////////////////////////////////////////////////////////
2485 /// Return the number of child mesh of this mesh.
2486 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
2487 /// (2003-09-08) of SMESH
2488 ///////////////////////////////////////////////////////////////////////////////
2489 int SMDS_Mesh::NbSubMesh() const
2490 {
2491         return myChildren.size();
2492 }
2493
2494 ///////////////////////////////////////////////////////////////////////////////
2495 /// Destroy the mesh and all its elements
2496 /// All pointer on elements owned by this mesh become illegals.
2497 ///////////////////////////////////////////////////////////////////////////////
2498 SMDS_Mesh::~SMDS_Mesh()
2499 {
2500   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2501   while(itc!=myChildren.end())
2502   {
2503     delete *itc;
2504     itc++;
2505   }
2506
2507   if(myParent==NULL)
2508   {
2509     delete myNodeIDFactory;
2510     delete myElementIDFactory;
2511   }
2512   else
2513   {
2514     SMDS_ElemIteratorPtr eIt = elementsIterator();
2515     while ( eIt->more() )
2516       {
2517         const SMDS_MeshElement *elem = eIt->next();
2518         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2519       }
2520     SMDS_NodeIteratorPtr itn = nodesIterator();
2521     while (itn->more())
2522       {
2523         const SMDS_MeshNode *node = itn->next();
2524         ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
2525         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2526       }
2527   }
2528
2529 //   SetOfNodes::Iterator itn(myNodes);
2530 //   for (; itn.More(); itn.Next())
2531 //     delete itn.Value();
2532
2533 //   SetOf0DElements::Iterator it0d (my0DElements);
2534 //   for (; it0d.More(); it0d.Next())
2535 //   {
2536 //     SMDS_MeshElement* elem = it0d.Value();
2537 //     delete elem;
2538 //   }
2539
2540 //   SetOfEdges::Iterator ite(myEdges);
2541 //   for (; ite.More(); ite.Next())
2542 //   {
2543 //     SMDS_MeshElement* elem = ite.Value();
2544 //     delete elem;
2545 //   }
2546
2547 //   SetOfFaces::Iterator itf(myFaces);
2548 //   for (; itf.More(); itf.Next())
2549 //   {
2550 //     SMDS_MeshElement* elem = itf.Value();
2551 //     delete elem;
2552 //   }
2553
2554 //   SetOfVolumes::Iterator itv(myVolumes);
2555 //   for (; itv.More(); itv.Next())
2556 //   {
2557 //     SMDS_MeshElement* elem = itv.Value();
2558 //     delete elem;
2559 //   }
2560 }
2561
2562 //================================================================================
2563 /*!
2564  * \brief Clear all data
2565  */
2566 //================================================================================
2567
2568 void SMDS_Mesh::Clear()
2569 {
2570   MESSAGE("SMDS_Mesh::Clear");
2571   if (myParent!=NULL)
2572     {
2573     SMDS_ElemIteratorPtr eIt = elementsIterator();
2574     while ( eIt->more() )
2575       {
2576         const SMDS_MeshElement *elem = eIt->next();
2577         myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
2578       }
2579     SMDS_NodeIteratorPtr itn = nodesIterator();
2580     while (itn->more())
2581       {
2582         const SMDS_MeshNode *node = itn->next();
2583         myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
2584       }
2585     }
2586   else
2587     {
2588     myNodeIDFactory->Clear();
2589     myElementIDFactory->Clear();
2590     }
2591
2592   SMDS_ElemIteratorPtr itv = elementsIterator();
2593   while (itv->more())
2594     {
2595       SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
2596       SMDSAbs_ElementType aType = elem->GetType();
2597       switch (aType)
2598       {
2599         case SMDSAbs_0DElement:
2600           delete elem;
2601           break;
2602         case SMDSAbs_Edge:
2603            myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
2604           break;
2605         case SMDSAbs_Face:
2606           myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
2607           break;
2608         case SMDSAbs_Volume:
2609           myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
2610           break;
2611         default:
2612           break;
2613       }
2614     }
2615   myCells.clear();
2616   myCellIdVtkToSmds.clear();
2617   //myCellIdSmdsToVtk.clear();
2618
2619   SMDS_NodeIteratorPtr itn = nodesIterator();
2620   while (itn->more())
2621     {
2622       SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
2623       node->SetPosition(SMDS_SpacePosition::originSpacePosition());
2624       myNodePool->destroy(node);
2625     }
2626   myNodes.clear();
2627
2628   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2629   while(itc!=myChildren.end())
2630     (*itc)->Clear();
2631
2632   myModified = false;
2633   xmin = 0; xmax = 0;
2634   ymin = 0; ymax = 0;
2635   zmin = 0; zmax = 0;
2636
2637   myInfo.Clear();
2638
2639   myGrid->Initialize();
2640   myGrid->Allocate();
2641   vtkPoints* points = vtkPoints::New();
2642   // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
2643   // using double type for storing coordinates of nodes instead float.
2644   points->SetDataType(VTK_DOUBLE);
2645   points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
2646   myGrid->SetPoints( points );
2647   points->Delete();
2648   myGrid->BuildLinks();
2649 }
2650
2651 ///////////////////////////////////////////////////////////////////////////////
2652 /// Return true if this mesh create faces with edges.
2653 /// A false returned value mean that faces are created with nodes. A concequence
2654 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2655 ///////////////////////////////////////////////////////////////////////////////
2656 bool SMDS_Mesh::hasConstructionEdges()
2657 {
2658         return myHasConstructionEdges;
2659 }
2660
2661 ///////////////////////////////////////////////////////////////////////////////
2662 /// Return true if this mesh create volumes with faces
2663 /// A false returned value mean that volumes are created with nodes or edges.
2664 /// (see hasConstructionEdges)
2665 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2666 /// unavailable.
2667 ///////////////////////////////////////////////////////////////////////////////
2668 bool SMDS_Mesh::hasConstructionFaces()
2669 {
2670         return myHasConstructionFaces;
2671 }
2672
2673 ///////////////////////////////////////////////////////////////////////////////
2674 /// Return true if nodes are linked to the finit elements, they are belonging to.
2675 /// Currently, It always return true.
2676 ///////////////////////////////////////////////////////////////////////////////
2677 bool SMDS_Mesh::hasInverseElements()
2678 {
2679         return myHasInverseElements;
2680 }
2681
2682 ///////////////////////////////////////////////////////////////////////////////
2683 /// Make this mesh creating construction edges (see hasConstructionEdges)
2684 /// @param b true to have construction edges, else false.
2685 ///////////////////////////////////////////////////////////////////////////////
2686 void SMDS_Mesh::setConstructionEdges(bool b)
2687 {
2688         myHasConstructionEdges=b;
2689 }
2690
2691 ///////////////////////////////////////////////////////////////////////////////
2692 /// Make this mesh creating construction faces (see hasConstructionFaces)
2693 /// @param b true to have construction faces, else false.
2694 ///////////////////////////////////////////////////////////////////////////////
2695 void SMDS_Mesh::setConstructionFaces(bool b)
2696 {
2697          myHasConstructionFaces=b;
2698 }
2699
2700 ///////////////////////////////////////////////////////////////////////////////
2701 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2702 /// @param b true to link nodes to elements, else false.
2703 ///////////////////////////////////////////////////////////////////////////////
2704 void SMDS_Mesh::setInverseElements(bool b)
2705 {
2706   if(!b) MESSAGE("Error : inverseElement=false not implemented");
2707   myHasInverseElements=b;
2708 }
2709
2710 namespace {
2711
2712 ///////////////////////////////////////////////////////////////////////////////
2713 ///Iterator on NCollection_Map
2714 ///////////////////////////////////////////////////////////////////////////////
2715 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2716 struct MYNode_Map_Iterator: public FATHER
2717 {
2718   int _ctr;
2719   const MAP& _map;
2720   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2721   {
2722       _ctr = 0;
2723   }
2724
2725   bool more()
2726   {
2727       while (_ctr < _map.size())
2728       {
2729           if (_map[_ctr])
2730               return true;
2731           _ctr++;
2732       }
2733           return false;
2734   }
2735
2736   ELEM next()
2737   {
2738     ELEM current = _map[_ctr];
2739     _ctr++;
2740     return current;
2741   }
2742 };
2743
2744   template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2745   struct MYElem_Map_Iterator: public FATHER
2746   {
2747     size_t _ctr;
2748     int _type, _more;
2749     const MAP& _map;
2750     MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2751     {
2752       _ctr = 0;
2753       _type = typ;
2754       _more = _ctr < _map.size();
2755       if ( _more && ( !_map[_ctr] || ( _type != SMDSAbs_All && _map[_ctr]->GetType() != _type)))
2756         next();
2757     }
2758
2759     bool more()
2760     {
2761       return _more;
2762     }
2763
2764     ELEM next()
2765     {
2766       if ( !_more ) return NULL;
2767       ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2768       _more = 0;
2769       while ( !_more && ++_ctr < _map.size() )
2770         _more = ( _map[_ctr] && (_type == SMDSAbs_All || _map[_ctr]->GetType() == _type));
2771       return current;
2772     }
2773   };
2774
2775   //================================================================================
2776   /*!
2777    * \brief Iterator on elements in id increasing order
2778    */
2779   //================================================================================
2780
2781   template <typename ELEM=const SMDS_MeshElement*>
2782   class IdSortedIterator : public SMDS_Iterator<ELEM>
2783   {
2784     const SMDS_MeshElementIDFactory& myIDFact;
2785     int                              myID, myMaxID, myNbFound, myTotalNb;
2786     SMDSAbs_ElementType              myType;
2787     ELEM                             myElem;
2788
2789   public:
2790     IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
2791                      const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
2792                      const int                        totalNb)
2793       :myIDFact( fact ),
2794        myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
2795        myType( type ),
2796        myElem(0)
2797     {
2798       next();
2799     }
2800     bool more()
2801     {
2802       return myElem;
2803     }
2804     ELEM next()
2805     {
2806       ELEM current = myElem;
2807
2808       for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
2809         if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
2810             && myElem->GetType() != myType )
2811           myElem = 0;
2812
2813       myNbFound += bool(myElem);
2814
2815       return current;
2816     }
2817   };
2818 }
2819
2820 ///////////////////////////////////////////////////////////////////////////////
2821 /// Return an iterator on nodes of the current mesh factory
2822 ///////////////////////////////////////////////////////////////////////////////
2823
2824 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
2825 {
2826   typedef MYNode_Map_Iterator
2827     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2828   return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
2829
2830 //  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
2831 //  return ( idInceasingOrder ?
2832 //           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
2833 //           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
2834 }
2835
2836 ///////////////////////////////////////////////////////////////////////////////
2837 ///Return an iterator on 0D elements of the current mesh.
2838 ///////////////////////////////////////////////////////////////////////////////
2839
2840 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
2841 {
2842   typedef MYElem_Map_Iterator
2843     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2844   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
2845
2846 //  typedef MYNCollection_Map_Iterator
2847 //    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2848 //  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
2849 //  return ( idInceasingOrder ?
2850 //           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
2851 //                                                           SMDSAbs_0DElement,
2852 //                                                           Nb0DElements() )) :
2853 //           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
2854 }
2855
2856 ///////////////////////////////////////////////////////////////////////////////
2857 ///Return an iterator on edges of the current mesh.
2858 ///////////////////////////////////////////////////////////////////////////////
2859
2860 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
2861 {
2862   typedef MYElem_Map_Iterator
2863     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2864   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
2865
2866 //  typedef MYNCollection_Map_Iterator
2867 //    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2868 //  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
2869 //  return ( idInceasingOrder ?
2870 //           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2871 //                                                      SMDSAbs_Edge,
2872 //                                                      NbEdges() )) :
2873 //           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
2874 }
2875
2876 ///////////////////////////////////////////////////////////////////////////////
2877 ///Return an iterator on faces of the current mesh.
2878 ///////////////////////////////////////////////////////////////////////////////
2879
2880 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
2881 {
2882   typedef MYElem_Map_Iterator
2883     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2884   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
2885
2886 //  typedef MYNCollection_Map_Iterator
2887 //    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2888 //  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
2889 //  return ( idInceasingOrder ?
2890 //           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
2891 //                                                      SMDSAbs_Face,
2892 //                                                      NbFaces() )) :
2893 //           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
2894 }
2895
2896 ///////////////////////////////////////////////////////////////////////////////
2897 ///Return an iterator on volumes of the current mesh.
2898 ///////////////////////////////////////////////////////////////////////////////
2899
2900 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
2901 {
2902   typedef MYElem_Map_Iterator
2903     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2904   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
2905
2906   //  typedef MYNCollection_Map_Iterator
2907 //    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2908 //  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
2909 //  return ( idInceasingOrder ?
2910 //           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
2911 //                                                        SMDSAbs_Volume,
2912 //                                                        NbVolumes() )) :
2913 //           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
2914 }
2915
2916 ///////////////////////////////////////////////////////////////////////////////
2917 /// Return an iterator on elements of the current mesh factory
2918 ///////////////////////////////////////////////////////////////////////////////
2919 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2920 {
2921   switch (type) {
2922   case SMDSAbs_All:
2923     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2924     break;
2925   case SMDSAbs_Volume:
2926     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2927   case SMDSAbs_Face:
2928     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2929   case SMDSAbs_Edge:
2930     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2931   case SMDSAbs_0DElement:
2932     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2933   case SMDSAbs_Node:
2934     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2935     //return myNodeIDFactory->elementsIterator();
2936   default:;
2937   }
2938   return myElementIDFactory->elementsIterator();
2939 }
2940
2941 ///////////////////////////////////////////////////////////////////////////////
2942 /// Do intersection of sets (more than 2)
2943 ///////////////////////////////////////////////////////////////////////////////
2944 static set<const SMDS_MeshElement*> * intersectionOfSets(
2945         set<const SMDS_MeshElement*> vs[], int numberOfSets)
2946 {
2947         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2948         set<const SMDS_MeshElement*>* rsetB;
2949
2950         for(int i=0; i<numberOfSets-1; i++)
2951         {
2952                 rsetB=new set<const SMDS_MeshElement*>();
2953                 set_intersection(
2954                         rsetA->begin(), rsetA->end(),
2955                         vs[i+1].begin(), vs[i+1].end(),
2956                         inserter(*rsetB, rsetB->begin()));
2957                 delete rsetA;
2958                 rsetA=rsetB;
2959         }
2960         return rsetA;
2961 }
2962
2963 ///////////////////////////////////////////////////////////////////////////////
2964 /// Return the list of finite elements owning the given element: elements
2965 /// containing all the nodes of the given element, for instance faces and
2966 /// volumes containing a given edge.
2967 ///////////////////////////////////////////////////////////////////////////////
2968 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2969 {
2970         int numberOfSets=element->NbNodes();
2971         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2972
2973         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2974
2975         int i=0;
2976         while(itNodes->more())
2977         {
2978           const SMDS_MeshElement* node = itNodes->next();
2979           MYASSERT(node);
2980                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2981                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2982
2983                 //initSet[i]=set<const SMDS_MeshElement*>();
2984                 while(itFe->more())
2985                 {
2986                   const SMDS_MeshElement* elem = itFe->next();
2987                   MYASSERT(elem);
2988                   initSet[i].insert(elem);
2989
2990                 }
2991
2992                 i++;
2993         }
2994         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2995 //         MESSAGE("nb elems " << i << " intersection " << retSet->size());
2996         delete [] initSet;
2997         return retSet;
2998 }
2999
3000 ///////////////////////////////////////////////////////////////////////////////
3001 /// Return the list of nodes used only by the given elements
3002 ///////////////////////////////////////////////////////////////////////////////
3003 static set<const SMDS_MeshElement*> * getExclusiveNodes(
3004         set<const SMDS_MeshElement*>& elements)
3005 {
3006         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
3007         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
3008
3009         while(itElements!=elements.end())
3010         {
3011                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
3012                 itElements++;
3013
3014                 while(itNodes->more())
3015                 {
3016                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
3017                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3018                         set<const SMDS_MeshElement*> s;
3019                         while(itFe->more())
3020                           s.insert(itFe->next());
3021                         if(s==elements) toReturn->insert(n);
3022                 }
3023         }
3024         return toReturn;
3025 }
3026
3027 ///////////////////////////////////////////////////////////////////////////////
3028 ///Find the children of an element that are made of given nodes
3029 ///@param setOfChildren The set in which matching children will be inserted
3030 ///@param element The element were to search matching children
3031 ///@param nodes The nodes that the children must have to be selected
3032 ///////////////////////////////////////////////////////////////////////////////
3033 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
3034                                      const SMDS_MeshElement *      element,
3035                                      set<const SMDS_MeshElement*>& nodes)
3036 {
3037   switch(element->GetType())
3038     {
3039     case SMDSAbs_Node:
3040       MESSAGE("Internal Error: This should not happen");
3041       break;
3042     case SMDSAbs_0DElement:
3043       {
3044       }
3045       break;
3046     case SMDSAbs_Edge:
3047         {
3048                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3049                 while(itn->more())
3050                 {
3051                         const SMDS_MeshElement * e=itn->next();
3052                         if(nodes.find(e)!=nodes.end())
3053                         {
3054                           setOfChildren.insert(element);
3055                           break;
3056                         }
3057                 }
3058         } break;
3059     case SMDSAbs_Face:
3060         {
3061                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
3062                 while(itn->more())
3063                 {
3064                         const SMDS_MeshElement * e=itn->next();
3065                         if(nodes.find(e)!=nodes.end())
3066                         {
3067                           setOfChildren.insert(element);
3068                           break;
3069                         }
3070                 }
3071                 if(hasConstructionEdges())
3072                 {
3073                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
3074                         while(ite->more())
3075                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3076                 }
3077         } break;
3078     case SMDSAbs_Volume:
3079         {
3080                 if(hasConstructionFaces())
3081                 {
3082                         SMDS_ElemIteratorPtr ite=element->facesIterator();
3083                         while(ite->more())
3084                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3085                 }
3086                 else if(hasConstructionEdges())
3087                 {
3088                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
3089                         while(ite->more())
3090                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
3091                 }
3092         }
3093     }
3094 }
3095
3096 ///////////////////////////////////////////////////////////////////////////////
3097 ///@param elem The element to delete
3098 ///@param removenodes if true remaining nodes will be removed
3099 ///////////////////////////////////////////////////////////////////////////////
3100 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
3101                               const bool removenodes)
3102 {
3103   list<const SMDS_MeshElement *> removedElems;
3104   list<const SMDS_MeshElement *> removedNodes;
3105   RemoveElement( elem, removedElems, removedNodes, removenodes );
3106 }
3107
3108 ///////////////////////////////////////////////////////////////////////////////
3109 ///@param elem The element to delete
3110 ///@param removedElems to be filled with all removed elements
3111 ///@param removedNodes to be filled with all removed nodes
3112 ///@param removenodes if true remaining nodes will be removed
3113 ///////////////////////////////////////////////////////////////////////////////
3114 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
3115                               list<const SMDS_MeshElement *>& removedElems,
3116                               list<const SMDS_MeshElement *>& removedNodes,
3117                               bool                            removenodes)
3118 {
3119   //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
3120   // get finite elements built on elem
3121   set<const SMDS_MeshElement*> * s1;
3122   if (    (elem->GetType() == SMDSAbs_0DElement)
3123       || ((elem->GetType() == SMDSAbs_Edge) && !hasConstructionEdges())
3124       || ((elem->GetType() == SMDSAbs_Face) && !hasConstructionFaces())
3125       ||  (elem->GetType() == SMDSAbs_Volume) )
3126     {
3127       s1 = new set<const SMDS_MeshElement*> ();
3128       s1->insert(elem);
3129     }
3130   else
3131     s1 = getFinitElements(elem);
3132
3133   // get exclusive nodes (which would become free afterwards)
3134   set<const SMDS_MeshElement*> * s2;
3135   if (elem->GetType() == SMDSAbs_Node) // a node is removed
3136     {
3137       // do not remove nodes except elem
3138       s2 = new set<const SMDS_MeshElement*> ();
3139       s2->insert(elem);
3140       removenodes = true;
3141     }
3142   else
3143     s2 = getExclusiveNodes(*s1);
3144
3145   // form the set of finite and construction elements to remove
3146   set<const SMDS_MeshElement*> s3;
3147   set<const SMDS_MeshElement*>::iterator it = s1->begin();
3148   while (it != s1->end())
3149     {
3150       addChildrenWithNodes(s3, *it, *s2);
3151       s3.insert(*it);
3152       it++;
3153     }
3154   if (elem->GetType() != SMDSAbs_Node)
3155     s3.insert(elem);
3156
3157   // remove finite and construction elements
3158   it = s3.begin();
3159   while (it != s3.end())
3160     {
3161       // Remove element from <InverseElements> of its nodes
3162       SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
3163       while (itn->more())
3164         {
3165           SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
3166           n->RemoveInverseElement((*it));
3167         }
3168       int IdToRemove = (*it)->GetID();
3169       int vtkid = (*it)->getVtkId();
3170       //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
3171       //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
3172       switch ((*it)->GetType())
3173       {
3174         case SMDSAbs_Node:
3175           MYASSERT("Internal Error: This should not happen")
3176           ;
3177           break;
3178         case SMDSAbs_0DElement:
3179           if (IdToRemove >= 0)
3180             {
3181               myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
3182               myInfo.remove(*it);
3183             }
3184           removedElems.push_back((*it));
3185           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3186           delete (*it);
3187           break;
3188         case SMDSAbs_Edge:
3189           if (IdToRemove >= 0)
3190             {
3191               myCells[IdToRemove] = 0;
3192               myInfo.RemoveEdge(*it);
3193             }
3194           removedElems.push_back((*it));
3195           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3196           if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
3197             myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
3198           else
3199             delete (*it);
3200           break;
3201         case SMDSAbs_Face:
3202           if (IdToRemove >= 0)
3203             {
3204               myCells[IdToRemove] = 0;
3205               myInfo.RemoveFace(*it);
3206             }
3207           removedElems.push_back((*it));
3208           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3209           if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
3210             myFacePool->destroy((SMDS_VtkFace*) vtkElem);
3211           else
3212             delete (*it);
3213           break;
3214         case SMDSAbs_Volume:
3215           if (IdToRemove >= 0)
3216             {
3217               myCells[IdToRemove] = 0;
3218               myInfo.RemoveVolume(*it);
3219             }
3220           removedElems.push_back((*it));
3221           myElementIDFactory->ReleaseID(IdToRemove, vtkid);
3222           if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
3223             myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
3224           else
3225             delete (*it);
3226           break;
3227       }
3228       if (vtkid >= 0)
3229         {
3230           //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
3231           this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
3232         }
3233       it++;
3234     }
3235
3236   // remove exclusive (free) nodes
3237   if (removenodes)
3238     {
3239       it = s2->begin();
3240       while (it != s2->end())
3241         {
3242           int IdToRemove = (*it)->GetID();
3243           //MESSAGE( "SMDS: RM node " << IdToRemove);
3244           if (IdToRemove >= 0)
3245             {
3246               myNodes[IdToRemove] = 0;
3247               myInfo.myNbNodes--;
3248             }
3249           myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
3250           removedNodes.push_back((*it));
3251           if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
3252           {
3253             ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3254             myNodePool->destroy((SMDS_MeshNode*) vtkElem);
3255           }
3256           else
3257             delete (*it);
3258           it++;
3259         }
3260     }
3261
3262   delete s2;
3263   delete s1;
3264 }
3265
3266
3267 ///////////////////////////////////////////////////////////////////////////////
3268 ///@param elem The element to delete
3269 ///////////////////////////////////////////////////////////////////////////////
3270 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
3271 {
3272   int elemId = elem->GetID();
3273   int vtkId = elem->getVtkId();
3274   //MESSAGE("RemoveFreeElement " << elemId);
3275   SMDSAbs_ElementType aType = elem->GetType();
3276   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
3277   if (aType == SMDSAbs_Node) {
3278     //MESSAGE("Remove free node " << elemId);
3279     // only free node can be removed by this method
3280     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
3281     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
3282     if (!itFe->more()) { // free node
3283       myNodes[elemId] = 0;
3284       myInfo.myNbNodes--;
3285       ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition());
3286       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
3287       myNodeIDFactory->ReleaseID(elemId, vtkId);
3288     }
3289   } else {
3290     if (hasConstructionEdges() || hasConstructionFaces())
3291       // this methods is only for meshes without descendants
3292       return;
3293
3294     //MESSAGE("Remove free element " << elemId);
3295     // Remove element from <InverseElements> of its nodes
3296     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
3297     while (itn->more()) {
3298       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
3299         (const_cast<SMDS_MeshElement *>(itn->next()));
3300       n->RemoveInverseElement(elem);
3301     }
3302
3303     // in meshes without descendants elements are always free
3304      switch (aType) {
3305     case SMDSAbs_0DElement:
3306       myCells[elemId] = 0;
3307       myInfo.remove(elem);
3308       delete elem;
3309       break;
3310     case SMDSAbs_Edge:
3311       myCells[elemId] = 0;
3312       myInfo.RemoveEdge(elem);
3313       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
3314       break;
3315     case SMDSAbs_Face:
3316       myCells[elemId] = 0;
3317       myInfo.RemoveFace(elem);
3318       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
3319       break;
3320     case SMDSAbs_Volume:
3321       myCells[elemId] = 0;
3322       myInfo.RemoveVolume(elem);
3323       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
3324       break;
3325     default:
3326       break;
3327     }
3328     myElementIDFactory->ReleaseID(elemId, vtkId);
3329
3330     this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
3331     // --- to do: keep vtkid in a list of reusable cells
3332   }
3333 }
3334
3335 /*!
3336  * Checks if the element is present in mesh.
3337  * Useful to determine dead pointers.
3338  */
3339 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
3340 {
3341   // we should not imply on validity of *elem, so iterate on containers
3342   // of all types in the hope of finding <elem> somewhere there
3343   SMDS_NodeIteratorPtr itn = nodesIterator();
3344   while (itn->more())
3345     if (elem == itn->next())
3346       return true;
3347   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
3348   while (it0d->more())
3349     if (elem == it0d->next())
3350       return true;
3351   SMDS_EdgeIteratorPtr ite = edgesIterator();
3352   while (ite->more())
3353     if (elem == ite->next())
3354       return true;
3355   SMDS_FaceIteratorPtr itf = facesIterator();
3356   while (itf->more())
3357     if (elem == itf->next())
3358       return true;
3359   SMDS_VolumeIteratorPtr itv = volumesIterator();
3360   while (itv->more())
3361     if (elem == itv->next())
3362       return true;
3363   return false;
3364 }
3365
3366 //=======================================================================
3367 //function : MaxNodeID
3368 //purpose  :
3369 //=======================================================================
3370
3371 int SMDS_Mesh::MaxNodeID() const
3372 {
3373   return myNodeMax;
3374 }
3375
3376 //=======================================================================
3377 //function : MinNodeID
3378 //purpose  :
3379 //=======================================================================
3380
3381 int SMDS_Mesh::MinNodeID() const
3382 {
3383   return myNodeMin;
3384 }
3385
3386 //=======================================================================
3387 //function : MaxElementID
3388 //purpose  :
3389 //=======================================================================
3390
3391 int SMDS_Mesh::MaxElementID() const
3392 {
3393   return myElementIDFactory->GetMaxID();
3394 }
3395
3396 //=======================================================================
3397 //function : MinElementID
3398 //purpose  :
3399 //=======================================================================
3400
3401 int SMDS_Mesh::MinElementID() const
3402 {
3403   return myElementIDFactory->GetMinID();
3404 }
3405
3406 //=======================================================================
3407 //function : Renumber
3408 //purpose  : Renumber all nodes or elements.
3409 //=======================================================================
3410
3411 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
3412 {
3413     MESSAGE("Renumber");
3414   if ( deltaID == 0 )
3415     return;
3416
3417   SMDS_MeshNodeIDFactory * idFactory =
3418     isNodes ? myNodeIDFactory : myElementIDFactory;
3419
3420   // get existing elements in the order of ID increasing
3421   map<int,SMDS_MeshElement*> elemMap;
3422   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
3423   while ( idElemIt->more() ) {
3424     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
3425     int id = elem->GetID();
3426     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
3427   }
3428   // release their ids
3429   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
3430   idFactory->Clear();
3431 //   for ( ; elemIt != elemMap.end(); elemIt++ )
3432 //   {
3433 //     int id = (*elemIt).first;
3434 //     idFactory->ReleaseID( id );
3435 //   }
3436   // set new IDs
3437   int ID = startID;
3438   elemIt = elemMap.begin();
3439   for ( ; elemIt != elemMap.end(); elemIt++ )
3440   {
3441     idFactory->BindID( ID, (*elemIt).second );
3442     ID += deltaID;
3443   }
3444 }
3445
3446 //=======================================================================
3447 //function : GetElementType
3448 //purpose  : Return type of element or node with id
3449 //=======================================================================
3450
3451 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
3452 {
3453   SMDS_MeshElement* elem = 0;
3454   if( iselem )
3455     elem = myElementIDFactory->MeshElement( id );
3456   else
3457     elem = myNodeIDFactory->MeshElement( id );
3458
3459   if( !elem )
3460   {
3461     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3462     return SMDSAbs_All;
3463   }
3464   else
3465     return elem->GetType();
3466 }
3467
3468
3469
3470 //********************************************************************
3471 //********************************************************************
3472 //********                                                   *********
3473 //*****       Methods for addition of quadratic elements        ******
3474 //********                                                   *********
3475 //********************************************************************
3476 //********************************************************************
3477
3478 //=======================================================================
3479 //function : AddEdgeWithID
3480 //purpose  :
3481 //=======================================================================
3482 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3483 {
3484   return SMDS_Mesh::AddEdgeWithID
3485     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3486      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3487      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3488      ID);
3489 }
3490
3491 //=======================================================================
3492 //function : AddEdge
3493 //purpose  :
3494 //=======================================================================
3495 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3496                                   const SMDS_MeshNode* n2,
3497                                   const SMDS_MeshNode* n12)
3498 {
3499   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3500 }
3501
3502 //=======================================================================
3503 //function : AddEdgeWithID
3504 //purpose  :
3505 //=======================================================================
3506 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3507                                         const SMDS_MeshNode * n2,
3508                                         const SMDS_MeshNode * n12,
3509                                         int ID)
3510 {
3511   if ( !n1 || !n2 || !n12 ) return 0;
3512
3513   // --- retrieve nodes ID
3514   vector<vtkIdType> nodeIds;
3515   nodeIds.clear();
3516   nodeIds.push_back(n1->getVtkId());
3517   nodeIds.push_back(n2->getVtkId());
3518   nodeIds.push_back(n12->getVtkId());
3519
3520   SMDS_MeshEdge * edge = 0;
3521   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3522   edgevtk->init(nodeIds, this);
3523   if (!this->registerElement(ID,edgevtk))
3524     {
3525       this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
3526       myEdgePool->destroy(edgevtk);
3527       return 0;
3528     }
3529   edge = edgevtk;
3530   adjustmyCellsCapacity(ID);
3531   myCells[ID] = edge;
3532   myInfo.myNbQuadEdges++;
3533
3534 //  if (!registerElement(ID, edge)) {
3535 //        RemoveElement(edge, false);
3536 //        edge = NULL;
3537 //  }
3538   return edge;
3539
3540 }
3541
3542
3543 //=======================================================================
3544 //function : AddFace
3545 //purpose  :
3546 //=======================================================================
3547 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3548                                   const SMDS_MeshNode * n2,
3549                                   const SMDS_MeshNode * n3,
3550                                   const SMDS_MeshNode * n12,
3551                                   const SMDS_MeshNode * n23,
3552                                   const SMDS_MeshNode * n31)
3553 {
3554   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3555                                   myElementIDFactory->GetFreeID());
3556 }
3557
3558 //=======================================================================
3559 //function : AddFaceWithID
3560 //purpose  :
3561 //=======================================================================
3562 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3563                                         int n12,int n23,int n31, int ID)
3564 {
3565   return SMDS_Mesh::AddFaceWithID
3566     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3567      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3568      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3569      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3570      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3571      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3572      ID);
3573 }
3574
3575 //=======================================================================
3576 //function : AddFaceWithID
3577 //purpose  :
3578 //=======================================================================
3579 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3580                                         const SMDS_MeshNode * n2,
3581                                         const SMDS_MeshNode * n3,
3582                                         const SMDS_MeshNode * n12,
3583                                         const SMDS_MeshNode * n23,
3584                                         const SMDS_MeshNode * n31,
3585                                         int ID)
3586 {
3587   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3588   if(hasConstructionEdges()) {
3589     // creation quadratic edges - not implemented
3590     return 0;
3591   }
3592   else
3593   {
3594     // --- retrieve nodes ID
3595     vector<vtkIdType> nodeIds;
3596     nodeIds.clear();
3597     nodeIds.push_back(n1->getVtkId());
3598     nodeIds.push_back(n2->getVtkId());
3599     nodeIds.push_back(n3->getVtkId());
3600     nodeIds.push_back(n12->getVtkId());
3601     nodeIds.push_back(n23->getVtkId());
3602     nodeIds.push_back(n31->getVtkId());
3603
3604     SMDS_MeshFace * face = 0;
3605     SMDS_VtkFace *facevtk = myFacePool->getNew();
3606     facevtk->init(nodeIds, this);
3607     if (!this->registerElement(ID,facevtk))
3608       {
3609         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3610         myFacePool->destroy(facevtk);
3611         return 0;
3612       }
3613     face = facevtk;
3614     adjustmyCellsCapacity(ID);
3615     myCells[ID] = face;
3616     myInfo.myNbQuadTriangles++;
3617
3618 //    if (!registerElement(ID, face)) {
3619 //      RemoveElement(face, false);
3620 //      face = NULL;
3621 //    }
3622     return face;
3623   }
3624 }
3625
3626
3627 //=======================================================================
3628 //function : AddFace
3629 //purpose  :
3630 //=======================================================================
3631 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3632                                   const SMDS_MeshNode * n2,
3633                                   const SMDS_MeshNode * n3,
3634                                   const SMDS_MeshNode * n4,
3635                                   const SMDS_MeshNode * n12,
3636                                   const SMDS_MeshNode * n23,
3637                                   const SMDS_MeshNode * n34,
3638                                   const SMDS_MeshNode * n41)
3639 {
3640   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3641                                   myElementIDFactory->GetFreeID());
3642 }
3643
3644 //=======================================================================
3645 //function : AddFaceWithID
3646 //purpose  :
3647 //=======================================================================
3648 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3649                                         int n12,int n23,int n34,int n41, int ID)
3650 {
3651   return SMDS_Mesh::AddFaceWithID
3652     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3653      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3654      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3655      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3656      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3657      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3658      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3659      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3660      ID);
3661 }
3662
3663 //=======================================================================
3664 //function : AddFaceWithID
3665 //purpose  :
3666 //=======================================================================
3667 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3668                                         const SMDS_MeshNode * n2,
3669                                         const SMDS_MeshNode * n3,
3670                                         const SMDS_MeshNode * n4,
3671                                         const SMDS_MeshNode * n12,
3672                                         const SMDS_MeshNode * n23,
3673                                         const SMDS_MeshNode * n34,
3674                                         const SMDS_MeshNode * n41,
3675                                         int ID)
3676 {
3677   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3678   if(hasConstructionEdges()) {
3679     // creation quadratic edges - not implemented
3680         return 0;
3681   }
3682   else
3683   {
3684     // --- retrieve nodes ID
3685     vector<vtkIdType> nodeIds;
3686     nodeIds.clear();
3687     nodeIds.push_back(n1->getVtkId());
3688     nodeIds.push_back(n2->getVtkId());
3689     nodeIds.push_back(n3->getVtkId());
3690     nodeIds.push_back(n4->getVtkId());
3691     nodeIds.push_back(n12->getVtkId());
3692     nodeIds.push_back(n23->getVtkId());
3693     nodeIds.push_back(n34->getVtkId());
3694     nodeIds.push_back(n41->getVtkId());
3695
3696     SMDS_MeshFace * face = 0;
3697     SMDS_VtkFace *facevtk = myFacePool->getNew();
3698     facevtk->init(nodeIds, this);
3699     if (!this->registerElement(ID,facevtk))
3700       {
3701         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3702         myFacePool->destroy(facevtk);
3703         return 0;
3704       }
3705     face = facevtk;
3706     adjustmyCellsCapacity(ID);
3707     myCells[ID] = face;
3708     myInfo.myNbQuadQuadrangles++;
3709
3710 //    if (!registerElement(ID, face)) {
3711 //      RemoveElement(face, false);
3712 //      face = NULL;
3713 //    }
3714     return face;
3715   }
3716 }
3717
3718 //=======================================================================
3719 //function : AddFace
3720 //purpose  :
3721 //=======================================================================
3722 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3723                                   const SMDS_MeshNode * n2,
3724                                   const SMDS_MeshNode * n3,
3725                                   const SMDS_MeshNode * n4,
3726                                   const SMDS_MeshNode * n12,
3727                                   const SMDS_MeshNode * n23,
3728                                   const SMDS_MeshNode * n34,
3729                                   const SMDS_MeshNode * n41,
3730                                   const SMDS_MeshNode * nCenter)
3731 {
3732   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,nCenter,
3733                                   myElementIDFactory->GetFreeID());
3734 }
3735
3736 //=======================================================================
3737 //function : AddFaceWithID
3738 //purpose  :
3739 //=======================================================================
3740 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3741                                         int n12,int n23,int n34,int n41, int nCenter, int ID)
3742 {
3743   return SMDS_Mesh::AddFaceWithID
3744     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3745      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3746      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3747      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3748      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3749      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3750      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3751      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3752      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nCenter),
3753      ID);
3754 }
3755
3756 //=======================================================================
3757 //function : AddFaceWithID
3758 //purpose  :
3759 //=======================================================================
3760 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3761                                         const SMDS_MeshNode * n2,
3762                                         const SMDS_MeshNode * n3,
3763                                         const SMDS_MeshNode * n4,
3764                                         const SMDS_MeshNode * n12,
3765                                         const SMDS_MeshNode * n23,
3766                                         const SMDS_MeshNode * n34,
3767                                         const SMDS_MeshNode * n41,
3768                                         const SMDS_MeshNode * nCenter,
3769                                         int ID)
3770 {
3771   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
3772   if(hasConstructionEdges()) {
3773     // creation quadratic edges - not implemented
3774         return 0;
3775   }
3776   else
3777   {
3778     // --- retrieve nodes ID
3779     vector<vtkIdType> nodeIds;
3780     nodeIds.clear();
3781     nodeIds.push_back(n1->getVtkId());
3782     nodeIds.push_back(n2->getVtkId());
3783     nodeIds.push_back(n3->getVtkId());
3784     nodeIds.push_back(n4->getVtkId());
3785     nodeIds.push_back(n12->getVtkId());
3786     nodeIds.push_back(n23->getVtkId());
3787     nodeIds.push_back(n34->getVtkId());
3788     nodeIds.push_back(n41->getVtkId());
3789     nodeIds.push_back(nCenter->getVtkId());
3790
3791     SMDS_MeshFace * face = 0;
3792     SMDS_VtkFace *facevtk = myFacePool->getNew();
3793     facevtk->init(nodeIds, this);
3794     if (!this->registerElement(ID,facevtk))
3795       {
3796         this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
3797         myFacePool->destroy(facevtk);
3798         return 0;
3799       }
3800     face = facevtk;
3801     adjustmyCellsCapacity(ID);
3802     myCells[ID] = face;
3803     myInfo.myNbBiQuadQuadrangles++;
3804
3805 //    if (!registerElement(ID, face)) {
3806 //      RemoveElement(face, false);
3807 //      face = NULL;
3808 //    }
3809     return face;
3810   }
3811 }
3812
3813
3814 //=======================================================================
3815 //function : AddVolume
3816 //purpose  :
3817 //=======================================================================
3818 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3819                                       const SMDS_MeshNode * n2,
3820                                       const SMDS_MeshNode * n3,
3821                                       const SMDS_MeshNode * n4,
3822                                       const SMDS_MeshNode * n12,
3823                                       const SMDS_MeshNode * n23,
3824                                       const SMDS_MeshNode * n31,
3825                                       const SMDS_MeshNode * n14,
3826                                       const SMDS_MeshNode * n24,
3827                                       const SMDS_MeshNode * n34)
3828 {
3829   int ID = myElementIDFactory->GetFreeID();
3830   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3831                                                    n31, n14, n24, n34, ID);
3832   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3833   return v;
3834 }
3835
3836 //=======================================================================
3837 //function : AddVolumeWithID
3838 //purpose  :
3839 //=======================================================================
3840 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3841                                             int n12,int n23,int n31,
3842                                             int n14,int n24,int n34, int ID)
3843 {
3844   return SMDS_Mesh::AddVolumeWithID
3845     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3846      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3847      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3848      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3849      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3850      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3851      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3852      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3853      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3854      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3855      ID);
3856 }
3857
3858 //=======================================================================
3859 //function : AddVolumeWithID
3860 //purpose  : 2d order tetrahedron of 10 nodes
3861 //=======================================================================
3862 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3863                                             const SMDS_MeshNode * n2,
3864                                             const SMDS_MeshNode * n3,
3865                                             const SMDS_MeshNode * n4,
3866                                             const SMDS_MeshNode * n12,
3867                                             const SMDS_MeshNode * n23,
3868                                             const SMDS_MeshNode * n31,
3869                                             const SMDS_MeshNode * n14,
3870                                             const SMDS_MeshNode * n24,
3871                                             const SMDS_MeshNode * n34,
3872                                             int ID)
3873 {
3874   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3875     return 0;
3876   if(hasConstructionFaces()) {
3877     // creation quadratic faces - not implemented
3878     return 0;
3879   }
3880   // --- retrieve nodes ID
3881   vector<vtkIdType> nodeIds;
3882   nodeIds.clear();
3883   nodeIds.push_back(n1->getVtkId());
3884   nodeIds.push_back(n3->getVtkId());
3885   nodeIds.push_back(n2->getVtkId());
3886   nodeIds.push_back(n4->getVtkId());
3887
3888   nodeIds.push_back(n31->getVtkId());
3889   nodeIds.push_back(n23->getVtkId());
3890   nodeIds.push_back(n12->getVtkId());
3891
3892   nodeIds.push_back(n14->getVtkId());
3893   nodeIds.push_back(n34->getVtkId());
3894   nodeIds.push_back(n24->getVtkId());
3895
3896   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3897   volvtk->init(nodeIds, this);
3898   if (!this->registerElement(ID,volvtk))
3899     {
3900       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
3901       myVolumePool->destroy(volvtk);
3902       return 0;
3903     }
3904   adjustmyCellsCapacity(ID);
3905   myCells[ID] = volvtk;
3906   myInfo.myNbQuadTetras++;
3907
3908 //  if (!registerElement(ID, volvtk)) {
3909 //    RemoveElement(volvtk, false);
3910 //    volvtk = NULL;
3911 //  }
3912   return volvtk;
3913 }
3914
3915
3916 //=======================================================================
3917 //function : AddVolume
3918 //purpose  :
3919 //=======================================================================
3920 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3921                                       const SMDS_MeshNode * n2,
3922                                       const SMDS_MeshNode * n3,
3923                                       const SMDS_MeshNode * n4,
3924                                       const SMDS_MeshNode * n5,
3925                                       const SMDS_MeshNode * n12,
3926                                       const SMDS_MeshNode * n23,
3927                                       const SMDS_MeshNode * n34,
3928                                       const SMDS_MeshNode * n41,
3929                                       const SMDS_MeshNode * n15,
3930                                       const SMDS_MeshNode * n25,
3931                                       const SMDS_MeshNode * n35,
3932                                       const SMDS_MeshNode * n45)
3933 {
3934   int ID = myElementIDFactory->GetFreeID();
3935   SMDS_MeshVolume * v =
3936     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3937                                n15, n25, n35, n45, ID);
3938   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3939   return v;
3940 }
3941
3942 //=======================================================================
3943 //function : AddVolumeWithID
3944 //purpose  :
3945 //=======================================================================
3946 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3947                                             int n12,int n23,int n34,int n41,
3948                                             int n15,int n25,int n35,int n45, int ID)
3949 {
3950   return SMDS_Mesh::AddVolumeWithID
3951     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3952      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3953      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3954      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3955      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3956      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3957      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3958      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3959      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3960      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3961      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3962      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3963      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3964      ID);
3965 }
3966
3967 //=======================================================================
3968 //function : AddVolumeWithID
3969 //purpose  : 2d order pyramid of 13 nodes
3970 //=======================================================================
3971 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3972                                             const SMDS_MeshNode * n2,
3973                                             const SMDS_MeshNode * n3,
3974                                             const SMDS_MeshNode * n4,
3975                                             const SMDS_MeshNode * n5,
3976                                             const SMDS_MeshNode * n12,
3977                                             const SMDS_MeshNode * n23,
3978                                             const SMDS_MeshNode * n34,
3979                                             const SMDS_MeshNode * n41,
3980                                             const SMDS_MeshNode * n15,
3981                                             const SMDS_MeshNode * n25,
3982                                             const SMDS_MeshNode * n35,
3983                                             const SMDS_MeshNode * n45,
3984                                             int ID)
3985 {
3986   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3987       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3988     return 0;
3989   if(hasConstructionFaces()) {
3990     // creation quadratic faces - not implemented
3991     return 0;
3992   }
3993   // --- retrieve nodes ID
3994   vector<vtkIdType> nodeIds;
3995   nodeIds.clear();
3996   nodeIds.push_back(n1->getVtkId());
3997   nodeIds.push_back(n4->getVtkId());
3998   nodeIds.push_back(n3->getVtkId());
3999   nodeIds.push_back(n2->getVtkId());
4000   nodeIds.push_back(n5->getVtkId());
4001
4002   nodeIds.push_back(n41->getVtkId());
4003   nodeIds.push_back(n34->getVtkId());
4004   nodeIds.push_back(n23->getVtkId());
4005   nodeIds.push_back(n12->getVtkId());
4006
4007   nodeIds.push_back(n15->getVtkId());
4008   nodeIds.push_back(n45->getVtkId());
4009   nodeIds.push_back(n35->getVtkId());
4010   nodeIds.push_back(n25->getVtkId());
4011
4012   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4013   volvtk->init(nodeIds, this);
4014   if (!this->registerElement(ID,volvtk))
4015     {
4016       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4017       myVolumePool->destroy(volvtk);
4018       return 0;
4019     }
4020   adjustmyCellsCapacity(ID);
4021   myCells[ID] = volvtk;
4022   myInfo.myNbQuadPyramids++;
4023
4024 //  if (!registerElement(ID, volvtk)) {
4025 //    RemoveElement(volvtk, false);
4026 //    volvtk = NULL;
4027 //  }
4028   return volvtk;
4029 }
4030
4031
4032 //=======================================================================
4033 //function : AddVolume
4034 //purpose  :
4035 //=======================================================================
4036 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4037                                       const SMDS_MeshNode * n2,
4038                                       const SMDS_MeshNode * n3,
4039                                       const SMDS_MeshNode * n4,
4040                                       const SMDS_MeshNode * n5,
4041                                       const SMDS_MeshNode * n6,
4042                                       const SMDS_MeshNode * n12,
4043                                       const SMDS_MeshNode * n23,
4044                                       const SMDS_MeshNode * n31,
4045                                       const SMDS_MeshNode * n45,
4046                                       const SMDS_MeshNode * n56,
4047                                       const SMDS_MeshNode * n64,
4048                                       const SMDS_MeshNode * n14,
4049                                       const SMDS_MeshNode * n25,
4050                                       const SMDS_MeshNode * n36)
4051 {
4052   int ID = myElementIDFactory->GetFreeID();
4053   SMDS_MeshVolume * v =
4054     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
4055                                n45, n56, n64, n14, n25, n36, ID);
4056   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4057   return v;
4058 }
4059
4060 //=======================================================================
4061 //function : AddVolumeWithID
4062 //purpose  :
4063 //=======================================================================
4064 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
4065                                             int n4, int n5, int n6,
4066                                             int n12,int n23,int n31,
4067                                             int n45,int n56,int n64,
4068                                             int n14,int n25,int n36, int ID)
4069 {
4070   return SMDS_Mesh::AddVolumeWithID
4071     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
4072      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
4073      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
4074      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
4075      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
4076      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
4077      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4078      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4079      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
4080      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
4081      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4082      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
4083      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
4084      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
4085      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
4086      ID);
4087 }
4088
4089 //=======================================================================
4090 //function : AddVolumeWithID
4091 //purpose  : 2d order Pentahedron with 15 nodes
4092 //=======================================================================
4093 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4094                                             const SMDS_MeshNode * n2,
4095                                             const SMDS_MeshNode * n3,
4096                                             const SMDS_MeshNode * n4,
4097                                             const SMDS_MeshNode * n5,
4098                                             const SMDS_MeshNode * n6,
4099                                             const SMDS_MeshNode * n12,
4100                                             const SMDS_MeshNode * n23,
4101                                             const SMDS_MeshNode * n31,
4102                                             const SMDS_MeshNode * n45,
4103                                             const SMDS_MeshNode * n56,
4104                                             const SMDS_MeshNode * n64,
4105                                             const SMDS_MeshNode * n14,
4106                                             const SMDS_MeshNode * n25,
4107                                             const SMDS_MeshNode * n36,
4108                                             int ID)
4109 {
4110   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
4111       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
4112     return 0;
4113   if(hasConstructionFaces()) {
4114     // creation quadratic faces - not implemented
4115     return 0;
4116   }
4117   // --- retrieve nodes ID
4118   vector<vtkIdType> nodeIds;
4119   nodeIds.clear();
4120   nodeIds.push_back(n1->getVtkId());
4121   nodeIds.push_back(n2->getVtkId());
4122   nodeIds.push_back(n3->getVtkId());
4123
4124   nodeIds.push_back(n4->getVtkId());
4125   nodeIds.push_back(n5->getVtkId());
4126   nodeIds.push_back(n6->getVtkId());
4127
4128   nodeIds.push_back(n12->getVtkId());
4129   nodeIds.push_back(n23->getVtkId());
4130   nodeIds.push_back(n31->getVtkId());
4131
4132   nodeIds.push_back(n45->getVtkId());
4133   nodeIds.push_back(n56->getVtkId());
4134   nodeIds.push_back(n64->getVtkId());
4135
4136   nodeIds.push_back(n14->getVtkId());
4137   nodeIds.push_back(n25->getVtkId());
4138   nodeIds.push_back(n36->getVtkId());
4139
4140   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4141   volvtk->init(nodeIds, this);
4142   if (!this->registerElement(ID,volvtk))
4143     {
4144       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4145       myVolumePool->destroy(volvtk);
4146       return 0;
4147     }
4148   adjustmyCellsCapacity(ID);
4149   myCells[ID] = volvtk;
4150   myInfo.myNbQuadPrisms++;
4151
4152 //  if (!registerElement(ID, volvtk)) {
4153 //    RemoveElement(volvtk, false);
4154 //    volvtk = NULL;
4155 //  }
4156   return volvtk;
4157 }
4158
4159
4160 //=======================================================================
4161 //function : AddVolume
4162 //purpose  :
4163 //=======================================================================
4164 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4165                                       const SMDS_MeshNode * n2,
4166                                       const SMDS_MeshNode * n3,
4167                                       const SMDS_MeshNode * n4,
4168                                       const SMDS_MeshNode * n5,
4169                                       const SMDS_MeshNode * n6,
4170                                       const SMDS_MeshNode * n7,
4171                                       const SMDS_MeshNode * n8,
4172                                       const SMDS_MeshNode * n12,
4173                                       const SMDS_MeshNode * n23,
4174                                       const SMDS_MeshNode * n34,
4175                                       const SMDS_MeshNode * n41,
4176                                       const SMDS_MeshNode * n56,
4177                                       const SMDS_MeshNode * n67,
4178                                       const SMDS_MeshNode * n78,
4179                                       const SMDS_MeshNode * n85,
4180                                       const SMDS_MeshNode * n15,
4181                                       const SMDS_MeshNode * n26,
4182                                       const SMDS_MeshNode * n37,
4183                                       const SMDS_MeshNode * n48)
4184 {
4185   int ID = myElementIDFactory->GetFreeID();
4186   SMDS_MeshVolume * v =
4187     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4188                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
4189   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4190   return v;
4191 }
4192
4193 //=======================================================================
4194 //function : AddVolumeWithID
4195 //purpose  :
4196 //=======================================================================
4197 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4198                                             int n5, int n6, int n7, int n8,
4199                                             int n12,int n23,int n34,int n41,
4200                                             int n56,int n67,int n78,int n85,
4201                                             int n15,int n26,int n37,int n48, int ID)
4202 {
4203   return SMDS_Mesh::AddVolumeWithID
4204     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4205      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4206      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4207      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4208      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4209      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4210      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4211      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4212      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4213      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4214      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4215      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4216      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4217      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4218      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4219      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4220      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4221      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4222      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4223      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4224      ID);
4225 }
4226
4227 //=======================================================================
4228 //function : AddVolumeWithID
4229 //purpose  : 2d order Hexahedrons with 20 nodes
4230 //=======================================================================
4231 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4232                                             const SMDS_MeshNode * n2,
4233                                             const SMDS_MeshNode * n3,
4234                                             const SMDS_MeshNode * n4,
4235                                             const SMDS_MeshNode * n5,
4236                                             const SMDS_MeshNode * n6,
4237                                             const SMDS_MeshNode * n7,
4238                                             const SMDS_MeshNode * n8,
4239                                             const SMDS_MeshNode * n12,
4240                                             const SMDS_MeshNode * n23,
4241                                             const SMDS_MeshNode * n34,
4242                                             const SMDS_MeshNode * n41,
4243                                             const SMDS_MeshNode * n56,
4244                                             const SMDS_MeshNode * n67,
4245                                             const SMDS_MeshNode * n78,
4246                                             const SMDS_MeshNode * n85,
4247                                             const SMDS_MeshNode * n15,
4248                                             const SMDS_MeshNode * n26,
4249                                             const SMDS_MeshNode * n37,
4250                                             const SMDS_MeshNode * n48,
4251                                             int ID)
4252 {
4253   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4254       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
4255     return 0;
4256   if(hasConstructionFaces()) {
4257     return 0;
4258     // creation quadratic faces - not implemented
4259   }
4260   // --- retrieve nodes ID
4261   vector<vtkIdType> nodeIds;
4262   nodeIds.clear();
4263   nodeIds.push_back(n1->getVtkId());
4264   nodeIds.push_back(n4->getVtkId());
4265   nodeIds.push_back(n3->getVtkId());
4266   nodeIds.push_back(n2->getVtkId());
4267
4268   nodeIds.push_back(n5->getVtkId());
4269   nodeIds.push_back(n8->getVtkId());
4270   nodeIds.push_back(n7->getVtkId());
4271   nodeIds.push_back(n6->getVtkId());
4272
4273   nodeIds.push_back(n41->getVtkId());
4274   nodeIds.push_back(n34->getVtkId());
4275   nodeIds.push_back(n23->getVtkId());
4276   nodeIds.push_back(n12->getVtkId());
4277
4278   nodeIds.push_back(n85->getVtkId());
4279   nodeIds.push_back(n78->getVtkId());
4280   nodeIds.push_back(n67->getVtkId());
4281   nodeIds.push_back(n56->getVtkId());
4282
4283   nodeIds.push_back(n15->getVtkId());
4284   nodeIds.push_back(n48->getVtkId());
4285   nodeIds.push_back(n37->getVtkId());
4286   nodeIds.push_back(n26->getVtkId());
4287
4288   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4289   volvtk->init(nodeIds, this);
4290   if (!this->registerElement(ID,volvtk))
4291     {
4292       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4293       myVolumePool->destroy(volvtk);
4294       return 0;
4295     }
4296   adjustmyCellsCapacity(ID);
4297   myCells[ID] = volvtk;
4298   myInfo.myNbQuadHexas++;
4299
4300 //  if (!registerElement(ID, volvtk)) {
4301 //    RemoveElement(volvtk, false);
4302 //    volvtk = NULL;
4303 //  }
4304   return volvtk;
4305 }
4306
4307 //=======================================================================
4308 //function : AddVolume
4309 //purpose  :
4310 //=======================================================================
4311 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
4312                                       const SMDS_MeshNode * n2,
4313                                       const SMDS_MeshNode * n3,
4314                                       const SMDS_MeshNode * n4,
4315                                       const SMDS_MeshNode * n5,
4316                                       const SMDS_MeshNode * n6,
4317                                       const SMDS_MeshNode * n7,
4318                                       const SMDS_MeshNode * n8,
4319                                       const SMDS_MeshNode * n12,
4320                                       const SMDS_MeshNode * n23,
4321                                       const SMDS_MeshNode * n34,
4322                                       const SMDS_MeshNode * n41,
4323                                       const SMDS_MeshNode * n56,
4324                                       const SMDS_MeshNode * n67,
4325                                       const SMDS_MeshNode * n78,
4326                                       const SMDS_MeshNode * n85,
4327                                       const SMDS_MeshNode * n15,
4328                                       const SMDS_MeshNode * n26,
4329                                       const SMDS_MeshNode * n37,
4330                                       const SMDS_MeshNode * n48,
4331                                       const SMDS_MeshNode * n1234,
4332                                       const SMDS_MeshNode * n1256,
4333                                       const SMDS_MeshNode * n2367,
4334                                       const SMDS_MeshNode * n3478,
4335                                       const SMDS_MeshNode * n1458,
4336                                       const SMDS_MeshNode * n5678,
4337                                       const SMDS_MeshNode * nCenter)
4338 {
4339   int ID = myElementIDFactory->GetFreeID();
4340   SMDS_MeshVolume * v =
4341     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
4342                                n56, n67, n78, n85, n15, n26, n37, n48,
4343                                n1234, n1256, n2367, n3478, n1458, n5678, nCenter,
4344                                ID);
4345   if(v==NULL) myElementIDFactory->ReleaseID(ID);
4346   return v;
4347 }
4348
4349 //=======================================================================
4350 //function : AddVolumeWithID
4351 //purpose  :
4352 //=======================================================================
4353 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
4354                                             int n5, int n6, int n7, int n8,
4355                                             int n12,int n23,int n34,int n41,
4356                                             int n56,int n67,int n78,int n85,
4357                                             int n15,int n26,int n37,int n48,
4358                                             int n1234,int n1256,int n2367,int n3478,
4359                                             int n1458,int n5678,int nCenter, int ID)
4360 {
4361   return SMDS_Mesh::AddVolumeWithID
4362     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
4363      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
4364      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
4365      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
4366      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
4367      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
4368      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
4369      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
4370      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
4371      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
4372      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
4373      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
4374      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
4375      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
4376      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
4377      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
4378      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
4379      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
4380      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
4381      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
4382      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1234),
4383      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1256),
4384      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2367),
4385      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3478),
4386      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1458),
4387      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5678),
4388      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(nCenter),
4389      ID);
4390 }
4391
4392 //=======================================================================
4393 //function : AddVolumeWithID
4394 //purpose  : 2d order Hexahedrons with 20 nodes
4395 //=======================================================================
4396 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
4397                                             const SMDS_MeshNode * n2,
4398                                             const SMDS_MeshNode * n3,
4399                                             const SMDS_MeshNode * n4,
4400                                             const SMDS_MeshNode * n5,
4401                                             const SMDS_MeshNode * n6,
4402                                             const SMDS_MeshNode * n7,
4403                                             const SMDS_MeshNode * n8,
4404                                             const SMDS_MeshNode * n12,
4405                                             const SMDS_MeshNode * n23,
4406                                             const SMDS_MeshNode * n34,
4407                                             const SMDS_MeshNode * n41,
4408                                             const SMDS_MeshNode * n56,
4409                                             const SMDS_MeshNode * n67,
4410                                             const SMDS_MeshNode * n78,
4411                                             const SMDS_MeshNode * n85,
4412                                             const SMDS_MeshNode * n15,
4413                                             const SMDS_MeshNode * n26,
4414                                             const SMDS_MeshNode * n37,
4415                                             const SMDS_MeshNode * n48,
4416                                             const SMDS_MeshNode * n1234,
4417                                             const SMDS_MeshNode * n1256,
4418                                             const SMDS_MeshNode * n2367,
4419                                             const SMDS_MeshNode * n3478,
4420                                             const SMDS_MeshNode * n1458,
4421                                             const SMDS_MeshNode * n5678,
4422                                             const SMDS_MeshNode * nCenter,
4423                                             int ID)
4424 {
4425   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
4426       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
4427       !n1234 || !n1256 || !n2367 || !n3478 || !n1458 || !n5678 || !nCenter )
4428     return 0;
4429   if(hasConstructionFaces()) {
4430     return 0;
4431     // creation quadratic faces - not implemented
4432   }
4433   // --- retrieve nodes ID
4434   vector<vtkIdType> nodeIds;
4435   nodeIds.clear();
4436   nodeIds.push_back(n1->getVtkId());
4437   nodeIds.push_back(n4->getVtkId());
4438   nodeIds.push_back(n3->getVtkId());
4439   nodeIds.push_back(n2->getVtkId());
4440
4441   nodeIds.push_back(n5->getVtkId());
4442   nodeIds.push_back(n8->getVtkId());
4443   nodeIds.push_back(n7->getVtkId());
4444   nodeIds.push_back(n6->getVtkId());
4445
4446   nodeIds.push_back(n41->getVtkId());
4447   nodeIds.push_back(n34->getVtkId());
4448   nodeIds.push_back(n23->getVtkId());
4449   nodeIds.push_back(n12->getVtkId());
4450
4451   nodeIds.push_back(n85->getVtkId());
4452   nodeIds.push_back(n78->getVtkId());
4453   nodeIds.push_back(n67->getVtkId());
4454   nodeIds.push_back(n56->getVtkId());
4455
4456   nodeIds.push_back(n15->getVtkId());
4457   nodeIds.push_back(n48->getVtkId());
4458   nodeIds.push_back(n37->getVtkId());
4459   nodeIds.push_back(n26->getVtkId());
4460
4461   nodeIds.push_back(n1256->getVtkId());
4462   nodeIds.push_back(n3478->getVtkId());
4463   nodeIds.push_back(n1458->getVtkId());
4464   nodeIds.push_back(n2367->getVtkId());
4465   nodeIds.push_back(n1234->getVtkId());
4466   nodeIds.push_back(n5678->getVtkId());
4467   nodeIds.push_back(nCenter->getVtkId());
4468
4469   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
4470   volvtk->init(nodeIds, this);
4471   if (!this->registerElement(ID,volvtk))
4472     {
4473       this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
4474       myVolumePool->destroy(volvtk);
4475       return 0;
4476     }
4477   adjustmyCellsCapacity(ID);
4478   myCells[ID] = volvtk;
4479   myInfo.myNbTriQuadHexas++;
4480
4481   return volvtk;
4482 }
4483
4484
4485 void SMDS_Mesh::updateNodeMinMax()
4486 {
4487   myNodeMin = 0;
4488   if (myNodes.size() == 0)
4489   {
4490         myNodeMax=0;
4491         return;
4492   }
4493   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
4494     myNodeMin++;
4495   myNodeMax=myNodes.size()-1;
4496   while (!myNodes[myNodeMax] && (myNodeMin>=0))
4497     myNodeMin--;
4498 }
4499
4500 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
4501 {
4502 //  int val = myCellIdSmdsToVtk.size();
4503 //  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
4504 //  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
4505   int val = myNodes.size();
4506   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
4507   myNodes.resize(val +nbNodes, 0);
4508 }
4509
4510 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
4511 {
4512   int val = myCellIdVtkToSmds.size();
4513   MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
4514   myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
4515   val = myCells.size();
4516   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
4517   myNodes.resize(val +nbCells, 0);
4518 }
4519
4520 void SMDS_Mesh::adjustStructure()
4521 {
4522   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
4523 }
4524
4525 void SMDS_Mesh::dumpGrid(string ficdump)
4526 {
4527         MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
4528 //  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
4529 //  aWriter->SetFileName(ficdump.c_str());
4530 //  aWriter->SetInput(myGrid);
4531 //  if(myGrid->GetNumberOfCells())
4532 //  {
4533 //    aWriter->Write();
4534 //  }
4535 //  aWriter->Delete();
4536   ficdump = ficdump + "_connectivity";
4537   ofstream ficcon(ficdump.c_str(), ios::out);
4538   int nbPoints = myGrid->GetNumberOfPoints();
4539   ficcon << "-------------------------------- points " <<  nbPoints << endl;
4540   for (int i=0; i<nbPoints; i++)
4541   {
4542         ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
4543   }
4544   int nbCells = myGrid->GetNumberOfCells();
4545   ficcon << "-------------------------------- cells " <<  nbCells << endl;
4546   for (int i=0; i<nbCells; i++)
4547   {
4548 //      MESSAGE(i << " " << myGrid->GetCell(i));
4549 //      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
4550         ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
4551         int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
4552         vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
4553         for (int j=0; j<nbptcell; j++)
4554         {
4555                 ficcon << " " <<  listid->GetId(j);
4556         }
4557         ficcon << endl;
4558   }
4559   ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
4560         vtkCellLinks *links = myGrid->GetCellLinks();
4561   for (int i=0; i<nbPoints; i++)
4562   {
4563         int ncells = links->GetNcells(i);
4564         vtkIdType *cells = links->GetCells(i);
4565         ficcon << i << " - " << ncells << " -";
4566         for (int j=0; j<ncells; j++)
4567         {
4568                 ficcon << " " << cells[j];
4569         }
4570         ficcon << endl;
4571   }
4572   ficcon.close();
4573
4574 }
4575
4576 void SMDS_Mesh::compactMesh()
4577 {
4578   MESSAGE("SMDS_Mesh::compactMesh do nothing!");
4579 }
4580
4581 int SMDS_Mesh::fromVtkToSmds(int vtkid)
4582 {
4583   if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
4584     return myCellIdVtkToSmds[vtkid];
4585   throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
4586 }
4587
4588 void SMDS_Mesh::updateBoundingBox()
4589 {
4590   xmin = 0; xmax = 0;
4591   ymin = 0; ymax = 0;
4592   zmin = 0; zmax = 0;
4593   vtkPoints *points = myGrid->GetPoints();
4594   int myNodesSize = this->myNodes.size();
4595   for (int i = 0; i < myNodesSize; i++)
4596     {
4597       if (SMDS_MeshNode *n = myNodes[i])
4598         {
4599           double coords[3];
4600           points->GetPoint(n->myVtkID, coords);
4601           if (coords[0] < xmin) xmin = coords[0];
4602           else if (coords[0] > xmax) xmax = coords[0];
4603           if (coords[1] < ymin) ymin = coords[1];
4604           else if (coords[1] > ymax) ymax = coords[1];
4605           if (coords[2] < zmin) zmin = coords[2];
4606           else if (coords[2] > zmax) zmax = coords[2];
4607         }
4608     }
4609 }
4610
4611 double SMDS_Mesh::getMaxDim()
4612 {
4613   double dmax = 1.e-3;
4614   if ((xmax - xmin) > dmax) dmax = xmax -xmin;
4615   if ((ymax - ymin) > dmax) dmax = ymax -ymin;
4616   if ((zmax - zmin) > dmax) dmax = zmax -zmin;
4617   MESSAGE("getMaxDim " << dmax);
4618   return dmax;
4619 }
4620
4621 //! modification that needs compact structure and redraw
4622 void SMDS_Mesh::Modified()
4623 {
4624   if (this->myModified)
4625     {
4626       this->myModifTime++;
4627       MESSAGE("modified");
4628       myModified = false;
4629     }
4630 }
4631
4632 //! get last modification timeStamp
4633 unsigned long SMDS_Mesh::GetMTime() const
4634 {
4635   return this->myModifTime;
4636 }
4637
4638 bool SMDS_Mesh::isCompacted()
4639 {
4640   if (this->myModifTime > this->myCompactTime)
4641     {
4642       MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
4643       this->myCompactTime = this->myModifTime;
4644       return false;
4645     }
4646   return true;
4647 }