mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
Macro NO_CXX_EXCEPTION was removed from code. Method Raise() was replaced by explicit throw statement. Method Standard_Failure::Caught() was replaced by normal C++mechanism of exception transfer. Method Standard_Failure::Caught() is deprecated now. Eliminated empty constructors. Updated samples. Eliminate empty method ChangeValue from NCollection_Map class. Removed not operable methods from NCollection classes.
383 lines
11 KiB
Plaintext
383 lines
11 KiB
Plaintext
// Created on: 1993-12-14
|
|
// Created by: Christophe MARION
|
|
// Copyright (c) 1993-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
// 05-Jun-00 : hla : meme type de corr. que xab : dans la methode "Perform",
|
|
// suppression du test mal a propos "myintuinf > myintusup" avec
|
|
// "return" a la suite.
|
|
// 05-Sep-95 : xab : correction d'un probleme de determination d'intervalle
|
|
// de recherche
|
|
|
|
#include Extrema_ELPC_hxx
|
|
#include ThePOnC_hxx
|
|
#include ThePoint_hxx
|
|
#include TheVector_hxx
|
|
#include <StdFail_NotDone.hxx>
|
|
#include <Standard_DomainError.hxx>
|
|
#include <GeomAbs_CurveType.hxx>
|
|
#include <Precision.hxx>
|
|
#include <TColStd_Array1OfReal.hxx>
|
|
|
|
|
|
//=======================================================================
|
|
//function : Extrema_GLocateExtPC
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Extrema_GLocateExtPC::Extrema_GLocateExtPC() { }
|
|
|
|
|
|
//=======================================================================
|
|
//function : Extrema_GLocateExtPC
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
|
|
const TheCurve& C,
|
|
const Standard_Real U0,
|
|
const Standard_Real TolF)
|
|
{
|
|
Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF);
|
|
Perform(P, U0);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Extrema_GLocateExtPC
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint& P,
|
|
const TheCurve& C,
|
|
const Standard_Real U0,
|
|
const Standard_Real Umin,
|
|
const Standard_Real Usup,
|
|
const Standard_Real TolF)
|
|
{
|
|
Initialize(C, Umin, Usup, TolF);
|
|
Perform(P, U0);
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : Initialize
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void Extrema_GLocateExtPC::Initialize(const TheCurve& C,
|
|
const Standard_Real Umin,
|
|
const Standard_Real Usup,
|
|
const Standard_Real TolF)
|
|
{
|
|
myC = (Standard_Address)&C;
|
|
mytol = TolF;
|
|
myumin = Umin;
|
|
myusup = Usup;
|
|
type = TheCurveTool::GetType(C);
|
|
Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion());
|
|
if ((type == GeomAbs_BSplineCurve) ||
|
|
(type == GeomAbs_BezierCurve) ||
|
|
(type == GeomAbs_OffsetCurve) ||
|
|
(type == GeomAbs_OtherCurve))
|
|
{
|
|
myLocExtPC.Initialize(C, Umin, Usup, tolu);
|
|
}
|
|
else {
|
|
myExtremPC.Initialize(C, Umin, Usup, tolu);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : Perform
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void Extrema_GLocateExtPC::Perform(const ThePoint& P,
|
|
const Standard_Real U0)
|
|
{
|
|
Standard_Integer i, i1, i2, inter;
|
|
Standard_Real Par, valU, valU2 = RealLast(),
|
|
local_u0 ;
|
|
Standard_Real myintuinf=0, myintusup=0;
|
|
local_u0 = U0 ;
|
|
switch(type)
|
|
{
|
|
case GeomAbs_OtherCurve:
|
|
case GeomAbs_OffsetCurve:
|
|
case GeomAbs_BSplineCurve:
|
|
{
|
|
// La recherche de l extremum est faite intervalle continu C2 par
|
|
// intervalle continu C2 de la courbe
|
|
Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2);
|
|
TColStd_Array1OfReal theInter(1, n+1);
|
|
TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2);
|
|
//
|
|
// be gentle with the caller
|
|
//
|
|
if (local_u0 < myumin) {
|
|
local_u0 = myumin ;
|
|
}
|
|
else if (local_u0 > myusup) {
|
|
local_u0 = myusup ;
|
|
}
|
|
// Recherche de l intervalle ou se trouve U0
|
|
Standard_Boolean found = Standard_False;
|
|
inter = 1;
|
|
while (!found && inter <= n) {
|
|
// Intervalle commun a l intervalle C2 courant de la courbe et a
|
|
// l intervalle total de recherche de l'extremum (hla : au cas ou
|
|
// myintuinf > myintusup, c est que les 2 intervalles ne s intersectent
|
|
// pas, mais il n'y avait aucune raison de sortir en "return")
|
|
myintuinf = Max(theInter(inter), myumin);
|
|
myintusup = Min(theInter(inter+1), myusup);
|
|
if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True;
|
|
inter++;
|
|
}
|
|
|
|
if( found ) inter--; //IFV 16.06.00 - inter is increased after found!
|
|
|
|
// Essai sur l intervalle trouve
|
|
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
|
|
myintusup, mytol);
|
|
myLocExtPC.Perform(P, local_u0);
|
|
myDone = myLocExtPC.IsDone();
|
|
if (myDone) {
|
|
mypp = myLocExtPC.Point();
|
|
myismin = myLocExtPC.IsMin();
|
|
mydist2 = myLocExtPC.SquareDistance();
|
|
}
|
|
else {
|
|
Standard_Integer k = 1;
|
|
// Essai sur les intervalles alentours:
|
|
i1 = inter;
|
|
i2 = inter;
|
|
Standard_Real s1inf, s2inf, s1sup, s2sup;
|
|
ThePoint P1;
|
|
TheVector V1;
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
|
|
s2inf = (TheVector(P, P1)*V1);
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
|
|
s1sup = (TheVector(P, P1)*V1);
|
|
|
|
|
|
while (!myDone && (i2 > 0) && (i1 <= n))
|
|
{
|
|
i1 = inter + k;
|
|
i2 = inter - k;
|
|
if (i1 <= n)
|
|
{
|
|
myintuinf = Max(theInter(i1), myumin);
|
|
myintusup = Min(theInter(i1+1), myusup);
|
|
if (myintuinf < myintusup)
|
|
{
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
|
|
s2sup = (TheVector(P, P1)*V1);
|
|
if(Precision::IsInfinite(s2sup) || Precision::IsInfinite(s1sup))
|
|
{
|
|
break;
|
|
}
|
|
if (s1sup*s2sup <= RealEpsilon())
|
|
{
|
|
// extremum:
|
|
myDone = Standard_True;
|
|
mypp.SetValues(myintuinf, P1);
|
|
myismin = (s1sup <= 0.0);
|
|
mydist2 = P.SquareDistance(P1);
|
|
break;
|
|
}
|
|
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
|
|
s1sup = (TheVector(P, P1)*V1);
|
|
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
|
|
myintusup, mytol);
|
|
myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
|
|
myDone = myLocExtPC.IsDone();
|
|
if (myDone) {
|
|
mypp = myLocExtPC.Point();
|
|
myismin = myLocExtPC.IsMin();
|
|
mydist2 = myLocExtPC.SquareDistance();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (i2 > 0)
|
|
{
|
|
myintuinf = Max(theInter(i2), myumin);
|
|
myintusup = Min(theInter(i2+1), myusup);
|
|
if (myintuinf < myintusup)
|
|
{
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
|
|
s1inf = (TheVector(P, P1)*V1);
|
|
if(Precision::IsInfinite(s2inf) || Precision::IsInfinite(s1inf))
|
|
{
|
|
break;
|
|
}
|
|
if (s1inf*s2inf <= RealEpsilon())
|
|
{
|
|
// extremum:
|
|
myDone = Standard_True;
|
|
mypp.SetValues(myintusup, P1);
|
|
myismin = (s1inf <= 0.0);
|
|
mydist2 = P.SquareDistance(P1);
|
|
break;
|
|
}
|
|
|
|
TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
|
|
s2inf = (TheVector(P, P1)*V1);
|
|
myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf,
|
|
myintusup, mytol);
|
|
myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
|
|
myDone = myLocExtPC.IsDone();
|
|
|
|
if (myDone)
|
|
{
|
|
mypp = myLocExtPC.Point();
|
|
myismin = myLocExtPC.IsMin();
|
|
mydist2 = myLocExtPC.SquareDistance();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case GeomAbs_BezierCurve:
|
|
{
|
|
myLocExtPC.Perform(P, U0);
|
|
myDone = myLocExtPC.IsDone();
|
|
}
|
|
|
|
break;
|
|
default:
|
|
{
|
|
myExtremPC.Perform(P);
|
|
numberext = 0;
|
|
if (myExtremPC.IsDone())
|
|
{
|
|
for (i = 1; i <= myExtremPC.NbExt(); i++)
|
|
{
|
|
Par = myExtremPC.Point(i).Parameter();
|
|
valU = Abs(Par - U0);
|
|
if (valU <= valU2)
|
|
{
|
|
valU2 = valU;
|
|
numberext = i;
|
|
myDone = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numberext == 0)
|
|
myDone = Standard_False;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsDone
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean Extrema_GLocateExtPC::IsDone () const
|
|
{
|
|
return myDone;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Value
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Real Extrema_GLocateExtPC::SquareDistance () const
|
|
{
|
|
if (!myDone) { throw StdFail_NotDone(); }
|
|
Standard_Real d=0;
|
|
if ((type == GeomAbs_BezierCurve)) {
|
|
d = myLocExtPC.SquareDistance();
|
|
}
|
|
else if(type == GeomAbs_BSplineCurve ||
|
|
type == GeomAbs_OffsetCurve ||
|
|
type == GeomAbs_OtherCurve) {
|
|
d = mydist2;
|
|
}
|
|
else {
|
|
if (numberext != 0) {
|
|
d = myExtremPC.SquareDistance(numberext);
|
|
}
|
|
}
|
|
return d;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : IsMin
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean Extrema_GLocateExtPC::IsMin () const
|
|
{
|
|
if (!myDone) { throw StdFail_NotDone(); }
|
|
Standard_Boolean b=0;
|
|
if ((type == GeomAbs_BezierCurve)) {
|
|
b = myLocExtPC.IsMin();
|
|
}
|
|
else if(type == GeomAbs_BSplineCurve ||
|
|
type == GeomAbs_OffsetCurve ||
|
|
type == GeomAbs_OtherCurve) {
|
|
b = myismin;
|
|
}
|
|
else {
|
|
if (numberext != 0) {
|
|
b = myExtremPC.IsMin(numberext);
|
|
}
|
|
}
|
|
return b;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : Point
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
const ThePOnC & Extrema_GLocateExtPC::Point () const
|
|
{
|
|
if (!myDone) { throw StdFail_NotDone(); }
|
|
if (type == GeomAbs_BezierCurve) {
|
|
return myLocExtPC.Point();
|
|
}
|
|
else if(type == GeomAbs_BSplineCurve ||
|
|
type == GeomAbs_OffsetCurve ||
|
|
type == GeomAbs_OtherCurve) {
|
|
return mypp;
|
|
}
|
|
return myExtremPC.Point(numberext);
|
|
}
|