Salome HOME
Merge with OCC_development_01
[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         auto_ptr<set<const SMDS_MeshElement*> > pInitSet
1608           (new set<const SMDS_MeshElement*>[numberOfSets]);
1609         set<const SMDS_MeshElement*> *initSet = &(*pInitSet);
1610
1611         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
1612
1613         int i=0;
1614         while(itNodes->more())
1615         {
1616                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1617                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1618
1619                 //initSet[i]=set<const SMDS_MeshElement*>();
1620                 while(itFe->more())
1621                   initSet[i].insert(itFe->next());
1622
1623                 i++;
1624         }
1625         
1626         return intersectionOfSets(initSet, numberOfSets);
1627 }
1628
1629 ///////////////////////////////////////////////////////////////////////////////
1630 /// Return the list of nodes used only by the given elements
1631 ///////////////////////////////////////////////////////////////////////////////
1632 static set<const SMDS_MeshElement*> * getExclusiveNodes(
1633         set<const SMDS_MeshElement*>& elements)
1634 {
1635         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
1636         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
1637
1638         while(itElements!=elements.end())
1639         {
1640                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
1641                 itElements++;
1642         
1643                 while(itNodes->more())
1644                 {
1645                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
1646                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
1647                         set<const SMDS_MeshElement*> s;
1648                         while(itFe->more())
1649                           s.insert(itFe->next());
1650                         if(s==elements) toReturn->insert(n);
1651                 }
1652         }
1653         return toReturn;        
1654 }
1655
1656 ///////////////////////////////////////////////////////////////////////////////
1657 ///Find the children of an element that are made of given nodes 
1658 ///@param setOfChildren The set in which matching children will be inserted
1659 ///@param element The element were to search matching children
1660 ///@param nodes The nodes that the children must have to be selected
1661 ///////////////////////////////////////////////////////////////////////////////
1662 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren, 
1663         const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
1664 {
1665         
1666         switch(element->GetType())
1667         {
1668         case SMDSAbs_Node:
1669                 MESSAGE("Internal Error: This should not append");
1670                 break;
1671         case SMDSAbs_Edge:
1672         {
1673                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1674                 while(itn->more())
1675                 {
1676                         const SMDS_MeshElement * e=itn->next();
1677                         if(nodes.find(e)!=nodes.end())
1678                         {
1679                           setOfChildren.insert(element);
1680                           break;
1681                         }
1682                 }
1683         } break;
1684         case SMDSAbs_Face:
1685         {
1686                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
1687                 while(itn->more())
1688                 {
1689                         const SMDS_MeshElement * e=itn->next();
1690                         if(nodes.find(e)!=nodes.end())
1691                         {
1692                           setOfChildren.insert(element);
1693                           break;
1694                         }
1695                 }
1696                 if(hasConstructionEdges())
1697                 {
1698                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
1699                         while(ite->more())
1700                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1701                 }
1702         } break;        
1703         case SMDSAbs_Volume:
1704         {
1705                 if(hasConstructionFaces())
1706                 {
1707                         SMDS_ElemIteratorPtr ite=element->facesIterator();
1708                         while(ite->more())
1709                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1710                 }
1711                 else if(hasConstructionEdges())
1712                 {
1713                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
1714                         while(ite->more())
1715                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
1716                 }
1717         }
1718         }
1719 }
1720
1721 ///////////////////////////////////////////////////////////////////////////////
1722 ///@param elem The element to delete
1723 ///@param removenodes if true remaining nodes will be removed
1724 ///////////////////////////////////////////////////////////////////////////////
1725 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
1726         const bool removenodes)
1727 {
1728   list<const SMDS_MeshElement *> removedElems;
1729   list<const SMDS_MeshElement *> removedNodes;
1730   RemoveElement( elem, removedElems, removedNodes, removenodes );
1731 }
1732   
1733 ///////////////////////////////////////////////////////////////////////////////
1734 ///@param elem The element to delete
1735 ///@param removedElems contains all removed elements
1736 ///@param removedNodes contains all removed nodes
1737 ///@param removenodes if true remaining nodes will be removed
1738 ///////////////////////////////////////////////////////////////////////////////
1739 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
1740                               list<const SMDS_MeshElement *>& removedElems,
1741                               list<const SMDS_MeshElement *>& removedNodes,
1742                               bool                            removenodes)
1743 {
1744   // get finite elements built on elem
1745   set<const SMDS_MeshElement*> * s1;
1746   if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
1747       !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
1748   {
1749     s1 = new set<const SMDS_MeshElement*>();
1750     s1->insert(elem);
1751   }
1752   else
1753     s1 = getFinitElements(elem);
1754
1755   // get exclusive nodes (which would become free afterwards)
1756   set<const SMDS_MeshElement*> * s2;
1757   if (elem->GetType() == SMDSAbs_Node) // a node is removed
1758   {
1759     // do not remove nodes except elem
1760     s2 = new set<const SMDS_MeshElement*>();
1761     s2->insert(elem);
1762     removenodes = true;
1763   }
1764   else
1765     s2 = getExclusiveNodes(*s1);
1766
1767   // form the set of finite and construction elements to remove
1768   set<const SMDS_MeshElement*> s3;
1769   set<const SMDS_MeshElement*>::iterator it=s1->begin();
1770   while(it!=s1->end())
1771   {
1772     addChildrenWithNodes(s3, *it ,*s2);
1773     s3.insert(*it);
1774     it++;
1775   }
1776   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
1777
1778   // remove finite and construction elements
1779   it=s3.begin();
1780   while(it!=s3.end())
1781   {
1782     // Remove element from <InverseElements> of its nodes
1783     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
1784     while(itn->more())
1785     {
1786       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1787         (const_cast<SMDS_MeshElement *>(itn->next()));
1788       n->RemoveInverseElement( (*it) );
1789     }
1790
1791     switch((*it)->GetType())
1792     {
1793     case SMDSAbs_Node:
1794       MESSAGE("Internal Error: This should not happen");
1795       break;
1796     case SMDSAbs_Edge:
1797       myEdges.Remove(static_cast<SMDS_MeshEdge*>
1798                     (const_cast<SMDS_MeshElement*>(*it)));
1799       break;
1800     case SMDSAbs_Face:
1801       myFaces.Remove(static_cast<SMDS_MeshFace*>
1802                     (const_cast<SMDS_MeshElement*>(*it)));
1803       break;
1804     case SMDSAbs_Volume:
1805       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
1806                       (const_cast<SMDS_MeshElement*>(*it)));
1807       break;
1808     }
1809     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
1810     removedElems.push_back( (*it) );
1811     myElementIDFactory->ReleaseID((*it)->GetID());
1812     delete (*it);
1813     it++;
1814   }
1815
1816   // remove exclusive (free) nodes
1817   if(removenodes)
1818   {
1819     it=s2->begin();
1820     while(it!=s2->end())
1821     {
1822       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
1823       myNodes.Remove(static_cast<SMDS_MeshNode*>
1824                     (const_cast<SMDS_MeshElement*>(*it)));
1825       myNodeIDFactory->ReleaseID((*it)->GetID());
1826       removedNodes.push_back( (*it) );
1827       delete *it;
1828       it++;
1829     }
1830   }
1831
1832   delete s2;
1833   delete s1;
1834 }
1835
1836 /*!
1837  * Checks if the element is present in mesh.
1838  * Useful to determine dead pointers.
1839  */
1840 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
1841 {
1842   // we should not imply on validity of *elem, so iterate on containers
1843   // of all types in the hope of finding <elem> somewhere there
1844   SMDS_NodeIteratorPtr itn = nodesIterator();
1845   while (itn->more())
1846     if (elem == itn->next())
1847       return true;
1848   SMDS_EdgeIteratorPtr ite = edgesIterator();
1849   while (ite->more())
1850     if (elem == ite->next())
1851       return true;
1852   SMDS_FaceIteratorPtr itf = facesIterator();
1853   while (itf->more())
1854     if (elem == itf->next())
1855       return true;
1856   SMDS_VolumeIteratorPtr itv = volumesIterator();
1857   while (itv->more())
1858     if (elem == itv->next())
1859       return true;
1860   return false;
1861 }
1862
1863 //=======================================================================
1864 //function : MaxNodeID
1865 //purpose  : 
1866 //=======================================================================
1867
1868 int SMDS_Mesh::MaxNodeID() const
1869 {
1870   return myNodeIDFactory->GetMaxID();
1871 }
1872
1873 //=======================================================================
1874 //function : MinNodeID
1875 //purpose  : 
1876 //=======================================================================
1877
1878 int SMDS_Mesh::MinNodeID() const
1879 {
1880   return myNodeIDFactory->GetMinID();
1881 }
1882
1883 //=======================================================================
1884 //function : MaxElementID
1885 //purpose  : 
1886 //=======================================================================
1887
1888 int SMDS_Mesh::MaxElementID() const
1889 {
1890   return myElementIDFactory->GetMaxID();
1891 }
1892
1893 //=======================================================================
1894 //function : MinElementID
1895 //purpose  : 
1896 //=======================================================================
1897
1898 int SMDS_Mesh::MinElementID() const
1899 {
1900   return myElementIDFactory->GetMinID();
1901 }
1902
1903 //=======================================================================
1904 //function : Renumber
1905 //purpose  : Renumber all nodes or elements.
1906 //=======================================================================
1907
1908 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
1909 {
1910   if ( deltaID == 0 )
1911     return;
1912
1913   SMDS_MeshElementIDFactory * idFactory =
1914     isNodes ? myNodeIDFactory : myElementIDFactory;
1915
1916   // get existing elements in the order of ID increasing
1917   map<int,SMDS_MeshElement*> elemMap;
1918   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
1919   while ( idElemIt->more() ) {
1920     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
1921     int id = elem->GetID();
1922     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
1923   }
1924   // release their ids
1925   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
1926   for ( ; elemIt != elemMap.end(); elemIt++ )
1927   {
1928     int id = (*elemIt).first;
1929     idFactory->ReleaseID( id );
1930   }
1931   // set new IDs
1932   int ID = startID;
1933   elemIt = elemMap.begin();
1934   for ( ; elemIt != elemMap.end(); elemIt++ )
1935   {
1936     idFactory->BindID( ID, (*elemIt).second );
1937     ID += deltaID;
1938   }
1939 }
1940