0022627: Change OCCT memory management defaults
[occt.git] / src / Extrema / Extrema_ExtCS.cxx
CommitLineData
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
29Extrema_ExtCS::Extrema_ExtCS()
30{
31 myDone = Standard_False;
32}
33
34Extrema_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
46Extrema_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
63void 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
83void 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
316Standard_Boolean Extrema_ExtCS::IsDone() const
317{
318 return myDone;
319}
320
321Standard_Boolean Extrema_ExtCS::IsParallel() const
322{
323 return myIsPar;
324}
325
326
327Standard_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
336Standard_Integer Extrema_ExtCS::NbExt() const
337{
338 if(!myDone) StdFail_NotDone::Raise();
339 return mySqDist.Length();
340}
341
342
343
344void 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}