1 // File: Extrema_ExtCS.cxx
2 // Created: Tue Jul 18 10:33:04 1995
3 // Author: Modelistation
5 // Modified by MPS (june 96) :
6 // Dans les cas line /cone et line /tore on utilise la classe GenExtCS
7 // a la place de ExtElCS. Dans ExtElCS les cas line/cone et line/tore ne sont
10 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134
12 #include <Extrema_ExtCS.ixx>
13 #include <Extrema_GenExtCS.hxx>
14 #include <StdFail_NotDone.hxx>
15 #include <Standard_NotImplemented.hxx>
16 #include <StdFail_InfiniteSolutions.hxx>
17 #include <Precision.hxx>
18 #include <GeomAbs_CurveType.hxx>
21 #include <gp_Cylinder.hxx>
22 #include <gp_Cone.hxx>
23 #include <gp_Sphere.hxx>
24 #include <gp_Torus.hxx>
28 #include <Extrema_ExtPElC.hxx>
29 #include <Bnd_Box.hxx>
30 #include <BndLib_AddSurface.hxx>
31 #include <Extrema_ExtPElS.hxx>
33 Extrema_ExtCS::Extrema_ExtCS()
35 myDone = Standard_False;
38 Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
39 const Adaptor3d_Surface& S,
40 const Standard_Real TolC,
41 const Standard_Real TolS)
44 Initialize(S, S.FirstUParameter(), S.LastUParameter(),
45 S.FirstVParameter(), S.LastVParameter(),
47 Perform(C, C.FirstParameter(), C.LastParameter());
50 Extrema_ExtCS::Extrema_ExtCS(const Adaptor3d_Curve& C,
51 const Adaptor3d_Surface& S,
52 const Standard_Real UCinf,
53 const Standard_Real UCsup,
54 const Standard_Real Uinf,
55 const Standard_Real Usup,
56 const Standard_Real Vinf,
57 const Standard_Real Vsup,
58 const Standard_Real TolC,
59 const Standard_Real TolS)
62 Initialize(S, Uinf, Usup, Vinf, Vsup, TolC, TolS);
63 Perform(C, UCinf, UCsup);
67 void Extrema_ExtCS::Initialize(const Adaptor3d_Surface& S,
68 const Standard_Real Uinf,
69 const Standard_Real Usup,
70 const Standard_Real Vinf,
71 const Standard_Real Vsup,
72 const Standard_Real TolC,
73 const Standard_Real TolS)
75 myS = (Adaptor3d_SurfacePtr)&S;
76 myIsPar = Standard_False;
83 myStype = myS->GetType();
87 void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
88 const Standard_Real Uinf,
89 const Standard_Real Usup)
97 Standard_Integer NbT, NbU, NbV;
99 GeomAbs_CurveType myCtype = C.GetType();
109 myExtElCS.Perform(C.Line(), myS->Sphere());
111 case GeomAbs_Cylinder:
112 myExtElCS.Perform(C.Line(), myS->Cylinder());
115 myExtElCS.Perform(C.Line(), myS->Plane());
116 if (myExtElCS.IsParallel()) break;
120 case GeomAbs_BezierSurface:
121 case GeomAbs_BSplineSurface:
122 case GeomAbs_SurfaceOfRevolution:
123 case GeomAbs_SurfaceOfExtrusion:
124 case GeomAbs_OtherSurface:
126 Standard_Real cfirst = myucinf, clast = myucsup;
127 Standard_Real ufirst = myS->FirstUParameter(), ulast = myS->LastUParameter(),
128 vfirst = myS->FirstVParameter(), vlast = myS->LastVParameter();
130 if(Precision::IsInfinite(Abs(cfirst)) || Precision::IsInfinite(Abs(clast))) {
133 BndLib_AddSurface anAddSurf;
134 anAddSurf.Add(*myS, ufirst, ulast, vfirst, vlast, Precision::Confusion(), aSurfBox);
135 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
136 aSurfBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
137 Standard_Real tmin = Precision::Infinite(), tmax = -tmin;
138 gp_Lin aLin = C.Line();
141 if(!( Precision::IsInfinite(Abs(xmin)) || Precision::IsInfinite(Abs(xmax)) ||
142 Precision::IsInfinite(Abs(ymin)) || Precision::IsInfinite(Abs(ymax)) ||
143 Precision::IsInfinite(Abs(zmin)) || Precision::IsInfinite(Abs(zmax))) ) {
145 Extrema_ExtPElC anExt;
146 Extrema_POnCurv aPntOnLin;
147 Standard_Real aParOnLin;
148 Standard_Real lim = Precision::Infinite();
149 gp_Pnt aLimPntArray[8];
151 aLimPntArray[0].SetCoord(xmin, ymin, zmin);
152 aLimPntArray[1].SetCoord(xmax, ymin, zmin);
153 aLimPntArray[2].SetCoord(xmin, ymax, zmin);
154 aLimPntArray[3].SetCoord(xmax, ymax, zmin);
155 aLimPntArray[4].SetCoord(xmin, ymin, zmax);
156 aLimPntArray[5].SetCoord(xmax, ymin, zmax);
157 aLimPntArray[6].SetCoord(xmin, ymax, zmax);
158 aLimPntArray[7].SetCoord(xmax, ymax, zmax);
160 for(i = 0; i <= 7; i++) {
161 anExt.Perform(aLimPntArray[i], aLin, Precision::Confusion(), -lim, lim);
162 aPntOnLin = anExt.Point(1);
163 aParOnLin = aPntOnLin.Parameter();
164 tmin = Min(aParOnLin, tmin);
165 tmax = Max(aParOnLin, tmax);
175 cfirst = Max(cfirst, tmin);
176 clast = Min(clast, tmax);
182 Extrema_GenExtCS Ext(C, *myS, NbT, NbU, NbV, cfirst, clast, ufirst, ulast,
183 vfirst, vlast, mytolC, mytolS);
185 myDone = Ext.IsDone();
187 Standard_Integer NbExt = Ext.NbExt();
191 for (i = 1; i <= NbExt; i++) {
192 PC = Ext.PointOnCurve(i);
193 PS = Ext.PointOnSurface(i);
196 if (myS->IsUPeriodic())
197 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
198 if (myS->IsVPeriodic())
199 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
201 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
202 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
203 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) {
204 mySqDist.Append(Ext.SquareDistance(i));
206 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
222 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 Begin
225 if(myStype == GeomAbs_Cylinder) {
226 myExtElCS.Perform(C.Circle(), myS->Cylinder());
230 case GeomAbs_Hyperbola:
232 if(myCtype == GeomAbs_Hyperbola && myStype == GeomAbs_Plane) {
233 // Modified by skv - Thu Jul 7 12:29:34 2005 OCC9134 End
234 myExtElCS.Perform(C.Hyperbola(), myS->Plane());
240 Extrema_GenExtCS Ext;
241 Ext.Initialize(*myS, NbU, NbV, mytolS);
242 if(myCtype == GeomAbs_Hyperbola) {
243 Standard_Real tmin = Max(-20., C.FirstParameter());
244 Standard_Real tmax = Min(20., C.LastParameter());
245 Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
248 if(myCtype == GeomAbs_Circle && NbT < 13) {
251 Ext.Perform(C, NbT, mytolC);
254 myDone = Ext.IsDone();
256 Standard_Integer NbExt = Ext.NbExt();
260 for (i = 1; i <= NbExt; i++) {
261 PC = Ext.PointOnCurve(i);
262 PS = Ext.PointOnSurface(i);
266 T = ElCLib::InPeriod(T, myucinf, myucinf+C.Period());
267 if (myS->IsUPeriodic())
268 U = ElCLib::InPeriod(U, myuinf, myuinf+myS->UPeriod());
269 if (myS->IsVPeriodic())
270 V = ElCLib::InPeriod(V, myvinf, myvinf+myS->VPeriod());
272 if ((myucinf-T) <= mytolC && (T-myucsup) <= mytolC &&
273 (myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
274 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS) {
275 mySqDist.Append(Ext.SquareDistance(i));
276 PC.SetValues(T, PC.Value());
278 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
287 myDone = myExtElCS.IsDone();
289 myIsPar = myExtElCS.IsParallel();
291 mySqDist.Append(myExtElCS.SquareDistance(1));
294 Standard_Integer NbExt = myExtElCS.NbExt();
296 for (i = 1; i <= NbExt; i++) {
299 myExtElCS.Points(i, PC, PS);
300 Standard_Real Ucurve = PC.Parameter();
303 if((myStype == GeomAbs_Sphere) || (myStype == GeomAbs_Cylinder)) {
304 U = ElCLib::InPeriod(U, myuinf, myuinf+2.*PI);
307 if ((myuinf-U) <= mytolS && (U-myusup) <= mytolS &&
308 (myvinf-V) <= mytolS && (V-myvsup) <= mytolS &&
309 (myucinf-Ucurve) <= mytolC && (Ucurve-myucsup) <= mytolC) {
310 mySqDist.Append(myExtElCS.SquareDistance(i));
311 myPOnS.Append(Extrema_POnSurf(U, V, PS.Value()));
321 Standard_Boolean Extrema_ExtCS::IsDone() const
326 Standard_Boolean Extrema_ExtCS::IsParallel() const
332 Standard_Real Extrema_ExtCS::SquareDistance(const Standard_Integer N) const
334 if(!myDone) StdFail_NotDone::Raise();
335 if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
336 if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
337 return mySqDist.Value(N);
341 Standard_Integer Extrema_ExtCS::NbExt() const
343 if(!myDone) StdFail_NotDone::Raise();
344 return mySqDist.Length();
349 void Extrema_ExtCS::Points(const Standard_Integer N,
351 Extrema_POnSurf& P2) const
353 if(!myDone) StdFail_NotDone::Raise();
354 P1 = myPOnC.Value(N);
355 P2 = myPOnS.Value(N);