Salome HOME
Merge branch merge_1_2_d
[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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21
22 #include "utilities.h"
23 #include "SMDS_Mesh.hxx"
24 #include "SMDS_VolumeOfNodes.hxx"
25 #include "SMDS_VolumeOfFaces.hxx"
26 #include "SMDS_FaceOfNodes.hxx"
27 #include "SMDS_Tria3OfNodes.hxx"
28 #include "SMDS_HexahedronOfNodes.hxx"
29 #include "SMDS_FaceOfEdges.hxx"
30
31 #include <algorithm>
32 using namespace std;
33
34 ///////////////////////////////////////////////////////////////////////////////
35 /// Create a new mesh object
36 ///////////////////////////////////////////////////////////////////////////////
37 SMDS_Mesh::SMDS_Mesh()
38         :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
39         myElementIDFactory(new SMDS_MeshElementIDFactory()),
40         myHasConstructionEdges(false), myHasConstructionFaces(false),
41         myHasInverseElements(true)
42 {
43 }
44
45 ///////////////////////////////////////////////////////////////////////////////
46 /// Create a new child mesh
47 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
48 /// (2003-09-08) of SMESH
49 ///////////////////////////////////////////////////////////////////////////////
50 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
51         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
52         myElementIDFactory(parent->myElementIDFactory),
53         myHasConstructionEdges(false), myHasConstructionFaces(false),
54         myHasInverseElements(true)
55 {
56 }
57
58 ///////////////////////////////////////////////////////////////////////////////
59 ///Create a submesh and add it to the current mesh
60 ///////////////////////////////////////////////////////////////////////////////
61
62 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
63 {
64         SMDS_Mesh *submesh = new SMDS_Mesh(this);
65         myChildren.insert(myChildren.end(), submesh);
66         return submesh;
67 }
68
69 ///////////////////////////////////////////////////////////////////////////////
70 ///create a MeshNode and add it to the current Mesh
71 ///An ID is automatically assigned to the node.
72 ///@return : The created node
73 ///////////////////////////////////////////////////////////////////////////////
74
75 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
76 {
77         return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
78 }
79
80 ///////////////////////////////////////////////////////////////////////////////
81 ///create a MeshNode and add it to the current Mesh
82 ///@param ID : The ID of the MeshNode to create
83 ///@return : The created node or NULL if a node with this ID already exists
84 ///////////////////////////////////////////////////////////////////////////////
85 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
86 {
87         // find the MeshNode corresponding to ID
88         const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
89
90         if (node == NULL)
91         {
92                 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
93                 myNodes.insert(node);
94                 myNodeIDFactory->BindID(ID,node);
95                 return node;
96         }
97         else
98                 return NULL;
99 }
100
101 ///////////////////////////////////////////////////////////////////////////////
102 /// create a MeshEdge and add it to the current Mesh
103 /// @return : The created MeshEdge
104 ///////////////////////////////////////////////////////////////////////////////
105
106 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
107 {
108         SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
109         SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
110         if((node1==NULL)||(node2==NULL)) return NULL;
111         return AddEdgeWithID(node1, node2, ID);
112 }
113
114 ///////////////////////////////////////////////////////////////////////////////
115 /// create a MeshEdge and add it to the current Mesh
116 /// @return : The created MeshEdge
117 ///////////////////////////////////////////////////////////////////////////////
118
119 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
120         const SMDS_MeshNode * node2)
121 {
122         return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
123 }
124
125 ///////////////////////////////////////////////////////////////////////////////
126 /// Create a new edge and at it to the mesh
127 /// @param idnode1 ID of the first node
128 /// @param idnode2 ID of the second node
129 /// @param ID ID of the edge to create
130 /// @return The created edge or NULL if an edge with this ID already exists or
131 /// if input nodes are not found.
132 ///////////////////////////////////////////////////////////////////////////////
133
134 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
135                 const SMDS_MeshNode * n2, int ID)
136 {
137         SMDS_MeshNode *node1,*node2;
138         node1=const_cast<SMDS_MeshNode*>(n1);
139         node2=const_cast<SMDS_MeshNode*>(n2);
140
141         SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2);
142         if(myElementIDFactory->BindID(ID, edge))
143         {
144                 node1->AddInverseElement(edge);
145                 node2->AddInverseElement(edge);         
146                 myEdges.insert(edge);
147                 return edge;
148         } 
149         else
150         {
151                 delete edge;
152                 return NULL;
153         }
154 }
155
156 ///////////////////////////////////////////////////////////////////////////////
157 /// Add a triangle defined by its nodes. An ID is automatically affected to the
158 /// Created face
159 ///////////////////////////////////////////////////////////////////////////////
160
161 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
162         const SMDS_MeshNode * n2,
163         const SMDS_MeshNode * n3)
164 {
165         return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
166 }
167
168 ///////////////////////////////////////////////////////////////////////////////
169 /// Add a quadrangle defined by its nodes IDs
170 ///////////////////////////////////////////////////////////////////////////////
171
172 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
173 {
174         SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
175         SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
176         SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
177         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
178         return AddFaceWithID(node1, node2, node3, ID);  
179 }
180
181 ///////////////////////////////////////////////////////////////////////////////
182 /// Add a quadrangle defined by its nodes
183 ///////////////////////////////////////////////////////////////////////////////
184
185 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(
186         const SMDS_MeshNode * n1,
187         const SMDS_MeshNode * n2,
188         const SMDS_MeshNode * n3, int ID)
189 {
190         SMDS_MeshNode *node1, *node2, *node3;
191         node1=const_cast<SMDS_MeshNode*>(n1),
192         node2=const_cast<SMDS_MeshNode*>(n2),
193         node3=const_cast<SMDS_MeshNode*>(n3);
194         SMDS_MeshFace * face=createTriangle(node1, node2, node3);
195
196         if(myElementIDFactory->BindID(ID, face))
197         {
198                 node1->AddInverseElement(face);
199                 node2->AddInverseElement(face);
200         node3->AddInverseElement(face);
201                 return face;
202         }       
203         else
204         {
205                 RemoveFace(face);
206                 return NULL;
207         }
208 }
209
210 ///////////////////////////////////////////////////////////////////////////////
211 /// Add a triangle defined by its nodes. An ID is automatically affected to the
212 /// created face
213 ///////////////////////////////////////////////////////////////////////////////
214
215 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
216         const SMDS_MeshNode * n2,
217         const SMDS_MeshNode * n3,
218         const SMDS_MeshNode * n4)
219 {
220         return AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////
224 /// Add a quadrangle defined by its nodes IDs
225 ///////////////////////////////////////////////////////////////////////////////
226
227 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3,
228         int idnode4, int ID)
229 {
230         SMDS_MeshNode *node1, *node2, *node3, *node4;
231         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
232         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
233         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
234         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
235         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
236         return AddFaceWithID(node1, node2, node3, node4, ID);   
237 }
238
239 ///////////////////////////////////////////////////////////////////////////////
240 /// Add a quadrangle defined by its nodes
241 ///////////////////////////////////////////////////////////////////////////////
242
243 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
244         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
245         const SMDS_MeshNode * n4, int ID)
246 {
247         SMDS_MeshNode *node1, *node2, *node3, *node4;
248         node1=const_cast<SMDS_MeshNode*>(n1),
249         node2=const_cast<SMDS_MeshNode*>(n2),
250         node3=const_cast<SMDS_MeshNode*>(n3);
251         node4=const_cast<SMDS_MeshNode*>(n4);
252         SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4);
253
254         if(myElementIDFactory->BindID(ID, face))
255         {
256                 node1->AddInverseElement(face);
257                 node2->AddInverseElement(face);
258         node3->AddInverseElement(face);
259         node4->AddInverseElement(face);
260                 return face;
261         }       
262         else
263         {
264                 RemoveFace(face);
265                 return NULL;
266         }
267 }
268
269 ///////////////////////////////////////////////////////////////////////////////
270 ///Create a new tetrahedron and add it to the mesh. 
271 ///@return The created tetrahedron 
272 ///////////////////////////////////////////////////////////////////////////////
273
274 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
275         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
276         const SMDS_MeshNode * n4)
277 {
278         int ID = myElementIDFactory->GetFreeID();
279         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID);
280         if(v==NULL) myElementIDFactory->ReleaseID(ID);
281         return v;
282 }
283
284 ///////////////////////////////////////////////////////////////////////////////
285 ///Create a new tetrahedron and add it to the mesh. 
286 ///@param ID The ID of the new volume
287 ///@return The created tetrahedron or NULL if an edge with this ID already exists
288 ///or if input nodes are not found.
289 ///////////////////////////////////////////////////////////////////////////////
290
291 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
292         int idnode3, int idnode4, int ID)
293 {
294         SMDS_MeshNode *node1, *node2, *node3, *node4;
295         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
296         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
297         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
298         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
299         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
300         return AddVolumeWithID(node1, node2, node3, node4, ID);
301 }
302         
303 ///////////////////////////////////////////////////////////////////////////////
304 ///Create a new tetrahedron and add it to the mesh. 
305 ///@param ID The ID of the new volume
306 ///@return The created tetrahedron 
307 ///////////////////////////////////////////////////////////////////////////////
308
309 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
310                 const SMDS_MeshNode * n1,
311                 const SMDS_MeshNode * n2,
312                 const SMDS_MeshNode * n3,
313                 const SMDS_MeshNode * n4, int ID)
314 {
315         SMDS_MeshNode *node1, *node2, *node3, *node4;
316         node1=const_cast<SMDS_MeshNode*>(n1),
317         node2=const_cast<SMDS_MeshNode*>(n2),
318         node3=const_cast<SMDS_MeshNode*>(n3);
319         node4=const_cast<SMDS_MeshNode*>(n4);
320         SMDS_MeshVolume* volume;
321         if(hasConstructionFaces())
322         {
323                 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
324                 SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
325                 SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
326                 SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
327                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
328                 myVolumes.insert(volume);
329         }
330         else if(hasConstructionEdges())
331         {
332                 MESSAGE("Error : Not implemented");
333                 return NULL;
334         }
335         else
336         {
337                 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4);
338                 myVolumes.insert(volume);
339         }
340
341         if(myElementIDFactory->BindID(ID, volume))
342         {
343                 node1->AddInverseElement(volume);
344                 node2->AddInverseElement(volume);
345         node3->AddInverseElement(volume);
346                 node4->AddInverseElement(volume);
347                 return volume;
348         }       
349         else
350         {
351                 RemoveVolume(volume);
352                 return NULL;
353         }
354 }
355
356 ///////////////////////////////////////////////////////////////////////////////
357 ///Create a new pyramid and add it to the mesh. 
358 ///Nodes 1,2,3 and 4 define the base of the pyramid
359 ///@return The created pyramid 
360 ///////////////////////////////////////////////////////////////////////////////
361
362 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
363         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
364         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5)
365 {
366         int ID = myElementIDFactory->GetFreeID();
367         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID);
368         if(v==NULL) myElementIDFactory->ReleaseID(ID);
369         return v;
370 }
371
372 ///////////////////////////////////////////////////////////////////////////////
373 ///Create a new pyramid and add it to the mesh. 
374 ///Nodes 1,2,3 and 4 define the base of the pyramid
375 ///@param ID The ID of the new volume
376 ///@return The created pyramid or NULL if a pyramid with this ID already exists
377 ///or if input nodes are not found.
378 ///////////////////////////////////////////////////////////////////////////////
379
380 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
381         int idnode3, int idnode4, int idnode5, int ID)
382 {
383         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
384         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
385         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
386         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
387         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
388         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
389         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
390                 (node5=NULL))
391                 return NULL;
392         return AddVolumeWithID(node1, node2, node3, node4, node5, ID);
393 }
394         
395 ///////////////////////////////////////////////////////////////////////////////
396 ///Create a new pyramid and add it to the mesh.
397 ///Nodes 1,2,3 and 4 define the base of the pyramid
398 ///@param ID The ID of the new volume
399 ///@return The created pyramid
400 ///////////////////////////////////////////////////////////////////////////////
401
402 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
403                 const SMDS_MeshNode * n1,
404                 const SMDS_MeshNode * n2,
405                 const SMDS_MeshNode * n3,
406                 const SMDS_MeshNode * n4,
407                 const SMDS_MeshNode * n5, int ID)
408 {
409         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
410         node1=const_cast<SMDS_MeshNode*>(n1),
411         node2=const_cast<SMDS_MeshNode*>(n2),
412         node3=const_cast<SMDS_MeshNode*>(n3);
413         node4=const_cast<SMDS_MeshNode*>(n4);
414         node5=const_cast<SMDS_MeshNode*>(n5);
415         SMDS_MeshVolume* volume;
416         if(hasConstructionFaces())
417         {
418                 SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
419                 SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
420                 SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
421                 SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
422                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
423                 myVolumes.insert(volume);
424         }
425         else if(hasConstructionEdges())
426         {
427                 MESSAGE("Error : Not implemented");
428                 return NULL;
429         }
430         else
431         {
432                 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5);
433                 myVolumes.insert(volume);
434         }
435
436         if(myElementIDFactory->BindID(ID, volume))
437         {
438                 node1->AddInverseElement(volume);
439                 node2->AddInverseElement(volume);
440         node3->AddInverseElement(volume);
441                 node4->AddInverseElement(volume);
442                 node5->AddInverseElement(volume);
443                 return volume;
444         }       
445         else
446         {
447                 RemoveVolume(volume);
448                 return NULL;
449         }
450 }
451
452 ///////////////////////////////////////////////////////////////////////////////
453 ///Create a new prism and add it to the mesh. 
454 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
455 ///@return The created prism 
456 ///////////////////////////////////////////////////////////////////////////////
457
458 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
459         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
460         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
461         const SMDS_MeshNode * n6)
462 {
463         int ID = myElementIDFactory->GetFreeID();
464         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
465         if(v==NULL) myElementIDFactory->ReleaseID(ID);
466         return v;
467 }
468
469 ///////////////////////////////////////////////////////////////////////////////
470 ///Create a new prism and add it to the mesh. 
471 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
472 ///@param ID The ID of the new volume
473 ///@return The created prism or NULL if a prism with this ID already exists
474 ///or if input nodes are not found.
475 ///////////////////////////////////////////////////////////////////////////////
476
477 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
478         int idnode3, int idnode4, int idnode5, int idnode6, int ID)
479 {
480         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
481         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
482         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
483         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
484         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
485         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
486         node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
487         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
488                 (node5==NULL)||(node6=NULL))
489                 return NULL;
490         return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
491 }
492         
493 ///////////////////////////////////////////////////////////////////////////////
494 ///Create a new prism and add it to the mesh.
495 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
496 ///@param ID The ID of the new volume
497 ///@return The created prism
498 ///////////////////////////////////////////////////////////////////////////////
499
500 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
501                 const SMDS_MeshNode * n1,
502                 const SMDS_MeshNode * n2,
503                 const SMDS_MeshNode * n3,
504                 const SMDS_MeshNode * n4,
505                 const SMDS_MeshNode * n5,
506                 const SMDS_MeshNode * n6, int ID)
507 {
508         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
509         node1=const_cast<SMDS_MeshNode*>(n1),
510         node2=const_cast<SMDS_MeshNode*>(n2),
511         node3=const_cast<SMDS_MeshNode*>(n3);
512         node4=const_cast<SMDS_MeshNode*>(n4);
513         node5=const_cast<SMDS_MeshNode*>(n5);
514         node6=const_cast<SMDS_MeshNode*>(n6);
515         SMDS_MeshVolume* volume;
516         if(hasConstructionFaces())
517         {
518                 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
519                 SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
520                 SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
521                 SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
522                 SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
523                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
524                 myVolumes.insert(volume);
525         }
526         else if(hasConstructionEdges())
527         {
528                 MESSAGE("Error : Not implemented");
529                 return NULL;
530         }
531         else
532         {
533                 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6);
534                 myVolumes.insert(volume);
535         }
536
537         if(myElementIDFactory->BindID(ID, volume))
538         {
539                 node1->AddInverseElement(volume);
540                 node2->AddInverseElement(volume);
541         node3->AddInverseElement(volume);
542                 node4->AddInverseElement(volume);
543                 node5->AddInverseElement(volume);
544                 node6->AddInverseElement(volume);
545                 return volume;
546         }       
547         else
548         {
549                 RemoveVolume(volume);
550                 return NULL;
551         }
552 }
553
554 ///////////////////////////////////////////////////////////////////////////////
555 ///Create a new hexahedron and add it to the mesh. 
556 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
557 ///@return The created hexahedron 
558 ///////////////////////////////////////////////////////////////////////////////
559
560 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
561         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
562         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
563         const SMDS_MeshNode * n6, const SMDS_MeshNode * n7,
564         const SMDS_MeshNode * n8)
565 {
566         int ID = myElementIDFactory->GetFreeID();
567         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
568         if(v==NULL) myElementIDFactory->ReleaseID(ID);
569         return v;
570 }
571
572 ///////////////////////////////////////////////////////////////////////////////
573 ///Create a new hexahedron and add it to the mesh. 
574 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
575 ///@param ID The ID of the new volume
576 ///@return The created hexahedron or NULL if an hexahedron with this ID already
577 ///exists or if input nodes are not found.
578 ///////////////////////////////////////////////////////////////////////////////
579
580 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
581         int idnode3, int idnode4, int idnode5, int idnode6, int idnode7,
582         int idnode8, int ID)
583 {
584         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
585         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
586         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
587         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
588         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
589         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
590         node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
591         node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
592         node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
593         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
594                 (node5==NULL)||(node6=NULL)||(node7==NULL)||(node8=NULL))
595                 return NULL;
596         return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7,
597                 node8, ID);
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 prism or NULL if an hexadron with this ID already exists
605 ///or if input nodes are not found.
606 ///////////////////////////////////////////////////////////////////////////////
607
608 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
609                 const SMDS_MeshNode * n1,
610                 const SMDS_MeshNode * n2,
611                 const SMDS_MeshNode * n3,
612                 const SMDS_MeshNode * n4,
613                 const SMDS_MeshNode * n5,
614                 const SMDS_MeshNode * n6,
615                 const SMDS_MeshNode * n7,
616                 const SMDS_MeshNode * n8, int ID)
617 {
618         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
619         node1=const_cast<SMDS_MeshNode*>(n1),
620         node2=const_cast<SMDS_MeshNode*>(n2),
621         node3=const_cast<SMDS_MeshNode*>(n3);
622         node4=const_cast<SMDS_MeshNode*>(n4);
623         node5=const_cast<SMDS_MeshNode*>(n5);
624         node6=const_cast<SMDS_MeshNode*>(n6);
625         node7=const_cast<SMDS_MeshNode*>(n7);
626         node8=const_cast<SMDS_MeshNode*>(n8);
627         SMDS_MeshVolume* volume;
628         if(hasConstructionFaces())
629         {
630                 SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
631                 SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
632                 SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
633                 SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
634                 SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
635                 SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
636                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
637                 myVolumes.insert(volume);
638         }
639         else if(hasConstructionEdges())
640         {
641                 MESSAGE("Error : Not implemented");
642                 return NULL;
643         }
644         else
645         {
646                 volume=new SMDS_HexahedronOfNodes(node1,node2,node3,node4,node5,node6,
647                         node7,node8);
648                 myVolumes.insert(volume);
649         }
650
651         if(myElementIDFactory->BindID(ID, volume))
652         {
653                 node1->AddInverseElement(volume);
654                 node2->AddInverseElement(volume);
655         node3->AddInverseElement(volume);
656                 node4->AddInverseElement(volume);
657                 node5->AddInverseElement(volume);
658                 node6->AddInverseElement(volume);
659                 node7->AddInverseElement(volume);
660                 node8->AddInverseElement(volume);
661                 return volume;
662         }       
663         else
664         {
665                 RemoveVolume(volume);
666                 return NULL;
667         }
668 }
669
670 ///////////////////////////////////////////////////////////////////////////////
671 /// Return the node whose ID is 'ID'.
672 ///////////////////////////////////////////////////////////////////////////////
673 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
674 {
675         return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
676 }
677
678 ///////////////////////////////////////////////////////////////////////////////
679 ///Create a triangle and add it to the current mesh. This methode do not bind a
680 ///ID to the create triangle.
681 ///////////////////////////////////////////////////////////////////////////////
682 SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
683         SMDS_MeshNode * node2, SMDS_MeshNode * node3)
684 {
685         if(hasConstructionEdges())
686         {
687                 SMDS_MeshEdge *edge1, *edge2, *edge3;
688                 edge1=FindEdgeOrCreate(node1,node2);
689                 edge2=FindEdgeOrCreate(node2,node3);
690                 edge3=FindEdgeOrCreate(node3,node1);
691
692                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
693                 myFaces.insert(face);
694                 return face;
695         }
696         else
697         {
698                 SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3);
699                 myFaces.insert(face);
700                 return face;
701         }
702 }
703
704 ///////////////////////////////////////////////////////////////////////////////
705 ///Create a quadrangle and add it to the current mesh. This methode do not bind
706 ///a ID to the create triangle.
707 ///////////////////////////////////////////////////////////////////////////////
708 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
709         SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
710 {
711         if(hasConstructionEdges())
712         {
713                 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
714                 edge1=FindEdgeOrCreate(node1,node2);
715                 edge2=FindEdgeOrCreate(node2,node3);
716                 edge3=FindEdgeOrCreate(node3,node4);
717                 edge4=FindEdgeOrCreate(node4,node1);
718
719                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
720                 myFaces.insert(face);
721                 return face;
722         }
723         else
724         {
725                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
726                 myFaces.insert(face);
727                 return face;
728         }
729 }
730
731 ///////////////////////////////////////////////////////////////////////////////
732 /// Remove a node and all the elements which own this node
733 ///////////////////////////////////////////////////////////////////////////////
734
735 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
736 {
737         RemoveElement(node, true);
738 }
739
740 ///////////////////////////////////////////////////////////////////////////////
741 /// Remove an edge and all the elements which own this edge
742 ///////////////////////////////////////////////////////////////////////////////
743
744 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
745 {
746         RemoveElement(edge,true);
747 }
748
749 ///////////////////////////////////////////////////////////////////////////////
750 /// Remove an face and all the elements which own this face
751 ///////////////////////////////////////////////////////////////////////////////
752
753 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
754 {
755         RemoveElement(face, true);
756 }
757
758 ///////////////////////////////////////////////////////////////////////////////
759 /// Remove a volume
760 ///////////////////////////////////////////////////////////////////////////////
761
762 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
763 {
764         RemoveElement(volume, true);
765 }
766
767 //=======================================================================
768 //function : RemoveFromParent
769 //purpose  :
770 //=======================================================================
771
772 bool SMDS_Mesh::RemoveFromParent()
773 {
774         if (myParent==NULL) return false;
775         else return (myParent->RemoveSubMesh(this));
776 }
777
778 //=======================================================================
779 //function : RemoveSubMesh
780 //purpose  :
781 //=======================================================================
782
783 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
784 {
785         bool found = false;
786
787         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
788         for (; itmsh!=myChildren.end() && !found; itmsh++)
789         {
790                 SMDS_Mesh * submesh = *itmsh;
791                 if (submesh == aMesh)
792                 {
793                         found = true;
794                         myChildren.erase(itmsh);
795                 }
796         }
797
798         return found;
799 }
800
801
802 //=======================================================================
803 //function : FindEdge
804 //purpose  :
805 //=======================================================================
806
807 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
808 {
809         const SMDS_MeshNode * node1=FindNode(idnode1);
810         const SMDS_MeshNode * node2=FindNode(idnode2);
811         if((node1==NULL)||(node2==NULL)) return NULL;
812         return FindEdge(node1,node2);
813 }
814
815 ///////////////////////////////////////////////////////////////////////////////
816 ///
817 ///////////////////////////////////////////////////////////////////////////////
818 //#include "Profiler.h"
819 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
820         const SMDS_MeshNode * node2) const
821 {
822         const SMDS_MeshEdge * toReturn=NULL;
823         //PROFILER_Init();
824         //PROFILER_Set();
825         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->edgesIterator();
826         //PROFILER_Get(0);
827         //PROFILER_Set();
828         while(it1->more())
829         {
830                 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
831                         (it1->next());
832                 SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
833                 while(it2->more())
834                 {
835                         if(it2->next()->GetID()==node2->GetID())
836                         {
837                                 toReturn=e;
838                                 break;
839                         }
840                 }
841                 delete it2;
842         }
843         //PROFILER_Get(1);
844         delete it1;
845         return toReturn;
846 }
847
848
849 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
850         const SMDS_MeshNode * node2) 
851 {
852         SMDS_MeshEdge * toReturn=NULL;
853         toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
854         if(toReturn==NULL)      
855         {
856                 toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
857                         const_cast<SMDS_MeshNode*>(node2));
858                 myEdges.insert(toReturn);
859         } 
860         return toReturn;
861 }
862
863 //=======================================================================
864 //function : FindFace
865 //purpose  :
866 //=======================================================================
867
868 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
869         int idnode3) const
870 {
871         const SMDS_MeshNode * node1=FindNode(idnode1);
872         const SMDS_MeshNode * node2=FindNode(idnode2);
873         const SMDS_MeshNode * node3=FindNode(idnode3);
874         const SMDS_MeshFace * face;
875         const SMDS_MeshElement * node;
876         bool node2found, node3found;
877         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
878
879         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->facesIterator();
880         while(it1->more())
881         {
882                 face=static_cast<const SMDS_MeshFace*>(it1->next());
883                 if(face->NbNodes()!=3) continue;
884                 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
885                 node2found=false;
886                 node3found=false;
887                 while(it2->more())
888                 {
889                         node=it2->next();
890                         if(node->GetID()==idnode2) node2found=true;
891                         if(node->GetID()==idnode3) node3found=true;
892                 }
893                 delete it2;
894                 if(node2found&&node3found)
895                 {
896                         delete it1;
897                         return face;
898                 }
899         }
900         delete it1;
901         return NULL;
902 }
903
904 //=======================================================================
905 //function : FindFace
906 //purpose  :
907 //=======================================================================
908
909 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
910         int idnode4) const
911 {
912         const SMDS_MeshNode * node1=FindNode(idnode1);
913         const SMDS_MeshNode * node2=FindNode(idnode2);
914         const SMDS_MeshNode * node3=FindNode(idnode3);
915         const SMDS_MeshNode * node4=FindNode(idnode4);
916         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
917         return FindFace(node1, node2, node3, node4);
918 }
919
920 const SMDS_MeshFace* SMDS_Mesh::FindFace(
921                 const SMDS_MeshNode *node1,
922                 const SMDS_MeshNode *node2,
923                 const SMDS_MeshNode *node3,
924                 const SMDS_MeshNode *node4) const
925 {
926         const SMDS_MeshFace * face;
927         const SMDS_MeshElement * node;
928         bool node2found, node3found, node4found;
929         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->facesIterator();
930         while(it1->more())
931         {
932                 face=static_cast<const SMDS_MeshFace *>(it1->next());
933                 if(face->NbNodes()!=4) continue;
934                 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
935                 node2found=false;
936                 node3found=false;
937                 node4found=false;
938                 while(it2->more())
939                 {
940                         node=it2->next();
941                         if(node->GetID()==node2->GetID()) node2found=true;
942                         if(node->GetID()==node3->GetID()) node3found=true;
943                         if(node->GetID()==node4->GetID()) node4found=true;
944                 }
945                 delete it2;
946                 if(node2found&&node3found&&node4found)
947                 {
948                         delete it1;
949                         return face;
950                 }
951         }
952         delete it1;
953         return NULL;
954 }
955
956 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
957                 const SMDS_MeshNode *node1,
958                 const SMDS_MeshNode *node2,
959                 const SMDS_MeshNode *node3,
960                 const SMDS_MeshNode *node4)
961 {
962         SMDS_MeshFace * toReturn=NULL;
963         toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
964         if(toReturn==NULL)      
965         {
966                 toReturn=createQuadrangle(
967                         const_cast<SMDS_MeshNode *>(node1),
968                         const_cast<SMDS_MeshNode *>(node2),
969                         const_cast<SMDS_MeshNode *>(node3),
970                         const_cast<SMDS_MeshNode *>(node4)
971                 );
972         } 
973         return toReturn;
974 }
975
976 //=======================================================================
977 //function : FindElement
978 //purpose  :
979 //=======================================================================
980
981 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
982 {
983         return myElementIDFactory->MeshElement(IDelem);
984 }
985
986 //=======================================================================
987 //function : DumpNodes
988 //purpose  : 
989 //=======================================================================
990
991 void SMDS_Mesh::DumpNodes() const
992 {
993         MESSAGE("dump nodes of mesh : ");
994         SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
995         while(itnode->more()) MESSAGE(itnode->next());
996         delete itnode;
997 }
998
999 //=======================================================================
1000 //function : DumpEdges
1001 //purpose  : 
1002 //=======================================================================
1003
1004 void SMDS_Mesh::DumpEdges() const
1005 {
1006         MESSAGE("dump edges of mesh : ");
1007         SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
1008         while(itedge->more()) MESSAGE(itedge->next());
1009         delete itedge;
1010 }
1011
1012 //=======================================================================
1013 //function : DumpFaces
1014 //purpose  : 
1015 //=======================================================================
1016
1017 void SMDS_Mesh::DumpFaces() const
1018 {
1019         MESSAGE("dump faces of mesh : ");
1020         SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
1021         while(itface->more()) MESSAGE(itface->next());
1022         delete itface;
1023 }
1024
1025 //=======================================================================
1026 //function : DumpVolumes
1027 //purpose  : 
1028 //=======================================================================
1029
1030 void SMDS_Mesh::DumpVolumes() const
1031 {
1032         MESSAGE("dump volumes of mesh : ");
1033         SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
1034         while(itvol->more()) MESSAGE(itvol->next());
1035         delete itvol;
1036 }
1037
1038 //=======================================================================
1039 //function : DebugStats
1040 //purpose  : 
1041 //=======================================================================
1042
1043 void SMDS_Mesh::DebugStats() const
1044 {
1045         MESSAGE("Debug stats of mesh : ");
1046
1047         MESSAGE("===== NODES ====="<<NbNodes());
1048         MESSAGE("===== EDGES ====="<<NbEdges());
1049         MESSAGE("===== FACES ====="<<NbFaces());
1050         MESSAGE("===== VOLUMES ====="<<NbVolumes());
1051
1052         MESSAGE("End Debug stats of mesh ");
1053
1054         //#ifdef DEB
1055         
1056         SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1057         int sizeofnodes = 0;
1058         int sizeoffaces = 0;
1059
1060         while(itnode->more())
1061         {
1062                 const SMDS_MeshNode *node = itnode->next();
1063
1064                 sizeofnodes += sizeof(*node);
1065                 
1066                 SMDS_Iterator<const SMDS_MeshElement *> * it=
1067                         node->GetInverseElementIterator();
1068                 while(it->more())
1069                 {
1070                         const SMDS_MeshElement *me = it->next();
1071                         sizeofnodes += sizeof(me);
1072                 }
1073                 delete it;
1074
1075         }
1076         delete itnode;
1077         SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
1078         
1079         while(itface->more())
1080         {
1081                 const SMDS_MeshElement *face = itface->next();          
1082                 sizeoffaces += sizeof(*face);
1083
1084         }
1085         MESSAGE("total size of node elements = " << sizeofnodes);;
1086         MESSAGE("total size of face elements = " << sizeoffaces);;
1087
1088         //#endif
1089
1090 }
1091
1092 ///////////////////////////////////////////////////////////////////////////////
1093 /// Return the number of nodes
1094 ///////////////////////////////////////////////////////////////////////////////
1095 int SMDS_Mesh::NbNodes() const
1096 {
1097         return myNodes.size();
1098 }
1099
1100 ///////////////////////////////////////////////////////////////////////////////
1101 /// Return the number of edges (including construction edges)
1102 ///////////////////////////////////////////////////////////////////////////////
1103 int SMDS_Mesh::NbEdges() const
1104 {
1105         return myEdges.size();
1106 }
1107
1108 ///////////////////////////////////////////////////////////////////////////////
1109 /// Return the number of faces (including construction faces)
1110 ///////////////////////////////////////////////////////////////////////////////
1111 int SMDS_Mesh::NbFaces() const
1112 {
1113         return myFaces.size();
1114 }
1115
1116 ///////////////////////////////////////////////////////////////////////////////
1117 /// Return the number of volumes
1118 ///////////////////////////////////////////////////////////////////////////////
1119 int SMDS_Mesh::NbVolumes() const
1120 {
1121         return myVolumes.size();
1122 }
1123
1124 ///////////////////////////////////////////////////////////////////////////////
1125 /// Return the number of child mesh of this mesh.
1126 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1127 /// (2003-09-08) of SMESH
1128 ///////////////////////////////////////////////////////////////////////////////
1129 int SMDS_Mesh::NbSubMesh() const
1130 {
1131         return myChildren.size();
1132 }
1133
1134 ///////////////////////////////////////////////////////////////////////////////
1135 /// Destroy the mesh and all its elements
1136 /// All pointer on elements owned by this mesh become illegals.
1137 ///////////////////////////////////////////////////////////////////////////////
1138 SMDS_Mesh::~SMDS_Mesh()
1139 {
1140         if(myParent==NULL)
1141         {
1142                 delete myNodeIDFactory;
1143                 delete myElementIDFactory;
1144         }
1145
1146         list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1147         while(itc!=myChildren.end())
1148         {
1149                 delete *itc;
1150                 itc++;
1151         }
1152         
1153         SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1154         while(itn->more())
1155         {
1156                 delete itn->next();
1157         }
1158         delete itn;
1159
1160         set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1161         while(ite!=myEdges.end())
1162         {
1163                 delete *ite;
1164                 ite++;
1165         }
1166
1167         set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1168         while(itf!=myFaces.end())
1169         {
1170                 delete *itf;
1171                 itf++;
1172         }
1173
1174         set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1175         while(itv!=myVolumes.end())
1176         {
1177                 delete *itv;
1178                 itv++;
1179         }
1180
1181 }
1182
1183 ///////////////////////////////////////////////////////////////////////////////
1184 /// Return true if this mesh create faces with edges.
1185 /// A false returned value mean that faces are created with nodes. A concequence
1186 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1187 ///////////////////////////////////////////////////////////////////////////////
1188 bool SMDS_Mesh::hasConstructionEdges()
1189 {
1190         return myHasConstructionEdges;
1191 }
1192
1193 ///////////////////////////////////////////////////////////////////////////////
1194 /// Return true if this mesh create volumes with faces
1195 /// A false returned value mean that volumes are created with nodes or edges.
1196 /// (see hasConstructionEdges)
1197 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1198 /// unavailable.
1199 ///////////////////////////////////////////////////////////////////////////////
1200 bool SMDS_Mesh::hasConstructionFaces()
1201 {
1202         return myHasConstructionFaces;
1203 }
1204
1205 ///////////////////////////////////////////////////////////////////////////////
1206 /// Return true if nodes are linked to the finit elements, they are belonging to.
1207 /// Currently, It always return true.
1208 ///////////////////////////////////////////////////////////////////////////////
1209 bool SMDS_Mesh::hasInverseElements()
1210 {
1211         return myHasInverseElements;
1212 }
1213
1214 ///////////////////////////////////////////////////////////////////////////////
1215 /// Make this mesh creating construction edges (see hasConstructionEdges)
1216 /// @param b true to have construction edges, else false.
1217 ///////////////////////////////////////////////////////////////////////////////
1218 void SMDS_Mesh::setConstructionEdges(bool b)
1219 {
1220         myHasConstructionEdges=b;
1221 }
1222
1223 ///////////////////////////////////////////////////////////////////////////////
1224 /// Make this mesh creating construction faces (see hasConstructionFaces)
1225 /// @param b true to have construction faces, else false.
1226 ///////////////////////////////////////////////////////////////////////////////
1227 void SMDS_Mesh::setConstructionFaces(bool b)
1228 {
1229          myHasConstructionFaces=b;
1230 }
1231
1232 ///////////////////////////////////////////////////////////////////////////////
1233 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1234 /// @param b true to link nodes to elements, else false.
1235 ///////////////////////////////////////////////////////////////////////////////
1236 void SMDS_Mesh::setInverseElements(bool b)
1237 {
1238         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1239         myHasInverseElements=b;
1240 }
1241
1242 ///////////////////////////////////////////////////////////////////////////////
1243 /// Return an iterator on nodes of the current mesh. Once used this iterator
1244 /// must be free by the caller
1245 ///////////////////////////////////////////////////////////////////////////////
1246 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1247 {
1248         class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1249         {
1250                 const SetOfNodes& mySet;
1251                 SetOfNodes::iterator myIterator;
1252           public:
1253                 MyIterator(const SetOfNodes& s):mySet(s)
1254                 {
1255                         myIterator=mySet.begin();
1256                 }
1257
1258                 bool more()
1259                 {
1260                         return myIterator!=mySet.end();
1261                 }
1262
1263                 const SMDS_MeshNode* next()
1264                 {
1265                         const SMDS_MeshNode* current=*myIterator;
1266                         myIterator++;
1267                         return current; 
1268                 }       
1269         };
1270         return new MyIterator(myNodes);
1271 }
1272
1273 ///////////////////////////////////////////////////////////////////////////////
1274 ///Return an iterator on volumes of the current mesh. Once used this iterator
1275 ///must be free by the caller
1276 ///////////////////////////////////////////////////////////////////////////////
1277 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1278 {
1279         class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1280         {
1281                 const SetOfEdges& mySet;
1282                 const SMDS_MeshEdge * myEdge;
1283                 SetOfEdges::iterator myIterator;
1284           public:
1285                 MyIterator(const SetOfEdges& s):mySet(s)
1286                 {
1287                         myIterator=mySet.begin();
1288                 }
1289
1290                 bool more()
1291                 {
1292                         while((myIterator!=mySet.end()))
1293                         {
1294                                 if((*myIterator)->GetID()!=-1)
1295                                         return true;
1296                                 myIterator++;
1297                         }
1298                         return false;
1299                 }
1300
1301                 const SMDS_MeshEdge* next()
1302                 {
1303                         const SMDS_MeshEdge* current=*myIterator;
1304                         myIterator++;
1305                         return current; 
1306                 }       
1307         };
1308         return new MyIterator(myEdges);
1309 }
1310
1311 ///////////////////////////////////////////////////////////////////////////////
1312 ///Return an iterator on faces of the current mesh. Once used this iterator
1313 ///must be free by the caller
1314 ///////////////////////////////////////////////////////////////////////////////
1315 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1316 {
1317         class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1318         {
1319                 const SetOfFaces& mySet;
1320                 set<SMDS_MeshFace*>::iterator myIterator;
1321           public:
1322                 MyIterator(const SetOfFaces& s):mySet(s)
1323                 {
1324                         myIterator=mySet.begin();
1325                 }
1326
1327                 bool more()
1328                 {
1329                         while((myIterator!=mySet.end()))
1330                         {
1331                                 if((*myIterator)->GetID()!=-1)
1332                                         return true;
1333                                 myIterator++;
1334                         }
1335                         return false;
1336                 }
1337
1338                 const SMDS_MeshFace* next()
1339                 {
1340                         const SMDS_MeshFace* current=*myIterator;
1341                         myIterator++;
1342                         return current; 
1343                 }       
1344         };
1345         return new MyIterator(myFaces);
1346 }
1347
1348 ///////////////////////////////////////////////////////////////////////////////
1349 ///Return an iterator on volumes of the current mesh. Once used this iterator
1350 ///must be free by the caller
1351 ///////////////////////////////////////////////////////////////////////////////
1352 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1353 {
1354         class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1355         {
1356                 const SetOfVolumes& mySet;
1357                 SetOfVolumes::iterator myIterator;
1358           public:
1359                 MyIterator(const SetOfVolumes& s):mySet(s)
1360                 {
1361                         myIterator=mySet.begin();
1362                 }
1363
1364                 bool more()
1365                 {
1366                         return myIterator!=mySet.end();
1367                 }
1368
1369                 const SMDS_MeshVolume* next()
1370                 {
1371                         const SMDS_MeshVolume* current=*myIterator;
1372                         myIterator++;
1373                         return current; 
1374                 }       
1375         };
1376         return new MyIterator(myVolumes);
1377 }
1378
1379 ///////////////////////////////////////////////////////////////////////////////
1380 /// Do intersection of sets (more than 2)
1381 ///////////////////////////////////////////////////////////////////////////////
1382 set<const SMDS_MeshElement*> * intersectionOfSets(
1383         set<const SMDS_MeshElement*> vs[], int numberOfSets)
1384 {
1385         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1386         set<const SMDS_MeshElement*>* rsetB;
1387
1388         for(int i=0; i<numberOfSets-1; i++)
1389         {
1390                 rsetB=new set<const SMDS_MeshElement*>();
1391                 set_intersection(
1392                         rsetA->begin(), rsetA->end(),
1393                         vs[i+1].begin(), vs[i+1].end(),
1394                         inserter(*rsetB, rsetB->begin()));
1395                 delete rsetA;
1396                 rsetA=rsetB;
1397         }
1398         return rsetA;
1399 }
1400
1401 ///////////////////////////////////////////////////////////////////////////////
1402 /// Return the list of finit elements owning the given element
1403 ///////////////////////////////////////////////////////////////////////////////
1404 set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1405 {
1406         int numberOfSets=element->NbNodes();
1407         set<const SMDS_MeshElement*> initSet[numberOfSets];
1408
1409         SMDS_Iterator<const SMDS_MeshElement*> * itNodes=element->nodesIterator();
1410
1411         int i=0;
1412         while(itNodes->more())
1413         {
1414                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1415                 SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
1416
1417                 //initSet[i]=set<const SMDS_MeshElement*>();
1418                 while(itFe->more()) initSet[i].insert(itFe->next());
1419
1420                 i++;
1421                 delete itFe;
1422         }
1423         delete itNodes;
1424         
1425         return intersectionOfSets(initSet, numberOfSets);
1426 }
1427
1428 ///////////////////////////////////////////////////////////////////////////////
1429 /// Return the list of nodes used only by the given elements
1430 ///////////////////////////////////////////////////////////////////////////////
1431 set<const SMDS_MeshElement*> * getExclusiveNodes(
1432         set<const SMDS_MeshElement*>& elements)
1433 {
1434         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1435         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1436
1437         while(itElements!=elements.end())
1438         {
1439                 SMDS_Iterator<const SMDS_MeshElement*> * itNodes=
1440                         (*itElements)->nodesIterator();
1441                 itElements++;
1442         
1443                 while(itNodes->more())
1444                 {
1445                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1446                         SMDS_Iterator<const SMDS_MeshElement*> * itFe = n->GetInverseElementIterator();
1447                         set<const SMDS_MeshElement*> s;
1448                         while(itFe->more()) s.insert(itFe->next());
1449                         delete itFe;
1450                         if(s==elements) toReturn->insert(n);
1451                 }
1452                 delete itNodes;
1453         }
1454         return toReturn;        
1455 }
1456
1457 ///////////////////////////////////////////////////////////////////////////////
1458 ///Find the children of an element that are made of given nodes 
1459 ///@param setOfChildren The set in which matching children will be inserted
1460 ///@param element The element were to search matching children
1461 ///@param nodes The nodes that the children must have to be selected
1462 ///////////////////////////////////////////////////////////////////////////////
1463 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren, 
1464         const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1465 {
1466         
1467         switch(element->GetType())
1468         {
1469         case SMDSAbs_Node:
1470                 MESSAGE("Internal Error: This should not append");
1471                 break;
1472         case SMDSAbs_Edge:
1473         {
1474                 SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
1475                 while(itn->more())
1476                 {
1477                         const SMDS_MeshElement * e=itn->next();
1478                         if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
1479                 }
1480                 delete itn;
1481         } break;        
1482         case SMDSAbs_Face:
1483         {
1484                 SMDS_Iterator<const SMDS_MeshElement*> * itn=element->nodesIterator();
1485                 while(itn->more())
1486                 {
1487                         const SMDS_MeshElement * e=itn->next();
1488                         if(nodes.find(e)!=nodes.end()) setOfChildren.insert(element);
1489                 }
1490                 delete itn;
1491                 if(hasConstructionEdges())
1492                 {
1493                         SMDS_Iterator<const SMDS_MeshElement*>* ite=element->edgesIterator();
1494                         while(ite->more())
1495                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1496                         delete ite;
1497                 }
1498         } break;        
1499         case SMDSAbs_Volume:
1500         {
1501                 if(hasConstructionFaces())
1502                 {
1503                         SMDS_Iterator<const SMDS_MeshElement*> * ite=element->facesIterator();
1504                         while(ite->more())
1505                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1506                         delete ite;
1507                 }
1508                 else if(hasConstructionEdges())
1509                 {
1510                         SMDS_Iterator<const SMDS_MeshElement*> * ite=element->edgesIterator();
1511                         while(ite->more())
1512                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1513                         delete ite;
1514                 }
1515         }
1516         }
1517 }
1518
1519 ///////////////////////////////////////////////////////////////////////////////
1520 ///@param elem The element to delete
1521 ///@param removenodes if true remaining nodes will be removed
1522 ///////////////////////////////////////////////////////////////////////////////
1523 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1524         const bool removenodes)
1525 {
1526         set<const SMDS_MeshElement*> * s1=getFinitElements(elem);
1527         
1528         set<const SMDS_MeshElement*> * s2=getExclusiveNodes(*s1);
1529         set<const SMDS_MeshElement*> s3;
1530         set<const SMDS_MeshElement*>::iterator it=s1->begin();
1531         while(it!=s1->end())
1532         {
1533                 addChildrenWithNodes(s3, *it ,*s2);
1534                 s3.insert(*it);
1535                 it++;
1536         }
1537         if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);      
1538         it=s3.begin();
1539         while(it!=s3.end())
1540         {
1541                 switch((*it)->GetType())
1542                 {
1543                 case SMDSAbs_Node:
1544                         MESSAGE("Internal Error: This should not happen");
1545                         break;
1546                 case SMDSAbs_Edge:
1547                         myEdges.erase(static_cast<SMDS_MeshEdge*>(
1548                                 const_cast<SMDS_MeshElement*>(*it)));   
1549                         break;
1550                 case SMDSAbs_Face:
1551                         myFaces.erase(static_cast<SMDS_MeshFace*>(
1552                                 const_cast<SMDS_MeshElement*>(*it)));
1553                         break;
1554                 case SMDSAbs_Volume:
1555                         myVolumes.erase(static_cast<SMDS_MeshVolume*>(
1556                                 const_cast<SMDS_MeshElement*>(*it)));   
1557                         break;
1558                 }
1559                 delete (*it);
1560                 it++;
1561         }       
1562         if(removenodes)
1563         {
1564                 it=s2->begin();
1565                 while(it!=s2->end())
1566                 {
1567                         myNodes.erase(static_cast<SMDS_MeshNode*>(
1568                                 const_cast<SMDS_MeshElement*>(*it)));
1569                         delete *it;
1570                         it++;
1571                 }
1572         }
1573                 
1574         delete s2;
1575         delete s1;
1576 }