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