1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
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.
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.
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.
19 //-----------------------------------------------------------------
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>
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>
41 //=======================================================================
44 //=======================================================================
46 static 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)
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();
60 Standard_Real Step,D1NormMax;
61 if (IT == GeomAbs_IsoV)
63 if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) )
66 if(Step < Precision::PConfusion()) {
67 return Standard_False;
71 for (T=U1;T<=U2;T=T+Step)
73 S.D1(T,Param,P,D1U,D1V);
74 D1NormMax=Max(D1NormMax,D1U.Magnitude());
77 if (D1NormMax >TolMax || D1NormMax < TolMin )
78 Along = Standard_False;
83 if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) )
86 if(Step < Precision::PConfusion()) {
87 return Standard_False;
90 for (T=V1;T<=V2;T=T+Step)
92 S.D1(Param,T,P,D1U,D1V);
93 D1NormMax=Max(D1NormMax,D1V.Magnitude());
96 if (D1NormMax >TolMax || D1NormMax < TolMin )
97 Along = Standard_False;
106 //=======================================================================
107 //function : TreatSolution
109 //=======================================================================
111 void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
112 const Standard_Real Val)
116 if (myS->IsUPeriodic()) {
117 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
119 if (myS->IsVPeriodic()) {
120 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
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);
130 //=======================================================================
131 //function : Extrema_ExtPS
133 //=======================================================================
135 Extrema_ExtPS::Extrema_ExtPS()
137 myDone = Standard_False;
141 //=======================================================================
142 //function : Extrema_ExtPS
144 //=======================================================================
146 Extrema_ExtPS::Extrema_ExtPS(const gp_Pnt& P,
147 const Adaptor3d_Surface& S,
148 const Standard_Real TolU,
149 const Standard_Real TolV,
150 const Extrema_ExtFlag F,
151 const Extrema_ExtAlgo A)
156 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
157 S.FirstVParameter(), S.LastVParameter(),
162 //=======================================================================
163 //function : Extrema_ExtPS
165 //=======================================================================
167 Extrema_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,
174 const Standard_Real TolV,
175 const Extrema_ExtFlag F,
176 const Extrema_ExtAlgo A)
181 Initialize(S, Uinf, Usup, Vinf, Vsup, TolU, TolV);
186 //=======================================================================
187 //function : Initialize
189 //=======================================================================
191 void 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)
199 myS = (Adaptor3d_SurfacePtr)&S;
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;
212 mytype = myS->GetType();
214 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
215 myS->GetType() == GeomAbs_BezierSurface );
217 Standard_Integer nbU = (isB) ? 44 : 32;
218 Standard_Integer nbV = (isB) ? 44 : 32;
220 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
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);
229 if(bUIsoIsDeg) nbU = 300;
230 if(bVIsoIsDeg) nbV = 300;
232 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
235 //=======================================================================
238 //=======================================================================
240 void Extrema_ExtPS::Perform(const gp_Pnt& P)
249 case GeomAbs_Cylinder:
250 myExtPElS.Perform(P, myS->Cylinder(), Precision::Confusion());
253 myExtPElS.Perform(P, myS->Plane(), Precision::Confusion());
256 myExtPElS.Perform(P, myS->Cone(), Precision::Confusion());
259 myExtPElS.Perform(P, myS->Sphere(), Precision::Confusion());
262 myExtPElS.Perform(P, myS->Torus(), Precision::Confusion());
266 case GeomAbs_SurfaceOfExtrusion: {
267 Extrema_ExtPExtS anExtPExtS(P,
268 Adaptor3d_SurfaceOfLinearExtrusion(myS->BasisCurve(),
270 myuinf,myusup, myvinf,myvsup, mytolu,mytolv);
271 myDone = anExtPExtS.IsDone();
273 for (i = 1; i <= anExtPExtS.NbExt(); i++) {
274 TreatSolution (anExtPExtS.Point(i), anExtPExtS.SquareDistance(i));
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();
287 for (i = 1; i <= anExtPRevS.NbExt(); i++) {
288 TreatSolution (anExtPRevS.Point(i), anExtPRevS.SquareDistance(i));
296 myDone = myExtPS.IsDone();
298 for (i = 1; i <= myExtPS.NbExt(); i++)
299 TreatSolution (myExtPS.Point(i), myExtPS.SquareDistance(i));
304 myDone = myExtPElS.IsDone();
306 for (i = 1; i <= myExtPElS.NbExt(); i++)
307 TreatSolution (myExtPElS.Point(i), myExtPElS.SquareDistance(i));
313 Standard_Boolean Extrema_ExtPS::IsDone() const
319 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
321 if(!myDone) StdFail_NotDone::Raise();
322 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
323 return mySqDist.Value(N);
327 Standard_Integer Extrema_ExtPS::NbExt() const
329 if(!myDone) StdFail_NotDone::Raise();
330 return mySqDist.Length();
335 Extrema_POnSurf Extrema_ExtPS::Point(const Standard_Integer N) const
337 if(!myDone) StdFail_NotDone::Raise();
338 return myPoints.Value(N);
342 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
343 Standard_Real& dUfVl,
344 Standard_Real& dUlVf,
345 Standard_Real& dUlVl,
361 void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
366 void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)