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