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> |
44 | |
45 | Extrema_ExtCS::Extrema_ExtCS() |
46 | { |
47 | myDone = Standard_False; |
48 | } |
49 | |
50 | Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C, |
51 | const Adaptor3d_Surface& S, |
52 | const Standard_Real TolC, |
53 | const Standard_Real TolS) |
54 | |
55 | { |
56 | Initialize(S, S.FirstUParameter(), S.LastUParameter(), |
57 | S.FirstVParameter(), S.LastVParameter(), |
58 | TolC, TolS); |
59 | Perform(C, C.FirstParameter(), C.LastParameter()); |
60 | } |
61 | |
62 | Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C, |
63 | const Adaptor3d_Surface& S, |
64 | const Standard_Real UCinf, |
65 | const Standard_Real UCsup, |
66 | const Standard_Real Uinf, |
67 | const Standard_Real Usup, |
68 | const Standard_Real Vinf, |
69 | const Standard_Real Vsup, |
70 | const Standard_Real TolC, |
71 | const Standard_Real TolS) |
72 | |
73 | { |
74 | Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS); |
75 | Perform(C, UCinf, UCsup); |
76 | } |
77 | |
78 | |
79 | void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S, |
80 | const Standard_Real Uinf, |
81 | const Standard_Real Usup, |
82 | const Standard_Real Vinf, |
83 | const Standard_Real Vsup, |
84 | const Standard_Real TolC, |
85 | const Standard_Real TolS) |
86 | { |
87 | myS = (Adaptor3d_SurfacePtr)&S; |
88 | myIsPar = Standard_False; |
89 | myuinf = Uinf; |
90 | myusup = Usup; |
91 | myvinf = Vinf; |
92 | myvsup = Vsup; |
93 | mytolC = TolC; |
94 | mytolS = TolS; |
95 | myStype = myS->GetType(); |
96 | } |
97 | |
98 | |
99 | void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C, |
100 | const Standard_Real Uinf, |
101 | const Standard_Real Usup) |
102 | { |
103 | myucinf = Uinf; |
104 | myucsup = Usup; |
105 | myPOnS.Clear(); |
106 | myPOnC.Clear(); |
107 | mySqDist.Clear(); |
108 | Standard_Integer i; |
109 | Standard_Integer NbT, NbU, NbV; |
110 | NbT = NbU = NbV = 10; |
111 | GeomAbs_CurveType myCtype = C.GetType(); |
112 | |
113 | |
114 | switch(myCtype) { |
115 | |
116 | case GeomAbs_Line: |
117 | { |
118 | |
119 | switch(myStype) { |
120 | case GeomAbs_Sphere: |
121 | myExtElCS.Perform(C.Line(), myS->Sphere()); |
122 | break; |
123 | case GeomAbs_Cylinder: |
124 | myExtElCS.Perform(C.Line(), myS->Cylinder()); |
125 | break; |
126 | case GeomAbs_Plane: |
127 | myExtElCS.Perform(C.Line(), myS->Plane()); |
128 | if (myExtElCS.IsParallel()) break; |
129 | |
130 | case GeomAbs_Torus: |
131 | case GeomAbs_Cone: |
132 | case GeomAbs_BezierSurface: |
133 | case GeomAbs_BSplineSurface: |
134 | case GeomAbs_SurfaceOfRevolution: |
135 | case GeomAbs_SurfaceOfExtrusion: |
136 | case GeomAbs_OtherSurface: |
137 | { |
138 | Standard_Real cfirst = myucinf, clast = myucsup; |
139 | Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(), |
140 | vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter(); |
141 | |
142 | if(Precision::IsInfinite(Abs(cfirst)) || Precision::IsInfinite(Abs(clast))) { |
143 | |
144 | Bnd_Box aSurfBox; |
6e6cd5d9 |
145 | BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox); |
7fd59977 |
146 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; |
147 | aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax); |
148 | Standard_Real tmin = Precision::Infinite(), tmax = -tmin; |
149 | gp_Lin aLin = C.Line(); |
150 | |
151 | |
152 | if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) || |
153 | Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) || |
154 | Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) { |
155 | |
156 | Extrema_ExtPElC anExt; |
157 | Extrema_POnCurv aPntOnLin; |
158 | Standard_Real aParOnLin; |
159 | Standard_Real lim = Precision::Infinite(); |
160 | gp_Pnt aLimPntArray[8]; |
161 | |
162 | aLimPntArray[0].SetCoord(xmin, ymin, zmin); |
163 | aLimPntArray[1].SetCoord(xmax, ymin, zmin); |
164 | aLimPntArray[2].SetCoord(xmin, ymax, zmin); |
165 | aLimPntArray[3].SetCoord(xmax, ymax, zmin); |
166 | aLimPntArray[4].SetCoord(xmin, ymin, zmax); |
167 | aLimPntArray[5].SetCoord(xmax, ymin, zmax); |
168 | aLimPntArray[6].SetCoord(xmin, ymax, zmax); |
169 | aLimPntArray[7].SetCoord(xmax, ymax, zmax); |
170 | |
171 | for(i = 0; i <= 7; i++) { |
172 | anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim); |
173 | aPntOnLin = anExt.Point(1); |
174 | aParOnLin = aPntOnLin.Parameter(); |
175 | tmin = Min(aParOnLin, tmin); |
176 | tmax = Max(aParOnLin, tmax); |
177 | } |
178 | |
179 | } |
180 | else { |
181 | tmin = -1.e+50; |
182 | tmax = 1.e+50; |
183 | } |
184 | |
185 | |
186 | cfirst = Max(cfirst, tmin); |
187 | clast = Min(clast, tmax); |
188 | |
189 | } |
190 | |
191 | |
192 | |
193 | Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast, |
194 | vfirst, vlast, mytolC, mytolS); |
195 | |
196 | myDone = Ext.IsDone(); |
197 | if (myDone) { |
198 | Standard_Integer NbExt = Ext.NbExt(); |
199 | Standard_Real T,U,V; |
200 | Extrema_POnCurv PC; |
201 | Extrema_POnSurf PS; |
202 | for (i = 1; i <= NbExt; i++) { |
203 | PC = Ext.PointOnCurve(i); |
204 | PS = Ext.PointOnSurface(i); |
205 | T = PC.Parameter(); |
206 | PS.Parameter(U, V); |
207 | if (myS->IsUPeriodic()) |
208 | U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod()); |
209 | if (myS->IsVPeriodic()) |
210 | V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod()); |
211 | |
212 | if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC && |
213 | (myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
214 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) { |
215 | mySqDist.Append(Ext.SquareDistance(i)); |
216 | myPOnC.Append(PC); |
217 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
218 | |
219 | |
220 | } |
221 | } |
222 | } |
223 | return; |
224 | |
225 | } |
226 | #ifndef DEB |
227 | default: |
228 | #endif |
229 | break; |
230 | } |
231 | break; |
232 | } |
233 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin |
234 | case GeomAbs_Circle: |
235 | { |
236 | if(myStype == GeomAbs_Cylinder) { |
237 | myExtElCS.Perform(C.Circle(), myS->Cylinder()); |
238 | break; |
239 | } |
240 | } |
241 | case GeomAbs_Hyperbola: |
242 | { |
243 | if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) { |
244 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End |
245 | myExtElCS.Perform(C.Hyperbola(), myS->Plane()); |
246 | break; |
247 | } |
248 | } |
249 | default: |
250 | { |
251 | Extrema_GenExtCS Ext; |
252 | Ext.Initialize(*myS, NbU, NbV, mytolS); |
253 | if(myCtype == GeomAbs_Hyperbola) { |
254 | Standard_Real tmin = Max(-20., C.FirstParameter()); |
255 | Standard_Real tmax = Min(20., C.LastParameter()); |
256 | Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow |
257 | } |
258 | else { |
259 | if(myCtype == GeomAbs_Circle && NbT < 13) { |
260 | NbT = 13; |
261 | } |
262 | Ext.Perform(C, NbT, mytolC); |
263 | } |
264 | |
265 | myDone = Ext.IsDone(); |
266 | if (myDone) { |
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); |
276 | if (C.IsPeriodic()) |
277 | T = ElCLib::InPeriod(T, myucinf, myucinf+C.Period()); |
278 | if (myS->IsUPeriodic()) |
279 | U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod()); |
280 | if (myS->IsVPeriodic()) |
281 | V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod()); |
282 | |
283 | if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC && |
284 | (myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
285 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) { |
286 | mySqDist.Append(Ext.SquareDistance(i)); |
287 | PC.SetValues(T, PC.Value()); |
288 | myPOnC.Append(PC); |
289 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
290 | } |
291 | } |
292 | } |
293 | return; |
294 | } |
295 | break; |
296 | } |
297 | |
298 | myDone = myExtElCS.IsDone(); |
299 | if (myDone) { |
300 | myIsPar = myExtElCS.IsParallel(); |
301 | if (myIsPar) { |
302 | mySqDist.Append(myExtElCS.SquareDistance(1)); |
303 | } |
304 | else { |
305 | Standard_Integer NbExt = myExtElCS.NbExt(); |
306 | Standard_Real U, V; |
307 | for (i = 1; i <= NbExt; i++) { |
308 | Extrema_POnCurv PC; |
309 | Extrema_POnSurf PS; |
310 | myExtElCS.Points(i, PC, PS); |
311 | Standard_Real Ucurve = PC.Parameter(); |
312 | PS.Parameter(U, V); |
313 | |
314 | if((myStype == GeomAbs_Sphere) || (myStype == GeomAbs_Cylinder)) { |
c6541a0c |
315 | U = ElCLib::InPeriod(U, myuinf, myuinf+2.*M_PI); |
7fd59977 |
316 | } |
317 | |
318 | if ((myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
319 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS && |
320 | (myucinf-Ucurve) <= mytolC && (Ucurve-myucsup) <= mytolC) { |
321 | mySqDist.Append(myExtElCS.SquareDistance(i)); |
322 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
323 | myPOnC.Append(PC); |
324 | } |
325 | } |
326 | } |
327 | } |
328 | |
329 | } |
330 | |
331 | |
332 | Standard_Boolean Extrema_ExtCS::IsDone() const |
333 | { |
334 | return myDone; |
335 | } |
336 | |
337 | Standard_Boolean Extrema_ExtCS::IsParallel() const |
338 | { |
339 | return myIsPar; |
340 | } |
341 | |
342 | |
343 | Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const |
344 | { |
345 | if(!myDone) StdFail_NotDone::Raise(); |
346 | if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise(); |
347 | if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise(); |
348 | return mySqDist.Value(N); |
349 | } |
350 | |
351 | |
352 | Standard_Integer Extrema_ExtCS::NbExt() const |
353 | { |
354 | if(!myDone) StdFail_NotDone::Raise(); |
355 | return mySqDist.Length(); |
356 | } |
357 | |
358 | |
359 | |
360 | void Extrema_ExtCS::Points(const Standard_Integer N, |
361 | Extrema_POnCurv& P1, |
362 | Extrema_POnSurf& P2) const |
363 | { |
364 | if(!myDone) StdFail_NotDone::Raise(); |
365 | P1 = myPOnC.Value(N); |
366 | P2 = myPOnS.Value(N); |
367 | } |