0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / MAT2d / MAT2d_MiniPath.cxx
1 // Created on: 1993-10-07
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 <Extrema_ExtCC2d.hxx>
19 #include <Extrema_ExtPC2d.hxx>
20 #include <Extrema_POnCurv2d.hxx>
21 #include <Geom2d_CartesianPoint.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <Geom2d_Point.hxx>
24 #include <Geom2dAdaptor_Curve.hxx>
25 #include <MAT2d_Array2OfConnexion.hxx>
26 #include <MAT2d_Connexion.hxx>
27 #include <MAT2d_MiniPath.hxx>
28 #include <Standard_NotImplemented.hxx>
29 #include <TColGeom2d_SequenceOfGeometry.hxx>
30 #include <TColStd_SequenceOfInteger.hxx>
31
32 //============================================================================
33 //function : MAT2d_MiniPath()
34 //purpose  :
35 //============================================================================
36 MAT2d_MiniPath::MAT2d_MiniPath()
37 : theDirection(1.0),
38   indStart(0)
39 {
40 }
41
42 //============================================================================
43 //function : Perform
44 //purpose  : Calcul du chemin reliant les differents elements de <aFigure>.
45 //           le chemin part de la ligne <IndStart>.
46 //           <Sense> = True les lignes sont orientes dans le sens trigo.
47 //============================================================================
48 void MAT2d_MiniPath::Perform
49   (const MAT2d_SequenceOfSequenceOfGeometry& Figure,
50    const Standard_Integer                    IndStart,
51    const Standard_Boolean                    Sense)
52 {
53
54   Standard_Integer         i,j;
55   Standard_Integer         NbLines   = Figure.Length();
56   MAT2d_Array2OfConnexion  Connexion (1,NbLines,1,NbLines);
57   
58   indStart     = IndStart;
59   theDirection = 1.;
60   if (Sense) theDirection = -1.;
61
62   //----------------------------------------------------------------------
63   // Calcul des connexions qui realisent le minimum de distance entre les
64   // differents elements de la figure.
65   //----------------------------------------------------------------------
66   for (i = 1; i < NbLines; i++) {
67     for (j =i+1; j <= NbLines; j++){
68       Connexion(i,j) = MinimumL1L2(Figure,i,j);
69       Connexion(j,i) = Connexion(i,j)->Reverse();
70     }
71   }
72  
73   TColStd_SequenceOfInteger Set1;
74   TColStd_SequenceOfInteger Set2;
75   Standard_Real             DistS1S2;
76   Standard_Integer          IndiceLine1,IndiceLine2;
77   Standard_Integer          ISuiv =0,MinOnSet1 =0,MinOnSet2 =0;
78   //---------------------------------------------------------------------------
79   // - 0 Set1 est initialise avec la ligne de depart.
80   //     Set2 contient toutes les autres.
81   //---------------------------------------------------------------------------
82
83   Set1.Append(IndStart);
84
85   for (i=1 ; i<=NbLines ; i++){
86     if (i != IndStart){
87       Set2.Append(i);
88     }
89   }
90
91   //---------------------------------------------------------------------------
92   // - 1 Recherche de la connexion C la plus courte entre Set1 et Set2.
93   // - 2 La ligne de Set2 realisant le minimum de distance est inseree dans 
94   //     Set1 et supprime dans Set2.
95   // - 3 Insertion de la connexion dans l ensemble des connexions.
96   // - 4 Si Set2 est non vide retour en 1.
97   //---------------------------------------------------------------------------
98
99   while (!Set2.IsEmpty()){
100     DistS1S2 = RealLast();
101     for (i = 1; i <= Set1.Length(); i++) {
102       IndiceLine1 = Set1.Value(i);
103       for (j = 1 ; j<= Set2.Length() ;j++) {
104         IndiceLine2 = Set2.Value(j);
105         if(Connexion(IndiceLine1,IndiceLine2)->Distance() < DistS1S2) {
106           ISuiv     = j;
107           DistS1S2  = Connexion(IndiceLine1,IndiceLine2)->Distance();
108           MinOnSet1 = IndiceLine1;
109           MinOnSet2 = IndiceLine2;
110         }
111       }
112     }
113     Set1.Append(Set2.Value(ISuiv)); 
114     Set2.Remove(ISuiv);
115     Append(Connexion(MinOnSet1,MinOnSet2));
116   }
117
118   //----------------------------------------------------------------
119   // Construction du chemin en parcourant l ensemble des connexions.
120   //----------------------------------------------------------------
121   RunOnConnexions() ;
122 }
123
124
125 //============================================================================
126 //function : Append
127 //purpose  : Insertion d une nouvelle connexion dans le chemin.
128 //
129 //           Les connexions et les lignes constituent un arbre dont
130 //           - les noeuds sont les lignes.
131 //           - les connexions sont les branches.
132 //         
133 //============================================================================
134 void MAT2d_MiniPath::Append(const Handle(MAT2d_Connexion)& C)
135 {
136   Handle(MAT2d_Connexion) CC;
137
138   if (!theConnexions.IsBound(C->IndexFirstLine())) {
139     MAT2d_SequenceOfConnexion Seq;
140     theConnexions.Bind(C->IndexFirstLine(),Seq);
141     theConnexions(C->IndexFirstLine()).Append(C);
142     theFather.Bind(C->IndexSecondLine(),C);
143     return;
144   }
145
146   MAT2d_SequenceOfConnexion& Seq  = theConnexions(C->IndexFirstLine()); 
147   Standard_Integer IndexAfter     = 0;
148   Standard_Integer NbConnexions   = Seq.Length();
149
150   for (Standard_Integer i = 1; i <= NbConnexions; i++) {
151     CC = Seq.Value(i);
152     if (CC->IsAfter(C,theDirection)){
153       IndexAfter = i;
154       break;
155     }
156   }
157   //----------------------------------------------------------------------
158   // Insertion de <C> avant <IAfter>.
159   // Si <IAfter> = 0 => Pas de connexions apres <C> => <C> est la
160   // derniere.
161   //----------------------------------------------------------------------
162   if (IndexAfter == 0) {
163     Seq.Append(C);
164   }
165   else {
166     Seq.InsertBefore(IndexAfter,C);
167   }
168   theFather.Bind(C->IndexSecondLine(),C);
169   return;
170 }
171
172 //============================================================================
173 //function : Path
174 //purpose  : Retour de la sequence de connexions definissant le chemin.
175 //============================================================================
176 const MAT2d_SequenceOfConnexion& MAT2d_MiniPath::Path() const
177 {
178   return thePath;
179 }
180
181 //============================================================================
182 //function : IsConnexionsFrom
183 //purpose :
184 //============================================================================
185 Standard_Boolean MAT2d_MiniPath::IsConnexionsFrom
186   (const Standard_Integer i) const
187 {
188   return (theConnexions.IsBound(i));
189 }
190
191 //============================================================================
192 //function : Connexions
193 //purpose  : Retour de la sequence de connexions issue de la ligne <i>.
194 //============================================================================
195 MAT2d_SequenceOfConnexion& MAT2d_MiniPath::ConnexionsFrom 
196   (const Standard_Integer i)
197 {
198   return theConnexions.ChangeFind(i);
199 }
200
201 //============================================================================
202 //function : IsRoot
203 //purpose  :
204 //============================================================================
205 Standard_Boolean MAT2d_MiniPath::IsRoot(const Standard_Integer ILine) const
206 {
207   return (ILine == indStart);
208 }
209
210 //============================================================================
211 //function : Father
212 //purpose  : Retour de la premiere connexion qui arrive sur la ligne i
213 //============================================================================
214 Handle(MAT2d_Connexion) MAT2d_MiniPath::Father(const Standard_Integer ILine)
215 {
216   return theFather.ChangeFind(ILine);
217 }
218
219
220 //============================================================================
221 //function : RunOnConnexions
222 //purpose  : Construction de <thePath> en parcourant <theConnexions>.
223 //============================================================================
224 void MAT2d_MiniPath::RunOnConnexions() 
225 {
226   Standard_Integer                  i;
227   Handle(MAT2d_Connexion)           C;
228   const MAT2d_SequenceOfConnexion&  SC = theConnexions(indStart);
229
230   thePath.Clear();
231   
232   for ( i = 1; i <= SC.Length(); i++) {
233     C = SC.Value(i);
234     thePath.Append(C);
235     ExploSons(thePath,C);
236     thePath.Append(C->Reverse());
237   }
238 }
239
240 //============================================================================
241 //function : ExploSons
242 //purpose  : 
243 //============================================================================
244 void MAT2d_MiniPath::ExploSons(      MAT2d_SequenceOfConnexion& CResult,
245                                const Handle(MAT2d_Connexion)&   CRef   ) 
246 {
247   Standard_Integer                 i;  
248   Standard_Integer                 Index = CRef->IndexSecondLine();
249
250   if (!theConnexions.IsBound(Index)) return;
251
252   const MAT2d_SequenceOfConnexion& SC    = theConnexions(Index);
253   Handle(MAT2d_Connexion)          CRR   = CRef->Reverse();
254   Handle(MAT2d_Connexion)          C;
255
256   for ( i = 1; i <= SC.Length(); i++) {
257     C = SC.Value(i);
258     if (C->IsAfter(CRR,theDirection)) {
259       CResult.Append(C);
260       ExploSons(CResult,C);
261       CResult.Append(C->Reverse());
262     }
263   }
264
265   for ( i = 1; i <= SC.Length(); i++) {
266     C = SC.Value(i);
267     if (!C->IsAfter(CRR,theDirection)) {
268       CResult.Append(C);
269       ExploSons(CResult,C);
270       CResult.Append(C->Reverse());
271     }
272     else {
273       break;
274     }
275   }
276 }
277
278       
279 //============================================================================
280 //function : MinimumL1L2
281 //purpose  : Calcul de la connexion realisant le minimum de distance entre les
282 //           lignes d indice <IL1> et <IL2> dans <Figure>.
283 //============================================================================
284 Handle(MAT2d_Connexion) MAT2d_MiniPath::MinimumL1L2
285   (const MAT2d_SequenceOfSequenceOfGeometry& Figure,
286    const Standard_Integer                    IL1,
287    const Standard_Integer                    IL2) const
288 {
289   Extrema_POnCurv2d              PointOnCurv1,PointOnCurv2;
290   Standard_Integer               IC1,IC2,IMinC1 =0,IMinC2 =0,i;
291   Standard_Real                  DistL1L2_2,DistP1P2_2;
292   Standard_Real                  ParameterOnC1 =0.,ParameterOnC2 =0.;
293   TColGeom2d_SequenceOfGeometry  L1,L2;
294   gp_Pnt2d                       Point1,Point2,P1,P2;
295   Handle(Geom2d_Curve)           Item1;
296   Handle(Geom2d_Curve)           Item2;
297
298   L1 = Figure.Value(IL1);
299   L2 = Figure.Value(IL2);
300
301   DistL1L2_2 = RealLast();
302
303   //---------------------------------------------------------------------------
304   // Calcul des extremas de distances entre les composants de L1 et de L2.
305   //---------------------------------------------------------------------------
306
307   for (IC1 = 1; IC1 <= L1.Length(); IC1++) {
308
309     Handle(Standard_Type)   Type1 = L1.Value(IC1)->DynamicType();
310     if (Type1 != STANDARD_TYPE(Geom2d_CartesianPoint)) {
311       Item1 = Handle(Geom2d_Curve)::DownCast(L1.Value(IC1));
312     }
313     else {
314         P1 = Handle(Geom2d_Point)::DownCast(L1.Value(IC1))->Pnt2d();
315     }
316
317     for (IC2 = 1; IC2 <= L2.Length(); IC2++) {
318
319       Handle(Standard_Type)   Type2 = L2.Value(IC2)->DynamicType();
320       if (Type2 != STANDARD_TYPE(Geom2d_CartesianPoint)) {
321         Item2 = Handle(Geom2d_Curve)::DownCast(L2.Value(IC2));
322       }
323       else {
324         P2 = Handle(Geom2d_Point)::DownCast(L2.Value(IC2))->Pnt2d();
325       }
326
327       if (Type1 == STANDARD_TYPE(Geom2d_CartesianPoint) &&
328           Type2 == STANDARD_TYPE(Geom2d_CartesianPoint)   ) {
329         DistP1P2_2 = P1.SquareDistance(P2);
330         if (DistP1P2_2 <= DistL1L2_2) {
331           DistL1L2_2      = DistP1P2_2;
332           IMinC1        = IC1;
333           IMinC2        = IC2;
334           Point1        = P1;
335           Point2        = P2;
336           ParameterOnC1 = 0.;
337           ParameterOnC2 = 0.;
338         }
339       }
340       else if (Type1 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
341         Geom2dAdaptor_Curve C2(Item2);
342         Extrema_ExtPC2d Extremas(P1,C2);
343         if (Extremas.IsDone()){
344           for (i = 1; i <= Extremas.NbExt(); i++) {
345             if (Extremas.SquareDistance(i) < DistL1L2_2) {
346               DistL1L2_2    = Extremas.SquareDistance(i);
347               IMinC1        = IC1;
348               IMinC2        = IC2;
349               PointOnCurv2  = Extremas.Point(i);
350               ParameterOnC1 = 0.;
351               ParameterOnC2 = PointOnCurv2.Parameter();
352               Point1        = P1;
353               Point2        = PointOnCurv2.Value();
354             }
355           }
356         }
357       }
358       else if (Type2 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
359         Geom2dAdaptor_Curve C1(Item1);
360         Extrema_ExtPC2d Extremas(P2,C1);
361         if (Extremas.IsDone()){
362           for (i=1;i<=Extremas.NbExt();i++) {
363             if (Extremas.SquareDistance(i) < DistL1L2_2) {
364               DistL1L2_2    = Extremas.SquareDistance(i);
365               IMinC1        = IC1;
366               IMinC2        = IC2;
367               PointOnCurv1  = Extremas.Point(i);
368               ParameterOnC2 = 0.;
369               ParameterOnC1 = PointOnCurv1.Parameter();
370               Point1        = PointOnCurv1.Value();
371               Point2        = P2;
372             }
373           }
374         }
375       }
376       else {
377         Geom2dAdaptor_Curve C1(Item1);
378         Geom2dAdaptor_Curve C2(Item2);
379         Extrema_ExtCC2d Extremas(C1,C2);
380         if (!Extremas.IsParallel() && Extremas.IsDone()){
381           for ( i=1; i <= Extremas.NbExt(); i++) {
382             if (Extremas.SquareDistance(i) < DistL1L2_2) {
383               DistL1L2_2    = Extremas.SquareDistance(i);
384               IMinC1        = IC1;
385               IMinC2        = IC2;
386               Extremas.Points(i,PointOnCurv1,PointOnCurv2);
387               ParameterOnC1 = PointOnCurv1.Parameter();
388               ParameterOnC2 = PointOnCurv2.Parameter();
389               Point1        = PointOnCurv1.Value();
390               Point2        = PointOnCurv2.Value();
391             }
392           }
393         }
394       }
395     }
396   }
397   Handle(MAT2d_Connexion) ConnexionL1L2;
398   ConnexionL1L2 = new MAT2d_Connexion(IL1,IL2,IMinC1,IMinC2,sqrt (DistL1L2_2),
399                                       ParameterOnC1,ParameterOnC2,
400                                       Point1,Point2);
401   return ConnexionL1L2;
402 }
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425