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_HSurfaceOfLinearExtrusion.hxx>
18 #include <GeomAdaptor_HSurfaceOfRevolution.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;
151 //=======================================================================
152 //function : Extrema_ExtPS
154 //=======================================================================
156 Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
157 const Adaptor3d_Surface& theS,
158 const Standard_Real theTolU,
159 const Standard_Real theTolV,
160 const Extrema_ExtFlag theF,
161 const Extrema_ExtAlgo theA)
163 myExtPS.SetFlag (theF);
164 myExtPS.SetAlgo (theA);
167 theS.FirstUParameter(),
168 theS.LastUParameter(),
169 theS.FirstVParameter(),
170 theS.LastVParameter(),
177 //=======================================================================
178 //function : Extrema_ExtPS
180 //=======================================================================
182 Extrema_ExtPS::Extrema_ExtPS (const gp_Pnt& theP,
183 const Adaptor3d_Surface& theS,
184 const Standard_Real theUinf,
185 const Standard_Real theUsup,
186 const Standard_Real theVinf,
187 const Standard_Real theVsup,
188 const Standard_Real theTolU,
189 const Standard_Real theTolV,
190 const Extrema_ExtFlag theF,
191 const Extrema_ExtAlgo theA)
193 myExtPS.SetFlag (theF);
194 myExtPS.SetAlgo (theA);
208 //=======================================================================
209 //function : Initialize
211 //=======================================================================
213 void Extrema_ExtPS::Initialize (const Adaptor3d_Surface& theS,
214 const Standard_Real theUinf,
215 const Standard_Real theUsup,
216 const Standard_Real theVinf,
217 const Standard_Real theVsup,
218 const Standard_Real theTolU,
219 const Standard_Real theTolV)
221 myS = (Adaptor3d_SurfacePtr)&theS;
227 if (Precision::IsNegativeInfinite(myuinf)) myuinf = -1e10;
228 if (Precision::IsPositiveInfinite(myusup)) myusup = 1e10;
229 if (Precision::IsNegativeInfinite(myvinf)) myvinf = -1e10;
230 if (Precision::IsPositiveInfinite(myvsup)) myvsup = 1e10;
234 mytype = myS->GetType();
236 Standard_Boolean isB = ( myS->GetType() == GeomAbs_BSplineSurface ||
237 myS->GetType() == GeomAbs_BezierSurface );
239 Standard_Integer nbU = (isB) ? 44 : 32;
240 Standard_Integer nbV = (isB) ? 44 : 32;
242 Standard_Boolean bUIsoIsDeg = Standard_False, bVIsoIsDeg = Standard_False;
244 if(myS->GetType() != GeomAbs_Plane) {
245 bUIsoIsDeg = IsoIsDeg(theS, myuinf, GeomAbs_IsoU, 0., 1.e-9) ||
246 IsoIsDeg(theS, myusup, GeomAbs_IsoU, 0., 1.e-9);
247 bVIsoIsDeg = IsoIsDeg(theS, myvinf, GeomAbs_IsoV, 0., 1.e-9) ||
248 IsoIsDeg(theS, myvsup, GeomAbs_IsoV, 0., 1.e-9);
251 if(bUIsoIsDeg) nbU = 300;
252 if(bVIsoIsDeg) nbV = 300;
254 myExtPS.Initialize(*myS, nbU, nbV, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
256 myExtPExtS.Nullify();
257 myExtPRevS.Nullify();
260 //=======================================================================
263 //=======================================================================
265 void Extrema_ExtPS::Perform(const gp_Pnt& thePoint)
272 case GeomAbs_Cylinder:
273 myExtPElS.Perform (thePoint, myS->Cylinder(), Precision::Confusion());
276 myExtPElS.Perform (thePoint, myS->Plane(), Precision::Confusion());
279 myExtPElS.Perform (thePoint, myS->Cone(), Precision::Confusion());
282 myExtPElS.Perform (thePoint, myS->Sphere(), Precision::Confusion());
285 myExtPElS.Perform (thePoint, myS->Torus(), Precision::Confusion());
288 case GeomAbs_SurfaceOfExtrusion:
290 if (myExtPExtS.IsNull())
292 Handle(GeomAdaptor_HSurfaceOfLinearExtrusion) aS (new GeomAdaptor_HSurfaceOfLinearExtrusion (
293 GeomAdaptor_SurfaceOfLinearExtrusion (myS->BasisCurve(), myS->Direction())));
295 myExtPExtS = new Extrema_ExtPExtS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
299 myExtPExtS->Perform (thePoint);
302 myDone = myExtPExtS->IsDone();
305 for (Standard_Integer anIdx = 1; anIdx <= myExtPExtS->NbExt(); ++anIdx)
307 TreatSolution (myExtPExtS->Point (anIdx), myExtPExtS->SquareDistance (anIdx));
314 case GeomAbs_SurfaceOfRevolution:
316 if (myExtPRevS.IsNull())
318 Handle(GeomAdaptor_HSurfaceOfRevolution) aS (new GeomAdaptor_HSurfaceOfRevolution (
319 GeomAdaptor_SurfaceOfRevolution (myS->BasisCurve(), myS->AxeOfRevolution())));
321 myExtPRevS = new Extrema_ExtPRevS (thePoint, aS, myuinf, myusup, myvinf, myvsup, mytolu, mytolv);
325 myExtPRevS->Perform (thePoint);
328 myDone = myExtPRevS->IsDone();
331 for (Standard_Integer anIdx = 1; anIdx <= myExtPRevS->NbExt(); ++anIdx)
333 TreatSolution (myExtPRevS->Point (anIdx), myExtPRevS->SquareDistance (anIdx));
342 myExtPS.Perform (thePoint);
343 myDone = myExtPS.IsDone();
346 for (Standard_Integer anIdx = 1; anIdx <= myExtPS.NbExt(); ++anIdx)
348 TreatSolution (myExtPS.Point (anIdx), myExtPS.SquareDistance (anIdx));
355 myDone = myExtPElS.IsDone();
358 for (Standard_Integer anIdx = 1; anIdx <= myExtPElS.NbExt(); ++anIdx)
360 TreatSolution (myExtPElS.Point (anIdx), myExtPElS.SquareDistance (anIdx));
366 Standard_Boolean Extrema_ExtPS::IsDone() const
372 Standard_Real Extrema_ExtPS::SquareDistance(const Standard_Integer N) const
374 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
375 return mySqDist.Value(N);
379 Standard_Integer Extrema_ExtPS::NbExt() const
381 if (!IsDone()) throw StdFail_NotDone();
382 return mySqDist.Length();
386 const Extrema_POnSurf& Extrema_ExtPS::Point(const Standard_Integer N) const
388 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
389 return myPoints.Value(N);
393 void Extrema_ExtPS::TrimmedSquareDistances(Standard_Real& dUfVf,
394 Standard_Real& dUfVl,
395 Standard_Real& dUlVf,
396 Standard_Real& dUlVl,
412 void Extrema_ExtPS::SetFlag(const Extrema_ExtFlag F)
417 void Extrema_ExtPS::SetAlgo(const Extrema_ExtAlgo A)