1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0022848: Optimize projection of points in ShapeAnalysis_Surface

This commit is contained in:
GKA 2012-02-22 12:30:10 +00:00 committed by bugmaster
parent 88c36d5906
commit 6062bf3e4a
4 changed files with 30 additions and 189 deletions

View File

@ -10,8 +10,28 @@
private class FuncExtPS from Extrema
inherits FunctionSetWithDerivatives from math
---Purpose: Function to find the extrema of the
-- distance between a point and a surface.
---Purpose:
--
-- Functional for search of extremum of the distance between point P and
-- surface S, starting from approximate solution (u0, v0).
--
-- The class inherits math_FunctionSetWithDerivatives and thus is intended
-- for use in math_FunctionSetRoot algorithm .
--
-- Denoting derivatives of the surface S(u,v) by u and v, respectively, as
-- Su and Sv, the two functions to be nullified are:
--
-- F1(u,v) = (S - P) * Su
-- F2(u,v) = (S - P) * Sv
--
-- The derivatives of the functional are:
--
-- Duf1(u,v) = Su^2 + (S-P) * Suu;
-- Dvf1(u,v) = Su * Sv + (S-P) * Suv
-- Duf2(u,v) = Sv * Su + (S-P) * Suv = Dvf1
-- Dvf2(u,v) = Sv^2 + (S-P) * Svv
--
-- Here * denotes scalar product, and ^2 is square power.
uses POnSurf from Extrema,
SequenceOfPOnSurf from Extrema,
@ -74,13 +94,6 @@ is
raises OutOfRange;
-- if N < 1 or N > NbExt(me).
-- Modified by skv - Thu Sep 30 15:19:59 2004 OCC593 Begin
HasDegIso(me) returns Boolean from Standard;
-- Modified by skv - Thu Sep 30 15:19:59 2004 OCC593 End
Bidon(me) returns SurfacePtr from Adaptor3d
is static private;
fields
myP : Pnt from gp;
myS : SurfacePtr from Adaptor3d;
@ -93,7 +106,5 @@ fields
myPoint: SequenceOfPOnSurf from Extrema;
myPinit: Boolean;
mySinit: Boolean;
myUIsoIsDeg: Boolean;
myVIsoIsDeg: Boolean;
end FuncExtPS;

View File

@ -13,108 +13,19 @@
#include <Precision.hxx>
#include <GeomAbs_IsoType.hxx>
/*-----------------------------------------------------------------------------
Fonctions permettant de rechercher une distance extremale entre un point P
et une surface S (en partant d'un point approche S(u0,v0)).
Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par
l'algorithme math_FunctionSetRoot.
Si on note Dus et Dvs, les derivees en u et v, les 2 fonctions a annuler sont:
{ F1(u,v) = (S(u,v)-P).Dus(u,v) }
{ F2(u,v) = (S(u,v)-P).Dvs(u,v) }
Si on note Duus, Dvvs et Duvs, les derivees secondes de S, les derivees de F1
et F2 sont egales a:
{ Duf1(u,v) = Dus(u,v).Dus(u,v) + (S(u,v)-P).Duus(u,v)
= ||Dus(u,v)|| ** 2 + (S(u,v)-P).Duus(u,v)
{ Dvf1(u,v) = Dvs(u,v).Dus(u,v) + (S(u,v)-P).Duvs(u,v)
{ Duf2(u,v) = Dus(u,v).Dvs(u,v) + (S(u,v)-P).Duvs(u,v) = dF1v(u,v)
{ Dvf2(u,v) = Dvs(u,v).Dvs(u,v) + (S(u,v)-P).Dvvs(u,v)
= ||Dvs(u,v)|| ** 2 + (S(u,v)-P).Dvvs(u,v)
----------------------------------------------------------------------------*/
// modified by NIZHNY-EAP Wed Nov 21 17:33:05 2001
// -- Dus and Dvs normalized, Df modified accordingly (BUC61043)
//=============================================================================
//------------------------------------------------------------------------------
// This method checks if isocurve is punctual (for details see Geom_OffsetSurface
// and Geom_OsculatingSurface
//-------------------------------------------------------------------------------
static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
const Standard_Real Param,
const GeomAbs_IsoType IT,
const Standard_Real TolMin,
const Standard_Real TolMax)
{
Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
Standard_Boolean Along = Standard_True;
U1 = S.FirstUParameter();
U2 = S.LastUParameter();
V1 = S.FirstVParameter();
V2 = S.LastVParameter();
gp_Vec D1U,D1V;
gp_Pnt P;
Standard_Real Step,D1NormMax;
if (IT == GeomAbs_IsoV)
{
Step = (U2 - U1)/10;
D1NormMax=0.;
for (T=U1;T<=U2;T=T+Step)
{
S.D1(T,Param,P,D1U,D1V);
D1NormMax=Max(D1NormMax,D1U.Magnitude());
}
if (D1NormMax >TolMax || D1NormMax < TolMin )
Along = Standard_False;
}
else
{
Step = (V2 - V1)/10;
D1NormMax=0.;
for (T=V1;T<=V2;T=T+Step)
{
S.D1(Param,T,P,D1U,D1V);
D1NormMax=Max(D1NormMax,D1V.Magnitude());
}
if (D1NormMax >TolMax || D1NormMax < TolMin )
Along = Standard_False;
}
return Along;
}
Extrema_FuncExtPS::Extrema_FuncExtPS ()
{
myPinit = Standard_False;
mySinit = Standard_False;
myUIsoIsDeg = Standard_False;
myVIsoIsDeg = Standard_False;
}
//=============================================================================
Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P,
const Adaptor3d_Surface& S)
{
myP = P;
myS = (Adaptor3d_SurfacePtr)&S;
myUIsoIsDeg = Standard_False;
myVIsoIsDeg = Standard_False;
GeomAbs_SurfaceType aSType = S.GetType();
if(aSType == GeomAbs_BezierSurface ||
aSType == GeomAbs_BSplineSurface) {
Standard_Real u1, u2, v1, v2;
Standard_Real tol = Precision::Confusion();
u1 = S.FirstUParameter();
u2 = S.LastUParameter();
v1 = S.FirstVParameter();
v2 = S.LastVParameter();
myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) ||
IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol);
myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) ||
IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol);
}
myPinit = Standard_True;
mySinit = Standard_True;
}
@ -123,22 +34,7 @@ Extrema_FuncExtPS::Extrema_FuncExtPS (const gp_Pnt& P,
void Extrema_FuncExtPS::Initialize(const Adaptor3d_Surface& S)
{
myS = (Adaptor3d_SurfacePtr)&S;
myUIsoIsDeg = Standard_False;
myVIsoIsDeg = Standard_False;
GeomAbs_SurfaceType aSType = S.GetType();
if(aSType == GeomAbs_BezierSurface ||
aSType == GeomAbs_BSplineSurface) {
Standard_Real u1, u2, v1, v2;
Standard_Real tol = Precision::Confusion();
u1 = S.FirstUParameter();
u2 = S.LastUParameter();
v1 = S.FirstVParameter();
v2 = S.LastVParameter();
myUIsoIsDeg = IsoIsDeg(S, u1, GeomAbs_IsoU, 0., tol) ||
IsoIsDeg(S, u2, GeomAbs_IsoU, 0., tol);
myVIsoIsDeg = IsoIsDeg(S, v1, GeomAbs_IsoV, 0., tol) ||
IsoIsDeg(S, v2, GeomAbs_IsoV, 0., tol);
}
mySinit = Standard_True;
myPoint.Clear();
mySqDist.Clear();
@ -174,19 +70,7 @@ Standard_Boolean Extrema_FuncExtPS::Value (const math_Vector& UV,
myS->D1(myU,myV,myPs,Dus,Dvs);
gp_Vec PPs (myP,myPs);
// EAP
if(myVIsoIsDeg)
{
Standard_Real DusMod = Dus.Magnitude();
if (DusMod>gp::Resolution() && DusMod<1.)
Dus.Multiply(1/DusMod);
}
if (myUIsoIsDeg) {
Standard_Real DvsMod = Dvs.Magnitude();
if (DvsMod>gp::Resolution() && DvsMod<1.)
Dvs.Multiply(1/DvsMod);
}
F(1) = PPs.Dot(Dus);
F(2) = PPs.Dot(Dvs);
@ -213,57 +97,13 @@ Standard_Boolean Extrema_FuncExtPS::Values (const math_Vector& UV,
myS->D2(myU,myV,myPs,Dus,Dvs,Duus,Dvvs,Duvs);
gp_Vec PPs (myP,myPs);
// EAP
// Df(1,1) = Dus.SquareMagnitude() + PPs.Dot(Duus);
// Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
// Df(2,1) = Df(1,2);
// Df(2,2) = Dvs.SquareMagnitude() + PPs.Dot(Dvvs);
// 25/03/02 akm : (OCC231) Further normalization of derivatives for surfaces
// with singularities will hence be performed only when modulus
// becomes less than 1.0. Thus the continuity will be kept,
// and normalization will be switched off 'far' from singularities.
// 1. V iso
Standard_Real DusMod2 = Dus.SquareMagnitude();
if (myVIsoIsDeg)
{
Standard_Real DusMod = Sqrt(DusMod2);
if (DusMod2>gp::Resolution() && DusMod2<1.)
{
Dus.Multiply(1/DusMod);
Df(1,1) = DusMod2 + PPs.Dot( (Duus*DusMod - Dus*(Dus.Dot(Duus)/DusMod)) / DusMod2 );
Df(1,2) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DusMod-Dus*(Dus.Dot(Duvs)/DusMod)) / DusMod2 );
}
else {
Df(1,1) = DusMod2 + PPs.Dot(Duus);
Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
}
}
else {
Df(1,1) = DusMod2 + PPs.Dot(Duus);
Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
}
// 2. U iso
Standard_Real DvsMod2 = Dvs.SquareMagnitude();
if (myUIsoIsDeg)
{
Standard_Real DvsMod = Sqrt(DvsMod2);
if (DvsMod2>gp::Resolution() && DvsMod2<1.)
{
Dvs.Multiply(1/DvsMod);
Df(2,1) = Dvs.Dot(Dus) + PPs.Dot( (Duvs*DvsMod-Dvs*(Dvs.Dot(Duvs)/DvsMod)) / DvsMod2 );
Df(2,2) = DvsMod2 + PPs.Dot( (Duus*DvsMod - Dus*(Dus.Dot(Duus)/DvsMod)) / DvsMod2 );
}
else {
Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
Df(2,2) = DvsMod2 + PPs.Dot(Dvvs);
}
}
else {
Df(2,1) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
Df(2,2) = DvsMod2 + PPs.Dot(Dvvs);
}
Df(1,1) = Dus.SquareMagnitude() + PPs.Dot(Duus);
Df(1,2) = Dvs.Dot(Dus) + PPs.Dot(Duvs);
Df(2,1) = Df(1,2);
Df(2,2) = Dvs.SquareMagnitude() + PPs.Dot(Dvvs);
// 3. Value
F(1) = PPs.Dot(Dus);
F(2) = PPs.Dot(Dvs);
@ -298,11 +138,3 @@ Extrema_POnSurf Extrema_FuncExtPS::Point (const Standard_Integer N) const
if (!myPinit || !mySinit) Standard_TypeMismatch::Raise();
return myPoint.Value(N);
}
//=============================================================================
// Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 Begin
Standard_Boolean Extrema_FuncExtPS::HasDegIso() const
{
return myUIsoIsDeg || myVIsoIsDeg;
}
// Modified by skv - Thu Sep 30 15:21:07 2004 OCC593 End

View File

@ -416,9 +416,6 @@ void Extrema_GenExtPS::FindSolution(const gp_Pnt& P, const math_Vector& UV, cons
Standard_Integer aNbMaxIter = 100;
if (myF.HasDegIso())
aNbMaxIter = 150;
gp_Pnt PStart = myS->Value(UV(1), UV(2));
Standard_Real DistStart = P.SquareDistance(PStart);
Standard_Real DistSol = DistStart;

View File

@ -985,6 +985,7 @@ gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real
dv = Min (myVDelt, SurfAdapt.VResolution (preci));
myExtSrf = mySurf;
Standard_Real Tol = Precision::PConfusion();
myExtPS.SetFlag (Extrema_ExtFlag_MIN);
myExtPS.Initialize ( myExtSrf, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol );
myExtOK = Standard_True;
}