b311480e |
1 | // Created on: 1995-07-18 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 |
23 | |
24 | #include <Extrema_ExtCS.ixx> |
25 | #include <Extrema_GenExtCS.hxx> |
26 | #include <StdFail_NotDone.hxx> |
27 | #include <Standard_NotImplemented.hxx> |
28 | #include <StdFail_InfiniteSolutions.hxx> |
29 | #include <Precision.hxx> |
30 | #include <GeomAbs_CurveType.hxx> |
31 | #include <gp_Pnt.hxx> |
32 | #include <gp_Pln.hxx> |
33 | #include <gp_Cylinder.hxx> |
34 | #include <gp_Cone.hxx> |
35 | #include <gp_Sphere.hxx> |
36 | #include <gp_Torus.hxx> |
37 | #include <gp_Lin.hxx> |
38 | |
39 | #include <ElCLib.hxx> |
40 | #include <Extrema_ExtPElC.hxx> |
41 | #include <Bnd_Box.hxx> |
42 | #include <BndLib_AddSurface.hxx> |
43 | #include <Extrema_ExtPElS.hxx> |
38308958 |
44 | #include <TColStd_Array1OfReal.hxx> |
45 | #include <Extrema_ExtPS.hxx> |
7fd59977 |
46 | |
47 | Extrema_ExtCS::Extrema_ExtCS() |
48 | { |
49 | myDone = Standard_False; |
50 | } |
51 | |
52 | Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C, |
53 | const Adaptor3d_Surface& S, |
54 | const Standard_Real TolC, |
55 | const Standard_Real TolS) |
56 | |
57 | { |
58 | Initialize(S, S.FirstUParameter(), S.LastUParameter(), |
59 | S.FirstVParameter(), S.LastVParameter(), |
60 | TolC, TolS); |
61 | Perform(C, C.FirstParameter(), C.LastParameter()); |
62 | } |
63 | |
64 | Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C, |
65 | const Adaptor3d_Surface& S, |
66 | const Standard_Real UCinf, |
67 | const Standard_Real UCsup, |
68 | const Standard_Real Uinf, |
69 | const Standard_Real Usup, |
70 | const Standard_Real Vinf, |
71 | const Standard_Real Vsup, |
72 | const Standard_Real TolC, |
73 | const Standard_Real TolS) |
74 | |
75 | { |
76 | Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS); |
77 | Perform(C, UCinf, UCsup); |
78 | } |
79 | |
80 | |
81 | void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S, |
82 | const Standard_Real Uinf, |
83 | const Standard_Real Usup, |
84 | const Standard_Real Vinf, |
85 | const Standard_Real Vsup, |
86 | const Standard_Real TolC, |
87 | const Standard_Real TolS) |
88 | { |
89 | myS = (Adaptor3d_SurfacePtr)&S; |
90 | myIsPar = Standard_False; |
91 | myuinf = Uinf; |
92 | myusup = Usup; |
93 | myvinf = Vinf; |
94 | myvsup = Vsup; |
95 | mytolC = TolC; |
96 | mytolS = TolS; |
97 | myStype = myS->GetType(); |
98 | } |
99 | |
100 | |
101 | void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C, |
102 | const Standard_Real Uinf, |
103 | const Standard_Real Usup) |
104 | { |
105 | myucinf = Uinf; |
106 | myucsup = Usup; |
107 | myPOnS.Clear(); |
108 | myPOnC.Clear(); |
109 | mySqDist.Clear(); |
38308958 |
110 | Standard_Integer i, j; |
7fd59977 |
111 | Standard_Integer NbT, NbU, NbV; |
112 | NbT = NbU = NbV = 10; |
113 | GeomAbs_CurveType myCtype = C.GetType(); |
114 | |
115 | |
116 | switch(myCtype) { |
117 | |
118 | case GeomAbs_Line: |
119 | { |
120 | |
121 | switch(myStype) { |
122 | case GeomAbs_Sphere: |
123 | myExtElCS.Perform(C.Line(), myS->Sphere()); |
124 | break; |
125 | case GeomAbs_Cylinder: |
126 | myExtElCS.Perform(C.Line(), myS->Cylinder()); |
127 | break; |
128 | case GeomAbs_Plane: |
129 | myExtElCS.Perform(C.Line(), myS->Plane()); |
130 | if (myExtElCS.IsParallel()) break; |
131 | |
132 | case GeomAbs_Torus: |
133 | case GeomAbs_Cone: |
134 | case GeomAbs_BezierSurface: |
135 | case GeomAbs_BSplineSurface: |
136 | case GeomAbs_SurfaceOfRevolution: |
137 | case GeomAbs_SurfaceOfExtrusion: |
138 | case GeomAbs_OtherSurface: |
139 | { |
140 | Standard_Real cfirst = myucinf, clast = myucsup; |
141 | Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(), |
142 | vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter(); |
143 | |
144 | if(Precision::IsInfinite(Abs(cfirst)) || Precision::IsInfinite(Abs(clast))) { |
145 | |
146 | Bnd_Box aSurfBox; |
6e6cd5d9 |
147 | BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox); |
7fd59977 |
148 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; |
149 | aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax); |
150 | Standard_Real tmin = Precision::Infinite(), tmax = -tmin; |
151 | gp_Lin aLin = C.Line(); |
152 | |
153 | |
154 | if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) || |
155 | Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) || |
156 | Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) { |
157 | |
158 | Extrema_ExtPElC anExt; |
159 | Extrema_POnCurv aPntOnLin; |
160 | Standard_Real aParOnLin; |
161 | Standard_Real lim = Precision::Infinite(); |
162 | gp_Pnt aLimPntArray[8]; |
163 | |
164 | aLimPntArray[0].SetCoord(xmin, ymin, zmin); |
165 | aLimPntArray[1].SetCoord(xmax, ymin, zmin); |
166 | aLimPntArray[2].SetCoord(xmin, ymax, zmin); |
167 | aLimPntArray[3].SetCoord(xmax, ymax, zmin); |
168 | aLimPntArray[4].SetCoord(xmin, ymin, zmax); |
169 | aLimPntArray[5].SetCoord(xmax, ymin, zmax); |
170 | aLimPntArray[6].SetCoord(xmin, ymax, zmax); |
171 | aLimPntArray[7].SetCoord(xmax, ymax, zmax); |
172 | |
173 | for(i = 0; i <= 7; i++) { |
174 | anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim); |
175 | aPntOnLin = anExt.Point(1); |
176 | aParOnLin = aPntOnLin.Parameter(); |
177 | tmin = Min(aParOnLin, tmin); |
178 | tmax = Max(aParOnLin, tmax); |
179 | } |
180 | |
181 | } |
182 | else { |
183 | tmin = -1.e+50; |
184 | tmax = 1.e+50; |
185 | } |
186 | |
187 | |
188 | cfirst = Max(cfirst, tmin); |
189 | clast = Min(clast, tmax); |
190 | |
191 | } |
192 | |
193 | |
194 | |
195 | Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast, |
196 | vfirst, vlast, mytolC, mytolS); |
197 | |
198 | myDone = Ext.IsDone(); |
199 | if (myDone) { |
200 | Standard_Integer NbExt = Ext.NbExt(); |
201 | Standard_Real T,U,V; |
202 | Extrema_POnCurv PC; |
203 | Extrema_POnSurf PS; |
204 | for (i = 1; i <= NbExt; i++) { |
205 | PC = Ext.PointOnCurve(i); |
206 | PS = Ext.PointOnSurface(i); |
207 | T = PC.Parameter(); |
208 | PS.Parameter(U, V); |
38308958 |
209 | AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i)); |
7fd59977 |
210 | } |
211 | } |
212 | return; |
213 | |
214 | } |
215 | #ifndef DEB |
216 | default: |
217 | #endif |
218 | break; |
219 | } |
220 | break; |
221 | } |
222 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin |
223 | case GeomAbs_Circle: |
224 | { |
225 | if(myStype == GeomAbs_Cylinder) { |
226 | myExtElCS.Perform(C.Circle(), myS->Cylinder()); |
227 | break; |
228 | } |
229 | } |
230 | case GeomAbs_Hyperbola: |
231 | { |
232 | if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) { |
233 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End |
234 | myExtElCS.Perform(C.Hyperbola(), myS->Plane()); |
235 | break; |
236 | } |
237 | } |
238 | default: |
239 | { |
240 | Extrema_GenExtCS Ext; |
241 | Ext.Initialize(*myS, NbU, NbV, mytolS); |
242 | if(myCtype == GeomAbs_Hyperbola) { |
243 | Standard_Real tmin = Max(-20., C.FirstParameter()); |
244 | Standard_Real tmax = Min(20., C.LastParameter()); |
245 | Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow |
246 | } |
247 | else { |
248 | if(myCtype == GeomAbs_Circle && NbT < 13) { |
249 | NbT = 13; |
250 | } |
251 | Ext.Perform(C, NbT, mytolC); |
252 | } |
253 | |
254 | myDone = Ext.IsDone(); |
255 | if (myDone) { |
256 | Standard_Integer NbExt = Ext.NbExt(); |
257 | Standard_Real T,U,V; |
258 | Extrema_POnCurv PC; |
259 | Extrema_POnSurf PS; |
260 | for (i = 1; i <= NbExt; i++) { |
261 | PC = Ext.PointOnCurve(i); |
262 | PS = Ext.PointOnSurface(i); |
263 | T = PC.Parameter(); |
264 | PS.Parameter(U, V); |
38308958 |
265 | AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i)); |
7fd59977 |
266 | } |
38308958 |
267 | |
268 | //Add sharp points |
269 | Standard_Integer SolNumber = mySqDist.Length(); |
270 | Standard_Address CopyC = (Standard_Address)&C; |
271 | Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)CopyC; |
272 | Standard_Integer NbIntervals = aC.NbIntervals(GeomAbs_C1); |
273 | TColStd_Array1OfReal SharpPoints(1, NbIntervals+1); |
274 | aC.Intervals(SharpPoints, GeomAbs_C1); |
275 | for (i = 1; i <= SharpPoints.Upper(); i++) |
276 | { |
277 | T = SharpPoints(i); |
278 | gp_Pnt aPnt = C.Value(T); |
279 | Extrema_ExtPS ProjPS(aPnt, *myS, mytolS, mytolS); |
280 | if (!ProjPS.IsDone()) |
281 | continue; |
282 | Standard_Integer NbProj = ProjPS.NbExt(), jmin = 0; |
283 | Standard_Real MinSqDist = RealLast(); |
284 | for (j = 1; j <= NbProj; j++) |
285 | { |
286 | Standard_Real aSqDist = ProjPS.SquareDistance(j); |
287 | if (aSqDist < MinSqDist) |
288 | { |
289 | MinSqDist = aSqDist; |
290 | jmin = j; |
291 | } |
292 | } |
293 | if (jmin != 0) |
294 | { |
295 | ProjPS.Point(jmin).Parameter(U,V); |
296 | AddSolution(C, T, U, V, |
297 | aPnt, ProjPS.Point(jmin).Value(), MinSqDist); |
298 | } |
299 | } |
300 | //Cut sharp solutions to keep only minimum and maximum |
301 | Standard_Integer imin = SolNumber + 1, imax = mySqDist.Length(); |
302 | for (i = SolNumber + 1; i <= mySqDist.Length(); i++) |
303 | { |
304 | if (mySqDist(i) < mySqDist(imin)) |
305 | imin = i; |
306 | if (mySqDist(i) > mySqDist(imax)) |
307 | imax = i; |
308 | } |
309 | if (mySqDist.Length() > SolNumber + 2) |
310 | { |
311 | Standard_Real MinSqDist = mySqDist(imin); |
312 | Standard_Real MaxSqDist = mySqDist(imax); |
313 | Extrema_POnCurv MinPC = myPOnC(imin); |
314 | Extrema_POnCurv MaxPC = myPOnC(imax); |
315 | Extrema_POnSurf MinPS = myPOnS(imin); |
316 | Extrema_POnSurf MaxPS = myPOnS(imax); |
317 | |
318 | mySqDist.Remove(SolNumber + 1, mySqDist.Length()); |
319 | myPOnC.Remove(SolNumber + 1, myPOnC.Length()); |
320 | myPOnS.Remove(SolNumber + 1, myPOnS.Length()); |
321 | |
322 | mySqDist.Append(MinSqDist); |
323 | myPOnC.Append(MinPC); |
324 | myPOnS.Append(MinPS); |
325 | mySqDist.Append(MaxSqDist); |
326 | myPOnC.Append(MaxPC); |
327 | myPOnS.Append(MaxPS); |
328 | } |
7fd59977 |
329 | } |
330 | return; |
331 | } |
332 | break; |
333 | } |
334 | |
335 | myDone = myExtElCS.IsDone(); |
336 | if (myDone) { |
337 | myIsPar = myExtElCS.IsParallel(); |
338 | if (myIsPar) { |
339 | mySqDist.Append(myExtElCS.SquareDistance(1)); |
340 | } |
341 | else { |
342 | Standard_Integer NbExt = myExtElCS.NbExt(); |
343 | Standard_Real U, V; |
344 | for (i = 1; i <= NbExt; i++) { |
345 | Extrema_POnCurv PC; |
346 | Extrema_POnSurf PS; |
347 | myExtElCS.Points(i, PC, PS); |
348 | Standard_Real Ucurve = PC.Parameter(); |
349 | PS.Parameter(U, V); |
38308958 |
350 | AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i)); |
7fd59977 |
351 | } |
352 | } |
353 | } |
354 | |
355 | } |
356 | |
357 | |
358 | Standard_Boolean Extrema_ExtCS::IsDone() const |
359 | { |
360 | return myDone; |
361 | } |
362 | |
363 | Standard_Boolean Extrema_ExtCS::IsParallel() const |
364 | { |
365 | return myIsPar; |
366 | } |
367 | |
368 | |
369 | Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const |
370 | { |
371 | if(!myDone) StdFail_NotDone::Raise(); |
372 | if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise(); |
373 | if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise(); |
374 | return mySqDist.Value(N); |
375 | } |
376 | |
377 | |
378 | Standard_Integer Extrema_ExtCS::NbExt() const |
379 | { |
380 | if(!myDone) StdFail_NotDone::Raise(); |
381 | return mySqDist.Length(); |
382 | } |
383 | |
384 | |
385 | |
386 | void Extrema_ExtCS::Points(const Standard_Integer N, |
387 | Extrema_POnCurv& P1, |
388 | Extrema_POnSurf& P2) const |
389 | { |
390 | if(!myDone) StdFail_NotDone::Raise(); |
391 | P1 = myPOnC.Value(N); |
392 | P2 = myPOnS.Value(N); |
393 | } |
38308958 |
394 | |
395 | Standard_Boolean Extrema_ExtCS::AddSolution(const Adaptor3d_Curve& theCurve, |
396 | const Standard_Real aT, |
397 | const Standard_Real aU, |
398 | const Standard_Real aV, |
399 | const gp_Pnt& PointOnCurve, |
400 | const gp_Pnt& PointOnSurf, |
401 | const Standard_Real SquareDist) |
402 | { |
403 | Standard_Boolean Added = Standard_False; |
404 | |
405 | Standard_Real T = aT, U = aU, V = aV; |
406 | |
407 | if (theCurve.IsPeriodic()) |
408 | T = ElCLib::InPeriod(T, myucinf, myucinf + theCurve.Period()); |
409 | if (myS->IsUPeriodic()) |
410 | U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod()); |
411 | if (myS->IsVPeriodic()) |
412 | V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod()); |
413 | |
414 | Extrema_POnCurv aPC; |
415 | Extrema_POnSurf aPS; |
416 | if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC && |
417 | (myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
418 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) |
419 | { |
420 | Standard_Boolean IsNewSolution = Standard_True; |
421 | for (Standard_Integer j = 1; j <= mySqDist.Length(); j++) |
422 | { |
423 | aPC = myPOnC(j); |
424 | aPS = myPOnS(j); |
425 | Standard_Real Tj = aPC.Parameter(); |
426 | Standard_Real Uj, Vj; |
427 | aPS.Parameter(Uj, Vj); |
428 | if (Abs(T - Tj) <= mytolC && |
429 | Abs(U - Uj) <= mytolS && |
430 | Abs(V - Vj) <= mytolS) |
431 | { |
432 | IsNewSolution = Standard_False; |
433 | break; |
434 | } |
435 | } |
436 | if (IsNewSolution) |
437 | { |
438 | mySqDist.Append(SquareDist); |
439 | aPC.SetValues(T, PointOnCurve); |
440 | myPOnC.Append(aPC); |
441 | myPOnS.Append(Extrema_POnSurf(U, V, PointOnSurf)); |
442 | Added = Standard_True; |
443 | } |
444 | } |
445 | return Added; |
446 | } |