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