1 // File: Extrema_ExtPExtS.cdl
2 // Created: Thu Sep 16 16:53:38 1999
3 // Author: Edward AGAPOV
4 // <eap@strelox.nnov.matra-dtv.fr>
5 // Copyright: Matra Datavision 1999
7 #include <Standard_NotImplemented.hxx>
8 #include <Standard_OutOfRange.hxx>
9 #include <StdFail_NotDone.hxx>
10 #include <Adaptor3d_HCurve.hxx>
12 #include <Extrema_ExtPElC.hxx>
13 #include <Extrema_ExtPExtS.hxx>
14 #include <Extrema_POnCurv.hxx>
15 #include <Extrema_POnSurf.hxx>
16 #include <Precision.hxx>
24 #include <math_FunctionSetRoot.hxx>
25 #include <math_Vector.hxx>
26 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
28 static gp_Ax2 GetPosition (const Handle(Adaptor3d_HCurve)& C);
30 static void PerformExtPElC (Extrema_ExtPElC& E,
32 const Handle(Adaptor3d_HCurve)& C,
33 const Standard_Real Tol);
35 static Standard_Boolean
36 IsCaseAnalyticallyComputable (const GeomAbs_CurveType& theType,
37 const gp_Ax2& theCurvePos,
38 const gp_Dir& theSurfaceDirection) ;
40 static gp_Pnt GetValue(const Standard_Real U,
41 const Handle(Adaptor3d_HCurve)& C);
42 //=======================================================================
44 //purpose : Returns the projection of a point <Point> on a plane
45 // <ThePlane> along a direction <TheDir>.
46 //=======================================================================
47 static gp_Pnt ProjectPnt(const gp_Ax2& ThePlane,
51 gp_Vec PO(Point,ThePlane.Location());
52 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
53 Alpha /= TheDir * ThePlane.Direction();
55 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
59 //=======================================================================
60 //function : IsOriginalPnt
62 //=======================================================================
64 static Standard_Boolean IsOriginalPnt (const gp_Pnt& P,
65 const Extrema_POnSurf* Points,
66 const Standard_Integer NbPoints)
68 for (Standard_Integer i=1; i<=NbPoints; i++) {
69 if (Points[i-1].Value().IsEqual(P, Precision::Confusion())) {
70 return Standard_False;
76 //=======================================================================
77 //function : MakePreciser
79 //=======================================================================
81 void Extrema_ExtPExtS::MakePreciser (Standard_Real& U,
83 const Standard_Boolean isMin,
84 const gp_Ax2& OrtogSection) const
88 } else if (U<myuinf) {
92 Standard_Real step = (myusup - myuinf) / 30, D2e, D2next ,D2prev;
94 Pe = ProjectPnt (OrtogSection, myDirection, GetValue(U,myC)),
95 Pprev = ProjectPnt (OrtogSection, myDirection, GetValue(U-step, myC)),
96 Pnext = ProjectPnt (OrtogSection, myDirection, GetValue(U+step, myC));
97 D2e = P.SquareDistance(Pe),
98 D2next = P.SquareDistance(Pnext),
99 D2prev = P.SquareDistance(Pprev);
100 Standard_Boolean notFound;
102 notFound = (D2e > D2prev || D2e > D2next);
104 notFound = (D2e < D2prev || D2e < D2next);
106 if (notFound && (D2e < D2next && isMin)) {
123 Pnext = ProjectPnt (OrtogSection, myDirection, GetValue(U+step, myC));
124 D2next = P.SquareDistance(Pnext);
126 notFound = D2e > D2next;
128 notFound = D2e < D2next;
132 //=============================================================================
134 Extrema_ExtPExtS::Extrema_ExtPExtS ()
136 myDone = Standard_False;
139 //=============================================================================
141 Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt& P,
142 const Adaptor3d_SurfaceOfLinearExtrusion& S,
143 const Standard_Real Umin,
144 const Standard_Real Usup,
145 const Standard_Real Vmin,
146 const Standard_Real Vsup,
147 const Standard_Real TolU,
148 const Standard_Real TolV)
151 Umin, Usup, Vmin, Vsup,
155 //=============================================================================
157 Extrema_ExtPExtS::Extrema_ExtPExtS (const gp_Pnt& P,
158 const Adaptor3d_SurfaceOfLinearExtrusion& S,
159 const Standard_Real TolU,
160 const Standard_Real TolV)
163 S.FirstUParameter(), S.LastUParameter(),
164 S.FirstVParameter(), S.LastVParameter(),
168 //=======================================================================
169 //function : Initialize
171 //=======================================================================
173 void Extrema_ExtPExtS::Initialize(const Adaptor3d_SurfaceOfLinearExtrusion& S,
174 const Standard_Real Uinf,
175 const Standard_Real Usup,
176 const Standard_Real Vinf,
177 const Standard_Real Vsup,
178 const Standard_Real TolU,
179 const Standard_Real TolV)
189 Handle(Adaptor3d_HCurve) anACurve = S.BasisCurve();
193 myPosition = GetPosition(myC);
194 myDirection = S.Direction();
195 myIsAnalyticallyComputable = //Standard_False;
196 IsCaseAnalyticallyComputable (myC->GetType(),myPosition,myDirection);
198 if (!myIsAnalyticallyComputable)
200 myExtPS.Initialize(S, 32, 32,
201 Uinf, Usup, Vinf, Vsup,
206 //=======================================================================
209 //=======================================================================
211 void Extrema_ExtPExtS::Perform (const gp_Pnt& P)
213 myDone = Standard_False;
216 if (!myIsAnalyticallyComputable) {
218 myDone = myExtPS.IsDone();
219 // modified by NIZHNY-EAP Wed Nov 17 12:59:08 1999 ___BEGIN___
220 myNbExt = myExtPS.NbExt();
221 // modified by NIZHNY-EAP Wed Nov 17 12:59:09 1999 ___END___
225 gp_Pnt Pe, Pp = ProjectPnt(myPosition,myDirection,P);
226 Extrema_ExtPElC anExt;
227 PerformExtPElC(anExt, Pp, myC, mytolu);
228 if (!anExt.IsDone()) return;
230 gp_Ax2 anOrtogSection (P, myDirection);
235 myDirection.IsParallel(myPosition.Direction(),Precision::Angular());
236 Standard_Integer i, aNbExt = anExt.NbExt();
237 math_Vector UV(1,2), Tol(1,2), UVinf(1,2), UVsup(1,2);
238 Tol(1) = mytolu; Tol(2) = mytolv;
239 UVinf(1) = myuinf; UVinf(2) = myvinf;
240 UVsup(1) = myusup; UVsup(2) = myvsup;
243 for (i=1; i<=aNbExt; i++) {
244 Extrema_POnCurv POC=anExt.Point(i);
246 //// modified by jgv, 23.12.2008 for OCC17194 ////
247 if (myC->IsPeriodic())
249 Standard_Real U2 = U;
250 ElCLib::AdjustPeriodic(myuinf, myuinf + 2.*PI, Precision::PConfusion(), U, U2);
252 //////////////////////////////////////////////////
253 gp_Pnt E = POC.Value();
254 Pe = ProjectPnt(anOrtogSection, myDirection, E);
257 V = gp_Vec(E,Pe) * gp_Vec(myDirection);
258 // modified by NIZHNY-MKK Thu Sep 18 14:46:14 2003.BEGIN
259 // myPoint[++myNbExt] = Extrema_POnSurf(U, V, Pe);
260 // myValue[myNbExt] = anExt.Value(i);
261 myPoint[myNbExt] = Extrema_POnSurf(U, V, Pe);
262 mySqDist[myNbExt] = anExt.SquareDistance(i);
264 // modified by NIZHNY-MKK Thu Sep 18 14:46:18 2003.END
268 isMin = anExt.IsMin(i);//( Pp.Distance(GetValue(U+10,myC)) > anExt.Value(i) );
270 MakePreciser(U, P, isMin, anOrtogSection);
271 E = GetValue(U, myC);
272 Pe = ProjectPnt (anOrtogSection, myDirection, E),
273 V = gp_Vec(E,Pe) * gp_Vec(myDirection);
274 UV(1) = U; UV(2) = V;
275 math_FunctionSetRoot aFSR (myF,UV,Tol,UVinf,UVsup);
276 // for (Standard_Integer k=1 ; k <= myF.NbExt();
278 for ( k=1 ; k <= myF.NbExt(); k++) {
279 if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) {
280 // modified by NIZHNY-MKK Thu Sep 18 14:46:41 2003.BEGIN
281 // myPoint[++myNbExt] = myF.Point(k);
282 // myValue[myNbExt] = myF.Value(k);
283 myPoint[myNbExt] = myF.Point(k);
284 mySqDist[myNbExt] = myF.SquareDistance(k);
286 // modified by NIZHNY-MKK Thu Sep 18 14:46:43 2003.END
289 // try symmetric point
291 MakePreciser(U, P, isMin, anOrtogSection);
292 E = GetValue(U, myC);
293 Pe = ProjectPnt (anOrtogSection, myDirection, E),
294 V = gp_Vec(E,Pe) * gp_Vec(myDirection);
295 UV(1) = U; UV(2) = V;
297 aFSR.Perform (myF,UV,UVinf,UVsup);
299 for (k=1 ; k <= myF.NbExt(); k++) {
300 if (IsOriginalPnt(myF.Point(k).Value(), myPoint, myNbExt)) {
301 // modified by NIZHNY-MKK Thu Sep 18 14:46:59 2003.BEGIN
302 // myPoint[++myNbExt] = myF.Point(k);
303 // myValue[myNbExt] = myF.Value(k);
304 myPoint[myNbExt] = myF.Point(k);
305 mySqDist[myNbExt] = myF.SquareDistance(k);
307 // modified by NIZHNY-MKK Thu Sep 18 14:47:04 2003.END
312 myDone = Standard_True;
316 //=============================================================================
318 Standard_Boolean Extrema_ExtPExtS::IsDone () const { return myDone; }
319 //=============================================================================
321 Standard_Integer Extrema_ExtPExtS::NbExt () const
323 if (!IsDone()) { StdFail_NotDone::Raise(); }
324 if (myIsAnalyticallyComputable)
327 return myExtPS.NbExt();
329 //=============================================================================
331 Standard_Real Extrema_ExtPExtS::SquareDistance (const Standard_Integer N) const
333 if (!IsDone()) { StdFail_NotDone::Raise(); }
334 if ((N < 1) || (N > myNbExt)) { Standard_OutOfRange::Raise(); }
335 if (myIsAnalyticallyComputable)
336 // modified by NIZHNY-MKK Thu Sep 18 14:48:39 2003.BEGIN
337 // return myValue[N];
338 return mySqDist[N-1];
339 // modified by NIZHNY-MKK Thu Sep 18 14:48:42 2003.END
341 return myExtPS.SquareDistance(N);
343 //=============================================================================
345 Extrema_POnSurf Extrema_ExtPExtS::Point (const Standard_Integer N) const
347 if (!IsDone()) { StdFail_NotDone::Raise(); }
348 if ((N < 1) || (N > myNbExt)) { Standard_OutOfRange::Raise(); }
349 if (myIsAnalyticallyComputable) {
350 // modified by NIZHNY-MKK Thu Sep 18 14:47:40 2003.BEGIN
351 // return myPoint[N];
354 // modified by NIZHNY-MKK Thu Sep 18 14:47:43 2003.END
356 return myExtPS.Point(N);
358 //=============================================================================
361 static gp_Ax2 GetPosition (const Handle(Adaptor3d_HCurve)& C)
363 switch (C->GetType()) {
365 gp_Lin L = C->Line();
366 gp_Pln Pln = gp_Pln(L.Location(), L.Direction());
367 //:abv 30.05.02: OCC - use constructor instead of Set...s() to avoid exception
368 gp_Ax2 Pos ( Pln.Location(), Pln.Position().Direction(), Pln.Position().XDirection() );
369 // Pos.SetAxis(Pln.XAxis());
370 // Pos.SetXDirection(Pln.YAxis().Direction());
371 // Pos.SetYDirection(Pln.Position().Direction());
375 return C->Circle().Position();
376 case GeomAbs_Ellipse:
377 return C->Ellipse().Position();
378 case GeomAbs_Hyperbola:
379 return C->Hyperbola().Position();
380 case GeomAbs_Parabola:
381 return C->Parabola().Position();
386 //=============================================================================
388 static void PerformExtPElC (Extrema_ExtPElC& E,
390 const Handle(Adaptor3d_HCurve)& C,
391 const Standard_Real Tol)
393 switch (C->GetType()) {
394 case GeomAbs_Hyperbola:
395 E.Perform(P, C->Hyperbola(), Tol, -Precision::Infinite(),Precision::Infinite());
398 E.Perform(P, C->Line(), Tol, -Precision::Infinite(),Precision::Infinite());
401 E.Perform(P, C->Circle(), Tol, 0.0, 2.0 * PI);
403 case GeomAbs_Ellipse:
404 E.Perform(P, C->Ellipse(), Tol, 0.0, 2.0 * PI);
406 case GeomAbs_Parabola:
407 E.Perform(P, C->Parabola(), Tol, -Precision::Infinite(),Precision::Infinite());
416 //=======================================================================
417 //function : IsCaseAnalyticallyComputable
419 //=======================================================================
421 static Standard_Boolean IsCaseAnalyticallyComputable
422 (const GeomAbs_CurveType& theType,
423 const gp_Ax2& theCurvePos,
424 const gp_Dir& theSurfaceDirection)
430 case GeomAbs_Ellipse:
431 case GeomAbs_Hyperbola:
432 case GeomAbs_Parabola:
435 return Standard_False;
437 // check if it is a plane
438 if (Abs(theCurvePos.Direction() * theSurfaceDirection) <= gp::Resolution())
439 return Standard_False;
441 return Standard_True;
443 //=======================================================================
444 //function : GetValue
446 //=======================================================================
448 static gp_Pnt GetValue(const Standard_Real U,
449 const Handle(Adaptor3d_HCurve)& C)
451 switch (C->GetType()) {
453 return ElCLib::Value(U, C->Line());
455 return ElCLib::Value(U, C->Circle());
456 case GeomAbs_Ellipse:
457 return ElCLib::Value(U, C->Ellipse());
458 case GeomAbs_Hyperbola:
459 return ElCLib::Value(U, C->Hyperbola());
460 case GeomAbs_Parabola:
461 return ElCLib::Value(U, C->Parabola());
466 //=======================================================================
469 //=======================================================================
471 //static Standard_Real GetU(const gp_Vec& vec,
473 // const Handle(Adaptor3d_HCurve)& C)
475 // switch (C->GetType()) {
476 // case GeomAbs_Line:
477 // return ElCLib::Parameter(C->Line().Translated(vec), P);
478 // case GeomAbs_Circle:
479 // return ElCLib::Parameter(C->Circle().Translated(vec), P);
480 // case GeomAbs_Ellipse:
481 // return ElCLib::Parameter(C->Ellipse().Translated(vec), P);
482 // case GeomAbs_Hyperbola:
483 // return ElCLib::Parameter(C->Hyperbola().Translated(vec), P);
484 // case GeomAbs_Parabola:
485 // return ElCLib::Parameter(C->Parabola().Translated(vec), P);