0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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_Surface.hxx>
20#include <Bnd_Box.hxx>
21#include <BndLib_AddSurface.hxx>
22#include <ElCLib.hxx>
23#include <ElSLib.hxx>
24#include <Extrema_ExtCS.hxx>
7fd59977 25#include <Extrema_GenExtCS.hxx>
42cf5bc1 26#include <Extrema_POnCurv.hxx>
27#include <Extrema_POnSurf.hxx>
7fd59977 28#include <GeomAbs_CurveType.hxx>
42cf5bc1 29#include <gp_Lin.hxx>
42cf5bc1 30#include <gp_Pnt.hxx>
42cf5bc1 31#include <Precision.hxx>
42cf5bc1 32#include <Standard_OutOfRange.hxx>
42cf5bc1 33#include <StdFail_NotDone.hxx>
38308958 34#include <TColStd_Array1OfReal.hxx>
e8e8b273 35#include <Extrema_ExtPS.hxx>
7fd59977 36
d533dafb 37Extrema_ExtCS::Extrema_ExtCS()
38: myS(NULL),
39 myDone(Standard_False),
40 myIsPar(Standard_False),
41 myuinf(0.0),
42 myusup(0.0),
43 myvinf(0.0),
44 myvsup(0.0),
45 mytolC(0.0),
46 mytolS(0.0),
47 myucinf(0.0),
48 myucsup(0.0),
49 myStype(GeomAbs_OtherSurface)
7fd59977 50{
7fd59977 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{
d6e050ac 59 Initialize (S, TolC, TolS);
7fd59977 60 Perform(C, C.FirstParameter(), C.LastParameter());
61}
62
63Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
29d778bf 64 const Adaptor3d_Surface& S,
65 const Standard_Real UCinf,
66 const Standard_Real UCsup,
67 const Standard_Real Uinf,
68 const Standard_Real Usup,
69 const Standard_Real Vinf,
70 const Standard_Real Vsup,
71 const Standard_Real TolC,
72 const Standard_Real TolS)
7fd59977 73
74{
75 Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS);
76 Perform(C, UCinf, UCsup);
77}
78
d6e050ac 79void Extrema_ExtCS::Initialize (const Adaptor3d_Surface& S, const Standard_Real TolC, const Standard_Real TolS)
80{
81 Initialize (S, S.FirstUParameter(), S.LastUParameter(),
82 S.FirstVParameter(), S.LastVParameter(),
83 TolC, TolS);
84}
7fd59977 85
86void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S,
29d778bf 87 const Standard_Real Uinf,
88 const Standard_Real Usup,
89 const Standard_Real Vinf,
90 const Standard_Real Vsup,
91 const Standard_Real TolC,
92 const Standard_Real TolS)
7fd59977 93{
d6e050ac 94 myS = &S;
7fd59977 95 myIsPar = Standard_False;
96 myuinf = Uinf;
97 myusup = Usup;
98 myvinf = Vinf;
99 myvsup = Vsup;
100 mytolC = TolC;
101 mytolS = TolS;
102 myStype = myS->GetType();
103}
104
29d778bf 105
7fd59977 106void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
29d778bf 107 const Standard_Real Uinf,
108 const Standard_Real Usup)
7fd59977 109{
110 myucinf = Uinf;
111 myucsup = Usup;
112 myPOnS.Clear();
113 myPOnC.Clear();
114 mySqDist.Clear();
38308958 115 Standard_Integer i, j;
7fd59977 116 Standard_Integer NbT, NbU, NbV;
79aa9b5c 117 NbT = 12; NbU = NbV = 10;
7fd59977 118 GeomAbs_CurveType myCtype = C.GetType();
119
03cca6f7 120 myDone = Standard_False;
121 // Try analytic computation of extrema
122 Standard_Boolean isComputeAnalytic = Standard_True;
7fd59977 123
124 switch(myCtype) {
125
126 case GeomAbs_Line:
127 {
29d778bf 128
7fd59977 129 switch(myStype) {
130 case GeomAbs_Sphere:
29d778bf 131 myExtElCS.Perform(C.Line(), myS->Sphere());
132 break;
7fd59977 133 case GeomAbs_Cylinder:
29d778bf 134 myExtElCS.Perform(C.Line(), myS->Cylinder());
135 break;
7fd59977 136 case GeomAbs_Plane:
29d778bf 137 myExtElCS.Perform(C.Line(), myS->Plane());
138 if (myExtElCS.IsParallel()) break;
b1811c1d 139 Standard_FALLTHROUGH
7fd59977 140
141 case GeomAbs_Torus:
142 case GeomAbs_Cone:
143 case GeomAbs_BezierSurface:
144 case GeomAbs_BSplineSurface:
145 case GeomAbs_SurfaceOfRevolution:
146 case GeomAbs_SurfaceOfExtrusion:
1896126e 147 case GeomAbs_OffsetSurface:
7fd59977 148 case GeomAbs_OtherSurface:
29d778bf 149 {
150 Standard_Real cfirst = myucinf, clast = myucsup;
151 Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(),
152 vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter();
7fd59977 153
4563cf3e 154 if (!(Precision::IsInfinite(ufirst) || Precision::IsInfinite(ulast) ||
155 Precision::IsInfinite(vfirst) || Precision::IsInfinite(vlast)))
156 {
157 Standard_Real tmin = Precision::Infinite(), tmax = -tmin;
158 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
29d778bf 159 Bnd_Box aSurfBox;
1896126e 160 BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox);
29d778bf 161 aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
29d778bf 162 gp_Lin aLin = C.Line();
4563cf3e 163 Standard_Real aParOnLin;
164 gp_Pnt aLimPntArray[8];
165
166 aLimPntArray[0].SetCoord(xmin, ymin, zmin);
167 aLimPntArray[1].SetCoord(xmax, ymin, zmin);
168 aLimPntArray[2].SetCoord(xmin, ymax, zmin);
169 aLimPntArray[3].SetCoord(xmax, ymax, zmin);
170 aLimPntArray[4].SetCoord(xmin, ymin, zmax);
171 aLimPntArray[5].SetCoord(xmax, ymin, zmax);
172 aLimPntArray[6].SetCoord(xmin, ymax, zmax);
173 aLimPntArray[7].SetCoord(xmax, ymax, zmax);
174
175 for (i = 0; i <= 7; i++) {
176 aParOnLin = ElCLib::Parameter(aLin, aLimPntArray[i]);
177 tmin = Min(aParOnLin, tmin);
178 tmax = Max(aParOnLin, tmax);
29d778bf 179 }
29d778bf 180 cfirst = Max(cfirst, tmin);
4563cf3e 181 clast = Min(clast, tmax);
29d778bf 182 }
183
fa6d1712 184 if (myS->IsUPeriodic())
185 NbU = 13;
186 if (myS->IsVPeriodic())
187 NbV = 13;
29d778bf 188
e8e8b273 189 if (clast - cfirst <= Precision::Confusion())
190 {
191 Standard_Real aCPar = (cfirst + clast) / 2.;
192 gp_Pnt aPm = C.Value(aCPar);
193 Extrema_ExtPS anExtPS(aPm, *myS, ufirst, ulast,
194 vfirst, vlast, mytolS, mytolS, Extrema_ExtFlag_MIN);
195 myDone = anExtPS.IsDone();
196 if (myDone) {
197 Standard_Integer NbExt = anExtPS.NbExt();
198 Standard_Real T = aCPar, U, V;
199 Extrema_POnCurv PC;
200 Extrema_POnSurf PS;
201 for (i = 1; i <= NbExt; i++) {
202 PS = anExtPS.Point(i);
203 PS.Parameter(U, V);
204 AddSolution(C, T, U, V, PC.Value(), PS.Value(), anExtPS.SquareDistance(i));
205 }
206 }
207 return;
208 }
209
29d778bf 210 Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast,
211 vfirst, vlast, mytolC, mytolS);
212
213 myDone = Ext.IsDone();
214 if (myDone) {
215 Standard_Integer NbExt = Ext.NbExt();
216 Standard_Real T,U,V;
217 Extrema_POnCurv PC;
218 Extrema_POnSurf PS;
219 for (i = 1; i <= NbExt; i++) {
220 PC = Ext.PointOnCurve(i);
221 PS = Ext.PointOnSurface(i);
222 T = PC.Parameter();
223 PS.Parameter(U, V);
38308958 224 AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
29d778bf 225 }
226 }
227 return;
29d778bf 228 }
7fd59977 229 }
230 break;
231 }
29d778bf 232 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin
7fd59977 233 case GeomAbs_Circle:
234 {
235 if(myStype == GeomAbs_Cylinder) {
29d778bf 236 myExtElCS.Perform(C.Circle(), myS->Cylinder());
237 break;
7fd59977 238 }
9dfbbfe6 239 else if(myStype == GeomAbs_Plane)
240 {
241 myExtElCS.Perform(C.Circle(), myS->Plane());
242 break;
243 }
03cca6f7 244 else if (myStype == GeomAbs_Sphere)
245 {
246 myExtElCS.Perform(C.Circle(), myS->Sphere());
247 break;
248 }
7fd59977 249 }
b1811c1d 250 Standard_FALLTHROUGH
7fd59977 251 case GeomAbs_Hyperbola:
252 {
253 if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) {
29d778bf 254 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End
255 myExtElCS.Perform(C.Hyperbola(), myS->Plane());
256 break;
7fd59977 257 }
258 }
b1811c1d 259 Standard_FALLTHROUGH
7fd59977 260 default:
261 {
03cca6f7 262 isComputeAnalytic = Standard_False;
263 break;
264 }
265 }
266
267 if (isComputeAnalytic)
268 {
269 if (myExtElCS.IsDone())
270 {
271 myDone = Standard_True;
272 myIsPar = myExtElCS.IsParallel();
273 if (myIsPar)
274 {
275 mySqDist.Append(myExtElCS.SquareDistance(1));
7fd59977 276 }
03cca6f7 277 else
278 {
279 Standard_Integer NbExt = myExtElCS.NbExt();
280 for (i = 1; i <= NbExt; i++)
fa6d1712 281 {
03cca6f7 282 Extrema_POnCurv PC;
283 Extrema_POnSurf PS;
284 myExtElCS.Points(i, PC, PS);
285 Standard_Real Ucurve = PC.Parameter();
286 Standard_Real U, V;
29d778bf 287 PS.Parameter(U, V);
03cca6f7 288 AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i));
29d778bf 289 }
38308958 290
03cca6f7 291 if (mySqDist.Length() == 0 && NbExt > 0)
38308958 292 {
03cca6f7 293 // Analytical extrema seem to be out of curve/surface boundaries.
294 // Try extremity points of curve.
295 gp_Pnt aPOnC[2], aPOnS[2];
296 Standard_Real aT[2] = { myucinf, myucsup }, U[2], V[2];
297 Standard_Real aDist[2] = { -1, -1 };
298 for (i = 0; i < 2; ++i)
38308958 299 {
03cca6f7 300 if (Precision::IsInfinite(aT[i]))
301 continue;
302
303 aPOnC[i] = C.Value(aT[i]);
304 switch (myStype)
38308958 305 {
03cca6f7 306 case GeomAbs_Plane:
307 {
308 ElSLib::Parameters(myS->Plane(), aPOnC[i], U[i], V[i]);
309 aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Plane());
310 break;
311 }
312 case GeomAbs_Sphere:
313 {
314 ElSLib::Parameters(myS->Sphere(), aPOnC[i], U[i], V[i]);
315 aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Sphere());
316 break;
317 }
318 case GeomAbs_Cylinder:
319 {
320 ElSLib::Parameters(myS->Cylinder(), aPOnC[i], U[i], V[i]);
321 aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Cylinder());
322 break;
323 }
324 case GeomAbs_Torus:
325 {
326 ElSLib::Parameters(myS->Torus(), aPOnC[i], U[i], V[i]);
327 aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Torus());
328 break;
329 }
330 case GeomAbs_Cone:
331 {
332 ElSLib::Parameters(myS->Cone(), aPOnC[i], U[i], V[i]);
333 aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Cone());
334 break;
335 }
336 default:
337 continue;
38308958 338 }
03cca6f7 339
340 aDist[i] = aPOnC[i].SquareDistance(aPOnS[i]);
38308958 341 }
03cca6f7 342
343 Standard_Boolean bAdd[2] = {Standard_False, Standard_False};
344
345 // Choose solution to add
346 if (aDist[0] >= 0. && aDist[1] >= 0.)
38308958 347 {
03cca6f7 348 Standard_Real aDiff = aDist[0] - aDist[1];
349 // Both computed -> take only minimal
350 if (Abs(aDiff) < Precision::Confusion())
351 // Add both
352 bAdd[0] = bAdd[1] = Standard_True;
353 else if (aDiff < 0)
354 // Add first
355 bAdd[0] = Standard_True;
356 else
357 // Add second
358 bAdd[1] = Standard_True;
359 }
360 else if (aDist[0] >= 0.)
361 // Add first
362 bAdd[0] = Standard_True;
363 else if (aDist[1] >= 0.)
364 // Add second
365 bAdd[1] = Standard_True;
366
367 for (i = 0; i < 2; ++i)
368 {
369 if (bAdd[i])
370 AddSolution(C, aT[i], U[i], V[i], aPOnC[i], aPOnS[i], aDist[i]);
38308958 371 }
38308958 372 }
7fd59977 373 }
374 return;
375 }
7fd59977 376 }
29d778bf 377
03cca6f7 378 // Elementary extrema is not done, try generic solution
379 Extrema_GenExtCS Ext;
380 Ext.Initialize(*myS, NbU, NbV, mytolS);
381 if (myCtype == GeomAbs_Hyperbola) {
382 Standard_Real tmin = Max(-20., C.FirstParameter());
383 Standard_Real tmax = Min(20., C.LastParameter());
384 Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
385 }
386 else {
387 if ((myCtype == GeomAbs_Circle && NbT < 13) ||
388 (myCtype == GeomAbs_BSplineCurve && NbT < 13))
389 {
390 NbT = 13;
391 }
392 Ext.Perform(C, NbT, mytolC);
393 }
394
395 myDone = Ext.IsDone();
7fd59977 396 if (myDone) {
03cca6f7 397 Standard_Integer NbExt = Ext.NbExt();
398 Standard_Real T, U, V;
399 Extrema_POnCurv PC;
400 Extrema_POnSurf PS;
401 for (i = 1; i <= NbExt; i++) {
402 PC = Ext.PointOnCurve(i);
403 PS = Ext.PointOnSurface(i);
404 T = PC.Parameter();
405 PS.Parameter(U, V);
406 AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
7fd59977 407 }
03cca6f7 408
409 //Add sharp points
410 Standard_Integer SolNumber = mySqDist.Length();
411 Standard_Address CopyC = (Standard_Address)&C;
412 Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)CopyC;
413 Standard_Integer NbIntervals = aC.NbIntervals(GeomAbs_C1);
414 TColStd_Array1OfReal SharpPoints(1, NbIntervals + 1);
415 aC.Intervals(SharpPoints, GeomAbs_C1);
416
417 Extrema_ExtPS aProjPS;
418 aProjPS.Initialize(*myS,
419 myS->FirstUParameter(),
420 myS->LastUParameter(),
421 myS->FirstVParameter(),
422 myS->LastVParameter(),
423 mytolS,
424 mytolS);
425
426 for (i = 2; i < SharpPoints.Upper(); ++i)
427 {
428 T = SharpPoints(i);
429 gp_Pnt aPnt = C.Value(T);
430 aProjPS.Perform(aPnt);
431 if (!aProjPS.IsDone())
432 continue;
433 Standard_Integer NbProj = aProjPS.NbExt(), jmin = 0;
434 Standard_Real MinSqDist = RealLast();
435 for (j = 1; j <= NbProj; j++)
9dfbbfe6 436 {
03cca6f7 437 Standard_Real aSqDist = aProjPS.SquareDistance(j);
438 if (aSqDist < MinSqDist)
9dfbbfe6 439 {
03cca6f7 440 MinSqDist = aSqDist;
441 jmin = j;
9dfbbfe6 442 }
443 }
03cca6f7 444 if (jmin != 0)
445 {
446 aProjPS.Point(jmin).Parameter(U, V);
447 AddSolution(C, T, U, V,
448 aPnt, aProjPS.Point(jmin).Value(), MinSqDist);
449 }
450 }
451 //Cut sharp solutions to keep only minimum and maximum
452 Standard_Integer imin = SolNumber + 1, imax = mySqDist.Length();
453 for (i = SolNumber + 1; i <= mySqDist.Length(); i++)
454 {
455 if (mySqDist(i) < mySqDist(imin))
456 imin = i;
457 if (mySqDist(i) > mySqDist(imax))
458 imax = i;
459 }
460 if (mySqDist.Length() > SolNumber + 2)
461 {
462 Standard_Real MinSqDist = mySqDist(imin);
463 Standard_Real MaxSqDist = mySqDist(imax);
464 Extrema_POnCurv MinPC = myPOnC(imin);
465 Extrema_POnCurv MaxPC = myPOnC(imax);
466 Extrema_POnSurf MinPS = myPOnS(imin);
467 Extrema_POnSurf MaxPS = myPOnS(imax);
468
469 mySqDist.Remove(SolNumber + 1, mySqDist.Length());
470 myPOnC.Remove(SolNumber + 1, myPOnC.Length());
471 myPOnS.Remove(SolNumber + 1, myPOnS.Length());
472
473 mySqDist.Append(MinSqDist);
474 myPOnC.Append(MinPC);
475 myPOnS.Append(MinPS);
476 mySqDist.Append(MaxSqDist);
477 myPOnC.Append(MaxPC);
478 myPOnS.Append(MaxPS);
7fd59977 479 }
480 }
7fd59977 481}
482
483
484Standard_Boolean Extrema_ExtCS::IsDone() const
485{
486 return myDone;
487}
488
489Standard_Boolean Extrema_ExtCS::IsParallel() const
490{
638ad7f3 491 if (!IsDone())
492 {
493 throw StdFail_NotDone();
494 }
495
7fd59977 496 return myIsPar;
497}
498
499
500Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
501{
638ad7f3 502 if (N < 1 || N > NbExt())
503 {
504 throw Standard_OutOfRange();
505 }
506
7fd59977 507 return mySqDist.Value(N);
508}
509
510
511Standard_Integer Extrema_ExtCS::NbExt() const
512{
638ad7f3 513 if (!IsDone())
514 {
515 throw StdFail_NotDone();
516 }
517
518 return mySqDist.Length();
7fd59977 519}
520
521
522
523void Extrema_ExtCS::Points(const Standard_Integer N,
638ad7f3 524 Extrema_POnCurv& P1,
525 Extrema_POnSurf& P2) const
7fd59977 526{
638ad7f3 527 if (N < 1 || N > NbExt())
528 {
529 throw Standard_OutOfRange();
530 }
531
7fd59977 532 P1 = myPOnC.Value(N);
533 P2 = myPOnS.Value(N);
534}
38308958 535
536Standard_Boolean Extrema_ExtCS::AddSolution(const Adaptor3d_Curve& theCurve,
29d778bf 537 const Standard_Real aT,
538 const Standard_Real aU,
539 const Standard_Real aV,
540 const gp_Pnt& PointOnCurve,
541 const gp_Pnt& PointOnSurf,
542 const Standard_Real SquareDist)
38308958 543{
544 Standard_Boolean Added = Standard_False;
545
546 Standard_Real T = aT, U = aU, V = aV;
29d778bf 547
38308958 548 if (theCurve.IsPeriodic())
549 T = ElCLib::InPeriod(T, myucinf, myucinf + theCurve.Period());
550 if (myS->IsUPeriodic())
551 U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
552 if (myS->IsVPeriodic())
553 V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
554
555 Extrema_POnCurv aPC;
556 Extrema_POnSurf aPS;
557 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
29d778bf 558 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
559 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS)
38308958 560 {
561 Standard_Boolean IsNewSolution = Standard_True;
562 for (Standard_Integer j = 1; j <= mySqDist.Length(); j++)
563 {
564 aPC = myPOnC(j);
565 aPS = myPOnS(j);
566 Standard_Real Tj = aPC.Parameter();
567 Standard_Real Uj, Vj;
568 aPS.Parameter(Uj, Vj);
569 if (Abs(T - Tj) <= mytolC &&
29d778bf 570 Abs(U - Uj) <= mytolS &&
571 Abs(V - Vj) <= mytolS)
38308958 572 {
573 IsNewSolution = Standard_False;
574 break;
575 }
576 }
577 if (IsNewSolution)
578 {
579 mySqDist.Append(SquareDist);
580 aPC.SetValues(T, PointOnCurve);
581 myPOnC.Append(aPC);
582 myPOnS.Append(Extrema_POnSurf(U, V, PointOnSurf));
583 Added = Standard_True;
584 }
585 }
586 return Added;
587}