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