0022312: Translation of french commentaries in OCCT files
[occt.git] / src / Extrema / Extrema_ExtPS.cxx
1 // File Extrema_ExtPS.cxx
2 //-----------------------------------------------------------------
3
4 #include <Extrema_ExtPS.ixx>
5 #include <Extrema_GenExtPS.hxx>
6 #include <StdFail_NotDone.hxx>
7 #include <Standard_NotImplemented.hxx>
8 #include <Precision.hxx>
9 #include <GeomAbs_CurveType.hxx>
10 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
11 #include <Adaptor3d_SurfaceOfRevolution.hxx>
12 #include <ElCLib.hxx>
13 #include <gp_Pnt.hxx>
14 #include <gp_Pln.hxx>
15 #include <gp_Cylinder.hxx>
16 #include <gp_Cone.hxx>
17 #include <gp_Sphere.hxx>
18 #include <gp_Torus.hxx>
19 #include <Extrema_ExtPExtS.hxx>
20 #include <Extrema_ExtPRevS.hxx>
21 #include <Extrema_POnSurf.hxx>
22 #include <GeomAbs_IsoType.hxx>
23
24 //=======================================================================
25 //function : IsoIsDeg
26 //purpose  : 
27 //=======================================================================
28
29 static Standard_Boolean IsoIsDeg  (const Adaptor3d_Surface& S,
30                                    const Standard_Real      Param,
31                                    const GeomAbs_IsoType    IT,
32                                    const Standard_Real      TolMin,
33                                    const Standard_Real      TolMax) 
34 {
35     Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
36     Standard_Boolean Along = Standard_True;
37     U1 = S.FirstUParameter();
38     U2 = S.LastUParameter();
39     V1 = S.FirstVParameter();
40     V2 = S.LastVParameter();
41     gp_Vec D1U,D1V;
42     gp_Pnt P;
43     Standard_Real Step,D1NormMax;
44     if (IT == GeomAbs_IsoV) 
45     {
46       Step = (U2 - U1)/10;
47       if(Step < Precision::PConfusion()) {
48         return Standard_False;
49       }
50       if(Step < Precision::PConfusion()) {
51         return Standard_False;
52       }
53       D1NormMax=0.;
54       for (T=U1;T<=U2;T=T+Step) 
55       {
56         S.D1(T,Param,P,D1U,D1V);
57         D1NormMax=Max(D1NormMax,D1U.Magnitude());
58       }
59
60       if (D1NormMax >TolMax || D1NormMax < TolMin ) 
61            Along = Standard_False;
62     }
63     else 
64     {
65       Step = (V2 - V1)/10;
66       if(Step < Precision::PConfusion()) {
67         return Standard_False;
68       }
69       if(Step < Precision::PConfusion()) {
70         return Standard_False;
71       }
72       D1NormMax=0.;
73       for (T=V1;T<=V2;T=T+Step) 
74       {
75         S.D1(Param,T,P,D1U,D1V);
76         D1NormMax=Max(D1NormMax,D1V.Magnitude());
77       }
78
79       if (D1NormMax >TolMax || D1NormMax < TolMin ) 
80            Along = Standard_False;
81
82
83     }
84     return Along;
85 }
86
87 //=======================================================================
88 //function : TreatSolution
89 //purpose  : 
90 //=======================================================================
91
92 void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
93                                    const Standard_Real Val)
94 {
95   Standard_Real U, V;
96   PS.Parameter(U, V);
97   if (myS->IsUPeriodic()) {
98     U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
99   }
100   if (myS->IsVPeriodic()) {
101     V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
102   }
103   if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
104       (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
105     myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
106     mySqDist.Append(Val);
107   }
108 }
109
110
111 //=======================================================================
112 //function : Extrema_ExtPS
113 //purpose  : 
114 //=======================================================================
115
116 Extrema_ExtPS::Extrema_ExtPS() 
117 {
118   myDone = Standard_False;
119 }
120
121
122 //=======================================================================
123 //function : Extrema_ExtPS
124 //purpose  : 
125 //=======================================================================
126
127 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt&          P,
128                              const Adaptor3d_Surface& S,
129                              const Standard_Real    TolU,
130                              const Standard_Real    TolV,
131            const Extrema_ExtFlag F,
132            const Extrema_ExtAlgo A)
133
134 {
135   myExtPS.SetFlag(F);
136   myExtPS.SetAlgo(A);
137   Initialize(S, S.FirstUParameter(), S.LastUParameter(), 
138                 S.FirstVParameter(), S.LastVParameter(), 
139                 TolU, TolV);
140   Perform(P);
141 }
142
143 //=======================================================================
144 //function : Extrema_ExtPS
145 //purpose  : 
146 //=======================================================================
147
148 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt&          P,
149                              const Adaptor3d_Surface& S,
150                              const Standard_Real    Uinf,       
151                              const Standard_Real    Usup,
152                              const Standard_Real    Vinf,       
153                              const Standard_Real    Vsup,
154                              const Standard_Real    TolU,
155                              const Standard_Real    TolV,
156            const Extrema_ExtFlag F,
157            const Extrema_ExtAlgo A)
158
159 {
160   myExtPS.SetFlag(F);
161   myExtPS.SetAlgo(A);
162   Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
163   Perform(P);
164 }
165
166
167 //=======================================================================
168 //function : Initialize
169 //purpose  : 
170 //=======================================================================
171
172 void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S,
173                                const Standard_Real    Uinf,     
174                                const Standard_Real    Usup,
175                                const Standard_Real    Vinf,     
176                                const Standard_Real    Vsup,
177                                const Standard_Real    TolU,
178                                const Standard_Real    TolV)
179 {
180   myS = (Adaptor3d_SurfacePtr)&S;
181   myuinf = Uinf;
182   myusup = Usup;
183   myvinf = Vinf;
184   myvsup = Vsup;
185
186   if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
187   if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
188   if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
189   if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
190
191   mytolu = TolU;
192   mytolv = TolV;
193   mytype = myS->GetType();
194
195   Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
196                            myS->GetType() == GeomAbs_BezierSurface );
197
198   Standard_Integer nbU = (isB) ? 44 : 32;
199   Standard_Integer nbV = (isB) ? 44 : 32;
200
201   Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
202
203   if(myS->GetType() != GeomAbs_Plane) {
204     bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
205                  IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9);
206     bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
207                  IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9);
208   }
209
210   if(bUIsoIsDeg) nbU = 300;
211   if(bVIsoIsDeg) nbV = 300;
212
213   myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
214 }
215
216 //=======================================================================
217 //function : Perform
218 //purpose  : 
219 //=======================================================================
220
221 void Extrema_ExtPS::Perform(const gp_Pnt& P)
222 {
223   myPoints.Clear();
224   mySqDist.Clear();
225   Standard_Integer i;
226   P11 = myS->Value(myuinf, myvinf);
227   P12 = myS->Value(myuinf, myvsup);
228   P21 = myS->Value(myusup, myvinf);
229   P22 = myS->Value(myusup, myvsup);
230   d11 = P.SquareDistance(P11);
231   d12 = P.SquareDistance(P12);
232   d21 = P.SquareDistance(P21);
233   d22 = P.SquareDistance(P22);
234   
235   switch(mytype) {
236     
237   case GeomAbs_Cylinder:
238     myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
239     break;
240   case GeomAbs_Plane:
241     myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
242     break;
243   case GeomAbs_Cone:
244     myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
245     break;
246   case GeomAbs_Sphere:
247     myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
248     break;
249   case GeomAbs_Torus:
250     myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
251     break;
252
253     
254   case GeomAbs_SurfaceOfExtrusion: {
255     Extrema_ExtPExtS anExtPExtS(P,
256                                 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
257                                                                    myS->Direction()),
258                                 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
259     myDone = anExtPExtS.IsDone();
260     if (myDone) 
261       for (i = 1; i <= anExtPExtS.NbExt(); i++) {
262         TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
263       }
264     return;
265   }
266
267     
268   case GeomAbs_SurfaceOfRevolution: {
269     Extrema_ExtPRevS anExtPRevS(P,
270                                 Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(),
271                                                               myS->AxeOfRevolution()),
272                                 myuinf, myusup,myvinf, myvsup,mytolu, mytolv);
273     myDone = anExtPRevS.IsDone();
274     if (myDone) 
275       for (i = 1; i <= anExtPRevS.NbExt(); i++) {
276         TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
277       }
278     return;
279   }
280
281     
282   default: 
283     myExtPS.Perform(P);
284     myDone = myExtPS.IsDone();
285     if (myDone) 
286       for (i = 1; i <= myExtPS.NbExt(); i++) 
287         TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
288     return;
289   }
290
291   
292   myDone = myExtPElS.IsDone();
293   if (myDone) 
294     for (i = 1; i <= myExtPElS.NbExt(); i++) 
295       TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
296   return;
297 }
298
299
300
301 Standard_Boolean Extrema_ExtPS::IsDone() const
302 {
303   return myDone;
304 }
305
306
307 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
308 {
309   if(!myDone) StdFail_NotDone::Raise();
310   if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
311   return mySqDist.Value(N);
312 }
313
314
315 Standard_Integer Extrema_ExtPS::NbExt() const
316 {
317   if(!myDone) StdFail_NotDone::Raise();
318   return mySqDist.Length();
319 }
320
321
322
323 Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
324 {
325   if(!myDone) StdFail_NotDone::Raise();
326   return myPoints.Value(N);
327 }
328
329
330 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
331                                       Standard_Real& dUfVl,
332                                       Standard_Real& dUlVf,
333                                       Standard_Real& dUlVl,
334                                       gp_Pnt&        PUfVf,
335                                       gp_Pnt&        PUfVl,
336                                       gp_Pnt&        PUlVf,
337                                       gp_Pnt&        PUlVl) const
338 {
339   dUfVf = d11;
340   dUfVl = d12;
341   dUlVf = d21;
342   dUlVl = d22;
343   PUfVf = P11;
344   PUfVl = P12;
345   PUlVf = P21;
346   PUlVl = P22;
347 }
348
349 void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
350 {
351   myExtPS.SetFlag(F);
352 }
353
354 void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
355 {
356   myExtPS.SetAlgo(A);
357 }