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