1 // File Extrema_ExtPS.cxx
2 //-----------------------------------------------------------------
3 // modif JMB le 17 Mai 1999.
4 // on trimme la surface a +/- 10000 plutot qu'a l'infini
5 // (sinon ca raise dans les Math)
7 //-----------------------------------------------------------------
9 #include <Extrema_ExtPS.ixx>
10 #include <Extrema_GenExtPS.hxx>
11 #include <StdFail_NotDone.hxx>
12 #include <Standard_NotImplemented.hxx>
13 #include <Precision.hxx>
14 #include <GeomAbs_CurveType.hxx>
15 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
16 #include <Adaptor3d_SurfaceOfRevolution.hxx>
20 #include <gp_Cylinder.hxx>
21 #include <gp_Cone.hxx>
22 #include <gp_Sphere.hxx>
23 #include <gp_Torus.hxx>
24 #include <Extrema_ExtPExtS.hxx>
25 #include <Extrema_ExtPRevS.hxx>
26 #include <Extrema_POnSurf.hxx>
27 #include <GeomAbs_IsoType.hxx>
29 //=======================================================================
32 //=======================================================================
34 static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
35 const Standard_Real Param,
36 const GeomAbs_IsoType IT,
37 const Standard_Real TolMin,
38 const Standard_Real TolMax)
40 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
41 Standard_Boolean Along = Standard_True;
42 U1 = S.FirstUParameter();
43 U2 = S.LastUParameter();
44 V1 = S.FirstVParameter();
45 V2 = S.LastVParameter();
48 Standard_Real Step,D1NormMax;
49 if (IT == GeomAbs_IsoV)
52 if(Step < Precision::PConfusion()) {
53 return Standard_False;
56 for (T=U1;T<=U2;T=T+Step)
58 S.D1(T,Param,P,D1U,D1V);
59 D1NormMax=Max(D1NormMax,D1U.Magnitude());
62 if (D1NormMax >TolMax || D1NormMax < TolMin )
63 Along = Standard_False;
68 if(Step < Precision::PConfusion()) {
69 return Standard_False;
72 for (T=V1;T<=V2;T=T+Step)
74 S.D1(Param,T,P,D1U,D1V);
75 D1NormMax=Max(D1NormMax,D1V.Magnitude());
78 if (D1NormMax >TolMax || D1NormMax < TolMin )
79 Along = Standard_False;
86 //=======================================================================
87 //function : TreatSolution
89 //=======================================================================
91 void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
92 const Standard_Real Val)
96 if (myS->IsUPeriodic()) {
97 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
99 if (myS->IsVPeriodic()) {
100 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
102 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
103 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
104 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
105 mySqDist.Append(Val);
110 //=======================================================================
111 //function : Extrema_ExtPS
113 //=======================================================================
115 Extrema_ExtPS::Extrema_ExtPS()
117 myDone = Standard_False;
121 //=======================================================================
122 //function : Extrema_ExtPS
124 //=======================================================================
126 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
127 const Adaptor3d_Surface& S,
128 const Standard_Real TolU,
129 const Standard_Real TolV)
132 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
133 S.FirstVParameter(), S.LastVParameter(),
138 //=======================================================================
139 //function : Extrema_ExtPS
141 //=======================================================================
143 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
144 const Adaptor3d_Surface& S,
145 const Standard_Real Uinf,
146 const Standard_Real Usup,
147 const Standard_Real Vinf,
148 const Standard_Real Vsup,
149 const Standard_Real TolU,
150 const Standard_Real TolV)
153 Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
158 //=======================================================================
159 //function : Initialize
161 //=======================================================================
163 void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S,
164 const Standard_Real Uinf,
165 const Standard_Real Usup,
166 const Standard_Real Vinf,
167 const Standard_Real Vsup,
168 const Standard_Real TolU,
169 const Standard_Real TolV)
171 myS = (Adaptor3d_SurfacePtr)&S;
177 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
178 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
179 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
180 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
184 mytype = myS->GetType();
186 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
187 myS->GetType() == GeomAbs_BezierSurface );
189 Standard_Integer nbU = (isB) ? 44 : 32;
190 Standard_Integer nbV = (isB) ? 44 : 32;
192 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
194 if(myS->GetType() != GeomAbs_Plane) {
195 bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
196 IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9);
197 bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
198 IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9);
201 if(bUIsoIsDeg) nbU = 300;
202 if(bVIsoIsDeg) nbV = 300;
204 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
207 //=======================================================================
210 //=======================================================================
212 void Extrema_ExtPS::Perform(const gp_Pnt& P)
217 P11 = myS->Value(myuinf, myvinf);
218 P12 = myS->Value(myuinf, myvsup);
219 P21 = myS->Value(myusup, myvinf);
220 P22 = myS->Value(myusup, myvsup);
221 d11 = P.SquareDistance(P11);
222 d12 = P.SquareDistance(P12);
223 d21 = P.SquareDistance(P21);
224 d22 = P.SquareDistance(P22);
228 case GeomAbs_Cylinder:
229 myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
232 myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
235 myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
238 myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
241 myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
245 case GeomAbs_SurfaceOfExtrusion: {
246 Extrema_ExtPExtS anExtPExtS(P,
247 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
249 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
250 myDone = anExtPExtS.IsDone();
252 for (i = 1; i <= anExtPExtS.NbExt(); i++) {
253 TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
259 case GeomAbs_SurfaceOfRevolution: {
260 Extrema_ExtPRevS anExtPRevS(P,
261 Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(),
262 myS->AxeOfRevolution()),
263 myuinf, myusup,myvinf, myvsup,mytolu, mytolv);
264 myDone = anExtPRevS.IsDone();
266 for (i = 1; i <= anExtPRevS.NbExt(); i++) {
267 TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
275 myDone = myExtPS.IsDone();
277 for (i = 1; i <= myExtPS.NbExt(); i++)
278 TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
283 myDone = myExtPElS.IsDone();
285 for (i = 1; i <= myExtPElS.NbExt(); i++)
286 TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
292 Standard_Boolean Extrema_ExtPS::IsDone() const
298 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
300 if(!myDone) StdFail_NotDone::Raise();
301 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
302 return mySqDist.Value(N);
306 Standard_Integer Extrema_ExtPS::NbExt() const
308 if(!myDone) StdFail_NotDone::Raise();
309 return mySqDist.Length();
314 Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
316 if(!myDone) StdFail_NotDone::Raise();
317 return myPoints.Value(N);
321 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
322 Standard_Real& dUfVl,
323 Standard_Real& dUlVf,
324 Standard_Real& dUlVl,