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