Salome HOME
c25456840afa7cf61172621d9607c150edb8aadd
[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 ///////////////////////////////////////////////////////////////////////////////
42 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
43         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
44         myElementIDFactory(parent->myElementIDFactory),
45         myHasConstructionEdges(false), myHasConstructionFaces(false),
46         myHasInverseElements(true)
47 {
48 }
49
50 ///////////////////////////////////////////////////////////////////////////////
51 ///Create a submesh and add it to the current mesh
52 ///////////////////////////////////////////////////////////////////////////////
53
54 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
55 {
56         SMDS_Mesh *submesh = new SMDS_Mesh(this);
57         myChildren.insert(myChildren.end(), submesh);
58         return submesh;
59 }
60
61 ///////////////////////////////////////////////////////////////////////////////
62 ///create a MeshNode and add it to the current Mesh
63 ///@return : The created node
64 ///////////////////////////////////////////////////////////////////////////////
65
66 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
67 {
68         return AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
69 }
70
71 ///////////////////////////////////////////////////////////////////////////////
72 ///create a MeshNode and add it to the current Mesh
73 ///@param ID : The ID of the MeshNode to create
74 ///@return : The created node or NULL if a node with this ID already exists
75 ///////////////////////////////////////////////////////////////////////////////
76 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
77 {
78         // find the MeshNode corresponding to ID
79         const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
80
81         if (node == NULL)
82         {
83                 SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
84                 myNodes.insert(node);
85                 myNodeIDFactory->BindID(ID,node);
86                 return node;
87         }
88         else
89                 return NULL;
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////
93 ///create a MeshEdge and add it to the current Mesh
94 ///@return : The created MeshEdge
95 ///////////////////////////////////////////////////////////////////////////////
96
97 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
98 {
99         SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
100         SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
101         if((node1==NULL)||(node2==NULL)) return NULL;
102         return AddEdgeWithID(node1, node2, ID);
103 }
104
105 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
106         const SMDS_MeshNode * node2)
107 {
108         return AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
109 }
110 ///////////////////////////////////////////////////////////////////////////////
111 ///Create a new edge and at it to the mesh
112 ///@param idnode1 ID of the first node
113 ///@param idnode2 ID of the second node
114 ///@param ID ID of the edge to create
115 ///@return The created edge or NULL if an edge with this ID already exists or
116 ///if input nodes are not found.
117 ///////////////////////////////////////////////////////////////////////////////
118
119 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
120                 const SMDS_MeshNode * n2, int ID)
121 {
122         SMDS_MeshNode *node1,*node2;
123         node1=const_cast<SMDS_MeshNode*>(n1);
124         node2=const_cast<SMDS_MeshNode*>(n2);
125
126         SMDS_MeshEdge * edge=new SMDS_MeshEdge(node1,node2);
127         if(myElementIDFactory->BindID(ID, edge))
128         {
129                 node1->AddInverseElement(edge);
130                 node2->AddInverseElement(edge);         
131                 myEdges.insert(edge);
132                 return edge;
133         } 
134         else
135         {
136                 delete edge;
137                 return NULL;
138         }
139 }
140
141 ///////////////////////////////////////////////////////////////////////////////
142 /// Add a triangle defined by its nodes. An ID is automatically affected to the
143 /// Created face
144 ///////////////////////////////////////////////////////////////////////////////
145
146 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
147         const SMDS_MeshNode * n2,
148         const SMDS_MeshNode * n3)
149 {
150         return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
151 }
152
153 ///////////////////////////////////////////////////////////////////////////////
154 /// Add a quadrangle defined by its nodes IDs
155 ///////////////////////////////////////////////////////////////////////////////
156
157 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
158 {
159         SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
160         SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
161         SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
162         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
163         return AddFaceWithID(node1, node2, node3, ID);  
164 }
165
166 ///////////////////////////////////////////////////////////////////////////////
167 /// Add a quadrangle defined by its nodes
168 ///////////////////////////////////////////////////////////////////////////////
169
170 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(
171         const SMDS_MeshNode * n1,
172         const SMDS_MeshNode * n2,
173         const SMDS_MeshNode * n3, int ID)
174 {
175         SMDS_MeshNode *node1, *node2, *node3;
176         node1=const_cast<SMDS_MeshNode*>(n1),
177         node2=const_cast<SMDS_MeshNode*>(n2),
178         node3=const_cast<SMDS_MeshNode*>(n3);
179         SMDS_MeshFace * face=createTriangle(node1, node2, node3);
180
181         if(myElementIDFactory->BindID(ID, face))
182         {
183                 node1->AddInverseElement(face);
184                 node2->AddInverseElement(face);
185         node3->AddInverseElement(face);
186                 return face;
187         }       
188         else
189         {
190                 RemoveFace(face);
191                 return NULL;
192         }
193 }
194
195 ///////////////////////////////////////////////////////////////////////////////
196 /// Add a triangle defined by its nodes. An ID is automatically affected to the
197 /// created face
198 ///////////////////////////////////////////////////////////////////////////////
199
200 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
201         const SMDS_MeshNode * n2,
202         const SMDS_MeshNode * n3,
203         const SMDS_MeshNode * n4)
204 {
205         return AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
206 }
207
208 ///////////////////////////////////////////////////////////////////////////////
209 /// Add a quadrangle defined by its nodes IDs
210 ///////////////////////////////////////////////////////////////////////////////
211
212 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3,
213         int idnode4, int ID)
214 {
215         SMDS_MeshNode *node1, *node2, *node3, *node4;
216         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
217         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
218         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
219         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
220         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
221         return AddFaceWithID(node1, node2, node3, node4, ID);   
222 }
223
224 ///////////////////////////////////////////////////////////////////////////////
225 /// Add a quadrangle defined by its nodes
226 ///////////////////////////////////////////////////////////////////////////////
227
228 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
229         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
230         const SMDS_MeshNode * n4, int ID)
231 {
232         SMDS_MeshNode *node1, *node2, *node3, *node4;
233         node1=const_cast<SMDS_MeshNode*>(n1),
234         node2=const_cast<SMDS_MeshNode*>(n2),
235         node3=const_cast<SMDS_MeshNode*>(n3);
236         node4=const_cast<SMDS_MeshNode*>(n4);
237         SMDS_MeshFace * face=createQuadrangle(node1, node2, node3, node4);
238
239         if(myElementIDFactory->BindID(ID, face))
240         {
241                 node1->AddInverseElement(face);
242                 node2->AddInverseElement(face);
243         node3->AddInverseElement(face);
244         node4->AddInverseElement(face);
245                 return face;
246         }       
247         else
248         {
249                 RemoveFace(face);
250                 return NULL;
251         }
252 }
253
254 ///////////////////////////////////////////////////////////////////////////////
255 ///Create a new tetrahedron and add it to the mesh. 
256 ///@return The created tetrahedron or NULL if an edge with this ID already exists
257 ///or if input nodes are not found.
258 ///////////////////////////////////////////////////////////////////////////////
259
260 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
261         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
262         const SMDS_MeshNode * n4)
263 {
264         int ID = myElementIDFactory->GetFreeID();
265         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, ID);
266         if(v==NULL) myElementIDFactory->ReleaseID(ID);
267         return v;
268 }
269
270 ///////////////////////////////////////////////////////////////////////////////
271 ///Create a new tetrahedron and add it to the mesh. 
272 ///@param ID The ID of the new volume
273 ///@return The created tetrahedron or NULL if an edge with this ID already exists
274 ///or if input nodes are not found.
275 ///////////////////////////////////////////////////////////////////////////////
276
277 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
278         int idnode3, int idnode4, int ID)
279 {
280         SMDS_MeshNode *node1, *node2, *node3, *node4;
281         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
282         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
283         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
284         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
285         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)) return NULL;
286         return AddVolumeWithID(node1, node2, node3, node4, ID);
287 }
288         
289 ///////////////////////////////////////////////////////////////////////////////
290 ///Create a new tetrahedron and add it to the mesh. 
291 ///@param ID The ID of the new volume
292 ///@return The created tetrahedron or NULL if an edge with this ID already exists
293 ///or if input nodes are not found.
294 ///////////////////////////////////////////////////////////////////////////////
295
296 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
297                 const SMDS_MeshNode * n1,
298                 const SMDS_MeshNode * n2,
299                 const SMDS_MeshNode * n3,
300                 const SMDS_MeshNode * n4, int ID)
301 {
302         SMDS_MeshNode *node1, *node2, *node3, *node4;
303         node1=const_cast<SMDS_MeshNode*>(n1),
304         node2=const_cast<SMDS_MeshNode*>(n2),
305         node3=const_cast<SMDS_MeshNode*>(n3);
306         node4=const_cast<SMDS_MeshNode*>(n4);
307         SMDS_MeshVolume* volume;
308         if(hasConstructionFaces())
309         {
310                 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
311                 SMDS_MeshFace * f2=createTriangle(node1,node2,node4);
312                 SMDS_MeshFace * f3=createTriangle(node1,node3,node4);
313                 SMDS_MeshFace * f4=createTriangle(node2,node3,node4);
314                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
315                 myVolumes.insert(volume);
316         }
317         else if(hasConstructionEdges())
318         {
319                 MESSAGE("Error : Not implemented");
320                 return NULL;
321         }
322         else
323         {
324                 MESSAGE("Error : Not implemented");
325                 return NULL;
326         }
327
328         if(myElementIDFactory->BindID(ID, volume))
329         {
330                 node1->AddInverseElement(volume);
331                 node2->AddInverseElement(volume);
332         node3->AddInverseElement(volume);
333                 node4->AddInverseElement(volume);
334                 return volume;
335         }       
336         else
337         {
338                 RemoveVolume(volume);
339                 return NULL;
340         }
341 }
342
343 ///////////////////////////////////////////////////////////////////////////////
344 ///Create a new pyramid and add it to the mesh. 
345 ///Nodes 1,2,3 and 4 define the base of the pyramid
346 ///@return The created pyramid or NULL if an edge with this ID already exists
347 ///or if input nodes are not found.
348 ///////////////////////////////////////////////////////////////////////////////
349
350 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
351         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
352         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5)
353 {
354         int ID = myElementIDFactory->GetFreeID();
355         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, ID);
356         if(v==NULL) myElementIDFactory->ReleaseID(ID);
357         return v;
358 }
359
360 ///////////////////////////////////////////////////////////////////////////////
361 ///Create a new pyramid and add it to the mesh. 
362 ///Nodes 1,2,3 and 4 define the base of the pyramid
363 ///@param ID The ID of the new volume
364 ///@return The created pyramid or NULL if an edge with this ID already exists
365 ///or if input nodes are not found.
366 ///////////////////////////////////////////////////////////////////////////////
367
368 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
369         int idnode3, int idnode4, int idnode5, int ID)
370 {
371         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
372         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
373         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
374         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
375         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
376         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
377         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
378                 (node5=NULL))
379                 return NULL;
380         return AddVolumeWithID(node1, node2, node3, node4, node5, ID);
381 }
382         
383 ///////////////////////////////////////////////////////////////////////////////
384 ///Create a new pyramid and add it to the mesh.
385 ///Nodes 1,2,3 and 4 define the base of the pyramid
386 ///@param ID The ID of the new volume
387 ///@return The created pyramid or NULL if an edge with this ID already exists
388 ///or if input nodes are not found.
389 ///////////////////////////////////////////////////////////////////////////////
390
391 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
392                 const SMDS_MeshNode * n1,
393                 const SMDS_MeshNode * n2,
394                 const SMDS_MeshNode * n3,
395                 const SMDS_MeshNode * n4,
396                 const SMDS_MeshNode * n5, int ID)
397 {
398         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
399         node1=const_cast<SMDS_MeshNode*>(n1),
400         node2=const_cast<SMDS_MeshNode*>(n2),
401         node3=const_cast<SMDS_MeshNode*>(n3);
402         node4=const_cast<SMDS_MeshNode*>(n4);
403         node5=const_cast<SMDS_MeshNode*>(n5);
404         SMDS_MeshVolume* volume;
405         if(hasConstructionFaces())
406         {
407                 SMDS_MeshFace * f1=createQuadrangle(node1,node2,node3,node4);
408                 SMDS_MeshFace * f2=createTriangle(node1,node2,node5);
409                 SMDS_MeshFace * f3=createTriangle(node2,node3,node5);
410                 SMDS_MeshFace * f4=createTriangle(node3,node4,node5);
411                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
412                 myVolumes.insert(volume);
413         }
414         else if(hasConstructionEdges())
415         {
416                 MESSAGE("Error : Not implemented");
417                 return NULL;
418         }
419         else
420         {
421                 MESSAGE("Error : Not implemented");
422                 return NULL;
423         }
424
425         if(myElementIDFactory->BindID(ID, volume))
426         {
427                 node1->AddInverseElement(volume);
428                 node2->AddInverseElement(volume);
429         node3->AddInverseElement(volume);
430                 node4->AddInverseElement(volume);
431                 node5->AddInverseElement(volume);
432                 return volume;
433         }       
434         else
435         {
436                 RemoveVolume(volume);
437                 return NULL;
438         }
439 }
440
441 ///////////////////////////////////////////////////////////////////////////////
442 ///Create a new prism and add it to the mesh. 
443 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
444 ///@return The created prism or NULL if an edge with this ID already exists
445 ///or if input nodes are not found.
446 ///////////////////////////////////////////////////////////////////////////////
447
448 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
449         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
450         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
451         const SMDS_MeshNode * n6)
452 {
453         int ID = myElementIDFactory->GetFreeID();
454         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
455         if(v==NULL) myElementIDFactory->ReleaseID(ID);
456         return v;
457 }
458
459 ///////////////////////////////////////////////////////////////////////////////
460 ///Create a new prism and add it to the mesh. 
461 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
462 ///@param ID The ID of the new volume
463 ///@return The created prism or NULL if an edge with this ID already exists
464 ///or if input nodes are not found.
465 ///////////////////////////////////////////////////////////////////////////////
466
467 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
468         int idnode3, int idnode4, int idnode5, int idnode6, int ID)
469 {
470         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
471         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
472         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
473         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
474         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
475         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
476         node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
477         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
478                 (node5==NULL)||(node6=NULL))
479                 return NULL;
480         return AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
481 }
482         
483 ///////////////////////////////////////////////////////////////////////////////
484 ///Create a new prism and add it to the mesh.
485 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
486 ///@param ID The ID of the new volume
487 ///@return The created prism or NULL if an edge with this ID already exists
488 ///or if input nodes are not found.
489 ///////////////////////////////////////////////////////////////////////////////
490
491 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
492                 const SMDS_MeshNode * n1,
493                 const SMDS_MeshNode * n2,
494                 const SMDS_MeshNode * n3,
495                 const SMDS_MeshNode * n4,
496                 const SMDS_MeshNode * n5,
497                 const SMDS_MeshNode * n6, int ID)
498 {
499         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
500         node1=const_cast<SMDS_MeshNode*>(n1),
501         node2=const_cast<SMDS_MeshNode*>(n2),
502         node3=const_cast<SMDS_MeshNode*>(n3);
503         node4=const_cast<SMDS_MeshNode*>(n4);
504         node5=const_cast<SMDS_MeshNode*>(n5);
505         node6=const_cast<SMDS_MeshNode*>(n6);
506         SMDS_MeshVolume* volume;
507         if(hasConstructionFaces())
508         {
509                 SMDS_MeshFace * f1=createTriangle(node1,node2,node3);
510                 SMDS_MeshFace * f2=createTriangle(node4,node5,node6);
511                 SMDS_MeshFace * f3=createQuadrangle(node1,node4,node5,node2);
512                 SMDS_MeshFace * f4=createQuadrangle(node2,node5,node6,node3);
513                 SMDS_MeshFace * f5=createQuadrangle(node3,node6,node4,node1);
514                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
515                 myVolumes.insert(volume);
516         }
517         else if(hasConstructionEdges())
518         {
519                 MESSAGE("Error : Not implemented");
520                 return NULL;
521         }
522         else
523         {
524                 MESSAGE("Error : Not implemented");
525                 return NULL;
526         }
527
528         if(myElementIDFactory->BindID(ID, volume))
529         {
530                 node1->AddInverseElement(volume);
531                 node2->AddInverseElement(volume);
532         node3->AddInverseElement(volume);
533                 node4->AddInverseElement(volume);
534                 node5->AddInverseElement(volume);
535                 node6->AddInverseElement(volume);
536                 return volume;
537         }       
538         else
539         {
540                 RemoveVolume(volume);
541                 return NULL;
542         }
543 }
544
545 ///////////////////////////////////////////////////////////////////////////////
546 ///Create a new hexahedron and add it to the mesh. 
547 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
548 ///@return The created hexahedron or NULL if an edge with this ID already exists
549 ///or if input nodes are not found.
550 ///////////////////////////////////////////////////////////////////////////////
551
552 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
553         const SMDS_MeshNode * n2, const SMDS_MeshNode * n3,
554         const SMDS_MeshNode * n4, const SMDS_MeshNode * n5,
555         const SMDS_MeshNode * n6, const SMDS_MeshNode * n7,
556         const SMDS_MeshNode * n8)
557 {
558         int ID = myElementIDFactory->GetFreeID();
559         SMDS_MeshVolume * v = AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
560         if(v==NULL) myElementIDFactory->ReleaseID(ID);
561         return v;
562 }
563
564 ///////////////////////////////////////////////////////////////////////////////
565 ///Create a new hexahedron and add it to the mesh. 
566 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
567 ///@param ID The ID of the new volume
568 ///@return The created hexahedron or NULL if an edge with this ID already exists
569 ///or if input nodes are not found.
570 ///////////////////////////////////////////////////////////////////////////////
571
572 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, int idnode2,
573         int idnode3, int idnode4, int idnode5, int idnode6, int idnode7,
574         int idnode8, int ID)
575 {
576         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
577         node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
578         node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
579         node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
580         node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
581         node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
582         node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
583         node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
584         node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
585         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4=NULL)||
586                 (node5==NULL)||(node6=NULL)||(node7==NULL)||(node8=NULL))
587                 return NULL;
588         return AddVolumeWithID(node1, node2, node3, node4, node5, node6, node7,
589                 node8, ID);
590 }
591         
592 ///////////////////////////////////////////////////////////////////////////////
593 ///Create a new prism and add it to the mesh.
594 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
595 ///@param ID The ID of the new volume
596 ///@return The created prism or NULL if an edge with this ID already exists
597 ///or if input nodes are not found.
598 ///////////////////////////////////////////////////////////////////////////////
599
600 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(
601                 const SMDS_MeshNode * n1,
602                 const SMDS_MeshNode * n2,
603                 const SMDS_MeshNode * n3,
604                 const SMDS_MeshNode * n4,
605                 const SMDS_MeshNode * n5,
606                 const SMDS_MeshNode * n6,
607                 const SMDS_MeshNode * n7,
608                 const SMDS_MeshNode * n8, int ID)
609 {
610         SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
611         node1=const_cast<SMDS_MeshNode*>(n1),
612         node2=const_cast<SMDS_MeshNode*>(n2),
613         node3=const_cast<SMDS_MeshNode*>(n3);
614         node4=const_cast<SMDS_MeshNode*>(n4);
615         node5=const_cast<SMDS_MeshNode*>(n5);
616         node6=const_cast<SMDS_MeshNode*>(n6);
617         node7=const_cast<SMDS_MeshNode*>(n7);
618         node8=const_cast<SMDS_MeshNode*>(n8);
619         SMDS_MeshVolume* volume;
620         if(hasConstructionFaces())
621         {
622                 SMDS_MeshFace * f1=FindFaceOrCreate(node1,node2,node3,node4);
623                 SMDS_MeshFace * f2=FindFaceOrCreate(node5,node6,node7,node8);
624                 SMDS_MeshFace * f3=FindFaceOrCreate(node1,node4,node8,node5);
625                 SMDS_MeshFace * f4=FindFaceOrCreate(node1,node2,node6,node5);
626                 SMDS_MeshFace * f5=FindFaceOrCreate(node2,node3,node7,node6);
627                 SMDS_MeshFace * f6=FindFaceOrCreate(node3,node4,node8,node7);
628                 volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
629                 myVolumes.insert(volume);
630         }
631         else if(hasConstructionEdges())
632         {
633                 MESSAGE("Error : Not implemented");
634                 return NULL;
635         }
636         else
637         {
638                 volume=new SMDS_VolumeOfNodes(node1,node2,node3,node4,node5,node6,
639                         node7,node8);
640                 myVolumes.insert(volume);
641         }
642
643         if(myElementIDFactory->BindID(ID, volume))
644         {
645                 node1->AddInverseElement(volume);
646                 node2->AddInverseElement(volume);
647         node3->AddInverseElement(volume);
648                 node4->AddInverseElement(volume);
649                 node5->AddInverseElement(volume);
650                 node6->AddInverseElement(volume);
651                 node7->AddInverseElement(volume);
652                 node8->AddInverseElement(volume);
653                 return volume;
654         }       
655         else
656         {
657                 RemoveVolume(volume);
658                 return NULL;
659         }
660 }
661
662 //=======================================================================
663 //function : FindNode
664 //purpose  :
665 //=======================================================================
666
667 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
668 {
669         return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
670 }
671
672 ///////////////////////////////////////////////////////////////////////////////
673 ///Create a triangle and add it to the current mesh. This methode do not bind a
674 ///ID to the create triangle.
675 ///////////////////////////////////////////////////////////////////////////////
676 SMDS_MeshFace * SMDS_Mesh::createTriangle(SMDS_MeshNode * node1,
677         SMDS_MeshNode * node2, SMDS_MeshNode * node3)
678 {
679         if(hasConstructionEdges())
680         {
681                 SMDS_MeshEdge *edge1, *edge2, *edge3;
682                 edge1=FindEdgeOrCreate(node1,node2);
683                 edge2=FindEdgeOrCreate(node2,node3);
684                 edge3=FindEdgeOrCreate(node3,node1);
685
686                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
687                 myFaces.insert(face);
688                 return face;
689         }
690         else
691         {
692                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
693                 myFaces.insert(face);
694                 return face;
695         }
696 }
697
698 ///////////////////////////////////////////////////////////////////////////////
699 ///Create a quadrangle and add it to the current mesh. This methode do not bind
700 ///a ID to the create triangle.
701 ///////////////////////////////////////////////////////////////////////////////
702 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(SMDS_MeshNode * node1,
703         SMDS_MeshNode * node2, SMDS_MeshNode * node3, SMDS_MeshNode * node4)
704 {
705         if(hasConstructionEdges())
706         {
707                 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
708                 edge1=FindEdgeOrCreate(node1,node2);
709                 edge2=FindEdgeOrCreate(node2,node3);
710                 edge3=FindEdgeOrCreate(node3,node4);
711                 edge4=FindEdgeOrCreate(node4,node1);
712
713                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
714                 myFaces.insert(face);
715                 return face;
716         }
717         else
718         {
719                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
720                 myFaces.insert(face);
721                 return face;
722         }
723 }
724
725
726 //=======================================================================
727 //function : RemoveNode
728 //purpose  :
729 //=======================================================================
730
731 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
732 {
733         SMDS_Iterator<const SMDS_MeshElement *> * it=
734                 node->GetInverseElementIterator();
735         while(it->more()) RemoveElement(it->next(),true);
736         myNodeIDFactory->ReleaseID(node->GetID());
737         myNodes.erase(const_cast<SMDS_MeshNode*>(node));
738 }
739
740 //=======================================================================
741 //function : RemoveEdge
742 //purpose  :
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 //function : RemoveFace
755 //purpose  :
756 //=======================================================================
757
758 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
759 {
760         /** @todo to be fix */
761         myFaces.erase(const_cast<SMDS_MeshFace*>(face));
762         //removeElementDependencies(face);
763         delete face;
764 }
765
766 //=======================================================================
767 //function : RemoveVolume
768 //purpose  :
769 //=======================================================================
770
771 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
772 {
773         /** @todo to be fix */
774         myVolumes.erase(const_cast<SMDS_MeshVolume*>(volume));
775         //removeElementDependencies(volume);
776         delete volume;
777 }
778 ///////////////////////////////////////////////////////////////////////////////
779 /// Remove no longer used sub element of an element. Unbind the element ID
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 int SMDS_Mesh::NbNodes() const
1157 {
1158         return myNodes.size();
1159 }
1160
1161 int SMDS_Mesh::NbEdges() const
1162 {
1163         return myEdges.size();
1164 }
1165
1166 int SMDS_Mesh::NbFaces() const
1167 {
1168         return myFaces.size();
1169 }
1170
1171 int SMDS_Mesh::NbVolumes() const
1172 {
1173         return myVolumes.size();
1174 }
1175
1176 int SMDS_Mesh::NbSubMesh() const
1177 {
1178         return myChildren.size();
1179 }
1180
1181 SMDS_Mesh::~SMDS_Mesh()
1182 {
1183         if(myParent==NULL)
1184         {
1185                 delete myNodeIDFactory;
1186                 delete myElementIDFactory;
1187         }
1188
1189         list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1190         while(itc!=myChildren.end())
1191         {
1192                 delete *itc;
1193                 itc++;
1194         }
1195         
1196         SMDS_Iterator<const SMDS_MeshNode*> * itn=nodesIterator();
1197         while(itn->more())
1198         {
1199                 delete itn->next();
1200         }
1201         delete itn;
1202
1203         set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
1204         while(ite!=myEdges.end())
1205         {
1206                 delete *ite;
1207                 ite++;
1208         }
1209
1210         set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
1211         while(itf!=myFaces.end())
1212         {
1213                 delete *itf;
1214                 itf++;
1215         }
1216
1217         set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
1218         while(itv!=myVolumes.end())
1219         {
1220                 delete *itv;
1221                 itv++;
1222         }
1223
1224 }
1225
1226 bool SMDS_Mesh::hasConstructionEdges()
1227 {
1228         return myHasConstructionEdges;
1229 }
1230
1231 bool SMDS_Mesh::hasConstructionFaces()
1232 {
1233         return myHasConstructionFaces;
1234 }
1235
1236 bool SMDS_Mesh::hasInverseElements()
1237 {
1238         return myHasInverseElements;
1239 }
1240
1241 void SMDS_Mesh::setConstructionEdges(bool b)
1242 {
1243         myHasConstructionEdges=b;
1244 }
1245
1246 void SMDS_Mesh::setConstructionFaces(bool b)
1247 {
1248          myHasConstructionFaces=b;
1249 }
1250
1251 void SMDS_Mesh::setInverseElements(bool b)
1252 {
1253         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1254         myHasInverseElements=b;
1255 }
1256
1257 ///////////////////////////////////////////////////////////////////////////////
1258 ///Return an iterator on nodes of the current mesh. Once used this iterator
1259 ///must be free by the caller
1260 ///////////////////////////////////////////////////////////////////////////////
1261 SMDS_Iterator<const SMDS_MeshNode *> * SMDS_Mesh::nodesIterator() const
1262 {
1263         class MyIterator:public SMDS_Iterator<const SMDS_MeshNode*>
1264         {
1265                 const SetOfNodes& mySet;
1266                 SetOfNodes::iterator myIterator;
1267           public:
1268                 MyIterator(const SetOfNodes& s):mySet(s)
1269                 {
1270                         myIterator=mySet.begin();
1271                 }
1272
1273                 bool more()
1274                 {
1275                         return myIterator!=mySet.end();
1276                 }
1277
1278                 const SMDS_MeshNode* next()
1279                 {
1280                         const SMDS_MeshNode* current=*myIterator;
1281                         myIterator++;
1282                         return current; 
1283                 }       
1284         };
1285         return new MyIterator(myNodes);
1286 }
1287
1288 ///////////////////////////////////////////////////////////////////////////////
1289 ///Return an iterator on volumes of the current mesh. Once used this iterator
1290 ///must be free by the caller
1291 ///////////////////////////////////////////////////////////////////////////////
1292 SMDS_Iterator<const SMDS_MeshEdge *> * SMDS_Mesh::edgesIterator() const
1293 {
1294         class MyIterator:public SMDS_Iterator<const SMDS_MeshEdge*>
1295         {
1296                 const SetOfEdges& mySet;
1297                 const SMDS_MeshEdge * myEdge;
1298                 SetOfEdges::iterator myIterator;
1299           public:
1300                 MyIterator(const SetOfEdges& s):mySet(s)
1301                 {
1302                         myIterator=mySet.begin();
1303                 }
1304
1305                 bool more()
1306                 {
1307                         while((myIterator!=mySet.end()))
1308                         {
1309                                 if((*myIterator)->GetID()!=-1)
1310                                         return true;
1311                                 myIterator++;
1312                         }
1313                         return false;
1314                 }
1315
1316                 const SMDS_MeshEdge* next()
1317                 {
1318                         const SMDS_MeshEdge* current=*myIterator;
1319                         myIterator++;
1320                         return current; 
1321                 }       
1322         };
1323         return new MyIterator(myEdges);
1324 }
1325
1326 ///////////////////////////////////////////////////////////////////////////////
1327 ///Return an iterator on faces of the current mesh. Once used this iterator
1328 ///must be free by the caller
1329 ///////////////////////////////////////////////////////////////////////////////
1330 SMDS_Iterator<const SMDS_MeshFace *> * SMDS_Mesh::facesIterator() const
1331 {
1332         class MyIterator:public SMDS_Iterator<const SMDS_MeshFace*>
1333         {
1334                 const SetOfFaces& mySet;
1335                 set<SMDS_MeshFace*>::iterator myIterator;
1336           public:
1337                 MyIterator(const SetOfFaces& s):mySet(s)
1338                 {
1339                         myIterator=mySet.begin();
1340                 }
1341
1342                 bool more()
1343                 {
1344                         while((myIterator!=mySet.end()))
1345                         {
1346                                 if((*myIterator)->GetID()!=-1)
1347                                         return true;
1348                                 myIterator++;
1349                         }
1350                         return false;
1351                 }
1352
1353                 const SMDS_MeshFace* next()
1354                 {
1355                         const SMDS_MeshFace* current=*myIterator;
1356                         myIterator++;
1357                         return current; 
1358                 }       
1359         };
1360         return new MyIterator(myFaces);
1361 }
1362
1363 ///////////////////////////////////////////////////////////////////////////////
1364 ///Return an iterator on volumes of the current mesh. Once used this iterator
1365 ///must be free by the caller
1366 ///////////////////////////////////////////////////////////////////////////////
1367 SMDS_Iterator<const SMDS_MeshVolume *> * SMDS_Mesh::volumesIterator() const
1368 {
1369         class MyIterator:public SMDS_Iterator<const SMDS_MeshVolume*>
1370         {
1371                 const SetOfVolumes& mySet;
1372                 SetOfVolumes::iterator myIterator;
1373           public:
1374                 MyIterator(const SetOfVolumes& s):mySet(s)
1375                 {
1376                         myIterator=mySet.begin();
1377                 }
1378
1379                 bool more()
1380                 {
1381                         return myIterator!=mySet.end();
1382                 }
1383
1384                 const SMDS_MeshVolume* next()
1385                 {
1386                         const SMDS_MeshVolume* current=*myIterator;
1387                         myIterator++;
1388                         return current; 
1389                 }       
1390         };
1391         return new MyIterator(myVolumes);
1392 }
1393