Salome HOME
1f704a681d20b72e46de6438efc7fcfbe99d5aed
[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     SMDS_ElemIteratorPtr eIt = elementsIterator();
2260     while ( eIt->more() )
2261       myElementIDFactory->ReleaseID(eIt->next()->GetID());
2262     SMDS_NodeIteratorPtr itn = nodesIterator();
2263     while (itn->more())
2264       myNodeIDFactory->ReleaseID(itn->next()->GetID());
2265   }
2266   else {
2267     myNodeIDFactory->Clear();
2268     myElementIDFactory->Clear();
2269   }
2270
2271   SMDS_ElemIteratorPtr itv = elementsIterator();
2272   while (itv->more())
2273     delete itv->next();
2274   myCells.clear();
2275
2276 //  SMDS_VolumeIteratorPtr itv = volumesIterator();
2277 //  while (itv->more())
2278 //    delete itv->next();
2279 //  myVolumes.Clear();
2280 //
2281 //  SMDS_FaceIteratorPtr itf = facesIterator();
2282 //  while (itf->more())
2283 //    delete itf->next();
2284 //  myFaces.Clear();
2285 //
2286 //  SMDS_EdgeIteratorPtr ite = edgesIterator();
2287 //  while (ite->more())
2288 //    delete ite->next();
2289 //  myEdges.Clear();
2290 //
2291 //  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2292 //  while (it0d->more())
2293 //    delete it0d->next();
2294 //  my0DElements.Clear();
2295
2296   SMDS_NodeIteratorPtr itn = nodesIterator();
2297   while (itn->more())
2298     delete itn->next();
2299   myNodes.clear();
2300
2301   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
2302   while(itc!=myChildren.end())
2303     (*itc)->Clear();
2304
2305   myInfo.Clear();
2306 }
2307
2308 ///////////////////////////////////////////////////////////////////////////////
2309 /// Return true if this mesh create faces with edges.
2310 /// A false returned value mean that faces are created with nodes. A concequence
2311 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
2312 ///////////////////////////////////////////////////////////////////////////////
2313 bool SMDS_Mesh::hasConstructionEdges()
2314 {
2315         return myHasConstructionEdges;
2316 }
2317
2318 ///////////////////////////////////////////////////////////////////////////////
2319 /// Return true if this mesh create volumes with faces
2320 /// A false returned value mean that volumes are created with nodes or edges.
2321 /// (see hasConstructionEdges)
2322 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
2323 /// unavailable.
2324 ///////////////////////////////////////////////////////////////////////////////
2325 bool SMDS_Mesh::hasConstructionFaces()
2326 {
2327         return myHasConstructionFaces;
2328 }
2329
2330 ///////////////////////////////////////////////////////////////////////////////
2331 /// Return true if nodes are linked to the finit elements, they are belonging to.
2332 /// Currently, It always return true.
2333 ///////////////////////////////////////////////////////////////////////////////
2334 bool SMDS_Mesh::hasInverseElements()
2335 {
2336         return myHasInverseElements;
2337 }
2338
2339 ///////////////////////////////////////////////////////////////////////////////
2340 /// Make this mesh creating construction edges (see hasConstructionEdges)
2341 /// @param b true to have construction edges, else false.
2342 ///////////////////////////////////////////////////////////////////////////////
2343 void SMDS_Mesh::setConstructionEdges(bool b)
2344 {
2345         myHasConstructionEdges=b;
2346 }
2347
2348 ///////////////////////////////////////////////////////////////////////////////
2349 /// Make this mesh creating construction faces (see hasConstructionFaces)
2350 /// @param b true to have construction faces, else false.
2351 ///////////////////////////////////////////////////////////////////////////////
2352 void SMDS_Mesh::setConstructionFaces(bool b)
2353 {
2354          myHasConstructionFaces=b;
2355 }
2356
2357 ///////////////////////////////////////////////////////////////////////////////
2358 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
2359 /// @param b true to link nodes to elements, else false.
2360 ///////////////////////////////////////////////////////////////////////////////
2361 void SMDS_Mesh::setInverseElements(bool b)
2362 {
2363         if(!b) MESSAGE("Error : inverseElement=false not implemented");
2364         myHasInverseElements=b;
2365 }
2366
2367 ///////////////////////////////////////////////////////////////////////////////
2368 ///Iterator on NCollection_Map
2369 ///////////////////////////////////////////////////////////////////////////////
2370 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2371 struct MYNode_Map_Iterator: public FATHER
2372 {
2373   int _ctr;
2374   const MAP& _map;
2375   MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
2376   {
2377       _ctr = 0;
2378   }
2379
2380   bool more()
2381   {
2382       while (_ctr < _map.size())
2383       {
2384           if (_map[_ctr])
2385               return true;
2386           _ctr++;
2387       }
2388           return false;
2389   }
2390
2391   ELEM next()
2392   {
2393     ELEM current = _map[_ctr];
2394     _ctr++;
2395     return current;
2396   }
2397 };
2398
2399 template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
2400 struct MYElem_Map_Iterator: public FATHER
2401 {
2402   int _ctr;
2403   int _type;
2404   const MAP& _map;
2405   MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
2406   {
2407       _ctr = 0;
2408       _type = typ;
2409   }
2410
2411   bool more()
2412   {
2413       while (_ctr < _map.size())
2414       {
2415           if (_map[_ctr])
2416             if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
2417               return true;
2418           _ctr++;
2419       }
2420           return false;
2421   }
2422
2423   ELEM next()
2424   {
2425     ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
2426     _ctr++;
2427     return current;
2428   }
2429 };
2430
2431 ///////////////////////////////////////////////////////////////////////////////
2432 /// Return an iterator on nodes of the current mesh factory
2433 ///////////////////////////////////////////////////////////////////////////////
2434
2435 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
2436 {
2437   //return SMDS_NodeIteratorPtr
2438   //  (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
2439   typedef MYNode_Map_Iterator
2440     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
2441   return SMDS_NodeIteratorPtr(new TIterator(myNodes));
2442 }
2443
2444 ///////////////////////////////////////////////////////////////////////////////
2445 ///Return an iterator on 0D elements of the current mesh.
2446 ///////////////////////////////////////////////////////////////////////////////
2447
2448 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
2449 {
2450   typedef MYElem_Map_Iterator
2451     < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
2452   return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
2453 }
2454
2455 ///////////////////////////////////////////////////////////////////////////////
2456 ///Return an iterator on edges of the current mesh.
2457 ///////////////////////////////////////////////////////////////////////////////
2458
2459 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
2460 {
2461   typedef MYElem_Map_Iterator
2462     < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
2463   return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
2464 }
2465
2466 ///////////////////////////////////////////////////////////////////////////////
2467 ///Return an iterator on faces of the current mesh.
2468 ///////////////////////////////////////////////////////////////////////////////
2469
2470 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2471 {
2472   typedef MYElem_Map_Iterator
2473     < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
2474   return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
2475 }
2476
2477 ///////////////////////////////////////////////////////////////////////////////
2478 ///Return an iterator on volumes of the current mesh.
2479 ///////////////////////////////////////////////////////////////////////////////
2480
2481 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2482 {
2483   typedef MYElem_Map_Iterator
2484     < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
2485   return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
2486 }
2487
2488 ///////////////////////////////////////////////////////////////////////////////
2489 /// Return an iterator on elements of the current mesh factory
2490 ///////////////////////////////////////////////////////////////////////////////
2491 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
2492 {
2493   switch (type) {
2494   case SMDSAbs_All:
2495     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
2496     break;
2497   case SMDSAbs_Volume:
2498     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
2499   case SMDSAbs_Face:
2500     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
2501   case SMDSAbs_Edge:
2502     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
2503   case SMDSAbs_0DElement:
2504     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
2505   case SMDSAbs_Node:
2506     return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
2507     //return myNodeIDFactory->elementsIterator();
2508   default:;
2509   }
2510   return myElementIDFactory->elementsIterator();
2511 }
2512
2513 ///////////////////////////////////////////////////////////////////////////////
2514 /// Do intersection of sets (more than 2)
2515 ///////////////////////////////////////////////////////////////////////////////
2516 static set<const SMDS_MeshElement*> * intersectionOfSets(
2517         set<const SMDS_MeshElement*> vs[], int numberOfSets)
2518 {
2519         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2520         set<const SMDS_MeshElement*>* rsetB;
2521
2522         for(int i=0; i<numberOfSets-1; i++)
2523         {
2524                 rsetB=new set<const SMDS_MeshElement*>();
2525                 set_intersection(
2526                         rsetA->begin(), rsetA->end(),
2527                         vs[i+1].begin(), vs[i+1].end(),
2528                         inserter(*rsetB, rsetB->begin()));
2529                 delete rsetA;
2530                 rsetA=rsetB;
2531         }
2532         return rsetA;
2533 }
2534
2535 ///////////////////////////////////////////////////////////////////////////////
2536 /// Return the list of finite elements owning the given element: elements
2537 /// containing all the nodes of the given element, for instance faces and
2538 /// volumes containing a given edge.
2539 ///////////////////////////////////////////////////////////////////////////////
2540 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2541 {
2542         int numberOfSets=element->NbNodes();
2543         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2544
2545         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2546
2547         int i=0;
2548         while(itNodes->more())
2549         {
2550           const SMDS_MeshElement* node = itNodes->next();
2551           MYASSERT(node);
2552                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
2553                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2554
2555                 //initSet[i]=set<const SMDS_MeshElement*>();
2556                 while(itFe->more())
2557                 {
2558                   const SMDS_MeshElement* elem = itFe->next();
2559                   MYASSERT(elem);
2560                   initSet[i].insert(elem);
2561
2562                 }
2563
2564                 i++;
2565         }
2566         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2567         MESSAGE("nb elems " << i << " intersection " << retSet->size());
2568         delete [] initSet;
2569         return retSet;
2570 }
2571
2572 ///////////////////////////////////////////////////////////////////////////////
2573 /// Return the list of nodes used only by the given elements
2574 ///////////////////////////////////////////////////////////////////////////////
2575 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2576         set<const SMDS_MeshElement*>& elements)
2577 {
2578         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2579         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2580
2581         while(itElements!=elements.end())
2582         {
2583                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2584                 itElements++;
2585
2586                 while(itNodes->more())
2587                 {
2588                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2589                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2590                         set<const SMDS_MeshElement*> s;
2591                         while(itFe->more())
2592                           s.insert(itFe->next());
2593                         if(s==elements) toReturn->insert(n);
2594                 }
2595         }
2596         return toReturn;
2597 }
2598
2599 ///////////////////////////////////////////////////////////////////////////////
2600 ///Find the children of an element that are made of given nodes
2601 ///@param setOfChildren The set in which matching children will be inserted
2602 ///@param element The element were to search matching children
2603 ///@param nodes The nodes that the children must have to be selected
2604 ///////////////////////////////////////////////////////////////////////////////
2605 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
2606                                      const SMDS_MeshElement *      element,
2607                                      set<const SMDS_MeshElement*>& nodes)
2608 {
2609   switch(element->GetType())
2610     {
2611     case SMDSAbs_Node:
2612       MESSAGE("Internal Error: This should not happend");
2613       break;
2614     case SMDSAbs_0DElement:
2615       {
2616       }
2617       break;
2618     case SMDSAbs_Edge:
2619         {
2620                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2621                 while(itn->more())
2622                 {
2623                         const SMDS_MeshElement * e=itn->next();
2624                         if(nodes.find(e)!=nodes.end())
2625                         {
2626                           setOfChildren.insert(element);
2627                           break;
2628                         }
2629                 }
2630         } break;
2631     case SMDSAbs_Face:
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                 if(hasConstructionEdges())
2644                 {
2645                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2646                         while(ite->more())
2647                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2648                 }
2649         } break;
2650     case SMDSAbs_Volume:
2651         {
2652                 if(hasConstructionFaces())
2653                 {
2654                         SMDS_ElemIteratorPtr ite=element->facesIterator();
2655                         while(ite->more())
2656                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2657                 }
2658                 else if(hasConstructionEdges())
2659                 {
2660                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2661                         while(ite->more())
2662                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2663                 }
2664         }
2665     }
2666 }
2667
2668 ///////////////////////////////////////////////////////////////////////////////
2669 ///@param elem The element to delete
2670 ///@param removenodes if true remaining nodes will be removed
2671 ///////////////////////////////////////////////////////////////////////////////
2672 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2673                               const bool removenodes)
2674 {
2675   list<const SMDS_MeshElement *> removedElems;
2676   list<const SMDS_MeshElement *> removedNodes;
2677   RemoveElement( elem, removedElems, removedNodes, removenodes );
2678 }
2679
2680 ///////////////////////////////////////////////////////////////////////////////
2681 ///@param elem The element to delete
2682 ///@param removedElems to be filled with all removed elements
2683 ///@param removedNodes to be filled with all removed nodes
2684 ///@param removenodes if true remaining nodes will be removed
2685 ///////////////////////////////////////////////////////////////////////////////
2686 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
2687                               list<const SMDS_MeshElement *>& removedElems,
2688                               list<const SMDS_MeshElement *>& removedNodes,
2689                               bool                            removenodes)
2690 {
2691   //MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
2692   // get finite elements built on elem
2693   set<const SMDS_MeshElement*> * s1;
2694   if (elem->GetType() == SMDSAbs_0DElement ||
2695       elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
2696       elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
2697       elem->GetType() == SMDSAbs_Volume)
2698   {
2699     s1 = new set<const SMDS_MeshElement*>();
2700     s1->insert(elem);
2701   }
2702   else
2703     s1 = getFinitElements(elem);
2704
2705   // get exclusive nodes (which would become free afterwards)
2706   set<const SMDS_MeshElement*> * s2;
2707   if (elem->GetType() == SMDSAbs_Node) // a node is removed
2708   {
2709     // do not remove nodes except elem
2710     s2 = new set<const SMDS_MeshElement*>();
2711     s2->insert(elem);
2712     removenodes = true;
2713   }
2714   else
2715     s2 = getExclusiveNodes(*s1);
2716
2717   // form the set of finite and construction elements to remove
2718   set<const SMDS_MeshElement*> s3;
2719   set<const SMDS_MeshElement*>::iterator it=s1->begin();
2720   while(it!=s1->end())
2721   {
2722     addChildrenWithNodes(s3, *it ,*s2);
2723     s3.insert(*it);
2724     it++;
2725   }
2726   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2727
2728   // remove finite and construction elements
2729   it=s3.begin();
2730   while(it!=s3.end())
2731   {
2732     // Remove element from <InverseElements> of its nodes
2733     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2734     while(itn->more())
2735     {
2736       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2737         (const_cast<SMDS_MeshElement *>(itn->next()));
2738       n->RemoveInverseElement( (*it) );
2739     }
2740
2741     switch((*it)->GetType())
2742     {
2743     case SMDSAbs_Node:
2744       MYASSERT("Internal Error: This should not happen");
2745       break;
2746     case SMDSAbs_0DElement:
2747       myCells[(*it)->GetID()] = 0;  // -PR- ici ou dans myElementIDFactory->ReleaseID ?
2748       myInfo.remove(*it);
2749       removedElems.push_back( (*it) );
2750       myElementIDFactory->ReleaseID((*it)->GetID());
2751       delete (*it);
2752       break;
2753     case SMDSAbs_Edge:
2754       myCells[(*it)->GetID()] = 0;
2755       myInfo.RemoveEdge(*it);
2756       removedElems.push_back( (*it) );
2757       myElementIDFactory->ReleaseID((*it)->GetID());
2758       if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
2759         myEdgePool->destroy((SMDS_VtkEdge*)vtkElem);
2760       else delete (*it);
2761       break;
2762     case SMDSAbs_Face:
2763       myCells[(*it)->GetID()] = 0;
2764       myInfo.RemoveFace(*it);
2765       removedElems.push_back( (*it) );
2766       myElementIDFactory->ReleaseID((*it)->GetID());
2767       if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
2768         myFacePool->destroy((SMDS_VtkFace*)vtkElem);
2769       else delete (*it);
2770       break;
2771     case SMDSAbs_Volume:
2772       myCells[(*it)->GetID()] = 0;
2773       myInfo.RemoveVolume(*it);
2774       removedElems.push_back( (*it) );
2775       myElementIDFactory->ReleaseID((*it)->GetID());
2776       if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
2777         myVolumePool->destroy((SMDS_VtkVolume*)vtkElem);
2778       else delete (*it);
2779       break;
2780     }
2781     it++;
2782   }
2783
2784   // remove exclusive (free) nodes
2785   if(removenodes)
2786   {
2787     it=s2->begin();
2788     while(it!=s2->end())
2789     {
2790       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2791       myNodes[(*it)->GetID()] = 0;
2792       myInfo.myNbNodes--;
2793       myNodeIDFactory->ReleaseID((*it)->GetID());
2794       removedNodes.push_back( (*it) );
2795       if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
2796         myNodePool->destroy((SMDS_MeshNode*)vtkElem);
2797       else delete (*it);
2798       it++;
2799     }
2800   }
2801
2802   delete s2;
2803   delete s1;
2804 }
2805
2806
2807 ///////////////////////////////////////////////////////////////////////////////
2808 ///@param elem The element to delete
2809 ///////////////////////////////////////////////////////////////////////////////
2810 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2811 {
2812   int elemId = elem->GetID();
2813   //MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
2814   SMDSAbs_ElementType aType = elem->GetType();
2815   SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
2816   if (aType == SMDSAbs_Node) {
2817     // only free node can be removed by this method
2818     const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
2819     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2820     if (!itFe->more()) { // free node
2821       myNodes[elemId] = 0;
2822       myInfo.myNbNodes--;
2823       myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
2824       myNodeIDFactory->ReleaseID(elemId);
2825     }
2826   } else {
2827     if (hasConstructionEdges() || hasConstructionFaces())
2828       // this methods is only for meshes without descendants
2829       return;
2830
2831     int vtkid = this->fromSmdsToVtk(elemId);
2832
2833     // Remove element from <InverseElements> of its nodes
2834     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2835     while (itn->more()) {
2836       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2837         (const_cast<SMDS_MeshElement *>(itn->next()));
2838       n->RemoveInverseElement(elem);
2839     }
2840
2841     // in meshes without descendants elements are always free
2842      switch (aType) {
2843     case SMDSAbs_0DElement:
2844       myCells[elemId] = 0;
2845       myInfo.remove(elem);
2846       delete elem;
2847       break;
2848     case SMDSAbs_Edge:
2849       myCells[elemId] = 0;
2850       myInfo.RemoveEdge(elem);
2851       myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
2852       break;
2853     case SMDSAbs_Face:
2854       myCells[elemId] = 0;
2855       myInfo.RemoveFace(elem);
2856       myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
2857       break;
2858     case SMDSAbs_Volume:
2859       myCells[elemId] = 0;
2860       myInfo.RemoveVolume(elem);
2861       myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
2862       break;
2863     default:
2864       break;
2865     }
2866     myElementIDFactory->ReleaseID(elemId);
2867
2868     this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
2869     // --- to do: keep vtkid in a list of reusable cells
2870   }
2871 }
2872
2873 /*!
2874  * Checks if the element is present in mesh.
2875  * Useful to determine dead pointers.
2876  */
2877 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2878 {
2879   // we should not imply on validity of *elem, so iterate on containers
2880   // of all types in the hope of finding <elem> somewhere there
2881   SMDS_NodeIteratorPtr itn = nodesIterator();
2882   while (itn->more())
2883     if (elem == itn->next())
2884       return true;
2885   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
2886   while (it0d->more())
2887     if (elem == it0d->next())
2888       return true;
2889   SMDS_EdgeIteratorPtr ite = edgesIterator();
2890   while (ite->more())
2891     if (elem == ite->next())
2892       return true;
2893   SMDS_FaceIteratorPtr itf = facesIterator();
2894   while (itf->more())
2895     if (elem == itf->next())
2896       return true;
2897   SMDS_VolumeIteratorPtr itv = volumesIterator();
2898   while (itv->more())
2899     if (elem == itv->next())
2900       return true;
2901   return false;
2902 }
2903
2904 //=======================================================================
2905 //function : MaxNodeID
2906 //purpose  :
2907 //=======================================================================
2908
2909 int SMDS_Mesh::MaxNodeID() const
2910 {
2911   return myNodeMax;
2912 }
2913
2914 //=======================================================================
2915 //function : MinNodeID
2916 //purpose  :
2917 //=======================================================================
2918
2919 int SMDS_Mesh::MinNodeID() const
2920 {
2921   return myNodeMin;
2922 }
2923
2924 //=======================================================================
2925 //function : MaxElementID
2926 //purpose  :
2927 //=======================================================================
2928
2929 int SMDS_Mesh::MaxElementID() const
2930 {
2931   return myElementIDFactory->GetMaxID();
2932 }
2933
2934 //=======================================================================
2935 //function : MinElementID
2936 //purpose  :
2937 //=======================================================================
2938
2939 int SMDS_Mesh::MinElementID() const
2940 {
2941   return myElementIDFactory->GetMinID();
2942 }
2943
2944 //=======================================================================
2945 //function : Renumber
2946 //purpose  : Renumber all nodes or elements.
2947 //=======================================================================
2948
2949 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
2950 {
2951     MESSAGE("Renumber");
2952   if ( deltaID == 0 )
2953     return;
2954
2955   SMDS_MeshNodeIDFactory * idFactory =
2956     isNodes ? myNodeIDFactory : myElementIDFactory;
2957
2958   // get existing elements in the order of ID increasing
2959   map<int,SMDS_MeshElement*> elemMap;
2960   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2961   while ( idElemIt->more() ) {
2962     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2963     int id = elem->GetID();
2964     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2965   }
2966   // release their ids
2967   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2968   idFactory->Clear();
2969 //   for ( ; elemIt != elemMap.end(); elemIt++ )
2970 //   {
2971 //     int id = (*elemIt).first;
2972 //     idFactory->ReleaseID( id );
2973 //   }
2974   // set new IDs
2975   int ID = startID;
2976   elemIt = elemMap.begin();
2977   for ( ; elemIt != elemMap.end(); elemIt++ )
2978   {
2979     idFactory->BindID( ID, (*elemIt).second );
2980     ID += deltaID;
2981   }
2982 }
2983
2984 //=======================================================================
2985 //function : GetElementType
2986 //purpose  : Return type of element or node with id
2987 //=======================================================================
2988
2989 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2990 {
2991   SMDS_MeshElement* elem = 0;
2992   if( iselem )
2993     elem = myElementIDFactory->MeshElement( id );
2994   else
2995     elem = myNodeIDFactory->MeshElement( id );
2996
2997   if( !elem )
2998   {
2999     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
3000     return SMDSAbs_All;
3001   }
3002   else
3003     return elem->GetType();
3004 }
3005
3006
3007
3008 //********************************************************************
3009 //********************************************************************
3010 //********                                                   *********
3011 //*****       Methods for addition of quadratic elements        ******
3012 //********                                                   *********
3013 //********************************************************************
3014 //********************************************************************
3015
3016 //=======================================================================
3017 //function : AddEdgeWithID
3018 //purpose  :
3019 //=======================================================================
3020 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
3021 {
3022   return SMDS_Mesh::AddEdgeWithID
3023     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3024      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3025      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3026      ID);
3027 }
3028
3029 //=======================================================================
3030 //function : AddEdge
3031 //purpose  :
3032 //=======================================================================
3033 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
3034                                   const SMDS_MeshNode* n2,
3035                                   const SMDS_MeshNode* n12)
3036 {
3037   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
3038 }
3039
3040 //=======================================================================
3041 //function : AddEdgeWithID
3042 //purpose  :
3043 //=======================================================================
3044 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
3045                                         const SMDS_MeshNode * n2,
3046                                         const SMDS_MeshNode * n12,
3047                                         int ID)
3048 {
3049   if ( !n1 || !n2 || !n12 ) return 0;
3050
3051   // --- retrieve nodes ID
3052   vector<vtkIdType> nodeIds;
3053   nodeIds.clear();
3054   nodeIds.push_back(n1->getId());
3055   nodeIds.push_back(n2->getId());
3056   nodeIds.push_back(n12->getId());
3057
3058   SMDS_MeshEdge * edge = 0;
3059   SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
3060   edgevtk->init(nodeIds, this);
3061   edge = edgevtk;
3062   adjustmyCellsCapacity(ID);
3063   myCells[ID] = edge;
3064   myInfo.myNbQuadEdges++;
3065
3066   if (!registerElement(ID, edge)) {
3067           RemoveElement(edge, false);
3068           edge = NULL;
3069   }
3070   return edge;
3071
3072 }
3073
3074
3075 //=======================================================================
3076 //function : AddFace
3077 //purpose  :
3078 //=======================================================================
3079 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3080                                   const SMDS_MeshNode * n2,
3081                                   const SMDS_MeshNode * n3,
3082                                   const SMDS_MeshNode * n12,
3083                                   const SMDS_MeshNode * n23,
3084                                   const SMDS_MeshNode * n31)
3085 {
3086   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
3087                                   myElementIDFactory->GetFreeID());
3088 }
3089
3090 //=======================================================================
3091 //function : AddFaceWithID
3092 //purpose  :
3093 //=======================================================================
3094 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
3095                                         int n12,int n23,int n31, int ID)
3096 {
3097   return SMDS_Mesh::AddFaceWithID
3098     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3099      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3100      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3101      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3102      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3103      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
3104      ID);
3105 }
3106
3107 //=======================================================================
3108 //function : AddFaceWithID
3109 //purpose  :
3110 //=======================================================================
3111 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3112                                         const SMDS_MeshNode * n2,
3113                                         const SMDS_MeshNode * n3,
3114                                         const SMDS_MeshNode * n12,
3115                                         const SMDS_MeshNode * n23,
3116                                         const SMDS_MeshNode * n31,
3117                                         int ID)
3118 {
3119   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
3120   if(hasConstructionEdges()) {
3121     // creation quadratic edges - not implemented
3122     return 0;
3123   }
3124   else
3125   {
3126     // --- retrieve nodes ID
3127     vector<vtkIdType> nodeIds;
3128     nodeIds.clear();
3129     nodeIds.push_back(n1->getId());
3130     nodeIds.push_back(n2->getId());
3131     nodeIds.push_back(n3->getId());
3132     nodeIds.push_back(n12->getId());
3133     nodeIds.push_back(n23->getId());
3134     nodeIds.push_back(n31->getId());
3135
3136     SMDS_MeshFace * face = 0;
3137     SMDS_VtkFace *facevtk = myFacePool->getNew();
3138     facevtk->init(nodeIds, this);
3139     face = facevtk;
3140     adjustmyCellsCapacity(ID);
3141     myCells[ID] = face;
3142     myInfo.myNbQuadTriangles++;
3143
3144     if (!registerElement(ID, face)) {
3145       RemoveElement(face, false);
3146       face = NULL;
3147     }
3148     return face;
3149   }
3150 }
3151
3152
3153 //=======================================================================
3154 //function : AddFace
3155 //purpose  :
3156 //=======================================================================
3157 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
3158                                   const SMDS_MeshNode * n2,
3159                                   const SMDS_MeshNode * n3,
3160                                   const SMDS_MeshNode * n4,
3161                                   const SMDS_MeshNode * n12,
3162                                   const SMDS_MeshNode * n23,
3163                                   const SMDS_MeshNode * n34,
3164                                   const SMDS_MeshNode * n41)
3165 {
3166   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
3167                                   myElementIDFactory->GetFreeID());
3168 }
3169
3170 //=======================================================================
3171 //function : AddFaceWithID
3172 //purpose  :
3173 //=======================================================================
3174 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
3175                                         int n12,int n23,int n34,int n41, int ID)
3176 {
3177   return SMDS_Mesh::AddFaceWithID
3178     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
3179      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
3180      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
3181      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
3182      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
3183      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
3184      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
3185      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
3186      ID);
3187 }
3188
3189 //=======================================================================
3190 //function : AddFaceWithID
3191 //purpose  :
3192 //=======================================================================
3193 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
3194                                         const SMDS_MeshNode * n2,
3195                                         const SMDS_MeshNode * n3,
3196                                         const SMDS_MeshNode * n4,
3197                                         const SMDS_MeshNode * n12,
3198                                         const SMDS_MeshNode * n23,
3199                                         const SMDS_MeshNode * n34,
3200                                         const SMDS_MeshNode * n41,
3201                                         int ID)
3202 {
3203   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
3204   if(hasConstructionEdges()) {
3205     // creation quadratic edges - not implemented
3206         return 0;
3207   }
3208   else
3209   {
3210     // --- retrieve nodes ID
3211     vector<vtkIdType> nodeIds;
3212     nodeIds.clear();
3213     nodeIds.push_back(n1->getId());
3214     nodeIds.push_back(n2->getId());
3215     nodeIds.push_back(n3->getId());
3216     nodeIds.push_back(n4->getId());
3217     nodeIds.push_back(n12->getId());
3218     nodeIds.push_back(n23->getId());
3219     nodeIds.push_back(n34->getId());
3220     nodeIds.push_back(n41->getId());
3221
3222     SMDS_MeshFace * face = 0;
3223     SMDS_VtkFace *facevtk = myFacePool->getNew();
3224     facevtk->init(nodeIds, this);
3225     face = facevtk;
3226     adjustmyCellsCapacity(ID);
3227     myCells[ID] = face;
3228     myInfo.myNbQuadQuadrangles++;
3229
3230     if (!registerElement(ID, face)) {
3231       RemoveElement(face, false);
3232       face = NULL;
3233     }
3234     return face;
3235   }
3236 }
3237
3238
3239 //=======================================================================
3240 //function : AddVolume
3241 //purpose  :
3242 //=======================================================================
3243 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3244                                       const SMDS_MeshNode * n2,
3245                                       const SMDS_MeshNode * n3,
3246                                       const SMDS_MeshNode * n4,
3247                                       const SMDS_MeshNode * n12,
3248                                       const SMDS_MeshNode * n23,
3249                                       const SMDS_MeshNode * n31,
3250                                       const SMDS_MeshNode * n14,
3251                                       const SMDS_MeshNode * n24,
3252                                       const SMDS_MeshNode * n34)
3253 {
3254   int ID = myElementIDFactory->GetFreeID();
3255   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
3256                                                    n31, n14, n24, n34, ID);
3257   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3258   return v;
3259 }
3260
3261 //=======================================================================
3262 //function : AddVolumeWithID
3263 //purpose  :
3264 //=======================================================================
3265 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3266                                             int n12,int n23,int n31,
3267                                             int n14,int n24,int n34, int ID)
3268 {
3269   return SMDS_Mesh::AddVolumeWithID
3270     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3271      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3272      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3273      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3274      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3275      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3276      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3277      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3278      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
3279      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3280      ID);
3281 }
3282
3283 //=======================================================================
3284 //function : AddVolumeWithID
3285 //purpose  : 2d order tetrahedron of 10 nodes
3286 //=======================================================================
3287 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3288                                             const SMDS_MeshNode * n2,
3289                                             const SMDS_MeshNode * n3,
3290                                             const SMDS_MeshNode * n4,
3291                                             const SMDS_MeshNode * n12,
3292                                             const SMDS_MeshNode * n23,
3293                                             const SMDS_MeshNode * n31,
3294                                             const SMDS_MeshNode * n14,
3295                                             const SMDS_MeshNode * n24,
3296                                             const SMDS_MeshNode * n34,
3297                                             int ID)
3298 {
3299   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
3300     return 0;
3301   if(hasConstructionFaces()) {
3302     // creation quadratic faces - not implemented
3303     return 0;
3304   }
3305   // --- retrieve nodes ID
3306   vector<vtkIdType> nodeIds;
3307   nodeIds.clear();
3308   nodeIds.push_back(n1->getId());
3309   nodeIds.push_back(n3->getId());
3310   nodeIds.push_back(n2->getId());
3311   nodeIds.push_back(n4->getId());
3312
3313   nodeIds.push_back(n31->getId());
3314   nodeIds.push_back(n23->getId());
3315   nodeIds.push_back(n12->getId());
3316
3317   nodeIds.push_back(n14->getId());
3318   nodeIds.push_back(n34->getId());
3319   nodeIds.push_back(n24->getId());
3320
3321   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3322   volvtk->init(nodeIds, this);
3323   adjustmyCellsCapacity(ID);
3324   myCells[ID] = volvtk;
3325   myInfo.myNbQuadTetras++;
3326
3327   if (!registerElement(ID, volvtk)) {
3328     RemoveElement(volvtk, false);
3329     volvtk = NULL;
3330   }
3331   return volvtk;
3332 }
3333
3334
3335 //=======================================================================
3336 //function : AddVolume
3337 //purpose  :
3338 //=======================================================================
3339 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3340                                       const SMDS_MeshNode * n2,
3341                                       const SMDS_MeshNode * n3,
3342                                       const SMDS_MeshNode * n4,
3343                                       const SMDS_MeshNode * n5,
3344                                       const SMDS_MeshNode * n12,
3345                                       const SMDS_MeshNode * n23,
3346                                       const SMDS_MeshNode * n34,
3347                                       const SMDS_MeshNode * n41,
3348                                       const SMDS_MeshNode * n15,
3349                                       const SMDS_MeshNode * n25,
3350                                       const SMDS_MeshNode * n35,
3351                                       const SMDS_MeshNode * n45)
3352 {
3353   int ID = myElementIDFactory->GetFreeID();
3354   SMDS_MeshVolume * v =
3355     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
3356                                n15, n25, n35, n45, ID);
3357   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3358   return v;
3359 }
3360
3361 //=======================================================================
3362 //function : AddVolumeWithID
3363 //purpose  :
3364 //=======================================================================
3365 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
3366                                             int n12,int n23,int n34,int n41,
3367                                             int n15,int n25,int n35,int n45, int ID)
3368 {
3369   return SMDS_Mesh::AddVolumeWithID
3370     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3371      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3372      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3373      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3374      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3375      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3376      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3377      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3378      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3379      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3380      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3381      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
3382      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3383      ID);
3384 }
3385
3386 //=======================================================================
3387 //function : AddVolumeWithID
3388 //purpose  : 2d order pyramid of 13 nodes
3389 //=======================================================================
3390 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3391                                             const SMDS_MeshNode * n2,
3392                                             const SMDS_MeshNode * n3,
3393                                             const SMDS_MeshNode * n4,
3394                                             const SMDS_MeshNode * n5,
3395                                             const SMDS_MeshNode * n12,
3396                                             const SMDS_MeshNode * n23,
3397                                             const SMDS_MeshNode * n34,
3398                                             const SMDS_MeshNode * n41,
3399                                             const SMDS_MeshNode * n15,
3400                                             const SMDS_MeshNode * n25,
3401                                             const SMDS_MeshNode * n35,
3402                                             const SMDS_MeshNode * n45,
3403                                             int ID)
3404 {
3405   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
3406       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
3407     return 0;
3408   if(hasConstructionFaces()) {
3409     // creation quadratic faces - not implemented
3410     return 0;
3411   }
3412   // --- retrieve nodes ID
3413   vector<vtkIdType> nodeIds;
3414   nodeIds.clear();
3415   nodeIds.push_back(n1->getId());
3416   nodeIds.push_back(n4->getId());
3417   nodeIds.push_back(n3->getId());
3418   nodeIds.push_back(n2->getId());
3419   nodeIds.push_back(n5->getId());
3420
3421   nodeIds.push_back(n41->getId());
3422   nodeIds.push_back(n34->getId());
3423   nodeIds.push_back(n23->getId());
3424   nodeIds.push_back(n12->getId());
3425
3426   nodeIds.push_back(n15->getId());
3427   nodeIds.push_back(n45->getId());
3428   nodeIds.push_back(n35->getId());
3429   nodeIds.push_back(n25->getId());
3430
3431   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3432   volvtk->init(nodeIds, this);
3433   adjustmyCellsCapacity(ID);
3434   myCells[ID] = volvtk;
3435   myInfo.myNbQuadPyramids++;
3436
3437   if (!registerElement(ID, volvtk)) {
3438     RemoveElement(volvtk, false);
3439     volvtk = NULL;
3440   }
3441   return volvtk;
3442 }
3443
3444
3445 //=======================================================================
3446 //function : AddVolume
3447 //purpose  :
3448 //=======================================================================
3449 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3450                                       const SMDS_MeshNode * n2,
3451                                       const SMDS_MeshNode * n3,
3452                                       const SMDS_MeshNode * n4,
3453                                       const SMDS_MeshNode * n5,
3454                                       const SMDS_MeshNode * n6,
3455                                       const SMDS_MeshNode * n12,
3456                                       const SMDS_MeshNode * n23,
3457                                       const SMDS_MeshNode * n31,
3458                                       const SMDS_MeshNode * n45,
3459                                       const SMDS_MeshNode * n56,
3460                                       const SMDS_MeshNode * n64,
3461                                       const SMDS_MeshNode * n14,
3462                                       const SMDS_MeshNode * n25,
3463                                       const SMDS_MeshNode * n36)
3464 {
3465   int ID = myElementIDFactory->GetFreeID();
3466   SMDS_MeshVolume * v =
3467     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
3468                                n45, n56, n64, n14, n25, n36, ID);
3469   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3470   return v;
3471 }
3472
3473 //=======================================================================
3474 //function : AddVolumeWithID
3475 //purpose  :
3476 //=======================================================================
3477 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
3478                                             int n4, int n5, int n6,
3479                                             int n12,int n23,int n31,
3480                                             int n45,int n56,int n64,
3481                                             int n14,int n25,int n36, int ID)
3482 {
3483   return SMDS_Mesh::AddVolumeWithID
3484     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
3485      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
3486      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
3487      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
3488      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
3489      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
3490      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3491      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3492      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
3493      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
3494      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3495      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
3496      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
3497      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
3498      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
3499      ID);
3500 }
3501
3502 //=======================================================================
3503 //function : AddVolumeWithID
3504 //purpose  : 2d order Pentahedron with 15 nodes
3505 //=======================================================================
3506 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3507                                             const SMDS_MeshNode * n2,
3508                                             const SMDS_MeshNode * n3,
3509                                             const SMDS_MeshNode * n4,
3510                                             const SMDS_MeshNode * n5,
3511                                             const SMDS_MeshNode * n6,
3512                                             const SMDS_MeshNode * n12,
3513                                             const SMDS_MeshNode * n23,
3514                                             const SMDS_MeshNode * n31,
3515                                             const SMDS_MeshNode * n45,
3516                                             const SMDS_MeshNode * n56,
3517                                             const SMDS_MeshNode * n64,
3518                                             const SMDS_MeshNode * n14,
3519                                             const SMDS_MeshNode * n25,
3520                                             const SMDS_MeshNode * n36,
3521                                             int ID)
3522 {
3523   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
3524       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
3525     return 0;
3526   if(hasConstructionFaces()) {
3527     // creation quadratic faces - not implemented
3528     return 0;
3529   }
3530   // --- retrieve nodes ID
3531   vector<vtkIdType> nodeIds;
3532   nodeIds.clear();
3533   nodeIds.push_back(n1->getId());
3534   nodeIds.push_back(n2->getId());
3535   nodeIds.push_back(n3->getId());
3536
3537   nodeIds.push_back(n4->getId());
3538   nodeIds.push_back(n5->getId());
3539   nodeIds.push_back(n6->getId());
3540
3541   nodeIds.push_back(n12->getId());
3542   nodeIds.push_back(n23->getId());
3543   nodeIds.push_back(n31->getId());
3544
3545   nodeIds.push_back(n45->getId());
3546   nodeIds.push_back(n56->getId());
3547   nodeIds.push_back(n64->getId());
3548
3549   nodeIds.push_back(n14->getId());
3550   nodeIds.push_back(n25->getId());
3551   nodeIds.push_back(n36->getId());
3552
3553   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3554   volvtk->init(nodeIds, this);
3555   adjustmyCellsCapacity(ID);
3556   myCells[ID] = volvtk;
3557   myInfo.myNbQuadPrisms++;
3558
3559   if (!registerElement(ID, volvtk)) {
3560     RemoveElement(volvtk, false);
3561     volvtk = NULL;
3562   }
3563   return volvtk;
3564 }
3565
3566
3567 //=======================================================================
3568 //function : AddVolume
3569 //purpose  :
3570 //=======================================================================
3571 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
3572                                       const SMDS_MeshNode * n2,
3573                                       const SMDS_MeshNode * n3,
3574                                       const SMDS_MeshNode * n4,
3575                                       const SMDS_MeshNode * n5,
3576                                       const SMDS_MeshNode * n6,
3577                                       const SMDS_MeshNode * n7,
3578                                       const SMDS_MeshNode * n8,
3579                                       const SMDS_MeshNode * n12,
3580                                       const SMDS_MeshNode * n23,
3581                                       const SMDS_MeshNode * n34,
3582                                       const SMDS_MeshNode * n41,
3583                                       const SMDS_MeshNode * n56,
3584                                       const SMDS_MeshNode * n67,
3585                                       const SMDS_MeshNode * n78,
3586                                       const SMDS_MeshNode * n85,
3587                                       const SMDS_MeshNode * n15,
3588                                       const SMDS_MeshNode * n26,
3589                                       const SMDS_MeshNode * n37,
3590                                       const SMDS_MeshNode * n48)
3591 {
3592   int ID = myElementIDFactory->GetFreeID();
3593   SMDS_MeshVolume * v =
3594     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
3595                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
3596   if(v==NULL) myElementIDFactory->ReleaseID(ID);
3597   return v;
3598 }
3599
3600 //=======================================================================
3601 //function : AddVolumeWithID
3602 //purpose  :
3603 //=======================================================================
3604 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
3605                                             int n5, int n6, int n7, int n8,
3606                                             int n12,int n23,int n34,int n41,
3607                                             int n56,int n67,int n78,int n85,
3608                                             int n15,int n26,int n37,int n48, int ID)
3609 {
3610   return SMDS_Mesh::AddVolumeWithID
3611     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
3612      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
3613      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
3614      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
3615      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
3616      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
3617      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
3618      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
3619      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
3620      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
3621      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
3622      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
3623      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
3624      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3625      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3626      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3627      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3628      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3629      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3630      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3631      ID);
3632 }
3633
3634 //=======================================================================
3635 //function : AddVolumeWithID
3636 //purpose  : 2d order Hexahedrons with 20 nodes
3637 //=======================================================================
3638 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3639                                             const SMDS_MeshNode * n2,
3640                                             const SMDS_MeshNode * n3,
3641                                             const SMDS_MeshNode * n4,
3642                                             const SMDS_MeshNode * n5,
3643                                             const SMDS_MeshNode * n6,
3644                                             const SMDS_MeshNode * n7,
3645                                             const SMDS_MeshNode * n8,
3646                                             const SMDS_MeshNode * n12,
3647                                             const SMDS_MeshNode * n23,
3648                                             const SMDS_MeshNode * n34,
3649                                             const SMDS_MeshNode * n41,
3650                                             const SMDS_MeshNode * n56,
3651                                             const SMDS_MeshNode * n67,
3652                                             const SMDS_MeshNode * n78,
3653                                             const SMDS_MeshNode * n85,
3654                                             const SMDS_MeshNode * n15,
3655                                             const SMDS_MeshNode * n26,
3656                                             const SMDS_MeshNode * n37,
3657                                             const SMDS_MeshNode * n48,
3658                                             int ID)
3659 {
3660   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3661       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3662     return 0;
3663   if(hasConstructionFaces()) {
3664     return 0;
3665     // creation quadratic faces - not implemented
3666   }
3667   // --- retrieve nodes ID
3668   vector<vtkIdType> nodeIds;
3669   nodeIds.clear();
3670   nodeIds.push_back(n1->getId());
3671   nodeIds.push_back(n4->getId());
3672   nodeIds.push_back(n3->getId());
3673   nodeIds.push_back(n2->getId());
3674
3675   nodeIds.push_back(n5->getId());
3676   nodeIds.push_back(n8->getId());
3677   nodeIds.push_back(n7->getId());
3678   nodeIds.push_back(n6->getId());
3679
3680   nodeIds.push_back(n41->getId());
3681   nodeIds.push_back(n34->getId());
3682   nodeIds.push_back(n23->getId());
3683   nodeIds.push_back(n12->getId());
3684
3685   nodeIds.push_back(n85->getId());
3686   nodeIds.push_back(n78->getId());
3687   nodeIds.push_back(n67->getId());
3688   nodeIds.push_back(n56->getId());
3689
3690   nodeIds.push_back(n15->getId());
3691   nodeIds.push_back(n48->getId());
3692   nodeIds.push_back(n37->getId());
3693   nodeIds.push_back(n26->getId());
3694
3695   SMDS_VtkVolume *volvtk = myVolumePool->getNew();
3696   volvtk->init(nodeIds, this);
3697   adjustmyCellsCapacity(ID);
3698   myCells[ID] = volvtk;
3699   myInfo.myNbQuadHexas++;
3700
3701   if (!registerElement(ID, volvtk)) {
3702     RemoveElement(volvtk, false);
3703     volvtk = NULL;
3704   }
3705   return volvtk;
3706 }
3707
3708 void SMDS_Mesh::updateNodeMinMax()
3709 {
3710   myNodeMin = 0;
3711   if (myNodes.size() == 0)
3712   {
3713         myNodeMax=0;
3714         return;
3715   }
3716   while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
3717     myNodeMin++;
3718   myNodeMax=myNodes.size()-1;
3719   while (!myNodes[myNodeMax] && (myNodeMin>=0))
3720     myNodeMin--;
3721 }
3722
3723 void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
3724 {
3725   int val = myIDElements.size();
3726   MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
3727   myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
3728   val = myNodes.size();
3729   MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
3730   myNodes.resize(val +nbNodes, 0);
3731 }
3732
3733 void SMDS_Mesh::incrementCellsCapacity(int nbCells)
3734 {
3735   int val = myVtkIndex.size();
3736   MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
3737   myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
3738   val = myCells.size();
3739   MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
3740   myNodes.resize(val +nbCells, 0);
3741 }
3742
3743 void SMDS_Mesh::adjustStructure()
3744 {
3745   myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
3746 }
3747
3748 void SMDS_Mesh::dumpGrid(string ficdump)
3749 {
3750         MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
3751 //  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
3752 //  aWriter->SetFileName(ficdump.c_str());
3753 //  aWriter->SetInput(myGrid);
3754 //  if(myGrid->GetNumberOfCells())
3755 //  {
3756 //    aWriter->Write();
3757 //  }
3758 //  aWriter->Delete();
3759   ficdump = ficdump + "_connectivity";
3760   ofstream ficcon(ficdump.c_str(), ios::out);
3761   int nbPoints = myGrid->GetNumberOfPoints();
3762   ficcon << "-------------------------------- points " <<  nbPoints << endl;
3763   for (int i=0; i<nbPoints; i++)
3764   {
3765         ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
3766   }
3767   int nbCells = myGrid->GetNumberOfCells();
3768   ficcon << "-------------------------------- cells " <<  nbCells << endl;
3769   for (int i=0; i<nbCells; i++)
3770   {
3771 //      MESSAGE(i << " " << myGrid->GetCell(i));
3772 //      MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
3773         ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
3774         int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
3775         vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
3776         for (int j=0; j<nbptcell; j++)
3777         {
3778                 ficcon << " " <<  listid->GetId(j);
3779         }
3780         ficcon << endl;
3781   }
3782   ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
3783         vtkCellLinks *links = myGrid->GetCellLinks();
3784   for (int i=0; i<nbPoints; i++)
3785   {
3786         int ncells = links->GetNcells(i);
3787         vtkIdType *cells = links->GetCells(i);
3788         ficcon << i << " - " << ncells << " -";
3789         for (int j=0; j<ncells; j++)
3790         {
3791                 ficcon << " " << cells[j];
3792         }
3793         ficcon << endl;
3794   }
3795   ficcon.close();
3796
3797 }