Salome HOME
When the main window was maximized some dialogs were cropped at the bottom of the...
[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         SMDS_Iterator<const SMDS_MeshElement *> * it=
735                 node->GetInverseElementIterator();
736         while(it->more()) RemoveElement(it->next(),true);
737         myNodeIDFactory->ReleaseID(node->GetID());
738         myNodes.erase(const_cast<SMDS_MeshNode*>(node));
739 }
740
741 ///////////////////////////////////////////////////////////////////////////////
742 /// Remove an edge and all the elements which own this edge
743 ///////////////////////////////////////////////////////////////////////////////
744
745 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
746 {
747         /** @todo to be fix */
748         myEdges.erase(const_cast<SMDS_MeshEdge*>(edge));
749         //removeElementDependencies(edge);
750         delete edge;
751 }
752
753 ///////////////////////////////////////////////////////////////////////////////
754 /// Remove an face and all the elements which own this face
755 ///////////////////////////////////////////////////////////////////////////////
756
757 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
758 {
759         /** @todo to be fix */
760         myFaces.erase(const_cast<SMDS_MeshFace*>(face));
761         //removeElementDependencies(face);
762         delete face;
763 }
764
765 ///////////////////////////////////////////////////////////////////////////////
766 /// Remove a volume
767 ///////////////////////////////////////////////////////////////////////////////
768
769 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
770 {
771         /** @todo to be fix */
772         myVolumes.erase(const_cast<SMDS_MeshVolume*>(volume));
773         //removeElementDependencies(volume);
774         delete volume;
775 }
776
777 ///////////////////////////////////////////////////////////////////////////////
778 /// Remove no longer used sub element of an element. Unbind the element ID
779 ///////////////////////////////////////////////////////////////////////////////
780
781 void SMDS_Mesh::removeElementDependencies(SMDS_MeshElement * element)
782 {
783         /** @todo to be fix */
784         myElementIDFactory->ReleaseID(element->GetID());
785         SMDS_Iterator<const SMDS_MeshElement*> * it=element->nodesIterator();
786         while(it->more())
787         {
788                 SMDS_MeshNode * node=static_cast<SMDS_MeshNode*>(
789                         const_cast<SMDS_MeshElement*>(it->next()));
790                 node->RemoveInverseElement(element);
791                 if(node->emptyInverseElements()) RemoveNode(node);
792         }
793 }
794
795 //=======================================================================
796 //function : RemoveElement
797 //purpose  :
798 //=======================================================================
799
800 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
801         const bool removenodes)
802 {
803         /** @todo to be fix */
804         switch(elem->GetType())
805         {
806     case SMDSAbs_Node:
807                 RemoveNode((const SMDS_MeshNode*)elem);
808                 return;
809     case SMDSAbs_Edge:
810                 RemoveEdge((const SMDS_MeshEdge*)elem);
811                 break;
812     case SMDSAbs_Face:
813                 RemoveFace((const SMDS_MeshFace*)elem);
814                 break;
815     case SMDSAbs_Volume:
816                 RemoveVolume((const SMDS_MeshVolume*)elem);
817                 break;
818     default :
819                 MESSAGE("remove function : unknown type");
820                 return;
821         }
822 /*      
823         SMDS_Iterator<const SMDS_MeshNode*> * it=elem->nodesIterator();
824         while(it->more())
825         {
826                 const SMDS_MeshNode * node=it->next();
827                 
828         }*/
829 }
830
831 //=======================================================================
832 //function : RemoveFromParent
833 //purpose  :
834 //=======================================================================
835
836 bool SMDS_Mesh::RemoveFromParent()
837 {
838         if (myParent==NULL) return false;
839         else return (myParent->RemoveSubMesh(this));
840 }
841
842 //=======================================================================
843 //function : RemoveSubMesh
844 //purpose  :
845 //=======================================================================
846
847 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
848 {
849         bool found = false;
850
851         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
852         for (; itmsh!=myChildren.end() && !found; itmsh++)
853         {
854                 SMDS_Mesh * submesh = *itmsh;
855                 if (submesh == aMesh)
856                 {
857                         found = true;
858                         myChildren.erase(itmsh);
859                 }
860         }
861
862         return found;
863 }
864
865
866 //=======================================================================
867 //function : FindEdge
868 //purpose  :
869 //=======================================================================
870
871 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
872 {
873         const SMDS_MeshNode * node1=FindNode(idnode1);
874         const SMDS_MeshNode * node2=FindNode(idnode2);
875         if((node1==NULL)||(node2==NULL)) return NULL;
876         return FindEdge(node1,node2);
877 }
878
879 ///////////////////////////////////////////////////////////////////////////////
880 ///
881 ///////////////////////////////////////////////////////////////////////////////
882 //#include "Profiler.h"
883 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
884         const SMDS_MeshNode * node2) const
885 {
886         const SMDS_MeshEdge * toReturn=NULL;
887         //PROFILER_Init();
888         //PROFILER_Set();
889         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->edgesIterator();
890         //PROFILER_Get(0);
891         //PROFILER_Set();
892         while(it1->more())
893         {
894                 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
895                         (it1->next());
896                 SMDS_Iterator<const SMDS_MeshElement *>* it2=e->nodesIterator();
897                 while(it2->more())
898                 {
899                         if(it2->next()->GetID()==node2->GetID())
900                         {
901                                 toReturn=e;
902                                 break;
903                         }
904                 }
905                 delete it2;
906         }
907         //PROFILER_Get(1);
908         delete it1;
909         return toReturn;
910 }
911
912
913 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
914         const SMDS_MeshNode * node2) 
915 {
916         SMDS_MeshEdge * toReturn=NULL;
917         toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
918         if(toReturn==NULL)      
919         {
920                 toReturn=new SMDS_MeshEdge(const_cast<SMDS_MeshNode*>(node1),
921                         const_cast<SMDS_MeshNode*>(node2));
922                 myEdges.insert(toReturn);
923         } 
924         return toReturn;
925 }
926
927 //=======================================================================
928 //function : FindFace
929 //purpose  :
930 //=======================================================================
931
932 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
933         int idnode3) const
934 {
935         const SMDS_MeshNode * node1=FindNode(idnode1);
936         const SMDS_MeshNode * node2=FindNode(idnode2);
937         const SMDS_MeshNode * node3=FindNode(idnode3);
938         const SMDS_MeshFace * face;
939         const SMDS_MeshElement * node;
940         bool node2found, node3found;
941         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
942
943         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->facesIterator();
944         while(it1->more())
945         {
946                 face=static_cast<const SMDS_MeshFace*>(it1->next());
947                 if(face->NbNodes()!=3) continue;
948                 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
949                 node2found=false;
950                 node3found=false;
951                 while(it2->more())
952                 {
953                         node=it2->next();
954                         if(node->GetID()==idnode2) node2found=true;
955                         if(node->GetID()==idnode3) node3found=true;
956                 }
957                 delete it2;
958                 if(node2found&&node3found)
959                 {
960                         delete it1;
961                         return face;
962                 }
963         }
964         delete it1;
965         return NULL;
966 }
967
968 //=======================================================================
969 //function : FindFace
970 //purpose  :
971 //=======================================================================
972
973 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
974         int idnode4) const
975 {
976         const SMDS_MeshNode * node1=FindNode(idnode1);
977         const SMDS_MeshNode * node2=FindNode(idnode2);
978         const SMDS_MeshNode * node3=FindNode(idnode3);
979         const SMDS_MeshNode * node4=FindNode(idnode4);
980         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
981         return FindFace(node1, node2, node3, node4);
982 }
983
984 const SMDS_MeshFace* SMDS_Mesh::FindFace(
985                 const SMDS_MeshNode *node1,
986                 const SMDS_MeshNode *node2,
987                 const SMDS_MeshNode *node3,
988                 const SMDS_MeshNode *node4) const
989 {
990         const SMDS_MeshFace * face;
991         const SMDS_MeshElement * node;
992         bool node2found, node3found, node4found;
993         SMDS_Iterator<const SMDS_MeshElement *>*  it1=node1->facesIterator();
994         while(it1->more())
995         {
996                 face=static_cast<const SMDS_MeshFace *>(it1->next());
997                 if(face->NbNodes()!=4) continue;
998                 SMDS_Iterator<const SMDS_MeshElement *>* it2=face->nodesIterator();
999                 node2found=false;
1000                 node3found=false;
1001                 node4found=false;
1002                 while(it2->more())
1003                 {
1004                         node=it2->next();
1005                         if(node->GetID()==node2->GetID()) node2found=true;
1006                         if(node->GetID()==node3->GetID()) node3found=true;
1007                         if(node->GetID()==node4->GetID()) node4found=true;
1008                 }
1009                 delete it2;
1010                 if(node2found&&node3found&&node4found)
1011                 {
1012                         delete it1;
1013                         return face;
1014                 }
1015         }
1016         delete it1;
1017         return NULL;
1018 }
1019
1020 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1021                 const SMDS_MeshNode *node1,
1022                 const SMDS_MeshNode *node2,
1023                 const SMDS_MeshNode *node3,
1024                 const SMDS_MeshNode *node4)
1025 {
1026         SMDS_MeshFace * toReturn=NULL;
1027         toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1028         if(toReturn==NULL)      
1029         {
1030                 toReturn=createQuadrangle(
1031                         const_cast<SMDS_MeshNode *>(node1),
1032                         const_cast<SMDS_MeshNode *>(node2),
1033                         const_cast<SMDS_MeshNode *>(node3),
1034                         const_cast<SMDS_MeshNode *>(node4)
1035                 );
1036         } 
1037         return toReturn;
1038 }
1039
1040 //=======================================================================
1041 //function : FindElement
1042 //purpose  :
1043 //=======================================================================
1044
1045 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1046 {
1047         return myElementIDFactory->MeshElement(IDelem);
1048 }
1049
1050 //=======================================================================
1051 //function : DumpNodes
1052 //purpose  : 
1053 //=======================================================================
1054
1055 void SMDS_Mesh::DumpNodes() const
1056 {
1057         MESSAGE("dump nodes of mesh : ");
1058         SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1059         while(itnode->more()) MESSAGE(itnode->next());
1060         delete itnode;
1061 }
1062
1063 //=======================================================================
1064 //function : DumpEdges
1065 //purpose  : 
1066 //=======================================================================
1067
1068 void SMDS_Mesh::DumpEdges() const
1069 {
1070         MESSAGE("dump edges of mesh : ");
1071         SMDS_Iterator<const SMDS_MeshEdge *> * itedge=edgesIterator();
1072         while(itedge->more()) MESSAGE(itedge->next());
1073         delete itedge;
1074 }
1075
1076 //=======================================================================
1077 //function : DumpFaces
1078 //purpose  : 
1079 //=======================================================================
1080
1081 void SMDS_Mesh::DumpFaces() const
1082 {
1083         MESSAGE("dump faces of mesh : ");
1084         SMDS_Iterator<const SMDS_MeshFace *> * itface=facesIterator();
1085         while(itface->more()) MESSAGE(itface->next());
1086         delete itface;
1087 }
1088
1089 //=======================================================================
1090 //function : DumpVolumes
1091 //purpose  : 
1092 //=======================================================================
1093
1094 void SMDS_Mesh::DumpVolumes() const
1095 {
1096         MESSAGE("dump volumes of mesh : ");
1097         SMDS_Iterator<const SMDS_MeshVolume *> * itvol=volumesIterator();
1098         while(itvol->more()) MESSAGE(itvol->next());
1099         delete itvol;
1100 }
1101
1102 //=======================================================================
1103 //function : DebugStats
1104 //purpose  : 
1105 //=======================================================================
1106
1107 void SMDS_Mesh::DebugStats() const
1108 {
1109         MESSAGE("Debug stats of mesh : ");
1110
1111         MESSAGE("===== NODES ====="<<NbNodes());
1112         MESSAGE("===== EDGES ====="<<NbEdges());
1113         MESSAGE("===== FACES ====="<<NbFaces());
1114         MESSAGE("===== VOLUMES ====="<<NbVolumes());
1115
1116         MESSAGE("End Debug stats of mesh ");
1117
1118         //#ifdef DEB
1119         
1120         SMDS_Iterator<const SMDS_MeshNode *> * itnode=nodesIterator();
1121         int sizeofnodes = 0;
1122         int sizeoffaces = 0;
1123
1124         while(itnode->more())
1125         {
1126                 const SMDS_MeshNode *node = itnode->next();
1127
1128                 sizeofnodes += sizeof(*node);
1129                 
1130                 SMDS_Iterator<const SMDS_MeshElement *> * it=
1131                         node->GetInverseElementIterator();
1132                 while(it->more())
1133                 {
1134                         const SMDS_MeshElement *me = it->next();
1135                         sizeofnodes += sizeof(me);
1136                 }
1137                 delete it;
1138
1139         }
1140         delete itnode;
1141         SMDS_Iterator<const SMDS_MeshFace*>* itface=facesIterator();
1142         
1143         while(itface->more())
1144         {
1145                 const SMDS_MeshElement *face = itface->next();          
1146                 sizeoffaces += sizeof(*face);
1147
1148         }
1149         MESSAGE("total size of node elements = " << sizeofnodes);;
1150         MESSAGE("total size of face elements = " << sizeoffaces);;
1151
1152         //#endif
1153
1154 }
1155
1156 ///////////////////////////////////////////////////////////////////////////////
1157 /// Return the number of nodes
1158 ///////////////////////////////////////////////////////////////////////////////
1159 int SMDS_Mesh::NbNodes() const
1160 {
1161         return myNodes.size();
1162 }
1163
1164 ///////////////////////////////////////////////////////////////////////////////
1165 /// Return the number of edges (including construction edges)
1166 ///////////////////////////////////////////////////////////////////////////////
1167 int SMDS_Mesh::NbEdges() const
1168 {
1169         return myEdges.size();
1170 }
1171
1172 ///////////////////////////////////////////////////////////////////////////////
1173 /// Return the number of faces (including construction faces)
1174 ///////////////////////////////////////////////////////////////////////////////
1175 int SMDS_Mesh::NbFaces() const
1176 {
1177         return myFaces.size();
1178 }
1179
1180 ///////////////////////////////////////////////////////////////////////////////
1181 /// Return the number of volumes
1182 ///////////////////////////////////////////////////////////////////////////////
1183 int SMDS_Mesh::NbVolumes() const
1184 {
1185         return myVolumes.size();
1186 }
1187
1188 ///////////////////////////////////////////////////////////////////////////////
1189 /// Return the number of child mesh of this mesh.
1190 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1191 /// (2003-09-08) of SMESH
1192 ///////////////////////////////////////////////////////////////////////////////
1193 int SMDS_Mesh::NbSubMesh() const
1194 {
1195         return myChildren.size();
1196 }
1197
1198 ///////////////////////////////////////////////////////////////////////////////
1199 /// Destroy the mesh and all its elements
1200 /// All pointer on elements owned by this mesh become illegals.
1201 ///////////////////////////////////////////////////////////////////////////////
1202 SMDS_Mesh::~SMDS_Mesh()
1203 {
1204         if(myParent==NULL)
1205         {
1206                 delete myNodeIDFactory;
1207                 delete myElementIDFactory;
1208         }
1209
1210         list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1211         while(itc!=myChildren.end())
1212         {
1213                 delete *itc;
1214                 itc++;
1215         }
1216         
1217         SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1218         while(itn->more())
1219         {
1220                 delete itn->next();
1221         }
1222         delete itn;
1223
1224         set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1225         while(ite!=myEdges.end())
1226         {
1227                 delete *ite;
1228                 ite++;
1229         }
1230
1231         set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1232         while(itf!=myFaces.end())
1233         {
1234                 delete *itf;
1235                 itf++;
1236         }
1237
1238         set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1239         while(itv!=myVolumes.end())
1240         {
1241                 delete *itv;
1242                 itv++;
1243         }
1244
1245 }
1246
1247 ///////////////////////////////////////////////////////////////////////////////
1248 /// Return true if this mesh create faces with edges.
1249 /// A false returned value mean that faces are created with nodes. A concequence
1250 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1251 ///////////////////////////////////////////////////////////////////////////////
1252 bool SMDS_Mesh::hasConstructionEdges()
1253 {
1254         return myHasConstructionEdges;
1255 }
1256
1257 ///////////////////////////////////////////////////////////////////////////////
1258 /// Return true if this mesh create volumes with faces
1259 /// A false returned value mean that volumes are created with nodes or edges.
1260 /// (see hasConstructionEdges)
1261 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1262 /// unavailable.
1263 ///////////////////////////////////////////////////////////////////////////////
1264 bool SMDS_Mesh::hasConstructionFaces()
1265 {
1266         return myHasConstructionFaces;
1267 }
1268
1269 ///////////////////////////////////////////////////////////////////////////////
1270 /// Return true if nodes are linked to the finit elements, they are belonging to.
1271 /// Currently, It always return true.
1272 ///////////////////////////////////////////////////////////////////////////////
1273 bool SMDS_Mesh::hasInverseElements()
1274 {
1275         return myHasInverseElements;
1276 }
1277
1278 ///////////////////////////////////////////////////////////////////////////////
1279 /// Make this mesh creating construction edges (see hasConstructionEdges)
1280 /// @param b true to have construction edges, else false.
1281 ///////////////////////////////////////////////////////////////////////////////
1282 void SMDS_Mesh::setConstructionEdges(bool b)
1283 {
1284         myHasConstructionEdges=b;
1285 }
1286
1287 ///////////////////////////////////////////////////////////////////////////////
1288 /// Make this mesh creating construction faces (see hasConstructionFaces)
1289 /// @param b true to have construction faces, else false.
1290 ///////////////////////////////////////////////////////////////////////////////
1291 void SMDS_Mesh::setConstructionFaces(bool b)
1292 {
1293          myHasConstructionFaces=b;
1294 }
1295
1296 ///////////////////////////////////////////////////////////////////////////////
1297 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1298 /// @param b true to link nodes to elements, else false.
1299 ///////////////////////////////////////////////////////////////////////////////
1300 void SMDS_Mesh::setInverseElements(bool b)
1301 {
1302         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1303         myHasInverseElements=b;
1304 }
1305
1306 ///////////////////////////////////////////////////////////////////////////////
1307 /// Return an iterator on nodes of the current mesh. Once used this iterator
1308 /// must be free by the caller
1309 ///////////////////////////////////////////////////////////////////////////////
1310 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1311 {
1312         class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1313         {
1314                 const SetOfNodes& mySet;
1315                 SetOfNodes::iterator myIterator;
1316           public:
1317                 MyIterator(const SetOfNodes& s):mySet(s)
1318                 {
1319                         myIterator=mySet.begin();
1320                 }
1321
1322                 bool more()
1323                 {
1324                         return myIterator!=mySet.end();
1325                 }
1326
1327                 const SMDS_MeshNode* next()
1328                 {
1329                         const SMDS_MeshNode* current=*myIterator;
1330                         myIterator++;
1331                         return current; 
1332                 }       
1333         };
1334         return new MyIterator(myNodes);
1335 }
1336
1337 ///////////////////////////////////////////////////////////////////////////////
1338 ///Return an iterator on volumes of the current mesh. Once used this iterator
1339 ///must be free by the caller
1340 ///////////////////////////////////////////////////////////////////////////////
1341 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1342 {
1343         class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1344         {
1345                 const SetOfEdges& mySet;
1346                 const SMDS_MeshEdge * myEdge;
1347                 SetOfEdges::iterator myIterator;
1348           public:
1349                 MyIterator(const SetOfEdges& s):mySet(s)
1350                 {
1351                         myIterator=mySet.begin();
1352                 }
1353
1354                 bool more()
1355                 {
1356                         while((myIterator!=mySet.end()))
1357                         {
1358                                 if((*myIterator)->GetID()!=-1)
1359                                         return true;
1360                                 myIterator++;
1361                         }
1362                         return false;
1363                 }
1364
1365                 const SMDS_MeshEdge* next()
1366                 {
1367                         const SMDS_MeshEdge* current=*myIterator;
1368                         myIterator++;
1369                         return current; 
1370                 }       
1371         };
1372         return new MyIterator(myEdges);
1373 }
1374
1375 ///////////////////////////////////////////////////////////////////////////////
1376 ///Return an iterator on faces of the current mesh. Once used this iterator
1377 ///must be free by the caller
1378 ///////////////////////////////////////////////////////////////////////////////
1379 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1380 {
1381         class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1382         {
1383                 const SetOfFaces& mySet;
1384                 set<SMDS_MeshFace*>::iterator myIterator;
1385           public:
1386                 MyIterator(const SetOfFaces& s):mySet(s)
1387                 {
1388                         myIterator=mySet.begin();
1389                 }
1390
1391                 bool more()
1392                 {
1393                         while((myIterator!=mySet.end()))
1394                         {
1395                                 if((*myIterator)->GetID()!=-1)
1396                                         return true;
1397                                 myIterator++;
1398                         }
1399                         return false;
1400                 }
1401
1402                 const SMDS_MeshFace* next()
1403                 {
1404                         const SMDS_MeshFace* current=*myIterator;
1405                         myIterator++;
1406                         return current; 
1407                 }       
1408         };
1409         return new MyIterator(myFaces);
1410 }
1411
1412 ///////////////////////////////////////////////////////////////////////////////
1413 ///Return an iterator on volumes of the current mesh. Once used this iterator
1414 ///must be free by the caller
1415 ///////////////////////////////////////////////////////////////////////////////
1416 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1417 {
1418         class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1419         {
1420                 const SetOfVolumes& mySet;
1421                 SetOfVolumes::iterator myIterator;
1422           public:
1423                 MyIterator(const SetOfVolumes& s):mySet(s)
1424                 {
1425                         myIterator=mySet.begin();
1426                 }
1427
1428                 bool more()
1429                 {
1430                         return myIterator!=mySet.end();
1431                 }
1432
1433                 const SMDS_MeshVolume* next()
1434                 {
1435                         const SMDS_MeshVolume* current=*myIterator;
1436                         myIterator++;
1437                         return current; 
1438                 }       
1439         };
1440         return new MyIterator(myVolumes);
1441 }
1442