0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / Extrema / Extrema_GLocateExtPC.gxx
CommitLineData
b311480e 1// Created on: 1993-12-14
2// Created by: Christophe MARION
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// 05-Jun-00 : hla : meme type de corr. que xab : dans la methode "Perform",
18// suppression du test mal a propos "myintuinf > myintusup" avec
19// "return" a la suite.
20// 05-Sep-95 : xab : correction d'un probleme de determination d'intervalle
21// de recherche
22
23#include Extrema_ELPC_hxx
24#include ThePOnC_hxx
25#include ThePoint_hxx
26#include TheVector_hxx
27#include <StdFail_NotDone.hxx>
28#include <Standard_DomainError.hxx>
29#include <GeomAbs_CurveType.hxx>
30#include <Precision.hxx>
31#include <TColStd_Array1OfReal.hxx>
32
33
34//=======================================================================
35//function : Extrema_GLocateExtPC
36//purpose :
37//=======================================================================
38
39Extrema_GLocateExtPC::Extrema_GLocateExtPC() { }
40
41
42//=======================================================================
43//function : Extrema_GLocateExtPC
44//purpose :
45//=======================================================================
46
47Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
a86d3ec0 48 const TheCurve& C,
49 const Standard_Real U0,
50 const Standard_Real TolF)
7fd59977 51{
52 Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF);
53 Perform(P, U0);
54}
55
56//=======================================================================
57//function : Extrema_GLocateExtPC
58//purpose :
59//=======================================================================
60
61Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
a86d3ec0 62 const TheCurve& C,
63 const Standard_Real U0,
64 const Standard_Real Umin,
65 const Standard_Real Usup,
66 const Standard_Real TolF)
7fd59977 67{
68 Initialize(C, Umin, Usup, TolF);
69 Perform(P, U0);
70}
71
72
73
74//=======================================================================
75//function : Initialize
76//purpose :
77//=======================================================================
78
79void Extrema_GLocateExtPC::Initialize(const TheCurve& C,
a86d3ec0 80 const Standard_Real Umin,
81 const Standard_Real Usup,
82 const Standard_Real TolF)
7fd59977 83{
84 myC = (Standard_Address)&C;
85 mytol = TolF;
86 myumin = Umin;
87 myusup = Usup;
88 type = TheCurveTool::GetType(C);
89 Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion());
90 if ((type == GeomAbs_BSplineCurve) ||
1aec3320 91 (type == GeomAbs_BezierCurve) ||
92 (type == GeomAbs_OffsetCurve) ||
93 (type == GeomAbs_OtherCurve))
94 {
a86d3ec0 95 myLocExtPC.Initialize(C, Umin, Usup, tolu);
7fd59977 96 }
97 else {
98 myExtremPC.Initialize(C, Umin, Usup, tolu);
99 }
100}
101
102
103
104
105//=======================================================================
106//function : Perform
107//purpose :
108//=======================================================================
109
110void Extrema_GLocateExtPC::Perform(const ThePoint& P,
a86d3ec0 111 const Standard_Real U0)
7fd59977 112{
113 Standard_Integer i, i1, i2, inter;
7fd59977 114 Standard_Real Par, valU, valU2 = RealLast(),
a86d3ec0 115 local_u0 ;
7fd59977 116 Standard_Real myintuinf=0, myintusup=0;
117 local_u0 = U0 ;
a86d3ec0 118 switch(type)
119 {
120 case GeomAbs_OtherCurve:
1aec3320 121 case GeomAbs_OffsetCurve:
a86d3ec0 122 case GeomAbs_BSplineCurve:
123 {
7fd59977 124 // La recherche de l extremum est faite intervalle continu C2 par
125 // intervalle continu C2 de la courbe
126 Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2);
127 TColStd_Array1OfReal theInter(1, n+1);
128 TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2);
a86d3ec0 129 //
130 // be gentle with the caller
131 //
7fd59977 132 if (local_u0 < myumin) {
a86d3ec0 133 local_u0 = myumin ;
7fd59977 134 }
135 else if (local_u0 > myusup) {
a86d3ec0 136 local_u0 = myusup ;
7fd59977 137 }
138 // Recherche de l intervalle ou se trouve U0
139 Standard_Boolean found = Standard_False;
140 inter = 1;
141 while (!found && inter <= n) {
142 // Intervalle commun a l intervalle C2 courant de la courbe et a
143 // l intervalle total de recherche de l'extremum (hla : au cas ou
144 // myintuinf > myintusup, c est que les 2 intervalles ne s intersectent
145 // pas, mais il n'y avait aucune raison de sortir en "return")
146 myintuinf = Max(theInter(inter), myumin);
147 myintusup = Min(theInter(inter+1), myusup);
a86d3ec0 148 if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True;
149 inter++;
7fd59977 150 }
151
152 if( found ) inter--; //IFV 16.06.00 - inter is increased after found!
153
154 // Essai sur l intervalle trouve
155 myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
a86d3ec0 156 myintusup, mytol);
7fd59977 157 myLocExtPC.Perform(P, local_u0);
158 myDone = myLocExtPC.IsDone();
159 if (myDone) {
a86d3ec0 160 mypp = myLocExtPC.Point();
161 myismin = myLocExtPC.IsMin();
162 mydist2 = myLocExtPC.SquareDistance();
7fd59977 163 }
164 else {
a86d3ec0 165 Standard_Integer k = 1;
166 // Essai sur les intervalles alentours:
167 i1 = inter;
168 i2 = inter;
169 Standard_Real s1inf, s2inf, s1sup, s2sup;
170 ThePoint P1;
171 TheVector V1;
172 TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
173 s2inf = (TheVector(P, P1)*V1);
174 TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
175 s1sup = (TheVector(P, P1)*V1);
176
177
178 while (!myDone && (i2 > 0) && (i1 <= n))
179 {
180 i1 = inter + k;
181 i2 = inter - k;
182 if (i1 <= n)
183 {
184 myintuinf = Max(theInter(i1), myumin);
185 myintusup = Min(theInter(i1+1), myusup);
186 if (myintuinf < myintusup)
187 {
188 TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
189 s2sup = (TheVector(P, P1)*V1);
f4dee9bb 190 if(Precision::IsInfinite(s2sup) || Precision::IsInfinite(s1sup))
191 {
192 break;
193 }
a86d3ec0 194 if (s1sup*s2sup <= RealEpsilon())
195 {
196 // extremum:
197 myDone = Standard_True;
198 mypp.SetValues(myintuinf, P1);
199 myismin = (s1sup <= 0.0);
200 mydist2 = P.SquareDistance(P1);
201 break;
202 }
203
204 TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
205 s1sup = (TheVector(P, P1)*V1);
206 myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
207 myintusup, mytol);
208 myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
209 myDone = myLocExtPC.IsDone();
210 if (myDone) {
211 mypp = myLocExtPC.Point();
212 myismin = myLocExtPC.IsMin();
213 mydist2 = myLocExtPC.SquareDistance();
214 break;
215 }
216 }
217 }
218
219 if (i2 > 0)
220 {
221 myintuinf = Max(theInter(i2), myumin);
222 myintusup = Min(theInter(i2+1), myusup);
223 if (myintuinf < myintusup)
224 {
225 TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
226 s1inf = (TheVector(P, P1)*V1);
f4dee9bb 227 if(Precision::IsInfinite(s2inf) || Precision::IsInfinite(s1inf))
228 {
229 break;
230 }
a86d3ec0 231 if (s1inf*s2inf <= RealEpsilon())
232 {
233 // extremum:
234 myDone = Standard_True;
235 mypp.SetValues(myintusup, P1);
236 myismin = (s1inf <= 0.0);
237 mydist2 = P.SquareDistance(P1);
238 break;
239 }
240
241 TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
242 s2inf = (TheVector(P, P1)*V1);
243 myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
244 myintusup, mytol);
245 myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
246 myDone = myLocExtPC.IsDone();
247
248 if (myDone)
249 {
250 mypp = myLocExtPC.Point();
251 myismin = myLocExtPC.IsMin();
252 mydist2 = myLocExtPC.SquareDistance();
253 break;
254 }
255 }
256 }
257
258 k++;
259 }
7fd59977 260 }
261 }
a86d3ec0 262
263 break;
264
265 case GeomAbs_BezierCurve:
266 {
7fd59977 267 myLocExtPC.Perform(P, U0);
268 myDone = myLocExtPC.IsDone();
269 }
a86d3ec0 270
271 break;
272 default:
273 {
7fd59977 274 myExtremPC.Perform(P);
275 numberext = 0;
a86d3ec0 276 if (myExtremPC.IsDone())
277 {
278 for (i = 1; i <= myExtremPC.NbExt(); i++)
279 {
280 Par = myExtremPC.Point(i).Parameter();
281 valU = Abs(Par - U0);
282 if (valU <= valU2)
283 {
284 valU2 = valU;
285 numberext = i;
286 myDone = Standard_True;
287 }
288 }
7fd59977 289 }
a86d3ec0 290
291 if (numberext == 0)
292 myDone = Standard_False;
293
7fd59977 294 break;
295 }
296 }
297}
298
299
300
301
302//=======================================================================
303//function : IsDone
304//purpose :
305//=======================================================================
306
307Standard_Boolean Extrema_GLocateExtPC::IsDone () const
308{
309 return myDone;
310}
311
312
313//=======================================================================
314//function : Value
315//purpose :
316//=======================================================================
317
318Standard_Real Extrema_GLocateExtPC::SquareDistance () const
319{
9775fa61 320 if (!myDone) { throw StdFail_NotDone(); }
7fd59977 321 Standard_Real d=0;
322 if ((type == GeomAbs_BezierCurve)) {
323 d = myLocExtPC.SquareDistance();
324 }
1aec3320 325 else if(type == GeomAbs_BSplineCurve ||
326 type == GeomAbs_OffsetCurve ||
327 type == GeomAbs_OtherCurve) {
7fd59977 328 d = mydist2;
329 }
330 else {
331 if (numberext != 0) {
332 d = myExtremPC.SquareDistance(numberext);
333 }
334 }
335 return d;
336}
337
338
339//=======================================================================
340//function : IsMin
341//purpose :
342//=======================================================================
343
344Standard_Boolean Extrema_GLocateExtPC::IsMin () const
345{
9775fa61 346 if (!myDone) { throw StdFail_NotDone(); }
7fd59977 347 Standard_Boolean b=0;
348 if ((type == GeomAbs_BezierCurve)) {
349 b = myLocExtPC.IsMin();
350 }
1aec3320 351 else if(type == GeomAbs_BSplineCurve ||
352 type == GeomAbs_OffsetCurve ||
353 type == GeomAbs_OtherCurve) {
7fd59977 354 b = myismin;
355 }
356 else {
357 if (numberext != 0) {
358 b = myExtremPC.IsMin(numberext);
359 }
360 }
361 return b;
362}
363
364
365//=======================================================================
366//function : Point
367//purpose :
368//=======================================================================
369
5d99f2c8 370const ThePOnC & Extrema_GLocateExtPC::Point () const
7fd59977 371{
9775fa61 372 if (!myDone) { throw StdFail_NotDone(); }
7fd59977 373 if (type == GeomAbs_BezierCurve) {
5d99f2c8 374 return myLocExtPC.Point();
7fd59977 375 }
1aec3320 376 else if(type == GeomAbs_BSplineCurve ||
377 type == GeomAbs_OffsetCurve ||
378 type == GeomAbs_OtherCurve) {
5d99f2c8 379 return mypp;
7fd59977 380 }
5d99f2c8 381 return myExtremPC.Point(numberext);
7fd59977 382}