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 |
37 | Extrema_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 | |
53 | Extrema_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 | |
63 | Extrema_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 |
79 | void 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 | |
86 | void 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 |
106 | void 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 | |
484 | Standard_Boolean Extrema_ExtCS::IsDone() const |
485 | { |
486 | return myDone; |
487 | } |
488 | |
489 | Standard_Boolean Extrema_ExtCS::IsParallel() const |
490 | { |
638ad7f3 |
491 | if (!IsDone()) |
492 | { |
493 | throw StdFail_NotDone(); |
494 | } |
495 | |
7fd59977 |
496 | return myIsPar; |
497 | } |
498 | |
499 | |
500 | Standard_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 | |
511 | Standard_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 | |
523 | void 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 | |
536 | Standard_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 | } |