0022883: Extrema can not find projection of 3D point on surface.
[occt.git] / src / Extrema / Extrema_ExtPS.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19//-----------------------------------------------------------------
7fd59977 20
21#include <Extrema_ExtPS.ixx>
22#include <Extrema_GenExtPS.hxx>
23#include <StdFail_NotDone.hxx>
24#include <Standard_NotImplemented.hxx>
25#include <Precision.hxx>
26#include <GeomAbs_CurveType.hxx>
27#include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
28#include <Adaptor3d_SurfaceOfRevolution.hxx>
29#include <ElCLib.hxx>
30#include <gp_Pnt.hxx>
31#include <gp_Pln.hxx>
32#include <gp_Cylinder.hxx>
33#include <gp_Cone.hxx>
34#include <gp_Sphere.hxx>
35#include <gp_Torus.hxx>
36#include <Extrema_ExtPExtS.hxx>
37#include <Extrema_ExtPRevS.hxx>
38#include <Extrema_POnSurf.hxx>
39#include <GeomAbs_IsoType.hxx>
40
41//=======================================================================
42//function : IsoIsDeg
43//purpose :
44//=======================================================================
45
46static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
47 const Standard_Real Param,
48 const GeomAbs_IsoType IT,
49 const Standard_Real TolMin,
50 const Standard_Real TolMax)
51{
52 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
53 Standard_Boolean Along = Standard_True;
54 U1 = S.FirstUParameter();
55 U2 = S.LastUParameter();
56 V1 = S.FirstVParameter();
57 V2 = S.LastVParameter();
58 gp_Vec D1U,D1V;
59 gp_Pnt P;
60 Standard_Real Step,D1NormMax;
61 if (IT == GeomAbs_IsoV)
62 {
5368adff 63 if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) )
7fd59977 64 {
5368adff 65 Step = (U2 - U1)/10;
66 if(Step < Precision::PConfusion()) {
67 return Standard_False;
68 }
69 D1NormMax=0.;
70
71 for (T=U1;T<=U2;T=T+Step)
72 {
73 S.D1(T,Param,P,D1U,D1V);
74 D1NormMax=Max(D1NormMax,D1U.Magnitude());
75 }
76
77 if (D1NormMax >TolMax || D1NormMax < TolMin )
78 Along = Standard_False;
7fd59977 79 }
7fd59977 80 }
81 else
82 {
5368adff 83 if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) )
7fd59977 84 {
5368adff 85 Step = (V2 - V1)/10;
86 if(Step < Precision::PConfusion()) {
87 return Standard_False;
88 }
89 D1NormMax=0.;
90 for (T=V1;T<=V2;T=T+Step)
91 {
92 S.D1(Param,T,P,D1U,D1V);
93 D1NormMax=Max(D1NormMax,D1V.Magnitude());
94 }
95
96 if (D1NormMax >TolMax || D1NormMax < TolMin )
97 Along = Standard_False;
7fd59977 98 }
99
7fd59977 100
101
102 }
103 return Along;
104}
105
106//=======================================================================
107//function : TreatSolution
108//purpose :
109//=======================================================================
110
111void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
112 const Standard_Real Val)
113{
114 Standard_Real U, V;
115 PS.Parameter(U, V);
116 if (myS->IsUPeriodic()) {
117 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
118 }
119 if (myS->IsVPeriodic()) {
120 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
121 }
122 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
123 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
124 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
125 mySqDist.Append(Val);
126 }
127}
128
129
130//=======================================================================
131//function : Extrema_ExtPS
132//purpose :
133//=======================================================================
134
135Extrema_ExtPS::Extrema_ExtPS()
136{
137 myDone = Standard_False;
138}
139
140
141//=======================================================================
142//function : Extrema_ExtPS
143//purpose :
144//=======================================================================
145
146Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
147 const Adaptor3d_Surface& S,
148 const Standard_Real TolU,
92d1589b
A
149 const Standard_Real TolV,
150 const Extrema_ExtFlag F,
151 const Extrema_ExtAlgo A)
7fd59977 152
153{
92d1589b
A
154 myExtPS.SetFlag(F);
155 myExtPS.SetAlgo(A);
7fd59977 156 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
157 S.FirstVParameter(), S.LastVParameter(),
158 TolU, TolV);
159 Perform(P);
160}
161
162//=======================================================================
163//function : Extrema_ExtPS
164//purpose :
165//=======================================================================
166
167Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
168 const Adaptor3d_Surface& S,
169 const Standard_Real Uinf,
170 const Standard_Real Usup,
171 const Standard_Real Vinf,
172 const Standard_Real Vsup,
173 const Standard_Real TolU,
92d1589b
A
174 const Standard_Real TolV,
175 const Extrema_ExtFlag F,
176 const Extrema_ExtAlgo A)
7fd59977 177
178{
92d1589b
A
179 myExtPS.SetFlag(F);
180 myExtPS.SetAlgo(A);
7fd59977 181 Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
182 Perform(P);
183}
184
185
186//=======================================================================
187//function : Initialize
188//purpose :
189//=======================================================================
190
191void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S,
192 const Standard_Real Uinf,
193 const Standard_Real Usup,
194 const Standard_Real Vinf,
195 const Standard_Real Vsup,
196 const Standard_Real TolU,
197 const Standard_Real TolV)
198{
199 myS = (Adaptor3d_SurfacePtr)&S;
200 myuinf = Uinf;
201 myusup = Usup;
202 myvinf = Vinf;
203 myvsup = Vsup;
204
205 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
206 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
207 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
208 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
209
210 mytolu = TolU;
211 mytolv = TolV;
212 mytype = myS->GetType();
213
214 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
215 myS->GetType() == GeomAbs_BezierSurface );
216
217 Standard_Integer nbU = (isB) ? 44 : 32;
218 Standard_Integer nbV = (isB) ? 44 : 32;
219
220 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
221
222 if(myS->GetType() != GeomAbs_Plane) {
223 bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
224 IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9);
225 bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
226 IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9);
227 }
228
229 if(bUIsoIsDeg) nbU = 300;
230 if(bVIsoIsDeg) nbV = 300;
231
232 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
233}
234
235//=======================================================================
236//function : Perform
237//purpose :
238//=======================================================================
239
240void Extrema_ExtPS::Perform(const gp_Pnt& P)
241{
242 myPoints.Clear();
243 mySqDist.Clear();
244 Standard_Integer i;
5368adff 245
7fd59977 246
247 switch(mytype) {
248
249 case GeomAbs_Cylinder:
250 myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
251 break;
252 case GeomAbs_Plane:
253 myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
254 break;
255 case GeomAbs_Cone:
256 myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
257 break;
258 case GeomAbs_Sphere:
259 myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
260 break;
261 case GeomAbs_Torus:
262 myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
263 break;
264
265
266 case GeomAbs_SurfaceOfExtrusion: {
267 Extrema_ExtPExtS anExtPExtS(P,
268 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
269 myS->Direction()),
270 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
271 myDone = anExtPExtS.IsDone();
272 if (myDone)
273 for (i = 1; i <= anExtPExtS.NbExt(); i++) {
274 TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
275 }
276 return;
277 }
278
279
280 case GeomAbs_SurfaceOfRevolution: {
281 Extrema_ExtPRevS anExtPRevS(P,
282 Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(),
283 myS->AxeOfRevolution()),
284 myuinf, myusup,myvinf, myvsup,mytolu, mytolv);
285 myDone = anExtPRevS.IsDone();
286 if (myDone)
287 for (i = 1; i <= anExtPRevS.NbExt(); i++) {
288 TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
289 }
290 return;
291 }
292
293
294 default:
295 myExtPS.Perform(P);
296 myDone = myExtPS.IsDone();
297 if (myDone)
298 for (i = 1; i <= myExtPS.NbExt(); i++)
299 TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
300 return;
301 }
302
303
304 myDone = myExtPElS.IsDone();
305 if (myDone)
306 for (i = 1; i <= myExtPElS.NbExt(); i++)
307 TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
308 return;
309}
310
311
312
313Standard_Boolean Extrema_ExtPS::IsDone() const
314{
315 return myDone;
316}
317
318
319Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
320{
321 if(!myDone) StdFail_NotDone::Raise();
322 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
323 return mySqDist.Value(N);
324}
325
326
327Standard_Integer Extrema_ExtPS::NbExt() const
328{
329 if(!myDone) StdFail_NotDone::Raise();
330 return mySqDist.Length();
331}
332
333
334
335Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
336{
337 if(!myDone) StdFail_NotDone::Raise();
338 return myPoints.Value(N);
339}
340
341
342void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
343 Standard_Real& dUfVl,
344 Standard_Real& dUlVf,
345 Standard_Real& dUlVl,
346 gp_Pnt& PUfVf,
347 gp_Pnt& PUfVl,
348 gp_Pnt& PUlVf,
349 gp_Pnt& PUlVl) const
350{
351 dUfVf = d11;
352 dUfVl = d12;
353 dUlVf = d21;
354 dUlVl = d22;
355 PUfVf = P11;
356 PUfVl = P12;
357 PUlVf = P21;
358 PUlVl = P22;
359}
92d1589b
A
360
361void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
362{
363 myExtPS.SetFlag(F);
364}
365
366void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)
367{
368 myExtPS.SetAlgo(A);
0d969553 369}