Salome HOME
yfr : Merge with v1.2
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
1 //  SMESH SMDS : implementaion of Salome mesh data structure
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMDS_Mesh.cxx
25 //  Author : Jean-Michel BOULCOURT
26 //  Module : SMESH
27
28 using namespace std;
29 #include "SMDS_Mesh.ixx"
30 #include "SMDS_MapIteratorOfExtendedOrientedMap.hxx"
31 #include "SMDS_ListOfMeshElement.hxx"
32 #include "SMDS_ListIteratorOfListOfMeshElement.hxx"
33 #include "SMDS_MeshNode.hxx"
34 #include "SMDS_MeshEdge.hxx"
35 #include "SMDS_MeshFace.hxx"
36 #include "SMDS_MeshTriangle.hxx"
37 #include "SMDS_MeshQuadrangle.hxx"
38 #include "SMDS_MeshVolume.hxx"
39 #include "SMDS_MeshTetrahedron.hxx"
40 #include "SMDS_MeshPyramid.hxx"
41 #include "SMDS_MeshPrism.hxx"
42 #include "SMDS_MeshHexahedron.hxx"
43 #include "SMDS_ListOfMesh.hxx"
44 #include "SMDS_ListIteratorOfListOfMesh.hxx"
45
46
47 #include <Standard_ErrorHandler.hxx>
48 #include <Standard_NoSuchObject.hxx>
49
50 #include "utilities.h"
51
52
53 //=======================================================================
54 //function : SMDS_Mesh
55 //purpose  : creation of a new mesh object
56 //=======================================================================
57
58 SMDS_Mesh::SMDS_Mesh(const Standard_Integer nbnodes,
59                      const Standard_Integer nbedges, 
60                      const Standard_Integer nbfaces,
61                      const Standard_Integer nbvolumes)
62   :myNodes(nbnodes),myEdges(nbedges),myFaces(nbfaces),myVolumes(nbvolumes),
63    myNodeIDFactory(new SMDS_MeshNodeIDFactory()), 
64    myElementIDFactory(new SMDS_MeshElementIDFactory()),myHasInverse(Standard_False)
65 {
66 }
67
68 //=======================================================================
69 //function : SMDS_Mesh
70 //purpose  :  
71 //=======================================================================
72
73 SMDS_Mesh::SMDS_Mesh(const Handle(SMDS_Mesh)& parent,
74                      const Standard_Integer nbnodes)
75   :myNodes(nbnodes),myParent(parent),myNodeIDFactory(parent->myNodeIDFactory),
76    myElementIDFactory(parent->myElementIDFactory),
77    myHasInverse(Standard_False)
78 {
79 }
80
81 //=======================================================================
82 //function : AddSubMesh
83 //purpose  : create an submesh
84 //=======================================================================
85
86 Handle(SMDS_Mesh) SMDS_Mesh::AddSubMesh()
87 {
88   Handle(SMDS_Mesh) submesh = new SMDS_Mesh(this);
89   if (!submesh.IsNull()) {
90     myChildren.Append(submesh);
91   }
92
93   return submesh;
94 }
95
96
97 //=======================================================================
98 //function : AddNode
99 //purpose  : create a MeshNode and returns an ID
100 //=======================================================================
101
102 Standard_Integer SMDS_Mesh::AddNode(const Standard_Real x, 
103                                     const Standard_Real y, 
104                                     const Standard_Real z)
105 {
106   Standard_Integer ID = myNodeIDFactory->GetFreeID();
107
108   Handle(SMDS_MeshElement) node = new SMDS_MeshNode(ID,x,y,z);
109   AddNode(node);
110
111   return ID;
112 }
113
114 //=======================================================================
115 //function : AddNode
116 //purpose  : create a MeshNode. Returns False if the ID already exists
117 //=======================================================================
118
119 Standard_Boolean SMDS_Mesh::AddNodeWithID(const Standard_Real x, 
120                                           const Standard_Real y, 
121                                           const Standard_Real z,
122                                           const Standard_Integer ID)
123 {
124
125   // find the MeshNode corresponding to ID
126   Handle(SMDS_MeshElement) node;
127   node = GetNode(ID);
128
129   if (node.IsNull()) {
130     node = new SMDS_MeshNode(ID,x,y,z);
131     AddNode(node);
132     return Standard_True;
133   } else
134     return Standard_False;
135     
136 }
137
138 //=======================================================================
139 //function : AddNode
140 //purpose  : add  an existing node in  the mesh (useful for submesh)
141 //=======================================================================
142
143 Standard_Boolean SMDS_Mesh::AddNode(const Standard_Integer ID)
144 {
145   // find the MeshNode corresponding to ID
146   Handle(SMDS_MeshElement) node;
147
148   node = GetNode(ID);
149
150   if (!node.IsNull()) {
151     myNodes.Add(node);
152     return Standard_True;;
153   } else
154     return Standard_False;
155 }
156
157 //=======================================================================
158 //function : AddNode
159 //purpose  : 
160 //=======================================================================
161
162 Standard_Boolean SMDS_Mesh::AddNode(const Handle(SMDS_MeshElement)& node)
163 {
164
165   if (!node.IsNull()) {
166     myNodes.Add(node);
167     if (!myParent.IsNull()) {
168       myParent->AddNode(node);
169     }
170     return Standard_True;
171   } else
172     return Standard_False;
173 }
174
175
176 //=======================================================================
177 //function : AddEdge
178 //purpose  : 
179 //=======================================================================
180
181 Standard_Integer SMDS_Mesh::AddEdge(const Standard_Integer idnode1,
182                                             const Standard_Integer idnode2)
183 {
184   Standard_Integer ID = myElementIDFactory->GetFreeID();
185   
186   if (AddEdgeWithID(idnode1,idnode2,ID))
187     return ID;
188   else 
189     return 0;
190
191 }
192
193 //=======================================================================
194 //function : AddEdge
195 //purpose  : 
196 //=======================================================================
197
198 Standard_Boolean SMDS_Mesh::AddEdgeWithID(const Standard_Integer idnode1,
199                                           const Standard_Integer idnode2,
200                                           const Standard_Integer ID)
201 {
202   Handle(SMDS_MeshElement) edge,elem;
203   Standard_Boolean successAdd = Standard_False;
204
205   // find the MeshNode corresponding to idnode1
206   if (AddNode(idnode1)) {
207     // find the MeshNode corresponding to idnode2
208     if (AddNode(idnode2)) {
209       elem = CreateEdge(ID,idnode1,idnode2);
210       edge = FindEdge(elem);
211       if (edge.IsNull()) {
212         edge = elem;
213         myEdges.Add(edge);
214       }
215       successAdd = myElementIDFactory->BindID(ID,edge);
216     }
217   }
218   
219   return successAdd;
220
221 }
222
223 //=======================================================================
224 //function : AddFace
225 //purpose  : 
226 //=======================================================================
227
228 Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, 
229                                     const Standard_Integer idnode2,
230                                     const Standard_Integer idnode3)
231 {
232   Standard_Integer ID = myElementIDFactory->GetFreeID();
233   
234   if (AddFaceWithID(idnode1,idnode2,idnode3,ID))
235     return ID;
236   else 
237     return 0;
238
239 }
240
241 //=======================================================================
242 //function : AddFace
243 //purpose  : 
244 //=======================================================================
245
246 Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, 
247                                           const Standard_Integer idnode2,
248                                           const Standard_Integer idnode3,
249                                           const Standard_Integer ID)
250 {
251   Handle(SMDS_MeshElement) face,elem;
252   Standard_Boolean successAdd = Standard_False;
253
254   // find the MeshNode corresponding to idnode1
255   if (AddNode(idnode1)) {
256     // find the MeshNode corresponding to idnode2
257     if (AddNode(idnode2)) {
258       // find the MeshNode corresponding to idnode3
259       if (AddNode(idnode3)) {
260         elem = CreateFace(ID,idnode1,idnode2,idnode3);
261         face = FindFace(elem);
262         if (face.IsNull()) {
263           face = elem;
264           myFaces.Add(face);
265         }
266         successAdd = myElementIDFactory->BindID(ID,face);
267       }
268     }
269   }
270
271   return successAdd;
272
273 }
274
275
276 //=======================================================================
277 //function : AddFace
278 //purpose  : 
279 //=======================================================================
280
281 Standard_Integer SMDS_Mesh::AddFace(const Standard_Integer idnode1, 
282                                             const Standard_Integer idnode2,
283                                             const Standard_Integer idnode3,
284                                             const Standard_Integer idnode4)
285 {
286   Standard_Integer ID = myElementIDFactory->GetFreeID();
287   
288   if (AddFaceWithID(idnode1,idnode2,idnode3,idnode4,ID))
289     return ID;
290   else
291     return 0;
292
293 }
294
295
296 //=======================================================================
297 //function : AddFace
298 //purpose  : 
299 //=======================================================================
300
301 Standard_Boolean SMDS_Mesh::AddFaceWithID(const Standard_Integer idnode1, 
302                                           const Standard_Integer idnode2,
303                                           const Standard_Integer idnode3,
304                                           const Standard_Integer idnode4,
305                                           const Standard_Integer ID)
306 {
307   Handle(SMDS_MeshElement) face,elem;
308   Standard_Boolean successAdd = Standard_False;
309
310   // find the MeshNode corresponding to idnode1
311   if (AddNode(idnode1)) {
312     // find the MeshNode corresponding to idnode2
313     if (AddNode(idnode2)) {
314       // find the MeshNode corresponding to idnode3
315       if (AddNode(idnode3)) {
316         // find the MeshNode corresponding to idnode4
317         if (AddNode(idnode4)) {
318           elem = CreateFace(ID,idnode1,idnode2,idnode3,idnode4);
319           face = FindFace(elem);
320           if (face.IsNull()) {
321             face = elem;
322             myFaces.Add(face);
323           }
324           successAdd = myElementIDFactory->BindID(ID,face);
325         }
326       }
327     }
328   }
329
330   return successAdd;
331
332 }
333
334
335
336 //=======================================================================
337 //function : AddVolume
338 //purpose  : Tetrahedra
339 //=======================================================================
340
341 Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, 
342                                       const Standard_Integer idnode2,
343                                       const Standard_Integer idnode3,
344                                       const Standard_Integer idnode4)
345 {
346   Standard_Integer ID = myElementIDFactory->GetFreeID();
347   
348   if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,ID))
349     return ID;
350   else
351     return 0;
352
353 }
354
355 //=======================================================================
356 //function : AddVolume
357 //purpose  : Tetrahedra
358 //=======================================================================
359
360 Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, 
361                                             const Standard_Integer idnode2,
362                                             const Standard_Integer idnode3,
363                                             const Standard_Integer idnode4,
364                                             const Standard_Integer ID)
365 {
366   Handle(SMDS_MeshElement) volume,elem;
367   Standard_Boolean successAdd = Standard_False;
368
369   // find the MeshNode corresponding to idnode1
370   if (AddNode(idnode1)) {
371     // find the MeshNode corresponding to idnode2
372     if (AddNode(idnode2)) {
373       // find the MeshNode corresponding to idnode3
374       if (AddNode(idnode3)) {
375         // find the MeshNode corresponding to idnode4
376         if (AddNode(idnode4)) {
377           elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4);
378           volume = FindVolume(elem);
379           if (volume.IsNull()) {
380             volume = elem;
381             myVolumes.Add(volume);
382           }
383           successAdd = myElementIDFactory->BindID(ID,volume);
384         }
385       }
386     }
387   }
388
389   return successAdd;
390
391 }
392
393 //=======================================================================
394 //function : AddVolume
395 //purpose  : Pyramid
396 //=======================================================================
397
398 Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, 
399                                       const Standard_Integer idnode2,
400                                       const Standard_Integer idnode3,
401                                       const Standard_Integer idnode4,
402                                       const Standard_Integer idnode5)
403 {
404   Standard_Integer ID = myElementIDFactory->GetFreeID();
405   
406   if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,idnode5,ID))
407     return ID;
408   else
409     return 0;
410
411 }
412
413 //=======================================================================
414 //function : AddVolume
415 //purpose  : Pyramid
416 //=======================================================================
417
418 Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, 
419                                                     const Standard_Integer idnode2,
420                                                     const Standard_Integer idnode3,
421                                                     const Standard_Integer idnode4,
422                                                     const Standard_Integer idnode5,
423                                                     const Standard_Integer ID)
424 {
425   Handle(SMDS_MeshElement) volume,elem;
426   Standard_Boolean successAdd = Standard_False;
427
428   // find the MeshNode corresponding to idnode1
429   if (AddNode(idnode1)) {
430     // find the MeshNode corresponding to idnode2
431     if (AddNode(idnode2)) {
432       // find the MeshNode corresponding to idnode3
433       if (AddNode(idnode3)) {
434         // find the MeshNode corresponding to idnode4
435         if (AddNode(idnode4)) {
436           // find the MeshNode corresponding to idnode5
437           if (AddNode(idnode5)) {
438             elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5);
439             volume = FindVolume(elem);
440             if (volume.IsNull()) {
441               volume = elem;
442               myVolumes.Add(volume);
443             }
444             successAdd = myElementIDFactory->BindID(ID,volume);
445           }
446         }
447       }
448     }
449   }
450
451   return successAdd;
452
453 }
454
455 //=======================================================================
456 //function : AddVolume
457 //purpose  : Prism
458 //=======================================================================
459
460 Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, 
461                                       const Standard_Integer idnode2,
462                                       const Standard_Integer idnode3,
463                                       const Standard_Integer idnode4,
464                                       const Standard_Integer idnode5,
465                                       const Standard_Integer idnode6)
466 {
467   Standard_Integer ID = myElementIDFactory->GetFreeID();
468   
469   if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,
470                       idnode5,idnode6,ID))
471     return ID;
472   else
473     return 0;
474
475 }
476
477 //=======================================================================
478 //function : AddVolume
479 //purpose  : Prism
480 //=======================================================================
481
482 Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, 
483                                             const Standard_Integer idnode2,
484                                             const Standard_Integer idnode3,
485                                             const Standard_Integer idnode4,
486                                             const Standard_Integer idnode5,
487                                             const Standard_Integer idnode6,
488                                             const Standard_Integer ID)
489 {
490   Handle(SMDS_MeshElement) volume,elem;
491   Standard_Boolean successAdd = Standard_False;
492
493   // find the MeshNode corresponding to idnode1
494   if (AddNode(idnode1)) {
495     // find the MeshNode corresponding to idnode2
496     if (AddNode(idnode2)) {
497       // find the MeshNode corresponding to idnode3
498       if (AddNode(idnode3)) {
499         // find the MeshNode corresponding to idnode4
500         if (AddNode(idnode4)) {
501           // find the MeshNode corresponding to idnode5
502           if (AddNode(idnode5)) {
503             // find the MeshNode corresponding to idnode6
504             if (AddNode(idnode6)) {
505               elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6);
506               volume = FindVolume(elem);
507               if (volume.IsNull()) {
508                 volume = elem;
509                 myVolumes.Add(volume);
510               }
511               successAdd = myElementIDFactory->BindID(ID,volume);
512             }
513           }
514         }
515       }
516     }
517   }
518
519   return successAdd;
520
521 }
522
523 //=======================================================================
524 //function : AddVolume
525 //purpose  : Hexahedra
526 //=======================================================================
527
528 Standard_Integer SMDS_Mesh::AddVolume(const Standard_Integer idnode1, 
529                                       const Standard_Integer idnode2,
530                                       const Standard_Integer idnode3,
531                                       const Standard_Integer idnode4,
532                                       const Standard_Integer idnode5,
533                                       const Standard_Integer idnode6,
534                                       const Standard_Integer idnode7,
535                                       const Standard_Integer idnode8)
536 {
537   Standard_Integer ID = myElementIDFactory->GetFreeID();
538   
539   if (AddVolumeWithID(idnode1,idnode2,idnode3,idnode4,
540                       idnode5,idnode6,idnode7,idnode8,ID))
541     return ID;
542   else
543     return 0;
544
545 }
546
547 //=======================================================================
548 //function : AddVolume
549 //purpose  : Hexahedra
550 //=======================================================================
551
552 Standard_Boolean SMDS_Mesh::AddVolumeWithID(const Standard_Integer idnode1, 
553                                             const Standard_Integer idnode2,
554                                             const Standard_Integer idnode3,
555                                             const Standard_Integer idnode4,
556                                             const Standard_Integer idnode5,
557                                             const Standard_Integer idnode6,
558                                             const Standard_Integer idnode7,
559                                             const Standard_Integer idnode8,
560                                             const Standard_Integer ID)
561 {
562   Handle(SMDS_MeshElement) volume,elem;
563   Standard_Boolean successAdd = Standard_False;
564
565   // find the MeshNode corresponding to idnode1
566   if (AddNode(idnode1)) {
567     // find the MeshNode corresponding to idnode2
568     if (AddNode(idnode2)) {
569       // find the MeshNode corresponding to idnode3
570       if (AddNode(idnode3)) {
571         // find the MeshNode corresponding to idnode4
572         if (AddNode(idnode4)) {
573           // find the MeshNode corresponding to idnode5
574           if (AddNode(idnode5)) {
575             // find the MeshNode corresponding to idnode6
576             if (AddNode(idnode6)) {
577               // find the MeshNode corresponding to idnode7
578               if (AddNode(idnode7)) {
579                 // find the MeshNode corresponding to idnode8
580                 if (AddNode(idnode8)) {
581                   elem = CreateVolume(ID,idnode1,idnode2,idnode3,idnode4,idnode5,
582                                       idnode6,idnode7,idnode8);
583                   volume = FindVolume(elem);
584                   if (volume.IsNull()) {
585                     volume = elem;
586                     myVolumes.Add(volume);
587                   }
588                   successAdd = myElementIDFactory->BindID(ID,volume);
589                 }
590               }
591             }
592           }
593         }
594       }
595     }
596   }
597
598   return successAdd;
599
600 }
601
602
603 //=======================================================================
604 //function : GetNode
605 //purpose  : returns the MeshNode corresponding to the ID
606 //=======================================================================
607
608 Handle(SMDS_MeshElement) SMDS_Mesh::GetNode(const Standard_Integer idnode) const
609 {
610
611   Handle(SMDS_MeshElement) node;
612
613   Handle(SMDS_MeshElement) elem = FindNode(idnode);
614   if (!elem.IsNull()) { // found one correspondance
615     node =  elem;
616   } else {
617     if (!myParent.IsNull())
618       node = myParent->GetNode(idnode);
619   }
620
621   return node;
622 }
623
624 //=======================================================================
625 //function : FindNode
626 //purpose  : 
627 //=======================================================================
628
629 Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Standard_Integer ID) const
630 {
631   Handle(SMDS_MeshElement) elem;
632   if (myNodes.ContainsID(ID))
633     elem = myNodes.FindID(ID);
634   return elem;
635 }
636
637 //=======================================================================
638 //function : FindNode
639 //purpose  : 
640 //=======================================================================
641
642 Handle(SMDS_MeshElement) SMDS_Mesh::FindNode(const Handle(SMDS_MeshElement)& node) const
643 {
644   Handle(SMDS_MeshElement) elem;
645   if (myNodes.Contains(node))
646     elem = myNodes.Find(node);
647
648   return elem;
649 }
650
651 //=======================================================================
652 //function : CreateEdge
653 //purpose  : 
654 //=======================================================================
655
656 Handle(SMDS_MeshElement) SMDS_Mesh::CreateEdge(const Standard_Integer ID,
657                                                const Standard_Integer idnode1,
658                                                const Standard_Integer idnode2) const
659 {
660   Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(ID,idnode1,idnode2);
661   return edge;
662 }
663
664
665 //=======================================================================
666 //function : CreateFace
667 //purpose  : 
668 //=======================================================================
669
670 Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID,
671                                                const Standard_Integer idnode1,
672                                                const Standard_Integer idnode2,
673                                                const Standard_Integer idnode3) const
674 {
675   Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(ID,idnode1,idnode2,idnode3);
676   return face;
677 }
678
679
680 //=======================================================================
681 //function : CreateFace
682 //purpose  : 
683 //=======================================================================
684
685 Handle(SMDS_MeshElement) SMDS_Mesh::CreateFace(const Standard_Integer ID,
686                                                const Standard_Integer idnode1,
687                                                const Standard_Integer idnode2,
688                                                const Standard_Integer idnode3,
689                                                const Standard_Integer idnode4) const
690 {
691   Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(ID,idnode1,idnode2,idnode3,idnode4);
692   return face;
693 }
694
695 //=======================================================================
696 //function : CreateVolume
697 //purpose  : 
698 //=======================================================================
699
700 Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID,
701                                                  const Standard_Integer idnode1,
702                                                  const Standard_Integer idnode2,
703                                                  const Standard_Integer idnode3,
704                                                  const Standard_Integer idnode4) const
705 {
706   Handle(SMDS_MeshVolume) volume = new SMDS_MeshTetrahedron(ID,idnode1,idnode2,idnode3,idnode4);
707   return volume;
708 }
709
710 //=======================================================================
711 //function : CreateVolume
712 //purpose  : 
713 //=======================================================================
714
715 Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID,
716                                                  const Standard_Integer idnode1,
717                                                  const Standard_Integer idnode2,
718                                                  const Standard_Integer idnode3,
719                                                  const Standard_Integer idnode4,
720                                                  const Standard_Integer idnode5) const
721 {
722   Handle(SMDS_MeshVolume) volume = new SMDS_MeshPyramid(ID,idnode1,idnode2,idnode3,idnode4,idnode5);
723   return volume;
724 }
725
726 //=======================================================================
727 //function : CreateVolume
728 //purpose  : 
729 //=======================================================================
730
731 Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID,
732                                                  const Standard_Integer idnode1,
733                                                  const Standard_Integer idnode2,
734                                                  const Standard_Integer idnode3,
735                                                  const Standard_Integer idnode4,
736                                                  const Standard_Integer idnode5,
737                                                  const Standard_Integer idnode6) const
738 {
739   Handle(SMDS_MeshVolume) volume = new SMDS_MeshPrism(ID,idnode1,idnode2,idnode3,idnode4,idnode5,idnode6);
740   return volume;
741 }
742
743 //=======================================================================
744 //function : CreateVolume
745 //purpose  : 
746 //=======================================================================
747
748 Handle(SMDS_MeshElement) SMDS_Mesh::CreateVolume(const Standard_Integer ID,
749                                                  const Standard_Integer idnode1,
750                                                  const Standard_Integer idnode2,
751                                                  const Standard_Integer idnode3,
752                                                  const Standard_Integer idnode4,
753                                                  const Standard_Integer idnode5,
754                                                  const Standard_Integer idnode6,
755                                                  const Standard_Integer idnode7,
756                                                  const Standard_Integer idnode8) const
757 {
758   Handle(SMDS_MeshVolume) volume = new SMDS_MeshHexahedron(ID,idnode1,idnode2,idnode3,idnode4,
759                                                            idnode5,idnode6,idnode7,idnode8);
760   return volume;
761 }
762
763 //=======================================================================
764 //function : Contains
765 //purpose  : 
766 //=======================================================================
767
768 Standard_Boolean SMDS_Mesh::Contains(const Handle(SMDS_MeshElement)& elem) const
769 {
770   Standard_Boolean isinmesh = Standard_False;
771   if (myNodes.Contains(elem))
772     isinmesh = Standard_True;
773   else if (myEdges.Contains(elem))
774     isinmesh = Standard_True;
775   else if (myFaces.Contains(elem))
776     isinmesh = Standard_True;
777   else if (myVolumes.Contains(elem))
778     isinmesh = Standard_True;
779
780   return isinmesh;
781 }
782
783 //=======================================================================
784 //function : FindEdge
785 //purpose  : 
786 //=======================================================================
787
788 Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Handle(SMDS_MeshElement)& edge) const
789 {
790   Handle(SMDS_MeshElement) elem;
791   if (myEdges.Contains(edge))
792     elem = myEdges.Find(edge);
793
794   return elem;
795 }
796
797 //=======================================================================
798 //function : FindFace
799 //purpose  : 
800 //=======================================================================
801
802 Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Handle(SMDS_MeshElement)& face) const
803 {
804   Handle(SMDS_MeshElement) elem;
805   if (myFaces.Contains(face))
806     elem = myFaces.Find(face);
807
808   return elem;
809 }
810
811
812 //=======================================================================
813 //function : FindVolume
814 //purpose  : 
815 //=======================================================================
816
817 Handle(SMDS_MeshElement) SMDS_Mesh::FindVolume(const Handle(SMDS_MeshElement)& volume) const
818 {
819   Handle(SMDS_MeshElement) elem;
820   if (myVolumes.Contains(volume))
821     elem = myVolumes.Find(volume);
822
823   return elem;
824 }
825
826
827 //=======================================================================
828 //function : FreeNode
829 //purpose  : 
830 //=======================================================================
831
832 void SMDS_Mesh::FreeNode(const Handle(SMDS_MeshElement)& node)
833 {
834     myNodes.Remove(node);
835
836     SMDS_ListIteratorOfListOfMesh itmsh(myChildren);
837     for (;itmsh.More(); itmsh.Next()) {
838       const Handle(SMDS_Mesh)& submesh = itmsh.Value();
839       submesh->RemoveNode(node->GetID());
840     }
841 }
842
843
844
845 //=======================================================================
846 //function : RemoveNode
847 //purpose  : 
848 //=======================================================================
849
850 void SMDS_Mesh::RemoveNode(const Standard_Integer IDnode)
851 {
852   // find the MeshNode corresponding to IDnode
853   Handle(SMDS_MeshElement) node = FindNode(IDnode);
854   if (RemoveNode(node)) {
855     if (myParent.IsNull()) { // if no parent we can release the ID
856       myNodeIDFactory->ReleaseID(IDnode);
857     }
858   }
859   
860 }
861
862 //=======================================================================
863 //function : RemoveNode
864 //purpose  : 
865 //=======================================================================
866
867 Standard_Boolean SMDS_Mesh::RemoveNode(const Handle(SMDS_MeshElement)& node)
868 {
869   Standard_Boolean successRemove = Standard_False;
870
871   if (!node.IsNull()) {
872     if (myHasInverse && myNodes.Contains(node)) {
873       SMDS_MapOfMeshOrientedElement map(1);
874       BuildMapNodeAncestors(node,map);
875       RemoveAncestors(node,map);
876     }
877
878     FreeNode(node);
879     successRemove = Standard_True;
880   }
881
882   return successRemove;
883 }
884
885 //=======================================================================
886 //function : RemoveEdge
887 //purpose  : 
888 //=======================================================================
889
890 void SMDS_Mesh::RemoveEdge(const Standard_Integer idnode1, const Standard_Integer idnode2)
891 {
892   Handle(SMDS_MeshElement) edge = FindEdge(idnode1,idnode2);
893   RemoveEdge(edge);
894 }
895
896 //=======================================================================
897 //function : RemoveEdge
898 //purpose  : 
899 //=======================================================================
900
901 void SMDS_Mesh::RemoveEdge(const Handle(SMDS_MeshElement)& edge)
902 {
903
904   if (!edge.IsNull()) {
905     myEdges.Remove(edge);
906
907     myElementIDFactory->ReleaseID(edge->GetID());
908   }
909 }
910
911
912 //=======================================================================
913 //function : RemoveFace
914 //purpose  : 
915 //=======================================================================
916
917 void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, 
918                            const Standard_Integer idnode2,
919                            const Standard_Integer idnode3)
920 {
921   Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3);
922   RemoveFace(face);
923 }
924
925 //=======================================================================
926 //function : RemoveFace
927 //purpose  : 
928 //=======================================================================
929
930 void SMDS_Mesh::RemoveFace(const Standard_Integer idnode1, 
931                            const Standard_Integer idnode2,
932                            const Standard_Integer idnode3,
933                            const Standard_Integer idnode4)
934 {
935   Handle(SMDS_MeshElement) face = FindFace(idnode1,idnode2,idnode3,idnode4);
936   RemoveFace(face);
937 }
938
939
940 //=======================================================================
941 //function : RemoveFace
942 //purpose  : 
943 //=======================================================================
944
945 void SMDS_Mesh::RemoveFace(const Handle(SMDS_MeshElement)& face)
946 {
947   if (!face.IsNull()) {
948     myFaces.Remove(face);
949     myElementIDFactory->ReleaseID(face->GetID());
950   }
951 }
952
953 //=======================================================================
954 //function : RemoveVolume
955 //purpose  : 
956 //=======================================================================
957
958 void SMDS_Mesh::RemoveVolume(const Handle(SMDS_MeshElement)& volume)
959 {
960   if (myVolumes.Contains(volume)) {
961     myVolumes.Remove(volume);
962     myElementIDFactory->ReleaseID(volume->GetID());
963   }
964 }
965
966 //=======================================================================
967 //function : RemoveElement
968 //purpose  : 
969 //=======================================================================
970
971 void SMDS_Mesh::RemoveElement(const Standard_Integer IDelem,const Standard_Boolean removenodes)
972 {
973   Handle(SMDS_MeshElement) elem =  myElementIDFactory->MeshElement(IDelem);
974   RemoveElement(elem,removenodes);
975
976
977     
978 }
979
980 //=======================================================================
981 //function : RemoveElement
982 //purpose  : 
983 //=======================================================================
984
985 void SMDS_Mesh::RemoveElement(const Handle(SMDS_MeshElement)& elem,const Standard_Boolean removenodes)
986 {
987   if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) ) {
988     RemoveEdge(elem);
989   } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshNode))) {
990     RemoveNode(elem);
991     return;
992   } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshFace))) {
993     RemoveFace(elem);
994   } else if ( elem->IsKind(STANDARD_TYPE(SMDS_MeshVolume))) {
995     RemoveVolume(elem);
996   } else {
997     MESSAGE( "remove function : unknown type" );
998     return;
999   }
1000
1001   Standard_Integer nbcnx = elem->NbNodes();
1002   Standard_Integer i;
1003   for (i=1; i <= nbcnx; ++i) {
1004     RemoveInverseElement(GetNode(i,elem),elem);
1005     
1006   }
1007
1008   if (removenodes) {
1009     for (i=1; i <= nbcnx; ++i) {
1010       if (GetNode(i,elem)->InverseElements().IsEmpty())
1011         FreeNode(GetNode(i,elem));
1012     }
1013   }
1014
1015 }
1016  
1017 //=======================================================================
1018 //function : RemoveFromParent
1019 //purpose  : 
1020 //=======================================================================
1021
1022 Standard_Boolean SMDS_Mesh::RemoveFromParent()
1023 {
1024   if (myParent.IsNull())
1025     return Standard_False;
1026
1027   return (myParent->RemoveSubMesh(this));
1028
1029 }
1030
1031 //=======================================================================
1032 //function : RemoveSubMesh
1033 //purpose  : 
1034 //=======================================================================
1035
1036 Standard_Boolean SMDS_Mesh::RemoveSubMesh(const Handle(SMDS_Mesh)& aMesh)
1037 {
1038   Standard_Boolean found = Standard_False;
1039
1040   SMDS_ListIteratorOfListOfMesh itmsh(myChildren);
1041   for (;itmsh.More() && !found; itmsh.Next()) {
1042     Handle(SMDS_Mesh) submesh;
1043     submesh = itmsh.Value();
1044     if (submesh == aMesh) {
1045       found = Standard_True;
1046       myChildren.Remove(itmsh);
1047     }
1048   }
1049
1050   return found;
1051 }
1052
1053 //=======================================================================
1054 //function : RemoveInverseElement
1055 //purpose  : 
1056 //=======================================================================
1057
1058 void SMDS_Mesh::RemoveInverseElement(const Handle(SMDS_MeshElement)& elem, 
1059                                      const Handle(SMDS_MeshElement)& parent) const
1060 {
1061   if (!myHasInverse) 
1062     return;
1063
1064   Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem);
1065   node->RemoveInverseElement(parent);
1066 }
1067  
1068 //=======================================================================
1069 //function : RemoveAncestors
1070 //purpose  : 
1071 //=======================================================================
1072
1073 void SMDS_Mesh::RemoveAncestors(const Handle(SMDS_MeshElement)& elem,
1074                                 const SMDS_MapOfMeshOrientedElement& map)
1075 {
1076
1077   if (!myHasInverse) 
1078     return;
1079
1080   SMDS_MapIteratorOfExtendedOrientedMap itAnc(map);
1081
1082   for (;itAnc.More();itAnc.Next()) {
1083     const Handle(SMDS_MeshElement)& ME = itAnc.Key();
1084     Standard_Integer nbcnx = ME->NbNodes();
1085
1086     for (Standard_Integer i=1; i <= nbcnx; ++i) {
1087       RemoveInverseElement(GetNode(i,ME),ME);
1088     }
1089   }
1090
1091   SMDS_MapIteratorOfExtendedOrientedMap itAnc2(map);
1092
1093   for (;itAnc2.More();itAnc2.Next()) {
1094     const Handle(SMDS_MeshElement)& ME = itAnc2.Key();
1095     RemoveElement(ME);
1096   }
1097 }
1098
1099 //=======================================================================
1100 //function : BuildMapNodeAncestors
1101 //purpose  : 
1102 //=======================================================================
1103
1104 void SMDS_Mesh::BuildMapNodeAncestors(const Handle(SMDS_MeshElement)& ME, 
1105                                       SMDS_MapOfMeshOrientedElement& map) const
1106 {
1107
1108   if (!myHasInverse) 
1109     return;
1110
1111   Standard_Integer nbcnx = ME->NbNodes();
1112
1113   for (Standard_Integer i=1; i <= nbcnx; ++i) {
1114     const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements();
1115
1116     SMDS_ListIteratorOfListOfMeshElement it(lstInvElements);
1117     for (;it.More();it.Next()) {
1118       const Handle(SMDS_MeshElement)& meParent = it.Value();
1119       if (Contains(meParent))
1120         map.Add(meParent);
1121     }
1122
1123   }
1124
1125 }
1126
1127
1128 //=======================================================================
1129 //function : BuildMapEdgeAncestors
1130 //purpose  : 
1131 //=======================================================================
1132
1133 void SMDS_Mesh::BuildMapEdgeAncestors(const Handle(SMDS_MeshElement)& ME, 
1134                                       SMDS_MapOfMeshOrientedElement& map) const
1135 {
1136
1137   if (!myHasInverse) 
1138     return;
1139
1140   Standard_Integer nbcnx = ME->NbNodes();
1141
1142   for (Standard_Integer i=1; i <= nbcnx; ++i) {
1143     const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements();
1144
1145     SMDS_ListIteratorOfListOfMeshElement it(lstInvElements);
1146     for (;it.More();it.Next()) {
1147       const Handle(SMDS_MeshElement)& meParent = it.Value();
1148       if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge)) && Contains(meParent))
1149         map.Add(meParent);
1150     }
1151
1152   }
1153
1154 }
1155
1156
1157 //=======================================================================
1158 //function : BuildMapFaceAncestors
1159 //purpose  : 
1160 //=======================================================================
1161
1162 void SMDS_Mesh::BuildMapFaceAncestors(const Handle(SMDS_MeshElement)& ME, 
1163                                       SMDS_MapOfMeshOrientedElement& map) const
1164 {
1165
1166   if (!myHasInverse) 
1167     return;
1168
1169   Standard_Integer nbcnx = ME->NbNodes();
1170
1171   for (Standard_Integer i=1; i <= nbcnx; ++i) {
1172     const SMDS_ListOfMeshElement& lstInvElements = GetNode(i,ME)->InverseElements();
1173
1174     SMDS_ListIteratorOfListOfMeshElement it(lstInvElements);
1175     for (;it.More();it.Next()) {
1176       const Handle(SMDS_MeshElement)& meParent = it.Value();
1177       if ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshEdge))
1178            && ( !meParent->IsKind(STANDARD_TYPE(SMDS_MeshFace))) && Contains(meParent) )
1179         map.Add(meParent);
1180     }
1181
1182   }
1183
1184 }
1185
1186
1187 //=======================================================================
1188 //function : FindEdge
1189 //purpose  : 
1190 //=======================================================================
1191
1192 Handle(SMDS_MeshElement) SMDS_Mesh::FindEdge(const Standard_Integer idnode1,
1193                                              const Standard_Integer idnode2 ) const
1194 {
1195   Handle(SMDS_MeshEdge) edge = new SMDS_MeshEdge(0,idnode1,idnode2);
1196   return FindEdge(edge);
1197 }
1198
1199 //=======================================================================
1200 //function : FindFace
1201 //purpose  : 
1202 //=======================================================================
1203
1204 Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1,
1205                                              const Standard_Integer idnode2,
1206                                              const Standard_Integer idnode3 ) const
1207 {
1208   Handle(SMDS_MeshFace) face = new SMDS_MeshTriangle(0,idnode1,idnode2,idnode3);
1209   return FindFace(face);
1210 }
1211
1212 //=======================================================================
1213 //function : FindFace
1214 //purpose  : 
1215 //=======================================================================
1216
1217 Handle(SMDS_MeshElement) SMDS_Mesh::FindFace(const Standard_Integer idnode1,
1218                                              const Standard_Integer idnode2,
1219                                              const Standard_Integer idnode3,
1220                                              const Standard_Integer idnode4 ) const
1221 {
1222   Handle(SMDS_MeshFace) face = new SMDS_MeshQuadrangle(0,idnode1,idnode2,idnode3,idnode4);
1223   return FindFace(face);
1224 }
1225
1226 //=======================================================================
1227 //function : FindElement
1228 //purpose  : 
1229 //=======================================================================
1230
1231 Handle(SMDS_MeshElement) SMDS_Mesh::FindElement(const Standard_Integer IDelem) const
1232 {
1233   return myElementIDFactory->MeshElement(IDelem);
1234 }
1235
1236 //=======================================================================
1237 //function : GetNode
1238 //purpose  : 
1239 //=======================================================================
1240
1241 Handle(SMDS_MeshNode) SMDS_Mesh::GetNode(const Standard_Integer rank, 
1242                                          const Handle(SMDS_MeshElement)& ME) const
1243
1244 {
1245   const Standard_Integer idnode = ME->GetConnection(rank); // take care, no control of bounds
1246
1247   Handle(SMDS_MeshElement) elem = FindNode(idnode);
1248   Handle(SMDS_MeshNode)& node = *((Handle(SMDS_MeshNode)*)&elem);
1249   return node;
1250
1251 }
1252
1253
1254 //=======================================================================
1255 //function : DumpNodes
1256 //purpose  : 
1257 //=======================================================================
1258
1259 void SMDS_Mesh::DumpNodes() const
1260 {
1261   MESSAGE( "dump nodes of mesh : " );
1262
1263   SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes);
1264
1265   for (;itnode.More();itnode.Next()) {
1266     const Handle(SMDS_MeshElement)& node = itnode.Key();
1267     MESSAGE( node);
1268     
1269   }
1270
1271 }
1272
1273
1274
1275 //=======================================================================
1276 //function : DumpEdges
1277 //purpose  : 
1278 //=======================================================================
1279
1280 void SMDS_Mesh::DumpEdges() const
1281 {
1282   MESSAGE( "dump edges of mesh : " );
1283
1284   SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges);
1285
1286   for (;itedge.More();itedge.Next()) {
1287     const Handle(SMDS_MeshElement)& edge = itedge.Key();
1288     MESSAGE( edge);
1289   }
1290 }
1291
1292
1293
1294 //=======================================================================
1295 //function : DumpFaces
1296 //purpose  : 
1297 //=======================================================================
1298
1299 void SMDS_Mesh::DumpFaces() const
1300 {
1301   MESSAGE( "dump faces of mesh : " );
1302
1303   SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces);
1304
1305   for (;itface.More();itface.Next()) {
1306     const Handle(SMDS_MeshElement)& face = itface.Key();
1307     MESSAGE( face);
1308   }
1309 }
1310
1311
1312 //=======================================================================
1313 //function : DumpVolumes
1314 //purpose  : 
1315 //=======================================================================
1316
1317 void SMDS_Mesh::DumpVolumes() const
1318 {
1319   MESSAGE( "dump volumes of mesh : " );
1320
1321   SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes);
1322
1323   for (;itvol.More();itvol.Next()) {
1324     const Handle(SMDS_MeshElement)& volume = itvol.Key();
1325     MESSAGE( volume);
1326   }
1327 }
1328
1329
1330
1331 //=======================================================================
1332 //function : DebugStats
1333 //purpose  : 
1334 //=======================================================================
1335
1336 void SMDS_Mesh::DebugStats() const
1337 {
1338   //VRV: T2.4 impossible to use Logger server
1339   MESSAGE( "Debug stats of mesh : " );
1340
1341   MESSAGE( "===== NODES =====" );
1342   myNodes.Statistics(cout);
1343
1344   MESSAGE( "===== EDGES =====" );
1345   myEdges.Statistics(cout);
1346
1347   MESSAGE( "===== FACES =====" );
1348   myFaces.Statistics(cout);
1349
1350   MESSAGE( "===== VOLUMES =====" );
1351   myVolumes.Statistics(cout);
1352   //VRV: T2.4 impossible to use Logger server
1353
1354   MESSAGE( "End Debug stats of mesh " );
1355
1356   //#ifdef DEB
1357   SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes);
1358   Standard_Integer sizeofnodes = 0;
1359   Standard_Integer sizeoffaces = 0;
1360
1361
1362   for (;itnode.More();itnode.Next()) {
1363     const Handle(SMDS_MeshElement)& node = itnode.Key();
1364     
1365     Standard_Transient *p = node->This();
1366     sizeofnodes += sizeof( *((SMDS_MeshNode *)p) );
1367
1368     SMDS_ListIteratorOfListOfMeshElement it(node->InverseElements());
1369     for (;it.More();it.Next()) {
1370       const Handle(SMDS_MeshElement)& me = it.Value();
1371       sizeofnodes += sizeof(me);
1372     }
1373     
1374   }
1375
1376   SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces);
1377
1378   for (;itface.More();itface.Next()) {
1379     const Handle(SMDS_MeshElement)& face = itface.Key();
1380     
1381     Standard_Transient *p = face->This();
1382     sizeoffaces += sizeof( *((SMDS_MeshFace *)p) );
1383     
1384   }
1385   MESSAGE( "total size of node elements = " << sizeofnodes );;
1386   MESSAGE( "total size of face elements = " << sizeoffaces );;
1387
1388   //#endif
1389
1390 }
1391
1392 //=======================================================================
1393 //function : RebuildAllInverseConnections
1394 //purpose  : 
1395 //=======================================================================
1396
1397 void SMDS_Mesh::RebuildAllInverseConnections()
1398 {
1399   if (!myParent.IsNull())
1400     myParent->RebuildAllInverseConnections();
1401
1402   else {
1403     // Clear all inverseconnections from nodes
1404     SMDS_MapIteratorOfExtendedOrientedMap itnode(myNodes);
1405     
1406     for (;itnode.More();itnode.Next()) {
1407       const Handle(SMDS_MeshElement)& elem = itnode.Key();
1408       elem->ClearInverseElements();
1409     }
1410     
1411
1412     RebuildInverseConnections();
1413
1414     SMDS_ListIteratorOfListOfMesh itmsh(myChildren);
1415     for (;itmsh.More(); itmsh.Next()) {
1416       Handle(SMDS_Mesh) submesh;
1417       submesh = itmsh.Value();
1418     
1419       submesh->RebuildInverseConnections();
1420
1421     }
1422   }
1423 }
1424
1425 //=======================================================================
1426 //function : RebuildInverseConnections
1427 //purpose  : 
1428 //=======================================================================
1429
1430 void SMDS_Mesh::RebuildInverseConnections()
1431 {
1432   // rebuld inverse connections to volumes
1433   SMDS_MapIteratorOfExtendedOrientedMap itvol(myVolumes);
1434
1435   for (;itvol.More();itvol.Next()) {
1436     const Handle(SMDS_MeshElement)& vol = itvol.Key();
1437
1438     Standard_Integer nbcnx = vol->NbNodes();
1439     for (Standard_Integer inode=1; inode<=nbcnx; ++inode) {
1440       Standard_Integer idnode = vol->GetConnection(inode);
1441       Handle(SMDS_MeshElement) node = FindNode(idnode);
1442       if (!node.IsNull())
1443         node->AddInverseElement(vol);
1444     }
1445     
1446   }
1447
1448   // rebuld inverse connections to faces
1449   SMDS_MapIteratorOfExtendedOrientedMap itface(myFaces);
1450
1451   for (;itface.More();itface.Next()) {
1452     const Handle(SMDS_MeshElement)& face = itface.Key();
1453
1454     Standard_Integer nbcnx = face->NbNodes();
1455     for (Standard_Integer inode=1; inode<=nbcnx; ++inode) {
1456       Standard_Integer idnode = face->GetConnection(inode);
1457       Handle(SMDS_MeshElement) node = FindNode(idnode);
1458       if (!node.IsNull())
1459         node->AddInverseElement(face);
1460     }
1461     
1462   }
1463
1464   // rebuld inverse connections to edges
1465   SMDS_MapIteratorOfExtendedOrientedMap itedge(myEdges);
1466
1467   for (;itedge.More();itedge.Next()) {
1468     const Handle(SMDS_MeshElement)& edge = itedge.Key();
1469
1470     Standard_Integer nbcnx = edge->NbNodes();
1471     for (Standard_Integer inode=1; inode<=nbcnx; ++inode) {
1472       Standard_Integer idnode = edge->GetConnection(inode);
1473       Handle(SMDS_MeshElement) node = FindNode(idnode);
1474       if (!node.IsNull())
1475         node->AddInverseElement(edge);
1476     }
1477     
1478   }
1479
1480   myHasInverse = Standard_True;
1481 }
1482
1483
1484 //=======================================================================
1485 //function : SubMeshIterator
1486 //purpose  : returns the ith SubMesh
1487 //=======================================================================
1488
1489 void SMDS_Mesh::SubMeshIterator(SMDS_ListIteratorOfListOfMesh& itmsh) const
1490 {
1491   itmsh.Initialize(myChildren);
1492 }
1493