Salome HOME
763d61c47eb53d493a7a87c896eea73c3c86dd48
[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 #ifdef _MSC_VER
23 #pragma warning(disable:4786)
24 #endif
25
26 #include "utilities.h"
27 #include "SMDS_Mesh.hxx"
28 #include "SMDS_VolumeOfNodes.hxx"
29 #include "SMDS_VolumeOfFaces.hxx"
30 #include "SMDS_FaceOfNodes.hxx"
31 #include "SMDS_FaceOfEdges.hxx"
32
33 #include <algorithm>
34 #include <map>
35 using namespace std;
36
37 ///////////////////////////////////////////////////////////////////////////////
38 /// Create a new mesh object
39 ///////////////////////////////////////////////////////////////////////////////
40 SMDS_Mesh::SMDS_Mesh()
41         :myParent(NULL),
42         myNodeIDFactory(new SMDS_MeshElementIDFactory()),
43         myElementIDFactory(new SMDS_MeshElementIDFactory()),
44         myHasConstructionEdges(false), myHasConstructionFaces(false),
45         myHasInverseElements(true)
46 {
47 }
48
49 ///////////////////////////////////////////////////////////////////////////////
50 /// Create a new child mesh
51 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
52 /// (2003-09-08) of SMESH
53 ///////////////////////////////////////////////////////////////////////////////
54 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
55         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
56         myElementIDFactory(parent->myElementIDFactory),
57         myHasConstructionEdges(false), myHasConstructionFaces(false),
58         myHasInverseElements(true)
59 {
60 }
61
62 ///////////////////////////////////////////////////////////////////////////////
63 ///Create a submesh and add it to the current mesh
64 ///////////////////////////////////////////////////////////////////////////////
65
66 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
67 {
68         SMDS_Mesh *submesh = new SMDS_Mesh(this);
69         myChildren.insert(myChildren.end(), submesh);
70         return submesh;
71 }
72
73 ///////////////////////////////////////////////////////////////////////////////
74 ///create a MeshNode and add it to the current Mesh
75 ///An ID is automatically assigned to the node.
76 ///@return : The created node
77 ///////////////////////////////////////////////////////////////////////////////
78
79 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
80 {
81   return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
82 }
83
84 ///////////////////////////////////////////////////////////////////////////////
85 ///create a MeshNode and add it to the current Mesh
86 ///@param ID : The ID of the MeshNode to create
87 ///@return : The created node or NULL if a node with this ID already exists
88 ///////////////////////////////////////////////////////////////////////////////
89 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
90 {
91   // find the MeshNode corresponding to ID
92   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
93   if(!node){
94     SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
95     myNodes.Add(node);
96     myNodeIDFactory->BindID(ID,node);
97     return node;
98   }else
99     return NULL;
100 }
101
102 ///////////////////////////////////////////////////////////////////////////////
103 /// create a MeshEdge and add it to the current Mesh
104 /// @return : The created MeshEdge
105 ///////////////////////////////////////////////////////////////////////////////
106
107 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
108 {
109   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
110   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
111   if(!node1 || !node2) return NULL;
112   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
113 }
114
115 ///////////////////////////////////////////////////////////////////////////////
116 /// create a MeshEdge and add it to the current Mesh
117 /// @return : The created MeshEdge
118 ///////////////////////////////////////////////////////////////////////////////
119
120 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
121                                   const SMDS_MeshNode * node2)
122 {
123   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
124 }
125
126 ///////////////////////////////////////////////////////////////////////////////
127 /// Create a new edge and at it to the mesh
128 /// @param idnode1 ID of the first node
129 /// @param idnode2 ID of the second node
130 /// @param ID ID of the edge to create
131 /// @return The created edge or NULL if an element with this ID already exists or
132 /// if input nodes are not found.
133 ///////////////////////////////////////////////////////////////////////////////
134
135 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
136                                         const SMDS_MeshNode * n2, 
137                                         int ID)
138 {
139   SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
140   if(myElementIDFactory->BindID(ID, edge)) {
141     SMDS_MeshNode *node1,*node2;
142     node1=const_cast<SMDS_MeshNode*>(n1);
143     node2=const_cast<SMDS_MeshNode*>(n2);
144     node1->AddInverseElement(edge);
145     node2->AddInverseElement(edge);             
146     myEdges.Add(edge);
147     return edge;
148   } 
149   else {
150     delete edge;
151     return NULL;
152   }
153 }
154
155 ///////////////////////////////////////////////////////////////////////////////
156 /// Add a triangle defined by its nodes. An ID is automatically affected to the
157 /// Created face
158 ///////////////////////////////////////////////////////////////////////////////
159
160 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
161                                   const SMDS_MeshNode * n2,
162                                   const SMDS_MeshNode * n3)
163 {
164   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
165 }
166
167 ///////////////////////////////////////////////////////////////////////////////
168 /// Add a triangle defined by its nodes IDs
169 ///////////////////////////////////////////////////////////////////////////////
170
171 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
172 {
173   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
174   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
175   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
176   if(!node1 || !node2 || !node3) return NULL;
177   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);     
178 }
179
180 ///////////////////////////////////////////////////////////////////////////////
181 /// Add a triangle defined by its nodes
182 ///////////////////////////////////////////////////////////////////////////////
183
184 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
185                                         const SMDS_MeshNode * n2,
186                                         const SMDS_MeshNode * n3,
187                                         int ID)
188 {
189   SMDS_MeshFace * face=createTriangle(n1, n2, n3);
190
191   if (!registerElement(ID, face)) {
192     RemoveElement(face, false);
193     face = NULL;
194   }
195   return face;
196 }
197
198 ///////////////////////////////////////////////////////////////////////////////
199 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
200 /// created face
201 ///////////////////////////////////////////////////////////////////////////////
202
203 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
204                                   const SMDS_MeshNode * n2,
205                                   const SMDS_MeshNode * n3,
206                                   const SMDS_MeshNode * n4)
207 {
208   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
209 }
210
211 ///////////////////////////////////////////////////////////////////////////////
212 /// Add a quadrangle defined by its nodes IDs
213 ///////////////////////////////////////////////////////////////////////////////
214
215 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, 
216                                         int idnode2, 
217                                         int idnode3,
218                                         int idnode4, 
219                                         int ID)
220 {
221   SMDS_MeshNode *node1, *node2, *node3, *node4;
222   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
223   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
224   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
225   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
226   if(!node1 || !node2 || !node3 || !node4) return NULL;
227   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);      
228 }
229
230 ///////////////////////////////////////////////////////////////////////////////
231 /// Add a quadrangle defined by its nodes
232 ///////////////////////////////////////////////////////////////////////////////
233
234 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
235                                         const SMDS_MeshNode * n2,
236                                         const SMDS_MeshNode * n3,
237                                         const SMDS_MeshNode * n4,
238                                         int ID)
239 {
240   SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
241
242   if (!registerElement(ID, face)) {
243     RemoveElement(face, false);
244     face = NULL;
245   }
246   return face;
247 }
248
249 ///////////////////////////////////////////////////////////////////////////////
250 /// Add a triangle defined by its edges. An ID is automatically assigned to the
251 /// Created face
252 ///////////////////////////////////////////////////////////////////////////////
253
254 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
255                                   const SMDS_MeshEdge * e2,
256                                   const SMDS_MeshEdge * e3)
257 {
258   if (!hasConstructionEdges())
259     return NULL;
260   return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
261 }
262
263 ///////////////////////////////////////////////////////////////////////////////
264 /// Add a triangle defined by its edges
265 ///////////////////////////////////////////////////////////////////////////////
266
267 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
268                                         const SMDS_MeshEdge * e2,
269                                         const SMDS_MeshEdge * e3,
270                                         int ID)
271 {
272   if (!hasConstructionEdges())
273     return NULL;
274   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
275   myFaces.Add(face);
276
277   if (!registerElement(ID, face)) {
278     RemoveElement(face, false);
279     face = NULL;
280   }
281   return face;
282 }
283
284 ///////////////////////////////////////////////////////////////////////////////
285 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
286 /// Created face
287 ///////////////////////////////////////////////////////////////////////////////
288
289 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
290                                   const SMDS_MeshEdge * e2,
291                                   const SMDS_MeshEdge * e3,
292                                   const SMDS_MeshEdge * e4)
293 {
294   if (!hasConstructionEdges())
295     return NULL;
296   return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
297 }
298
299 ///////////////////////////////////////////////////////////////////////////////
300 /// Add a quadrangle defined by its edges
301 ///////////////////////////////////////////////////////////////////////////////
302
303 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
304                                         const SMDS_MeshEdge * e2,
305                                         const SMDS_MeshEdge * e3,
306                                         const SMDS_MeshEdge * e4,
307                                         int ID)
308 {
309   if (!hasConstructionEdges())
310     return NULL;
311   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
312   myFaces.Add(face);
313
314   if (!registerElement(ID, face))
315   {
316     RemoveElement(face, false);
317     face = NULL;
318   }
319   return face;
320 }
321
322 ///////////////////////////////////////////////////////////////////////////////
323 ///Create a new tetrahedron and add it to the mesh. 
324 ///@return The created tetrahedron 
325 ///////////////////////////////////////////////////////////////////////////////
326
327 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
328                                       const SMDS_MeshNode * n2, 
329                                       const SMDS_MeshNode * n3,
330                                       const SMDS_MeshNode * n4)
331 {
332   int ID = myElementIDFactory->GetFreeID();
333   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
334   if(v==NULL) myElementIDFactory->ReleaseID(ID);
335   return v;
336 }
337
338 ///////////////////////////////////////////////////////////////////////////////
339 ///Create a new tetrahedron and add it to the mesh. 
340 ///@param ID The ID of the new volume
341 ///@return The created tetrahedron or NULL if an element with this ID already exists
342 ///or if input nodes are not found.
343 ///////////////////////////////////////////////////////////////////////////////
344
345 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
346                                              int idnode2,
347                                              int idnode3, 
348                                              int idnode4, 
349                                              int ID)
350 {
351   SMDS_MeshNode *node1, *node2, *node3, *node4;
352   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
353   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
354   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
355   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
356   if(!node1 || !node2 || !node3 || !node4) return NULL;
357   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
358 }
359         
360 ///////////////////////////////////////////////////////////////////////////////
361 ///Create a new tetrahedron and add it to the mesh. 
362 ///@param ID The ID of the new volume
363 ///@return The created tetrahedron 
364 ///////////////////////////////////////////////////////////////////////////////
365
366 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
367                                             const SMDS_MeshNode * n2,
368                                             const SMDS_MeshNode * n3,
369                                             const SMDS_MeshNode * n4,
370                                             int ID)
371 {
372   SMDS_MeshVolume* volume;
373   if(hasConstructionFaces()) {
374     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
375     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
376     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
377     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
378     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
379     myVolumes.Add(volume);
380   }
381   else if(hasConstructionEdges()) {
382     MESSAGE("Error : Not implemented");
383     return NULL;
384   }
385   else {
386     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
387     myVolumes.Add(volume);
388   }
389
390   if (!registerElement(ID, volume)) {
391     RemoveElement(volume, false);
392     volume = NULL;
393   }
394   return volume;
395 }
396
397 ///////////////////////////////////////////////////////////////////////////////
398 ///Create a new pyramid and add it to the mesh. 
399 ///Nodes 1,2,3 and 4 define the base of the pyramid
400 ///@return The created pyramid 
401 ///////////////////////////////////////////////////////////////////////////////
402
403 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
404                                       const SMDS_MeshNode * n2, 
405                                       const SMDS_MeshNode * n3,
406                                       const SMDS_MeshNode * n4, 
407                                       const SMDS_MeshNode * n5)
408 {
409   int ID = myElementIDFactory->GetFreeID();
410   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
411   if(v==NULL) myElementIDFactory->ReleaseID(ID);
412   return v;
413 }
414
415 ///////////////////////////////////////////////////////////////////////////////
416 ///Create a new pyramid and add it to the mesh. 
417 ///Nodes 1,2,3 and 4 define the base of the pyramid
418 ///@param ID The ID of the new volume
419 ///@return The created pyramid or NULL if an element with this ID already exists
420 ///or if input nodes are not found.
421 ///////////////////////////////////////////////////////////////////////////////
422
423 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
424                                              int idnode2,
425                                              int idnode3, 
426                                              int idnode4, 
427                                              int idnode5, 
428                                              int ID)
429 {
430   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
431   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
432   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
433   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
434   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
435   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
436   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
437   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
438 }
439         
440 ///////////////////////////////////////////////////////////////////////////////
441 ///Create a new pyramid and add it to the mesh.
442 ///Nodes 1,2,3 and 4 define the base of the pyramid
443 ///@param ID The ID of the new volume
444 ///@return The created pyramid
445 ///////////////////////////////////////////////////////////////////////////////
446
447 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
448                                             const SMDS_MeshNode * n2,
449                                             const SMDS_MeshNode * n3,
450                                             const SMDS_MeshNode * n4,
451                                             const SMDS_MeshNode * n5,
452                                             int ID)
453 {
454   SMDS_MeshVolume* volume;
455   if(hasConstructionFaces()) {
456     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
457     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
458     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
459     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
460     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
461     myVolumes.Add(volume);
462   }
463   else if(hasConstructionEdges()) {
464     MESSAGE("Error : Not implemented");
465     return NULL;
466   }
467   else {
468     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
469     myVolumes.Add(volume);
470   }
471
472   if (!registerElement(ID, volume)) {
473     RemoveElement(volume, false);
474     volume = NULL;
475   }
476   return volume;
477 }
478
479 ///////////////////////////////////////////////////////////////////////////////
480 ///Create a new prism and add it to the mesh. 
481 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
482 ///@return The created prism 
483 ///////////////////////////////////////////////////////////////////////////////
484
485 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
486                                       const SMDS_MeshNode * n2, 
487                                       const SMDS_MeshNode * n3,
488                                       const SMDS_MeshNode * n4, 
489                                       const SMDS_MeshNode * n5,
490                                       const SMDS_MeshNode * n6)
491 {
492   int ID = myElementIDFactory->GetFreeID();
493   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
494   if(v==NULL) myElementIDFactory->ReleaseID(ID);
495   return v;
496 }
497
498 ///////////////////////////////////////////////////////////////////////////////
499 ///Create a new prism and add it to the mesh. 
500 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
501 ///@param ID The ID of the new volume
502 ///@return The created prism or NULL if an element with this ID already exists
503 ///or if input nodes are not found.
504 ///////////////////////////////////////////////////////////////////////////////
505
506 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
507                                              int idnode2,
508                                              int idnode3, 
509                                              int idnode4, 
510                                              int idnode5, 
511                                              int idnode6, 
512                                              int ID)
513 {
514   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
515   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
516   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
517   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
518   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
519   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
520   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
521   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
522   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
523 }
524         
525 ///////////////////////////////////////////////////////////////////////////////
526 ///Create a new prism and add it to the mesh.
527 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
528 ///@param ID The ID of the new volume
529 ///@return The created prism
530 ///////////////////////////////////////////////////////////////////////////////
531
532 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
533                                             const SMDS_MeshNode * n2,
534                                             const SMDS_MeshNode * n3,
535                                             const SMDS_MeshNode * n4,
536                                             const SMDS_MeshNode * n5,
537                                             const SMDS_MeshNode * n6,
538                                             int ID)
539 {
540   SMDS_MeshVolume* volume;
541   if(hasConstructionFaces()) {
542     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
543     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
544     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
545     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
546     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
547     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
548     myVolumes.Add(volume);
549   }
550   else if(hasConstructionEdges()) {
551     MESSAGE("Error : Not implemented");
552     return NULL;
553   }
554   else {
555     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
556     myVolumes.Add(volume);
557   }
558
559   if (!registerElement(ID, volume)) {
560     RemoveElement(volume, false);
561     volume = NULL;
562   }
563   return volume;
564 }
565
566 ///////////////////////////////////////////////////////////////////////////////
567 ///Create a new hexahedron and add it to the mesh. 
568 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
569 ///@return The created hexahedron 
570 ///////////////////////////////////////////////////////////////////////////////
571
572 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
573                                       const SMDS_MeshNode * n2, 
574                                       const SMDS_MeshNode * n3,
575                                       const SMDS_MeshNode * n4, 
576                                       const SMDS_MeshNode * n5,
577                                       const SMDS_MeshNode * n6, 
578                                       const SMDS_MeshNode * n7,
579                                       const SMDS_MeshNode * n8)
580 {
581   int ID = myElementIDFactory->GetFreeID();
582   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
583   if(v==NULL) myElementIDFactory->ReleaseID(ID);
584   return v;
585 }
586
587 ///////////////////////////////////////////////////////////////////////////////
588 ///Create a new hexahedron and add it to the mesh. 
589 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
590 ///@param ID The ID of the new volume
591 ///@return The created hexahedron or NULL if an element with this ID already
592 ///exists or if input nodes are not found.
593 ///////////////////////////////////////////////////////////////////////////////
594
595 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
596                                              int idnode2,
597                                              int idnode3, 
598                                              int idnode4, 
599                                              int idnode5, 
600                                              int idnode6, 
601                                              int idnode7,
602                                              int idnode8, 
603                                              int ID)
604 {
605   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
606   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
607   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
608   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
609   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
610   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
611   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
612   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
613   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
614   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
615     return NULL;
616   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
617                                     node7, node8, ID);
618 }
619         
620 ///////////////////////////////////////////////////////////////////////////////
621 ///Create a new hexahedron and add it to the mesh.
622 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
623 ///@param ID The ID of the new volume
624 ///@return The created prism or NULL if an element with this ID already exists
625 ///or if input nodes are not found.
626 ///////////////////////////////////////////////////////////////////////////////
627
628 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
629                                             const SMDS_MeshNode * n2,
630                                             const SMDS_MeshNode * n3,
631                                             const SMDS_MeshNode * n4,
632                                             const SMDS_MeshNode * n5,
633                                             const SMDS_MeshNode * n6,
634                                             const SMDS_MeshNode * n7,
635                                             const SMDS_MeshNode * n8,
636                                             int ID)
637 {
638   SMDS_MeshVolume* volume;
639   if(hasConstructionFaces()) {
640     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
641     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
642     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
643     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
644     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
645     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
646     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
647     myVolumes.Add(volume);
648   }
649   else if(hasConstructionEdges()) {
650     MESSAGE("Error : Not implemented");
651     return NULL;
652   }
653   else {
654 //    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
655     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
656     myVolumes.Add(volume);
657   }
658
659   if (!registerElement(ID, volume)) {
660     RemoveElement(volume, false);
661     volume = NULL;
662   }
663   return volume;
664 }
665
666 ///////////////////////////////////////////////////////////////////////////////
667 ///Create a new tetrahedron defined by its faces and add it to the mesh.
668 ///@return The created tetrahedron
669 ///////////////////////////////////////////////////////////////////////////////
670
671 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
672                                       const SMDS_MeshFace * f2,
673                                       const SMDS_MeshFace * f3,
674                                       const SMDS_MeshFace * f4)
675 {
676   if (!hasConstructionFaces())
677     return NULL;
678   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
679 }
680
681 ///////////////////////////////////////////////////////////////////////////////
682 ///Create a new tetrahedron defined by its faces and add it to the mesh.
683 ///@param ID The ID of the new volume
684 ///@return The created tetrahedron 
685 ///////////////////////////////////////////////////////////////////////////////
686
687 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
688                                             const SMDS_MeshFace * f2,
689                                             const SMDS_MeshFace * f3,
690                                             const SMDS_MeshFace * f4,
691                                             int ID)
692 {
693   if (!hasConstructionFaces())
694     return NULL;
695   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
696   myVolumes.Add(volume);
697
698   if (!registerElement(ID, volume)) {
699     RemoveElement(volume, false);
700     volume = NULL;
701   }
702   return volume;
703 }
704
705 ///////////////////////////////////////////////////////////////////////////////
706 ///Create a new pyramid defined by its faces and add it to the mesh.
707 ///@return The created pyramid
708 ///////////////////////////////////////////////////////////////////////////////
709
710 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
711                                       const SMDS_MeshFace * f2,
712                                       const SMDS_MeshFace * f3,
713                                       const SMDS_MeshFace * f4,
714                                       const SMDS_MeshFace * f5)
715 {
716   if (!hasConstructionFaces())
717     return NULL;
718   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
719 }
720
721 ///////////////////////////////////////////////////////////////////////////////
722 ///Create a new pyramid defined by its faces and add it to the mesh.
723 ///@param ID The ID of the new volume
724 ///@return The created pyramid 
725 ///////////////////////////////////////////////////////////////////////////////
726
727 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
728                                             const SMDS_MeshFace * f2,
729                                             const SMDS_MeshFace * f3,
730                                             const SMDS_MeshFace * f4,
731                                             const SMDS_MeshFace * f5,
732                                             int ID)
733 {
734   if (!hasConstructionFaces())
735     return NULL;
736   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
737   myVolumes.Add(volume);
738
739   if (!registerElement(ID, volume)) {
740     RemoveElement(volume, false);
741     volume = NULL;
742   }
743   return volume;
744 }
745
746 ///////////////////////////////////////////////////////////////////////////////
747 ///Create a new prism defined by its faces and add it to the mesh.
748 ///@return The created prism
749 ///////////////////////////////////////////////////////////////////////////////
750
751 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
752                                       const SMDS_MeshFace * f2,
753                                       const SMDS_MeshFace * f3,
754                                       const SMDS_MeshFace * f4,
755                                       const SMDS_MeshFace * f5,
756                                       const SMDS_MeshFace * f6)
757 {
758   if (!hasConstructionFaces())
759     return NULL;
760   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
761 }
762
763 ///////////////////////////////////////////////////////////////////////////////
764 ///Create a new prism defined by its faces and add it to the mesh.
765 ///@param ID The ID of the new volume
766 ///@return The created prism 
767 ///////////////////////////////////////////////////////////////////////////////
768
769 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
770                                             const SMDS_MeshFace * f2,
771                                             const SMDS_MeshFace * f3,
772                                             const SMDS_MeshFace * f4,
773                                             const SMDS_MeshFace * f5,
774                                             const SMDS_MeshFace * f6,
775                                             int ID)
776 {
777   if (!hasConstructionFaces())
778     return NULL;
779   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
780   myVolumes.Add(volume);
781
782   if (!registerElement(ID, volume)) {
783     RemoveElement(volume, false);
784     volume = NULL;
785   }
786   return volume;
787 }
788
789 ///////////////////////////////////////////////////////////////////////////////
790 /// Registers element with the given ID, maintains inverse connections
791 ///////////////////////////////////////////////////////////////////////////////
792 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
793 {
794   if (myElementIDFactory->BindID(ID, element)) {
795     SMDS_ElemIteratorPtr it = element->nodesIterator();
796     while (it->more()) {
797       SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
798         (const_cast<SMDS_MeshElement*>(it->next()));
799       node->AddInverseElement(element);
800     }
801     return true;
802   }
803   return false;
804 }
805
806 ///////////////////////////////////////////////////////////////////////////////
807 /// Return the node whose ID is 'ID'.
808 ///////////////////////////////////////////////////////////////////////////////
809 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
810 {
811   return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
812 }
813
814 ///////////////////////////////////////////////////////////////////////////////
815 ///Create a triangle and add it to the current mesh. This methode do not bind a
816 ///ID to the create triangle.
817 ///////////////////////////////////////////////////////////////////////////////
818 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
819                                           const SMDS_MeshNode * node2,
820                                           const SMDS_MeshNode * node3)
821 {
822         if(hasConstructionEdges())
823         {
824                 SMDS_MeshEdge *edge1, *edge2, *edge3;
825                 edge1=FindEdgeOrCreate(node1,node2);
826                 edge2=FindEdgeOrCreate(node2,node3);
827                 edge3=FindEdgeOrCreate(node3,node1);
828
829                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
830                 myFaces.Add(face);
831                 return face;
832         }
833         else
834         {
835                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
836                 myFaces.Add(face);
837                 return face;
838         }
839 }
840
841 ///////////////////////////////////////////////////////////////////////////////
842 ///Create a quadrangle and add it to the current mesh. This methode do not bind
843 ///a ID to the create triangle.
844 ///////////////////////////////////////////////////////////////////////////////
845 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
846                                             const SMDS_MeshNode * node2,
847                                             const SMDS_MeshNode * node3,
848                                             const SMDS_MeshNode * node4)
849 {
850         if(hasConstructionEdges())
851         {
852                 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
853                 edge1=FindEdgeOrCreate(node1,node2);
854                 edge2=FindEdgeOrCreate(node2,node3);
855                 edge3=FindEdgeOrCreate(node3,node4);
856                 edge4=FindEdgeOrCreate(node4,node1);
857
858                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
859                 myFaces.Add(face);
860                 return face;
861         }
862         else
863         {
864                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
865                 myFaces.Add(face);
866                 return face;
867         }
868 }
869
870 ///////////////////////////////////////////////////////////////////////////////
871 /// Remove a node and all the elements which own this node
872 ///////////////////////////////////////////////////////////////////////////////
873
874 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
875 {
876         RemoveElement(node, true);
877 }
878
879 ///////////////////////////////////////////////////////////////////////////////
880 /// Remove an edge and all the elements which own this edge
881 ///////////////////////////////////////////////////////////////////////////////
882
883 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
884 {
885         RemoveElement(edge,true);
886 }
887
888 ///////////////////////////////////////////////////////////////////////////////
889 /// Remove an face and all the elements which own this face
890 ///////////////////////////////////////////////////////////////////////////////
891
892 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
893 {
894         RemoveElement(face, true);
895 }
896
897 ///////////////////////////////////////////////////////////////////////////////
898 /// Remove a volume
899 ///////////////////////////////////////////////////////////////////////////////
900
901 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
902 {
903         RemoveElement(volume, true);
904 }
905
906 //=======================================================================
907 //function : RemoveFromParent
908 //purpose  :
909 //=======================================================================
910
911 bool SMDS_Mesh::RemoveFromParent()
912 {
913         if (myParent==NULL) return false;
914         else return (myParent->RemoveSubMesh(this));
915 }
916
917 //=======================================================================
918 //function : RemoveSubMesh
919 //purpose  :
920 //=======================================================================
921
922 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
923 {
924         bool found = false;
925
926         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
927         for (; itmsh!=myChildren.end() && !found; itmsh++)
928         {
929                 SMDS_Mesh * submesh = *itmsh;
930                 if (submesh == aMesh)
931                 {
932                         found = true;
933                         myChildren.erase(itmsh);
934                 }
935         }
936
937         return found;
938 }
939
940 //=======================================================================
941 //function : ChangeElementNodes
942 //purpose  : 
943 //=======================================================================
944
945 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
946                                    const SMDS_MeshNode    * nodes[],
947                                    const int                nbnodes)
948 {
949   // keep current nodes of elem
950   set<const SMDS_MeshElement*> oldNodes;
951   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
952   while(itn->more())
953     oldNodes.insert(  itn->next() );
954
955   // change nodes
956   bool Ok = false;
957   switch ( elem->GetType() )
958   {
959   case SMDSAbs_Edge: {
960     if ( nbnodes == 2 ) {
961       const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
962       if ( edge )
963         Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
964     }
965     break;
966   }
967   case SMDSAbs_Face: {
968     const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
969     if ( face )
970       Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
971     break;
972   }
973   case SMDSAbs_Volume: {
974     const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
975     if ( vol )
976       Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
977     break;
978   }
979   default:
980     MESSAGE ( "WRONG ELEM TYPE");
981   }
982
983   if ( Ok ) { // update InverseElements
984
985     // AddInverseElement to new nodes
986     for ( int i = 0; i < nbnodes; i++ )
987       if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
988         // new node
989         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
990       else
991         // remove from oldNodes a node that remains in elem
992         oldNodes.erase( nodes[i] );
993
994
995     // RemoveInverseElement from the nodes removed from elem
996     set<const SMDS_MeshElement*>::iterator it;
997     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
998     {
999       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1000         (const_cast<SMDS_MeshElement *>( *it ));
1001       n->RemoveInverseElement( elem );
1002     }
1003   }
1004
1005   //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1006
1007   return Ok;
1008 }
1009
1010 //=======================================================================
1011 //function : FindEdge
1012 //purpose  :
1013 //=======================================================================
1014
1015 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1016 {
1017         const SMDS_MeshNode * node1=FindNode(idnode1);
1018         const SMDS_MeshNode * node2=FindNode(idnode2);
1019         if((node1==NULL)||(node2==NULL)) return NULL;
1020         return FindEdge(node1,node2);
1021 }
1022
1023 //#include "Profiler.h"
1024 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1025                                          const SMDS_MeshNode * node2)
1026 {
1027         const SMDS_MeshEdge * toReturn=NULL;
1028         //PROFILER_Init();
1029         //PROFILER_Set();
1030         SMDS_ElemIteratorPtr it1=node1->edgesIterator();
1031         //PROFILER_Get(0);
1032         //PROFILER_Set();
1033         while(it1->more())
1034         {
1035                 const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
1036                         (it1->next());
1037                 SMDS_ElemIteratorPtr it2=e->nodesIterator();
1038                 while(it2->more())
1039                 {
1040                         if(it2->next()->GetID()==node2->GetID())
1041                         {
1042                                 toReturn=e;
1043                                 break;
1044                         }
1045                 }
1046         }
1047         //PROFILER_Get(1);
1048         return toReturn;
1049 }
1050
1051
1052 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1053         const SMDS_MeshNode * node2) 
1054 {
1055         SMDS_MeshEdge * toReturn=NULL;
1056         toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1057         if(toReturn==NULL)      
1058         {
1059           toReturn=new SMDS_MeshEdge(node1,node2);
1060           myEdges.Add(toReturn);
1061         } 
1062         return toReturn;
1063 }
1064
1065 //=======================================================================
1066 //function : FindFace
1067 //purpose  :
1068 //=======================================================================
1069
1070 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1071         int idnode3) const
1072 {
1073         const SMDS_MeshNode * node1=FindNode(idnode1);
1074         const SMDS_MeshNode * node2=FindNode(idnode2);
1075         const SMDS_MeshNode * node3=FindNode(idnode3);
1076         if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
1077         return FindFace(node1, node2, node3);
1078 }
1079
1080 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1081                 const SMDS_MeshNode *node1,
1082                 const SMDS_MeshNode *node2,
1083                 const SMDS_MeshNode *node3)
1084 {
1085         const SMDS_MeshFace * face;
1086         const SMDS_MeshElement * node;
1087         bool node2found, node3found;
1088
1089         SMDS_ElemIteratorPtr it1=node1->facesIterator();
1090         while(it1->more())
1091         {
1092                 face=static_cast<const SMDS_MeshFace*>(it1->next());
1093                 if(face->NbNodes()!=3) continue;
1094                 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1095                 node2found=false;
1096                 node3found=false;
1097                 while(it2->more())
1098                 {
1099                         node=it2->next();
1100                         if(node->GetID()==node2->GetID()) node2found=true;
1101                         if(node->GetID()==node3->GetID()) node3found=true;
1102                 }
1103                 if(node2found&&node3found)
1104                         return face;
1105         }
1106         return NULL;
1107 }
1108
1109 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1110                 const SMDS_MeshNode *node1,
1111                 const SMDS_MeshNode *node2,
1112                 const SMDS_MeshNode *node3)
1113 {
1114         SMDS_MeshFace * toReturn=NULL;
1115         toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1116         if(toReturn==NULL)
1117         {
1118           toReturn=createTriangle(node1,node2,node3);
1119         }
1120         return toReturn;
1121 }
1122
1123 //=======================================================================
1124 //function : FindFace
1125 //purpose  :
1126 //=======================================================================
1127
1128 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
1129         int idnode4) const
1130 {
1131         const SMDS_MeshNode * node1=FindNode(idnode1);
1132         const SMDS_MeshNode * node2=FindNode(idnode2);
1133         const SMDS_MeshNode * node3=FindNode(idnode3);
1134         const SMDS_MeshNode * node4=FindNode(idnode4);
1135         if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
1136         return FindFace(node1, node2, node3, node4);
1137 }
1138
1139 const SMDS_MeshFace* SMDS_Mesh::FindFace(
1140                 const SMDS_MeshNode *node1,
1141                 const SMDS_MeshNode *node2,
1142                 const SMDS_MeshNode *node3,
1143                 const SMDS_MeshNode *node4)
1144 {
1145         const SMDS_MeshFace * face;
1146         const SMDS_MeshElement * node;
1147         bool node2found, node3found, node4found;
1148         SMDS_ElemIteratorPtr it1=node1->facesIterator();
1149         while(it1->more())
1150         {
1151                 face=static_cast<const SMDS_MeshFace *>(it1->next());
1152                 if(face->NbNodes()!=4) continue;
1153                 SMDS_ElemIteratorPtr it2=face->nodesIterator();
1154                 node2found=false;
1155                 node3found=false;
1156                 node4found=false;
1157                 while(it2->more())
1158                 {
1159                         node=it2->next();
1160                         if(node->GetID()==node2->GetID()) node2found=true;
1161                         if(node->GetID()==node3->GetID()) node3found=true;
1162                         if(node->GetID()==node4->GetID()) node4found=true;
1163                 }
1164                 if(node2found&&node3found&&node4found)
1165                         return face;
1166         }
1167         return NULL;
1168 }
1169
1170 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
1171                 const SMDS_MeshNode *node1,
1172                 const SMDS_MeshNode *node2,
1173                 const SMDS_MeshNode *node3,
1174                 const SMDS_MeshNode *node4)
1175 {
1176         SMDS_MeshFace * toReturn=NULL;
1177         toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1178         if(toReturn==NULL)
1179         {
1180           toReturn=createQuadrangle(node1,node2,node3,node4);
1181         }
1182         return toReturn;
1183 }
1184
1185 //=======================================================================
1186 //function : FindElement
1187 //purpose  :
1188 //=======================================================================
1189
1190 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1191 {
1192         return myElementIDFactory->MeshElement(IDelem);
1193 }
1194
1195 //=======================================================================
1196 //function : DumpNodes
1197 //purpose  : 
1198 //=======================================================================
1199
1200 void SMDS_Mesh::DumpNodes() const
1201 {
1202         MESSAGE("dump nodes of mesh : ");
1203         SMDS_NodeIteratorPtr itnode=nodesIterator();
1204         while(itnode->more()) MESSAGE(itnode->next());
1205 }
1206
1207 //=======================================================================
1208 //function : DumpEdges
1209 //purpose  : 
1210 //=======================================================================
1211
1212 void SMDS_Mesh::DumpEdges() const
1213 {
1214         MESSAGE("dump edges of mesh : ");
1215         SMDS_EdgeIteratorPtr itedge=edgesIterator();
1216         while(itedge->more()) MESSAGE(itedge->next());
1217 }
1218
1219 //=======================================================================
1220 //function : DumpFaces
1221 //purpose  : 
1222 //=======================================================================
1223
1224 void SMDS_Mesh::DumpFaces() const
1225 {
1226         MESSAGE("dump faces of mesh : ");
1227         SMDS_FaceIteratorPtr itface=facesIterator();
1228         while(itface->more()) MESSAGE(itface->next());
1229 }
1230
1231 //=======================================================================
1232 //function : DumpVolumes
1233 //purpose  : 
1234 //=======================================================================
1235
1236 void SMDS_Mesh::DumpVolumes() const
1237 {
1238         MESSAGE("dump volumes of mesh : ");
1239         SMDS_VolumeIteratorPtr itvol=volumesIterator();
1240         while(itvol->more()) MESSAGE(itvol->next());
1241 }
1242
1243 //=======================================================================
1244 //function : DebugStats
1245 //purpose  : 
1246 //=======================================================================
1247
1248 void SMDS_Mesh::DebugStats() const
1249 {
1250         MESSAGE("Debug stats of mesh : ");
1251
1252         MESSAGE("===== NODES ====="<<NbNodes());
1253         MESSAGE("===== EDGES ====="<<NbEdges());
1254         MESSAGE("===== FACES ====="<<NbFaces());
1255         MESSAGE("===== VOLUMES ====="<<NbVolumes());
1256
1257         MESSAGE("End Debug stats of mesh ");
1258
1259         //#ifdef DEB
1260         
1261         SMDS_NodeIteratorPtr itnode=nodesIterator();
1262         int sizeofnodes = 0;
1263         int sizeoffaces = 0;
1264
1265         while(itnode->more())
1266         {
1267                 const SMDS_MeshNode *node = itnode->next();
1268
1269                 sizeofnodes += sizeof(*node);
1270                 
1271                 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1272                 while(it->more())
1273                 {
1274                         const SMDS_MeshElement *me = it->next();
1275                         sizeofnodes += sizeof(me);
1276                 }
1277
1278         }
1279
1280         SMDS_FaceIteratorPtr itface=facesIterator();
1281         while(itface->more())
1282         {
1283                 const SMDS_MeshElement *face = itface->next();          
1284                 sizeoffaces += sizeof(*face);
1285
1286         }
1287         MESSAGE("total size of node elements = " << sizeofnodes);;
1288         MESSAGE("total size of face elements = " << sizeoffaces);;
1289
1290         //#endif
1291 }
1292
1293 ///////////////////////////////////////////////////////////////////////////////
1294 /// Return the number of nodes
1295 ///////////////////////////////////////////////////////////////////////////////
1296 int SMDS_Mesh::NbNodes() const
1297 {
1298         return myNodes.Size();
1299 }
1300
1301 ///////////////////////////////////////////////////////////////////////////////
1302 /// Return the number of edges (including construction edges)
1303 ///////////////////////////////////////////////////////////////////////////////
1304 int SMDS_Mesh::NbEdges() const
1305 {
1306         return myEdges.Size();
1307 }
1308
1309 ///////////////////////////////////////////////////////////////////////////////
1310 /// Return the number of faces (including construction faces)
1311 ///////////////////////////////////////////////////////////////////////////////
1312 int SMDS_Mesh::NbFaces() const
1313 {
1314         return myFaces.Size();
1315 }
1316
1317 ///////////////////////////////////////////////////////////////////////////////
1318 /// Return the number of volumes
1319 ///////////////////////////////////////////////////////////////////////////////
1320 int SMDS_Mesh::NbVolumes() const
1321 {
1322         return myVolumes.Size();
1323 }
1324
1325 ///////////////////////////////////////////////////////////////////////////////
1326 /// Return the number of child mesh of this mesh.
1327 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1328 /// (2003-09-08) of SMESH
1329 ///////////////////////////////////////////////////////////////////////////////
1330 int SMDS_Mesh::NbSubMesh() const
1331 {
1332         return myChildren.size();
1333 }
1334
1335 ///////////////////////////////////////////////////////////////////////////////
1336 /// Destroy the mesh and all its elements
1337 /// All pointer on elements owned by this mesh become illegals.
1338 ///////////////////////////////////////////////////////////////////////////////
1339 SMDS_Mesh::~SMDS_Mesh()
1340 {
1341   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1342   while(itc!=myChildren.end())
1343   {
1344     delete *itc;
1345     itc++;
1346   }
1347
1348   SetOfNodes::Iterator itn(myNodes);
1349   for (; itn.More(); itn.Next())
1350     delete itn.Value();
1351
1352   SetOfEdges::Iterator ite(myEdges);
1353   for (; ite.More(); ite.Next())
1354   {
1355     SMDS_MeshElement* elem = ite.Value();
1356     if(myParent!=NULL)
1357       myElementIDFactory->ReleaseID(elem->GetID());
1358     delete elem;
1359   }
1360
1361   SetOfFaces::Iterator itf(myFaces);
1362   for (; itf.More(); itf.Next())
1363   {
1364     SMDS_MeshElement* elem = itf.Value();
1365     if(myParent!=NULL)
1366       myElementIDFactory->ReleaseID(elem->GetID());
1367     delete elem;
1368   }
1369
1370   SetOfVolumes::Iterator itv(myVolumes);
1371   for (; itv.More(); itv.Next())
1372   {
1373     SMDS_MeshElement* elem = itv.Value();
1374     if(myParent!=NULL)
1375       myElementIDFactory->ReleaseID(elem->GetID());
1376     delete elem;
1377   }
1378
1379   if(myParent==NULL)
1380   {
1381     delete myNodeIDFactory;
1382     delete myElementIDFactory;
1383   }
1384 }
1385
1386 ///////////////////////////////////////////////////////////////////////////////
1387 /// Return true if this mesh create faces with edges.
1388 /// A false returned value mean that faces are created with nodes. A concequence
1389 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1390 ///////////////////////////////////////////////////////////////////////////////
1391 bool SMDS_Mesh::hasConstructionEdges()
1392 {
1393         return myHasConstructionEdges;
1394 }
1395
1396 ///////////////////////////////////////////////////////////////////////////////
1397 /// Return true if this mesh create volumes with faces
1398 /// A false returned value mean that volumes are created with nodes or edges.
1399 /// (see hasConstructionEdges)
1400 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1401 /// unavailable.
1402 ///////////////////////////////////////////////////////////////////////////////
1403 bool SMDS_Mesh::hasConstructionFaces()
1404 {
1405         return myHasConstructionFaces;
1406 }
1407
1408 ///////////////////////////////////////////////////////////////////////////////
1409 /// Return true if nodes are linked to the finit elements, they are belonging to.
1410 /// Currently, It always return true.
1411 ///////////////////////////////////////////////////////////////////////////////
1412 bool SMDS_Mesh::hasInverseElements()
1413 {
1414         return myHasInverseElements;
1415 }
1416
1417 ///////////////////////////////////////////////////////////////////////////////
1418 /// Make this mesh creating construction edges (see hasConstructionEdges)
1419 /// @param b true to have construction edges, else false.
1420 ///////////////////////////////////////////////////////////////////////////////
1421 void SMDS_Mesh::setConstructionEdges(bool b)
1422 {
1423         myHasConstructionEdges=b;
1424 }
1425
1426 ///////////////////////////////////////////////////////////////////////////////
1427 /// Make this mesh creating construction faces (see hasConstructionFaces)
1428 /// @param b true to have construction faces, else false.
1429 ///////////////////////////////////////////////////////////////////////////////
1430 void SMDS_Mesh::setConstructionFaces(bool b)
1431 {
1432          myHasConstructionFaces=b;
1433 }
1434
1435 ///////////////////////////////////////////////////////////////////////////////
1436 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1437 /// @param b true to link nodes to elements, else false.
1438 ///////////////////////////////////////////////////////////////////////////////
1439 void SMDS_Mesh::setInverseElements(bool b)
1440 {
1441         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1442         myHasInverseElements=b;
1443 }
1444
1445 ///////////////////////////////////////////////////////////////////////////////
1446 /// Return an iterator on nodes of the current mesh factory
1447 ///////////////////////////////////////////////////////////////////////////////
1448 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1449 {
1450   SMDS_ElemIteratorPtr myIterator;
1451  public:
1452   SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1453   {}
1454
1455   bool more()
1456   {
1457     return myIterator->more();
1458   }
1459
1460   const SMDS_MeshNode* next()
1461   {
1462     return static_cast<const SMDS_MeshNode*>(myIterator->next());
1463   }
1464 };
1465
1466 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1467 {
1468   return SMDS_NodeIteratorPtr
1469     (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1470 }
1471
1472 ///////////////////////////////////////////////////////////////////////////////
1473 /// Return an iterator on elements of the current mesh factory
1474 ///////////////////////////////////////////////////////////////////////////////
1475 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1476 {
1477   return myElementIDFactory->elementsIterator();
1478 }
1479
1480 ///////////////////////////////////////////////////////////////////////////////
1481 ///Return an iterator on edges of the current mesh.
1482 ///////////////////////////////////////////////////////////////////////////////
1483 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1484 {
1485   typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1486   SetOfEdges::Iterator myIterator;
1487  public:
1488   SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1489   {}
1490
1491   bool more()
1492   {
1493     while(myIterator.More())
1494     {
1495       if(myIterator.Value()->GetID()!=-1)
1496         return true;
1497       myIterator.Next();
1498     }
1499     return false;
1500   }
1501
1502   const SMDS_MeshEdge* next()
1503   {
1504     const SMDS_MeshEdge* current = myIterator.Value();
1505     myIterator.Next();
1506     return current;
1507   }
1508 };
1509
1510 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1511 {
1512   return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1513 }
1514
1515 ///////////////////////////////////////////////////////////////////////////////
1516 ///Return an iterator on faces of the current mesh.
1517 ///////////////////////////////////////////////////////////////////////////////
1518 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1519 {
1520   typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1521   SetOfFaces::Iterator myIterator;
1522  public:
1523   SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
1524   {}
1525
1526   bool more()
1527   {
1528     while(myIterator.More())
1529     {
1530       if(myIterator.Value()->GetID()!=-1)
1531         return true;
1532       myIterator.Next();
1533     }
1534     return false;
1535   }
1536
1537   const SMDS_MeshFace* next()
1538   {
1539     const SMDS_MeshFace* current = myIterator.Value();
1540     myIterator.Next();
1541     return current;
1542   }
1543 };
1544
1545 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
1546 {
1547   return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
1548 }
1549
1550 ///////////////////////////////////////////////////////////////////////////////
1551 ///Return an iterator on volumes of the current mesh.
1552 ///////////////////////////////////////////////////////////////////////////////
1553 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
1554 {
1555   typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
1556   SetOfVolumes::Iterator myIterator;
1557  public:
1558   SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
1559   {}
1560
1561   bool more()
1562   {
1563     return myIterator.More() != Standard_False;
1564   }
1565
1566   const SMDS_MeshVolume* next()
1567   {
1568     const SMDS_MeshVolume* current = myIterator.Value();
1569     myIterator.Next();
1570     return current;
1571   }
1572 };
1573
1574 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
1575 {
1576   return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
1577 }
1578
1579 ///////////////////////////////////////////////////////////////////////////////
1580 /// Do intersection of sets (more than 2)
1581 ///////////////////////////////////////////////////////////////////////////////
1582 static set<const SMDS_MeshElement*> * intersectionOfSets(
1583         set<const SMDS_MeshElement*> vs[], int numberOfSets)
1584 {
1585         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
1586         set<const SMDS_MeshElement*>* rsetB;
1587
1588         for(int i=0; i<numberOfSets-1; i++)
1589         {
1590                 rsetB=new set<const SMDS_MeshElement*>();
1591                 set_intersection(
1592                         rsetA->begin(), rsetA->end(),
1593                         vs[i+1].begin(), vs[i+1].end(),
1594                         inserter(*rsetB, rsetB->begin()));
1595                 delete rsetA;
1596                 rsetA=rsetB;
1597         }
1598         return rsetA;
1599 }
1600
1601 ///////////////////////////////////////////////////////////////////////////////
1602 /// Return the list of finit elements owning the given element
1603 ///////////////////////////////////////////////////////////////////////////////
1604 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
1605 {
1606         int numberOfSets=element->NbNodes();
1607         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
1608
1609         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1610
1611         int i=0;
1612         while(itNodes->more())
1613         {
1614                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1615                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1616
1617                 //initSet[i]=set<const SMDS_MeshElement*>();
1618                 while(itFe->more())
1619                   initSet[i].insert(itFe->next());
1620
1621                 i++;
1622         }
1623         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
1624         delete [] initSet;
1625         return retSet;
1626 }
1627
1628 ///////////////////////////////////////////////////////////////////////////////
1629 /// Return the list of nodes used only by the given elements
1630 ///////////////////////////////////////////////////////////////////////////////
1631 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1632         set<const SMDS_MeshElement*>& elements)
1633 {
1634         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1635         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1636
1637         while(itElements!=elements.end())
1638         {
1639                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
1640                 itElements++;
1641         
1642                 while(itNodes->more())
1643                 {
1644                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1645                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1646                         set<const SMDS_MeshElement*> s;
1647                         while(itFe->more())
1648                           s.insert(itFe->next());
1649                         if(s==elements) toReturn->insert(n);
1650                 }
1651         }
1652         return toReturn;        
1653 }
1654
1655 ///////////////////////////////////////////////////////////////////////////////
1656 ///Find the children of an element that are made of given nodes 
1657 ///@param setOfChildren The set in which matching children will be inserted
1658 ///@param element The element were to search matching children
1659 ///@param nodes The nodes that the children must have to be selected
1660 ///////////////////////////////////////////////////////////////////////////////
1661 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren, 
1662         const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1663 {
1664         
1665         switch(element->GetType())
1666         {
1667         case SMDSAbs_Node:
1668                 MESSAGE("Internal Error: This should not append");
1669                 break;
1670         case SMDSAbs_Edge:
1671         {
1672                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1673                 while(itn->more())
1674                 {
1675                         const SMDS_MeshElement * e=itn->next();
1676                         if(nodes.find(e)!=nodes.end())
1677                         {
1678                           setOfChildren.insert(element);
1679                           break;
1680                         }
1681                 }
1682         } break;
1683         case SMDSAbs_Face:
1684         {
1685                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1686                 while(itn->more())
1687                 {
1688                         const SMDS_MeshElement * e=itn->next();
1689                         if(nodes.find(e)!=nodes.end())
1690                         {
1691                           setOfChildren.insert(element);
1692                           break;
1693                         }
1694                 }
1695                 if(hasConstructionEdges())
1696                 {
1697                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
1698                         while(ite->more())
1699                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1700                 }
1701         } break;        
1702         case SMDSAbs_Volume:
1703         {
1704                 if(hasConstructionFaces())
1705                 {
1706                         SMDS_ElemIteratorPtr ite=element->facesIterator();
1707                         while(ite->more())
1708                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1709                 }
1710                 else if(hasConstructionEdges())
1711                 {
1712                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
1713                         while(ite->more())
1714                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1715                 }
1716         }
1717         }
1718 }
1719
1720 ///////////////////////////////////////////////////////////////////////////////
1721 ///@param elem The element to delete
1722 ///@param removenodes if true remaining nodes will be removed
1723 ///////////////////////////////////////////////////////////////////////////////
1724 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1725         const bool removenodes)
1726 {
1727   list<const SMDS_MeshElement *> removedElems;
1728   list<const SMDS_MeshElement *> removedNodes;
1729   RemoveElement( elem, removedElems, removedNodes, removenodes );
1730 }
1731   
1732 ///////////////////////////////////////////////////////////////////////////////
1733 ///@param elem The element to delete
1734 ///@param removedElems contains all removed elements
1735 ///@param removedNodes contains all removed nodes
1736 ///@param removenodes if true remaining nodes will be removed
1737 ///////////////////////////////////////////////////////////////////////////////
1738 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
1739                               list<const SMDS_MeshElement *>& removedElems,
1740                               list<const SMDS_MeshElement *>& removedNodes,
1741                               bool                            removenodes)
1742 {
1743   // get finite elements built on elem
1744   set<const SMDS_MeshElement*> * s1;
1745   if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
1746       !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
1747   {
1748     s1 = new set<const SMDS_MeshElement*>();
1749     s1->insert(elem);
1750   }
1751   else
1752     s1 = getFinitElements(elem);
1753
1754   // get exclusive nodes (which would become free afterwards)
1755   set<const SMDS_MeshElement*> * s2;
1756   if (elem->GetType() == SMDSAbs_Node) // a node is removed
1757   {
1758     // do not remove nodes except elem
1759     s2 = new set<const SMDS_MeshElement*>();
1760     s2->insert(elem);
1761     removenodes = true;
1762   }
1763   else
1764     s2 = getExclusiveNodes(*s1);
1765
1766   // form the set of finite and construction elements to remove
1767   set<const SMDS_MeshElement*> s3;
1768   set<const SMDS_MeshElement*>::iterator it=s1->begin();
1769   while(it!=s1->end())
1770   {
1771     addChildrenWithNodes(s3, *it ,*s2);
1772     s3.insert(*it);
1773     it++;
1774   }
1775   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1776
1777   // remove finite and construction elements
1778   it=s3.begin();
1779   while(it!=s3.end())
1780   {
1781     // Remove element from <InverseElements> of its nodes
1782     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
1783     while(itn->more())
1784     {
1785       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1786         (const_cast<SMDS_MeshElement *>(itn->next()));
1787       n->RemoveInverseElement( (*it) );
1788     }
1789
1790     switch((*it)->GetType())
1791     {
1792     case SMDSAbs_Node:
1793       MESSAGE("Internal Error: This should not happen");
1794       break;
1795     case SMDSAbs_Edge:
1796       myEdges.Remove(static_cast<SMDS_MeshEdge*>
1797                     (const_cast<SMDS_MeshElement*>(*it)));
1798       break;
1799     case SMDSAbs_Face:
1800       myFaces.Remove(static_cast<SMDS_MeshFace*>
1801                     (const_cast<SMDS_MeshElement*>(*it)));
1802       break;
1803     case SMDSAbs_Volume:
1804       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
1805                       (const_cast<SMDS_MeshElement*>(*it)));
1806       break;
1807     }
1808     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
1809     removedElems.push_back( (*it) );
1810     myElementIDFactory->ReleaseID((*it)->GetID());
1811     delete (*it);
1812     it++;
1813   }
1814
1815   // remove exclusive (free) nodes
1816   if(removenodes)
1817   {
1818     it=s2->begin();
1819     while(it!=s2->end())
1820     {
1821       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
1822       myNodes.Remove(static_cast<SMDS_MeshNode*>
1823                     (const_cast<SMDS_MeshElement*>(*it)));
1824       myNodeIDFactory->ReleaseID((*it)->GetID());
1825       removedNodes.push_back( (*it) );
1826       delete *it;
1827       it++;
1828     }
1829   }
1830
1831   delete s2;
1832   delete s1;
1833 }
1834
1835 /*!
1836  * Checks if the element is present in mesh.
1837  * Useful to determine dead pointers.
1838  */
1839 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1840 {
1841   // we should not imply on validity of *elem, so iterate on containers
1842   // of all types in the hope of finding <elem> somewhere there
1843   SMDS_NodeIteratorPtr itn = nodesIterator();
1844   while (itn->more())
1845     if (elem == itn->next())
1846       return true;
1847   SMDS_EdgeIteratorPtr ite = edgesIterator();
1848   while (ite->more())
1849     if (elem == ite->next())
1850       return true;
1851   SMDS_FaceIteratorPtr itf = facesIterator();
1852   while (itf->more())
1853     if (elem == itf->next())
1854       return true;
1855   SMDS_VolumeIteratorPtr itv = volumesIterator();
1856   while (itv->more())
1857     if (elem == itv->next())
1858       return true;
1859   return false;
1860 }
1861
1862 //=======================================================================
1863 //function : MaxNodeID
1864 //purpose  : 
1865 //=======================================================================
1866
1867 int SMDS_Mesh::MaxNodeID() const
1868 {
1869   return myNodeIDFactory->GetMaxID();
1870 }
1871
1872 //=======================================================================
1873 //function : MinNodeID
1874 //purpose  : 
1875 //=======================================================================
1876
1877 int SMDS_Mesh::MinNodeID() const
1878 {
1879   return myNodeIDFactory->GetMinID();
1880 }
1881
1882 //=======================================================================
1883 //function : MaxElementID
1884 //purpose  : 
1885 //=======================================================================
1886
1887 int SMDS_Mesh::MaxElementID() const
1888 {
1889   return myElementIDFactory->GetMaxID();
1890 }
1891
1892 //=======================================================================
1893 //function : MinElementID
1894 //purpose  : 
1895 //=======================================================================
1896
1897 int SMDS_Mesh::MinElementID() const
1898 {
1899   return myElementIDFactory->GetMinID();
1900 }
1901
1902 //=======================================================================
1903 //function : Renumber
1904 //purpose  : Renumber all nodes or elements.
1905 //=======================================================================
1906
1907 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
1908 {
1909   if ( deltaID == 0 )
1910     return;
1911
1912   SMDS_MeshElementIDFactory * idFactory =
1913     isNodes ? myNodeIDFactory : myElementIDFactory;
1914
1915   // get existing elements in the order of ID increasing
1916   map<int,SMDS_MeshElement*> elemMap;
1917   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
1918   while ( idElemIt->more() ) {
1919     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
1920     int id = elem->GetID();
1921     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
1922   }
1923   // release their ids
1924   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
1925   for ( ; elemIt != elemMap.end(); elemIt++ )
1926   {
1927     int id = (*elemIt).first;
1928     idFactory->ReleaseID( id );
1929   }
1930   // set new IDs
1931   int ID = startID;
1932   elemIt = elemMap.begin();
1933   for ( ; elemIt != elemMap.end(); elemIt++ )
1934   {
1935     idFactory->BindID( ID, (*elemIt).second );
1936     ID += deltaID;
1937   }
1938 }
1939