Salome HOME
NPAL14335 (EDF 344 SMESH : "ERROR : Iterator not implemented " when loading a script)
[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          e->GetNodeIndex( node2 ) >= 0 &&
1324          e->GetNodeIndex( node3 ) >= 0 ) {
1325       return static_cast<const SMDS_MeshEdge*>( e );
1326     }
1327   }
1328   return 0;
1329 }
1330
1331
1332 //=======================================================================
1333 //function : FindFace
1334 //purpose  :
1335 //=======================================================================
1336
1337 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1338         int idnode3) const
1339 {
1340   const SMDS_MeshNode * node1=FindNode(idnode1);
1341   const SMDS_MeshNode * node2=FindNode(idnode2);
1342   const SMDS_MeshNode * node3=FindNode(idnode3);
1343   return FindFace(node1, node2, node3);
1344 }
1345
1346 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1347                                          const SMDS_MeshNode *node2,
1348                                          const SMDS_MeshNode *node3)
1349 {
1350   if ( !node1 ) return 0;
1351   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1352   while(it1->more()) {
1353     const SMDS_MeshElement * e = it1->next();
1354     if ( e->NbNodes() == 3 &&
1355          e->GetNodeIndex( node2 ) >= 0 &&
1356          e->GetNodeIndex( node3 ) >= 0 ) {
1357       return static_cast<const SMDS_MeshFace*>( e );
1358     }
1359   }
1360   return NULL;
1361 }
1362
1363 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1364                                            const SMDS_MeshNode *node2,
1365                                            const SMDS_MeshNode *node3)
1366 {
1367   SMDS_MeshFace * toReturn=NULL;
1368   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1369   if(toReturn==NULL) {
1370     toReturn = createTriangle(node1,node2,node3);
1371   }
1372   return toReturn;
1373 }
1374
1375
1376 //=======================================================================
1377 //function : FindFace
1378 //purpose  :
1379 //=======================================================================
1380
1381 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1382                                          int idnode3, int idnode4) const
1383 {
1384   const SMDS_MeshNode * node1=FindNode(idnode1);
1385   const SMDS_MeshNode * node2=FindNode(idnode2);
1386   const SMDS_MeshNode * node3=FindNode(idnode3);
1387   const SMDS_MeshNode * node4=FindNode(idnode4);
1388   return FindFace(node1, node2, node3, node4);
1389 }
1390
1391 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1392                                          const SMDS_MeshNode *node2,
1393                                          const SMDS_MeshNode *node3,
1394                                          const SMDS_MeshNode *node4)
1395 {
1396   if ( !node1 ) return 0;
1397   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1398   while(it1->more()) {
1399     const SMDS_MeshElement* f = it1->next();
1400     if ( f->NbNodes() == 4 &&
1401          f->GetNodeIndex( node2 ) >= 0 &&
1402          f->GetNodeIndex( node3 ) >= 0 &&
1403          f->GetNodeIndex( node4 ) >= 0 )
1404       return static_cast<const SMDS_MeshFace *>( f );
1405   }
1406   return NULL;
1407 }
1408
1409 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1410                                            const SMDS_MeshNode *node2,
1411                                            const SMDS_MeshNode *node3,
1412                                            const SMDS_MeshNode *node4)
1413 {
1414   SMDS_MeshFace * toReturn=NULL;
1415   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1416   if(toReturn==NULL) {
1417     toReturn=createQuadrangle(node1,node2,node3,node4);
1418   }
1419   return toReturn;
1420 }
1421
1422
1423 //=======================================================================
1424 //function : FindFace
1425 //purpose  :quadratic triangle
1426 //=======================================================================
1427
1428 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1429                                          int idnode3, int idnode4,
1430                                          int idnode5, int idnode6) const
1431 {
1432   const SMDS_MeshNode * node1 = FindNode(idnode1);
1433   const SMDS_MeshNode * node2 = FindNode(idnode2);
1434   const SMDS_MeshNode * node3 = FindNode(idnode3);
1435   const SMDS_MeshNode * node4 = FindNode(idnode4);
1436   const SMDS_MeshNode * node5 = FindNode(idnode5);
1437   const SMDS_MeshNode * node6 = FindNode(idnode6);
1438   return FindFace(node1, node2, node3, node4, node5, node6);
1439 }
1440
1441 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1442                                          const SMDS_MeshNode *node2,
1443                                          const SMDS_MeshNode *node3,
1444                                          const SMDS_MeshNode *node4,
1445                                          const SMDS_MeshNode *node5,
1446                                          const SMDS_MeshNode *node6)
1447 {
1448   if ( !node1 ) return 0;
1449   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1450   while(it1->more()) {
1451     const SMDS_MeshElement* f = it1->next();
1452     if ( f->NbNodes() == 6 &&
1453          f->GetNodeIndex( node2 ) >= 0 &&
1454          f->GetNodeIndex( node3 ) >= 0 &&
1455          f->GetNodeIndex( node4 ) >= 0 &&
1456          f->GetNodeIndex( node5 ) >= 0 &&
1457          f->GetNodeIndex( node6 ) >= 0 )
1458       return static_cast<const SMDS_MeshFace *>( f );
1459   }
1460   return NULL;
1461 }
1462
1463
1464 //=======================================================================
1465 //function : FindFace
1466 //purpose  : quadratic quadrangle
1467 //=======================================================================
1468
1469 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1470                                          int idnode3, int idnode4,
1471                                          int idnode5, int idnode6,
1472                                          int idnode7, int idnode8) const
1473 {
1474   const SMDS_MeshNode * node1 = FindNode(idnode1);
1475   const SMDS_MeshNode * node2 = FindNode(idnode2);
1476   const SMDS_MeshNode * node3 = FindNode(idnode3);
1477   const SMDS_MeshNode * node4 = FindNode(idnode4);
1478   const SMDS_MeshNode * node5 = FindNode(idnode5);
1479   const SMDS_MeshNode * node6 = FindNode(idnode6);
1480   const SMDS_MeshNode * node7 = FindNode(idnode7);
1481   const SMDS_MeshNode * node8 = FindNode(idnode8);
1482   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1483 }
1484
1485 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1486                                          const SMDS_MeshNode *node2,
1487                                          const SMDS_MeshNode *node3,
1488                                          const SMDS_MeshNode *node4,
1489                                          const SMDS_MeshNode *node5,
1490                                          const SMDS_MeshNode *node6,
1491                                          const SMDS_MeshNode *node7,
1492                                          const SMDS_MeshNode *node8)
1493 {
1494   if ( !node1 ) return 0;
1495   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1496   while(it1->more()) {
1497     const SMDS_MeshElement* f = it1->next();
1498     if ( f->NbNodes() == 8 &&
1499          f->GetNodeIndex( node2 ) >= 0 &&
1500          f->GetNodeIndex( node3 ) >= 0 &&
1501          f->GetNodeIndex( node4 ) >= 0 &&
1502          f->GetNodeIndex( node5 ) >= 0 &&
1503          f->GetNodeIndex( node6 ) >= 0 &&
1504          f->GetNodeIndex( node7 ) >= 0 &&
1505          f->GetNodeIndex( node8 ) >= 0 )
1506       return static_cast<const SMDS_MeshFace *>( f );
1507   }
1508   return NULL;
1509 }
1510
1511
1512 //=======================================================================
1513 //function : FindElement
1514 //purpose  :
1515 //=======================================================================
1516
1517 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1518 {
1519   return myElementIDFactory->MeshElement(IDelem);
1520 }
1521
1522 //=======================================================================
1523 //function : FindFace
1524 //purpose  : find polygon
1525 //=======================================================================
1526
1527 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1528 {
1529   int nbnodes = nodes_ids.size();
1530   std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1531   for (int inode = 0; inode < nbnodes; inode++) {
1532     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1533     if (node == NULL) return NULL;
1534   }
1535   return FindFace(poly_nodes);
1536 }
1537
1538 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1539 {
1540   if ( nodes.size() > 2 && nodes[0] ) {
1541     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1542     while (itF->more()) {
1543       const SMDS_MeshElement* f = itF->next();
1544       if ( f->NbNodes() == nodes.size() ) {
1545         int ok = true, i = 1;
1546         while ( ok && i < nodes.size() ) {
1547           ok = ( f->GetNodeIndex( nodes[ i++ ] ) >= 0 );
1548         }
1549         if ( ok )
1550           return static_cast<const SMDS_MeshFace *>( f );
1551       }
1552     }
1553   }
1554   return NULL;
1555 }
1556
1557 //=======================================================================
1558 //function : DumpNodes
1559 //purpose  : 
1560 //=======================================================================
1561
1562 void SMDS_Mesh::DumpNodes() const
1563 {
1564         MESSAGE("dump nodes of mesh : ");
1565         SMDS_NodeIteratorPtr itnode=nodesIterator();
1566         while(itnode->more()) MESSAGE(itnode->next());
1567 }
1568
1569 //=======================================================================
1570 //function : DumpEdges
1571 //purpose  : 
1572 //=======================================================================
1573
1574 void SMDS_Mesh::DumpEdges() const
1575 {
1576         MESSAGE("dump edges of mesh : ");
1577         SMDS_EdgeIteratorPtr itedge=edgesIterator();
1578         while(itedge->more()) MESSAGE(itedge->next());
1579 }
1580
1581 //=======================================================================
1582 //function : DumpFaces
1583 //purpose  : 
1584 //=======================================================================
1585
1586 void SMDS_Mesh::DumpFaces() const
1587 {
1588         MESSAGE("dump faces of mesh : ");
1589         SMDS_FaceIteratorPtr itface=facesIterator();
1590         while(itface->more()) MESSAGE(itface->next());
1591 }
1592
1593 //=======================================================================
1594 //function : DumpVolumes
1595 //purpose  : 
1596 //=======================================================================
1597
1598 void SMDS_Mesh::DumpVolumes() const
1599 {
1600         MESSAGE("dump volumes of mesh : ");
1601         SMDS_VolumeIteratorPtr itvol=volumesIterator();
1602         while(itvol->more()) MESSAGE(itvol->next());
1603 }
1604
1605 //=======================================================================
1606 //function : DebugStats
1607 //purpose  : 
1608 //=======================================================================
1609
1610 void SMDS_Mesh::DebugStats() const
1611 {
1612         MESSAGE("Debug stats of mesh : ");
1613
1614         MESSAGE("===== NODES ====="<<NbNodes());
1615         MESSAGE("===== EDGES ====="<<NbEdges());
1616         MESSAGE("===== FACES ====="<<NbFaces());
1617         MESSAGE("===== VOLUMES ====="<<NbVolumes());
1618
1619         MESSAGE("End Debug stats of mesh ");
1620
1621         //#ifdef DEB
1622         
1623         SMDS_NodeIteratorPtr itnode=nodesIterator();
1624         int sizeofnodes = 0;
1625         int sizeoffaces = 0;
1626
1627         while(itnode->more())
1628         {
1629                 const SMDS_MeshNode *node = itnode->next();
1630
1631                 sizeofnodes += sizeof(*node);
1632                 
1633                 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1634                 while(it->more())
1635                 {
1636                         const SMDS_MeshElement *me = it->next();
1637                         sizeofnodes += sizeof(me);
1638                 }
1639
1640         }
1641
1642         SMDS_FaceIteratorPtr itface=facesIterator();
1643         while(itface->more())
1644         {
1645                 const SMDS_MeshElement *face = itface->next();          
1646                 sizeoffaces += sizeof(*face);
1647
1648         }
1649         MESSAGE("total size of node elements = " << sizeofnodes);;
1650         MESSAGE("total size of face elements = " << sizeoffaces);;
1651
1652         //#endif
1653 }
1654
1655 ///////////////////////////////////////////////////////////////////////////////
1656 /// Return the number of nodes
1657 ///////////////////////////////////////////////////////////////////////////////
1658 int SMDS_Mesh::NbNodes() const
1659 {
1660         return myNodes.Size();
1661 }
1662
1663 ///////////////////////////////////////////////////////////////////////////////
1664 /// Return the number of edges (including construction edges)
1665 ///////////////////////////////////////////////////////////////////////////////
1666 int SMDS_Mesh::NbEdges() const
1667 {
1668         return myEdges.Size();
1669 }
1670
1671 ///////////////////////////////////////////////////////////////////////////////
1672 /// Return the number of faces (including construction faces)
1673 ///////////////////////////////////////////////////////////////////////////////
1674 int SMDS_Mesh::NbFaces() const
1675 {
1676         return myFaces.Size();
1677 }
1678
1679 ///////////////////////////////////////////////////////////////////////////////
1680 /// Return the number of volumes
1681 ///////////////////////////////////////////////////////////////////////////////
1682 int SMDS_Mesh::NbVolumes() const
1683 {
1684         return myVolumes.Size();
1685 }
1686
1687 ///////////////////////////////////////////////////////////////////////////////
1688 /// Return the number of child mesh of this mesh.
1689 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1690 /// (2003-09-08) of SMESH
1691 ///////////////////////////////////////////////////////////////////////////////
1692 int SMDS_Mesh::NbSubMesh() const
1693 {
1694         return myChildren.size();
1695 }
1696
1697 ///////////////////////////////////////////////////////////////////////////////
1698 /// Destroy the mesh and all its elements
1699 /// All pointer on elements owned by this mesh become illegals.
1700 ///////////////////////////////////////////////////////////////////////////////
1701 SMDS_Mesh::~SMDS_Mesh()
1702 {
1703   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1704   while(itc!=myChildren.end())
1705   {
1706     delete *itc;
1707     itc++;
1708   }
1709
1710   SetOfNodes::Iterator itn(myNodes);
1711   for (; itn.More(); itn.Next())
1712     delete itn.Value();
1713
1714   SetOfEdges::Iterator ite(myEdges);
1715   for (; ite.More(); ite.Next())
1716   {
1717     SMDS_MeshElement* elem = ite.Value();
1718     if(myParent!=NULL)
1719       myElementIDFactory->ReleaseID(elem->GetID());
1720     delete elem;
1721   }
1722
1723   SetOfFaces::Iterator itf(myFaces);
1724   for (; itf.More(); itf.Next())
1725   {
1726     SMDS_MeshElement* elem = itf.Value();
1727     if(myParent!=NULL)
1728       myElementIDFactory->ReleaseID(elem->GetID());
1729     delete elem;
1730   }
1731
1732   SetOfVolumes::Iterator itv(myVolumes);
1733   for (; itv.More(); itv.Next())
1734   {
1735     SMDS_MeshElement* elem = itv.Value();
1736     if(myParent!=NULL)
1737       myElementIDFactory->ReleaseID(elem->GetID());
1738     delete elem;
1739   }
1740
1741   if(myParent==NULL)
1742   {
1743     delete myNodeIDFactory;
1744     delete myElementIDFactory;
1745   }
1746 }
1747
1748 ///////////////////////////////////////////////////////////////////////////////
1749 /// Return true if this mesh create faces with edges.
1750 /// A false returned value mean that faces are created with nodes. A concequence
1751 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1752 ///////////////////////////////////////////////////////////////////////////////
1753 bool SMDS_Mesh::hasConstructionEdges()
1754 {
1755         return myHasConstructionEdges;
1756 }
1757
1758 ///////////////////////////////////////////////////////////////////////////////
1759 /// Return true if this mesh create volumes with faces
1760 /// A false returned value mean that volumes are created with nodes or edges.
1761 /// (see hasConstructionEdges)
1762 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1763 /// unavailable.
1764 ///////////////////////////////////////////////////////////////////////////////
1765 bool SMDS_Mesh::hasConstructionFaces()
1766 {
1767         return myHasConstructionFaces;
1768 }
1769
1770 ///////////////////////////////////////////////////////////////////////////////
1771 /// Return true if nodes are linked to the finit elements, they are belonging to.
1772 /// Currently, It always return true.
1773 ///////////////////////////////////////////////////////////////////////////////
1774 bool SMDS_Mesh::hasInverseElements()
1775 {
1776         return myHasInverseElements;
1777 }
1778
1779 ///////////////////////////////////////////////////////////////////////////////
1780 /// Make this mesh creating construction edges (see hasConstructionEdges)
1781 /// @param b true to have construction edges, else false.
1782 ///////////////////////////////////////////////////////////////////////////////
1783 void SMDS_Mesh::setConstructionEdges(bool b)
1784 {
1785         myHasConstructionEdges=b;
1786 }
1787
1788 ///////////////////////////////////////////////////////////////////////////////
1789 /// Make this mesh creating construction faces (see hasConstructionFaces)
1790 /// @param b true to have construction faces, else false.
1791 ///////////////////////////////////////////////////////////////////////////////
1792 void SMDS_Mesh::setConstructionFaces(bool b)
1793 {
1794          myHasConstructionFaces=b;
1795 }
1796
1797 ///////////////////////////////////////////////////////////////////////////////
1798 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1799 /// @param b true to link nodes to elements, else false.
1800 ///////////////////////////////////////////////////////////////////////////////
1801 void SMDS_Mesh::setInverseElements(bool b)
1802 {
1803         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1804         myHasInverseElements=b;
1805 }
1806
1807 ///////////////////////////////////////////////////////////////////////////////
1808 /// Return an iterator on nodes of the current mesh factory
1809 ///////////////////////////////////////////////////////////////////////////////
1810 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1811 {
1812   SMDS_ElemIteratorPtr myIterator;
1813  public:
1814   SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1815   {}
1816
1817   bool more()
1818   {
1819     return myIterator->more();
1820   }
1821
1822   const SMDS_MeshNode* next()
1823   {
1824     return static_cast<const SMDS_MeshNode*>(myIterator->next());
1825   }
1826 };
1827
1828 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1829 {
1830   return SMDS_NodeIteratorPtr
1831     (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1832 }
1833
1834 ///////////////////////////////////////////////////////////////////////////////
1835 /// Return an iterator on elements of the current mesh factory
1836 ///////////////////////////////////////////////////////////////////////////////
1837 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1838 {
1839   return myElementIDFactory->elementsIterator();
1840 }
1841
1842 ///////////////////////////////////////////////////////////////////////////////
1843 ///Return an iterator on edges of the current mesh.
1844 ///////////////////////////////////////////////////////////////////////////////
1845 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1846 {
1847   typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1848   SetOfEdges::Iterator myIterator;
1849  public:
1850   SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1851   {}
1852
1853   bool more()
1854   {
1855     while(myIterator.More())
1856     {
1857       if(myIterator.Value()->GetID()!=-1)
1858         return true;
1859       myIterator.Next();
1860     }
1861     return false;
1862   }
1863
1864   const SMDS_MeshEdge* next()
1865   {
1866     const SMDS_MeshEdge* current = myIterator.Value();
1867     myIterator.Next();
1868     return current;
1869   }
1870 };
1871
1872 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1873 {
1874   return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1875 }
1876
1877 ///////////////////////////////////////////////////////////////////////////////
1878 ///Return an iterator on faces of the current mesh.
1879 ///////////////////////////////////////////////////////////////////////////////
1880 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1881 {
1882   typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1883   SetOfFaces::Iterator myIterator;
1884  public:
1885   SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
1886   {}
1887
1888   bool more()
1889   {
1890     while(myIterator.More())
1891     {
1892       if(myIterator.Value()->GetID()!=-1)
1893         return true;
1894       myIterator.Next();
1895     }
1896     return false;
1897   }
1898
1899   const SMDS_MeshFace* next()
1900   {
1901     const SMDS_MeshFace* current = myIterator.Value();
1902     myIterator.Next();
1903     return current;
1904   }
1905 };
1906
1907 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1908 {
1909   return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
1910 }
1911
1912 ///////////////////////////////////////////////////////////////////////////////
1913 ///Return an iterator on volumes of the current mesh.
1914 ///////////////////////////////////////////////////////////////////////////////
1915 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
1916 {
1917   typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
1918   SetOfVolumes::Iterator myIterator;
1919  public:
1920   SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
1921   {}
1922
1923   bool more()
1924   {
1925     return myIterator.More() != Standard_False;
1926   }
1927
1928   const SMDS_MeshVolume* next()
1929   {
1930     const SMDS_MeshVolume* current = myIterator.Value();
1931     myIterator.Next();
1932     return current;
1933   }
1934 };
1935
1936 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1937 {
1938   return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
1939 }
1940
1941 ///////////////////////////////////////////////////////////////////////////////
1942 /// Do intersection of sets (more than 2)
1943 ///////////////////////////////////////////////////////////////////////////////
1944 static set<const SMDS_MeshElement*> * intersectionOfSets(
1945         set<const SMDS_MeshElement*> vs[], int numberOfSets)
1946 {
1947         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1948         set<const SMDS_MeshElement*>* rsetB;
1949
1950         for(int i=0; i<numberOfSets-1; i++)
1951         {
1952                 rsetB=new set<const SMDS_MeshElement*>();
1953                 set_intersection(
1954                         rsetA->begin(), rsetA->end(),
1955                         vs[i+1].begin(), vs[i+1].end(),
1956                         inserter(*rsetB, rsetB->begin()));
1957                 delete rsetA;
1958                 rsetA=rsetB;
1959         }
1960         return rsetA;
1961 }
1962
1963 ///////////////////////////////////////////////////////////////////////////////
1964 /// Return the list of finit elements owning the given element
1965 ///////////////////////////////////////////////////////////////////////////////
1966 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1967 {
1968         int numberOfSets=element->NbNodes();
1969         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
1970
1971         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1972
1973         int i=0;
1974         while(itNodes->more())
1975         {
1976                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1977                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1978
1979                 //initSet[i]=set<const SMDS_MeshElement*>();
1980                 while(itFe->more())
1981                   initSet[i].insert(itFe->next());
1982
1983                 i++;
1984         }
1985         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
1986         delete [] initSet;
1987         return retSet;
1988 }
1989
1990 ///////////////////////////////////////////////////////////////////////////////
1991 /// Return the list of nodes used only by the given elements
1992 ///////////////////////////////////////////////////////////////////////////////
1993 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1994         set<const SMDS_MeshElement*>& elements)
1995 {
1996         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1997         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1998
1999         while(itElements!=elements.end())
2000         {
2001                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2002                 itElements++;
2003         
2004                 while(itNodes->more())
2005                 {
2006                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2007                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2008                         set<const SMDS_MeshElement*> s;
2009                         while(itFe->more())
2010                           s.insert(itFe->next());
2011                         if(s==elements) toReturn->insert(n);
2012                 }
2013         }
2014         return toReturn;        
2015 }
2016
2017 ///////////////////////////////////////////////////////////////////////////////
2018 ///Find the children of an element that are made of given nodes 
2019 ///@param setOfChildren The set in which matching children will be inserted
2020 ///@param element The element were to search matching children
2021 ///@param nodes The nodes that the children must have to be selected
2022 ///////////////////////////////////////////////////////////////////////////////
2023 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren, 
2024         const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2025 {
2026         
2027         switch(element->GetType())
2028         {
2029         case SMDSAbs_Node:
2030                 MESSAGE("Internal Error: This should not append");
2031                 break;
2032         case SMDSAbs_Edge:
2033         {
2034                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2035                 while(itn->more())
2036                 {
2037                         const SMDS_MeshElement * e=itn->next();
2038                         if(nodes.find(e)!=nodes.end())
2039                         {
2040                           setOfChildren.insert(element);
2041                           break;
2042                         }
2043                 }
2044         } break;
2045         case SMDSAbs_Face:
2046         {
2047                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2048                 while(itn->more())
2049                 {
2050                         const SMDS_MeshElement * e=itn->next();
2051                         if(nodes.find(e)!=nodes.end())
2052                         {
2053                           setOfChildren.insert(element);
2054                           break;
2055                         }
2056                 }
2057                 if(hasConstructionEdges())
2058                 {
2059                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2060                         while(ite->more())
2061                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2062                 }
2063         } break;        
2064         case SMDSAbs_Volume:
2065         {
2066                 if(hasConstructionFaces())
2067                 {
2068                         SMDS_ElemIteratorPtr ite=element->facesIterator();
2069                         while(ite->more())
2070                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2071                 }
2072                 else if(hasConstructionEdges())
2073                 {
2074                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2075                         while(ite->more())
2076                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2077                 }
2078         }
2079         }
2080 }
2081
2082 ///////////////////////////////////////////////////////////////////////////////
2083 ///@param elem The element to delete
2084 ///@param removenodes if true remaining nodes will be removed
2085 ///////////////////////////////////////////////////////////////////////////////
2086 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2087         const bool removenodes)
2088 {
2089   list<const SMDS_MeshElement *> removedElems;
2090   list<const SMDS_MeshElement *> removedNodes;
2091   RemoveElement( elem, removedElems, removedNodes, removenodes );
2092 }
2093   
2094 ///////////////////////////////////////////////////////////////////////////////
2095 ///@param elem The element to delete
2096 ///@param removedElems contains all removed elements
2097 ///@param removedNodes contains all removed nodes
2098 ///@param removenodes if true remaining nodes will be removed
2099 ///////////////////////////////////////////////////////////////////////////////
2100 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
2101                               list<const SMDS_MeshElement *>& removedElems,
2102                               list<const SMDS_MeshElement *>& removedNodes,
2103                               bool                            removenodes)
2104 {
2105   // get finite elements built on elem
2106   set<const SMDS_MeshElement*> * s1;
2107   if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2108       !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2109       elem->GetType() == SMDSAbs_Volume)
2110   {
2111     s1 = new set<const SMDS_MeshElement*>();
2112     s1->insert(elem);
2113   }
2114   else
2115     s1 = getFinitElements(elem);
2116
2117   // get exclusive nodes (which would become free afterwards)
2118   set<const SMDS_MeshElement*> * s2;
2119   if (elem->GetType() == SMDSAbs_Node) // a node is removed
2120   {
2121     // do not remove nodes except elem
2122     s2 = new set<const SMDS_MeshElement*>();
2123     s2->insert(elem);
2124     removenodes = true;
2125   }
2126   else
2127     s2 = getExclusiveNodes(*s1);
2128
2129   // form the set of finite and construction elements to remove
2130   set<const SMDS_MeshElement*> s3;
2131   set<const SMDS_MeshElement*>::iterator it=s1->begin();
2132   while(it!=s1->end())
2133   {
2134     addChildrenWithNodes(s3, *it ,*s2);
2135     s3.insert(*it);
2136     it++;
2137   }
2138   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2139
2140   // remove finite and construction elements
2141   it=s3.begin();
2142   while(it!=s3.end())
2143   {
2144     // Remove element from <InverseElements> of its nodes
2145     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2146     while(itn->more())
2147     {
2148       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2149         (const_cast<SMDS_MeshElement *>(itn->next()));
2150       n->RemoveInverseElement( (*it) );
2151     }
2152
2153     switch((*it)->GetType())
2154     {
2155     case SMDSAbs_Node:
2156       MESSAGE("Internal Error: This should not happen");
2157       break;
2158     case SMDSAbs_Edge:
2159       myEdges.Remove(static_cast<SMDS_MeshEdge*>
2160                     (const_cast<SMDS_MeshElement*>(*it)));
2161       break;
2162     case SMDSAbs_Face:
2163       myFaces.Remove(static_cast<SMDS_MeshFace*>
2164                     (const_cast<SMDS_MeshElement*>(*it)));
2165       break;
2166     case SMDSAbs_Volume:
2167       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2168                       (const_cast<SMDS_MeshElement*>(*it)));
2169       break;
2170     }
2171     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2172     removedElems.push_back( (*it) );
2173     myElementIDFactory->ReleaseID((*it)->GetID());
2174     delete (*it);
2175     it++;
2176   }
2177
2178   // remove exclusive (free) nodes
2179   if(removenodes)
2180   {
2181     it=s2->begin();
2182     while(it!=s2->end())
2183     {
2184       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2185       myNodes.Remove(static_cast<SMDS_MeshNode*>
2186                     (const_cast<SMDS_MeshElement*>(*it)));
2187       myNodeIDFactory->ReleaseID((*it)->GetID());
2188       removedNodes.push_back( (*it) );
2189       delete *it;
2190       it++;
2191     }
2192   }
2193
2194   delete s2;
2195   delete s1;
2196 }
2197
2198   
2199 ///////////////////////////////////////////////////////////////////////////////
2200 ///@param elem The element to delete
2201 ///////////////////////////////////////////////////////////////////////////////
2202 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2203 {
2204   SMDSAbs_ElementType aType = elem->GetType();
2205   if (aType == SMDSAbs_Node) {
2206     // only free node can be removed by this method
2207     const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2208     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2209     if (!itFe->more()) { // free node
2210       myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2211       myNodeIDFactory->ReleaseID(elem->GetID());
2212       delete elem;
2213     }
2214   } else {
2215     if (hasConstructionEdges() || hasConstructionFaces())
2216       // this methods is only for meshes without descendants
2217       return;
2218
2219     // Remove element from <InverseElements> of its nodes
2220     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2221     while (itn->more()) {
2222       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2223         (const_cast<SMDS_MeshElement *>(itn->next()));
2224       n->RemoveInverseElement(elem);
2225     }
2226
2227     // in meshes without descendants elements are always free
2228     switch (aType) {
2229     case SMDSAbs_Edge:
2230       myEdges.Remove(static_cast<SMDS_MeshEdge*>
2231                      (const_cast<SMDS_MeshElement*>(elem)));
2232       break;
2233     case SMDSAbs_Face:
2234       myFaces.Remove(static_cast<SMDS_MeshFace*>
2235                      (const_cast<SMDS_MeshElement*>(elem)));
2236       break;
2237     case SMDSAbs_Volume:
2238       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2239                        (const_cast<SMDS_MeshElement*>(elem)));
2240       break;
2241     default:
2242       break;
2243     }
2244     myElementIDFactory->ReleaseID(elem->GetID());
2245     delete elem;
2246   }
2247 }
2248
2249 /*!
2250  * Checks if the element is present in mesh.
2251  * Useful to determine dead pointers.
2252  */
2253 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2254 {
2255   // we should not imply on validity of *elem, so iterate on containers
2256   // of all types in the hope of finding <elem> somewhere there
2257   SMDS_NodeIteratorPtr itn = nodesIterator();
2258   while (itn->more())
2259     if (elem == itn->next())
2260       return true;
2261   SMDS_EdgeIteratorPtr ite = edgesIterator();
2262   while (ite->more())
2263     if (elem == ite->next())
2264       return true;
2265   SMDS_FaceIteratorPtr itf = facesIterator();
2266   while (itf->more())
2267     if (elem == itf->next())
2268       return true;
2269   SMDS_VolumeIteratorPtr itv = volumesIterator();
2270   while (itv->more())
2271     if (elem == itv->next())
2272       return true;
2273   return false;
2274 }
2275
2276 //=======================================================================
2277 //function : MaxNodeID
2278 //purpose  : 
2279 //=======================================================================
2280
2281 int SMDS_Mesh::MaxNodeID() const
2282 {
2283   return myNodeIDFactory->GetMaxID();
2284 }
2285
2286 //=======================================================================
2287 //function : MinNodeID
2288 //purpose  : 
2289 //=======================================================================
2290
2291 int SMDS_Mesh::MinNodeID() const
2292 {
2293   return myNodeIDFactory->GetMinID();
2294 }
2295
2296 //=======================================================================
2297 //function : MaxElementID
2298 //purpose  : 
2299 //=======================================================================
2300
2301 int SMDS_Mesh::MaxElementID() const
2302 {
2303   return myElementIDFactory->GetMaxID();
2304 }
2305
2306 //=======================================================================
2307 //function : MinElementID
2308 //purpose  : 
2309 //=======================================================================
2310
2311 int SMDS_Mesh::MinElementID() const
2312 {
2313   return myElementIDFactory->GetMinID();
2314 }
2315
2316 //=======================================================================
2317 //function : Renumber
2318 //purpose  : Renumber all nodes or elements.
2319 //=======================================================================
2320
2321 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
2322 {
2323   if ( deltaID == 0 )
2324     return;
2325
2326   SMDS_MeshElementIDFactory * idFactory =
2327     isNodes ? myNodeIDFactory : myElementIDFactory;
2328
2329   // get existing elements in the order of ID increasing
2330   map<int,SMDS_MeshElement*> elemMap;
2331   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2332   while ( idElemIt->more() ) {
2333     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2334     int id = elem->GetID();
2335     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2336   }
2337   // release their ids
2338   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2339   for ( ; elemIt != elemMap.end(); elemIt++ )
2340   {
2341     int id = (*elemIt).first;
2342     idFactory->ReleaseID( id );
2343   }
2344   // set new IDs
2345   int ID = startID;
2346   elemIt = elemMap.begin();
2347   for ( ; elemIt != elemMap.end(); elemIt++ )
2348   {
2349     idFactory->BindID( ID, (*elemIt).second );
2350     ID += deltaID;
2351   }
2352 }
2353
2354 //=======================================================================
2355 //function : GetElementType
2356 //purpose  : Return type of element or node with id
2357 //=======================================================================
2358
2359 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2360 {
2361   SMDS_MeshElement* elem = 0;
2362   if( iselem )
2363     elem = myElementIDFactory->MeshElement( id );
2364   else
2365     elem = myNodeIDFactory->MeshElement( id );
2366
2367   if( !elem )
2368   {
2369     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2370     return SMDSAbs_All;
2371   }
2372   else
2373     return elem->GetType();
2374 }
2375
2376
2377
2378 //********************************************************************
2379 //********************************************************************
2380 //********                                                   *********
2381 //*****       Methods for addition of quadratic elements        ******
2382 //********                                                   *********
2383 //********************************************************************
2384 //********************************************************************
2385
2386 //=======================================================================
2387 //function : AddEdgeWithID
2388 //purpose  : 
2389 //=======================================================================
2390 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
2391 {
2392   return SMDS_Mesh::AddEdgeWithID
2393     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2394      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2395      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2396      ID);
2397 }
2398
2399 //=======================================================================
2400 //function : AddEdge
2401 //purpose  : 
2402 //=======================================================================
2403 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2404                                   const SMDS_MeshNode* n2,
2405                                   const SMDS_MeshNode* n12)
2406 {
2407   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2408 }
2409
2410 //=======================================================================
2411 //function : AddEdgeWithID
2412 //purpose  : 
2413 //=======================================================================
2414 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2415                                         const SMDS_MeshNode * n2, 
2416                                         const SMDS_MeshNode * n12, 
2417                                         int ID)
2418 {
2419   if ( !n1 || !n2 || !n12 ) return 0;
2420   SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2421   if(myElementIDFactory->BindID(ID, edge)) {
2422     SMDS_MeshNode *node1,*node2, *node12;
2423     node1 = const_cast<SMDS_MeshNode*>(n1);
2424     node2 = const_cast<SMDS_MeshNode*>(n2);
2425     node12 = const_cast<SMDS_MeshNode*>(n12);
2426     node1->AddInverseElement(edge);
2427     node2->AddInverseElement(edge);
2428     node12->AddInverseElement(edge);
2429     myEdges.Add(edge);
2430     return edge;
2431   } 
2432   else {
2433     delete edge;
2434     return NULL;
2435   }
2436 }
2437
2438
2439 //=======================================================================
2440 //function : AddFace
2441 //purpose  : 
2442 //=======================================================================
2443 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2444                                   const SMDS_MeshNode * n2,
2445                                   const SMDS_MeshNode * n3,
2446                                   const SMDS_MeshNode * n12,
2447                                   const SMDS_MeshNode * n23,
2448                                   const SMDS_MeshNode * n31)
2449 {
2450   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2451                                   myElementIDFactory->GetFreeID());
2452 }
2453
2454 //=======================================================================
2455 //function : AddFaceWithID
2456 //purpose  : 
2457 //=======================================================================
2458 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2459                                         int n12,int n23,int n31, int ID)
2460 {
2461   return SMDS_Mesh::AddFaceWithID
2462     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2463      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2464      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2465      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2466      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2467      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2468      ID);
2469 }
2470
2471 //=======================================================================
2472 //function : AddFaceWithID
2473 //purpose  : 
2474 //=======================================================================
2475 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2476                                         const SMDS_MeshNode * n2,
2477                                         const SMDS_MeshNode * n3,
2478                                         const SMDS_MeshNode * n12,
2479                                         const SMDS_MeshNode * n23,
2480                                         const SMDS_MeshNode * n31, 
2481                                         int ID)
2482 {
2483   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2484   if(hasConstructionEdges()) {
2485     // creation quadratic edges - not implemented
2486     return 0;
2487   }
2488   SMDS_QuadraticFaceOfNodes* face =
2489     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2490   myFaces.Add(face);
2491
2492   if (!registerElement(ID, face)) {
2493     RemoveElement(face, false);
2494     face = NULL;
2495   }
2496   return face;
2497 }
2498
2499
2500 //=======================================================================
2501 //function : AddFace
2502 //purpose  : 
2503 //=======================================================================
2504 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2505                                   const SMDS_MeshNode * n2,
2506                                   const SMDS_MeshNode * n3,
2507                                   const SMDS_MeshNode * n4,
2508                                   const SMDS_MeshNode * n12,
2509                                   const SMDS_MeshNode * n23,
2510                                   const SMDS_MeshNode * n34,
2511                                   const SMDS_MeshNode * n41)
2512 {
2513   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2514                                   myElementIDFactory->GetFreeID());
2515 }
2516
2517 //=======================================================================
2518 //function : AddFaceWithID
2519 //purpose  : 
2520 //=======================================================================
2521 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2522                                         int n12,int n23,int n34,int n41, int ID)
2523 {
2524   return SMDS_Mesh::AddFaceWithID
2525     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2526      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2527      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2528      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2529      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2530      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2531      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2532      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2533      ID);
2534 }
2535
2536 //=======================================================================
2537 //function : AddFaceWithID
2538 //purpose  : 
2539 //=======================================================================
2540 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2541                                         const SMDS_MeshNode * n2,
2542                                         const SMDS_MeshNode * n3,
2543                                         const SMDS_MeshNode * n4,
2544                                         const SMDS_MeshNode * n12,
2545                                         const SMDS_MeshNode * n23,
2546                                         const SMDS_MeshNode * n34, 
2547                                         const SMDS_MeshNode * n41, 
2548                                         int ID)
2549 {
2550   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2551   if(hasConstructionEdges()) {
2552     // creation quadratic edges - not implemented
2553   }
2554   SMDS_QuadraticFaceOfNodes* face =
2555     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2556   myFaces.Add(face);
2557
2558   if (!registerElement(ID, face)) {
2559     RemoveElement(face, false);
2560     face = NULL;
2561   }
2562   return face;
2563 }
2564
2565
2566 //=======================================================================
2567 //function : AddVolume
2568 //purpose  : 
2569 //=======================================================================
2570 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2571                                       const SMDS_MeshNode * n2, 
2572                                       const SMDS_MeshNode * n3,
2573                                       const SMDS_MeshNode * n4,
2574                                       const SMDS_MeshNode * n12,
2575                                       const SMDS_MeshNode * n23,
2576                                       const SMDS_MeshNode * n31,
2577                                       const SMDS_MeshNode * n14, 
2578                                       const SMDS_MeshNode * n24,
2579                                       const SMDS_MeshNode * n34)
2580 {
2581   int ID = myElementIDFactory->GetFreeID();
2582   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2583                                                    n31, n14, n24, n34, ID);
2584   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2585   return v;
2586 }
2587
2588 //=======================================================================
2589 //function : AddVolumeWithID
2590 //purpose  : 
2591 //=======================================================================
2592 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2593                                             int n12,int n23,int n31,
2594                                             int n14,int n24,int n34, int ID)
2595 {
2596   return SMDS_Mesh::AddVolumeWithID
2597     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2598      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2599      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2600      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2601      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2602      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2603      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2604      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2605      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2606      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2607      ID);
2608 }
2609
2610 //=======================================================================
2611 //function : AddVolumeWithID
2612 //purpose  : 2d order tetrahedron of 10 nodes
2613 //=======================================================================
2614 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2615                                             const SMDS_MeshNode * n2,
2616                                             const SMDS_MeshNode * n3,
2617                                             const SMDS_MeshNode * n4,
2618                                             const SMDS_MeshNode * n12,
2619                                             const SMDS_MeshNode * n23,
2620                                             const SMDS_MeshNode * n31,
2621                                             const SMDS_MeshNode * n14, 
2622                                             const SMDS_MeshNode * n24,
2623                                             const SMDS_MeshNode * n34,
2624                                             int ID)
2625 {
2626   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2627     return 0;
2628   if(hasConstructionFaces()) {
2629     // creation quadratic faces - not implemented
2630     return 0;
2631   }
2632   SMDS_QuadraticVolumeOfNodes * volume =
2633     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2634   myVolumes.Add(volume);
2635
2636   if (!registerElement(ID, volume)) {
2637     RemoveElement(volume, false);
2638     volume = NULL;
2639   }
2640   return volume;
2641 }
2642
2643
2644 //=======================================================================
2645 //function : AddVolume
2646 //purpose  : 
2647 //=======================================================================
2648 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2649                                       const SMDS_MeshNode * n2, 
2650                                       const SMDS_MeshNode * n3,
2651                                       const SMDS_MeshNode * n4,
2652                                       const SMDS_MeshNode * n5, 
2653                                       const SMDS_MeshNode * n12,
2654                                       const SMDS_MeshNode * n23,
2655                                       const SMDS_MeshNode * n34,
2656                                       const SMDS_MeshNode * n41,
2657                                       const SMDS_MeshNode * n15, 
2658                                       const SMDS_MeshNode * n25,
2659                                       const SMDS_MeshNode * n35,
2660                                       const SMDS_MeshNode * n45)
2661 {
2662   int ID = myElementIDFactory->GetFreeID();
2663   SMDS_MeshVolume * v =
2664     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2665                                n15, n25, n35, n45, ID);
2666   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2667   return v;
2668 }
2669
2670 //=======================================================================
2671 //function : AddVolumeWithID
2672 //purpose  : 
2673 //=======================================================================
2674 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2675                                             int n12,int n23,int n34,int n41,
2676                                             int n15,int n25,int n35,int n45, int ID)
2677 {
2678   return SMDS_Mesh::AddVolumeWithID
2679     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2680      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2681      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2682      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2683      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2684      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2685      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2686      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2687      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2688      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2689      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2690      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2691      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2692      ID);
2693 }
2694
2695 //=======================================================================
2696 //function : AddVolumeWithID
2697 //purpose  : 2d order pyramid of 13 nodes
2698 //=======================================================================
2699 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2700                                             const SMDS_MeshNode * n2,
2701                                             const SMDS_MeshNode * n3,
2702                                             const SMDS_MeshNode * n4,
2703                                             const SMDS_MeshNode * n5, 
2704                                             const SMDS_MeshNode * n12,
2705                                             const SMDS_MeshNode * n23,
2706                                             const SMDS_MeshNode * n34,
2707                                             const SMDS_MeshNode * n41,
2708                                             const SMDS_MeshNode * n15, 
2709                                             const SMDS_MeshNode * n25,
2710                                             const SMDS_MeshNode * n35,
2711                                             const SMDS_MeshNode * n45,
2712                                             int ID)
2713 {
2714   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2715       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2716     return 0;
2717   if(hasConstructionFaces()) {
2718     // creation quadratic faces - not implemented
2719     return 0;
2720   }
2721   SMDS_QuadraticVolumeOfNodes * volume =
2722     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2723                                     n34,n41,n15,n25,n35,n45);
2724   myVolumes.Add(volume);
2725
2726   if (!registerElement(ID, volume)) {
2727     RemoveElement(volume, false);
2728     volume = NULL;
2729   }
2730   return volume;
2731 }
2732
2733
2734 //=======================================================================
2735 //function : AddVolume
2736 //purpose  : 
2737 //=======================================================================
2738 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2739                                       const SMDS_MeshNode * n2, 
2740                                       const SMDS_MeshNode * n3,
2741                                       const SMDS_MeshNode * n4,
2742                                       const SMDS_MeshNode * n5, 
2743                                       const SMDS_MeshNode * n6, 
2744                                       const SMDS_MeshNode * n12,
2745                                       const SMDS_MeshNode * n23,
2746                                       const SMDS_MeshNode * n31, 
2747                                       const SMDS_MeshNode * n45,
2748                                       const SMDS_MeshNode * n56,
2749                                       const SMDS_MeshNode * n64, 
2750                                       const SMDS_MeshNode * n14,
2751                                       const SMDS_MeshNode * n25,
2752                                       const SMDS_MeshNode * n36)
2753 {
2754   int ID = myElementIDFactory->GetFreeID();
2755   SMDS_MeshVolume * v =
2756     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2757                                n45, n56, n64, n14, n25, n36, ID);
2758   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2759   return v;
2760 }
2761
2762 //=======================================================================
2763 //function : AddVolumeWithID
2764 //purpose  : 
2765 //=======================================================================
2766 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2767                                             int n4, int n5, int n6,
2768                                             int n12,int n23,int n31,
2769                                             int n45,int n56,int n64,
2770                                             int n14,int n25,int n36, int ID)
2771 {
2772   return SMDS_Mesh::AddVolumeWithID
2773     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2774      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2775      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2776      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2777      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2778      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2779      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2780      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2781      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2782      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2783      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2784      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2785      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2786      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2787      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2788      ID);
2789 }
2790
2791 //=======================================================================
2792 //function : AddVolumeWithID
2793 //purpose  : 2d order Pentahedron with 15 nodes
2794 //=======================================================================
2795 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2796                                             const SMDS_MeshNode * n2,
2797                                             const SMDS_MeshNode * n3,
2798                                             const SMDS_MeshNode * n4,
2799                                             const SMDS_MeshNode * n5, 
2800                                             const SMDS_MeshNode * n6, 
2801                                             const SMDS_MeshNode * n12,
2802                                             const SMDS_MeshNode * n23,
2803                                             const SMDS_MeshNode * n31, 
2804                                             const SMDS_MeshNode * n45,
2805                                             const SMDS_MeshNode * n56,
2806                                             const SMDS_MeshNode * n64, 
2807                                             const SMDS_MeshNode * n14,
2808                                             const SMDS_MeshNode * n25,
2809                                             const SMDS_MeshNode * n36,
2810                                             int ID)
2811 {
2812   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2813       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2814     return 0;
2815   if(hasConstructionFaces()) {
2816     // creation quadratic faces - not implemented
2817     return 0;
2818   }
2819   SMDS_QuadraticVolumeOfNodes * volume =
2820     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2821                                     n45,n56,n64,n14,n25,n36);
2822   myVolumes.Add(volume);
2823
2824   if (!registerElement(ID, volume)) {
2825     RemoveElement(volume, false);
2826     volume = NULL;
2827   }
2828   return volume;
2829 }
2830
2831
2832 //=======================================================================
2833 //function : AddVolume
2834 //purpose  : 
2835 //=======================================================================
2836 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2837                                       const SMDS_MeshNode * n2, 
2838                                       const SMDS_MeshNode * n3,
2839                                       const SMDS_MeshNode * n4,
2840                                       const SMDS_MeshNode * n5, 
2841                                       const SMDS_MeshNode * n6, 
2842                                       const SMDS_MeshNode * n7,
2843                                       const SMDS_MeshNode * n8, 
2844                                       const SMDS_MeshNode * n12,
2845                                       const SMDS_MeshNode * n23,
2846                                       const SMDS_MeshNode * n34,
2847                                       const SMDS_MeshNode * n41, 
2848                                       const SMDS_MeshNode * n56,
2849                                       const SMDS_MeshNode * n67,
2850                                       const SMDS_MeshNode * n78,
2851                                       const SMDS_MeshNode * n85, 
2852                                       const SMDS_MeshNode * n15,
2853                                       const SMDS_MeshNode * n26,
2854                                       const SMDS_MeshNode * n37,
2855                                       const SMDS_MeshNode * n48)
2856 {
2857   int ID = myElementIDFactory->GetFreeID();
2858   SMDS_MeshVolume * v =
2859     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2860                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
2861   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2862   return v;
2863 }
2864
2865 //=======================================================================
2866 //function : AddVolumeWithID
2867 //purpose  : 
2868 //=======================================================================
2869 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2870                                             int n5, int n6, int n7, int n8,
2871                                             int n12,int n23,int n34,int n41,
2872                                             int n56,int n67,int n78,int n85,
2873                                             int n15,int n26,int n37,int n48, int ID)
2874 {
2875   return SMDS_Mesh::AddVolumeWithID
2876     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2877      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2878      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
2879      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
2880      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
2881      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
2882      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
2883      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
2884      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2885      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2886      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2887      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2888      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2889      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
2890      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
2891      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
2892      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2893      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
2894      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
2895      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
2896      ID);
2897 }
2898
2899 //=======================================================================
2900 //function : AddVolumeWithID
2901 //purpose  : 2d order Hexahedrons with 20 nodes
2902 //=======================================================================
2903 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2904                                             const SMDS_MeshNode * n2,
2905                                             const SMDS_MeshNode * n3,
2906                                             const SMDS_MeshNode * n4,
2907                                             const SMDS_MeshNode * n5, 
2908                                             const SMDS_MeshNode * n6, 
2909                                             const SMDS_MeshNode * n7,
2910                                             const SMDS_MeshNode * n8, 
2911                                             const SMDS_MeshNode * n12,
2912                                             const SMDS_MeshNode * n23,
2913                                             const SMDS_MeshNode * n34,
2914                                             const SMDS_MeshNode * n41, 
2915                                             const SMDS_MeshNode * n56,
2916                                             const SMDS_MeshNode * n67,
2917                                             const SMDS_MeshNode * n78,
2918                                             const SMDS_MeshNode * n85, 
2919                                             const SMDS_MeshNode * n15,
2920                                             const SMDS_MeshNode * n26,
2921                                             const SMDS_MeshNode * n37,
2922                                             const SMDS_MeshNode * n48,
2923                                             int ID)
2924 {
2925   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
2926       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
2927     return 0;
2928   if(hasConstructionFaces()) {
2929     return 0;
2930     // creation quadratic faces - not implemented
2931   }
2932   SMDS_QuadraticVolumeOfNodes * volume =
2933     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
2934                                     n56,n67,n78,n85,n15,n26,n37,n48);
2935   myVolumes.Add(volume);
2936
2937   if (!registerElement(ID, volume)) {
2938     RemoveElement(volume, false);
2939     volume = NULL;
2940   }
2941   return volume;
2942 }
2943