0028832: MMgt_TShared can be replaced by Standard_Transient
[occt.git] / src / MAT / MAT_Zone.cxx
1 // Created on: 1993-05-05
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <MAT_Arc.hxx>
19 #include <MAT_BasicElt.hxx>
20 #include <MAT_Node.hxx>
21 #include <MAT_SequenceOfArc.hxx>
22 #include <MAT_Zone.hxx>
23 #include <Standard_Type.hxx>
24
25 IMPLEMENT_STANDARD_RTTIEXT(MAT_Zone,Standard_Transient)
26
27 //========================================================================
28 // function:
29 // purpose :
30 //========================================================================
31 MAT_Zone::MAT_Zone ()
32 {}
33
34 //========================================================================
35 // function:
36 // purpose :
37 //========================================================================
38 MAT_Zone::MAT_Zone(const Handle(MAT_BasicElt)& aBasicElt) 
39 {
40   Perform (aBasicElt);
41 }
42
43 //========================================================================
44 // function: Perform
45 // purpose :
46 //========================================================================
47 void MAT_Zone::Perform (const Handle(MAT_BasicElt)& aBasicElt) 
48 {
49   Handle (MAT_Node)       NextNode, StartNode;
50   Handle (MAT_Arc)        CurrentArc;
51
52   limited = Standard_True;
53   frontier.Clear();
54   // ------------------------------------------------------------------------
55   // Si le premier arc correspondant a la zone est Null => Sequence vide.
56   // ------------------------------------------------------------------------
57   if (aBasicElt->EndArc().IsNull()) return;
58
59   // ----------------------------
60   // Angle rentrant => Zone Vide.
61   // ----------------------------
62   // if(aBasicElt->EndArc() == aBasicElt->StartArc()) return;
63
64   // --------------------------------
65   // Initialisation de la frontier.
66   // --------------------------------
67   CurrentArc = aBasicElt->EndArc();
68   frontier.Append(CurrentArc);
69
70   // --------------------------------------------------------------------------  
71   // Determination du premier noeud qui permet de construire la zone en tournant
72   // surla gauche.
73   // --------------------------------------------------------------------------
74   NextNode  = NodeForTurn(CurrentArc,aBasicElt,MAT_Left);
75   StartNode = CurrentArc->TheOtherNode(NextNode);
76
77   // -------------------------------------------------------------------------
78   // Exploration du Graph toujours sur les arcs voisins a gauche jusqu'a
79   // - retour sur la Figure .
80   // - l acces a un noeud infini .
81   // (Ces deux  cas correspondent a des noeuds pendants.)
82   // - retour sur l arc de depart si le basicElt est ferme.
83   // -------------------------------------------------------------------------
84   
85   while (!NextNode->PendingNode() && (NextNode != StartNode)) {
86     CurrentArc = CurrentArc->Neighbour(NextNode,MAT_Left);
87     frontier.Append(CurrentArc);
88     NextNode   = CurrentArc->TheOtherNode(NextNode);
89   }
90
91   // -----------------------------------------------------------------------
92   // Si NextNode est a l infini : exploration du graph a partir du StartArc 
93   //   sur <aBasicElt>.
94   //   exploration sur les arcs voisins a droite.
95   // Sinon => Fin.
96   // -----------------------------------------------------------------------
97
98   if (NextNode->Infinite()) {
99     limited    = Standard_False;
100     CurrentArc = aBasicElt->StartArc();  
101     frontier.Append(CurrentArc);
102     // --------------------------------------------------------------------------
103     // Determination du premier noeud qui permet de construire la zone en 
104     //tournan surla droite.
105     // --------------------------------------------------------------------------
106     NextNode = NodeForTurn(CurrentArc,aBasicElt,MAT_Right);
107     
108     // -----------------------------------------------------
109     // Cette branche est aussi terminee par un noeud infini.
110     // -----------------------------------------------------
111     while (!NextNode->Infinite()) {
112       CurrentArc = CurrentArc->Neighbour(NextNode,MAT_Right);
113       frontier.Append(CurrentArc);
114       NextNode   = CurrentArc->TheOtherNode(NextNode);
115     }
116   }
117 }
118
119 //========================================================================
120 // function: NumberOfArcs
121 // purpose :
122 //========================================================================
123 Standard_Integer  MAT_Zone::NumberOfArcs()const 
124 {
125   return frontier.Length();
126 }
127
128 //========================================================================
129 // function: ArcOnFrontier
130 // purpose :
131 //========================================================================
132 Handle(MAT_Arc)  MAT_Zone::ArcOnFrontier(const Standard_Integer Index)const 
133 {
134   return frontier.Value(Index);
135 }
136
137 //========================================================================
138 // function: NoEmptyZone
139 // purpose :
140 //========================================================================
141 Standard_Boolean  MAT_Zone::NoEmptyZone()const 
142 {
143    return (!frontier.IsEmpty());
144 }
145
146 //========================================================================
147 // function: Limited
148 // purpose :
149 //========================================================================
150 Standard_Boolean  MAT_Zone::Limited()const 
151 {
152    return limited;
153 }
154
155 //========================================================================
156 // function:
157 // purpose :
158 //========================================================================
159 Handle(MAT_Node) MAT_Zone::NodeForTurn (const Handle(MAT_Arc)&      anArc,
160                                         const Handle(MAT_BasicElt)& aBE,
161                                         const MAT_Side              aSide) 
162      const
163 {
164   Handle(MAT_Arc)  NeighbourArc;
165   Handle(MAT_Node) NodeSol     ;
166
167   NodeSol      = anArc->FirstNode();
168   NeighbourArc = anArc->Neighbour(NodeSol,aSide);
169   if (NeighbourArc.IsNull()) {    
170     NodeSol      = anArc->SecondNode();
171     NeighbourArc = anArc->Neighbour(NodeSol,aSide);
172   }
173   if (NeighbourArc.IsNull()) {
174     return NodeSol;
175   }
176   if (NeighbourArc->FirstElement() == aBE) {
177     return NodeSol;
178   }
179   else if (NeighbourArc->SecondElement() == aBE) { 
180     return NodeSol;
181   }
182   else {
183     return anArc->TheOtherNode(NodeSol);
184   }
185 }