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