1 // Created on: 1995-07-18
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Extrema_GenExtCS.ixx>
19 #include <math_Vector.hxx>
20 #include <math_FunctionSetRoot.hxx>
21 #include <Precision.hxx>
23 #include <Geom_Line.hxx>
24 #include <Adaptor3d_HCurve.hxx>
25 #include <GeomAdaptor_Curve.hxx>
27 #include <Extrema_ExtCC.hxx>
28 #include <Extrema_POnCurv.hxx>
29 #include <Extrema_ExtPS.hxx>
31 //=======================================================================
32 //function : Extrema_GenExtCS
34 //=======================================================================
36 Extrema_GenExtCS::Extrema_GenExtCS()
38 myDone = Standard_False;
39 myInit = Standard_False;
42 //=======================================================================
43 //function : Extrema_GenExtCS
45 //=======================================================================
47 Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C,
48 const Adaptor3d_Surface& S,
49 const Standard_Integer NbT,
50 const Standard_Integer NbU,
51 const Standard_Integer NbV,
52 const Standard_Real Tol1,
53 const Standard_Real Tol2)
55 Initialize(S, NbU, NbV, Tol2);
56 Perform(C, NbT, Tol1);
59 //=======================================================================
60 //function : Extrema_GenExtCS
62 //=======================================================================
64 Extrema_GenExtCS::Extrema_GenExtCS(const Adaptor3d_Curve& C,
65 const Adaptor3d_Surface& S,
66 const Standard_Integer NbT,
67 const Standard_Integer NbU,
68 const Standard_Integer NbV,
69 const Standard_Real tmin,
70 const Standard_Real tsup,
71 const Standard_Real Umin,
72 const Standard_Real Usup,
73 const Standard_Real Vmin,
74 const Standard_Real Vsup,
75 const Standard_Real Tol1,
76 const Standard_Real Tol2)
78 Initialize(S, NbU, NbV, Umin,Usup,Vmin,Vsup,Tol2);
79 Perform(C, NbT, tmin, tsup, Tol1);
82 //=======================================================================
83 //function : Initialize
85 //=======================================================================
87 void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S,
88 const Standard_Integer NbU,
89 const Standard_Integer NbV,
90 const Standard_Real Tol2)
92 myumin = S.FirstUParameter();
93 myusup = S.LastUParameter();
94 myvmin = S.FirstVParameter();
95 myvsup = S.LastVParameter();
96 Initialize(S,NbU,NbV,myumin,myusup,myvmin,myvsup,Tol2);
99 //=======================================================================
100 //function : Initialize
102 //=======================================================================
104 void Extrema_GenExtCS::Initialize(const Adaptor3d_Surface& S,
105 const Standard_Integer NbU,
106 const Standard_Integer NbV,
107 const Standard_Real Umin,
108 const Standard_Real Usup,
109 const Standard_Real Vmin,
110 const Standard_Real Vsup,
111 const Standard_Real Tol2)
113 myS = (Adaptor3d_SurfacePtr)&S;
123 //=======================================================================
126 //=======================================================================
128 void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C,
129 const Standard_Integer NbT,
130 const Standard_Real Tol1)
132 mytmin = C.FirstParameter();
133 mytsup = C.LastParameter();
134 Perform(C, NbT, mytmin, mytsup,Tol1);
137 //=======================================================================
140 //=======================================================================
142 void Extrema_GenExtCS::Perform(const Adaptor3d_Curve& C,
143 const Standard_Integer NbT,
144 const Standard_Real tmin,
145 const Standard_Real tsup,
146 const Standard_Real Tol1)
148 myDone = Standard_False;
149 myF.Initialize(C,*myS);
154 // Modif de lvt pour trimer la surface non pas aux infinis mais a +/- 10000
156 Standard_Real trimusup = myusup, trimumin = myumin,trimvsup = myvsup,trimvmin = myvmin;
157 if (Precision::IsInfinite(trimusup)){
160 if (Precision::IsInfinite(trimvsup)){
163 if (Precision::IsInfinite(trimumin)){
166 if (Precision::IsInfinite(trimvmin)){
170 math_Vector Tol(1, 3);
174 math_Vector UV(1,3), UVinf(1,3), UVsup(1,3);
182 // 18/02/02 akm vvv : (OCC163) bad extremas - extrusion surface versus the line.
183 // Try to preset the initial solution as extrema between
184 // extrusion direction and the curve.
185 if (myS->GetType() == GeomAbs_SurfaceOfExtrusion)
187 gp_Dir aDir = myS->Direction();
188 Handle(Adaptor3d_HCurve) aCurve = myS->BasisCurve();
189 Standard_Real dfUFirst = aCurve->FirstParameter();
190 // Create iso line of U=U0
191 GeomAdaptor_Curve anAx(new Geom_Line(aCurve->Value(dfUFirst), aDir),
193 Extrema_ExtCC aLocator(C, anAx);
194 if (aLocator.IsDone() && aLocator.NbExt()>0)
196 Standard_Integer iExt;
197 // Try to find all extremas
198 Extrema_POnCurv aP1, aP2;
199 for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
201 aLocator.Points (iExt, aP1, aP2);
202 // Parameter on curve
203 UV(1) = aP1.Parameter();
204 // To find parameters on surf, try ExtPS
205 Extrema_ExtPS aPreciser (aP1.Value(), *myS, mytol2, mytol2);
206 if (aPreciser.IsDone())
208 // Managed to find extremas between point and surface
209 Standard_Integer iPExt;
210 for (iPExt=1; iPExt<=aPreciser.NbExt(); iPExt++)
212 aPreciser.Point(iPExt).Parameter(UV(2),UV(3));
213 math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup);
218 // Failed... try the point on iso line
220 UV(3) = aP2.Parameter();
221 math_FunctionSetRoot S1 (myF,UV,Tol,UVinf,UVsup);
223 } // for (iExt=1; iExt<=aLocator.NbExt(); iExt++)
224 } // if (aLocator.IsDone() && aLocator.NbExt()>0)
225 } // if (myS.Type() == GeomAbs_ExtrusionSurface)
228 Standard_Real aCUAdd = (mytsup - mytmin) / mytsample;
229 Standard_Real aSUAdd = (myusup - myumin) / myusample;
230 Standard_Real aSVAdd = (myvsup - myvmin) / myvsample;
231 Standard_Real tres = C.Resolution(1.);
232 Standard_Real ures = myS->UResolution(1.);
233 Standard_Real vres = myS->VResolution(1.);
234 tres = aCUAdd / tres;
235 ures = aSUAdd / ures;
236 vres = aSVAdd / vres;
237 Standard_Real minres = Min(tres, Min(ures, vres));
238 Standard_Real factor = 5.;
239 Standard_Integer maxnbs = 50;
241 if(minres > Epsilon(1.))
245 Standard_Real rsample = mytsample * tres / minres;
252 mytsample = RealToInt(rsample);
254 aCUAdd = (mytsup - mytmin) / mytsample;
258 Standard_Real rsample = myusample * ures / minres;
265 myusample = RealToInt(rsample);
267 aSUAdd = (myusup - myumin) / myusample;
271 Standard_Real rsample = myvsample * vres / minres;
278 myvsample = RealToInt(rsample);
280 aSVAdd = (myvsup - myvmin) / myvsample;
284 TColgp_HArray1OfPnt aCPs(1, mytsample);
285 TColgp_HArray2OfPnt aSPs(1, myusample, 1, myvsample);
286 Standard_Integer aRestIterCount = 3;
287 // The value is calculated by the bug CR23830.
288 Standard_Integer aCUDen = 2, aSUDen = 2, aSVDen = 2;
289 Standard_Boolean anAreAvSqsInited = Standard_False;
290 Standard_Real aCUSq = 0, aSUSq = 0, aSVSq = 0;
291 while (aRestIterCount--)
293 Standard_Real aMinCU = 0., aMinSU = 0., aMinSV = 0., aMaxCU = 0., aMaxSU = 0., aMaxSV = 0.;
294 Standard_Real aMinSqDist = DBL_MAX, aMaxSqDist = -DBL_MAX;
295 for (Standard_Integer aSUNom = 1; aSUNom < aSUDen; aSUNom += 2)
297 Standard_Real aSU0 = myumin + (aSUNom * aSUAdd) / aSUDen;
298 for (Standard_Integer aSVNom = 1; aSVNom < aSVDen; aSVNom += 2)
300 Standard_Real aSV0 = myvmin + (aSVNom * aSVAdd) / aSVDen;
301 for (Standard_Integer aCUNom = 1; aCUNom < aCUDen; aCUNom += 2)
303 Standard_Real aCU0 = mytmin + (aCUNom * aCUAdd) / aCUDen;
304 Standard_Real aCU = aCU0;
305 for (Standard_Integer aCUI = 1; aCUI <= mytsample;
306 aCUI++, aCU += aCUAdd)
308 aCPs.SetValue(aCUI, C.Value(aCU));
312 Standard_Real aSU = aSU0;
313 for (Standard_Integer aSUI = 1; aSUI <= myusample;
314 aSUI++, aSU += aSUAdd)
316 Standard_Real aSV = aSV0;
317 for (Standard_Integer aSVI = 1; aSVI <= myvsample;
318 aSVI++, aSV += aSVAdd)
320 gp_Pnt aSP = myS->Value(aSU, aSV);
321 aSPs.ChangeValue(aSUI, aSVI) = aSP;
322 Standard_Real aCU = aCU0;
323 for (Standard_Integer aCUI = 1; aCUI <= mytsample;
324 aCUI++, aCU += aCUAdd)
326 Standard_Real aSqDist = aSP.SquareDistance(aCPs.Value(aCUI));
327 if (aSqDist < aMinSqDist)
329 aMinSqDist = aSqDist;
334 if (aMaxSqDist < aSqDist)
336 aMaxSqDist = aSqDist;
347 // Find min approximation.
351 math_FunctionSetRoot anA(myF, UV, Tol, UVinf, UVsup, 100, aRestIterCount);
352 // Find max approximation.
353 if (!anA.IsDivergent() || !aRestIterCount)
358 math_FunctionSetRoot aFunc(myF, UV, Tol, UVinf, UVsup);
362 if (!anAreAvSqsInited)
364 anAreAvSqsInited = Standard_True;
366 const gp_Pnt * aCP1 = &aCPs.Value(1);
367 for (Standard_Integer aCUI = 2; aCUI <= mytsample; aCUI++)
369 const gp_Pnt & aCP2 = aCPs.Value(aCUI);
370 aCUSq += aCP1->SquareDistance(aCP2);
373 aCUSq /= mytsample - 1;
375 for (Standard_Integer aSVI = 1; aSVI <= myvsample; aSVI++)
377 const gp_Pnt * aSP1 = &aSPs.Value(1, aSVI);
378 for (Standard_Integer aSUI = 2; aSUI <= myusample; aSUI++)
380 const gp_Pnt & aSP2 = aSPs.Value(aSUI, aSVI);
381 aSUSq += aSP1->SquareDistance(aSP2);
385 aSUSq /= myvsample * (myusample - 1);
387 for (Standard_Integer aSUI = 1; aSUI <= myusample; aSUI++)
389 const gp_Pnt * aSP1 = &aSPs.Value(aSUI, 1);
390 for (Standard_Integer aSVI = 2; aSVI <= myvsample; aSVI++)
392 const gp_Pnt & aSP2 = aSPs.Value(aSUI, aSVI);
393 aSVSq += aSP1->SquareDistance(aSP2);
397 aSVSq /= myusample * (myvsample - 1);
400 if ((aSUSq <= aCUSq) && (aSVSq <= aCUSq))
405 else if ((aCUSq <= aSUSq) && (aSVSq <= aSUSq))
418 myDone = Standard_True;
421 //=======================================================================
424 //=======================================================================
426 Standard_Boolean Extrema_GenExtCS::IsDone() const
431 //=======================================================================
434 //=======================================================================
436 Standard_Integer Extrema_GenExtCS::NbExt() const
438 if (!IsDone()) { StdFail_NotDone::Raise(); }
442 //=======================================================================
445 //=======================================================================
447 Standard_Real Extrema_GenExtCS::SquareDistance(const Standard_Integer N) const
449 if (!IsDone()) { StdFail_NotDone::Raise(); }
450 return myF.SquareDistance(N);
453 //=======================================================================
454 //function : PointOnCurve
456 //=======================================================================
458 const Extrema_POnCurv& Extrema_GenExtCS::PointOnCurve(const Standard_Integer N) const
460 if (!IsDone()) { StdFail_NotDone::Raise(); }
461 return myF.PointOnCurve(N);
464 //=======================================================================
465 //function : PointOnSurface
467 //=======================================================================
469 const Extrema_POnSurf& Extrema_GenExtCS::PointOnSurface(const Standard_Integer N) const
471 if (!IsDone()) { StdFail_NotDone::Raise(); }
472 return myF.PointOnSurface(N);
475 //=======================================================================
476 //function : BidonSurface
478 //=======================================================================
480 Adaptor3d_SurfacePtr Extrema_GenExtCS::BidonSurface() const
482 return (Adaptor3d_SurfacePtr)0L;
485 //=======================================================================
486 //function : BidonCurve
488 //=======================================================================
490 Adaptor3d_CurvePtr Extrema_GenExtCS::BidonCurve() const
492 return (Adaptor3d_CurvePtr)0L;