1 // File: Extrema_ExtCS.cxx
2 // Created: Tue Jul 18 10:33:04 1995
3 // Author: Modelistation
6 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134
8 #include <Extrema_ExtCS.ixx>
9 #include <Extrema_GenExtCS.hxx>
10 #include <StdFail_NotDone.hxx>
11 #include <Standard_NotImplemented.hxx>
12 #include <StdFail_InfiniteSolutions.hxx>
13 #include <Precision.hxx>
14 #include <GeomAbs_CurveType.hxx>
17 #include <gp_Cylinder.hxx>
18 #include <gp_Cone.hxx>
19 #include <gp_Sphere.hxx>
20 #include <gp_Torus.hxx>
24 #include <Extrema_ExtPElC.hxx>
25 #include <Bnd_Box.hxx>
26 #include <BndLib_AddSurface.hxx>
27 #include <Extrema_ExtPElS.hxx>
29 Extrema_ExtCS::Extrema_ExtCS()
31 myDone = Standard_False;
34 Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
35 const Adaptor3d_Surface& S,
36 const Standard_Real TolC,
37 const Standard_Real TolS)
40 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
41 S.FirstVParameter(), S.LastVParameter(),
43 Perform(C, C.FirstParameter(), C.LastParameter());
46 Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
47 const Adaptor3d_Surface& S,
48 const Standard_Real UCinf,
49 const Standard_Real UCsup,
50 const Standard_Real Uinf,
51 const Standard_Real Usup,
52 const Standard_Real Vinf,
53 const Standard_Real Vsup,
54 const Standard_Real TolC,
55 const Standard_Real TolS)
58 Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS);
59 Perform(C, UCinf, UCsup);
63 void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S,
64 const Standard_Real Uinf,
65 const Standard_Real Usup,
66 const Standard_Real Vinf,
67 const Standard_Real Vsup,
68 const Standard_Real TolC,
69 const Standard_Real TolS)
71 myS = (Adaptor3d_SurfacePtr)&S;
72 myIsPar = Standard_False;
79 myStype = myS->GetType();
83 void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
84 const Standard_Real Uinf,
85 const Standard_Real Usup)
93 Standard_Integer NbT, NbU, NbV;
95 GeomAbs_CurveType myCtype = C.GetType();
105 myExtElCS.Perform(C.Line(), myS->Sphere());
107 case GeomAbs_Cylinder:
108 myExtElCS.Perform(C.Line(), myS->Cylinder());
111 myExtElCS.Perform(C.Line(), myS->Plane());
112 if (myExtElCS.IsParallel()) break;
116 case GeomAbs_BezierSurface:
117 case GeomAbs_BSplineSurface:
118 case GeomAbs_SurfaceOfRevolution:
119 case GeomAbs_SurfaceOfExtrusion:
120 case GeomAbs_OtherSurface:
122 Standard_Real cfirst = myucinf, clast = myucsup;
123 Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(),
124 vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter();
126 if(Precision::IsInfinite(Abs(cfirst)) || Precision::IsInfinite(Abs(clast))) {
129 BndLib_AddSurface::Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox);
130 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
131 aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
132 Standard_Real tmin = Precision::Infinite(), tmax = -tmin;
133 gp_Lin aLin = C.Line();
136 if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) ||
137 Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) ||
138 Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) {
140 Extrema_ExtPElC anExt;
141 Extrema_POnCurv aPntOnLin;
142 Standard_Real aParOnLin;
143 Standard_Real lim = Precision::Infinite();
144 gp_Pnt aLimPntArray[8];
146 aLimPntArray[0].SetCoord(xmin, ymin, zmin);
147 aLimPntArray[1].SetCoord(xmax, ymin, zmin);
148 aLimPntArray[2].SetCoord(xmin, ymax, zmin);
149 aLimPntArray[3].SetCoord(xmax, ymax, zmin);
150 aLimPntArray[4].SetCoord(xmin, ymin, zmax);
151 aLimPntArray[5].SetCoord(xmax, ymin, zmax);
152 aLimPntArray[6].SetCoord(xmin, ymax, zmax);
153 aLimPntArray[7].SetCoord(xmax, ymax, zmax);
155 for(i = 0; i <= 7; i++) {
156 anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim);
157 aPntOnLin = anExt.Point(1);
158 aParOnLin = aPntOnLin.Parameter();
159 tmin = Min(aParOnLin, tmin);
160 tmax = Max(aParOnLin, tmax);
170 cfirst = Max(cfirst, tmin);
171 clast = Min(clast, tmax);
177 Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast,
178 vfirst, vlast, mytolC, mytolS);
180 myDone = Ext.IsDone();
182 Standard_Integer NbExt = Ext.NbExt();
186 for (i = 1; i <= NbExt; i++) {
187 PC = Ext.PointOnCurve(i);
188 PS = Ext.PointOnSurface(i);
191 if (myS->IsUPeriodic())
192 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
193 if (myS->IsVPeriodic())
194 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
196 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
197 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
198 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) {
199 mySqDist.Append(Ext.SquareDistance(i));
201 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
217 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin
220 if(myStype == GeomAbs_Cylinder) {
221 myExtElCS.Perform(C.Circle(), myS->Cylinder());
225 case GeomAbs_Hyperbola:
227 if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) {
228 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End
229 myExtElCS.Perform(C.Hyperbola(), myS->Plane());
235 Extrema_GenExtCS Ext;
236 Ext.Initialize(*myS, NbU, NbV, mytolS);
237 if(myCtype == GeomAbs_Hyperbola) {
238 Standard_Real tmin = Max(-20., C.FirstParameter());
239 Standard_Real tmax = Min(20., C.LastParameter());
240 Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
243 if(myCtype == GeomAbs_Circle && NbT < 13) {
246 Ext.Perform(C, NbT, mytolC);
249 myDone = Ext.IsDone();
251 Standard_Integer NbExt = Ext.NbExt();
255 for (i = 1; i <= NbExt; i++) {
256 PC = Ext.PointOnCurve(i);
257 PS = Ext.PointOnSurface(i);
261 T = ElCLib::InPeriod(T, myucinf, myucinf+C.Period());
262 if (myS->IsUPeriodic())
263 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
264 if (myS->IsVPeriodic())
265 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
267 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
268 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
269 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) {
270 mySqDist.Append(Ext.SquareDistance(i));
271 PC.SetValues(T, PC.Value());
273 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
282 myDone = myExtElCS.IsDone();
284 myIsPar = myExtElCS.IsParallel();
286 mySqDist.Append(myExtElCS.SquareDistance(1));
289 Standard_Integer NbExt = myExtElCS.NbExt();
291 for (i = 1; i <= NbExt; i++) {
294 myExtElCS.Points(i, PC, PS);
295 Standard_Real Ucurve = PC.Parameter();
298 if((myStype == GeomAbs_Sphere) || (myStype == GeomAbs_Cylinder)) {
299 U = ElCLib::InPeriod(U, myuinf, myuinf+2.*M_PI);
302 if ((myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
303 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS &&
304 (myucinf-Ucurve) <= mytolC && (Ucurve-myucsup) <= mytolC) {
305 mySqDist.Append(myExtElCS.SquareDistance(i));
306 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
316 Standard_Boolean Extrema_ExtCS::IsDone() const
321 Standard_Boolean Extrema_ExtCS::IsParallel() const
327 Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
329 if(!myDone) StdFail_NotDone::Raise();
330 if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
331 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
332 return mySqDist.Value(N);
336 Standard_Integer Extrema_ExtCS::NbExt() const
338 if(!myDone) StdFail_NotDone::Raise();
339 return mySqDist.Length();
344 void Extrema_ExtCS::Points(const Standard_Integer N,
346 Extrema_POnSurf& P2) const
348 if(!myDone) StdFail_NotDone::Raise();
349 P1 = myPOnC.Value(N);
350 P2 = myPOnS.Value(N);