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