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