0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[occt.git] / src / Extrema / Extrema_ExtCS.cxx
CommitLineData
b311480e 1// Created on: 1995-07-18
2// Created by: Modelistation
3// Copyright (c) 1995-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.
7fd59977 16
17// Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134
18
42cf5bc1 19#include <Adaptor3d_Curve.hxx>
20#include <Adaptor3d_Surface.hxx>
21#include <Bnd_Box.hxx>
22#include <BndLib_AddSurface.hxx>
23#include <ElCLib.hxx>
24#include <ElSLib.hxx>
25#include <Extrema_ExtCS.hxx>
26#include <Extrema_ExtPElC.hxx>
27#include <Extrema_ExtPElS.hxx>
28#include <Extrema_ExtPS.hxx>
7fd59977 29#include <Extrema_GenExtCS.hxx>
42cf5bc1 30#include <Extrema_POnCurv.hxx>
31#include <Extrema_POnSurf.hxx>
7fd59977 32#include <GeomAbs_CurveType.hxx>
7fd59977 33#include <gp_Cone.hxx>
42cf5bc1 34#include <gp_Cylinder.hxx>
35#include <gp_Lin.hxx>
36#include <gp_Pln.hxx>
37#include <gp_Pnt.hxx>
7fd59977 38#include <gp_Sphere.hxx>
39#include <gp_Torus.hxx>
42cf5bc1 40#include <Precision.hxx>
41#include <Standard_NotImplemented.hxx>
42#include <Standard_OutOfRange.hxx>
43#include <Standard_TypeMismatch.hxx>
44#include <StdFail_InfiniteSolutions.hxx>
45#include <StdFail_NotDone.hxx>
38308958 46#include <TColStd_Array1OfReal.hxx>
7fd59977 47
48Extrema_ExtCS::Extrema_ExtCS()
49{
50 myDone = Standard_False;
51}
52
53Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
29d778bf 54 const Adaptor3d_Surface& S,
55 const Standard_Real TolC,
56 const Standard_Real TolS)
7fd59977 57
58{
59 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
29d778bf 60 S.FirstVParameter(), S.LastVParameter(),
61 TolC, TolS);
7fd59977 62 Perform(C, C.FirstParameter(), C.LastParameter());
63}
64
65Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
29d778bf 66 const Adaptor3d_Surface& S,
67 const Standard_Real UCinf,
68 const Standard_Real UCsup,
69 const Standard_Real Uinf,
70 const Standard_Real Usup,
71 const Standard_Real Vinf,
72 const Standard_Real Vsup,
73 const Standard_Real TolC,
74 const Standard_Real TolS)
7fd59977 75
76{
77 Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS);
78 Perform(C, UCinf, UCsup);
79}
80
81
82void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S,
29d778bf 83 const Standard_Real Uinf,
84 const Standard_Real Usup,
85 const Standard_Real Vinf,
86 const Standard_Real Vsup,
87 const Standard_Real TolC,
88 const Standard_Real TolS)
7fd59977 89{
90 myS = (Adaptor3d_SurfacePtr)&S;
91 myIsPar = Standard_False;
92 myuinf = Uinf;
93 myusup = Usup;
94 myvinf = Vinf;
95 myvsup = Vsup;
96 mytolC = TolC;
97 mytolS = TolS;
98 myStype = myS->GetType();
99}
100
29d778bf 101
7fd59977 102void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
29d778bf 103 const Standard_Real Uinf,
104 const Standard_Real Usup)
7fd59977 105{
106 myucinf = Uinf;
107 myucsup = Usup;
108 myPOnS.Clear();
109 myPOnC.Clear();
110 mySqDist.Clear();
38308958 111 Standard_Integer i, j;
7fd59977 112 Standard_Integer NbT, NbU, NbV;
113 NbT = NbU = NbV = 10;
114 GeomAbs_CurveType myCtype = C.GetType();
115
116
117 switch(myCtype) {
118
119 case GeomAbs_Line:
120 {
29d778bf 121
7fd59977 122 switch(myStype) {
123 case GeomAbs_Sphere:
29d778bf 124 myExtElCS.Perform(C.Line(), myS->Sphere());
125 break;
7fd59977 126 case GeomAbs_Cylinder:
29d778bf 127 myExtElCS.Perform(C.Line(), myS->Cylinder());
128 break;
7fd59977 129 case GeomAbs_Plane:
29d778bf 130 myExtElCS.Perform(C.Line(), myS->Plane());
131 if (myExtElCS.IsParallel()) break;
b1811c1d 132 Standard_FALLTHROUGH
7fd59977 133
134 case GeomAbs_Torus:
135 case GeomAbs_Cone:
136 case GeomAbs_BezierSurface:
137 case GeomAbs_BSplineSurface:
138 case GeomAbs_SurfaceOfRevolution:
139 case GeomAbs_SurfaceOfExtrusion:
1896126e 140 case GeomAbs_OffsetSurface:
7fd59977 141 case GeomAbs_OtherSurface:
29d778bf 142 {
143 Standard_Real cfirst = myucinf, clast = myucsup;
144 Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(),
145 vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter();
7fd59977 146
29d778bf 147 if(Precision::IsInfinite(Abs(cfirst)) || Precision::IsInfinite(Abs(clast))) {
7fd59977 148
29d778bf 149 Bnd_Box aSurfBox;
1896126e 150 BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox);
29d778bf 151 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
152 aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
153 Standard_Real tmin = Precision::Infinite(), tmax = -tmin;
154 gp_Lin aLin = C.Line();
155
156
157 if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) ||
158 Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) ||
159 Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) {
160
161 Extrema_ExtPElC anExt;
162 Extrema_POnCurv aPntOnLin;
163 Standard_Real aParOnLin;
164 Standard_Real lim = Precision::Infinite();
165 gp_Pnt aLimPntArray[8];
166
167 aLimPntArray[0].SetCoord(xmin, ymin, zmin);
168 aLimPntArray[1].SetCoord(xmax, ymin, zmin);
169 aLimPntArray[2].SetCoord(xmin, ymax, zmin);
170 aLimPntArray[3].SetCoord(xmax, ymax, zmin);
171 aLimPntArray[4].SetCoord(xmin, ymin, zmax);
172 aLimPntArray[5].SetCoord(xmax, ymin, zmax);
173 aLimPntArray[6].SetCoord(xmin, ymax, zmax);
174 aLimPntArray[7].SetCoord(xmax, ymax, zmax);
175
176 for(i = 0; i <= 7; i++) {
177 anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim);
178 aPntOnLin = anExt.Point(1);
179 aParOnLin = aPntOnLin.Parameter();
180 tmin = Min(aParOnLin, tmin);
181 tmax = Max(aParOnLin, tmax);
182 }
183
184 }
185 else {
186 tmin = -1.e+50;
187 tmax = 1.e+50;
188 }
189
190
191 cfirst = Max(cfirst, tmin);
192 clast = Min(clast, tmax);
193
194 }
195
fa6d1712 196 if (myS->IsUPeriodic())
197 NbU = 13;
198 if (myS->IsVPeriodic())
199 NbV = 13;
29d778bf 200
201 Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast,
202 vfirst, vlast, mytolC, mytolS);
203
204 myDone = Ext.IsDone();
205 if (myDone) {
206 Standard_Integer NbExt = Ext.NbExt();
207 Standard_Real T,U,V;
208 Extrema_POnCurv PC;
209 Extrema_POnSurf PS;
210 for (i = 1; i <= NbExt; i++) {
211 PC = Ext.PointOnCurve(i);
212 PS = Ext.PointOnSurface(i);
213 T = PC.Parameter();
214 PS.Parameter(U, V);
38308958 215 AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
29d778bf 216 }
217 }
218 return;
219
220 }
7fd59977 221 }
222 break;
223 }
29d778bf 224 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin
7fd59977 225 case GeomAbs_Circle:
226 {
227 if(myStype == GeomAbs_Cylinder) {
29d778bf 228 myExtElCS.Perform(C.Circle(), myS->Cylinder());
229 break;
7fd59977 230 }
9dfbbfe6 231 else if(myStype == GeomAbs_Plane)
232 {
233 myExtElCS.Perform(C.Circle(), myS->Plane());
234 break;
235 }
7fd59977 236 }
b1811c1d 237 Standard_FALLTHROUGH
7fd59977 238 case GeomAbs_Hyperbola:
239 {
240 if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) {
29d778bf 241 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End
242 myExtElCS.Perform(C.Hyperbola(), myS->Plane());
243 break;
7fd59977 244 }
245 }
b1811c1d 246 Standard_FALLTHROUGH
7fd59977 247 default:
248 {
249 Extrema_GenExtCS Ext;
250 Ext.Initialize(*myS, NbU, NbV, mytolS);
251 if(myCtype == GeomAbs_Hyperbola) {
29d778bf 252 Standard_Real tmin = Max(-20., C.FirstParameter());
253 Standard_Real tmax = Min(20., C.LastParameter());
254 Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
7fd59977 255 }
256 else {
fa6d1712 257 if((myCtype == GeomAbs_Circle && NbT < 13) ||
258 (myCtype == GeomAbs_BSplineCurve && NbT < 13) )
259 {
29d778bf 260 NbT = 13;
261 }
262 Ext.Perform(C, NbT, mytolC);
7fd59977 263 }
29d778bf 264
7fd59977 265 myDone = Ext.IsDone();
266 if (myDone) {
29d778bf 267 Standard_Integer NbExt = Ext.NbExt();
268 Standard_Real T,U,V;
269 Extrema_POnCurv PC;
270 Extrema_POnSurf PS;
271 for (i = 1; i <= NbExt; i++) {
272 PC = Ext.PointOnCurve(i);
273 PS = Ext.PointOnSurface(i);
274 T = PC.Parameter();
275 PS.Parameter(U, V);
38308958 276 AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
29d778bf 277 }
38308958 278
279 //Add sharp points
280 Standard_Integer SolNumber = mySqDist.Length();
281 Standard_Address CopyC = (Standard_Address)&C;
282 Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)CopyC;
283 Standard_Integer NbIntervals = aC.NbIntervals(GeomAbs_C1);
284 TColStd_Array1OfReal SharpPoints(1, NbIntervals+1);
285 aC.Intervals(SharpPoints, GeomAbs_C1);
0734c53d 286
287 Extrema_ExtPS aProjPS;
288 aProjPS.Initialize (*myS,
289 myS->FirstUParameter(),
290 myS->LastUParameter(),
291 myS->FirstVParameter(),
292 myS->LastVParameter(),
293 mytolS,
294 mytolS);
295
296 for (i = 2; i < SharpPoints.Upper(); ++i)
38308958 297 {
298 T = SharpPoints(i);
299 gp_Pnt aPnt = C.Value(T);
0734c53d 300 aProjPS.Perform (aPnt);
301 if (!aProjPS.IsDone())
38308958 302 continue;
0734c53d 303 Standard_Integer NbProj = aProjPS.NbExt(), jmin = 0;
38308958 304 Standard_Real MinSqDist = RealLast();
305 for (j = 1; j <= NbProj; j++)
306 {
0734c53d 307 Standard_Real aSqDist = aProjPS.SquareDistance(j);
38308958 308 if (aSqDist < MinSqDist)
309 {
310 MinSqDist = aSqDist;
311 jmin = j;
312 }
313 }
314 if (jmin != 0)
315 {
0734c53d 316 aProjPS.Point(jmin).Parameter(U,V);
38308958 317 AddSolution(C, T, U, V,
0734c53d 318 aPnt, aProjPS.Point(jmin).Value(), MinSqDist);
38308958 319 }
320 }
321 //Cut sharp solutions to keep only minimum and maximum
322 Standard_Integer imin = SolNumber + 1, imax = mySqDist.Length();
323 for (i = SolNumber + 1; i <= mySqDist.Length(); i++)
324 {
325 if (mySqDist(i) < mySqDist(imin))
326 imin = i;
327 if (mySqDist(i) > mySqDist(imax))
328 imax = i;
329 }
330 if (mySqDist.Length() > SolNumber + 2)
331 {
332 Standard_Real MinSqDist = mySqDist(imin);
333 Standard_Real MaxSqDist = mySqDist(imax);
334 Extrema_POnCurv MinPC = myPOnC(imin);
335 Extrema_POnCurv MaxPC = myPOnC(imax);
336 Extrema_POnSurf MinPS = myPOnS(imin);
337 Extrema_POnSurf MaxPS = myPOnS(imax);
29d778bf 338
38308958 339 mySqDist.Remove(SolNumber + 1, mySqDist.Length());
340 myPOnC.Remove(SolNumber + 1, myPOnC.Length());
341 myPOnS.Remove(SolNumber + 1, myPOnS.Length());
342
343 mySqDist.Append(MinSqDist);
344 myPOnC.Append(MinPC);
345 myPOnS.Append(MinPS);
346 mySqDist.Append(MaxSqDist);
347 myPOnC.Append(MaxPC);
348 myPOnS.Append(MaxPS);
349 }
7fd59977 350 }
351 return;
352 }
353 break;
354 }
29d778bf 355
7fd59977 356 myDone = myExtElCS.IsDone();
357 if (myDone) {
358 myIsPar = myExtElCS.IsParallel();
359 if (myIsPar) {
360 mySqDist.Append(myExtElCS.SquareDistance(1));
361 }
362 else {
363 Standard_Integer NbExt = myExtElCS.NbExt();
364 Standard_Real U, V;
365 for (i = 1; i <= NbExt; i++) {
29d778bf 366 Extrema_POnCurv PC;
367 Extrema_POnSurf PS;
368 myExtElCS.Points(i, PC, PS);
369 Standard_Real Ucurve = PC.Parameter();
370 PS.Parameter(U, V);
38308958 371 AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i));
7fd59977 372 }
9dfbbfe6 373 if(mySqDist.Length() == 0 && NbExt > 0)
374 {
375 //Analytical extremas seem to be out of curve/surface boundaries.
376 //For plane it is possible to add extremity points of curve
377 if(myStype == GeomAbs_Plane)
378 {
379 gp_Pln aPln = myS->Plane();
380 gp_Pnt PC, PP;
381 if(!Precision::IsInfinite(myucinf))
382 {
383 PC = C.Value(myucinf);
384 ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
385 PP = ElSLib::PlaneValue(U, V, aPln.Position());
386 AddSolution(C, myucinf, U, V, PC, PP, PC.SquareDistance(PP));
387 }
388 if(!Precision::IsInfinite(myucsup))
389 {
390 PC = C.Value(myucsup);
391 ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
392 PP = ElSLib::PlaneValue(U, V, aPln.Position());
393 AddSolution(C, myucsup, U, V, PC, PP, PC.SquareDistance(PP));
394 }
395 }
396 }
7fd59977 397 }
398 }
29d778bf 399
7fd59977 400}
401
402
403Standard_Boolean Extrema_ExtCS::IsDone() const
404{
405 return myDone;
406}
407
408Standard_Boolean Extrema_ExtCS::IsParallel() const
409{
410 return myIsPar;
411}
412
413
414Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
415{
9775fa61 416 if(!myDone) throw StdFail_NotDone();
417 if (myIsPar && N != 1) throw StdFail_InfiniteSolutions();
418 if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
7fd59977 419 return mySqDist.Value(N);
420}
421
422
423Standard_Integer Extrema_ExtCS::NbExt() const
424{
9775fa61 425 if(!myDone) throw StdFail_NotDone();
9176540c 426 return myPOnC.Length();
7fd59977 427}
428
429
430
431void Extrema_ExtCS::Points(const Standard_Integer N,
29d778bf 432 Extrema_POnCurv& P1,
433 Extrema_POnSurf& P2) const
7fd59977 434{
9775fa61 435 if(!myDone) throw StdFail_NotDone();
7fd59977 436 P1 = myPOnC.Value(N);
437 P2 = myPOnS.Value(N);
438}
38308958 439
440Standard_Boolean Extrema_ExtCS::AddSolution(const Adaptor3d_Curve& theCurve,
29d778bf 441 const Standard_Real aT,
442 const Standard_Real aU,
443 const Standard_Real aV,
444 const gp_Pnt& PointOnCurve,
445 const gp_Pnt& PointOnSurf,
446 const Standard_Real SquareDist)
38308958 447{
448 Standard_Boolean Added = Standard_False;
449
450 Standard_Real T = aT, U = aU, V = aV;
29d778bf 451
38308958 452 if (theCurve.IsPeriodic())
453 T = ElCLib::InPeriod(T, myucinf, myucinf + theCurve.Period());
454 if (myS->IsUPeriodic())
455 U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
456 if (myS->IsVPeriodic())
457 V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
458
459 Extrema_POnCurv aPC;
460 Extrema_POnSurf aPS;
461 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
29d778bf 462 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
463 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS)
38308958 464 {
465 Standard_Boolean IsNewSolution = Standard_True;
466 for (Standard_Integer j = 1; j <= mySqDist.Length(); j++)
467 {
468 aPC = myPOnC(j);
469 aPS = myPOnS(j);
470 Standard_Real Tj = aPC.Parameter();
471 Standard_Real Uj, Vj;
472 aPS.Parameter(Uj, Vj);
473 if (Abs(T - Tj) <= mytolC &&
29d778bf 474 Abs(U - Uj) <= mytolS &&
475 Abs(V - Vj) <= mytolS)
38308958 476 {
477 IsNewSolution = Standard_False;
478 break;
479 }
480 }
481 if (IsNewSolution)
482 {
483 mySqDist.Append(SquareDist);
484 aPC.SetValues(T, PointOnCurve);
485 myPOnC.Append(aPC);
486 myPOnS.Append(Extrema_POnSurf(U, V, PointOnSurf));
487 Added = Standard_True;
488 }
489 }
490 return Added;
491}