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