1 // File Extrema_ExtPS.cxx
2 //-----------------------------------------------------------------
4 #include <Extrema_ExtPS.ixx>
5 #include <Extrema_GenExtPS.hxx>
6 #include <StdFail_NotDone.hxx>
7 #include <Standard_NotImplemented.hxx>
8 #include <Precision.hxx>
9 #include <GeomAbs_CurveType.hxx>
10 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
11 #include <Adaptor3d_SurfaceOfRevolution.hxx>
15 #include <gp_Cylinder.hxx>
16 #include <gp_Cone.hxx>
17 #include <gp_Sphere.hxx>
18 #include <gp_Torus.hxx>
19 #include <Extrema_ExtPExtS.hxx>
20 #include <Extrema_ExtPRevS.hxx>
21 #include <Extrema_POnSurf.hxx>
22 #include <GeomAbs_IsoType.hxx>
24 //=======================================================================
27 //=======================================================================
29 static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
30 const Standard_Real Param,
31 const GeomAbs_IsoType IT,
32 const Standard_Real TolMin,
33 const Standard_Real TolMax)
35 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
36 Standard_Boolean Along = Standard_True;
37 U1 = S.FirstUParameter();
38 U2 = S.LastUParameter();
39 V1 = S.FirstVParameter();
40 V2 = S.LastVParameter();
43 Standard_Real Step,D1NormMax;
44 if (IT == GeomAbs_IsoV)
47 if(Step < Precision::PConfusion()) {
48 return Standard_False;
50 if(Step < Precision::PConfusion()) {
51 return Standard_False;
54 for (T=U1;T<=U2;T=T+Step)
56 S.D1(T,Param,P,D1U,D1V);
57 D1NormMax=Max(D1NormMax,D1U.Magnitude());
60 if (D1NormMax >TolMax || D1NormMax < TolMin )
61 Along = Standard_False;
66 if(Step < Precision::PConfusion()) {
67 return Standard_False;
69 if(Step < Precision::PConfusion()) {
70 return Standard_False;
73 for (T=V1;T<=V2;T=T+Step)
75 S.D1(Param,T,P,D1U,D1V);
76 D1NormMax=Max(D1NormMax,D1V.Magnitude());
79 if (D1NormMax >TolMax || D1NormMax < TolMin )
80 Along = Standard_False;
87 //=======================================================================
88 //function : TreatSolution
90 //=======================================================================
92 void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
93 const Standard_Real Val)
97 if (myS->IsUPeriodic()) {
98 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
100 if (myS->IsVPeriodic()) {
101 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
103 if ((myuinf-U) <= mytolu && (U-myusup) <= mytolu &&
104 (myvinf-V) <= mytolv && (V-myvsup) <= mytolv) {
105 myPoints.Append(Extrema_POnSurf (U, V, PS.Value()));
106 mySqDist.Append(Val);
111 //=======================================================================
112 //function : Extrema_ExtPS
114 //=======================================================================
116 Extrema_ExtPS::Extrema_ExtPS()
118 myDone = Standard_False;
122 //=======================================================================
123 //function : Extrema_ExtPS
125 //=======================================================================
127 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
128 const Adaptor3d_Surface& S,
129 const Standard_Real TolU,
130 const Standard_Real TolV,
131 const Extrema_ExtFlag F,
132 const Extrema_ExtAlgo A)
137 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
138 S.FirstVParameter(), S.LastVParameter(),
143 //=======================================================================
144 //function : Extrema_ExtPS
146 //=======================================================================
148 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
149 const Adaptor3d_Surface& S,
150 const Standard_Real Uinf,
151 const Standard_Real Usup,
152 const Standard_Real Vinf,
153 const Standard_Real Vsup,
154 const Standard_Real TolU,
155 const Standard_Real TolV,
156 const Extrema_ExtFlag F,
157 const Extrema_ExtAlgo A)
162 Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
167 //=======================================================================
168 //function : Initialize
170 //=======================================================================
172 void Extrema_ExtPS::Initialize(const Adaptor3d_Surface& S,
173 const Standard_Real Uinf,
174 const Standard_Real Usup,
175 const Standard_Real Vinf,
176 const Standard_Real Vsup,
177 const Standard_Real TolU,
178 const Standard_Real TolV)
180 myS = (Adaptor3d_SurfacePtr)&S;
186 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
187 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
188 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
189 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
193 mytype = myS->GetType();
195 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
196 myS->GetType() == GeomAbs_BezierSurface );
198 Standard_Integer nbU = (isB) ? 44 : 32;
199 Standard_Integer nbV = (isB) ? 44 : 32;
201 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
203 if(myS->GetType() != GeomAbs_Plane) {
204 bUIsoIsDeg = IsoIsDeg(S, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
205 IsoIsDeg(S, myusup, GeomAbs_IsoU, 0., 1.e-9);
206 bVIsoIsDeg = IsoIsDeg(S, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
207 IsoIsDeg(S, myvsup, GeomAbs_IsoV, 0., 1.e-9);
210 if(bUIsoIsDeg) nbU = 300;
211 if(bVIsoIsDeg) nbV = 300;
213 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
216 //=======================================================================
219 //=======================================================================
221 void Extrema_ExtPS::Perform(const gp_Pnt& P)
226 P11 = myS->Value(myuinf, myvinf);
227 P12 = myS->Value(myuinf, myvsup);
228 P21 = myS->Value(myusup, myvinf);
229 P22 = myS->Value(myusup, myvsup);
230 d11 = P.SquareDistance(P11);
231 d12 = P.SquareDistance(P12);
232 d21 = P.SquareDistance(P21);
233 d22 = P.SquareDistance(P22);
237 case GeomAbs_Cylinder:
238 myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
241 myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
244 myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
247 myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
250 myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
254 case GeomAbs_SurfaceOfExtrusion: {
255 Extrema_ExtPExtS anExtPExtS(P,
256 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
258 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
259 myDone = anExtPExtS.IsDone();
261 for (i = 1; i <= anExtPExtS.NbExt(); i++) {
262 TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
268 case GeomAbs_SurfaceOfRevolution: {
269 Extrema_ExtPRevS anExtPRevS(P,
270 Adaptor3d_SurfaceOfRevolution(myS->BasisCurve(),
271 myS->AxeOfRevolution()),
272 myuinf, myusup,myvinf, myvsup,mytolu, mytolv);
273 myDone = anExtPRevS.IsDone();
275 for (i = 1; i <= anExtPRevS.NbExt(); i++) {
276 TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
284 myDone = myExtPS.IsDone();
286 for (i = 1; i <= myExtPS.NbExt(); i++)
287 TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
292 myDone = myExtPElS.IsDone();
294 for (i = 1; i <= myExtPElS.NbExt(); i++)
295 TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
301 Standard_Boolean Extrema_ExtPS::IsDone() const
307 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
309 if(!myDone) StdFail_NotDone::Raise();
310 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
311 return mySqDist.Value(N);
315 Standard_Integer Extrema_ExtPS::NbExt() const
317 if(!myDone) StdFail_NotDone::Raise();
318 return mySqDist.Length();
323 Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
325 if(!myDone) StdFail_NotDone::Raise();
326 return myPoints.Value(N);
330 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
331 Standard_Real& dUfVl,
332 Standard_Real& dUlVf,
333 Standard_Real& dUlVl,
349 void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
354 void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)