mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-05 18:16:23 +03:00
0023994: GeomAPI_ExtremaCurveCurve class calculates wrong values
Adding test casefor this fix
This commit is contained in:
parent
03679c4858
commit
afed7fd721
@ -27,6 +27,10 @@ inherits Transient from Standard
|
||||
|
||||
---Purpose:
|
||||
|
||||
uses
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfReal from TColStd
|
||||
|
||||
raises NotDone from StdFail
|
||||
|
||||
is
|
||||
@ -36,6 +40,12 @@ is
|
||||
Create (theC: Curve; theUFirst, theULast: Real; theNbSamples: Integer;
|
||||
theToCalculate: Boolean)returns mutable CurveCache from Extrema;
|
||||
|
||||
Create (theC: Curve; theUFirst, theULast: Real;
|
||||
IntervalsCN: Array1OfReal from TColStd;
|
||||
StartIndex, EndIndex: Integer;
|
||||
Coeff: Real)
|
||||
returns mutable CurveCache from Extrema;
|
||||
|
||||
SetCurve (me: mutable; theC: Curve; theNbSamples: Integer;
|
||||
theToCalculate: Boolean);
|
||||
---Purpose: Sets the \a theRank-th curve (1 or 2) and its parameters.
|
||||
@ -57,6 +67,12 @@ is
|
||||
---Purpose: Returns True if the points array has already been calculated
|
||||
-- for specified curve and range
|
||||
|
||||
Parameters (me) returns HArray1OfReal from TColStd
|
||||
raises NotDone from StdFail;
|
||||
---C++: inline
|
||||
---C++: return const &
|
||||
---Purpose: Raises StdFail_NotDone if points have not yet been calculated.
|
||||
|
||||
Points (me) returns ArrayOfPnt
|
||||
raises NotDone from StdFail;
|
||||
---C++: inline
|
||||
@ -95,6 +111,7 @@ fields
|
||||
myTrimFirst : Real;
|
||||
myTrimLast : Real;
|
||||
myNbSamples : Integer;
|
||||
myParamArray : HArray1OfReal from TColStd;
|
||||
myPntArray : ArrayOfPnt;
|
||||
myIsArrayValid: Boolean;
|
||||
|
||||
|
@ -36,6 +36,64 @@ Extrema_CurveCache::Extrema_CurveCache(const Curve& theC,
|
||||
SetCurve (theC, theUFirst, theULast, theNbSamples, theToCalculate);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Extrema_CurveCache
|
||||
//purpose : with sampling by knots and between them
|
||||
//=======================================================================
|
||||
|
||||
Extrema_CurveCache::Extrema_CurveCache(const Curve& theC,
|
||||
const Standard_Real theUFirst,
|
||||
const Standard_Real theULast,
|
||||
const TColStd_Array1OfReal& IntervalsCN,
|
||||
const Standard_Integer StartIndex,
|
||||
const Standard_Integer EndIndex,
|
||||
const Standard_Real Coeff)
|
||||
{
|
||||
myC = (Standard_Address)&theC;
|
||||
myIsArrayValid = Standard_False;
|
||||
myParamArray.Nullify();
|
||||
myPntArray.Nullify();
|
||||
|
||||
myTrimFirst = myFirst = theUFirst;
|
||||
myTrimLast = myLast = theULast;
|
||||
|
||||
Standard_Integer Nbp = (Standard_Integer) (2 * Coeff);
|
||||
myNbSamples = (EndIndex - StartIndex)*Nbp + 1;
|
||||
|
||||
const Standard_Integer aNbSTresh = 10000;
|
||||
if (myNbSamples > aNbSTresh)
|
||||
{
|
||||
Nbp = aNbSTresh / (EndIndex - StartIndex);
|
||||
myNbSamples = (EndIndex - StartIndex)*Nbp + 1;
|
||||
}
|
||||
|
||||
//Cache points
|
||||
myParamArray = new TColStd_HArray1OfReal(1, myNbSamples);
|
||||
myPntArray = new ArrayOfPnt (1, myNbSamples);
|
||||
|
||||
const Curve& aCurve = *((Curve*)myC);
|
||||
|
||||
Standard_Integer i, j, k = 1;
|
||||
Standard_Real aPar;
|
||||
for (i = StartIndex; i < EndIndex; i++)
|
||||
{
|
||||
Standard_Real delta = (IntervalsCN(i+1) - IntervalsCN(i)) / Nbp;
|
||||
for (j = 0; j < Nbp; j++)
|
||||
{
|
||||
aPar = IntervalsCN(i) + j*delta;
|
||||
myParamArray->SetValue(k, aPar);
|
||||
myPntArray->SetValue(k++, aCurve.Value(aPar));
|
||||
}
|
||||
}
|
||||
Standard_Real aDelta = (myTrimLast - myTrimFirst) / myNbSamples / 200.;
|
||||
myParamArray->SetValue(1, myTrimFirst + aDelta);
|
||||
myPntArray->SetValue(1, aCurve.Value(myTrimFirst + aDelta));
|
||||
myParamArray->SetValue(myNbSamples, myTrimLast - aDelta);
|
||||
myPntArray->SetValue(myNbSamples, aCurve.Value(myTrimLast - aDelta));
|
||||
|
||||
myIsArrayValid = Standard_True; //cache is available now
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Extrema_CurveCache
|
||||
//purpose :
|
||||
@ -58,6 +116,7 @@ void Extrema_CurveCache::SetCurve (const Curve& theC,
|
||||
myC = (Standard_Address)&theC;
|
||||
myNbSamples = theNbSamples;
|
||||
myIsArrayValid = Standard_False;
|
||||
myParamArray.Nullify();
|
||||
myPntArray.Nullify();
|
||||
if (theToCalculate) {
|
||||
CalculatePoints();
|
||||
@ -99,6 +158,7 @@ void Extrema_CurveCache::SetRange (const Standard_Real theUFirst,
|
||||
}
|
||||
|
||||
myIsArrayValid = Standard_False;
|
||||
myParamArray.Nullify();
|
||||
myPntArray.Nullify();
|
||||
if (theToCalculate) {
|
||||
CalculatePoints();
|
||||
@ -124,11 +184,13 @@ void Extrema_CurveCache::CalculatePoints()
|
||||
|
||||
//Cache points
|
||||
|
||||
myParamArray = new TColStd_HArray1OfReal(1, myNbSamples);
|
||||
myPntArray = new ArrayOfPnt (1, myNbSamples);
|
||||
|
||||
Standard_Integer i;
|
||||
Standard_Real aPar;
|
||||
for (i = 1, aPar = aPar0; i <= myNbSamples; i++, aPar += aDelta) {
|
||||
myParamArray->SetValue(i, aPar);
|
||||
myPntArray->SetValue (i, aCurve.Value (aPar));
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
// roman.lygin@gmail.com
|
||||
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : IsValid
|
||||
@ -31,6 +32,17 @@ inline Standard_Boolean Extrema_CurveCache::IsValid() const
|
||||
return myIsArrayValid;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Parameters
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
inline const Handle(TColStd_HArray1OfReal)& Extrema_CurveCache::Parameters() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if (!myIsArrayValid, "Extrema_CurveCache::Parameters()")
|
||||
return myParamArray;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Points
|
||||
//purpose :
|
||||
|
@ -272,8 +272,11 @@ void Extrema_GExtCC::Perform()
|
||||
//common case - use _GenExtCC
|
||||
//1. check and prepare caches
|
||||
|
||||
Standard_Integer i, aNbS[2] = {32, 32}, aNbInter[2] = {1, 1};
|
||||
Standard_Integer i;
|
||||
Standard_Integer aNbS[2] = {32, 32}, aNbInter[2] = {1, 1};
|
||||
Standard_Real Coeff[2] = {1., 1.};
|
||||
Standard_Real rf = 0., rl = 0., LL[2] = {-1., -1.};
|
||||
Standard_Boolean KnotSampling[2] = {Standard_False, Standard_False};
|
||||
for (i = 0; i < 2; i++) {
|
||||
TColStd_ListOfTransient& aCacheList = myCacheLists[i];
|
||||
if (aCacheList.IsEmpty()) {
|
||||
@ -288,10 +291,14 @@ void Extrema_GExtCC::Perform()
|
||||
aNbS[i] = aC.NbPoles() * 2;
|
||||
break;
|
||||
case GeomAbs_BSplineCurve:
|
||||
if (aC.Degree() <= 3 &&
|
||||
aC.NbKnots() > 2)
|
||||
KnotSampling[i] = Standard_True;
|
||||
|
||||
aNbS[i] = aC.NbPoles() * 2;
|
||||
rf = (Tool1::BSpline(*((Curve1*)myC[i])))->FirstParameter();
|
||||
rl = (Tool1::BSpline(*((Curve1*)myC[i])))->LastParameter();
|
||||
aNbS[i] = (Standard_Integer) ( aNbS[i] * ((mySup[i] - myInf[i]) / (rl - rf)) + 1 );
|
||||
rf = (Tool1::BSpline(*((Curve1*)myC[i])))->FirstParameter();
|
||||
rl = (Tool1::BSpline(*((Curve1*)myC[i])))->LastParameter();
|
||||
aNbS[i] = (Standard_Integer) ( aNbS[i] * ((mySup[i] - myInf[i]) / (rl - rf)) + 1 );
|
||||
case GeomAbs_OtherCurve:
|
||||
//adjust number of sample points for B-Splines and Other curves
|
||||
aNbInter[i] = aC.NbIntervals (GeomAbs_C2);
|
||||
@ -314,10 +321,12 @@ void Extrema_GExtCC::Perform()
|
||||
|
||||
if(LL[0] > 0. && LL[1] > 0.) {
|
||||
if(LL[0] > 4.*LL[1]) {
|
||||
aNbS[0] = (Standard_Integer) ( aNbS[0] * LL[0]/LL[1]/2. );
|
||||
Coeff[0] = LL[0]/LL[1]/2.;
|
||||
aNbS[0] = (Standard_Integer) ( aNbS[0] * Coeff[0] );
|
||||
}
|
||||
else if(LL[1] > 4.*LL[0]) {
|
||||
aNbS[1] = (Standard_Integer) (aNbS[1] * LL[1]/LL[0]/2. );
|
||||
Coeff[1] = LL[1]/LL[0]/2.;
|
||||
aNbS[1] = (Standard_Integer) (aNbS[1] * Coeff[1] );
|
||||
}
|
||||
}
|
||||
//modified by NIZNHY-PKV Tue Apr 17 10:01:32 2012f
|
||||
@ -337,16 +346,48 @@ void Extrema_GExtCC::Perform()
|
||||
//no caches, build them
|
||||
Curve1& aC = *(Curve1*)myC[i];
|
||||
|
||||
if (aC.GetType() >= GeomAbs_BSplineCurve) {
|
||||
if (aC.GetType() >= GeomAbs_BSplineCurve)
|
||||
{
|
||||
//can be multiple intervals, one cache per one C2 interval
|
||||
TColStd_Array1OfReal anArr (1, aNbInter[i] + 1);
|
||||
aC.Intervals (anArr, GeomAbs_C2);
|
||||
for (Standard_Integer k = 1; k <= aNbInter[i]; k++) {
|
||||
Handle(Extrema_CCache) aCache = new Extrema_CCache (aC,
|
||||
anArr(k), anArr(k+1), aNbS[i], Standard_True);
|
||||
aCacheList.Append (aCache);
|
||||
|
||||
if (KnotSampling[i])
|
||||
{
|
||||
Standard_Integer NbIntervCN = aC.NbIntervals(GeomAbs_CN);
|
||||
TColStd_Array1OfReal IntervalsCN(1, NbIntervCN + 1);
|
||||
aC.Intervals(IntervalsCN, GeomAbs_CN);
|
||||
|
||||
Standard_Integer j = 1, start_j = 1, k;
|
||||
Standard_Real NextKnot;
|
||||
for (k = 1; k <= aNbInter[i]; k++)
|
||||
{
|
||||
do
|
||||
{
|
||||
NextKnot = IntervalsCN(j+1);
|
||||
j++;
|
||||
}
|
||||
while (NextKnot != anArr(k+1));
|
||||
|
||||
Handle(Extrema_CCache) aCache =
|
||||
new Extrema_CCache (aC, anArr(k), anArr(k+1),
|
||||
IntervalsCN, start_j, j, Coeff[i]);
|
||||
aCacheList.Append (aCache);
|
||||
|
||||
start_j = j;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
for (Standard_Integer k = 1; k <= aNbInter[i]; k++) {
|
||||
Handle(Extrema_CCache) aCache =
|
||||
new Extrema_CCache (aC, anArr(k), anArr(k+1), aNbS[i], Standard_True);
|
||||
aCacheList.Append (aCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//single interval from myInf[i] to mySup[i]
|
||||
Handle(Extrema_CCache) aCache = new Extrema_CCache (aC,
|
||||
myInf[i], mySup[i], aNbS[i], Standard_True);
|
||||
|
@ -146,16 +146,6 @@ a- Constitution du tableau des distances (TbDist2(0,NbU+1,0,NbV+1)):
|
||||
aCache2->CalculatePoints();
|
||||
|
||||
// Calcul des distances
|
||||
//initialization of variables in the same way as in CalculatePoints()
|
||||
Standard_Real PasU = aCache1->TrimLastParameter() - aCache1->TrimFirstParameter();
|
||||
Standard_Real PasV = aCache2->TrimLastParameter() - aCache2->TrimFirstParameter();
|
||||
Standard_Real U0 = PasU / aNbU / 100.;
|
||||
Standard_Real V0 = PasV / aNbV / 100.;
|
||||
PasU = (PasU - U0) / (aNbU - 1);
|
||||
PasV = (PasV - V0) / (aNbV - 1);
|
||||
U0 = aCache1->TrimFirstParameter() + (U0/2.);
|
||||
V0 = aCache2->TrimFirstParameter() + (V0/2.);
|
||||
|
||||
const Curve1& aCurve1 = *((Curve1*)(myF.CurvePtr (1)));
|
||||
const Curve2& aCurve2 = *((Curve1*)(myF.CurvePtr (2)));
|
||||
const Handle(ArrayOfPnt)& aPntArray1 = aCache1->Points();
|
||||
@ -207,6 +197,8 @@ b- Calcul des minima:
|
||||
// - recherche d un minimum sur la grille
|
||||
Standard_Integer Nu, Nv;
|
||||
Standard_Real Dist2;
|
||||
const Handle(TColStd_HArray1OfReal)& aParamArray1 = aCache1->Parameters();
|
||||
const Handle(TColStd_HArray1OfReal)& aParamArray2 = aCache2->Parameters();
|
||||
for (NoU = 1; NoU <= aNbU; NoU++) {
|
||||
for (NoV = 1; NoV <= aNbV; NoV++) {
|
||||
if (TbSel(NoU,NoV) == 0) {
|
||||
@ -221,9 +213,9 @@ b- Calcul des minima:
|
||||
(TbDist2(NoU+1,NoV+1) >= Dist2)) {
|
||||
|
||||
// - calcul de l extremum sur la surface:
|
||||
UV(1) = U0 + (NoU - 1) * PasU;
|
||||
UV(2) = V0 + (NoV - 1) * PasV;
|
||||
|
||||
|
||||
UV(1) = aParamArray1->Value(NoU);
|
||||
UV(2) = aParamArray2->Value(NoV);
|
||||
|
||||
math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup);
|
||||
|
||||
@ -278,8 +270,9 @@ c- Calcul des maxima:
|
||||
(TbDist2(NoU+1,NoV+1) <= Dist2)) {
|
||||
|
||||
// - calcul de l extremum sur la surface:
|
||||
UV(1) = U0 + (NoU - 1) * PasU;
|
||||
UV(2) = V0 + (NoV - 1) * PasV;
|
||||
|
||||
UV(1) = aParamArray1->Value(NoU);
|
||||
UV(2) = aParamArray2->Value(NoV);
|
||||
|
||||
math_FunctionSetRoot S (myF,UV,Tol,UVinf,UVsup);
|
||||
|
||||
|
42
tests/bugs/moddata_3/bug23994
Executable file
42
tests/bugs/moddata_3/bug23994
Executable file
@ -0,0 +1,42 @@
|
||||
puts "================"
|
||||
puts "OCC23994"
|
||||
puts "================"
|
||||
puts ""
|
||||
#######################################################################
|
||||
# GeomAPI_ExtremaCurveCurve class calculates wrong values
|
||||
#######################################################################
|
||||
|
||||
set BugNumber CR23994
|
||||
|
||||
pload XDE
|
||||
|
||||
ReadStep D [locate_data_file bug23994_AirfoilRhomb_CalcDist_17_OP_Bell_Mouth_Roughing_shroud.stp]
|
||||
|
||||
XCheckProps D
|
||||
|
||||
XGetShape airflIntersctCrv D 0:1:1:1
|
||||
XGetShape rhombIntersctCrv D 0:1:1:2
|
||||
|
||||
explode rhombIntersctCrv
|
||||
mkcurve rhomb rhombIntersctCrv_1
|
||||
|
||||
explode airflIntersctCrv
|
||||
mkcurve airfl airflIntersctCrv_1
|
||||
|
||||
extrema airfl rhomb
|
||||
|
||||
if { [isdraw ext_1] } {
|
||||
mkedge result ext_1
|
||||
set length 9.09515
|
||||
} else {
|
||||
puts "${BugNumber}: invalid result"
|
||||
}
|
||||
|
||||
if { [isdraw ext_2] } {
|
||||
mkedge result ext_2
|
||||
set length 5.14563
|
||||
} else {
|
||||
puts "${BugNumber}: invalid result"
|
||||
}
|
||||
|
||||
set 2dviewer 1
|
Loading…
x
Reference in New Issue
Block a user