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; |
6e6cd5d9 |
129 | BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox); |
7fd59977 |
130 | Standard_Real xmin, ymin, zmin, xmax, ymax, zmax; |
131 | aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax); |
132 | Standard_Real tmin = Precision::Infinite(), tmax = -tmin; |
133 | gp_Lin aLin = C.Line(); |
134 | |
135 | |
136 | if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) || |
137 | Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) || |
138 | Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) { |
139 | |
140 | Extrema_ExtPElC anExt; |
141 | Extrema_POnCurv aPntOnLin; |
142 | Standard_Real aParOnLin; |
143 | Standard_Real lim = Precision::Infinite(); |
144 | gp_Pnt aLimPntArray[8]; |
145 | |
146 | aLimPntArray[0].SetCoord(xmin, ymin, zmin); |
147 | aLimPntArray[1].SetCoord(xmax, ymin, zmin); |
148 | aLimPntArray[2].SetCoord(xmin, ymax, zmin); |
149 | aLimPntArray[3].SetCoord(xmax, ymax, zmin); |
150 | aLimPntArray[4].SetCoord(xmin, ymin, zmax); |
151 | aLimPntArray[5].SetCoord(xmax, ymin, zmax); |
152 | aLimPntArray[6].SetCoord(xmin, ymax, zmax); |
153 | aLimPntArray[7].SetCoord(xmax, ymax, zmax); |
154 | |
155 | for(i = 0; i <= 7; i++) { |
156 | anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim); |
157 | aPntOnLin = anExt.Point(1); |
158 | aParOnLin = aPntOnLin.Parameter(); |
159 | tmin = Min(aParOnLin, tmin); |
160 | tmax = Max(aParOnLin, tmax); |
161 | } |
162 | |
163 | } |
164 | else { |
165 | tmin = -1.e+50; |
166 | tmax = 1.e+50; |
167 | } |
168 | |
169 | |
170 | cfirst = Max(cfirst, tmin); |
171 | clast = Min(clast, tmax); |
172 | |
173 | } |
174 | |
175 | |
176 | |
177 | Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast, |
178 | vfirst, vlast, mytolC, mytolS); |
179 | |
180 | myDone = Ext.IsDone(); |
181 | if (myDone) { |
182 | Standard_Integer NbExt = Ext.NbExt(); |
183 | Standard_Real T,U,V; |
184 | Extrema_POnCurv PC; |
185 | Extrema_POnSurf PS; |
186 | for (i = 1; i <= NbExt; i++) { |
187 | PC = Ext.PointOnCurve(i); |
188 | PS = Ext.PointOnSurface(i); |
189 | T = PC.Parameter(); |
190 | PS.Parameter(U, V); |
191 | if (myS->IsUPeriodic()) |
192 | U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod()); |
193 | if (myS->IsVPeriodic()) |
194 | V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod()); |
195 | |
196 | if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC && |
197 | (myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
198 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) { |
199 | mySqDist.Append(Ext.SquareDistance(i)); |
200 | myPOnC.Append(PC); |
201 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
202 | |
203 | |
204 | } |
205 | } |
206 | } |
207 | return; |
208 | |
209 | } |
210 | #ifndef DEB |
211 | default: |
212 | #endif |
213 | break; |
214 | } |
215 | break; |
216 | } |
217 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin |
218 | case GeomAbs_Circle: |
219 | { |
220 | if(myStype == GeomAbs_Cylinder) { |
221 | myExtElCS.Perform(C.Circle(), myS->Cylinder()); |
222 | break; |
223 | } |
224 | } |
225 | case GeomAbs_Hyperbola: |
226 | { |
227 | if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) { |
228 | // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End |
229 | myExtElCS.Perform(C.Hyperbola(), myS->Plane()); |
230 | break; |
231 | } |
232 | } |
233 | default: |
234 | { |
235 | Extrema_GenExtCS Ext; |
236 | Ext.Initialize(*myS, NbU, NbV, mytolS); |
237 | if(myCtype == GeomAbs_Hyperbola) { |
238 | Standard_Real tmin = Max(-20., C.FirstParameter()); |
239 | Standard_Real tmax = Min(20., C.LastParameter()); |
240 | Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow |
241 | } |
242 | else { |
243 | if(myCtype == GeomAbs_Circle && NbT < 13) { |
244 | NbT = 13; |
245 | } |
246 | Ext.Perform(C, NbT, mytolC); |
247 | } |
248 | |
249 | myDone = Ext.IsDone(); |
250 | if (myDone) { |
251 | Standard_Integer NbExt = Ext.NbExt(); |
252 | Standard_Real T,U,V; |
253 | Extrema_POnCurv PC; |
254 | Extrema_POnSurf PS; |
255 | for (i = 1; i <= NbExt; i++) { |
256 | PC = Ext.PointOnCurve(i); |
257 | PS = Ext.PointOnSurface(i); |
258 | T = PC.Parameter(); |
259 | PS.Parameter(U, V); |
260 | if (C.IsPeriodic()) |
261 | T = ElCLib::InPeriod(T, myucinf, myucinf+C.Period()); |
262 | if (myS->IsUPeriodic()) |
263 | U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod()); |
264 | if (myS->IsVPeriodic()) |
265 | V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod()); |
266 | |
267 | if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC && |
268 | (myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
269 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) { |
270 | mySqDist.Append(Ext.SquareDistance(i)); |
271 | PC.SetValues(T, PC.Value()); |
272 | myPOnC.Append(PC); |
273 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
274 | } |
275 | } |
276 | } |
277 | return; |
278 | } |
279 | break; |
280 | } |
281 | |
282 | myDone = myExtElCS.IsDone(); |
283 | if (myDone) { |
284 | myIsPar = myExtElCS.IsParallel(); |
285 | if (myIsPar) { |
286 | mySqDist.Append(myExtElCS.SquareDistance(1)); |
287 | } |
288 | else { |
289 | Standard_Integer NbExt = myExtElCS.NbExt(); |
290 | Standard_Real U, V; |
291 | for (i = 1; i <= NbExt; i++) { |
292 | Extrema_POnCurv PC; |
293 | Extrema_POnSurf PS; |
294 | myExtElCS.Points(i, PC, PS); |
295 | Standard_Real Ucurve = PC.Parameter(); |
296 | PS.Parameter(U, V); |
297 | |
298 | if((myStype == GeomAbs_Sphere) || (myStype == GeomAbs_Cylinder)) { |
c6541a0c |
299 | U = ElCLib::InPeriod(U, myuinf, myuinf+2.*M_PI); |
7fd59977 |
300 | } |
301 | |
302 | if ((myuinf-U) <= mytolS && (U-myusup) <= mytolS && |
303 | (myvinf-V) <= mytolS && (V-myvsup) <= mytolS && |
304 | (myucinf-Ucurve) <= mytolC && (Ucurve-myucsup) <= mytolC) { |
305 | mySqDist.Append(myExtElCS.SquareDistance(i)); |
306 | myPOnS.Append(Extrema_POnSurf(U, V, PS.Value())); |
307 | myPOnC.Append(PC); |
308 | } |
309 | } |
310 | } |
311 | } |
312 | |
313 | } |
314 | |
315 | |
316 | Standard_Boolean Extrema_ExtCS::IsDone() const |
317 | { |
318 | return myDone; |
319 | } |
320 | |
321 | Standard_Boolean Extrema_ExtCS::IsParallel() const |
322 | { |
323 | return myIsPar; |
324 | } |
325 | |
326 | |
327 | Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const |
328 | { |
329 | if(!myDone) StdFail_NotDone::Raise(); |
330 | if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise(); |
331 | if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise(); |
332 | return mySqDist.Value(N); |
333 | } |
334 | |
335 | |
336 | Standard_Integer Extrema_ExtCS::NbExt() const |
337 | { |
338 | if(!myDone) StdFail_NotDone::Raise(); |
339 | return mySqDist.Length(); |
340 | } |
341 | |
342 | |
343 | |
344 | void Extrema_ExtCS::Points(const Standard_Integer N, |
345 | Extrema_POnCurv& P1, |
346 | Extrema_POnSurf& P2) const |
347 | { |
348 | if(!myDone) StdFail_NotDone::Raise(); |
349 | P1 = myPOnC.Value(N); |
350 | P2 = myPOnS.Value(N); |
351 | } |