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