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