---Purpose:
+uses
+ Array1OfReal from TColStd,
+ HArray1OfReal from TColStd
+
raises NotDone from StdFail
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.
---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
myTrimFirst : Real;
myTrimLast : Real;
myNbSamples : Integer;
+ myParamArray : HArray1OfReal from TColStd;
myPntArray : ArrayOfPnt;
myIsArrayValid: Boolean;
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 :
myC = (Standard_Address)&theC;
myNbSamples = theNbSamples;
myIsArrayValid = Standard_False;
+ myParamArray.Nullify();
myPntArray.Nullify();
if (theToCalculate) {
CalculatePoints();
}
myIsArrayValid = Standard_False;
+ myParamArray.Nullify();
myPntArray.Nullify();
if (theToCalculate) {
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));
}
// roman.lygin@gmail.com
#include <StdFail_NotDone.hxx>
+#include <TColStd_HArray1OfReal.hxx>
//=======================================================================
//function : IsValid
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 :
//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()) {
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);
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
//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);
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();
// - 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) {
(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);
(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);
--- /dev/null
+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