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