1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 //-----------------------------------------------------------------
17 #include <GeomAdaptor_SurfaceOfLinearExtrusion.hxx>
18 #include <GeomAdaptor_SurfaceOfRevolution.hxx>
19 #include <Adaptor3d_Surface.hxx>
21 #include <Extrema_ExtPExtS.hxx>
22 #include <Extrema_ExtPRevS.hxx>
23 #include <Extrema_ExtPS.hxx>
24 #include <Extrema_GenExtPS.hxx>
25 #include <Extrema_POnSurf.hxx>
26 #include <GeomAbs_CurveType.hxx>
27 #include <GeomAbs_IsoType.hxx>
28 #include <gp_Cone.hxx>
29 #include <gp_Cylinder.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>
40 //=======================================================================
43 //=======================================================================
44 static 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)
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();
58 Standard_Real Step,D1NormMax;
59 if (IT == GeomAbs_IsoV)
61 if( !Precision::IsInfinite(U1) && !Precision::IsInfinite(U2) )
64 if(Step < Precision::PConfusion()) {
65 return Standard_False;
69 for (T=U1;T<=U2;T=T+Step)
71 S.D1(T,Param,P,D1U,D1V);
72 D1NormMax=Max(D1NormMax,D1U.Magnitude());
75 if (D1NormMax >TolMax || D1NormMax < TolMin )
76 Along = Standard_False;
81 if( !Precision::IsInfinite(V1) && !Precision::IsInfinite(V2) )
84 if(Step < Precision::PConfusion()) {
85 return Standard_False;
88 for (T=V1;T<=V2;T=T+Step)
90 S.D1(Param,T,P,D1U,D1V);
91 D1NormMax=Max(D1NormMax,D1V.Magnitude());
94 if (D1NormMax >TolMax || D1NormMax < TolMin )
95 Along = Standard_False;
104 //=======================================================================
105 //function : TreatSolution
107 //=======================================================================
109 void Extrema_ExtPS::TreatSolution (const Extrema_POnSurf& PS,
110 const Standard_Real Val)
114 if (myS->IsUPeriodic()) {
115 U = ElCLib::InPeriod(U, myuinf, myuinf + myS->UPeriod());
117 // Handle trimmed surfaces.
118 if (U > myusup + mytolu)
120 if (U < myuinf - mytolu)
123 if (myS->IsVPeriodic()) {
124 V = ElCLib::InPeriod(V, myvinf, myvinf + myS->VPeriod());
126 // Handle trimmed surfaces.
127 if (V > myvsup + mytolv)
129 if (V < myvinf - mytolv)
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);
140 //=======================================================================
141 //function : Extrema_ExtPS
143 //=======================================================================
145 Extrema_ExtPS::Extrema_ExtPS()
147 myDone(Standard_False),
158 mytype(GeomAbs_OtherSurface)
163 //=======================================================================
164 //function : Extrema_ExtPS
166 //=======================================================================
168 Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
169 const Adaptor3d_Surface& theS,
170 const Standard_Real theTolU,
171 const Standard_Real theTolV,
172 const Extrema_ExtFlag theF,
173 const Extrema_ExtAlgo theA)
175 myExtPS.SetFlag (theF);
176 myExtPS.SetAlgo (theA);
179 theS.FirstUParameter(),
180 theS.LastUParameter(),
181 theS.FirstVParameter(),
182 theS.LastVParameter(),
189 //=======================================================================
190 //function : Extrema_ExtPS
192 //=======================================================================
194 Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
195 const Adaptor3d_Surface& theS,
196 const Standard_Real theUinf,
197 const Standard_Real theUsup,
198 const Standard_Real theVinf,
199 const Standard_Real theVsup,
200 const Standard_Real theTolU,
201 const Standard_Real theTolV,
202 const Extrema_ExtFlag theF,
203 const Extrema_ExtAlgo theA)
205 myExtPS.SetFlag (theF);
206 myExtPS.SetAlgo (theA);
220 //=======================================================================
221 //function : Initialize
223 //=======================================================================
225 void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
226 const Standard_Real theUinf,
227 const Standard_Real theUsup,
228 const Standard_Real theVinf,
229 const Standard_Real theVsup,
230 const Standard_Real theTolU,
231 const Standard_Real theTolV)
239 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
240 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
241 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
242 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
246 mytype = myS->GetType();
248 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
249 myS->GetType() == GeomAbs_BezierSurface );
251 Standard_Integer nbU = (isB) ? 44 : 32;
252 Standard_Integer nbV = (isB) ? 44 : 32;
254 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
256 if(myS->GetType() != GeomAbs_Plane) {
257 bUIsoIsDeg = IsoIsDeg(theS, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
258 IsoIsDeg(theS, myusup, GeomAbs_IsoU, 0., 1.e-9);
259 bVIsoIsDeg = IsoIsDeg(theS, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
260 IsoIsDeg(theS, myvsup, GeomAbs_IsoV, 0., 1.e-9);
263 if(bUIsoIsDeg) nbU = 300;
264 if(bVIsoIsDeg) nbV = 300;
266 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
268 myExtPExtS.Nullify();
269 myExtPRevS.Nullify();
272 //=======================================================================
275 //=======================================================================
277 void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
284 case GeomAbs_Cylinder:
285 myExtPElS.Perform (thePoint, myS->Cylinder(), Precision::Confusion());
288 myExtPElS.Perform (thePoint, myS->Plane(), Precision::Confusion());
291 myExtPElS.Perform (thePoint, myS->Cone(), Precision::Confusion());
294 myExtPElS.Perform (thePoint, myS->Sphere(), Precision::Confusion());
297 myExtPElS.Perform (thePoint, myS->Torus(), Precision::Confusion());
300 case GeomAbs_SurfaceOfExtrusion:
302 if (myExtPExtS.IsNull())
304 Handle(GeomAdaptor_SurfaceOfLinearExtrusion) aS (new GeomAdaptor_SurfaceOfLinearExtrusion (
305 GeomAdaptor_SurfaceOfLinearExtrusion (myS->BasisCurve(), myS->Direction())));
307 myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
311 myExtPExtS->Perform (thePoint);
314 myDone = myExtPExtS->IsDone();
317 for (Standard_Integer anIdx = 1; anIdx <= myExtPExtS->NbExt(); ++anIdx)
319 TreatSolution (myExtPExtS->Point (anIdx), myExtPExtS->SquareDistance (anIdx));
326 case GeomAbs_SurfaceOfRevolution:
328 if (myExtPRevS.IsNull())
330 Handle(GeomAdaptor_SurfaceOfRevolution) aS (new GeomAdaptor_SurfaceOfRevolution (
331 GeomAdaptor_SurfaceOfRevolution (myS->BasisCurve(), myS->AxeOfRevolution())));
333 myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
337 myExtPRevS->Perform (thePoint);
340 myDone = myExtPRevS->IsDone();
343 for (Standard_Integer anIdx = 1; anIdx <= myExtPRevS->NbExt(); ++anIdx)
345 TreatSolution (myExtPRevS->Point (anIdx), myExtPRevS->SquareDistance (anIdx));
354 myExtPS.Perform (thePoint);
355 myDone = myExtPS.IsDone();
358 for (Standard_Integer anIdx = 1; anIdx <= myExtPS.NbExt(); ++anIdx)
360 TreatSolution (myExtPS.Point (anIdx), myExtPS.SquareDistance (anIdx));
367 myDone = myExtPElS.IsDone();
370 for (Standard_Integer anIdx = 1; anIdx <= myExtPElS.NbExt(); ++anIdx)
372 TreatSolution (myExtPElS.Point (anIdx), myExtPElS.SquareDistance (anIdx));
378 Standard_Boolean Extrema_ExtPS::IsDone() const
384 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
386 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
387 return mySqDist.Value(N);
391 Standard_Integer Extrema_ExtPS::NbExt() const
393 if (!IsDone()) throw StdFail_NotDone();
394 return mySqDist.Length();
398 const Extrema_POnSurf& Extrema_ExtPS::Point(const Standard_Integer N) const
400 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
401 return myPoints.Value(N);
405 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
406 Standard_Real& dUfVl,
407 Standard_Real& dUlVf,
408 Standard_Real& dUlVl,
424 void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
429 void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)