0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / Extrema / Extrema_ExtPS.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//-----------------------------------------------------------------
7fd59977 16
6b84c3f7 17#include <GeomAdaptor_HSurfaceOfLinearExtrusion.hxx>
18#include <GeomAdaptor_HSurfaceOfRevolution.hxx>
42cf5bc1 19#include <Adaptor3d_Surface.hxx>
7fd59977 20#include <ElCLib.hxx>
7fd59977 21#include <Extrema_ExtPExtS.hxx>
22#include <Extrema_ExtPRevS.hxx>
42cf5bc1 23#include <Extrema_ExtPS.hxx>
24#include <Extrema_GenExtPS.hxx>
7fd59977 25#include <Extrema_POnSurf.hxx>
42cf5bc1 26#include <GeomAbs_CurveType.hxx>
7fd59977 27#include <GeomAbs_IsoType.hxx>
42cf5bc1 28#include <gp_Cone.hxx>
29#include <gp_Cylinder.hxx>
30#include <gp_Pln.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Sphere.hxx>
33#include <gp_Torus.hxx>
34#include <Precision.hxx>
35#include <Standard_NotImplemented.hxx>
36#include <Standard_OutOfRange.hxx>
37#include <Standard_TypeMismatch.hxx>
38#include <StdFail_NotDone.hxx>
7fd59977 39
40//=======================================================================
41//function : IsoIsDeg
42//purpose :
43//=======================================================================
7fd59977 44static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
45 const Standard_Real Param,
46 const GeomAbs_IsoType IT,
47 const Standard_Real TolMin,
48 const Standard_Real TolMax)
49{
50 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
51 Standard_Boolean Along = Standard_True;
52 U1 = S.FirstUParameter();
53 U2 = S.LastUParameter();
54 V1 = S.FirstVParameter();
55 V2 = S.LastVParameter();
56 gp_Vec D1U,D1V;
57 gp_Pnt P;
58 Standard_Real Step,D1NormMax;
59 if (IT == GeomAbs_IsoV)
60 {
5368adff 61 if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) )
7fd59977 62 {
5368adff 63 Step = (U2 - U1)/10;
64 if(Step < Precision::PConfusion()) {
65 return Standard_False;
66 }
67 D1NormMax=0.;
68
69 for (T=U1;T<=U2;T=T+Step)
70 {
71 S.D1(T,Param,P,D1U,D1V);
72 D1NormMax=Max(D1NormMax,D1U.Magnitude());
73 }
74
75 if (D1NormMax >TolMax || D1NormMax < TolMin )
76 Along = Standard_False;
7fd59977 77 }
7fd59977 78 }
79 else
80 {
5368adff 81 if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) )
7fd59977 82 {
5368adff 83 Step = (V2 - V1)/10;
84 if(Step < Precision::PConfusion()) {
85 return Standard_False;
86 }
87 D1NormMax=0.;
88 for (T=V1;T<=V2;T=T+Step)
89 {
90 S.D1(Param,T,P,D1U,D1V);
91 D1NormMax=Max(D1NormMax,D1V.Magnitude());
92 }
93
94 if (D1NormMax >TolMax || D1NormMax < TolMin )
95 Along = Standard_False;
7fd59977 96 }
97
7fd59977 98
99
100 }
101 return Along;
102}
103
104//=======================================================================
105//function : TreatSolution
106//purpose :
107//=======================================================================
108
109void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
110 const Standard_Real Val)
111{
112 Standard_Real U, V;
113 PS.Parameter(U, V);
114 if (myS->IsUPeriodic()) {
9bf3177f 115 U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
116
117 // Handle trimmed surfaces.
118 if (U > myusup + mytolu)
119 U -= myS->UPeriod();
120 if (U < myuinf - mytolu)
121 U += myS->UPeriod();
7fd59977 122 }
123 if (myS->IsVPeriodic()) {
9bf3177f 124 V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
125
126 // Handle trimmed surfaces.
127 if (V > myvsup + mytolv)
128 V -= myS->VPeriod();
129 if (V < myvinf - mytolv)
130 V += myS->VPeriod();
7fd59977 131 }
132 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
133 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
134 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
135 mySqDist.Append(Val);
136 }
137}
138
139
140//=======================================================================
141//function : Extrema_ExtPS
142//purpose :
143//=======================================================================
144
0734c53d 145Extrema_ExtPS::Extrema_ExtPS()
7fd59977 146{
147 myDone = Standard_False;
148}
149
150
151//=======================================================================
152//function : Extrema_ExtPS
153//purpose :
154//=======================================================================
155
0734c53d 156Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
157 const Adaptor3d_Surface& theS,
158 const Standard_Real theTolU,
159 const Standard_Real theTolV,
160 const Extrema_ExtFlag theF,
161 const Extrema_ExtAlgo theA)
7fd59977 162{
0734c53d 163 myExtPS.SetFlag (theF);
164 myExtPS.SetAlgo (theA);
165
166 Initialize (theS,
167 theS.FirstUParameter(),
168 theS.LastUParameter(),
169 theS.FirstVParameter(),
170 theS.LastVParameter(),
171 theTolU,
172 theTolV);
173
174 Perform (theP);
7fd59977 175}
176
177//=======================================================================
178//function : Extrema_ExtPS
179//purpose :
180//=======================================================================
181
0734c53d 182Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
183 const Adaptor3d_Surface& theS,
184 const Standard_Real theUinf,
185 const Standard_Real theUsup,
186 const Standard_Real theVinf,
187 const Standard_Real theVsup,
188 const Standard_Real theTolU,
189 const Standard_Real theTolV,
190 const Extrema_ExtFlag theF,
191 const Extrema_ExtAlgo theA)
7fd59977 192{
0734c53d 193 myExtPS.SetFlag (theF);
194 myExtPS.SetAlgo (theA);
195
196 Initialize (theS,
197 theUinf,
198 theUsup,
199 theVinf,
200 theVsup,
201 theTolU,
202 theTolV);
203
204 Perform (theP);
7fd59977 205}
206
207
208//=======================================================================
209//function : Initialize
210//purpose :
211//=======================================================================
212
0734c53d 213void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
214 const Standard_Real theUinf,
215 const Standard_Real theUsup,
216 const Standard_Real theVinf,
217 const Standard_Real theVsup,
218 const Standard_Real theTolU,
219 const Standard_Real theTolV)
7fd59977 220{
0734c53d 221 myS = (Adaptor3d_SurfacePtr)&theS;
222 myuinf = theUinf;
223 myusup = theUsup;
224 myvinf = theVinf;
225 myvsup = theVsup;
7fd59977 226
227 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
228 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
229 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
230 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
231
0734c53d 232 mytolu = theTolU;
233 mytolv = theTolV;
7fd59977 234 mytype = myS->GetType();
235
236 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
0734c53d 237 myS->GetType() == GeomAbs_BezierSurface );
7fd59977 238
239 Standard_Integer nbU = (isB) ? 44 : 32;
240 Standard_Integer nbV = (isB) ? 44 : 32;
241
242 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
243
244 if(myS->GetType() != GeomAbs_Plane) {
0734c53d 245 bUIsoIsDeg = IsoIsDeg(theS, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
246 IsoIsDeg(theS, myusup, GeomAbs_IsoU, 0., 1.e-9);
247 bVIsoIsDeg = IsoIsDeg(theS, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
248 IsoIsDeg(theS, myvsup, GeomAbs_IsoV, 0., 1.e-9);
7fd59977 249 }
250
251 if(bUIsoIsDeg) nbU = 300;
252 if(bVIsoIsDeg) nbV = 300;
253
254 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
0734c53d 255
256 myExtPExtS.Nullify();
257 myExtPRevS.Nullify();
7fd59977 258}
259
260//=======================================================================
261//function : Perform
262//purpose :
263//=======================================================================
264
0734c53d 265void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
7fd59977 266{
267 myPoints.Clear();
268 mySqDist.Clear();
0734c53d 269
270 switch (mytype)
271 {
272 case GeomAbs_Cylinder:
273 myExtPElS.Perform (thePoint, myS->Cylinder(), Precision::Confusion());
274 break;
275 case GeomAbs_Plane:
276 myExtPElS.Perform (thePoint, myS->Plane(), Precision::Confusion());
277 break;
278 case GeomAbs_Cone:
279 myExtPElS.Perform (thePoint, myS->Cone(), Precision::Confusion());
280 break;
281 case GeomAbs_Sphere:
282 myExtPElS.Perform (thePoint, myS->Sphere(), Precision::Confusion());
283 break;
284 case GeomAbs_Torus:
285 myExtPElS.Perform (thePoint, myS->Torus(), Precision::Confusion());
286 break;
287
288 case GeomAbs_SurfaceOfExtrusion:
289 {
290 if (myExtPExtS.IsNull())
291 {
6b84c3f7 292 Handle(GeomAdaptor_HSurfaceOfLinearExtrusion) aS (new GeomAdaptor_HSurfaceOfLinearExtrusion (
293 GeomAdaptor_SurfaceOfLinearExtrusion (myS->BasisCurve(), myS->Direction())));
0734c53d 294
295 myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
296 }
297 else
298 {
299 myExtPExtS->Perform (thePoint);
7fd59977 300 }
7fd59977 301
0734c53d 302 myDone = myExtPExtS->IsDone();
303 if (myDone)
304 {
305 for (Standard_Integer anIdx = 1; anIdx <= myExtPExtS->NbExt(); ++anIdx)
306 {
307 TreatSolution (myExtPExtS->Point (anIdx), myExtPExtS->SquareDistance (anIdx));
308 }
7fd59977 309 }
7fd59977 310
0734c53d 311 return;
312 }
313
314 case GeomAbs_SurfaceOfRevolution:
315 {
316 if (myExtPRevS.IsNull())
317 {
6b84c3f7 318 Handle(GeomAdaptor_HSurfaceOfRevolution) aS (new GeomAdaptor_HSurfaceOfRevolution (
319 GeomAdaptor_SurfaceOfRevolution (myS->BasisCurve(), myS->AxeOfRevolution())));
0734c53d 320
321 myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
322 }
323 else
324 {
325 myExtPRevS->Perform (thePoint);
326 }
327
328 myDone = myExtPRevS->IsDone();
329 if (myDone)
330 {
331 for (Standard_Integer anIdx = 1; anIdx <= myExtPRevS->NbExt(); ++anIdx)
332 {
333 TreatSolution (myExtPRevS->Point (anIdx), myExtPRevS->SquareDistance (anIdx));
334 }
335 }
336
337 return;
338 }
339
340 default:
341 {
342 myExtPS.Perform (thePoint);
343 myDone = myExtPS.IsDone();
344 if (myDone)
345 {
346 for (Standard_Integer anIdx = 1; anIdx <= myExtPS.NbExt(); ++anIdx)
347 {
348 TreatSolution (myExtPS.Point (anIdx), myExtPS.SquareDistance (anIdx));
349 }
350 }
351 return;
352 }
7fd59977 353 }
354
7fd59977 355 myDone = myExtPElS.IsDone();
0734c53d 356 if (myDone)
357 {
358 for (Standard_Integer anIdx = 1; anIdx <= myExtPElS.NbExt(); ++anIdx)
359 {
360 TreatSolution (myExtPElS.Point (anIdx), myExtPElS.SquareDistance (anIdx));
361 }
362 }
7fd59977 363}
364
365
7fd59977 366Standard_Boolean Extrema_ExtPS::IsDone() const
367{
368 return myDone;
369}
370
371
372Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
373{
638ad7f3 374 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 375 return mySqDist.Value(N);
376}
377
378
379Standard_Integer Extrema_ExtPS::NbExt() const
380{
638ad7f3 381 if (!IsDone()) throw StdFail_NotDone();
7fd59977 382 return mySqDist.Length();
383}
384
385
5d99f2c8 386const Extrema_POnSurf& Extrema_ExtPS::Point(const Standard_Integer N) const
7fd59977 387{
638ad7f3 388 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 389 return myPoints.Value(N);
390}
391
392
393void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
394 Standard_Real& dUfVl,
395 Standard_Real& dUlVf,
396 Standard_Real& dUlVl,
397 gp_Pnt& PUfVf,
398 gp_Pnt& PUfVl,
399 gp_Pnt& PUlVf,
400 gp_Pnt& PUlVl) const
401{
402 dUfVf = d11;
403 dUfVl = d12;
404 dUlVf = d21;
405 dUlVl = d22;
406 PUfVf = P11;
407 PUfVl = P12;
408 PUlVf = P21;
409 PUlVl = P22;
410}
92d1589b
A
411
412void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
413{
414 myExtPS.SetFlag(F);
415}
416
417void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
418{
419 myExtPS.SetAlgo(A);
0d969553 420}