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