]> SALOME platform Git repositories - modules/smesh.git/blob - src/SMDS/SMDS_Mesh.cxx
Salome HOME
0de7c4af5b9c3193eac5eda1f327ef0a7bad1e4b
[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.salome-platform.org/ or email : webmaster.salome@opencascade.com
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 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
33 #include "SMDS_PolygonalFaceOfNodes.hxx"
34 #include "SMDS_QuadraticEdge.hxx"
35 #include "SMDS_QuadraticFaceOfNodes.hxx"
36 #include "SMDS_QuadraticVolumeOfNodes.hxx"
37
38 #include <algorithm>
39 #include <map>
40 using namespace std;
41
42 #ifndef WIN32
43 #include <sys/sysinfo.h>
44 #endif
45
46 //================================================================================
47 /*!
48  * \brief Raise an exception if free memory (ram+swap) too low
49  * \param doNotRaise - if true, suppres exception, just return free memory size
50  * \retval int - amount of available memory in MB or negative number in failure case
51  */
52 //================================================================================
53
54 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
55 {
56 #ifndef WIN32
57   struct sysinfo si;
58   int err = sysinfo( &si );
59   if ( err )
60     return -1;
61
62   const unsigned long Mbyte = 1024 * 1024;
63   // compute separately to avoid overflow
64   int freeMb =
65     ( si.freeram  * si.mem_unit ) / Mbyte +
66     ( si.freeswap * si.mem_unit ) / Mbyte;
67
68   if ( freeMb > 4 )
69     return freeMb;
70
71   if ( doNotRaise )
72     return 0;
73   cout<<"SMDS_Mesh::CheckMemory() throws std::bad_alloc() as freeMb="<<freeMb<<endl;
74   throw std::bad_alloc();
75 #else
76   return -1;
77 #endif
78 }
79
80 ///////////////////////////////////////////////////////////////////////////////
81 /// Create a new mesh object
82 ///////////////////////////////////////////////////////////////////////////////
83 SMDS_Mesh::SMDS_Mesh()
84         :myParent(NULL),
85         myNodeIDFactory(new SMDS_MeshElementIDFactory()),
86         myElementIDFactory(new SMDS_MeshElementIDFactory()),
87         myHasConstructionEdges(false), myHasConstructionFaces(false),
88         myHasInverseElements(true)
89 {
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////
93 /// Create a new child mesh
94 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
95 /// (2003-09-08) of SMESH
96 ///////////////////////////////////////////////////////////////////////////////
97 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
98         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
99         myElementIDFactory(parent->myElementIDFactory),
100         myHasConstructionEdges(false), myHasConstructionFaces(false),
101         myHasInverseElements(true)
102 {
103 }
104
105 ///////////////////////////////////////////////////////////////////////////////
106 ///Create a submesh and add it to the current mesh
107 ///////////////////////////////////////////////////////////////////////////////
108
109 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
110 {
111         SMDS_Mesh *submesh = new SMDS_Mesh(this);
112         myChildren.insert(myChildren.end(), submesh);
113         return submesh;
114 }
115
116 ///////////////////////////////////////////////////////////////////////////////
117 ///create a MeshNode and add it to the current Mesh
118 ///An ID is automatically assigned to the node.
119 ///@return : The created node
120 ///////////////////////////////////////////////////////////////////////////////
121
122 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
123 {
124   return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
125 }
126
127 ///////////////////////////////////////////////////////////////////////////////
128 ///create a MeshNode and add it to the current Mesh
129 ///@param ID : The ID of the MeshNode to create
130 ///@return : The created node or NULL if a node with this ID already exists
131 ///////////////////////////////////////////////////////////////////////////////
132 SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
133 {
134   // find the MeshNode corresponding to ID
135   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
136   if(!node){
137     CheckMemory();
138     SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
139     myNodes.Add(node);
140     myNodeIDFactory->BindID(ID,node);
141     return node;
142   }else
143     return NULL;
144 }
145
146 ///////////////////////////////////////////////////////////////////////////////
147 /// create a MeshEdge and add it to the current Mesh
148 /// @return : The created MeshEdge
149 ///////////////////////////////////////////////////////////////////////////////
150
151 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
152 {
153   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
154   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
155   if(!node1 || !node2) return NULL;
156   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
157 }
158
159 ///////////////////////////////////////////////////////////////////////////////
160 /// create a MeshEdge and add it to the current Mesh
161 /// @return : The created MeshEdge
162 ///////////////////////////////////////////////////////////////////////////////
163
164 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
165                                   const SMDS_MeshNode * node2)
166 {
167   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
168 }
169
170 ///////////////////////////////////////////////////////////////////////////////
171 /// Create a new edge and at it to the mesh
172 /// @param idnode1 ID of the first node
173 /// @param idnode2 ID of the second node
174 /// @param ID ID of the edge to create
175 /// @return The created edge or NULL if an element with this ID already exists or
176 /// if input nodes are not found.
177 ///////////////////////////////////////////////////////////////////////////////
178
179 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
180                                         const SMDS_MeshNode * n2, 
181                                         int ID)
182 {
183   if ( !n1 || !n2 ) return 0;
184
185   CheckMemory();
186   SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
187   if(myElementIDFactory->BindID(ID, edge)) {
188     SMDS_MeshNode *node1,*node2;
189     node1=const_cast<SMDS_MeshNode*>(n1);
190     node2=const_cast<SMDS_MeshNode*>(n2);
191     node1->AddInverseElement(edge);
192     node2->AddInverseElement(edge);             
193     myEdges.Add(edge);
194     return edge;
195   } 
196   else {
197     delete edge;
198     return NULL;
199   }
200 }
201
202 ///////////////////////////////////////////////////////////////////////////////
203 /// Add a triangle defined by its nodes. An ID is automatically affected to the
204 /// Created face
205 ///////////////////////////////////////////////////////////////////////////////
206
207 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
208                                   const SMDS_MeshNode * n2,
209                                   const SMDS_MeshNode * n3)
210 {
211   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
212 }
213
214 ///////////////////////////////////////////////////////////////////////////////
215 /// Add a triangle defined by its nodes IDs
216 ///////////////////////////////////////////////////////////////////////////////
217
218 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
219 {
220   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
221   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
222   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
223   if(!node1 || !node2 || !node3) return NULL;
224   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);     
225 }
226
227 ///////////////////////////////////////////////////////////////////////////////
228 /// Add a triangle defined by its nodes
229 ///////////////////////////////////////////////////////////////////////////////
230
231 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
232                                         const SMDS_MeshNode * n2,
233                                         const SMDS_MeshNode * n3,
234                                         int ID)
235 {
236   SMDS_MeshFace * face=createTriangle(n1, n2, n3);
237
238   if (face && !registerElement(ID, face)) {
239     RemoveElement(face, false);
240     face = NULL;
241   }
242   return face;
243 }
244
245 ///////////////////////////////////////////////////////////////////////////////
246 /// Add a quadrangle defined by its nodes. An ID is automatically affected to the
247 /// created face
248 ///////////////////////////////////////////////////////////////////////////////
249
250 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
251                                   const SMDS_MeshNode * n2,
252                                   const SMDS_MeshNode * n3,
253                                   const SMDS_MeshNode * n4)
254 {
255   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
256 }
257
258 ///////////////////////////////////////////////////////////////////////////////
259 /// Add a quadrangle defined by its nodes IDs
260 ///////////////////////////////////////////////////////////////////////////////
261
262 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, 
263                                         int idnode2, 
264                                         int idnode3,
265                                         int idnode4, 
266                                         int ID)
267 {
268   SMDS_MeshNode *node1, *node2, *node3, *node4;
269   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
270   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
271   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
272   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
273   if(!node1 || !node2 || !node3 || !node4) return NULL;
274   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);      
275 }
276
277 ///////////////////////////////////////////////////////////////////////////////
278 /// Add a quadrangle defined by its nodes
279 ///////////////////////////////////////////////////////////////////////////////
280
281 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
282                                         const SMDS_MeshNode * n2,
283                                         const SMDS_MeshNode * n3,
284                                         const SMDS_MeshNode * n4,
285                                         int ID)
286 {
287   SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
288
289   if (face && !registerElement(ID, face)) {
290     RemoveElement(face, false);
291     face = NULL;
292   }
293   return face;
294 }
295
296 ///////////////////////////////////////////////////////////////////////////////
297 /// Add a triangle defined by its edges. An ID is automatically assigned to the
298 /// Created face
299 ///////////////////////////////////////////////////////////////////////////////
300
301 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
302                                   const SMDS_MeshEdge * e2,
303                                   const SMDS_MeshEdge * e3)
304 {
305   if (!hasConstructionEdges())
306     return NULL;
307   return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
308 }
309
310 ///////////////////////////////////////////////////////////////////////////////
311 /// Add a triangle defined by its edges
312 ///////////////////////////////////////////////////////////////////////////////
313
314 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
315                                         const SMDS_MeshEdge * e2,
316                                         const SMDS_MeshEdge * e3,
317                                         int ID)
318 {
319   if (!hasConstructionEdges())
320     return NULL;
321   if ( !e1 || !e2 || !e3 ) return 0;
322
323   CheckMemory();
324   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
325   myFaces.Add(face);
326
327   if (!registerElement(ID, face)) {
328     RemoveElement(face, false);
329     face = NULL;
330   }
331   return face;
332 }
333
334 ///////////////////////////////////////////////////////////////////////////////
335 /// Add a quadrangle defined by its edges. An ID is automatically assigned to the
336 /// Created face
337 ///////////////////////////////////////////////////////////////////////////////
338
339 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
340                                   const SMDS_MeshEdge * e2,
341                                   const SMDS_MeshEdge * e3,
342                                   const SMDS_MeshEdge * e4)
343 {
344   if (!hasConstructionEdges())
345     return NULL;
346   return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
347 }
348
349 ///////////////////////////////////////////////////////////////////////////////
350 /// Add a quadrangle defined by its edges
351 ///////////////////////////////////////////////////////////////////////////////
352
353 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
354                                         const SMDS_MeshEdge * e2,
355                                         const SMDS_MeshEdge * e3,
356                                         const SMDS_MeshEdge * e4,
357                                         int ID)
358 {
359   if (!hasConstructionEdges())
360     return NULL;
361   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
362   CheckMemory();
363   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
364   myFaces.Add(face);
365
366   if (!registerElement(ID, face))
367   {
368     RemoveElement(face, false);
369     face = NULL;
370   }
371   return face;
372 }
373
374 ///////////////////////////////////////////////////////////////////////////////
375 ///Create a new tetrahedron and add it to the mesh. 
376 ///@return The created tetrahedron 
377 ///////////////////////////////////////////////////////////////////////////////
378
379 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
380                                       const SMDS_MeshNode * n2, 
381                                       const SMDS_MeshNode * n3,
382                                       const SMDS_MeshNode * n4)
383 {
384   int ID = myElementIDFactory->GetFreeID();
385   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
386   if(v==NULL) myElementIDFactory->ReleaseID(ID);
387   return v;
388 }
389
390 ///////////////////////////////////////////////////////////////////////////////
391 ///Create a new tetrahedron and add it to the mesh. 
392 ///@param ID The ID of the new volume
393 ///@return The created tetrahedron or NULL if an element with this ID already exists
394 ///or if input nodes are not found.
395 ///////////////////////////////////////////////////////////////////////////////
396
397 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
398                                              int idnode2,
399                                              int idnode3, 
400                                              int idnode4, 
401                                              int ID)
402 {
403   SMDS_MeshNode *node1, *node2, *node3, *node4;
404   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
405   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
406   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
407   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
408   if(!node1 || !node2 || !node3 || !node4) return NULL;
409   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
410 }
411         
412 ///////////////////////////////////////////////////////////////////////////////
413 ///Create a new tetrahedron and add it to the mesh. 
414 ///@param ID The ID of the new volume
415 ///@return The created tetrahedron 
416 ///////////////////////////////////////////////////////////////////////////////
417
418 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
419                                             const SMDS_MeshNode * n2,
420                                             const SMDS_MeshNode * n3,
421                                             const SMDS_MeshNode * n4,
422                                             int ID)
423 {
424   SMDS_MeshVolume* volume = 0;
425   if ( !n1 || !n2 || !n3 || !n4) return volume;
426   CheckMemory();
427   if(hasConstructionFaces()) {
428     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
429     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
430     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
431     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
432     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
433     myVolumes.Add(volume);
434   }
435   else if(hasConstructionEdges()) {
436     MESSAGE("Error : Not implemented");
437     return NULL;
438   }
439   else {
440     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
441     myVolumes.Add(volume);
442   }
443
444   if (!registerElement(ID, volume)) {
445     RemoveElement(volume, false);
446     volume = NULL;
447   }
448   return volume;
449 }
450
451 ///////////////////////////////////////////////////////////////////////////////
452 ///Create a new pyramid and add it to the mesh. 
453 ///Nodes 1,2,3 and 4 define the base of the pyramid
454 ///@return The created pyramid 
455 ///////////////////////////////////////////////////////////////////////////////
456
457 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
458                                       const SMDS_MeshNode * n2, 
459                                       const SMDS_MeshNode * n3,
460                                       const SMDS_MeshNode * n4, 
461                                       const SMDS_MeshNode * n5)
462 {
463   int ID = myElementIDFactory->GetFreeID();
464   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
465   if(v==NULL) myElementIDFactory->ReleaseID(ID);
466   return v;
467 }
468
469 ///////////////////////////////////////////////////////////////////////////////
470 ///Create a new pyramid and add it to the mesh. 
471 ///Nodes 1,2,3 and 4 define the base of the pyramid
472 ///@param ID The ID of the new volume
473 ///@return The created pyramid or NULL if an element with this ID already exists
474 ///or if input nodes are not found.
475 ///////////////////////////////////////////////////////////////////////////////
476
477 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
478                                              int idnode2,
479                                              int idnode3, 
480                                              int idnode4, 
481                                              int idnode5, 
482                                              int ID)
483 {
484   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
485   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
486   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
487   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
488   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
489   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
490   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
491   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
492 }
493         
494 ///////////////////////////////////////////////////////////////////////////////
495 ///Create a new pyramid and add it to the mesh.
496 ///Nodes 1,2,3 and 4 define the base of the pyramid
497 ///@param ID The ID of the new volume
498 ///@return The created pyramid
499 ///////////////////////////////////////////////////////////////////////////////
500
501 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
502                                             const SMDS_MeshNode * n2,
503                                             const SMDS_MeshNode * n3,
504                                             const SMDS_MeshNode * n4,
505                                             const SMDS_MeshNode * n5,
506                                             int ID)
507 {
508   SMDS_MeshVolume* volume = 0;
509   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
510   CheckMemory();
511   if(hasConstructionFaces()) {
512     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
513     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
514     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
515     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
516     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
517     myVolumes.Add(volume);
518   }
519   else if(hasConstructionEdges()) {
520     MESSAGE("Error : Not implemented");
521     return NULL;
522   }
523   else {
524     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
525     myVolumes.Add(volume);
526   }
527
528   if (!registerElement(ID, volume)) {
529     RemoveElement(volume, false);
530     volume = NULL;
531   }
532   return volume;
533 }
534
535 ///////////////////////////////////////////////////////////////////////////////
536 ///Create a new prism and add it to the mesh. 
537 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
538 ///@return The created prism 
539 ///////////////////////////////////////////////////////////////////////////////
540
541 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
542                                       const SMDS_MeshNode * n2, 
543                                       const SMDS_MeshNode * n3,
544                                       const SMDS_MeshNode * n4, 
545                                       const SMDS_MeshNode * n5,
546                                       const SMDS_MeshNode * n6)
547 {
548   int ID = myElementIDFactory->GetFreeID();
549   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
550   if(v==NULL) myElementIDFactory->ReleaseID(ID);
551   return v;
552 }
553
554 ///////////////////////////////////////////////////////////////////////////////
555 ///Create a new prism and add it to the mesh. 
556 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
557 ///@param ID The ID of the new volume
558 ///@return The created prism or NULL if an element with this ID already exists
559 ///or if input nodes are not found.
560 ///////////////////////////////////////////////////////////////////////////////
561
562 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
563                                              int idnode2,
564                                              int idnode3, 
565                                              int idnode4, 
566                                              int idnode5, 
567                                              int idnode6, 
568                                              int ID)
569 {
570   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
571   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
572   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
573   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
574   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
575   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
576   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
577   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
578   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
579 }
580         
581 ///////////////////////////////////////////////////////////////////////////////
582 ///Create a new prism and add it to the mesh.
583 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
584 ///@param ID The ID of the new volume
585 ///@return The created prism
586 ///////////////////////////////////////////////////////////////////////////////
587
588 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
589                                             const SMDS_MeshNode * n2,
590                                             const SMDS_MeshNode * n3,
591                                             const SMDS_MeshNode * n4,
592                                             const SMDS_MeshNode * n5,
593                                             const SMDS_MeshNode * n6,
594                                             int ID)
595 {
596   SMDS_MeshVolume* volume = 0;
597   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
598   CheckMemory();
599   if(hasConstructionFaces()) {
600     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
601     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
602     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
603     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
604     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
605     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
606     myVolumes.Add(volume);
607   }
608   else if(hasConstructionEdges()) {
609     MESSAGE("Error : Not implemented");
610     return NULL;
611   }
612   else {
613     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
614     myVolumes.Add(volume);
615   }
616
617   if (!registerElement(ID, volume)) {
618     RemoveElement(volume, false);
619     volume = NULL;
620   }
621   return volume;
622 }
623
624 ///////////////////////////////////////////////////////////////////////////////
625 ///Create a new hexahedron and add it to the mesh. 
626 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
627 ///@return The created hexahedron 
628 ///////////////////////////////////////////////////////////////////////////////
629
630 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
631                                       const SMDS_MeshNode * n2, 
632                                       const SMDS_MeshNode * n3,
633                                       const SMDS_MeshNode * n4, 
634                                       const SMDS_MeshNode * n5,
635                                       const SMDS_MeshNode * n6, 
636                                       const SMDS_MeshNode * n7,
637                                       const SMDS_MeshNode * n8)
638 {
639   int ID = myElementIDFactory->GetFreeID();
640   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
641   if(v==NULL) myElementIDFactory->ReleaseID(ID);
642   return v;
643 }
644
645 ///////////////////////////////////////////////////////////////////////////////
646 ///Create a new hexahedron and add it to the mesh. 
647 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
648 ///@param ID The ID of the new volume
649 ///@return The created hexahedron or NULL if an element with this ID already
650 ///exists or if input nodes are not found.
651 ///////////////////////////////////////////////////////////////////////////////
652
653 SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
654                                              int idnode2,
655                                              int idnode3, 
656                                              int idnode4, 
657                                              int idnode5, 
658                                              int idnode6, 
659                                              int idnode7,
660                                              int idnode8, 
661                                              int ID)
662 {
663   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
664   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
665   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
666   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
667   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
668   node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
669   node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
670   node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
671   node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
672   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
673     return NULL;
674   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
675                                     node7, node8, ID);
676 }
677         
678 ///////////////////////////////////////////////////////////////////////////////
679 ///Create a new hexahedron and add it to the mesh.
680 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
681 ///@param ID The ID of the new volume
682 ///@return The created prism or NULL if an element with this ID already exists
683 ///or if input nodes are not found.
684 ///////////////////////////////////////////////////////////////////////////////
685
686 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
687                                             const SMDS_MeshNode * n2,
688                                             const SMDS_MeshNode * n3,
689                                             const SMDS_MeshNode * n4,
690                                             const SMDS_MeshNode * n5,
691                                             const SMDS_MeshNode * n6,
692                                             const SMDS_MeshNode * n7,
693                                             const SMDS_MeshNode * n8,
694                                             int ID)
695 {
696   SMDS_MeshVolume* volume = 0;
697   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
698   CheckMemory();
699   if(hasConstructionFaces()) {
700     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
701     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
702     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
703     SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
704     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
705     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
706     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
707     myVolumes.Add(volume);
708   }
709   else if(hasConstructionEdges()) {
710     MESSAGE("Error : Not implemented");
711     return NULL;
712   }
713   else {
714 //    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
715     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
716     myVolumes.Add(volume);
717   }
718
719   if (!registerElement(ID, volume)) {
720     RemoveElement(volume, false);
721     volume = NULL;
722   }
723   return volume;
724 }
725
726 ///////////////////////////////////////////////////////////////////////////////
727 ///Create a new tetrahedron defined by its faces and add it to the mesh.
728 ///@return The created tetrahedron
729 ///////////////////////////////////////////////////////////////////////////////
730
731 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
732                                       const SMDS_MeshFace * f2,
733                                       const SMDS_MeshFace * f3,
734                                       const SMDS_MeshFace * f4)
735 {
736   if (!hasConstructionFaces())
737     return NULL;
738   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
739 }
740
741 ///////////////////////////////////////////////////////////////////////////////
742 ///Create a new tetrahedron defined by its faces and add it to the mesh.
743 ///@param ID The ID of the new volume
744 ///@return The created tetrahedron 
745 ///////////////////////////////////////////////////////////////////////////////
746
747 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
748                                             const SMDS_MeshFace * f2,
749                                             const SMDS_MeshFace * f3,
750                                             const SMDS_MeshFace * f4,
751                                             int ID)
752 {
753   if (!hasConstructionFaces())
754     return NULL;
755   if ( !f1 || !f2 || !f3 || !f4) return 0;
756   CheckMemory();
757   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
758   myVolumes.Add(volume);
759
760   if (!registerElement(ID, volume)) {
761     RemoveElement(volume, false);
762     volume = NULL;
763   }
764   return volume;
765 }
766
767 ///////////////////////////////////////////////////////////////////////////////
768 ///Create a new pyramid defined by its faces and add it to the mesh.
769 ///@return The created pyramid
770 ///////////////////////////////////////////////////////////////////////////////
771
772 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
773                                       const SMDS_MeshFace * f2,
774                                       const SMDS_MeshFace * f3,
775                                       const SMDS_MeshFace * f4,
776                                       const SMDS_MeshFace * f5)
777 {
778   if (!hasConstructionFaces())
779     return NULL;
780   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
781 }
782
783 ///////////////////////////////////////////////////////////////////////////////
784 ///Create a new pyramid defined by its faces and add it to the mesh.
785 ///@param ID The ID of the new volume
786 ///@return The created pyramid 
787 ///////////////////////////////////////////////////////////////////////////////
788
789 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
790                                             const SMDS_MeshFace * f2,
791                                             const SMDS_MeshFace * f3,
792                                             const SMDS_MeshFace * f4,
793                                             const SMDS_MeshFace * f5,
794                                             int ID)
795 {
796   if (!hasConstructionFaces())
797     return NULL;
798   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
799   CheckMemory();
800   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
801   myVolumes.Add(volume);
802
803   if (!registerElement(ID, volume)) {
804     RemoveElement(volume, false);
805     volume = NULL;
806   }
807   return volume;
808 }
809
810 ///////////////////////////////////////////////////////////////////////////////
811 ///Create a new prism defined by its faces and add it to the mesh.
812 ///@return The created prism
813 ///////////////////////////////////////////////////////////////////////////////
814
815 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
816                                       const SMDS_MeshFace * f2,
817                                       const SMDS_MeshFace * f3,
818                                       const SMDS_MeshFace * f4,
819                                       const SMDS_MeshFace * f5,
820                                       const SMDS_MeshFace * f6)
821 {
822   if (!hasConstructionFaces())
823     return NULL;
824   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
825 }
826
827 ///////////////////////////////////////////////////////////////////////////////
828 ///Create a new prism defined by its faces and add it to the mesh.
829 ///@param ID The ID of the new volume
830 ///@return The created prism 
831 ///////////////////////////////////////////////////////////////////////////////
832
833 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
834                                             const SMDS_MeshFace * f2,
835                                             const SMDS_MeshFace * f3,
836                                             const SMDS_MeshFace * f4,
837                                             const SMDS_MeshFace * f5,
838                                             const SMDS_MeshFace * f6,
839                                             int ID)
840 {
841   if (!hasConstructionFaces())
842     return NULL;
843   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
844   CheckMemory();
845   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
846   myVolumes.Add(volume);
847
848   if (!registerElement(ID, volume)) {
849     RemoveElement(volume, false);
850     volume = NULL;
851   }
852   return volume;
853 }
854
855 ///////////////////////////////////////////////////////////////////////////////
856 /// Add a polygon defined by its nodes IDs
857 ///////////////////////////////////////////////////////////////////////////////
858
859 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
860                                                   const int        ID)
861 {
862   int nbNodes = nodes_ids.size();
863   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
864   for (int i = 0; i < nbNodes; i++) {
865     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
866     if (!nodes[i]) return NULL;
867   }
868   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);  
869 }
870
871 ///////////////////////////////////////////////////////////////////////////////
872 /// Add a polygon defined by its nodes
873 ///////////////////////////////////////////////////////////////////////////////
874
875 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
876                           (std::vector<const SMDS_MeshNode*> nodes,
877                            const int                         ID)
878 {
879   SMDS_MeshFace * face;
880
881   CheckMemory();
882   if (hasConstructionEdges())
883   {
884     MESSAGE("Error : Not implemented");
885     return NULL;
886   }
887   else
888   {
889     for ( int i = 0; i < nodes.size(); ++i )
890       if ( !nodes[ i ] ) return 0;
891     face = new SMDS_PolygonalFaceOfNodes(nodes);
892     myFaces.Add(face);
893   }
894
895   if (!registerElement(ID, face)) {
896     RemoveElement(face, false);
897     face = NULL;
898   }
899   return face;
900 }
901
902 ///////////////////////////////////////////////////////////////////////////////
903 /// Add a polygon defined by its nodes.
904 /// An ID is automatically affected to the created face.
905 ///////////////////////////////////////////////////////////////////////////////
906
907 SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
908 {
909   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
910 }
911
912 ///////////////////////////////////////////////////////////////////////////////
913 /// Create a new polyhedral volume and add it to the mesh. 
914 /// @param ID The ID of the new volume
915 /// @return The created volume or NULL if an element with this ID already exists
916 /// or if input nodes are not found.
917 ///////////////////////////////////////////////////////////////////////////////
918
919 SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
920                              (std::vector<int> nodes_ids,
921                               std::vector<int> quantities,
922                               const int        ID)
923 {
924   int nbNodes = nodes_ids.size();
925   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
926   for (int i = 0; i < nbNodes; i++) {
927     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
928     if (!nodes[i]) return NULL;
929   }
930   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
931 }
932
933 ///////////////////////////////////////////////////////////////////////////////
934 /// Create a new polyhedral volume and add it to the mesh. 
935 /// @param ID The ID of the new volume
936 /// @return The created  volume
937 ///////////////////////////////////////////////////////////////////////////////
938
939 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
940                             (std::vector<const SMDS_MeshNode*> nodes,
941                              std::vector<int>                  quantities,
942                              const int                         ID)
943 {
944   SMDS_MeshVolume* volume;
945   CheckMemory();
946   if (hasConstructionFaces()) {
947     MESSAGE("Error : Not implemented");
948     return NULL;
949   } else if (hasConstructionEdges()) {
950     MESSAGE("Error : Not implemented");
951     return NULL;
952   } else {
953     for ( int i = 0; i < nodes.size(); ++i )
954       if ( !nodes[ i ] ) return 0;
955     volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
956     myVolumes.Add(volume);
957   }
958
959   if (!registerElement(ID, volume)) {
960     RemoveElement(volume, false);
961     volume = NULL;
962   }
963   return volume;
964 }
965
966 ///////////////////////////////////////////////////////////////////////////////
967 /// Create a new polyhedral volume and add it to the mesh. 
968 /// @return The created  volume
969 ///////////////////////////////////////////////////////////////////////////////
970
971 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
972                             (std::vector<const SMDS_MeshNode*> nodes,
973                              std::vector<int>                  quantities)
974 {
975   int ID = myElementIDFactory->GetFreeID();
976   SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
977   if (v == NULL) myElementIDFactory->ReleaseID(ID);
978   return v;
979 }
980
981 ///////////////////////////////////////////////////////////////////////////////
982 /// Registers element with the given ID, maintains inverse connections
983 ///////////////////////////////////////////////////////////////////////////////
984 bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
985 {
986   if (myElementIDFactory->BindID(ID, element)) {
987     SMDS_ElemIteratorPtr it = element->nodesIterator();
988     while (it->more()) {
989       SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
990         (const_cast<SMDS_MeshElement*>(it->next()));
991       node->AddInverseElement(element);
992     }
993     return true;
994   }
995   return false;
996 }
997
998 ///////////////////////////////////////////////////////////////////////////////
999 /// Return the node whose ID is 'ID'.
1000 ///////////////////////////////////////////////////////////////////////////////
1001 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
1002 {
1003   return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
1004 }
1005
1006 ///////////////////////////////////////////////////////////////////////////////
1007 ///Create a triangle and add it to the current mesh. This methode do not bind a
1008 ///ID to the create triangle.
1009 ///////////////////////////////////////////////////////////////////////////////
1010 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
1011                                           const SMDS_MeshNode * node2,
1012                                           const SMDS_MeshNode * node3)
1013 {
1014   if ( !node1 || !node2 || !node3) return 0;
1015   CheckMemory();
1016         if(hasConstructionEdges())
1017         {
1018                 SMDS_MeshEdge *edge1, *edge2, *edge3;
1019                 edge1=FindEdgeOrCreate(node1,node2);
1020                 edge2=FindEdgeOrCreate(node2,node3);
1021                 edge3=FindEdgeOrCreate(node3,node1);
1022
1023                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
1024                 myFaces.Add(face);
1025                 return face;
1026         }
1027         else
1028         {
1029                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
1030                 myFaces.Add(face);
1031                 return face;
1032         }
1033 }
1034
1035 ///////////////////////////////////////////////////////////////////////////////
1036 ///Create a quadrangle and add it to the current mesh. This methode do not bind
1037 ///a ID to the create triangle.
1038 ///////////////////////////////////////////////////////////////////////////////
1039 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
1040                                             const SMDS_MeshNode * node2,
1041                                             const SMDS_MeshNode * node3,
1042                                             const SMDS_MeshNode * node4)
1043 {
1044   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
1045   CheckMemory();
1046         if(hasConstructionEdges())
1047         {
1048                 SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
1049                 edge1=FindEdgeOrCreate(node1,node2);
1050                 edge2=FindEdgeOrCreate(node2,node3);
1051                 edge3=FindEdgeOrCreate(node3,node4);
1052                 edge4=FindEdgeOrCreate(node4,node1);
1053
1054                 SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
1055                 myFaces.Add(face);
1056                 return face;
1057         }
1058         else
1059         {
1060                 SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
1061                 myFaces.Add(face);
1062                 return face;
1063         }
1064 }
1065
1066 ///////////////////////////////////////////////////////////////////////////////
1067 /// Remove a node and all the elements which own this node
1068 ///////////////////////////////////////////////////////////////////////////////
1069
1070 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
1071 {
1072         RemoveElement(node, true);
1073 }
1074
1075 ///////////////////////////////////////////////////////////////////////////////
1076 /// Remove an edge and all the elements which own this edge
1077 ///////////////////////////////////////////////////////////////////////////////
1078
1079 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
1080 {
1081         RemoveElement(edge,true);
1082 }
1083
1084 ///////////////////////////////////////////////////////////////////////////////
1085 /// Remove an face and all the elements which own this face
1086 ///////////////////////////////////////////////////////////////////////////////
1087
1088 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
1089 {
1090         RemoveElement(face, true);
1091 }
1092
1093 ///////////////////////////////////////////////////////////////////////////////
1094 /// Remove a volume
1095 ///////////////////////////////////////////////////////////////////////////////
1096
1097 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
1098 {
1099         RemoveElement(volume, true);
1100 }
1101
1102 //=======================================================================
1103 //function : RemoveFromParent
1104 //purpose  :
1105 //=======================================================================
1106
1107 bool SMDS_Mesh::RemoveFromParent()
1108 {
1109         if (myParent==NULL) return false;
1110         else return (myParent->RemoveSubMesh(this));
1111 }
1112
1113 //=======================================================================
1114 //function : RemoveSubMesh
1115 //purpose  :
1116 //=======================================================================
1117
1118 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
1119 {
1120         bool found = false;
1121
1122         list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
1123         for (; itmsh!=myChildren.end() && !found; itmsh++)
1124         {
1125                 SMDS_Mesh * submesh = *itmsh;
1126                 if (submesh == aMesh)
1127                 {
1128                         found = true;
1129                         myChildren.erase(itmsh);
1130                 }
1131         }
1132
1133         return found;
1134 }
1135
1136 //=======================================================================
1137 //function : ChangeElementNodes
1138 //purpose  : 
1139 //=======================================================================
1140
1141 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
1142                                    const SMDS_MeshNode    * nodes[],
1143                                    const int                nbnodes)
1144 {
1145   // keep current nodes of elem
1146   set<const SMDS_MeshElement*> oldNodes;
1147   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1148   while(itn->more())
1149     oldNodes.insert(  itn->next() );
1150
1151   // change nodes
1152   bool Ok = false;
1153   switch ( elem->GetType() )
1154   {
1155   case SMDSAbs_Edge: {
1156     if ( nbnodes == 2 ) {
1157       const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
1158       if ( edge )
1159         Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
1160     }
1161     else if ( nbnodes == 3 ) {
1162       const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
1163       if ( edge )
1164         Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
1165     }
1166     break;
1167   }
1168   case SMDSAbs_Face: {
1169     const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
1170     if ( face ) {
1171       Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
1172     }
1173     else {
1174       const SMDS_QuadraticFaceOfNodes* QF =
1175         dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
1176       if ( QF ) {
1177         Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
1178       }
1179       else {
1180         /// ??? begin
1181         const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1182         if (face) {
1183           Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1184         }
1185         /// ??? end
1186       }
1187     }
1188     break;
1189   }
1190   //case SMDSAbs_PolygonalFace: {
1191   //  const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
1192   //  if (face) {
1193   //    Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
1194   //  }
1195   //  break;
1196   //}
1197   case SMDSAbs_Volume: {
1198     const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
1199     if ( vol ) {
1200       Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
1201     }
1202     else {
1203       const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
1204       if ( QV ) {
1205         Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
1206       }
1207     }
1208     break;
1209   }
1210   default:
1211     MESSAGE ( "WRONG ELEM TYPE");
1212   }
1213
1214   if ( Ok ) { // update InverseElements
1215
1216     // AddInverseElement to new nodes
1217     for ( int i = 0; i < nbnodes; i++ )
1218       if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
1219         // new node
1220         const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
1221       else
1222         // remove from oldNodes a node that remains in elem
1223         oldNodes.erase( nodes[i] );
1224
1225
1226     // RemoveInverseElement from the nodes removed from elem
1227     set<const SMDS_MeshElement*>::iterator it;
1228     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
1229     {
1230       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1231         (const_cast<SMDS_MeshElement *>( *it ));
1232       n->RemoveInverseElement( elem );
1233     }
1234   }
1235
1236   //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
1237
1238   return Ok;
1239 }
1240
1241 //=======================================================================
1242 //function : ChangePolyhedronNodes
1243 //purpose  : to change nodes of polyhedral volume
1244 //=======================================================================
1245 bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
1246                                        std::vector<const SMDS_MeshNode*> nodes,
1247                                        std::vector<int>                  quantities)
1248 {
1249   if (elem->GetType() != SMDSAbs_Volume) {
1250     MESSAGE("WRONG ELEM TYPE");
1251     return false;
1252   }
1253
1254   const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
1255   if (!vol) {
1256     return false;
1257   }
1258
1259   // keep current nodes of elem
1260   set<const SMDS_MeshElement*> oldNodes;
1261   SMDS_ElemIteratorPtr itn = elem->nodesIterator();
1262   while (itn->more()) {
1263     oldNodes.insert(itn->next());
1264   }
1265
1266   // change nodes
1267   bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
1268   if (!Ok) {
1269     return false;
1270   }
1271
1272   // update InverseElements
1273
1274   // AddInverseElement to new nodes
1275   int nbnodes = nodes.size();
1276   for (int i = 0; i < nbnodes; i++) {
1277     if (oldNodes.find(nodes[i]) == oldNodes.end()) {
1278       // new node
1279       const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
1280     } else {
1281       // remove from oldNodes a node that remains in elem
1282       oldNodes.erase(nodes[i]);
1283     }
1284   }
1285
1286   // RemoveInverseElement from the nodes removed from elem
1287   set<const SMDS_MeshElement*>::iterator it;
1288   for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
1289     SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
1290       (const_cast<SMDS_MeshElement *>( *it ));
1291     n->RemoveInverseElement(elem);
1292   }
1293
1294   return Ok;
1295 }
1296
1297
1298 //=======================================================================
1299 //function : FindEdge
1300 //purpose  :
1301 //=======================================================================
1302
1303 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
1304 {
1305   const SMDS_MeshNode * node1=FindNode(idnode1);
1306   const SMDS_MeshNode * node2=FindNode(idnode2);
1307   if((node1==NULL)||(node2==NULL)) return NULL;
1308   return FindEdge(node1,node2);
1309 }
1310
1311 //#include "Profiler.h"
1312 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1313                                          const SMDS_MeshNode * node2)
1314 {
1315   if ( !node1 ) return 0;
1316   const SMDS_MeshEdge * toReturn=NULL;
1317   //PROFILER_Init();
1318   //PROFILER_Set();
1319   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
1320   //PROFILER_Get(0);
1321   //PROFILER_Set();
1322   while(it1->more()) {
1323     const SMDS_MeshElement * e = it1->next();
1324     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
1325       toReturn = static_cast<const SMDS_MeshEdge*>( e );
1326       break;
1327     }
1328   }
1329   //PROFILER_Get(1);
1330   return toReturn;
1331 }
1332
1333
1334 //=======================================================================
1335 //function : FindEdgeOrCreate
1336 //purpose  :
1337 //=======================================================================
1338
1339 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
1340                                            const SMDS_MeshNode * node2) 
1341 {
1342   if ( !node1 || !node2) return 0;
1343   SMDS_MeshEdge * toReturn=NULL;
1344   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
1345   if(toReturn==NULL) {
1346     CheckMemory();
1347     toReturn=new SMDS_MeshEdge(node1,node2);
1348     myEdges.Add(toReturn);
1349   } 
1350   return toReturn;
1351 }
1352
1353
1354 //=======================================================================
1355 //function : FindEdge
1356 //purpose  :
1357 //=======================================================================
1358
1359 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
1360                                          int idnode3) const
1361 {
1362   const SMDS_MeshNode * node1=FindNode(idnode1);
1363   const SMDS_MeshNode * node2=FindNode(idnode2);
1364   const SMDS_MeshNode * node3=FindNode(idnode3);
1365   return FindEdge(node1,node2,node3);
1366 }
1367
1368 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
1369                                          const SMDS_MeshNode * node2,
1370                                          const SMDS_MeshNode * node3)
1371 {
1372   if ( !node1 ) return 0;
1373   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
1374   while(it1->more()) {
1375     const SMDS_MeshElement * e = it1->next();
1376     if ( e->NbNodes() == 3 ) {
1377       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1378       while(it2->more()) {
1379         const SMDS_MeshElement* n = it2->next();
1380         if( n!=node1 &&
1381             n!=node2 &&
1382             n!=node3 )
1383         {
1384           e = 0;
1385           break;
1386         }
1387       }
1388       if ( e )
1389         return static_cast<const SMDS_MeshEdge *> (e);
1390     }
1391   }
1392   return 0;
1393 }
1394
1395
1396 //=======================================================================
1397 //function : FindFace
1398 //purpose  :
1399 //=======================================================================
1400
1401 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1402         int idnode3) const
1403 {
1404   const SMDS_MeshNode * node1=FindNode(idnode1);
1405   const SMDS_MeshNode * node2=FindNode(idnode2);
1406   const SMDS_MeshNode * node3=FindNode(idnode3);
1407   return FindFace(node1, node2, node3);
1408 }
1409
1410 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1411                                          const SMDS_MeshNode *node2,
1412                                          const SMDS_MeshNode *node3)
1413 {
1414   if ( !node1 ) return 0;
1415   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1416   while(it1->more()) {
1417     const SMDS_MeshElement * e = it1->next();
1418     if ( e->NbNodes() == 3 ) {
1419       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1420       while(it2->more()) {
1421         const SMDS_MeshElement* n = it2->next();
1422         if( n!=node1 &&
1423             n!=node2 &&
1424             n!=node3 )
1425         {
1426           e = 0;
1427           break;
1428         }
1429       }
1430       if ( e )
1431         return static_cast<const SMDS_MeshFace *> (e);
1432     }
1433   }
1434   return 0;
1435 }
1436
1437 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1438                                            const SMDS_MeshNode *node2,
1439                                            const SMDS_MeshNode *node3)
1440 {
1441   SMDS_MeshFace * toReturn=NULL;
1442   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
1443   if(toReturn==NULL) {
1444     toReturn = createTriangle(node1,node2,node3);
1445   }
1446   return toReturn;
1447 }
1448
1449
1450 //=======================================================================
1451 //function : FindFace
1452 //purpose  :
1453 //=======================================================================
1454
1455 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1456                                          int idnode3, int idnode4) const
1457 {
1458   const SMDS_MeshNode * node1=FindNode(idnode1);
1459   const SMDS_MeshNode * node2=FindNode(idnode2);
1460   const SMDS_MeshNode * node3=FindNode(idnode3);
1461   const SMDS_MeshNode * node4=FindNode(idnode4);
1462   return FindFace(node1, node2, node3, node4);
1463 }
1464
1465 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1466                                          const SMDS_MeshNode *node2,
1467                                          const SMDS_MeshNode *node3,
1468                                          const SMDS_MeshNode *node4)
1469 {
1470   if ( !node1 ) return 0;
1471   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1472   while(it1->more()) {
1473     const SMDS_MeshElement * e = it1->next();
1474     if ( e->NbNodes() == 4 ) {
1475       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1476       while(it2->more()) {
1477         const SMDS_MeshElement* n = it2->next();
1478         if( n!=node1 &&
1479             n!=node2 &&
1480             n!=node3 &&
1481             n!=node4 )
1482         {
1483           e = 0;
1484           break;
1485         }
1486       }
1487       if ( e )
1488         return static_cast<const SMDS_MeshFace *> (e);
1489     }
1490   }
1491   return 0;
1492 }
1493
1494 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
1495                                            const SMDS_MeshNode *node2,
1496                                            const SMDS_MeshNode *node3,
1497                                            const SMDS_MeshNode *node4)
1498 {
1499   SMDS_MeshFace * toReturn=NULL;
1500   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
1501   if(toReturn==NULL) {
1502     toReturn=createQuadrangle(node1,node2,node3,node4);
1503   }
1504   return toReturn;
1505 }
1506
1507
1508 //=======================================================================
1509 //function : FindFace
1510 //purpose  :quadratic triangle
1511 //=======================================================================
1512
1513 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1514                                          int idnode3, int idnode4,
1515                                          int idnode5, int idnode6) const
1516 {
1517   const SMDS_MeshNode * node1 = FindNode(idnode1);
1518   const SMDS_MeshNode * node2 = FindNode(idnode2);
1519   const SMDS_MeshNode * node3 = FindNode(idnode3);
1520   const SMDS_MeshNode * node4 = FindNode(idnode4);
1521   const SMDS_MeshNode * node5 = FindNode(idnode5);
1522   const SMDS_MeshNode * node6 = FindNode(idnode6);
1523   return FindFace(node1, node2, node3, node4, node5, node6);
1524 }
1525
1526 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1527                                          const SMDS_MeshNode *node2,
1528                                          const SMDS_MeshNode *node3,
1529                                          const SMDS_MeshNode *node4,
1530                                          const SMDS_MeshNode *node5,
1531                                          const SMDS_MeshNode *node6)
1532 {
1533   if ( !node1 ) return 0;
1534   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1535   while(it1->more()) {
1536     const SMDS_MeshElement * e = it1->next();
1537     if ( e->NbNodes() == 6 ) {
1538       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1539       while(it2->more()) {
1540         const SMDS_MeshElement* n = it2->next();
1541         if( n!=node1 &&
1542             n!=node2 &&
1543             n!=node3 &&
1544             n!=node4 &&
1545             n!=node5 &&
1546             n!=node6 )
1547         {
1548           e = 0;
1549           break;
1550         }
1551       }
1552       if ( e )
1553         return static_cast<const SMDS_MeshFace *> (e);
1554     }
1555   }
1556   return 0;
1557 }
1558
1559
1560 //=======================================================================
1561 //function : FindFace
1562 //purpose  : quadratic quadrangle
1563 //=======================================================================
1564
1565 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
1566                                          int idnode3, int idnode4,
1567                                          int idnode5, int idnode6,
1568                                          int idnode7, int idnode8) const
1569 {
1570   const SMDS_MeshNode * node1 = FindNode(idnode1);
1571   const SMDS_MeshNode * node2 = FindNode(idnode2);
1572   const SMDS_MeshNode * node3 = FindNode(idnode3);
1573   const SMDS_MeshNode * node4 = FindNode(idnode4);
1574   const SMDS_MeshNode * node5 = FindNode(idnode5);
1575   const SMDS_MeshNode * node6 = FindNode(idnode6);
1576   const SMDS_MeshNode * node7 = FindNode(idnode7);
1577   const SMDS_MeshNode * node8 = FindNode(idnode8);
1578   return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
1579 }
1580
1581 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
1582                                          const SMDS_MeshNode *node2,
1583                                          const SMDS_MeshNode *node3,
1584                                          const SMDS_MeshNode *node4,
1585                                          const SMDS_MeshNode *node5,
1586                                          const SMDS_MeshNode *node6,
1587                                          const SMDS_MeshNode *node7,
1588                                          const SMDS_MeshNode *node8)
1589 {
1590   if ( !node1 ) return 0;
1591   SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
1592   while(it1->more()) {
1593     const SMDS_MeshElement * e = it1->next();
1594     if ( e->NbNodes() == 8 ) {
1595       SMDS_ElemIteratorPtr it2 = e->nodesIterator();
1596       while(it2->more()) {
1597         const SMDS_MeshElement* n = it2->next();
1598         if( n!=node1 &&
1599             n!=node2 &&
1600             n!=node3 &&
1601             n!=node4 &&
1602             n!=node5 &&
1603             n!=node6 &&
1604             n!=node7 &&
1605             n!=node8 )
1606         {
1607           e = 0;
1608           break;
1609         }
1610       }
1611       if ( e )
1612         return static_cast<const SMDS_MeshFace *> (e);
1613     }
1614   }
1615   return 0;
1616 }
1617
1618
1619 //=======================================================================
1620 //function : FindElement
1621 //purpose  :
1622 //=======================================================================
1623
1624 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
1625 {
1626   return myElementIDFactory->MeshElement(IDelem);
1627 }
1628
1629 //=======================================================================
1630 //function : FindFace
1631 //purpose  : find polygon
1632 //=======================================================================
1633
1634 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
1635 {
1636   int nbnodes = nodes_ids.size();
1637   std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
1638   for (int inode = 0; inode < nbnodes; inode++) {
1639     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
1640     if (node == NULL) return NULL;
1641   }
1642   return FindFace(poly_nodes);
1643 }
1644
1645 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
1646 {
1647   if ( nodes.size() > 2 && nodes[0] ) {
1648     SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
1649     while (itF->more()) {
1650       const SMDS_MeshElement* f = itF->next();
1651       if ( f->NbNodes() == nodes.size() ) {
1652         SMDS_ElemIteratorPtr it2 = f->nodesIterator();
1653         while(it2->more()) {
1654           if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
1655             f = 0;
1656             break;
1657           }
1658         }
1659         if ( f )
1660           return static_cast<const SMDS_MeshFace *> (f);
1661       }
1662     }
1663   }
1664   return NULL;
1665 }
1666
1667 //=======================================================================
1668 //function : DumpNodes
1669 //purpose  : 
1670 //=======================================================================
1671
1672 void SMDS_Mesh::DumpNodes() const
1673 {
1674         MESSAGE("dump nodes of mesh : ");
1675         SMDS_NodeIteratorPtr itnode=nodesIterator();
1676         while(itnode->more()) MESSAGE(itnode->next());
1677 }
1678
1679 //=======================================================================
1680 //function : DumpEdges
1681 //purpose  : 
1682 //=======================================================================
1683
1684 void SMDS_Mesh::DumpEdges() const
1685 {
1686         MESSAGE("dump edges of mesh : ");
1687         SMDS_EdgeIteratorPtr itedge=edgesIterator();
1688         while(itedge->more()) MESSAGE(itedge->next());
1689 }
1690
1691 //=======================================================================
1692 //function : DumpFaces
1693 //purpose  : 
1694 //=======================================================================
1695
1696 void SMDS_Mesh::DumpFaces() const
1697 {
1698         MESSAGE("dump faces of mesh : ");
1699         SMDS_FaceIteratorPtr itface=facesIterator();
1700         while(itface->more()) MESSAGE(itface->next());
1701 }
1702
1703 //=======================================================================
1704 //function : DumpVolumes
1705 //purpose  : 
1706 //=======================================================================
1707
1708 void SMDS_Mesh::DumpVolumes() const
1709 {
1710         MESSAGE("dump volumes of mesh : ");
1711         SMDS_VolumeIteratorPtr itvol=volumesIterator();
1712         while(itvol->more()) MESSAGE(itvol->next());
1713 }
1714
1715 //=======================================================================
1716 //function : DebugStats
1717 //purpose  : 
1718 //=======================================================================
1719
1720 void SMDS_Mesh::DebugStats() const
1721 {
1722         MESSAGE("Debug stats of mesh : ");
1723
1724         MESSAGE("===== NODES ====="<<NbNodes());
1725         MESSAGE("===== EDGES ====="<<NbEdges());
1726         MESSAGE("===== FACES ====="<<NbFaces());
1727         MESSAGE("===== VOLUMES ====="<<NbVolumes());
1728
1729         MESSAGE("End Debug stats of mesh ");
1730
1731         //#ifdef DEB
1732         
1733         SMDS_NodeIteratorPtr itnode=nodesIterator();
1734         int sizeofnodes = 0;
1735         int sizeoffaces = 0;
1736
1737         while(itnode->more())
1738         {
1739                 const SMDS_MeshNode *node = itnode->next();
1740
1741                 sizeofnodes += sizeof(*node);
1742                 
1743                 SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
1744                 while(it->more())
1745                 {
1746                         const SMDS_MeshElement *me = it->next();
1747                         sizeofnodes += sizeof(me);
1748                 }
1749
1750         }
1751
1752         SMDS_FaceIteratorPtr itface=facesIterator();
1753         while(itface->more())
1754         {
1755                 const SMDS_MeshElement *face = itface->next();          
1756                 sizeoffaces += sizeof(*face);
1757
1758         }
1759         MESSAGE("total size of node elements = " << sizeofnodes);;
1760         MESSAGE("total size of face elements = " << sizeoffaces);;
1761
1762         //#endif
1763 }
1764
1765 ///////////////////////////////////////////////////////////////////////////////
1766 /// Return the number of nodes
1767 ///////////////////////////////////////////////////////////////////////////////
1768 int SMDS_Mesh::NbNodes() const
1769 {
1770         return myNodes.Size();
1771 }
1772
1773 ///////////////////////////////////////////////////////////////////////////////
1774 /// Return the number of edges (including construction edges)
1775 ///////////////////////////////////////////////////////////////////////////////
1776 int SMDS_Mesh::NbEdges() const
1777 {
1778         return myEdges.Size();
1779 }
1780
1781 ///////////////////////////////////////////////////////////////////////////////
1782 /// Return the number of faces (including construction faces)
1783 ///////////////////////////////////////////////////////////////////////////////
1784 int SMDS_Mesh::NbFaces() const
1785 {
1786         return myFaces.Size();
1787 }
1788
1789 ///////////////////////////////////////////////////////////////////////////////
1790 /// Return the number of volumes
1791 ///////////////////////////////////////////////////////////////////////////////
1792 int SMDS_Mesh::NbVolumes() const
1793 {
1794         return myVolumes.Size();
1795 }
1796
1797 ///////////////////////////////////////////////////////////////////////////////
1798 /// Return the number of child mesh of this mesh.
1799 /// Note that the tree structure of SMDS_Mesh seems to be unused in this version
1800 /// (2003-09-08) of SMESH
1801 ///////////////////////////////////////////////////////////////////////////////
1802 int SMDS_Mesh::NbSubMesh() const
1803 {
1804         return myChildren.size();
1805 }
1806
1807 ///////////////////////////////////////////////////////////////////////////////
1808 /// Destroy the mesh and all its elements
1809 /// All pointer on elements owned by this mesh become illegals.
1810 ///////////////////////////////////////////////////////////////////////////////
1811 SMDS_Mesh::~SMDS_Mesh()
1812 {
1813   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
1814   while(itc!=myChildren.end())
1815   {
1816     delete *itc;
1817     itc++;
1818   }
1819
1820   SetOfNodes::Iterator itn(myNodes);
1821   for (; itn.More(); itn.Next())
1822     delete itn.Value();
1823
1824   SetOfEdges::Iterator ite(myEdges);
1825   for (; ite.More(); ite.Next())
1826   {
1827     SMDS_MeshElement* elem = ite.Value();
1828     if(myParent!=NULL)
1829       myElementIDFactory->ReleaseID(elem->GetID());
1830     delete elem;
1831   }
1832
1833   SetOfFaces::Iterator itf(myFaces);
1834   for (; itf.More(); itf.Next())
1835   {
1836     SMDS_MeshElement* elem = itf.Value();
1837     if(myParent!=NULL)
1838       myElementIDFactory->ReleaseID(elem->GetID());
1839     delete elem;
1840   }
1841
1842   SetOfVolumes::Iterator itv(myVolumes);
1843   for (; itv.More(); itv.Next())
1844   {
1845     SMDS_MeshElement* elem = itv.Value();
1846     if(myParent!=NULL)
1847       myElementIDFactory->ReleaseID(elem->GetID());
1848     delete elem;
1849   }
1850
1851   if(myParent==NULL)
1852   {
1853     delete myNodeIDFactory;
1854     delete myElementIDFactory;
1855   }
1856 }
1857
1858 ///////////////////////////////////////////////////////////////////////////////
1859 /// Return true if this mesh create faces with edges.
1860 /// A false returned value mean that faces are created with nodes. A concequence
1861 /// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
1862 ///////////////////////////////////////////////////////////////////////////////
1863 bool SMDS_Mesh::hasConstructionEdges()
1864 {
1865         return myHasConstructionEdges;
1866 }
1867
1868 ///////////////////////////////////////////////////////////////////////////////
1869 /// Return true if this mesh create volumes with faces
1870 /// A false returned value mean that volumes are created with nodes or edges.
1871 /// (see hasConstructionEdges)
1872 /// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
1873 /// unavailable.
1874 ///////////////////////////////////////////////////////////////////////////////
1875 bool SMDS_Mesh::hasConstructionFaces()
1876 {
1877         return myHasConstructionFaces;
1878 }
1879
1880 ///////////////////////////////////////////////////////////////////////////////
1881 /// Return true if nodes are linked to the finit elements, they are belonging to.
1882 /// Currently, It always return true.
1883 ///////////////////////////////////////////////////////////////////////////////
1884 bool SMDS_Mesh::hasInverseElements()
1885 {
1886         return myHasInverseElements;
1887 }
1888
1889 ///////////////////////////////////////////////////////////////////////////////
1890 /// Make this mesh creating construction edges (see hasConstructionEdges)
1891 /// @param b true to have construction edges, else false.
1892 ///////////////////////////////////////////////////////////////////////////////
1893 void SMDS_Mesh::setConstructionEdges(bool b)
1894 {
1895         myHasConstructionEdges=b;
1896 }
1897
1898 ///////////////////////////////////////////////////////////////////////////////
1899 /// Make this mesh creating construction faces (see hasConstructionFaces)
1900 /// @param b true to have construction faces, else false.
1901 ///////////////////////////////////////////////////////////////////////////////
1902 void SMDS_Mesh::setConstructionFaces(bool b)
1903 {
1904          myHasConstructionFaces=b;
1905 }
1906
1907 ///////////////////////////////////////////////////////////////////////////////
1908 /// Make this mesh creating link from nodes to elements (see hasInverseElements)
1909 /// @param b true to link nodes to elements, else false.
1910 ///////////////////////////////////////////////////////////////////////////////
1911 void SMDS_Mesh::setInverseElements(bool b)
1912 {
1913         if(!b) MESSAGE("Error : inverseElement=false not implemented");
1914         myHasInverseElements=b;
1915 }
1916
1917 ///////////////////////////////////////////////////////////////////////////////
1918 /// Return an iterator on nodes of the current mesh factory
1919 ///////////////////////////////////////////////////////////////////////////////
1920 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
1921 {
1922   SMDS_ElemIteratorPtr myIterator;
1923  public:
1924   SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
1925   {}
1926
1927   bool more()
1928   {
1929     return myIterator->more();
1930   }
1931
1932   const SMDS_MeshNode* next()
1933   {
1934     return static_cast<const SMDS_MeshNode*>(myIterator->next());
1935   }
1936 };
1937
1938 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
1939 {
1940   return SMDS_NodeIteratorPtr
1941     (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
1942 }
1943
1944 ///////////////////////////////////////////////////////////////////////////////
1945 /// Return an iterator on elements of the current mesh factory
1946 ///////////////////////////////////////////////////////////////////////////////
1947 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
1948 {
1949   return myElementIDFactory->elementsIterator();
1950 }
1951
1952 ///////////////////////////////////////////////////////////////////////////////
1953 ///Return an iterator on edges of the current mesh.
1954 ///////////////////////////////////////////////////////////////////////////////
1955 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
1956 {
1957   typedef SMDS_Mesh::SetOfEdges SetOfEdges;
1958   SetOfEdges::Iterator myIterator;
1959  public:
1960   SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
1961   {}
1962
1963   bool more()
1964   {
1965     while(myIterator.More())
1966     {
1967       if(myIterator.Value()->GetID()!=-1)
1968         return true;
1969       myIterator.Next();
1970     }
1971     return false;
1972   }
1973
1974   const SMDS_MeshEdge* next()
1975   {
1976     const SMDS_MeshEdge* current = myIterator.Value();
1977     myIterator.Next();
1978     return current;
1979   }
1980 };
1981
1982 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
1983 {
1984   return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
1985 }
1986
1987 ///////////////////////////////////////////////////////////////////////////////
1988 ///Return an iterator on faces of the current mesh.
1989 ///////////////////////////////////////////////////////////////////////////////
1990 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
1991 {
1992   typedef SMDS_Mesh::SetOfFaces SetOfFaces;
1993   SetOfFaces::Iterator myIterator;
1994  public:
1995   SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
1996   {}
1997
1998   bool more()
1999   {
2000     while(myIterator.More())
2001     {
2002       if(myIterator.Value()->GetID()!=-1)
2003         return true;
2004       myIterator.Next();
2005     }
2006     return false;
2007   }
2008
2009   const SMDS_MeshFace* next()
2010   {
2011     const SMDS_MeshFace* current = myIterator.Value();
2012     myIterator.Next();
2013     return current;
2014   }
2015 };
2016
2017 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
2018 {
2019   return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
2020 }
2021
2022 ///////////////////////////////////////////////////////////////////////////////
2023 ///Return an iterator on volumes of the current mesh.
2024 ///////////////////////////////////////////////////////////////////////////////
2025 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
2026 {
2027   typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
2028   SetOfVolumes::Iterator myIterator;
2029  public:
2030   SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
2031   {}
2032
2033   bool more()
2034   {
2035     return myIterator.More() != Standard_False;
2036   }
2037
2038   const SMDS_MeshVolume* next()
2039   {
2040     const SMDS_MeshVolume* current = myIterator.Value();
2041     myIterator.Next();
2042     return current;
2043   }
2044 };
2045
2046 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
2047 {
2048   return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
2049 }
2050
2051 ///////////////////////////////////////////////////////////////////////////////
2052 /// Do intersection of sets (more than 2)
2053 ///////////////////////////////////////////////////////////////////////////////
2054 static set<const SMDS_MeshElement*> * intersectionOfSets(
2055         set<const SMDS_MeshElement*> vs[], int numberOfSets)
2056 {
2057         set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
2058         set<const SMDS_MeshElement*>* rsetB;
2059
2060         for(int i=0; i<numberOfSets-1; i++)
2061         {
2062                 rsetB=new set<const SMDS_MeshElement*>();
2063                 set_intersection(
2064                         rsetA->begin(), rsetA->end(),
2065                         vs[i+1].begin(), vs[i+1].end(),
2066                         inserter(*rsetB, rsetB->begin()));
2067                 delete rsetA;
2068                 rsetA=rsetB;
2069         }
2070         return rsetA;
2071 }
2072
2073 ///////////////////////////////////////////////////////////////////////////////
2074 /// Return the list of finit elements owning the given element
2075 ///////////////////////////////////////////////////////////////////////////////
2076 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
2077 {
2078         int numberOfSets=element->NbNodes();
2079         set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
2080
2081         SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
2082
2083         int i=0;
2084         while(itNodes->more())
2085         {
2086                 const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2087                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2088
2089                 //initSet[i]=set<const SMDS_MeshElement*>();
2090                 while(itFe->more())
2091                   initSet[i].insert(itFe->next());
2092
2093                 i++;
2094         }
2095         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
2096         delete [] initSet;
2097         return retSet;
2098 }
2099
2100 ///////////////////////////////////////////////////////////////////////////////
2101 /// Return the list of nodes used only by the given elements
2102 ///////////////////////////////////////////////////////////////////////////////
2103 static set<const SMDS_MeshElement*> * getExclusiveNodes(
2104         set<const SMDS_MeshElement*>& elements)
2105 {
2106         set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
2107         set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
2108
2109         while(itElements!=elements.end())
2110         {
2111                 SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
2112                 itElements++;
2113         
2114                 while(itNodes->more())
2115                 {
2116                         const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
2117                         SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2118                         set<const SMDS_MeshElement*> s;
2119                         while(itFe->more())
2120                           s.insert(itFe->next());
2121                         if(s==elements) toReturn->insert(n);
2122                 }
2123         }
2124         return toReturn;        
2125 }
2126
2127 ///////////////////////////////////////////////////////////////////////////////
2128 ///Find the children of an element that are made of given nodes 
2129 ///@param setOfChildren The set in which matching children will be inserted
2130 ///@param element The element were to search matching children
2131 ///@param nodes The nodes that the children must have to be selected
2132 ///////////////////////////////////////////////////////////////////////////////
2133 void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren, 
2134         const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
2135 {
2136         
2137         switch(element->GetType())
2138         {
2139         case SMDSAbs_Node:
2140                 MESSAGE("Internal Error: This should not append");
2141                 break;
2142         case SMDSAbs_Edge:
2143         {
2144                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2145                 while(itn->more())
2146                 {
2147                         const SMDS_MeshElement * e=itn->next();
2148                         if(nodes.find(e)!=nodes.end())
2149                         {
2150                           setOfChildren.insert(element);
2151                           break;
2152                         }
2153                 }
2154         } break;
2155         case SMDSAbs_Face:
2156         {
2157                 SMDS_ElemIteratorPtr itn=element->nodesIterator();
2158                 while(itn->more())
2159                 {
2160                         const SMDS_MeshElement * e=itn->next();
2161                         if(nodes.find(e)!=nodes.end())
2162                         {
2163                           setOfChildren.insert(element);
2164                           break;
2165                         }
2166                 }
2167                 if(hasConstructionEdges())
2168                 {
2169                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2170                         while(ite->more())
2171                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2172                 }
2173         } break;        
2174         case SMDSAbs_Volume:
2175         {
2176                 if(hasConstructionFaces())
2177                 {
2178                         SMDS_ElemIteratorPtr ite=element->facesIterator();
2179                         while(ite->more())
2180                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2181                 }
2182                 else if(hasConstructionEdges())
2183                 {
2184                         SMDS_ElemIteratorPtr ite=element->edgesIterator();
2185                         while(ite->more())
2186                                 addChildrenWithNodes(setOfChildren, ite->next(), nodes);
2187                 }
2188         }
2189         }
2190 }
2191
2192 ///////////////////////////////////////////////////////////////////////////////
2193 ///@param elem The element to delete
2194 ///@param removenodes if true remaining nodes will be removed
2195 ///////////////////////////////////////////////////////////////////////////////
2196 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
2197         const bool removenodes)
2198 {
2199   list<const SMDS_MeshElement *> removedElems;
2200   list<const SMDS_MeshElement *> removedNodes;
2201   RemoveElement( elem, removedElems, removedNodes, removenodes );
2202 }
2203   
2204 ///////////////////////////////////////////////////////////////////////////////
2205 ///@param elem The element to delete
2206 ///@param removedElems contains all removed elements
2207 ///@param removedNodes contains all removed nodes
2208 ///@param removenodes if true remaining nodes will be removed
2209 ///////////////////////////////////////////////////////////////////////////////
2210 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
2211                               list<const SMDS_MeshElement *>& removedElems,
2212                               list<const SMDS_MeshElement *>& removedNodes,
2213                               bool                            removenodes)
2214 {
2215   // get finite elements built on elem
2216   set<const SMDS_MeshElement*> * s1;
2217   if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
2218       !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
2219       elem->GetType() == SMDSAbs_Volume)
2220   {
2221     s1 = new set<const SMDS_MeshElement*>();
2222     s1->insert(elem);
2223   }
2224   else
2225     s1 = getFinitElements(elem);
2226
2227   // get exclusive nodes (which would become free afterwards)
2228   set<const SMDS_MeshElement*> * s2;
2229   if (elem->GetType() == SMDSAbs_Node) // a node is removed
2230   {
2231     // do not remove nodes except elem
2232     s2 = new set<const SMDS_MeshElement*>();
2233     s2->insert(elem);
2234     removenodes = true;
2235   }
2236   else
2237     s2 = getExclusiveNodes(*s1);
2238
2239   // form the set of finite and construction elements to remove
2240   set<const SMDS_MeshElement*> s3;
2241   set<const SMDS_MeshElement*>::iterator it=s1->begin();
2242   while(it!=s1->end())
2243   {
2244     addChildrenWithNodes(s3, *it ,*s2);
2245     s3.insert(*it);
2246     it++;
2247   }
2248   if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
2249
2250   // remove finite and construction elements
2251   it=s3.begin();
2252   while(it!=s3.end())
2253   {
2254     // Remove element from <InverseElements> of its nodes
2255     SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
2256     while(itn->more())
2257     {
2258       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2259         (const_cast<SMDS_MeshElement *>(itn->next()));
2260       n->RemoveInverseElement( (*it) );
2261     }
2262
2263     switch((*it)->GetType())
2264     {
2265     case SMDSAbs_Node:
2266       MESSAGE("Internal Error: This should not happen");
2267       break;
2268     case SMDSAbs_Edge:
2269       myEdges.Remove(static_cast<SMDS_MeshEdge*>
2270                     (const_cast<SMDS_MeshElement*>(*it)));
2271       break;
2272     case SMDSAbs_Face:
2273       myFaces.Remove(static_cast<SMDS_MeshFace*>
2274                     (const_cast<SMDS_MeshElement*>(*it)));
2275       break;
2276     case SMDSAbs_Volume:
2277       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2278                       (const_cast<SMDS_MeshElement*>(*it)));
2279       break;
2280     }
2281     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
2282     removedElems.push_back( (*it) );
2283     myElementIDFactory->ReleaseID((*it)->GetID());
2284     delete (*it);
2285     it++;
2286   }
2287
2288   // remove exclusive (free) nodes
2289   if(removenodes)
2290   {
2291     it=s2->begin();
2292     while(it!=s2->end())
2293     {
2294       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
2295       myNodes.Remove(static_cast<SMDS_MeshNode*>
2296                     (const_cast<SMDS_MeshElement*>(*it)));
2297       myNodeIDFactory->ReleaseID((*it)->GetID());
2298       removedNodes.push_back( (*it) );
2299       delete *it;
2300       it++;
2301     }
2302   }
2303
2304   delete s2;
2305   delete s1;
2306 }
2307
2308   
2309 ///////////////////////////////////////////////////////////////////////////////
2310 ///@param elem The element to delete
2311 ///////////////////////////////////////////////////////////////////////////////
2312 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
2313 {
2314   SMDSAbs_ElementType aType = elem->GetType();
2315   if (aType == SMDSAbs_Node) {
2316     // only free node can be removed by this method
2317     const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
2318     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
2319     if (!itFe->more()) { // free node
2320       myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
2321       myNodeIDFactory->ReleaseID(elem->GetID());
2322       delete elem;
2323     }
2324   } else {
2325     if (hasConstructionEdges() || hasConstructionFaces())
2326       // this methods is only for meshes without descendants
2327       return;
2328
2329     // Remove element from <InverseElements> of its nodes
2330     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
2331     while (itn->more()) {
2332       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
2333         (const_cast<SMDS_MeshElement *>(itn->next()));
2334       n->RemoveInverseElement(elem);
2335     }
2336
2337     // in meshes without descendants elements are always free
2338     switch (aType) {
2339     case SMDSAbs_Edge:
2340       myEdges.Remove(static_cast<SMDS_MeshEdge*>
2341                      (const_cast<SMDS_MeshElement*>(elem)));
2342       break;
2343     case SMDSAbs_Face:
2344       myFaces.Remove(static_cast<SMDS_MeshFace*>
2345                      (const_cast<SMDS_MeshElement*>(elem)));
2346       break;
2347     case SMDSAbs_Volume:
2348       myVolumes.Remove(static_cast<SMDS_MeshVolume*>
2349                        (const_cast<SMDS_MeshElement*>(elem)));
2350       break;
2351     default:
2352       break;
2353     }
2354     myElementIDFactory->ReleaseID(elem->GetID());
2355     delete elem;
2356   }
2357 }
2358
2359 /*!
2360  * Checks if the element is present in mesh.
2361  * Useful to determine dead pointers.
2362  */
2363 bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
2364 {
2365   // we should not imply on validity of *elem, so iterate on containers
2366   // of all types in the hope of finding <elem> somewhere there
2367   SMDS_NodeIteratorPtr itn = nodesIterator();
2368   while (itn->more())
2369     if (elem == itn->next())
2370       return true;
2371   SMDS_EdgeIteratorPtr ite = edgesIterator();
2372   while (ite->more())
2373     if (elem == ite->next())
2374       return true;
2375   SMDS_FaceIteratorPtr itf = facesIterator();
2376   while (itf->more())
2377     if (elem == itf->next())
2378       return true;
2379   SMDS_VolumeIteratorPtr itv = volumesIterator();
2380   while (itv->more())
2381     if (elem == itv->next())
2382       return true;
2383   return false;
2384 }
2385
2386 //=======================================================================
2387 //function : MaxNodeID
2388 //purpose  : 
2389 //=======================================================================
2390
2391 int SMDS_Mesh::MaxNodeID() const
2392 {
2393   return myNodeIDFactory->GetMaxID();
2394 }
2395
2396 //=======================================================================
2397 //function : MinNodeID
2398 //purpose  : 
2399 //=======================================================================
2400
2401 int SMDS_Mesh::MinNodeID() const
2402 {
2403   return myNodeIDFactory->GetMinID();
2404 }
2405
2406 //=======================================================================
2407 //function : MaxElementID
2408 //purpose  : 
2409 //=======================================================================
2410
2411 int SMDS_Mesh::MaxElementID() const
2412 {
2413   return myElementIDFactory->GetMaxID();
2414 }
2415
2416 //=======================================================================
2417 //function : MinElementID
2418 //purpose  : 
2419 //=======================================================================
2420
2421 int SMDS_Mesh::MinElementID() const
2422 {
2423   return myElementIDFactory->GetMinID();
2424 }
2425
2426 //=======================================================================
2427 //function : Renumber
2428 //purpose  : Renumber all nodes or elements.
2429 //=======================================================================
2430
2431 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
2432 {
2433   if ( deltaID == 0 )
2434     return;
2435
2436   SMDS_MeshElementIDFactory * idFactory =
2437     isNodes ? myNodeIDFactory : myElementIDFactory;
2438
2439   // get existing elements in the order of ID increasing
2440   map<int,SMDS_MeshElement*> elemMap;
2441   SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
2442   while ( idElemIt->more() ) {
2443     SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
2444     int id = elem->GetID();
2445     elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
2446   }
2447   // release their ids
2448   map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
2449   for ( ; elemIt != elemMap.end(); elemIt++ )
2450   {
2451     int id = (*elemIt).first;
2452     idFactory->ReleaseID( id );
2453   }
2454   // set new IDs
2455   int ID = startID;
2456   elemIt = elemMap.begin();
2457   for ( ; elemIt != elemMap.end(); elemIt++ )
2458   {
2459     idFactory->BindID( ID, (*elemIt).second );
2460     ID += deltaID;
2461   }
2462 }
2463
2464 //=======================================================================
2465 //function : GetElementType
2466 //purpose  : Return type of element or node with id
2467 //=======================================================================
2468
2469 SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
2470 {
2471   SMDS_MeshElement* elem = 0;
2472   if( iselem )
2473     elem = myElementIDFactory->MeshElement( id );
2474   else
2475     elem = myNodeIDFactory->MeshElement( id );
2476
2477   if( !elem )
2478   {
2479     //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
2480     return SMDSAbs_All;
2481   }
2482   else
2483     return elem->GetType();
2484 }
2485
2486
2487
2488 //********************************************************************
2489 //********************************************************************
2490 //********                                                   *********
2491 //*****       Methods for addition of quadratic elements        ******
2492 //********                                                   *********
2493 //********************************************************************
2494 //********************************************************************
2495
2496 //=======================================================================
2497 //function : AddEdgeWithID
2498 //purpose  : 
2499 //=======================================================================
2500 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
2501 {
2502   return SMDS_Mesh::AddEdgeWithID
2503     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2504      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2505      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2506      ID);
2507 }
2508
2509 //=======================================================================
2510 //function : AddEdge
2511 //purpose  : 
2512 //=======================================================================
2513 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
2514                                   const SMDS_MeshNode* n2,
2515                                   const SMDS_MeshNode* n12)
2516 {
2517   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
2518 }
2519
2520 //=======================================================================
2521 //function : AddEdgeWithID
2522 //purpose  : 
2523 //=======================================================================
2524 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
2525                                         const SMDS_MeshNode * n2, 
2526                                         const SMDS_MeshNode * n12, 
2527                                         int ID)
2528 {
2529   if ( !n1 || !n2 || !n12 ) return 0;
2530   SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
2531   if(myElementIDFactory->BindID(ID, edge)) {
2532     SMDS_MeshNode *node1,*node2, *node12;
2533     node1 = const_cast<SMDS_MeshNode*>(n1);
2534     node2 = const_cast<SMDS_MeshNode*>(n2);
2535     node12 = const_cast<SMDS_MeshNode*>(n12);
2536     node1->AddInverseElement(edge);
2537     node2->AddInverseElement(edge);
2538     node12->AddInverseElement(edge);
2539     myEdges.Add(edge);
2540     return edge;
2541   } 
2542   else {
2543     delete edge;
2544     return NULL;
2545   }
2546 }
2547
2548
2549 //=======================================================================
2550 //function : AddFace
2551 //purpose  : 
2552 //=======================================================================
2553 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2554                                   const SMDS_MeshNode * n2,
2555                                   const SMDS_MeshNode * n3,
2556                                   const SMDS_MeshNode * n12,
2557                                   const SMDS_MeshNode * n23,
2558                                   const SMDS_MeshNode * n31)
2559 {
2560   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n12,n23,n31,
2561                                   myElementIDFactory->GetFreeID());
2562 }
2563
2564 //=======================================================================
2565 //function : AddFaceWithID
2566 //purpose  : 
2567 //=======================================================================
2568 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
2569                                         int n12,int n23,int n31, int ID)
2570 {
2571   return SMDS_Mesh::AddFaceWithID
2572     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2573      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2574      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2575      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2576      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2577      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n31),
2578      ID);
2579 }
2580
2581 //=======================================================================
2582 //function : AddFaceWithID
2583 //purpose  : 
2584 //=======================================================================
2585 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2586                                         const SMDS_MeshNode * n2,
2587                                         const SMDS_MeshNode * n3,
2588                                         const SMDS_MeshNode * n12,
2589                                         const SMDS_MeshNode * n23,
2590                                         const SMDS_MeshNode * n31, 
2591                                         int ID)
2592 {
2593   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
2594   if(hasConstructionEdges()) {
2595     // creation quadratic edges - not implemented
2596     return 0;
2597   }
2598   SMDS_QuadraticFaceOfNodes* face =
2599     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
2600   myFaces.Add(face);
2601
2602   if (!registerElement(ID, face)) {
2603     RemoveElement(face, false);
2604     face = NULL;
2605   }
2606   return face;
2607 }
2608
2609
2610 //=======================================================================
2611 //function : AddFace
2612 //purpose  : 
2613 //=======================================================================
2614 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
2615                                   const SMDS_MeshNode * n2,
2616                                   const SMDS_MeshNode * n3,
2617                                   const SMDS_MeshNode * n4,
2618                                   const SMDS_MeshNode * n12,
2619                                   const SMDS_MeshNode * n23,
2620                                   const SMDS_MeshNode * n34,
2621                                   const SMDS_MeshNode * n41)
2622 {
2623   return SMDS_Mesh::AddFaceWithID(n1,n2,n3,n4,n12,n23,n34,n41,
2624                                   myElementIDFactory->GetFreeID());
2625 }
2626
2627 //=======================================================================
2628 //function : AddFaceWithID
2629 //purpose  : 
2630 //=======================================================================
2631 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
2632                                         int n12,int n23,int n34,int n41, int ID)
2633 {
2634   return SMDS_Mesh::AddFaceWithID
2635     ((SMDS_MeshNode *)myNodeIDFactory->MeshElement(n1) ,
2636      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n2) ,
2637      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n3) ,
2638      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n4) ,
2639      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n12),
2640      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n23),
2641      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n34),
2642      (SMDS_MeshNode *)myNodeIDFactory->MeshElement(n41),
2643      ID);
2644 }
2645
2646 //=======================================================================
2647 //function : AddFaceWithID
2648 //purpose  : 
2649 //=======================================================================
2650 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
2651                                         const SMDS_MeshNode * n2,
2652                                         const SMDS_MeshNode * n3,
2653                                         const SMDS_MeshNode * n4,
2654                                         const SMDS_MeshNode * n12,
2655                                         const SMDS_MeshNode * n23,
2656                                         const SMDS_MeshNode * n34, 
2657                                         const SMDS_MeshNode * n41, 
2658                                         int ID)
2659 {
2660   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
2661   if(hasConstructionEdges()) {
2662     // creation quadratic edges - not implemented
2663   }
2664   SMDS_QuadraticFaceOfNodes* face =
2665     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
2666   myFaces.Add(face);
2667
2668   if (!registerElement(ID, face)) {
2669     RemoveElement(face, false);
2670     face = NULL;
2671   }
2672   return face;
2673 }
2674
2675
2676 //=======================================================================
2677 //function : AddVolume
2678 //purpose  : 
2679 //=======================================================================
2680 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2681                                       const SMDS_MeshNode * n2, 
2682                                       const SMDS_MeshNode * n3,
2683                                       const SMDS_MeshNode * n4,
2684                                       const SMDS_MeshNode * n12,
2685                                       const SMDS_MeshNode * n23,
2686                                       const SMDS_MeshNode * n31,
2687                                       const SMDS_MeshNode * n14, 
2688                                       const SMDS_MeshNode * n24,
2689                                       const SMDS_MeshNode * n34)
2690 {
2691   int ID = myElementIDFactory->GetFreeID();
2692   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n12, n23,
2693                                                    n31, n14, n24, n34, ID);
2694   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2695   return v;
2696 }
2697
2698 //=======================================================================
2699 //function : AddVolumeWithID
2700 //purpose  : 
2701 //=======================================================================
2702 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2703                                             int n12,int n23,int n31,
2704                                             int n14,int n24,int n34, int ID)
2705 {
2706   return SMDS_Mesh::AddVolumeWithID
2707     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2708      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2709      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2710      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2711      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2712      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2713      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2714      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2715      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n24),
2716      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2717      ID);
2718 }
2719
2720 //=======================================================================
2721 //function : AddVolumeWithID
2722 //purpose  : 2d order tetrahedron of 10 nodes
2723 //=======================================================================
2724 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2725                                             const SMDS_MeshNode * n2,
2726                                             const SMDS_MeshNode * n3,
2727                                             const SMDS_MeshNode * n4,
2728                                             const SMDS_MeshNode * n12,
2729                                             const SMDS_MeshNode * n23,
2730                                             const SMDS_MeshNode * n31,
2731                                             const SMDS_MeshNode * n14, 
2732                                             const SMDS_MeshNode * n24,
2733                                             const SMDS_MeshNode * n34,
2734                                             int ID)
2735 {
2736   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
2737     return 0;
2738   if(hasConstructionFaces()) {
2739     // creation quadratic faces - not implemented
2740     return 0;
2741   }
2742   SMDS_QuadraticVolumeOfNodes * volume =
2743     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
2744   myVolumes.Add(volume);
2745
2746   if (!registerElement(ID, volume)) {
2747     RemoveElement(volume, false);
2748     volume = NULL;
2749   }
2750   return volume;
2751 }
2752
2753
2754 //=======================================================================
2755 //function : AddVolume
2756 //purpose  : 
2757 //=======================================================================
2758 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2759                                       const SMDS_MeshNode * n2, 
2760                                       const SMDS_MeshNode * n3,
2761                                       const SMDS_MeshNode * n4,
2762                                       const SMDS_MeshNode * n5, 
2763                                       const SMDS_MeshNode * n12,
2764                                       const SMDS_MeshNode * n23,
2765                                       const SMDS_MeshNode * n34,
2766                                       const SMDS_MeshNode * n41,
2767                                       const SMDS_MeshNode * n15, 
2768                                       const SMDS_MeshNode * n25,
2769                                       const SMDS_MeshNode * n35,
2770                                       const SMDS_MeshNode * n45)
2771 {
2772   int ID = myElementIDFactory->GetFreeID();
2773   SMDS_MeshVolume * v =
2774     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n12, n23, n34, n41,
2775                                n15, n25, n35, n45, ID);
2776   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2777   return v;
2778 }
2779
2780 //=======================================================================
2781 //function : AddVolumeWithID
2782 //purpose  : 
2783 //=======================================================================
2784 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
2785                                             int n12,int n23,int n34,int n41,
2786                                             int n15,int n25,int n35,int n45, int ID)
2787 {
2788   return SMDS_Mesh::AddVolumeWithID
2789     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2790      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2791      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2792      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2793      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2794      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2795      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2796      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2797      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2798      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
2799      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2800      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n35),
2801      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2802      ID);
2803 }
2804
2805 //=======================================================================
2806 //function : AddVolumeWithID
2807 //purpose  : 2d order pyramid of 13 nodes
2808 //=======================================================================
2809 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2810                                             const SMDS_MeshNode * n2,
2811                                             const SMDS_MeshNode * n3,
2812                                             const SMDS_MeshNode * n4,
2813                                             const SMDS_MeshNode * n5, 
2814                                             const SMDS_MeshNode * n12,
2815                                             const SMDS_MeshNode * n23,
2816                                             const SMDS_MeshNode * n34,
2817                                             const SMDS_MeshNode * n41,
2818                                             const SMDS_MeshNode * n15, 
2819                                             const SMDS_MeshNode * n25,
2820                                             const SMDS_MeshNode * n35,
2821                                             const SMDS_MeshNode * n45,
2822                                             int ID)
2823 {
2824   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
2825       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
2826     return 0;
2827   if(hasConstructionFaces()) {
2828     // creation quadratic faces - not implemented
2829     return 0;
2830   }
2831   SMDS_QuadraticVolumeOfNodes * volume =
2832     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
2833                                     n34,n41,n15,n25,n35,n45);
2834   myVolumes.Add(volume);
2835
2836   if (!registerElement(ID, volume)) {
2837     RemoveElement(volume, false);
2838     volume = NULL;
2839   }
2840   return volume;
2841 }
2842
2843
2844 //=======================================================================
2845 //function : AddVolume
2846 //purpose  : 
2847 //=======================================================================
2848 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2849                                       const SMDS_MeshNode * n2, 
2850                                       const SMDS_MeshNode * n3,
2851                                       const SMDS_MeshNode * n4,
2852                                       const SMDS_MeshNode * n5, 
2853                                       const SMDS_MeshNode * n6, 
2854                                       const SMDS_MeshNode * n12,
2855                                       const SMDS_MeshNode * n23,
2856                                       const SMDS_MeshNode * n31, 
2857                                       const SMDS_MeshNode * n45,
2858                                       const SMDS_MeshNode * n56,
2859                                       const SMDS_MeshNode * n64, 
2860                                       const SMDS_MeshNode * n14,
2861                                       const SMDS_MeshNode * n25,
2862                                       const SMDS_MeshNode * n36)
2863 {
2864   int ID = myElementIDFactory->GetFreeID();
2865   SMDS_MeshVolume * v =
2866     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n12, n23, n31,
2867                                n45, n56, n64, n14, n25, n36, ID);
2868   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2869   return v;
2870 }
2871
2872 //=======================================================================
2873 //function : AddVolumeWithID
2874 //purpose  : 
2875 //=======================================================================
2876 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
2877                                             int n4, int n5, int n6,
2878                                             int n12,int n23,int n31,
2879                                             int n45,int n56,int n64,
2880                                             int n14,int n25,int n36, int ID)
2881 {
2882   return SMDS_Mesh::AddVolumeWithID
2883     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1) ,
2884      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2) ,
2885      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3) ,
2886      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4) ,
2887      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5) ,
2888      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6) ,
2889      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2890      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2891      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n31),
2892      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n45),
2893      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2894      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n64),
2895      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n14),
2896      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n25),
2897      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n36),
2898      ID);
2899 }
2900
2901 //=======================================================================
2902 //function : AddVolumeWithID
2903 //purpose  : 2d order Pentahedron with 15 nodes
2904 //=======================================================================
2905 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
2906                                             const SMDS_MeshNode * n2,
2907                                             const SMDS_MeshNode * n3,
2908                                             const SMDS_MeshNode * n4,
2909                                             const SMDS_MeshNode * n5, 
2910                                             const SMDS_MeshNode * n6, 
2911                                             const SMDS_MeshNode * n12,
2912                                             const SMDS_MeshNode * n23,
2913                                             const SMDS_MeshNode * n31, 
2914                                             const SMDS_MeshNode * n45,
2915                                             const SMDS_MeshNode * n56,
2916                                             const SMDS_MeshNode * n64, 
2917                                             const SMDS_MeshNode * n14,
2918                                             const SMDS_MeshNode * n25,
2919                                             const SMDS_MeshNode * n36,
2920                                             int ID)
2921 {
2922   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
2923       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
2924     return 0;
2925   if(hasConstructionFaces()) {
2926     // creation quadratic faces - not implemented
2927     return 0;
2928   }
2929   SMDS_QuadraticVolumeOfNodes * volume =
2930     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
2931                                     n45,n56,n64,n14,n25,n36);
2932   myVolumes.Add(volume);
2933
2934   if (!registerElement(ID, volume)) {
2935     RemoveElement(volume, false);
2936     volume = NULL;
2937   }
2938   return volume;
2939 }
2940
2941
2942 //=======================================================================
2943 //function : AddVolume
2944 //purpose  : 
2945 //=======================================================================
2946 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
2947                                       const SMDS_MeshNode * n2, 
2948                                       const SMDS_MeshNode * n3,
2949                                       const SMDS_MeshNode * n4,
2950                                       const SMDS_MeshNode * n5, 
2951                                       const SMDS_MeshNode * n6, 
2952                                       const SMDS_MeshNode * n7,
2953                                       const SMDS_MeshNode * n8, 
2954                                       const SMDS_MeshNode * n12,
2955                                       const SMDS_MeshNode * n23,
2956                                       const SMDS_MeshNode * n34,
2957                                       const SMDS_MeshNode * n41, 
2958                                       const SMDS_MeshNode * n56,
2959                                       const SMDS_MeshNode * n67,
2960                                       const SMDS_MeshNode * n78,
2961                                       const SMDS_MeshNode * n85, 
2962                                       const SMDS_MeshNode * n15,
2963                                       const SMDS_MeshNode * n26,
2964                                       const SMDS_MeshNode * n37,
2965                                       const SMDS_MeshNode * n48)
2966 {
2967   int ID = myElementIDFactory->GetFreeID();
2968   SMDS_MeshVolume * v =
2969     SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, n12, n23, n34, n41,
2970                                n56, n67, n78, n85, n15, n26, n37, n48, ID);
2971   if(v==NULL) myElementIDFactory->ReleaseID(ID);
2972   return v;
2973 }
2974
2975 //=======================================================================
2976 //function : AddVolumeWithID
2977 //purpose  : 
2978 //=======================================================================
2979 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
2980                                             int n5, int n6, int n7, int n8,
2981                                             int n12,int n23,int n34,int n41,
2982                                             int n56,int n67,int n78,int n85,
2983                                             int n15,int n26,int n37,int n48, int ID)
2984 {
2985   return SMDS_Mesh::AddVolumeWithID
2986     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
2987      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n2),
2988      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n3),
2989      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n4),
2990      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n5),
2991      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n6),
2992      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n7),
2993      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n8),
2994      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n12),
2995      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n23),
2996      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n34),
2997      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n41),
2998      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n56),
2999      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n67),
3000      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n78),
3001      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n85),
3002      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n15),
3003      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n26),
3004      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n37),
3005      (SMDS_MeshNode*) myNodeIDFactory->MeshElement(n48),
3006      ID);
3007 }
3008
3009 //=======================================================================
3010 //function : AddVolumeWithID
3011 //purpose  : 2d order Hexahedrons with 20 nodes
3012 //=======================================================================
3013 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
3014                                             const SMDS_MeshNode * n2,
3015                                             const SMDS_MeshNode * n3,
3016                                             const SMDS_MeshNode * n4,
3017                                             const SMDS_MeshNode * n5, 
3018                                             const SMDS_MeshNode * n6, 
3019                                             const SMDS_MeshNode * n7,
3020                                             const SMDS_MeshNode * n8, 
3021                                             const SMDS_MeshNode * n12,
3022                                             const SMDS_MeshNode * n23,
3023                                             const SMDS_MeshNode * n34,
3024                                             const SMDS_MeshNode * n41, 
3025                                             const SMDS_MeshNode * n56,
3026                                             const SMDS_MeshNode * n67,
3027                                             const SMDS_MeshNode * n78,
3028                                             const SMDS_MeshNode * n85, 
3029                                             const SMDS_MeshNode * n15,
3030                                             const SMDS_MeshNode * n26,
3031                                             const SMDS_MeshNode * n37,
3032                                             const SMDS_MeshNode * n48,
3033                                             int ID)
3034 {
3035   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
3036       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
3037     return 0;
3038   if(hasConstructionFaces()) {
3039     return 0;
3040     // creation quadratic faces - not implemented
3041   }
3042   SMDS_QuadraticVolumeOfNodes * volume =
3043     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
3044                                     n56,n67,n78,n85,n15,n26,n37,n48);
3045   myVolumes.Add(volume);
3046
3047   if (!registerElement(ID, volume)) {
3048     RemoveElement(volume, false);
3049     volume = NULL;
3050   }
3051   return volume;
3052 }