diff --git a/src/Bnd/Bnd_Range.cxx b/src/Bnd/Bnd_Range.cxx index d79b211dea..63d0961343 100644 --- a/src/Bnd/Bnd_Range.cxx +++ b/src/Bnd/Bnd_Range.cxx @@ -35,3 +35,143 @@ void Bnd_Range::Common(const Bnd_Range& theOther) myFirst = Max(myFirst, theOther.myFirst); myLast = Min(myLast, theOther.myLast); } + +//======================================================================= +//function : Union +//purpose : +//======================================================================= +Standard_Boolean Bnd_Range::Union(const Bnd_Range& theOther) +{ + if (IsVoid() || theOther.IsVoid()) + return Standard_False; + + if (myLast < theOther.myFirst) + return Standard_False; + + if (myFirst > theOther.myLast) + return Standard_False; + + myFirst = Min(myFirst, theOther.myFirst); + myLast = Max(myLast, theOther.myLast); + + return Standard_True; +} + +//======================================================================= +//function : IsIntersected +//purpose : +//======================================================================= +Standard_Integer Bnd_Range::IsIntersected(const Standard_Real theVal, + const Standard_Real thePeriod) const +{ + if (IsVoid()) + return Standard_False; + + const Standard_Real aPeriod = Abs(thePeriod); + const Standard_Real aDF = myFirst - theVal, + aDL = myLast - theVal; + + if (aPeriod <= RealSmall()) + { + const Standard_Real aDelta = aDF*aDL; + if (IsEqual(aDelta, 0.0)) + return 2; + + if (aDelta > 0.0) + return 0; + + return 1; + } + + //If intersects theVal then there exists an integer + //number N such as + // (myFirst <= theVal+aPeriod*N <= myLast) <=> + // ((myFirst-theVal)/aPeriod <= N <= (myLast-theVal)/aPeriod). + //I.e. the interval [aDF/aPeriod, aDL/aPeriod] must contain at least one + //integer number. + //In this case, Floor(aDF/aPeriod) and Floor(aDL/aPeriod) + //return different values or aDF/aPeriod (aDL/aPeriod) + //is strictly integer number. + //Examples: + // 1. (aDF/aPeriod==2.8, aDL/aPeriod==3.5 => + // Floor(aDF/aPeriod) == 2, Floor(aDL/aPeriod) == 3. + // 2. aDF/aPeriod==2.0, aDL/aPeriod==2.6 => + // Floor(aDF/aPeriod) == Floor(aDL/aPeriod) == 2. + + const Standard_Real aVal1 = aDF / aPeriod, + aVal2 = aDL / aPeriod; + const Standard_Integer aPar1 = static_cast(Floor(aVal1)); + const Standard_Integer aPar2 = static_cast(Floor(aVal2)); + if (aPar1 != aPar2) + {//Interval (myFirst, myLast] intersects seam-edge + if (IsEqual(aVal2, static_cast(aPar2))) + {//aVal2 is an integer number => myLast lies ON the "seam-edge" + return 2; + } + + return 1; + } + + //Here, aPar1 == aPar2. + + if (IsEqual(aVal1, static_cast(aPar1))) + {//aVal1 is an integer number => myFirst lies ON the "seam-edge" + return 2; + } + +#if 0 + // This check is excess because always myFirst <= myLast. + // So, this condition is never satisfied. + if (IsEqual(aVal2, static_cast(aPar2))) + {//aVal2 is an integer number => myLast lies ON the "seam-edge" + return 2; + } +#endif + + return 0; +} + +//======================================================================= +//function : Split +//purpose : +//======================================================================= +void Bnd_Range::Split(const Standard_Real theVal, + NCollection_List& theList, + const Standard_Real thePeriod) const +{ + const Standard_Real aPeriod = Abs(thePeriod); + if (IsIntersected(theVal, aPeriod) != 1) + { + theList.Append(*this); + return; + } + + const Standard_Boolean isPeriodic = (aPeriod > 0.0); + + if (!isPeriodic) + { + theList.Append(Bnd_Range(myFirst, theVal)); + theList.Append(Bnd_Range(theVal, myLast)); + return; + } + + Standard_Real aValPrev = theVal + aPeriod*Ceiling((myFirst - theVal) / aPeriod); + + //Now, (myFirst <= aValPrev < myFirst+aPeriod). + + if (aValPrev > myFirst) + { + theList.Append(Bnd_Range(myFirst, aValPrev)); + } + + for (Standard_Real aVal = aValPrev+aPeriod; aVal <= myLast; aVal += aPeriod) + { + theList.Append(Bnd_Range(aValPrev, aVal)); + aValPrev = aVal; + } + + if (aValPrev < myLast) + { + theList.Append(Bnd_Range(aValPrev, myLast)); + } +} \ No newline at end of file diff --git a/src/Bnd/Bnd_Range.hxx b/src/Bnd/Bnd_Range.hxx index 2afd47f8b2..01021b159d 100644 --- a/src/Bnd/Bnd_Range.hxx +++ b/src/Bnd/Bnd_Range.hxx @@ -19,6 +19,8 @@ #include #include +#include + //! This class describes a range in 1D space restricted //! by two real values. //! A range can be void indicating there is no point included in the range. @@ -42,6 +44,39 @@ public: //! Replaces with common-part of and theOther Standard_EXPORT void Common(const Bnd_Range& theOther); + + //! Joins *this and theOther to one interval. + //! Replaces *this to the result. + //! Returns false if the operation cannot be done (e.g. + //! input arguments are empty or separated). + Standard_EXPORT Standard_Boolean Union(const Bnd_Range& theOther); + + //! Splits to several sub-ranges by theVal value + //! (e.g. range [3, 15] will be split by theVal==5 to the two + //! ranges: [3, 5] and [5, 15]). New ranges will be pushed to + //! theList (theList must be initialized correctly before + //! calling this method). + //! If thePeriod != 0.0 then at least one boundary of + //! new ranges (if <*this> intersects theVal+k*thePeriod) will be equal to + //! theVal+thePeriod*k, where k is an integer number (k = 0, +/-1, +/-2, ...). + //! (let thePeriod in above example be 4 ==> we will obtain + //! four ranges: [3, 5], [5, 9], [9, 13] and [13, 15]. + Standard_EXPORT void Split(const Standard_Real theVal, + NCollection_List& theList, + const Standard_Real thePeriod = 0.0) const; + + //! Checks if intersects values like + //! theVal+k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...). + //! Returns: + //! 0 - if does not intersect the theVal+k*thePeriod. + //! 1 - if intersects theVal+k*thePeriod. + //! 2 - if myFirst or/and myLast are equal to theVal+k*thePeriod. + //! + //! ATTENTION!!! + //! If (myFirst == myLast) then this function will return only either 0 or 2. + Standard_EXPORT Standard_Integer + IsIntersected(const Standard_Real theVal, + const Standard_Real thePeriod = 0.0) const; //! Extends to include theParameter void Add(const Standard_Real theParameter) @@ -82,6 +117,21 @@ public: return Standard_True; } + //! Obtain first and last boundary of . + //! If is VOID the method returns false. + Standard_Boolean GetBounds(Standard_Real& theFirstPar, + Standard_Real& theLastPar) const + { + if(IsVoid()) + { + return Standard_False; + } + + theFirstPar = myFirst; + theLastPar = myLast; + return Standard_True; + } + //! Returns range value (MAX-MIN). Returns negative value for VOID range. Standard_Real Delta() const { @@ -113,6 +163,25 @@ public: myLast += theDelta; } + //! Returns the copy of <*this> shifted by theVal + Bnd_Range Shifted(const Standard_Real theVal) const + { + return Bnd_Range(myFirst + theVal, myLast + theVal); + } + + //! Shifts <*this> by theVal + void Shift(const Standard_Real theVal) + { + myFirst += theVal; + myLast += theVal; + } + + //! Returns TRUE if theOther is equal to <*this> + Standard_Boolean operator==(const Bnd_Range& theOther) const + { + return ((myFirst == theOther.myFirst) && (myLast == theOther.myLast)); + } + private: //! Start of range Standard_Real myFirst; diff --git a/src/ElCLib/ElCLib.cxx b/src/ElCLib/ElCLib.cxx index 6bfb2de05a..8801ef8a3b 100644 --- a/src/ElCLib/ElCLib.cxx +++ b/src/ElCLib/ElCLib.cxx @@ -49,6 +49,22 @@ static Standard_Real PIPI = M_PI + M_PI; //======================================================================= //function : InPeriod //purpose : Value theULast is never returned. +// Example of some case (checked on WIN64 platform) +// with some surface having period 2*PI = 6.2831853071795862. +// Let theUFirst be equal to 6.1645624650899675. Then, +// theULast must be equal to +// 6.1645624650899675+6.2831853071795862=12.4477477722695537. +// +// However, real result is 12.447747772269555. +// Therefore, new period value to adjust will be equal to +// 12.447747772269555-6.1645624650899675=6.2831853071795871. +// +// As we can see, (6.2831853071795871 != 6.2831853071795862). +// +// According to above said, this method should be used carefully. +// In order to increase reliability of this method, input arguments +// needs to be replaced with following: +// (theU, theUFirst, thePeriod). theULast parameter is excess. //======================================================================= Standard_Real ElCLib::InPeriod(const Standard_Real theU, const Standard_Real theUFirst, diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx index 75d377de48..9ab3fd04c2 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx @@ -77,7 +77,6 @@ static const Standard_Real theTol2D, const Bnd_Box2d& theUVSurf1, const Bnd_Box2d& theUVSurf2, - const Standard_Boolean isTheReverse, Standard_Boolean& isTheEmpty, Standard_Boolean& isTheSameSurface, Standard_Boolean& isTheMultiplePoint, diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx index 2567933247..30d0aebed3 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx @@ -172,33 +172,13 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1, aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter())); // Resolution is too big if the cylinder radius is - // too small. Therefore, we shall bounde its value above. + // too small. Therefore, we shall bind its value above. // Here, we use simple constant. const Standard_Real a2DTol = Min(1.0e-4, Min( S1->UResolution(TolTang), S2->UResolution(TolTang))); - //The bigger range the bigger nunber of points in Walking-line (WLine) - //we will be able to add and, consequently, we will obtain more - //precise intersection line. - //Every point of WLine is determined as function from U1-parameter, - //where U1 is U-parameter on 1st quadric. - //Therefore, we should use quadric with bigger range as 1st parameter - //in IntCyCy() function. - //On the other hand, there is no point in reversing in case of - //analytical intersection (when result is line, ellipse, point...). - //This result is independent of the arguments order. - Standard_Boolean isReversed = ((aU2l - aU2f) < (aU1l - aU1f)); - - if(isReversed) - { - myDone = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1, - Standard_True, empt, SameSurf, multpoint, slin, spnt); - } - else - { - myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2, - Standard_False, empt, SameSurf, multpoint, slin, spnt); - } + myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2, + empt, SameSurf, multpoint, slin, spnt); if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail) { diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx index 94bfab8b75..1a6cb9b87a 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx @@ -16,11 +16,10 @@ #include #include -#include #include -#include -#include #include +#include +#include //If Abs(a) <= aNulValue then it is considered that a = 0. static const Standard_Real aNulValue = 1.0e-11; @@ -372,7 +371,7 @@ public: myV2 = RealLast(); } - //Equal to 0 for 1st surface non-zerro for 2nd one. + //Equal to 0 for 1st surface non-zero for 2nd one. Standard_Integer mySurfID; Standard_Real myU1; @@ -413,8 +412,55 @@ public: { }; + // Returns parameters of system solved while finding + // intersection line + const ComputationMethods::stCoeffsValue &SICoeffs() const + { + return myCoeffs; + } + + // Returns quadric correspond to the index theIdx. + const IntSurf_Quadric& GetQSurface(const Standard_Integer theIdx) const + { + if (theIdx <= 1) + return myQuad1; + + return myQuad2; + } + + // Returns TRUE in case of reverting surfaces + Standard_Boolean IsReversed() const + { + return myIsReverse; + } + + // Returns 2D-tolerance + Standard_Real Get2dTolerance() const + { + return myTol2D; + } + + // Returns 3D-tolerance + Standard_Real Get3dTolerance() const + { + return myTol3D; + } + + // Returns UV-bounds of 1st surface + const Bnd_Box2d& UVS1() const + { + return myUVSurf1; + } + + // Returns UV-bounds of 2nd surface + const Bnd_Box2d& UVS2() const + { + return myUVSurf2; + } + void AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, const Standard_Real theU1, + const Standard_Real theU1Min, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV1Prev, @@ -425,8 +471,9 @@ public: Standard_Boolean& isTheFound1, Standard_Boolean& isTheFound2) const; - Standard_Boolean BoundariesComputing(Standard_Real theU1f[], - Standard_Real theU1l[]) const; + static Standard_Boolean BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs, + const Standard_Real thePeriod, + Bnd_Range theURange[]); void BoundaryEstimation(const gp_Cylinder& theCy1, const gp_Cylinder& theCy2, @@ -898,7 +945,6 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, const IntSurf_Quadric& Quad2, const IntAna_QuadQuadGeo& theInter, const Standard_Real Tol, - const Standard_Boolean isTheReverse, Standard_Boolean& Empty, Standard_Boolean& Same, Standard_Boolean& Multpoint, @@ -943,17 +989,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, ptsol.SetValue(psol,Tol,Standard_True); Standard_Real U1,V1,U2,V2; - - if(isTheReverse) - { - Quad2.Parameters(psol, U1, V1); - Quad1.Parameters(psol, U2, V2); - } - else - { - Quad1.Parameters(psol, U1, V1); - Quad2.Parameters(psol, U2, V2); - } + Quad1.Parameters(psol, U1, V1); + Quad2.Parameters(psol, U2, V2); ptsol.SetParameters(U1,V1,U2,V2); spnt.Append(ptsol); @@ -1100,30 +1137,12 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, pmult2.SetMultiple(Standard_True); Standard_Real oU1,oV1,oU2,oV2; - - if(isTheReverse) - { - Quad2.Parameters(pttang1,oU1,oV1); - Quad1.Parameters(pttang1,oU2,oV2); - } - else - { - Quad1.Parameters(pttang1,oU1,oV1); - Quad2.Parameters(pttang1,oU2,oV2); - } + Quad1.Parameters(pttang1, oU1, oV1); + Quad2.Parameters(pttang1, oU2, oV2); pmult1.SetParameters(oU1,oV1,oU2,oV2); - - if(isTheReverse) - { - Quad2.Parameters(pttang2,oU1,oV1); - Quad1.Parameters(pttang2,oU2,oV2); - } - else - { - Quad1.Parameters(pttang2,oU1,oV1); - Quad2.Parameters(pttang2,oU2,oV2); - } + Quad1.Parameters(pttang2,oU1,oV1); + Quad2.Parameters(pttang2,oU2,oV2); pmult2.SetParameters(oU1,oV1,oU2,oV2); @@ -1161,17 +1180,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, aIP.SetValue(aP,Tol,Standard_False); aIP.SetMultiple(Standard_False); // - - if(isTheReverse) - { - Quad2.Parameters(aP, aU1, aV1); - Quad1.Parameters(aP, aU2, aV2); - } - else - { - Quad1.Parameters(aP, aU1, aV1); - Quad2.Parameters(aP, aU2, aV2); - } + Quad1.Parameters(aP, aU1, aV1); + Quad2.Parameters(aP, aU2, aV2); aIP.SetParameters(aU1, aV1, aU2, aV2); // @@ -1245,16 +1255,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, aIP.SetMultiple(Standard_False); // - if(isTheReverse) - { - Quad2.Parameters(aP, aU1, aV1); - Quad1.Parameters(aP, aU2, aV2); - } - else - { - Quad1.Parameters(aP, aU1, aV1); - Quad2.Parameters(aP, aU2, aV2); - } + Quad1.Parameters(aP, aU1, aV1); + Quad2.Parameters(aP, aU2, aV2); aIP.SetParameters(aU1, aV1, aU2, aV2); // @@ -1418,7 +1420,7 @@ Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real theU //======================================================================= //function : CylCylComputeParameters //purpose : Computes U2 (U-parameter of the 2nd cylinder) and, if theDelta != 0, -// esimates the tolerance of U2-computing (estimation result is +// estimates the tolerance of U2-computing (estimation result is // assigned to *theDelta value). //======================================================================= Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par, @@ -1439,14 +1441,14 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real Standard_Real anArg = cos(theU1par - theCoeffs.mFI1); anArg = theCoeffs.mB*anArg + theCoeffs.mC; - if(anArg > aTol) + if(anArg >= aTol) { if(theDelta) *theDelta = 0.0; anArg = 1.0; } - else if(anArg < -aTol) + else if(anArg <= -aTol) { if(theDelta) *theDelta = 0.0; @@ -1494,6 +1496,10 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real return Standard_True; } +//======================================================================= +//function : CylCylComputeParameters +//purpose : Computes V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively). +//======================================================================= Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1, const Standard_Real theU2, const stCoeffsValue& theCoeffs, @@ -1513,7 +1519,11 @@ Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real return Standard_True; } - +//======================================================================= +//function : CylCylComputeParameters +//purpose : Computes U2 (U-parameter of the 2nd cylinder), +// V1 and V2 (V-parameters of the 1st and 2nd cylinder respectively). +//======================================================================= Standard_Boolean ComputationMethods::CylCylComputeParameters(const Standard_Real theU1par, const Standard_Integer theWLIndex, const stCoeffsValue& theCoeffs, @@ -1728,31 +1738,42 @@ Standard_Boolean InscribePoint( const Standard_Real theUfTarget, //======================================================================= //function : InscribeInterval -//purpose : Adjusts theUfGiven and (after that) adjusts theUlGiven to the result +//purpose : Shifts theRange in order to make at least one of its +// boundary in the range [theUfTarget, theUlTarget] //======================================================================= static Standard_Boolean InscribeInterval(const Standard_Real theUfTarget, - const Standard_Real theUlTarget, - Standard_Real& theUfGiven, - Standard_Real& theUlGiven, - const Standard_Real theTol2D, - const Standard_Real thePeriod) + const Standard_Real theUlTarget, + Bnd_Range &theRange, + const Standard_Real theTol2D, + const Standard_Real thePeriod) { - Standard_Real anUpar = theUfGiven; - const Standard_Real aDelta = theUlGiven - theUfGiven; - if(InscribePoint(theUfTarget, theUlTarget, anUpar, - theTol2D, thePeriod, Standard_False)) + Standard_Real anUpar = 0.0; + if (!theRange.GetMin(anUpar)) { - theUfGiven = anUpar; - theUlGiven = theUfGiven + aDelta; + return Standard_False; + } + + const Standard_Real aDelta = theRange.Delta(); + if(InscribePoint(theUfTarget, theUlTarget, anUpar, + theTol2D, thePeriod, (Abs(theUlTarget-anUpar) < theTol2D))) + { + theRange.SetVoid(); + theRange.Add(anUpar); + theRange.Add(anUpar + aDelta); } else { - anUpar = theUlGiven; - if(InscribePoint(theUfTarget, theUlTarget, anUpar, - theTol2D, thePeriod, Standard_False)) + if (!theRange.GetMAX(anUpar)) { - theUlGiven = anUpar; - theUfGiven = theUlGiven - aDelta; + return Standard_False; + } + + if(InscribePoint(theUfTarget, theUlTarget, anUpar, + theTol2D, thePeriod, (Abs(theUfTarget-anUpar) < theTol2D))) + { + theRange.SetVoid(); + theRange.Add(anUpar); + theRange.Add(anUpar - aDelta); } else { @@ -1811,6 +1832,11 @@ static Standard_Boolean ExcludeNearElements(Standard_Real theArr[], //======================================================================= //function : AddPointIntoWL //purpose : Surf1 is a surface, whose U-par is variable. +// If theFlBefore == TRUE then we enable the U1-parameter +// of the added point to be less than U1-parameter of +// previously added point (in general U1-parameter is +// always increased; therefore, this situation is abnormal). +// If theOnlyCheck==TRUE then no point will be added to theLine. //======================================================================= static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, const IntSurf_Quadric& theQuad2, @@ -1832,8 +1858,8 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, const Standard_Integer theWLIndex, const Standard_Real theTol3D, const Standard_Real theTol2D, - const Standard_Boolean theFlForce, - const Standard_Boolean theFlBefore = Standard_False) + const Standard_Boolean theFlBefore = Standard_False, + const Standard_Boolean theOnlyCheck = Standard_False) { //Check if the point is in the domain or can be inscribed in the domain after adjusting. @@ -1841,10 +1867,39 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, aPt2(theQuad2.Value(thePntOnSurf2.X(), thePntOnSurf2.Y())); Standard_Real aU1par = thePntOnSurf1.X(); + + // aU1par always increases. Therefore, we must reduce its + // value in order to continue creation of WLine. if(!InscribePoint(theUfSurf1, theUlSurf1, aU1par, theTol2D, - thePeriodOfSurf1, theFlForce)) + thePeriodOfSurf1, aU1par > 0.5*(theUfSurf1+theUlSurf1))) return Standard_False; + if ((theLine->NbPoints() > 0) && + ((theUlSurf1 - theUfSurf1) >= thePeriodOfSurf1) && + (((aU1par + thePeriodOfSurf1 - theUlSurf1) <= theTol2D) || + ((aU1par - thePeriodOfSurf1 - theUfSurf1) >= theTol2D))) + { + // aU1par can be adjusted to both theUlSurf1 and theUfSurf1 + // with equal possibilities. This code fragment allows choosing + // correct parameter from these two variants. + + Standard_Real aU1 = 0.0, aV1 = 0.0; + if (isTheReverse) + { + theLine->Value(theLine->NbPoints()).ParametersOnS2(aU1, aV1); + } + else + { + theLine->Value(theLine->NbPoints()).ParametersOnS1(aU1, aV1); + } + + const Standard_Real aDelta = aU1 - aU1par; + if (2.0*Abs(aDelta) > thePeriodOfSurf1) + { + aU1par += Sign(thePeriodOfSurf1, aDelta); + } + } + Standard_Real aU2par = thePntOnSurf2.X(); if(!InscribePoint(theUfSurf2, theUlSurf2, aU2par, theTol2D, thePeriodOfSurf1, Standard_False)) @@ -1887,7 +1942,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, if(!theFlBefore && (aU1par <= aUl)) { //Parameter value must be increased if theFlBefore == FALSE. - + aU1par += thePeriodOfSurf1; //The condition is as same as in @@ -1902,6 +1957,9 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, } } + if (theOnlyCheck) + return Standard_True; + //theTol2D is minimal step along parameter changed. //Therefore, if we apply this minimal step two //neighbour points will be always "same". Consequently, @@ -1913,6 +1971,9 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, } } + if (theOnlyCheck) + return Standard_True; + theLine->Add(aPnt); if(!isThePrecise) @@ -1959,6 +2020,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, //======================================================================= void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, const Standard_Real theU1, + const Standard_Real theU1Min, const Standard_Real theU2, const Standard_Real theV1, const Standard_Real theV1Prev, @@ -1995,7 +2057,6 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, for(Standard_Integer anIDBound = 0; anIDBound < 2; anIDBound++) { - const Standard_Integer anIndex = anIDSurf+anIDBound; aUVPoint[anIndex].mySurfID = anIDSurf; @@ -2015,7 +2076,10 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, theU2, theU1, aUVPoint[anIndex].myU1); - if(!aRes || aUVPoint[anIndex].myU1 >= theU1) + // aUVPoint[anIndex].myU1 is considered to be nearer to theU1 than + // to theU1+/-Period + if (!aRes || (aUVPoint[anIndex].myU1 >= theU1) || + (aUVPoint[anIndex].myU1 < theU1Min)) { //Intersection point is not found or out of the domain aUVPoint[anIndex].myU1 = RealLast(); @@ -2218,8 +2282,10 @@ static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1, //purpose : Computes true domain of future intersection curve (allows // avoiding excess iterations) //======================================================================= -Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], - Standard_Real theU1l[]) const +Standard_Boolean WorkWithBoundaries:: + BoundariesComputing(const ComputationMethods::stCoeffsValue &theCoeffs, + const Standard_Real thePeriod, + Bnd_Range theURange[]) { //All comments to this method is related to the comment //to ComputationMethods class @@ -2229,59 +2295,58 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], //Evidently, // -1 <= B*cos(U1-FI1)+C <= 1 - if(myCoeffs.mB > 0.0) + if (theCoeffs.mB > 0.0) { // -(1+C)/B <= cos(U1-FI1) <= (1-C)/B - if(myCoeffs.mB + Abs(myCoeffs.mC) < -1.0) + if (theCoeffs.mB + Abs(theCoeffs.mC) < -1.0) { //(1-C)/B < -1 or -(1+C)/B > 1 ==> No solution return Standard_False; } - else if(myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0) + else if (theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0) { //(1-C)/B >= 1 and -(1+C)/B <= -1 ==> U=[0;2*PI]+aFI1 - - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = myPeriod + myCoeffs.mFI1; + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(thePeriod + theCoeffs.mFI1); } - else if((1 + myCoeffs.mC <= myCoeffs.mB) && - (myCoeffs.mB <= 1 - myCoeffs.mC)) + else if ((1 + theCoeffs.mC <= theCoeffs.mB) && + (theCoeffs.mB <= 1 - theCoeffs.mC)) { //(1-C)/B >= 1 and -(1+C)/B >= -1 ==> //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1), //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB) - Standard_Real anArg = -(myCoeffs.mC + 1) / myCoeffs.mB; + Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB; if(anArg > 1.0) anArg = 1.0; if(anArg < -1.0) anArg = -1.0; const Standard_Real aDAngle = acos(anArg); - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = aDAngle + myCoeffs.mFI1; - theU1f[1] = myPeriod - aDAngle + myCoeffs.mFI1; - theU1l[1] = myPeriod + myCoeffs.mFI1; + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(aDAngle + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1); + theURange[1].Add(thePeriod + theCoeffs.mFI1); } - else if((1 - myCoeffs.mC <= myCoeffs.mB) && - (myCoeffs.mB <= 1 + myCoeffs.mC)) + else if ((1 - theCoeffs.mC <= theCoeffs.mB) && + (theCoeffs.mB <= 1 + theCoeffs.mC)) { //(1-C)/B <= 1 and -(1+C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1 //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB) - Standard_Real anArg = (1 - myCoeffs.mC) / myCoeffs.mB; + Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB; if(anArg > 1.0) anArg = 1.0; if(anArg < -1.0) anArg = -1.0; const Standard_Real aDAngle = acos(anArg); - theU1f[0] = aDAngle + myCoeffs.mFI1; - theU1l[0] = myPeriod - aDAngle + myCoeffs.mFI1; + theURange[0].Add(aDAngle + theCoeffs.mFI1); + theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1); } - else if(myCoeffs.mB - Abs(myCoeffs.mC) >= 1.0) + else if (theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0) { //(1-C)/B <= 1 and -(1+C)/B >= -1 ==> //(U=[aDAngle1;aDAngle2]+aFI1) || @@ -2289,8 +2354,8 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], //where aDAngle1 = acos((1 - myCoeffs.mC) / myCoeffs.mB), // aDAngle2 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB). - Standard_Real anArg1 = (1 - myCoeffs.mC) / myCoeffs.mB, - anArg2 = -(myCoeffs.mC + 1) / myCoeffs.mB; + Standard_Real anArg1 = (1 - theCoeffs.mC) / theCoeffs.mB, + anArg2 = -(theCoeffs.mC + 1) / theCoeffs.mB; if(anArg1 > 1.0) anArg1 = 1.0; if(anArg1 < -1.0) @@ -2304,77 +2369,75 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2); //(U=[aDAngle1;aDAngle2]+aFI1) || //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1) - - theU1f[0] = aDAngle1 + myCoeffs.mFI1; - theU1l[0] = aDAngle2 + myCoeffs.mFI1; - theU1f[1] = myPeriod - aDAngle2 + myCoeffs.mFI1; - theU1l[1] = myPeriod - aDAngle1 + myCoeffs.mFI1; + theURange[0].Add(aDAngle1 + theCoeffs.mFI1); + theURange[0].Add(aDAngle2 + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1); } else { return Standard_False; } } - else if(myCoeffs.mB < 0.0) + else if (theCoeffs.mB < 0.0) { // (1-C)/B <= cos(U1-FI1) <= -(1+C)/B - if(myCoeffs.mB + Abs(myCoeffs.mC) > 1.0) + if (theCoeffs.mB + Abs(theCoeffs.mC) > 1.0) { // -(1+C)/B < -1 or (1-C)/B > 1 ==> No solutions return Standard_False; } - else if(-myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0) + else if (-theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0) { // -(1+C)/B >= 1 and (1-C)/B <= -1 ==> U=[0;2*PI]+aFI1 - - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = myPeriod + myCoeffs.mFI1; + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(thePeriod + theCoeffs.mFI1); } - else if((-myCoeffs.mC - 1 <= myCoeffs.mB) && - ( myCoeffs.mB <= myCoeffs.mC - 1)) + else if ((-theCoeffs.mC - 1 <= theCoeffs.mB) && + (theCoeffs.mB <= theCoeffs.mC - 1)) { // -(1+C)/B >= 1 and (1-C)/B >= -1 ==> //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1), //where aDAngle = acos((1 - myCoeffs.mC) / myCoeffs.mB) - Standard_Real anArg = (1 - myCoeffs.mC) / myCoeffs.mB; + Standard_Real anArg = (1 - theCoeffs.mC) / theCoeffs.mB; if(anArg > 1.0) anArg = 1.0; if(anArg < -1.0) anArg = -1.0; const Standard_Real aDAngle = acos(anArg); - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = aDAngle + myCoeffs.mFI1; - theU1f[1] = myPeriod - aDAngle + myCoeffs.mFI1; - theU1l[1] = myPeriod + myCoeffs.mFI1; + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(aDAngle + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle + theCoeffs.mFI1); + theURange[1].Add(thePeriod + theCoeffs.mFI1); } - else if((myCoeffs.mC - 1 <= myCoeffs.mB) && - (myCoeffs.mB <= -myCoeffs.mB - 1)) + else if ((theCoeffs.mC - 1 <= theCoeffs.mB) && + (theCoeffs.mB <= -theCoeffs.mB - 1)) { // -(1+C)/B <= 1 and (1-C)/B <= -1 ==> U=[aDAngle;2*PI-aDAngle]+aFI1, //where aDAngle = acos(-(myCoeffs.mC + 1) / myCoeffs.mB). - Standard_Real anArg = -(myCoeffs.mC + 1) / myCoeffs.mB; + Standard_Real anArg = -(theCoeffs.mC + 1) / theCoeffs.mB; if(anArg > 1.0) anArg = 1.0; if(anArg < -1.0) anArg = -1.0; const Standard_Real aDAngle = acos(anArg); - theU1f[0] = aDAngle + myCoeffs.mFI1; - theU1l[0] = myPeriod - aDAngle + myCoeffs.mFI1; + theURange[0].Add(aDAngle + theCoeffs.mFI1); + theURange[0].Add(thePeriod - aDAngle + theCoeffs.mFI1); } - else if(-myCoeffs.mB - Abs(myCoeffs.mC) >= 1.0) + else if (-theCoeffs.mB - Abs(theCoeffs.mC) >= 1.0) { // -(1+C)/B <= 1 and (1-C)/B >= -1 ==> //(U=[aDAngle1;aDAngle2]+aFI1) || (U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1), //where aDAngle1 = acos(-(myCoeffs.mC + 1) / myCoeffs.mB), // aDAngle2 = acos((1 - myCoeffs.mC) / myCoeffs.mB) - Standard_Real anArg1 = -(myCoeffs.mC + 1) / myCoeffs.mB, - anArg2 = (1 - myCoeffs.mC) / myCoeffs.mB; + Standard_Real anArg1 = -(theCoeffs.mC + 1) / theCoeffs.mB, + anArg2 = (1 - theCoeffs.mC) / theCoeffs.mB; if(anArg1 > 1.0) anArg1 = 1.0; if(anArg1 < -1.0) @@ -2386,10 +2449,10 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], anArg2 = -1.0; const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2); - theU1f[0] = aDAngle1 + myCoeffs.mFI1; - theU1l[0] = aDAngle2 + myCoeffs.mFI1; - theU1f[1] = myPeriod - aDAngle2 + myCoeffs.mFI1; - theU1l[1] = myPeriod - aDAngle1 + myCoeffs.mFI1; + theURange[0].Add(aDAngle1 + theCoeffs.mFI1); + theURange[0].Add(aDAngle2 + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle2 + theCoeffs.mFI1); + theURange[1].Add(thePeriod - aDAngle1 + theCoeffs.mFI1); } else { @@ -2595,133 +2658,77 @@ void WorkWithBoundaries::BoundaryEstimation(const gp_Cylinder& theCy1, } //======================================================================= -//function : IntCyCy +//function : CyCyNoGeometric //purpose : //======================================================================= -IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, - const IntSurf_Quadric& theQuad2, - const Standard_Real theTol3D, - const Standard_Real theTol2D, - const Bnd_Box2d& theUVSurf1, - const Bnd_Box2d& theUVSurf2, - const Standard_Boolean isTheReverse, - Standard_Boolean& isTheEmpty, - Standard_Boolean& isTheSameSurface, - Standard_Boolean& isTheMultiplePoint, - IntPatch_SequenceOfLine& theSlin, - IntPatch_SequenceOfPoint& theSPnt) +static IntPatch_ImpImpIntersection::IntStatus + CyCyNoGeometric(const gp_Cylinder &theCyl1, + const gp_Cylinder &theCyl2, + const WorkWithBoundaries &theBW, + Bnd_Range theRange[], + const Standard_Integer theNbOfRanges /*=2*/, + Standard_Boolean& isTheEmpty, + IntPatch_SequenceOfLine& theSlin, + IntPatch_SequenceOfPoint& theSPnt) { - isTheEmpty = Standard_True; - isTheSameSurface = Standard_False; - isTheMultiplePoint = Standard_False; - theSlin.Clear(); - theSPnt.Clear(); + Standard_Real aUSurf1f = 0.0, aUSurf1l = 0.0, + aUSurf2f = 0.0, aUSurf2l = 0.0, + aVSurf1f = 0.0, aVSurf1l = 0.0, + aVSurf2f = 0.0, aVSurf2l = 0.0; - const gp_Cylinder &aCyl1 = theQuad1.Cylinder(), - &aCyl2 = theQuad2.Cylinder(); - - IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D); - - if (!anInter.IsDone()) - { - return IntPatch_ImpImpIntersection::IntStatus_Fail; - } - - if(anInter.TypeInter() != IntAna_NoGeometricSolution) - { - if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter, - theTol3D, isTheReverse, isTheEmpty, - isTheSameSurface, isTheMultiplePoint, - theSlin, theSPnt)) - { - return IntPatch_ImpImpIntersection::IntStatus_OK; - } - } - - //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.) - - Standard_Real aUSurf1f = 0.0, //const - aUSurf1l = 0.0, - aVSurf1f = 0.0, - aVSurf1l = 0.0; - Standard_Real aUSurf2f = 0.0, //const - aUSurf2l = 0.0, - aVSurf2f = 0.0, - aVSurf2l = 0.0; - - theUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l); - theUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l); - - const Standard_Integer aNbMaxPoints = 2000; - const Standard_Integer aNbMinPoints = 200; - const Standard_Integer aNbPoints = Min(Max(aNbMinPoints, - RealToInt(20.0*aCyl1.Radius())), aNbMaxPoints); - const Standard_Real aPeriod = 2.0*M_PI; - const Standard_Real aStepMin = theTol2D, - aStepMax = (aUSurf1l-aUSurf1f > M_PI/100.0) ? - (aUSurf1l-aUSurf1f)/IntToReal(aNbPoints) : - aUSurf1l-aUSurf1f; - - const Standard_Integer aNbWLines = 2; - - const ComputationMethods::stCoeffsValue anEquationCoeffs(aCyl1, aCyl2); - - const WorkWithBoundaries aBoundWork(theQuad1, theQuad2, anEquationCoeffs, - theUVSurf1, theUVSurf2, aNbWLines, - aPeriod, theTol3D, theTol2D, isTheReverse); + theBW.UVS1().Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l); + theBW.UVS2().Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l); Bnd_Range aRangeS1, aRangeS2; - aBoundWork.BoundaryEstimation(aCyl1, aCyl2, aRangeS1, aRangeS2); + theBW.BoundaryEstimation(theCyl1, theCyl2, aRangeS1, aRangeS2); if (aRangeS1.IsVoid() || aRangeS2.IsVoid()) return IntPatch_ImpImpIntersection::IntStatus_OK; { - //Quotation of the message from issue #26894 (author MSV): - //"We should return fail status from intersector if the result should be an - //infinite curve of non-analytical type... I propose to define the limit for the - //extent as the radius divided by 1e+2 and multiplied by 1e+7. - //Thus, taking into account the number of valuable digits (15), we provide reliable - //computations with an error not exceeding R/100." + //Quotation of the message from issue #26894 (author MSV): + //"We should return fail status from intersector if the result should be an + //infinite curve of non-analytical type... I propose to define the limit for the + //extent as the radius divided by 1e+2 and multiplied by 1e+7. + //Thus, taking into account the number of valuable digits (15), we provide reliable + //computations with an error not exceeding R/100." const Standard_Real aF = 1.0e+5; - const Standard_Real aMaxV1Range = aF*aCyl1.Radius(), aMaxV2Range = aF*aCyl2.Radius(); + const Standard_Real aMaxV1Range = aF*theCyl1.Radius(), aMaxV2Range = aF*theCyl2.Radius(); if ((aRangeS1.Delta() > aMaxV1Range) || (aRangeS2.Delta() > aMaxV2Range)) return IntPatch_ImpImpIntersection::IntStatus_InfiniteSectionCurve; } - //Boundaries (it is good idea to use Bnd_Range in the future, instead of aU1f and aU1l) - //Intersection result can include two non-connected regions - //(see WorkWithBoundaries::BoundariesComputing(...) method). - const Standard_Integer aNbOfBoundaries = 2; - Standard_Real aU1f[aNbOfBoundaries] = {-Precision::Infinite(), -Precision::Infinite()}; - Standard_Real aU1l[aNbOfBoundaries] = {Precision::Infinite(), Precision::Infinite()}; - - if(!aBoundWork.BoundariesComputing(aU1f, aU1l)) - return IntPatch_ImpImpIntersection::IntStatus_OK; + const ComputationMethods::stCoeffsValue &anEquationCoeffs = theBW.SICoeffs(); + const IntSurf_Quadric& aQuad1 = theBW.GetQSurface(1); + const IntSurf_Quadric& aQuad2 = theBW.GetQSurface(2); + const Standard_Boolean isReversed = theBW.IsReversed(); + const Standard_Real aTol2D = theBW.Get2dTolerance(); + const Standard_Real aTol3D = theBW.Get3dTolerance(); + const Standard_Real aPeriod = 2.0*M_PI; + const Standard_Integer aNbMaxPoints = 2000; + const Standard_Integer aNbMinPoints = 200; + const Standard_Integer aNbPoints = Min(Max(aNbMinPoints, + RealToInt(20.0*theCyl1.Radius())), aNbMaxPoints); + const Standard_Real aStepMin = aTol2D, + aStepMax = (aUSurf1l - aUSurf1f > M_PI / 100.0) ? + (aUSurf1l - aUSurf1f) / IntToReal(aNbPoints) : + aUSurf1l - aUSurf1f; //The main idea of the algorithm is to change U1-parameter - //(U-parameter of aCyl1) from aU1f to aU1l with some step + //(U-parameter of theCyl1) from aU1f to aU1l with some step //(step is adaptive) and to obtain set of intersection points. - for(Standard_Integer i = 0; i < aNbOfBoundaries; i++) + for (Standard_Integer i = 0; i < theNbOfRanges; i++) { - if(Precision::IsInfinite(aU1f[i]) && Precision::IsInfinite(aU1l[i])) + if (theRange[i].IsVoid()) continue; - InscribeInterval(aUSurf1f, aUSurf1l, aU1f[i], aU1l[i], theTol2D, aPeriod); + InscribeInterval(aUSurf1f, aUSurf1l, theRange[i], aTol2D, aPeriod); } - if( !Precision::IsInfinite(aU1f[0]) && !Precision::IsInfinite(aU1f[1]) && - !Precision::IsInfinite(aU1l[0]) && !Precision::IsInfinite(aU1l[1])) + if (theRange[0].Union(theRange[1])) { - if( ((aU1f[1] <= aU1l[0]) || (aU1l[1] <= aU1l[0])) && - ((aU1f[0] <= aU1l[1]) || (aU1l[0] <= aU1l[1]))) - {//Join all intervals to one - aU1f[0] = Min(aU1f[0], aU1f[1]); - aU1l[0] = Max(aU1l[0], aU1l[1]); - - aU1f[1] = -Precision::Infinite(); - aU1l[1] = Precision::Infinite(); - } + // Works only if (theNbOfRanges == 2). + theRange[1].SetVoid(); } //Critical points are the value of U1-parameter in the points @@ -2733,18 +2740,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //See CriticalPointsComputing(...) function to get detail information about this array. const Standard_Integer aNbCritPointsMax = 12; - Standard_Real anU1crit[aNbCritPointsMax] = {Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite(), - Precision::Infinite()}; + Standard_Real anU1crit[aNbCritPointsMax] = { Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite(), + Precision::Infinite() }; //This list of critical points is not full because it does not contain any points //which intersection line goes through V-bounds of cylinders in. @@ -2753,7 +2760,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, Standard_Integer aNbCritPoints = aNbCritPointsMax; CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, - aPeriod, theTol2D, aNbCritPoints, anU1crit); + aPeriod, aTol2D, aNbCritPoints, anU1crit); //Getting Walking-line @@ -2762,35 +2769,35 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, // No points have been added in WL WLFStatus_Absent = 0, // WL contains at least one point - WLFStatus_Exist = 1, + WLFStatus_Exist = 1, // WL has been finished in some critical point // We should start new line WLFStatus_Broken = 2 }; - for(Standard_Integer aCurInterval = 0; aCurInterval < aNbOfBoundaries; aCurInterval++) + const Standard_Integer aNbWLines = 2; + for (Standard_Integer aCurInterval = 0; aCurInterval < theNbOfRanges; aCurInterval++) { //Process every continuous region - - if(Precision::IsInfinite(aU1f[aCurInterval]) && Precision::IsInfinite(aU1l[aCurInterval])) - continue; - Standard_Boolean isAddedIntoWL[aNbWLines]; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) isAddedIntoWL[i] = Standard_False; - Standard_Real anUf = aU1f[aCurInterval], anUl = aU1l[aCurInterval]; - const Standard_Boolean isDeltaPeriod = IsEqual(anUl-anUf, aPeriod); + Standard_Real anUf = 1.0, anUl = 0.0; + if (!theRange[aCurInterval].GetBounds(anUf, anUl)) + continue; + + const Standard_Boolean isDeltaPeriod = IsEqual(anUl - anUf, aPeriod); //Inscribe and sort critical points - for(Standard_Integer i = 0; i < aNbCritPoints; i++) + for (Standard_Integer i = 0; i < aNbCritPoints; i++) { - InscribePoint(anUf, anUl, anU1crit[i], theTol2D, aPeriod, Standard_False); + InscribePoint(anUf, anUl, anU1crit[i], 0.0, aPeriod, Standard_False); } std::sort(anU1crit, anU1crit + aNbCritPoints); - while(anUf < anUl) + while (anUf < anUl) { //Change value of U-parameter on the 1st surface from anUf to anUl //(anUf will be modified in the cycle body). @@ -2804,7 +2811,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, Handle(IntSurf_LineOn2S) aL2S[aNbWLines]; Handle(IntPatch_WLine) aWLine[aNbWLines]; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { aL2S[i] = new IntSurf_LineOn2S(); aWLine[i] = new IntPatch_WLine(aL2S[i], Standard_False); @@ -2814,33 +2821,33 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, aV1Prev[i] = aV2Prev[i] = 0.0; anUexpect[i] = anUf; } - - Standard_Real aCriticalDelta[aNbCritPointsMax] = {0}; - for(Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++) + + Standard_Real aCriticalDelta[aNbCritPointsMax] = { 0 }; + for (Standard_Integer aCritPID = 0; aCritPID < aNbCritPoints; aCritPID++) { //We are not interested in elements of aCriticalDelta array //if their index is greater than or equal to aNbCritPoints aCriticalDelta[aCritPID] = anUf - anU1crit[aCritPID]; } - Standard_Real anU1 = anUf; + Standard_Real anU1 = anUf, aMinCriticalParam = anUf; Standard_Boolean isFirst = Standard_True; - - while(anU1 <= anUl) + + while (anU1 <= anUl) { //Change value of U-parameter on the 1st surface from anUf to anUl //(anUf will be modified in the cycle body). However, this cycle //can be broken if WL goes though some critical point. //Step is computed adaptively (see comments below). - for(Standard_Integer i = 0; i < aNbCritPoints; i++) + for (Standard_Integer i = 0; i < aNbCritPoints; i++) { - if((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0) + if ((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0) { //WL has gone through i-th critical point anU1 = anU1crit[i]; - for(Standard_Integer j = 0; j < aNbWLines; j++) + for (Standard_Integer j = 0; j < aNbWLines; j++) { aWLFindStatus[j] = WLFStatus_Broken; anUexpect[j] = anU1; @@ -2850,14 +2857,14 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } } - if(IsEqual(anU1, anUl)) + if (IsEqual(anU1, anUl)) { - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { aWLFindStatus[i] = WLFStatus_Broken; anUexpect[i] = anU1; - if(isDeltaPeriod) + if (isDeltaPeriod) { //if isAddedIntoWL[i] == TRUE WLine contains only one point //(which was end point of previous WLine). If we will @@ -2871,57 +2878,57 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } else { - isAddingWLEnabled[i] = ((theTol2D >= (anUexpect[i] - anU1)) || + isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) || (aWLFindStatus[i] == WLFStatus_Absent)); } }//for(Standard_Integer i = 0; i < aNbWLines; i++) } else { - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - isAddingWLEnabled[i] = ((theTol2D >= (anUexpect[i] - anU1)) || + isAddingWLEnabled[i] = ((aTol2D >= (anUexpect[i] - anU1)) || (aWLFindStatus[i] == WLFStatus_Absent)); }//for(Standard_Integer i = 0; i < aNbWLines; i++) } - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - const Standard_Integer aNbPntsWL = aWLine[i].IsNull() ? 0 : - aWLine[i]->Curve()->NbPoints(); - - if( (aWLFindStatus[i] == WLFStatus_Broken) || - (aWLFindStatus[i] == WLFStatus_Absent)) + const Standard_Integer aNbPntsWL = aWLine[i].IsNull() ? 0 : + aWLine[i]->Curve()->NbPoints(); + + if ((aWLFindStatus[i] == WLFStatus_Broken) || + (aWLFindStatus[i] == WLFStatus_Absent)) {//Begin and end of WLine must be on boundary point //or on seam-edge strictly (if it is possible). - Standard_Real aTol = theTol2D; + Standard_Real aTol = aTol2D; ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i], &aTol); - InscribePoint(aUSurf2f, aUSurf2l, aU2[i], theTol2D, aPeriod, Standard_False); + InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False); - aTol = Max(aTol, theTol2D); + aTol = Max(aTol, aTol2D); - if(Abs(aU2[i]) <= aTol) + if (Abs(aU2[i]) <= aTol) aU2[i] = 0.0; - else if(Abs(aU2[i] - aPeriod) <= aTol) + else if (Abs(aU2[i] - aPeriod) <= aTol) aU2[i] = aPeriod; - else if(Abs(aU2[i] - aUSurf2f) <= aTol) + else if (Abs(aU2[i] - aUSurf2f) <= aTol) aU2[i] = aUSurf2f; - else if(Abs(aU2[i] - aUSurf2l) <= aTol) + else if (Abs(aU2[i] - aUSurf2l) <= aTol) aU2[i] = aUSurf2l; } else { ComputationMethods::CylCylComputeParameters(anU1, i, anEquationCoeffs, aU2[i]); - InscribePoint(aUSurf2f, aUSurf2l, aU2[i], theTol2D, aPeriod, Standard_False); + InscribePoint(aUSurf2f, aUSurf2l, aU2[i], aTol2D, aPeriod, Standard_False); } - - if(aNbPntsWL == 0) + + if (aNbPntsWL == 0) {//the line has not contained any points yet - if(((aUSurf2f + aPeriod - aUSurf2l) <= 2.0*theTol2D) && - ((Abs(aU2[i] - aUSurf2f) < theTol2D) || - (Abs(aU2[i]-aUSurf2l) < theTol2D))) + if (((aUSurf2f + aPeriod - aUSurf2l) <= 2.0*aTol2D) && + ((Abs(aU2[i] - aUSurf2f) < aTol2D) || + (Abs(aU2[i] - aUSurf2l) < aTol2D))) { //In this case aU2[i] can have two values: current aU2[i] or //aU2[i]+aPeriod (aU2[i]-aPeriod). It is necessary to choose @@ -2936,7 +2943,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //increased too. And we will go out of surface boundary. //Therefore, If U2(U1) is increasing then U2 must be equal aUSurf2f. //Analogically, if U2(U1) is decreasing. - if(isIncreasing) + if (isIncreasing) { aU2[i] = aUSurf2f; } @@ -2948,19 +2955,19 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } else {//aNbPntsWL > 0 - if(((aUSurf2l - aUSurf2f) >= aPeriod) && - ((Abs(aU2[i] - aUSurf2f) < theTol2D) || - (Abs(aU2[i]-aUSurf2l) < theTol2D))) + if (((aUSurf2l - aUSurf2f) >= aPeriod) && + ((Abs(aU2[i] - aUSurf2f) < aTol2D) || + (Abs(aU2[i] - aUSurf2l) < aTol2D))) {//end of the line Standard_Real aU2prev = 0.0, aV2prev = 0.0; - if(isTheReverse) + if (isReversed) aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS1(aU2prev, aV2prev); else aWLine[i]->Curve()->Value(aNbPntsWL).ParametersOnS2(aU2prev, aV2prev); - if(2.0*Abs(aU2prev - aU2[i]) > aPeriod) + if (2.0*Abs(aU2prev - aU2[i]) > aPeriod) { - if(aU2prev > aU2[i]) + if (aU2prev > aU2[i]) aU2[i] += aPeriod; else aU2[i] -= aPeriod; @@ -2971,7 +2978,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, ComputationMethods::CylCylComputeParameters(anU1, aU2[i], anEquationCoeffs, aV1[i], aV2[i]); - if(isFirst) + if (isFirst) { aV1Prev[i] = aV1[i]; aV2Prev[i] = aV2[i]; @@ -2982,36 +2989,36 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //Looking for points into WLine Standard_Boolean isBroken = Standard_False; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(!isAddingWLEnabled[i]) + if (!isAddingWLEnabled[i]) { Standard_Boolean isBoundIntersect = Standard_False; - if( (Abs(aV1[i] - aVSurf1f) <= theTol2D) || - ((aV1[i]-aVSurf1f)*(aV1Prev[i]-aVSurf1f) < 0.0)) + if ((Abs(aV1[i] - aVSurf1f) <= aTol2D) || + ((aV1[i] - aVSurf1f)*(aV1Prev[i] - aVSurf1f) < 0.0)) { isBoundIntersect = Standard_True; } - else if( (Abs(aV1[i] - aVSurf1l) <= theTol2D) || - ( (aV1[i]-aVSurf1l)*(aV1Prev[i]-aVSurf1l) < 0.0)) + else if ((Abs(aV1[i] - aVSurf1l) <= aTol2D) || + ((aV1[i] - aVSurf1l)*(aV1Prev[i] - aVSurf1l) < 0.0)) { isBoundIntersect = Standard_True; } - else if( (Abs(aV2[i] - aVSurf2f) <= theTol2D) || - ( (aV2[i]-aVSurf2f)*(aV2Prev[i]-aVSurf2f) < 0.0)) + else if ((Abs(aV2[i] - aVSurf2f) <= aTol2D) || + ((aV2[i] - aVSurf2f)*(aV2Prev[i] - aVSurf2f) < 0.0)) { isBoundIntersect = Standard_True; } - else if( (Abs(aV2[i] - aVSurf2l) <= theTol2D) || - ( (aV2[i]-aVSurf2l)*(aV2Prev[i]-aVSurf2l) < 0.0)) + else if ((Abs(aV2[i] - aVSurf2l) <= aTol2D) || + ((aV2[i] - aVSurf2l)*(aV2Prev[i] - aVSurf2l) < 0.0)) { isBoundIntersect = Standard_True; } - if(aWLFindStatus[i] == WLFStatus_Broken) + if (aWLFindStatus[i] == WLFStatus_Broken) isBroken = Standard_True; - if(!isBoundIntersect) + if (!isBoundIntersect) { continue; } @@ -3022,19 +3029,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } // True if the current point already in the domain - const Standard_Boolean isInscribe = - ((aUSurf2f-aU2[i]) <= theTol2D) && ((aU2[i]-aUSurf2l) <= theTol2D) && - ((aVSurf1f - aV1[i]) <= theTol2D) && ((aV1[i] - aVSurf1l) <= theTol2D) && - ((aVSurf2f - aV2[i]) <= theTol2D) && ((aV2[i] - aVSurf2l) <= theTol2D); + const Standard_Boolean isInscribe = + ((aUSurf2f - aU2[i]) <= aTol2D) && ((aU2[i] - aUSurf2l) <= aTol2D) && + ((aVSurf1f - aV1[i]) <= aTol2D) && ((aV1[i] - aVSurf1l) <= aTol2D) && + ((aVSurf2f - aV2[i]) <= aTol2D) && ((aV2[i] - aVSurf2l) <= aTol2D); //isVIntersect == TRUE if intersection line intersects two (!) //V-bounds of cylinder (1st or 2nd - no matter) const Standard_Boolean isVIntersect = - ( ((aVSurf1f-aV1[i])*(aVSurf1f-aV1Prev[i]) < RealSmall()) && - ((aVSurf1l-aV1[i])*(aVSurf1l-aV1Prev[i]) < RealSmall())) || - ( ((aVSurf2f-aV2[i])*(aVSurf2f-aV2Prev[i]) < RealSmall()) && - ((aVSurf2l-aV2[i])*(aVSurf2l-aV2Prev[i]) < RealSmall())); - + (((aVSurf1f - aV1[i])*(aVSurf1f - aV1Prev[i]) < RealSmall()) && + ((aVSurf1l - aV1[i])*(aVSurf1l - aV1Prev[i]) < RealSmall())) || + (((aVSurf2f - aV2[i])*(aVSurf2f - aV2Prev[i]) < RealSmall()) && + ((aVSurf2l - aV2[i])*(aVSurf2l - aV2Prev[i]) < RealSmall())); //isFound1 == TRUE if intersection line intersects V-bounds // (First or Last - no matter) of the 1st cylynder @@ -3045,52 +3051,52 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, if (aWLFindStatus[i] == WLFStatus_Absent) { - if(((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1-aUSurf1l) < theTol2D)) + if (((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1 - aUSurf1l) < aTol2D)) { isForce = Standard_True; } } - aBoundWork.AddBoundaryPoint(aWLine[i], anU1, aU2[i], aV1[i], aV1Prev[i], - aV2[i], aV2Prev[i], i, isForce, - isFound1, isFound2); + theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i], + aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i, isForce, + isFound1, isFound2); const Standard_Boolean isPrevVBound = !isVIntersect && - ((Abs(aV1Prev[i] - aVSurf1f) <= theTol2D) || - (Abs(aV1Prev[i] - aVSurf1l) <= theTol2D) || - (Abs(aV2Prev[i] - aVSurf2f) <= theTol2D) || - (Abs(aV2Prev[i] - aVSurf2l) <= theTol2D)); + ((Abs(aV1Prev[i] - aVSurf1f) <= aTol2D) || + (Abs(aV1Prev[i] - aVSurf1l) <= aTol2D) || + (Abs(aV2Prev[i] - aVSurf2f) <= aTol2D) || + (Abs(aV2Prev[i] - aVSurf2l) <= aTol2D)); aV1Prev[i] = aV1[i]; aV2Prev[i] = aV2[i]; - if((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound) + if ((aWLFindStatus[i] == WLFStatus_Exist) && (isFound1 || isFound2) && !isPrevVBound) { aWLFindStatus[i] = WLFStatus_Broken; //start a new line } - else if(isInscribe) + else if (isInscribe) { - if((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2)) + if ((aWLFindStatus[i] == WLFStatus_Absent) && (isFound1 || isFound2)) { aWLFindStatus[i] = WLFStatus_Exist; } - if( (aWLFindStatus[i] != WLFStatus_Broken) || - (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl)) + if ((aWLFindStatus[i] != WLFStatus_Broken) || + (aWLine[i]->NbPnts() >= 1) || IsEqual(anU1, anUl)) { - if(aWLine[i]->NbPnts() > 0) + if (aWLine[i]->NbPnts() > 0) { Standard_Real aU2p = 0.0, aV2p = 0.0; - if(isTheReverse) + if (isReversed) aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p); else aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p); const Standard_Real aDelta = aU2[i] - aU2p; - if(2*Abs(aDelta) > aPeriod) + if (2.0 * Abs(aDelta) > aPeriod) { - if(aDelta > 0.0) + if (aDelta > 0.0) { aU2[i] -= aPeriod; } @@ -3101,47 +3107,47 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } } - if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse, Standard_True, + if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True, gp_Pnt2d(anU1, aV1[i]), gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod, - aWLine[i]->Curve(), i, theTol3D, theTol2D, isForce)) + aWLine[i]->Curve(), i, aTol3D, aTol2D, isForce)) { - if(aWLFindStatus[i] == WLFStatus_Absent) + if (aWLFindStatus[i] == WLFStatus_Absent) { aWLFindStatus[i] = WLFStatus_Exist; } } - else if(!isFound1 && !isFound2) + else if (!isFound1 && !isFound2) {//We do not add any point while doing this iteration - if(aWLFindStatus[i] == WLFStatus_Exist) + if (aWLFindStatus[i] == WLFStatus_Exist) { aWLFindStatus[i] = WLFStatus_Broken; - } + } } } } else {//We do not add any point while doing this iteration - if(aWLFindStatus[i] == WLFStatus_Exist) + if (aWLFindStatus[i] == WLFStatus_Exist) { aWLFindStatus[i] = WLFStatus_Broken; } } - - if(aWLFindStatus[i] == WLFStatus_Broken) + + if (aWLFindStatus[i] == WLFStatus_Broken) isBroken = Standard_True; }//for(Standard_Integer i = 0; i < aNbWLines; i++) - if(isBroken) + if (isBroken) {//current lines are filled. Go to the next lines anUf = anU1; Standard_Boolean isAdded = Standard_True; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(isAddingWLEnabled[i]) + if (isAddingWLEnabled[i]) { continue; } @@ -3150,28 +3156,28 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False; - aBoundWork.AddBoundaryPoint(aWLine[i], anU1, aU2[i], aV1[i], aV1Prev[i], - aV2[i], aV2Prev[i], i, - Standard_False, isFound1, isFound2); + theBW.AddBoundaryPoint(aWLine[i], anU1, aMinCriticalParam, aU2[i], + aV1[i], aV1Prev[i], aV2[i], aV2Prev[i], i, + Standard_False, isFound1, isFound2); - if(isFound1 || isFound2) + if (isFound1 || isFound2) { isAdded = Standard_True; } - if(aWLine[i]->NbPnts() > 0) + if (aWLine[i]->NbPnts() > 0) { Standard_Real aU2p = 0.0, aV2p = 0.0; - if(isTheReverse) + if (isReversed) aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS1(aU2p, aV2p); else aWLine[i]->Point(aWLine[i]->NbPnts()).ParametersOnS2(aU2p, aV2p); const Standard_Real aDelta = aU2[i] - aU2p; - if(2*Abs(aDelta) > aPeriod) + if (2 * Abs(aDelta) > aPeriod) { - if(aDelta > 0.0) + if (aDelta > 0.0) { aU2[i] -= aPeriod; } @@ -3182,18 +3188,18 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } } - if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse, + if(AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True, gp_Pnt2d(anU1, aV1[i]), gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(), - i, theTol3D, theTol2D, Standard_False)) + i, aTol3D, aTol2D, Standard_False)) { isAdded = Standard_True; } } - if(!isAdded) + if (!isAdded) { //Before breaking WL, we must complete it correctly //(e.g. to prolong to the surface boundary). @@ -3201,16 +3207,16 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //(have maximal U1-parameter) and try to add it in //the current WL. Standard_Real anUmaxAdded = RealFirst(); - + { Standard_Boolean isChanged = Standard_False; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(aWLFindStatus[i] == WLFStatus_Absent) + if (aWLFindStatus[i] == WLFStatus_Absent) continue; Standard_Real aU1c = 0.0, aV1c = 0.0; - if(isTheReverse) + if (isReversed) aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS2(aU1c, aV1c); else aWLine[i]->Curve()->Value(aWLine[i]->NbPnts()).ParametersOnS1(aU1c, aV1c); @@ -3219,29 +3225,29 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, isChanged = Standard_True; } - if(!isChanged) + if (!isChanged) { //If anUmaxAdded were not changed in previous cycle then //we would break existing WLines. break; } } - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(isAddingWLEnabled[i]) + if (isAddingWLEnabled[i]) { continue; } ComputationMethods::CylCylComputeParameters(anUmaxAdded, i, anEquationCoeffs, - aU2[i], aV1[i], aV2[i]); + aU2[i], aV1[i], aV2[i]); - AddPointIntoWL( theQuad1, theQuad2, anEquationCoeffs, isTheReverse, - Standard_True, gp_Pnt2d(anUmaxAdded, aV1[i]), - gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l, - aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l, - aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(), - i, theTol3D, theTol2D, Standard_False); + AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, + Standard_True, gp_Pnt2d(anUmaxAdded, aV1[i]), + gp_Pnt2d(aU2[i], aV2[i]), aUSurf1f, aUSurf1l, + aUSurf2f, aUSurf2l, aVSurf1f, aVSurf1l, + aVSurf2f, aVSurf2l, aPeriod, aWLine[i]->Curve(), + i, aTol3D, aTol2D, Standard_False); } } @@ -3257,21 +3263,21 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //in every iteration. It allows avoiding "flying" intersection //points too far each from other (see issue #24915). - const Standard_Real aDeltaV1 = aRangeS1.Delta()/IntToReal(aNbPoints), - aDeltaV2 = aRangeS2.Delta()/IntToReal(aNbPoints); - + const Standard_Real aDeltaV1 = aRangeS1.Delta() / IntToReal(aNbPoints), + aDeltaV2 = aRangeS2.Delta() / IntToReal(aNbPoints); + math_Matrix aMatr(1, 3, 1, 5); Standard_Real aMinUexp = RealLast(); - - for(Standard_Integer i = 0; i < aNbWLines; i++) + + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(theTol2D < (anUexpect[i] - anU1)) + if (aTol2D < (anUexpect[i] - anU1)) { continue; } - if(aWLFindStatus[i] == WLFStatus_Absent) + if (aWLFindStatus[i] == WLFStatus_Absent) { anUexpect[i] += aStepMax; aMinUexp = Min(aMinUexp, anUexpect[i]); @@ -3309,7 +3315,7 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //The solution is approximate. More over, all requirements to the //linearization must be satisfied in order to obtain quality result. - if(!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp)) + if (!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp)) { //To avoid cycling-up anUexpect[i] += aStepMax; @@ -3318,10 +3324,10 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, continue; } - if(aStepTmp < aStepMin) + if (aStepTmp < aStepMin) aStepTmp = aStepMin; - - if(aStepTmp > aStepMax) + + if (aStepTmp > aStepMax) aStepTmp = aStepMax; anUexpect[i] = anU1 + aStepTmp; @@ -3331,26 +3337,26 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, anU1 = aMinUexp; } - if(Precision::PConfusion() >= (anUl - anU1)) + if (Precision::PConfusion() >= (anUl - anU1)) anU1 = anUl; anUf = anU1; - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if(aWLine[i]->NbPnts() != 1) + if (aWLine[i]->NbPnts() != 1) isAddedIntoWL[i] = Standard_False; - if(anU1 == anUl) + if (anU1 == anUl) {//strictly equal. Tolerance is considered above. anUexpect[i] = anUl; } } } - for(Standard_Integer i = 0; i < aNbWLines; i++) + for (Standard_Integer i = 0; i < aNbWLines; i++) { - if((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i])) + if ((aWLine[i]->NbPnts() == 1) && (!isAddedIntoWL[i])) { isTheEmpty = Standard_False; Standard_Real u1, v1, u2, v2; @@ -3358,34 +3364,34 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, IntPatch_Point aP; aP.SetParameter(u1); aP.SetParameters(u1, v1, u2, v2); - aP.SetTolerance(theTol3D); + aP.SetTolerance(aTol3D); aP.SetValue(aWLine[i]->Point(1).Value()); theSPnt.Append(aP); } - else if(aWLine[i]->NbPnts() > 1) + else if (aWLine[i]->NbPnts() > 1) { Standard_Boolean isGood = Standard_True; - if(aWLine[i]->NbPnts() == 2) + if (aWLine[i]->NbPnts() == 2) { const IntSurf_PntOn2S& aPf = aWLine[i]->Point(1); const IntSurf_PntOn2S& aPl = aWLine[i]->Point(2); - - if(aPf.IsSame(aPl, Precision::Confusion())) + + if (aPf.IsSame(aPl, Precision::Confusion())) isGood = Standard_False; } - if(isGood) + if (isGood) { isTheEmpty = Standard_False; isAddedIntoWL[i] = Standard_True; - SeekAdditionalPoints( theQuad1, theQuad2, aWLine[i]->Curve(), - anEquationCoeffs, i, aNbPoints, 1, - aWLine[i]->NbPnts(), theTol2D, aPeriod, - isTheReverse); + SeekAdditionalPoints(aQuad1, aQuad2, aWLine[i]->Curve(), + anEquationCoeffs, i, aNbPoints, 1, + aWLine[i]->NbPnts(), aTol2D, aPeriod, + isReversed); - aWLine[i]->ComputeVertexParameters(theTol3D); + aWLine[i]->ComputeVertexParameters(aTol3D); theSlin.Append(aWLine[i]); } } @@ -3404,19 +3410,19 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, //Delete the points in theSPnt, which //lie at least in one of the line in theSlin. - for(Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++) + for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++) { - for(Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++) + for (Standard_Integer aNbLin = 1; aNbLin <= theSlin.Length(); aNbLin++) { - Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine):: - DownCast(theSlin.Value(aNbLin))); + Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine):: + DownCast(theSlin.Value(aNbLin))); const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aWLine1->NbPnts()); const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNbPnt).PntOn2S(); - if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) || - aPntCur.IsSame(aPntLWL1, Precision::Confusion())) + if (aPntCur.IsSame(aPntFWL1, Precision::Confusion()) || + aPntCur.IsSame(aPntLWL1, Precision::Confusion())) { theSPnt.Remove(aNbPnt); aNbPnt--; @@ -3425,10 +3431,20 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, } } - const Standard_Real aDU = aStepMin + Epsilon(aStepMin); - //Try to add new points in the neighbourhood of existing point - for(Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++) + //Try to add new points in the neighborhood of existing point + for (Standard_Integer aNbPnt = 1; aNbPnt <= theSPnt.Length(); aNbPnt++) { + // Standard algorithm (implemented above) could not find any + // continuous curve in neighborhood of aPnt2S (e.g. because + // this curve is too small; see tests\bugs\modalg_5\bug25292_35 and _36). + // Here, we will try to find several new points nearer to aPnt2S. + + // The algorithm below tries to find two points in every + // intervals [u1 - aStepMax, u1] and [u1, u1 + aStepMax] + // and every new point will be in maximal distance from + // u1. If these two points exist they will be joined + // by the intersection curve. + const IntPatch_Point& aPnt2S = theSPnt.Value(aNbPnt); Standard_Real u1, v1, u2, v2; @@ -3436,81 +3452,331 @@ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, Handle(IntSurf_LineOn2S) aL2S = new IntSurf_LineOn2S(); Handle(IntPatch_WLine) aWLine = new IntPatch_WLine(aL2S, Standard_False); - aWLine->Curve()->Add(aPnt2S.PntOn2S()); //Define the index of WLine, which lies the point aPnt2S in. - Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0; Standard_Integer anIndex = 0; - if(isTheReverse) + + Standard_Real anUf = 0.0, anUl = 0.0, aCurU2 = 0.0; + if (isReversed) { anUf = Max(u2 - aStepMax, aUSurf1f); - anUl = u2; + anUl = Min(u2 + aStepMax, aUSurf1l); aCurU2 = u1; } else { anUf = Max(u1 - aStepMax, aUSurf1f); - anUl = u1; + anUl = Min(u1 + aStepMax, aUSurf1l); aCurU2 = u2; } - Standard_Real aDelta = RealLast(); - for (Standard_Integer i = 0; i < aNbWLines; i++) - { - Standard_Real anU2t = 0.0; - if(!ComputationMethods::CylCylComputeParameters(anUl, i, anEquationCoeffs, anU2t)) - continue; - const Standard_Real aDU2 = Abs(anU2t - aCurU2); - if(aDU2 < aDelta) + const Standard_Real anUinf = anUf, anUsup = anUl, anUmid = 0.5*(anUf + anUl); + + { + //Find the value of anIndex variable. + Standard_Real aDelta = RealLast(); + for (Standard_Integer i = 0; i < aNbWLines; i++) { - aDelta = aDU2; - anIndex = i; + Standard_Real anU2t = 0.0; + if (!ComputationMethods::CylCylComputeParameters(anUmid, i, anEquationCoeffs, anU2t)) + continue; + + Standard_Real aDU2 = fmod(Abs(anU2t - aCurU2), aPeriod); + aDU2 = Min(aDU2, Abs(aDU2 - aPeriod)); + if (aDU2 < aDelta) + { + aDelta = aDU2; + anIndex = i; + } } } - //Try to fill aWLine by additional points - while(anUl - anUf > RealSmall()) - { - Standard_Real anU2 = 0.0, anV1 = 0.0, anV2 = 0.0; - Standard_Boolean isDone = - ComputationMethods::CylCylComputeParameters(anUf, anIndex, anEquationCoeffs, - anU2, anV1, anV2); - anUf += aDU; + // Bisection method is used in order to find every new point. + // I.e. if we need to find intersection point in the interval [anUinf, anUmid] + // we check the point anUC = 0.5*(anUinf+anUmid). If it is an intersection point + // we try to find another point in the interval [anUinf, anUC] (because we find the point in + // maximal distance from anUmid). If it is not then we try to find another point in the + // interval [anUC, anUmid]. Next iterations will be made analogically. + // When we find intersection point in the interval [anUmid, anUsup] we try to find + // another point in the interval [anUC, anUsup] if anUC is intersection point and + // in the interval [anUmid, anUC], otherwise. - if(!isDone) + Standard_Real anAddedPar[2] = { anUmid, anUmid }; + + for (Standard_Integer aParID = 0; aParID < 2; aParID++) + { + if (aParID == 0) { - continue; + anUf = anUinf; + anUl = anUmid; + } + else // if(aParID == 1) + { + anUf = anUmid; + anUl = anUsup; } - if(AddPointIntoWL(theQuad1, theQuad2, anEquationCoeffs, isTheReverse, - Standard_True, gp_Pnt2d(anUf, anV1), gp_Pnt2d(anU2, anV2), + Standard_Real &aPar1 = (aParID == 0) ? anUf : anUl, + &aPar2 = (aParID == 0) ? anUl : anUf; + + while (Abs(aPar2 - aPar1) > aStepMin) + { + Standard_Real anUC = 0.5*(anUf + anUl); + Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0; + Standard_Boolean isDone = ComputationMethods:: + CylCylComputeParameters(anUC, anIndex, anEquationCoeffs, aU2, aV1, aV2); + + if (isDone) + { + if (Abs(aV1 - aVSurf1f) <= aTol2D) + aV1 = aVSurf1f; + + if (Abs(aV1 - aVSurf1l) <= aTol2D) + aV1 = aVSurf1l; + + if (Abs(aV2 - aVSurf2f) <= aTol2D) + aV2 = aVSurf2f; + + if (Abs(aV2 - aVSurf2l) <= aTol2D) + aV2 = aVSurf2l; + + isDone = AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, + Standard_True, gp_Pnt2d(anUC, aV1), gp_Pnt2d(aU2, aV2), + aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, + aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, + aPeriod, aWLine->Curve(), anIndex, aTol3D, + aTol2D, Standard_False, Standard_True); + } + + if (isDone) + { + anAddedPar[0] = Min(anAddedPar[0], anUC); + anAddedPar[1] = Max(anAddedPar[1], anUC); + aPar2 = anUC; + } + else + { + aPar1 = anUC; + } + } + } + + //Fill aWLine by additional points + if (anAddedPar[1] - anAddedPar[0] > aStepMin) + { + for (Standard_Integer aParID = 0; aParID < 2; aParID++) + { + Standard_Real aU2 = 0.0, aV1 = 0.0, aV2 = 0.0; + ComputationMethods::CylCylComputeParameters(anAddedPar[aParID], anIndex, + anEquationCoeffs, aU2, aV1, aV2); + + AddPointIntoWL(aQuad1, aQuad2, anEquationCoeffs, isReversed, Standard_True, + gp_Pnt2d(anAddedPar[aParID], aV1), gp_Pnt2d(aU2, aV2), aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, - aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, - aPeriod, aWLine->Curve(), anIndex, theTol3D, - theTol2D, Standard_False, Standard_True)) - { - break; + aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l, aPeriod, aWLine->Curve(), + anIndex, aTol3D, aTol2D, Standard_False, Standard_False); } - } - if(aWLine->NbPnts() > 1) - { - SeekAdditionalPoints( theQuad1, theQuad2, aWLine->Curve(), + SeekAdditionalPoints(aQuad1, aQuad2, aWLine->Curve(), anEquationCoeffs, anIndex, aNbMinPoints, - 1, aWLine->NbPnts(), theTol2D, aPeriod, - isTheReverse); + 1, aWLine->NbPnts(), aTol2D, aPeriod, + isReversed); - aWLine->ComputeVertexParameters(theTol3D); + aWLine->ComputeVertexParameters(aTol3D); theSlin.Append(aWLine); - + theSPnt.Remove(aNbPnt); aNbPnt--; } } - + return IntPatch_ImpImpIntersection::IntStatus_OK; } +//======================================================================= +//function : IntCyCy +//purpose : +//======================================================================= +IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1, + const IntSurf_Quadric& theQuad2, + const Standard_Real theTol3D, + const Standard_Real theTol2D, + const Bnd_Box2d& theUVSurf1, + const Bnd_Box2d& theUVSurf2, + Standard_Boolean& isTheEmpty, + Standard_Boolean& isTheSameSurface, + Standard_Boolean& isTheMultiplePoint, + IntPatch_SequenceOfLine& theSlin, + IntPatch_SequenceOfPoint& theSPnt) +{ + isTheEmpty = Standard_True; + isTheSameSurface = Standard_False; + isTheMultiplePoint = Standard_False; + theSlin.Clear(); + theSPnt.Clear(); + + const gp_Cylinder aCyl1 = theQuad1.Cylinder(), + aCyl2 = theQuad2.Cylinder(); + + IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D); + + if (!anInter.IsDone()) + { + return IntPatch_ImpImpIntersection::IntStatus_Fail; + } + + if(anInter.TypeInter() != IntAna_NoGeometricSolution) + { + if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter, + theTol3D, isTheEmpty, + isTheSameSurface, isTheMultiplePoint, + theSlin, theSPnt)) + { + return IntPatch_ImpImpIntersection::IntStatus_OK; + } + } + + //Here, intersection line is not an analytical curve(line, circle, ellipsis etc.) + + Standard_Real aUSBou[2][2], aVSBou[2][2]; //const + + theUVSurf1.Get(aUSBou[0][0], aVSBou[0][0], aUSBou[0][1], aVSBou[0][1]); + theUVSurf2.Get(aUSBou[1][0], aVSBou[1][0], aUSBou[1][1], aVSBou[1][1]); + + const Standard_Real aPeriod = 2.0*M_PI; + const Standard_Integer aNbWLines = 2; + + const ComputationMethods::stCoeffsValue anEquationCoeffs1(aCyl1, aCyl2); + const ComputationMethods::stCoeffsValue anEquationCoeffs2(aCyl2, aCyl1); + + //Boundaries. + //Intersection result can include two non-connected regions + //(see WorkWithBoundaries::BoundariesComputing(...) method). + const Standard_Integer aNbOfBoundaries = 2; + Bnd_Range anURange[2][aNbOfBoundaries]; //const + + if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs1, aPeriod, anURange[0])) + return IntPatch_ImpImpIntersection::IntStatus_OK; + + if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs2, aPeriod, anURange[1])) + return IntPatch_ImpImpIntersection::IntStatus_OK; + + //anURange[*] can be in different periodic regions in + //compare with First-Last surface. E.g. the surface + //is full cylinder [0, 2*PI] but anURange is [5, 7]. + //Trivial common range computation returns [5, 2*PI] and + //its summary length is 2*PI-5 == 1.28... only. That is wrong. + //This problem can be solved by the following + //algorithm: + // 1. split anURange[*] by the surface boundary; + // 2. shift every new range in order to inscribe it + // in [Ufirst, Ulast] of cylinder; + // 3. consider only common ranges between [Ufirst, Ulast] + // and new ranges. + // + // In above example, we obtain following: + // 1. two ranges: [5, 2*PI] and [2*PI, 7]; + // 2. after shifting: [5, 2*PI] and [0, 7-2*PI]; + // 3. Common ranges: ([5, 2*PI] and [0, 2*PI]) == [5, 2*PI], + // ([0, 7-2*PI] and [0, 2*PI]) == [0, 7-2*PI]; + // 4. Their summary length is (2*PI-5)+(7-2*PI-0)==7-5==2 ==> GOOD. + + Standard_Real aSumRange[2] = { 0.0, 0.0 }; + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; + for (Standard_Integer aCID = 0; aCID < 2; aCID++) + { + anAlloc->Reset(); + NCollection_List aListOfRng(anAlloc); + + aListOfRng.Append(anURange[aCID][0]); + aListOfRng.Append(anURange[aCID][1]); + + const Standard_Real aSplitArr[3] = {aUSBou[aCID][0], aUSBou[aCID][1], 0.0}; + + NCollection_List::Iterator anITrRng; + for (Standard_Integer aSInd = 0; aSInd < 3; aSInd++) + { + NCollection_List aLstTemp(aListOfRng); + aListOfRng.Clear(); + for (anITrRng.Init(aLstTemp); anITrRng.More(); anITrRng.Next()) + { + Bnd_Range& aRng = anITrRng.Value(); + aRng.Split(aSplitArr[aSInd], aListOfRng, aPeriod); + } + } + + anITrRng.Init(aListOfRng); + for (; anITrRng.More(); anITrRng.Next()) + { + Bnd_Range& aCurrRange = anITrRng.Value(); + + Bnd_Range aBoundR; + aBoundR.Add(aUSBou[aCID][0]); + aBoundR.Add(aUSBou[aCID][1]); + + if (!InscribeInterval(aUSBou[aCID][0], aUSBou[aCID][1], + aCurrRange, theTol2D, aPeriod)) + { + //If aCurrRange does not have common block with + //[Ufirst, Ulast] of cylinder then we will try + //to inscribe [Ufirst, Ulast] in the boundaries of aCurrRange. + Standard_Real aF = 1.0, aL = 0.0; + if (!aCurrRange.GetBounds(aF, aL)) + continue; + + if ((aL < aUSBou[aCID][0])) + { + aCurrRange.Shift(aPeriod); + } + else if (aF > aUSBou[aCID][1]) + { + aCurrRange.Shift(-aPeriod); + } + } + + aBoundR.Common(aCurrRange); + + const Standard_Real aDelta = aBoundR.Delta(); + + if (aDelta > 0.0) + { + aSumRange[aCID] += aDelta; + } + } + } + + //The bigger range the bigger number of points in Walking-line (WLine) + //we will be able to add and consequently we will obtain more + //precise intersection line. + //Every point of WLine is determined as function from U1-parameter, + //where U1 is U-parameter on 1st quadric. + //Therefore, we should use quadric with bigger range as 1st parameter + //in IntCyCy() function. + //On the other hand, there is no point in reversing in case of + //analytical intersection (when result is line, ellipse, point...). + //This result is independent of the arguments order. + const Standard_Boolean isToReverse = (aSumRange[1] > aSumRange[0]); + + if (isToReverse) + { + const WorkWithBoundaries aBoundWork(theQuad2, theQuad1, anEquationCoeffs2, + theUVSurf2, theUVSurf1, aNbWLines, + aPeriod, theTol3D, theTol2D, Standard_True); + + return CyCyNoGeometric(aCyl2, aCyl1, aBoundWork, anURange[1], aNbOfBoundaries, + isTheEmpty, theSlin, theSPnt); + } + else + { + const WorkWithBoundaries aBoundWork(theQuad1, theQuad2, anEquationCoeffs1, + theUVSurf1, theUVSurf2, aNbWLines, + aPeriod, theTol3D, theTol2D, Standard_False); + + return CyCyNoGeometric(aCyl1, aCyl2, aBoundWork, anURange[0], aNbOfBoundaries, + isTheEmpty, theSlin, theSPnt); + } +} + //======================================================================= //function : IntCySp //purpose : diff --git a/src/IntPatch/IntPatch_Intersection.cxx b/src/IntPatch/IntPatch_Intersection.cxx index 6213b3541a..d1c3173570 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -1405,19 +1405,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder)) { - IntPatch_WLineTool::JoinWLines( slin, spnt, TolTang, - theS1->IsUPeriodic()? theS1->UPeriod() : 0.0, - theS2->IsUPeriodic()? theS2->UPeriod() : 0.0, - theS1->IsVPeriodic()? theS1->VPeriod() : 0.0, - theS2->IsVPeriodic()? theS2->VPeriod() : 0.0, - theS1->FirstUParameter(), - theS1->LastUParameter(), - theS1->FirstVParameter(), - theS1->LastVParameter(), - theS2->FirstUParameter(), - theS2->LastUParameter(), - theS2->FirstVParameter(), - theS2->LastVParameter()); + IntPatch_WLineTool::JoinWLines(slin, spnt, theS1, theS2, TolTang); } if(isWLExist) diff --git a/src/IntPatch/IntPatch_WLineTool.cxx b/src/IntPatch/IntPatch_WLineTool.cxx index 5ac700ad08..78148f677a 100644 --- a/src/IntPatch/IntPatch_WLineTool.cxx +++ b/src/IntPatch/IntPatch_WLineTool.cxx @@ -15,9 +15,12 @@ #include #include +#include #include #include #include +#include +#include // It is pure empirical value. const Standard_Real IntPatch_WLineTool::myMaxConcatAngle = M_PI/6; @@ -483,64 +486,6 @@ static Handle(IntPatch_WLine) return MakeNewWLine(theWLine, aNewPointsHash); } -//======================================================================= -//function : IsOnPeriod -//purpose : Checks, if [theU1, theU2] intersects the period-value -// (k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...). -// -// Returns: -// 0 - if interval [theU1, theU2] does not intersect the "period-value" -// or if thePeriod == 0.0; -// 1 - if interval (theU1, theU2) intersect the "period-value". -// 2 - if theU1 or/and theU2 lie ON the "period-value" -// -//ATTENTION!!! -// If (theU1 == theU2) then this function will return only both 0 or 2. -//======================================================================= -static Standard_Integer IsOnPeriod(const Standard_Real theU1, - const Standard_Real theU2, - const Standard_Real thePeriod) -{ - if(thePeriod < RealSmall()) - return 0; - - //If interval [theU1, theU2] intersect seam-edge then there exists an integer - //number N such as - // (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T), - //where T is the period. - //I.e. the inerval [theU1/T, theU2/T] must contain at least one - //integer number. In this case, Floor(theU1/T) and Floor(theU2/T) - //return different values or theU1/T is strictly integer number. - //Examples: - // 1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3. - // 2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2. - - const Standard_Real aVal1 = theU1/thePeriod, - aVal2 = theU2/thePeriod; - const Standard_Integer aPar1 = static_cast(Floor(aVal1)); - const Standard_Integer aPar2 = static_cast(Floor(aVal2)); - if(aPar1 != aPar2) - {//Interval (theU1, theU2] intersects seam-edge - if(IsEqual(aVal2, static_cast(aPar2))) - {//aVal2 is an integer number => theU2 lies ON the "seam-edge" - return 2; - } - - return 1; - } - - //Here, aPar1 == aPar2. - - if(IsEqual(aVal1, static_cast(aPar1))) - {//aVal1 is an integer number => theU1 lies ON the "seam-edge" - return 2; - } - - //If aVal2 is a true integer number then always (aPar1 != aPar2). - - return 0; -} - //======================================================================= //function : IsSeamOrBound //purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge" @@ -550,129 +495,90 @@ static Standard_Integer IsOnPeriod(const Standard_Real theU1, // If thePtmid match "seam-edge" or boundaries strictly // (without any tolerance) then the function will return TRUE. // See comments in function body for detail information. +// +// Arrays theArrPeriods, theFBound and theLBound must be filled +// as follows: +// [0] - U-parameter of 1st surface; +// [1] - V-parameter of 1st surface; +// [2] - U-parameter of 2nd surface; +// [3] - V-parameter of 2nd surface. //======================================================================= static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf, const IntSurf_PntOn2S& thePtl, const IntSurf_PntOn2S& thePtmid, - const Standard_Real theU1Period, - const Standard_Real theU2Period, - const Standard_Real theV1Period, - const Standard_Real theV2Period, - const Standard_Real theUfSurf1, - const Standard_Real theUlSurf1, - const Standard_Real theVfSurf1, - const Standard_Real theVlSurf1, - const Standard_Real theUfSurf2, - const Standard_Real theUlSurf2, - const Standard_Real theVfSurf2, - const Standard_Real theVlSurf2) + const Standard_Real theArrPeriods[4], + const Standard_Real theFBound[4], + const Standard_Real theLBound[4]) { - Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0; - Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0; - thePtf.Parameters(aU11, aV11, aU12, aV12); - thePtl.Parameters(aU21, aV21, aU22, aV22); + Standard_Real aParF[4] = { 0.0, 0.0, 0.0, 0.0 }; + Standard_Real aParL[4] = { 0.0, 0.0, 0.0, 0.0 }; + thePtf.Parameters(aParF[0], aParF[1], aParF[2], aParF[3]); + thePtl.Parameters(aParL[0], aParL[1], aParL[2], aParL[3]); - MinMax(aU11, aU21); - MinMax(aV11, aV21); - MinMax(aU12, aU22); - MinMax(aV12, aV22); + Bnd_Range aBndR[4]; - if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0) - {//Interval [aU11, aU21] intersects theUfSurf1 - return Standard_True; + for (Standard_Integer i = 0; i < 4; i++) + { + aBndR[i].Add(aParF[i]); + aBndR[i].Add(aParL[i]); + + if (aBndR[i].IsIntersected(theFBound[i], theArrPeriods[i]) == 1) + return Standard_True; + + if (aBndR[i].IsIntersected(theLBound[i], theArrPeriods[i]) == 1) + return Standard_True; } - if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0) - {//Interval [aU11, aU21] intersects theUlSurf1 - return Standard_True; + for (Standard_Integer i = 0; i < 4; i++) + { + if (theArrPeriods[i] == 0.0) + { + //Strictly equal + continue; + } + + const Standard_Real aDelta = Abs(aParL[i] - aParF[i]); + if (2.0*aDelta > theArrPeriods[i]) + { + //Most likely, seam is intersected. + return Standard_True; + } + + if (aBndR[i].IsIntersected(0.0, theArrPeriods[i]) == 1) + return Standard_True; } - if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0) - {//Interval [aV11, aV21] intersects theVfSurf1 - return Standard_True; + //The segment [thePtf, thePtl] does not intersect the boundaries and + //the seam-edge of the surfaces. + //Nevertheless, following situation is possible: + + // seam or + // bound + // | + // thePtf * | + // | + // * thePtmid + // thePtl * | + // | + + //This case must be processed, too. + + Standard_Real aMPar[4] = { 0.0, 0.0, 0.0, 0.0 }; + thePtmid.Parameters(aMPar[0], aMPar[1], aMPar[2], aMPar[3]); + + for (Standard_Integer i = 0; i < 4; i++) + { + const Bnd_Range aBR(aMPar[i], aMPar[i]); + if (aBR.IsIntersected(theFBound[i], theArrPeriods[i])) + return Standard_True; + + if (aBR.IsIntersected(theLBound[i], theArrPeriods[i])) + return Standard_True; + + if (aBR.IsIntersected(0.0, theArrPeriods[i])) + return Standard_True; } - if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0) - {//Interval [aV11, aV21] intersects theVlSurf1 - return Standard_True; - } - - if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0) - {//Interval [aU12, aU22] intersects theUfSurf2 - return Standard_True; - } - - if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0) - {//Interval [aU12, aU22] intersects theUlSurf2 - return Standard_True; - } - - if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0) - {//Interval [aV12, aV22] intersects theVfSurf2 - return Standard_True; - } - - if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0) - {//Interval [aV12, aV22] intersects theVlSurf2 - return Standard_True; - } - - if(IsOnPeriod(aU11, aU21, theU1Period)) - return Standard_True; - - if(IsOnPeriod(aV11, aV21, theV1Period)) - return Standard_True; - - if(IsOnPeriod(aU12, aU22, theU2Period)) - return Standard_True; - - if(IsOnPeriod(aV12, aV22, theV2Period)) - return Standard_True; - - /* - The segment [thePtf, thePtl] does not intersect the boundaries and - the seam-edge of the surfaces. - Nevertheless, following situation is possible: - - seam or - bound - | - thePtf * | - | - * thePtmid - thePtl * | - | - - This case must be processed, too. - */ - - Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0; - thePtmid.Parameters(aU1, aV1, aU2, aV2); - - if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1)) - return Standard_True; - - if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2)) - return Standard_True; - - if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1)) - return Standard_True; - - if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2)) - return Standard_True; - - if(IsOnPeriod(aU1, aU1, theU1Period)) - return Standard_True; - - if(IsOnPeriod(aU2, aU2, theU2Period)) - return Standard_True; - - if(IsOnPeriod(aV1, aV1, theV1Period)) - return Standard_True; - - if(IsOnPeriod(aV2, aV2, theV2Period)) - return Standard_True; - return Standard_False; } @@ -919,59 +825,75 @@ static IntPatchWT_WLsConnectionType thePtWL2.Parameters(aParWL2[0], aParWL2[1], aParWL2[2], aParWL2[3]); theNewPoint.Parameters(aNewPar[0], aNewPar[1], aNewPar[2], aNewPar[3]); + Bnd_Range aR1, aR2; + Standard_Boolean isOnBoundary = Standard_False; for(Standard_Integer i = 0; i < 4; i++) { - if(IsOnPeriod(aParWL1[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[i])) + if (theArrPeriods[i] == 0.0) + { + //Strictly equal + continue; + } + + aR1.SetVoid(); + aR1.Add(aParWL1[i]); + aR1.Add(aParWL2[i]); + + if (aR1.IsIntersected(aParLBC[i],theArrPeriods[i])) { //Check, if we intersect surface boundary when we will extend Wline1 or Wline2 //to theNewPoint MinMax(aParWL1[i], aParWL2[i]); - if(theArrPeriods[i] > 0.0) + if(aNewPar[i] > aParWL2[i]) { - if(aNewPar[i] > aParWL2[i]) - { - //Source situation: - // - //---*---------------*------------*----- - // aParWL1[i] aParWL2[i] aNewPar[i] - // - //After possible adjusting: - // - //---*---------------*------------*----- - // aParWL1[i] aNewPar[i] aParWL2[i] - // - //Now we will be able to extend every WLine to - //aNewPar[i] to make them close to each other. - //However, it is necessary to add check if we - //intersect boundary. - const Standard_Real aPar = aParWL1[i] + + //Source situation: + // + //---*---------------*------------*----- + // aParWL1[i] aParWL2[i] aNewPar[i] + // + //After possible adjusting: + // + //---*---------------*------------*----- + // aParWL1[i] aNewPar[i] aParWL2[i] + // + //Now we will be able to extend every WLine to + //aNewPar[i] to make them close to each other. + //However, it is necessary to add check if we + //intersect boundary. + const Standard_Real aPar = aParWL1[i] + theArrPeriods[i]*Ceiling((aNewPar[i]-aParWL1[i])/theArrPeriods[i]); - aParWL1[i] = aParWL2[i]; - aParWL2[i] = aPar; - } - else if(aNewPar[i] < aParWL1[i]) - { - //See comments to main "if". - //Source situation: - // - //---*---------------*------------*----- - // aNewPar[i] aParWL1[i] aParWL2[i] - // - //After possible adjusting: - // - //---*---------------*------------*----- - // aParWL1[i] aNewPar[i] aParWL2[i] + aParWL1[i] = aParWL2[i]; + aParWL2[i] = aPar; + } + else if(aNewPar[i] < aParWL1[i]) + { + //See comments to main "if". + //Source situation: + // + //---*---------------*------------*----- + // aNewPar[i] aParWL1[i] aParWL2[i] + // + //After possible adjusting: + // + //---*---------------*------------*----- + // aParWL1[i] aNewPar[i] aParWL2[i] - const Standard_Real aPar = aParWL2[i] - + const Standard_Real aPar = aParWL2[i] - theArrPeriods[i]*Ceiling((aParWL2[i]-aNewPar[i])/theArrPeriods[i]); - aParWL2[i] = aParWL1[i]; - aParWL1[i] = aPar; - } + aParWL2[i] = aParWL1[i]; + aParWL1[i] = aPar; } - if( IsOnPeriod(aParWL1[i] - aParLBC[i], aNewPar[i] - aParLBC[i], theArrPeriods[i]) || - IsOnPeriod(aNewPar[i] - aParLBC[i], aParWL2[i] - aParLBC[i], theArrPeriods[i])) + aR1.SetVoid(); + aR2.SetVoid(); + aR1.Add(aParWL1[i]); + aR1.Add(aNewPar[i]); + aR2.Add(aNewPar[i]); + aR2.Add(aParWL2[i]); + + if (aR1.IsIntersected(aParLBC[i], theArrPeriods[i]) || + aR2.IsIntersected(aParLBC[i], theArrPeriods[i])) { return IntPatchWT_NotConnected; } @@ -995,13 +917,15 @@ static IntPatchWT_WLsConnectionType //purpose : Check if joining is possible // (see IntPatch_WLineTool::JoinWLines(...)) //======================================================================= -Standard_Boolean CheckArgumentsToJoin(const gp_Vec& theVec1, - const gp_Vec& theVec2) +Standard_Boolean CheckArgumentsToJoin(const Handle(Adaptor3d_HSurface)& theS1, + const Handle(Adaptor3d_HSurface)& theS2, + const IntSurf_PntOn2S& thePnt, + const Standard_Real theMinRad) { - // [0, PI] - range - const Standard_Real anAngle = theVec1.Angle(theVec2); + const Standard_Real aRad = + IntPatch_PointLine::CurvatureRadiusOfIntersLine(theS1, theS2, thePnt); - return (anAngle < IntPatch_WLineTool::myMaxConcatAngle); + return (aRad > theMinRad); } //======================================================================= @@ -1415,33 +1339,38 @@ Handle(IntPatch_WLine) IntPatch_WLineTool:: return aResult; } - //======================================================================= //function : JoinWLines //purpose : //======================================================================= void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin, IntPatch_SequenceOfPoint& theSPnt, - const Standard_Real theTol3D, - const Standard_Real theU1Period, - const Standard_Real theU2Period, - const Standard_Real theV1Period, - const Standard_Real theV2Period, - const Standard_Real theUfSurf1, - const Standard_Real theUlSurf1, - const Standard_Real theVfSurf1, - const Standard_Real theVlSurf1, - const Standard_Real theUfSurf2, - const Standard_Real theUlSurf2, - const Standard_Real theVfSurf2, - const Standard_Real theVlSurf2) + Handle(Adaptor3d_HSurface) theS1, + Handle(Adaptor3d_HSurface) theS2, + const Standard_Real theTol3D) { if(theSlin.Length() == 0) return; - for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++) + // For two cylindrical surfaces only + const Standard_Real aMinRad = 1.0e-3*Min(theS1->Cylinder().Radius(), + theS2->Cylinder().Radius()); + + const Standard_Real anArrPeriods[4] = {theS1->IsUPeriodic() ? theS1->UPeriod() : 0.0, + theS1->IsVPeriodic() ? theS1->VPeriod() : 0.0, + theS2->IsUPeriodic() ? theS2->UPeriod() : 0.0, + theS2->IsVPeriodic() ? theS2->VPeriod() : 0.0}; + + const Standard_Real anArrFBonds[4] = {theS1->FirstUParameter(), theS1->FirstVParameter(), + theS2->FirstUParameter(), theS2->FirstVParameter()}; + const Standard_Real anArrLBonds[4] = {theS1->LastUParameter(), theS1->LastVParameter(), + theS2->LastUParameter(), theS2->LastVParameter()}; + + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator(); + + for(Standard_Integer aN1 = 1; aN1 <= theSlin.Length(); aN1++) { - Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1))); + Handle(IntPatch_WLine) aWLine1(Handle(IntPatch_WLine)::DownCast(theSlin.Value(aN1))); if(aWLine1.IsNull()) {//We must have failed to join not-point-lines @@ -1449,184 +1378,169 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin, } const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts(); - const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1); - const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1); + const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); + const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1); for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++) { const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S(); - if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) || - aPntCur.IsSame(aPntLW1, Precision::Confusion())) + if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) || + aPntCur.IsSame(aPntLWL1, Precision::Confusion())) { theSPnt.Remove(aNPt); aNPt--; } } - Standard_Boolean hasBeenRemoved = Standard_False; - for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++) - { - Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2))); + anAlloc->Reset(); + NCollection_List aListFC(anAlloc), + aListLC(anAlloc); + + Standard_Boolean isFirstConnected = Standard_False, isLastConnected = Standard_False; - if(aWLine2.IsNull()) + for (Standard_Integer aN2 = 1; aN2 <= theSlin.Length(); aN2++) + { + if (aN2 == aN1) continue; - const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); + Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(aN2))); - const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1); - const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1); + if (aWLine2.IsNull()) + continue; + + isFirstConnected = isLastConnected = Standard_False; + + const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1); const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2); - if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion())) + Standard_Real aSqDistF = aPntFWL1.Value().SquareDistance(aPntFWL2.Value()); + Standard_Real aSqDistL = aPntFWL1.Value().SquareDistance(aPntLWL2.Value()); + + const Standard_Real aSqMinFDist = Min(aSqDistF, aSqDistL); + if (aSqMinFDist < Precision::SquareConfusion()) { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); - - Standard_Boolean aCond = - CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()), - gp_Vec(aPt2.Value(), aPntFWL2.Value())); - - aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1, - theU1Period, theU2Period, - theV1Period, theV2Period, - theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, - theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2); - - if(aCond) + if (CheckArgumentsToJoin(theS1, theS2, aPntFWL1, aMinRad)) { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) + const Standard_Boolean isFM = (aSqDistF < aSqDistL); + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); + const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) : + aWLine2->Point(aNbPntsWL2 - 1); + + if (!IsSeamOrBound(aPt1, aPt2, aPntFWL1, + anArrPeriods, anArrFBonds, anArrLBonds)) { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->InsertBefore(1, aPt); + isFirstConnected = Standard_True; } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; } } - if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion())) + aSqDistF = aPntLWL1.Value().SquareDistance(aPntFWL2.Value()); + aSqDistL = aPntLWL1.Value().SquareDistance(aPntLWL2.Value()); + + const Standard_Real aSqMinLDist = Min(aSqDistF, aSqDistL); + if (aSqMinLDist < Precision::SquareConfusion()) { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); - - Standard_Boolean aCond = - CheckArgumentsToJoin(gp_Vec(aPntFWL1.Value(), aPt1.Value()), - gp_Vec(aPt2.Value(), aPntLWL2.Value())); - - aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntFWL1, - theU1Period, theU2Period, - theV1Period, theV2Period, - theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, - theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2); - - if(aCond) + if (CheckArgumentsToJoin(theS1, theS2, aPntLWL1, aMinRad)) { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) + const Standard_Boolean isFM = (aSqDistF < aSqDistL); + const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1 - 1); + const IntSurf_PntOn2S& aPt2 = isFM ? aWLine2->Point(2) : + aWLine2->Point(aNbPntsWL2 - 1); + + if (!IsSeamOrBound(aPt1, aPt2, aPntLWL1, + anArrPeriods, anArrFBonds, anArrLBonds)) { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->InsertBefore(1, aPt); + isLastConnected = Standard_True; } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; } } - if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion())) + if (isFirstConnected && isLastConnected) { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2); - - Standard_Boolean aCond = - CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()), - gp_Vec(aPntFWL2.Value(), aPt2.Value())); - - aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1, - theU1Period, theU2Period, - theV1Period, theV2Period, - theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, - theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2); - - if(aCond) + if (aSqMinFDist < aSqMinLDist) { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->Add(aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; + aListFC.Append(aN2); + } + else + { + aListLC.Append(aN2); } } - - if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion())) + else if (isFirstConnected) { - const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1); - const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1); + aListFC.Append(aN2); + } + else if (isLastConnected) + { + aListLC.Append(aN2); + } + } - Standard_Boolean aCond = - CheckArgumentsToJoin(gp_Vec(aPt1.Value(), aPntLWL1.Value()), - gp_Vec(aPntLWL2.Value(), aPt2.Value())); + isFirstConnected = (aListFC.Extent() == 1); + isLastConnected = (aListLC.Extent() == 1); - aCond = aCond && !IsSeamOrBound(aPt1, aPt2, aPntLWL1, - theU1Period, theU2Period, - theV1Period, theV2Period, - theUfSurf1, theUlSurf1, - theVfSurf1, theVlSurf1, - theUfSurf2, theUlSurf2, - theVfSurf2, theVlSurf2); + if (!(isFirstConnected || isLastConnected)) + { + continue; + } - if(aCond) + const Standard_Integer anIndexWL2 = isFirstConnected ? aListFC.First() : aListLC.First(); + Handle(IntPatch_WLine) aWLine2(Handle(IntPatch_WLine)::DownCast(theSlin.Value(anIndexWL2))); + + const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts(); + const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1); + + aWLine1->ClearVertexes(); + + if (isFirstConnected) + { + if (aPntFWL1.IsSame(aPntFWL2, Precision::Confusion())) + { + //First-First-connection + for (Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) { - aWLine1->ClearVertexes(); - for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) - { - const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); - aWLine1->Curve()->Add(aPt); - } - - aWLine1->ComputeVertexParameters(theTol3D); - - theSlin.Remove(aNumOfLine2); - aNumOfLine2--; - hasBeenRemoved = Standard_True; - - continue; + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->InsertBefore(1, aPt); + } + } + else + { + //First-Last-connection + for (Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->InsertBefore(1, aPt); + } + } + } + else //if (isLastConnected) + { + if (aPntLWL1.IsSame(aPntFWL2, Precision::Confusion())) + { + //Last-First connection + for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->Add(aPt); + } + } + else + { + //Last-Last connection + for (Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--) + { + const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt); + aWLine1->Curve()->Add(aPt); } } } - if(hasBeenRemoved) - aNumOfLine1--; + aWLine1->ComputeVertexParameters(theTol3D); + theSlin.Remove(anIndexWL2); + aN1--; } } diff --git a/src/IntPatch/IntPatch_WLineTool.hxx b/src/IntPatch/IntPatch_WLineTool.hxx index 9a40853f9b..6f72a222a9 100644 --- a/src/IntPatch/IntPatch_WLineTool.hxx +++ b/src/IntPatch/IntPatch_WLineTool.hxx @@ -14,9 +14,10 @@ #ifndef _IntPatch_WLineTool_HeaderFile #define _IntPatch_WLineTool_HeaderFile +#include + #include #include -#include class Adaptor3d_TopolTool; @@ -59,20 +60,9 @@ public: //! this point will be deleted. Standard_EXPORT static void JoinWLines(IntPatch_SequenceOfLine& theSlin, IntPatch_SequenceOfPoint& theSPnt, - const Standard_Real theTol3D, - const Standard_Real theU1Period, - const Standard_Real theU2Period, - const Standard_Real theV1Period, - const Standard_Real theV2Period, - const Standard_Real theUfSurf1, - const Standard_Real theUlSurf1, - const Standard_Real theVfSurf1, - const Standard_Real theVlSurf1, - const Standard_Real theUfSurf2, - const Standard_Real theUlSurf2, - const Standard_Real theVfSurf2, - const Standard_Real theVlSurf2); - + Handle(Adaptor3d_HSurface) theS1, + Handle(Adaptor3d_HSurface) theS2, + const Standard_Real theTol3D); //! Extends every line from theSlin (if it is possible) to be started/finished //! in strictly determined point (in the place of joint of two lines). @@ -80,7 +70,8 @@ public: //! The Walking lines are supposed (algorithm will do nothing for not-Walking line) //! to be computed as a result of intersection. Both theS1 and theS2 //! must be quadrics. Other cases are not supported. -//! theArrPeriods must be filled as follows: +//! theArrPeriods must be filled as follows (every value must not be negative; +//! if the surface is not periodic the period must be equal to 0.0 strictly): //! {, , //! , }. Standard_EXPORT static void diff --git a/tests/bugs/modalg_5/bug24915 b/tests/bugs/modalg_5/bug24915 index b7a3688064..2c25dd4e91 100755 --- a/tests/bugs/modalg_5/bug24915 +++ b/tests/bugs/modalg_5/bug24915 @@ -25,17 +25,26 @@ checkshape r # 2. geometry set MaxTol 1.0e-7 +set GoodNBCurv 3 + set log [bopcurves b1 b2 -2d] if { ! [regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv] } { puts "Error: Cannot find tolerance value in output of bopcurve command" } +if { $NbCurv != $GoodNBCurv } { + puts "Error: Number of curves is wrong!" +} + if {${Toler} > ${MaxTol}} { puts "Error: Tolerance is too big!" } smallview -donly b2 c_2 -fit -checkview -screenshot -2d -path ${imagedir}/${test_image}.png + +for {set i 1} {$i <= $GoodNBCurv} {incr i} { + donly b2 c_$i + fit + checkview -screenshot -2d -path ${imagedir}/${test_image}_$i.png +} diff --git a/tests/bugs/modalg_5/bug25292_11 b/tests/bugs/modalg_5/bug25292_11 index d23102021c..de9171d948 100644 --- a/tests/bugs/modalg_5/bug25292_11 +++ b/tests/bugs/modalg_5/bug25292_11 @@ -44,38 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- -# 1 puts "" mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } v2d diff --git a/tests/bugs/modalg_5/bug25292_12 b/tests/bugs/modalg_5/bug25292_12 index 264b1abeb0..61e028aa8f 100644 --- a/tests/bugs/modalg_5/bug25292_12 +++ b/tests/bugs/modalg_5/bug25292_12 @@ -44,38 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- -# 1 puts "" mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } v2d diff --git a/tests/bugs/modalg_5/bug25292_15 b/tests/bugs/modalg_5/bug25292_15 index fe414df1eb..efc2c8364d 100644 --- a/tests/bugs/modalg_5/bug25292_15 +++ b/tests/bugs/modalg_5/bug25292_15 @@ -6,27 +6,6 @@ puts "" # Face/Face intersection algorithm gives different results for different order of the arguments ####################################################################### -proc GetRange { curve } { - global U1 - global U2 - - set log [uplevel dump $curve] - - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 -} - puts "##############################" puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!" puts "##############################" @@ -51,62 +30,42 @@ mksurface s2 f2 ################# intersect res s1 s2 ################# + set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - if { $GoodNbCurv == 1 } { - puts "OK: Curve Number is good!" + renamevar res res_1 +} + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 } else { - puts "Error: Curve Number is bad!" - } - - set U1 0.0 - set U2 0.0 - - GetRange res - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res s1 ${U1} ${U2} 10 1e-7 - xdistcs res s2 ${U1} ${U2} 10 1e-7 -} else { - set ic 1 - set AllowRepeate 1 - while { $AllowRepeate != 0 } { - set che [whatis res_$ic] - set ind [string first "3d curve" $che] - if {${ind} < 0} { - set AllowRepeate 0 - } else { - set U1 0.0 - set U2 0.0 - - GetRange res_$ic - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7 - xdistcs res_$ic s2 0 1 10 1e-7 - - incr ic + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" } - } - - if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Curve Number is good!" - } else { - puts "Error: Curve Number is bad!" + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } } + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Curve Number is good!" +} else { + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_16 b/tests/bugs/modalg_5/bug25292_16 index 7eaf3a70d0..8f791a4d29 100644 --- a/tests/bugs/modalg_5/bug25292_16 +++ b/tests/bugs/modalg_5/bug25292_16 @@ -6,27 +6,6 @@ puts "" # Face/Face intersection algorithm gives different results for different order of the arguments ####################################################################### -proc GetRange { curve } { - global U1 - global U2 - - set log [uplevel dump $curve] - - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 -} - puts "##############################" puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!" puts "##############################" @@ -56,58 +35,37 @@ set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - if { $GoodNbCurv == 1 } { - puts "OK: Curve Number is good!" + renamevar res res_1 +} + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 } else { - puts "Error: Curve Number is bad!" - } - - set U1 0.0 - set U2 0.0 - - GetRange res - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res s1 ${U1} ${U2} 10 1e-7 - xdistcs res s2 ${U1} ${U2} 10 1e-7 -} else { - set ic 1 - set AllowRepeate 1 - while { $AllowRepeate != 0 } { - set che [whatis res_$ic] - set ind [string first "3d curve" $che] - if {${ind} < 0} { - set AllowRepeate 0 - } else { - set U1 0.0 - set U2 0.0 - - GetRange res_$ic - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7 - xdistcs res_$ic s2 0 1 10 1e-7 - - incr ic + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" } - } - - if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Curve Number is good!" - } else { - puts "Error: Curve Number is bad!" + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } } + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Curve Number is good!" +} else { + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_21 b/tests/bugs/modalg_5/bug25292_21 index fefe9698ea..516f96dac4 100644 --- a/tests/bugs/modalg_5/bug25292_21 +++ b/tests/bugs/modalg_5/bug25292_21 @@ -44,35 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- +puts "" + mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } smallview diff --git a/tests/bugs/modalg_5/bug25292_22 b/tests/bugs/modalg_5/bug25292_22 index 9f59bd0a01..b641b0a3b5 100644 --- a/tests/bugs/modalg_5/bug25292_22 +++ b/tests/bugs/modalg_5/bug25292_22 @@ -44,35 +44,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- +puts "" + mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } smallview diff --git a/tests/bugs/modalg_5/bug25292_25 b/tests/bugs/modalg_5/bug25292_25 index ac1987c964..dd0effa35a 100644 --- a/tests/bugs/modalg_5/bug25292_25 +++ b/tests/bugs/modalg_5/bug25292_25 @@ -6,27 +6,6 @@ puts "" # Face/Face intersection algorithm gives different results for different order of the arguments ####################################################################### -proc GetRange { curve } { - global U1 - global U2 - - set log [uplevel dump $curve] - - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 -} - puts "##############################" puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!" puts "##############################" @@ -56,59 +35,37 @@ set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - if { $GoodNbCurv == 1 } { - puts "OK: Curve Number is good!" + renamevar res res_1 +} + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 } else { - puts "Error: Curve Number is bad!" - } - - set U1 0.0 - set U2 0.0 - - GetRange res - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res s1 ${U1} ${U2} 10 1e-7 - xdistcs res s2 ${U1} ${U2} 10 1e-7 -} else { - set ic 1 - set AllowRepeate 1 - while { $AllowRepeate != 0 } { - set che [whatis res_$ic] - set ind [string first "3d curve" $che] - if {${ind} < 0} { - set AllowRepeate 0 - } else { - set U1 0.0 - set U2 0.0 - - GetRange res_$ic - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7 - xdistcs res_$ic s2 0 1 10 1e-7 - - incr ic + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" } - } - - if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Curve Number is good!" - } else { - puts "Error: Curve Number is bad!" + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } } +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Curve Number is good!" +} else { + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_26 b/tests/bugs/modalg_5/bug25292_26 index 332ec45114..0a75614d86 100644 --- a/tests/bugs/modalg_5/bug25292_26 +++ b/tests/bugs/modalg_5/bug25292_26 @@ -6,27 +6,6 @@ puts "" # Face/Face intersection algorithm gives different results for different order of the arguments ####################################################################### -proc GetRange { curve } { - global U1 - global U2 - - set log [uplevel dump $curve] - - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 -} - puts "##############################" puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!" puts "##############################" @@ -56,58 +35,37 @@ set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - if { $GoodNbCurv == 1 } { - puts "OK: Curve Number is good!" + renamevar res res_1 +} + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis res_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 } else { - puts "Error: Curve Number is bad!" - } - - set U1 0.0 - set U2 0.0 - - GetRange res - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res s1 ${U1} ${U2} 10 1e-7 - xdistcs res s2 ${U1} ${U2} 10 1e-7 -} else { - set ic 1 - set AllowRepeate 1 - while { $AllowRepeate != 0 } { - set che [whatis res_$ic] - set ind [string first "3d curve" $che] - if {${ind} < 0} { - set AllowRepeate 0 - } else { - set U1 0.0 - set U2 0.0 - - GetRange res_$ic - - puts "U1 = ${U1}" - puts "U2 = ${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 ${U1} ${U2} 10 1e-7 - xdistcs res_$ic s2 0 1 10 1e-7 - - incr ic + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" } - } - - if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Curve Number is good!" - } else { - puts "Error: Curve Number is bad!" + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } } + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Curve Number is good!" +} else { + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_31 b/tests/bugs/modalg_5/bug25292_31 index c081b07961..b807823edd 100644 --- a/tests/bugs/modalg_5/bug25292_31 +++ b/tests/bugs/modalg_5/bug25292_31 @@ -38,35 +38,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- +puts "" + mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 1e-8 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 1e-8 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } smallview diff --git a/tests/bugs/modalg_5/bug25292_32 b/tests/bugs/modalg_5/bug25292_32 index 9b1e241a2b..04a5a0e620 100644 --- a/tests/bugs/modalg_5/bug25292_32 +++ b/tests/bugs/modalg_5/bug25292_32 @@ -38,35 +38,23 @@ if {${NbCurv} != ${GoodNbCurv}} { #------------- +puts "" + mksurface s1 f1 mksurface s2 f2 for {set i 1} {$i <= ${NbCurv}} {incr i} { - set log [dump c_$i] + bounds c_$i U1 U2 + + puts "U2=[dval U1]" + puts "U2=[dval U2]" - regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles - puts "Degree=${Degree}" - puts "Poles=${Poles}" - puts "KnotsPoles=${KnotsPoles}" - puts "" - - set Knot 1 - set exp_string "Knots :\n\n +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U1 Mult1 - - set Knot ${KnotsPoles} - set exp_string " +${Knot} : +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)" - regexp ${exp_string} ${log} full U2 Mult2 - - puts "U1=${U1}" - puts "U2=${U2}" - - if {[expr {$U2 - $U1}] < 1.0e-20} { + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs c_$i s1 ${U1} ${U2} 10 1e-7 1e-8 - xdistcs c_$i s2 ${U1} ${U2} 10 1e-7 1e-8 + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } smallview diff --git a/tests/bugs/modalg_5/bug25292_33 b/tests/bugs/modalg_5/bug25292_33 index 4c9a5cafb3..4dc56b478e 100644 --- a/tests/bugs/modalg_5/bug25292_33 +++ b/tests/bugs/modalg_5/bug25292_33 @@ -28,37 +28,39 @@ intersect res s1 s2 set che [whatis res] set ind [string first "3d curve" $che] - -set AllowRepeate 1 -set ic 1 - if {${ind} >= 0} { #Only variable "res" exists renamevar res res_1 } +set ic 1 +set AllowRepeate 1 while { $AllowRepeate != 0 } { set che [whatis res_$ic] set ind [string first "3d curve" $che] if {${ind} < 0} { set AllowRepeate 0 - break + } else { + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" + } + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } - - bounds res_$ic U1 U2 - - if {[dval (U2-U1)] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7 - xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7 - - incr ic } - + if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm" + puts "OK: Curve Number is good!" } else { - puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found" -} \ No newline at end of file + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_34 b/tests/bugs/modalg_5/bug25292_34 index 9d23d65990..628a446c4f 100644 --- a/tests/bugs/modalg_5/bug25292_34 +++ b/tests/bugs/modalg_5/bug25292_34 @@ -29,37 +29,39 @@ intersect res s2 s1 set che [whatis res] set ind [string first "3d curve" $che] - -set AllowRepeate 1 -set ic 1 - if {${ind} >= 0} { #Only variable "res" exists renamevar res res_1 } +set ic 1 +set AllowRepeate 1 while { $AllowRepeate != 0 } { set che [whatis res_$ic] set ind [string first "3d curve" $che] if {${ind} < 0} { set AllowRepeate 0 - break + } else { + display res_$ic + + bounds res_$ic U1 U2 + + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { + puts "Error: Wrong curve's range!" + } + + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 + + incr ic } - - bounds res_$ic U1 U2 - - if {[dval (U2-U1)] < 1.0e-20} { - puts "Error: Wrong curve's range!" - } - - xdistcs res_$ic s1 U1 U2 10 1e-6 1e-7 - xdistcs res_$ic s2 U1 U2 10 1e-6 1e-7 - - incr ic } - + if {[expr {$ic - 1}] == $GoodNbCurv} { - puts "OK: Good number of intersection curve(s) obtained by Surface/Surface Intersection Algorithm" + puts "OK: Curve Number is good!" } else { - puts "Error: $GoodNbCurv intersection curve(s) expected but [expr {$ic - 1}] found" -} \ No newline at end of file + puts "Error: Curve Number is bad!" +} diff --git a/tests/bugs/modalg_5/bug25292_35 b/tests/bugs/modalg_5/bug25292_35 index aaea2c2c5a..fd20ff2330 100644 --- a/tests/bugs/modalg_5/bug25292_35 +++ b/tests/bugs/modalg_5/bug25292_35 @@ -37,8 +37,7 @@ set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - copy res res_1 + renamevar res res_1 } set ic 1 @@ -49,26 +48,24 @@ while { $AllowRepeate != 0 } { if {${ind} < 0} { set AllowRepeate 0 } else { - set le [length res_$ic] - regexp "The length res_$ic is +(\[-0-9.+eE\]+)" ${le} full ll - - if { $ll < 1.0e-7 } { - puts "Error: Curve is too small!" - } + display res_$ic bounds res_$ic U1 U2 - if {[dval U2-U1] < 1.0e-9} { + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs res_$ic s1 U1 U2 10 1e-7 - xdistcs res_$ic s2 U1 U2 10 1e-7 + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 incr ic } } - + if {[expr {$ic - 1}] == $GoodNbCurv} { puts "OK: Curve Number is good!" } else { diff --git a/tests/bugs/modalg_5/bug25292_36 b/tests/bugs/modalg_5/bug25292_36 index a7a1d58f2f..dd3cac81cb 100644 --- a/tests/bugs/modalg_5/bug25292_36 +++ b/tests/bugs/modalg_5/bug25292_36 @@ -37,8 +37,7 @@ set che [whatis res] set ind [string first "3d curve" $che] if {${ind} >= 0} { #Only variable "res" exists - - copy res res_1 + renamevar res res_1 } set ic 1 @@ -49,19 +48,24 @@ while { $AllowRepeate != 0 } { if {${ind} < 0} { set AllowRepeate 0 } else { + display res_$ic + bounds res_$ic U1 U2 - if {[dval U2-U1] < 1.0e-9} { + dval U1 + dval U2 + + if {[dval U2-U1] < 1.0e-20} { puts "Error: Wrong curve's range!" } - xdistcs res_$ic s1 U1 U2 10 1e-7 - xdistcs res_$ic s2 U1 U2 10 1e-7 + xdistcs res_$ic s1 U1 U2 10 1.0e-7 + xdistcs res_$ic s2 U1 U2 10 1.0e-7 incr ic } } - + if {[expr {$ic - 1}] == $GoodNbCurv} { puts "OK: Curve Number is good!" } else { diff --git a/tests/bugs/modalg_6/bug26310_3 b/tests/bugs/modalg_6/bug26310_3 index 3879f7ca43..771fb120de 100644 --- a/tests/bugs/modalg_6/bug26310_3 +++ b/tests/bugs/modalg_6/bug26310_3 @@ -9,10 +9,21 @@ puts "" restore [locate_data_file OCC26310-b1.brep] b1 restore [locate_data_file OCC26310-b2.brep] b2 -bop b1 b2 +bclearobjects +bcleartools +baddobjects b1 +baddtools b2 +bfillds -bopcut res1 -boptuc res2 + +# SECTION +bbop rr 4 + +# CUT 1-2 +bbop res1 2 + +# CUT 2-1 +bbop res2 3 checkshape res1 checkshape res2 @@ -28,9 +39,13 @@ if { [string compare -nocase $log2 "Shape(s) seem(s) to be valid for BOP.\n"] } puts "ERROR. res2 is not valid for BOP" } +checknbshapes res1 -wire 6 -face 6 -shell 1 -solid 1 -t +checknbshapes res2 -wire 6 -face 6 -shell 1 -solid 1 -t + smallview -donly res1 +donly rr fit +donly res1 xwd ${imagedir}/${casename}_1.png donly res2 fit diff --git a/tests/bugs/modalg_6/bug26310_4 b/tests/bugs/modalg_6/bug26310_4 index b5a9c363f5..80823e2ddf 100644 --- a/tests/bugs/modalg_6/bug26310_4 +++ b/tests/bugs/modalg_6/bug26310_4 @@ -9,10 +9,21 @@ puts "" restore [locate_data_file OCC26310-b1.brep] b1 restore [locate_data_file OCC26310-b2.brep] b2 -bop b2 b1 +bclearobjects +bcleartools +baddobjects b2 +baddtools b1 +bfillds -bopcut res1 -boptuc res2 + +# SECTION +bbop rr 4 + +# CUT 1-2 +bbop res1 2 + +# CUT 2-1 +bbop res2 3 checkshape res1 checkshape res2 @@ -20,26 +31,22 @@ checkshape res2 set log1 [bopargcheck res1 #F] set log2 [bopargcheck res2 #F] -if { [string first "Faulties for FIRST shape found : 2" $log1] >= 0 } { - puts "ERROR in bopargcheck res1" +if { [string compare -nocase $log1 "Shape(s) seem(s) to be valid for BOP.\n"] } { + puts "ERROR. res1 is not valid for BOP" } -if { [string first "Shapes with Continuity C0 : YES Cases(2) Total shapes(2)" $log1] >= 0 } { - puts "ERROR. res1 with continuity C0." +if { [string compare -nocase $log2 "Shape(s) seem(s) to be valid for BOP.\n"] } { + puts "ERROR. res2 is not valid for BOP" } -if { [string first "Faulties for FIRST shape found : 2" $log2] >= 0 } { - puts "ERROR in bopargcheck res2" -} - -if { [string first "Shapes with Continuity C0 : YES Cases(2) Total shapes(2)" $log2] >= 0 } { - puts "ERROR. res2 with continuity C0." -} +checknbshapes res1 -wire 6 -face 6 -shell 1 -solid 1 -t +checknbshapes res2 -wire 6 -face 6 -shell 1 -solid 1 -t smallview donly res1 fit xwd ${imagedir}/${casename}_1.png -donly res2 +donly rr fit +donly res2 xwd ${imagedir}/${casename}_2.png diff --git a/tests/bugs/modalg_6/bug27310_1 b/tests/bugs/modalg_6/bug27310_1 index 3aff9cf90e..146b73dda3 100644 --- a/tests/bugs/modalg_6/bug27310_1 +++ b/tests/bugs/modalg_6/bug27310_1 @@ -6,8 +6,11 @@ puts "" # Huge tolerance obtained in the result of intersection of two cylindrical faces ################################################# +# Number of intersection curves cannot be subject to anything (indeed, output result can be empty). +# The main reason of the bug #27310 was a HUGE TOLERANCE VALUE (TolReached > 10). +# See test "bugs moddata_2 bug496" in case of doubt. + set ExpTol 1.0e-7 -set GoodNbCurv 2 restore [locate_data_file OCC496a.brep] a restore [locate_data_file OCC496b.brep] b @@ -19,15 +22,4 @@ set log [bopcurves a_8 b_2 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv -if {${NbCurv} != ${GoodNbCurv}} { - puts "Error: Number of curves is bad!" -} - -checkreal TolReached $Toler $ExpTol 0.0 0.1 - -smallview -don c_* -fit -disp a_8 b_2 - -checkview -screenshot -2d -path ${imagedir}/${test_image}.png +checkreal TolReached $Toler $ExpTol 0.0 0.1 \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27310_2 b/tests/bugs/modalg_6/bug27310_2 index 8c578725be..38eda856fe 100644 --- a/tests/bugs/modalg_6/bug27310_2 +++ b/tests/bugs/modalg_6/bug27310_2 @@ -6,8 +6,11 @@ puts "" # Huge tolerance obtained in the result of intersection of two cylindrical faces ################################################# -set ExpTol 6.9230965382090094e-006 -set GoodNbCurv 2 +# Number of intersection curves cannot be subject to anything (indeed, output result can be empty). +# The main reason of the bug #27310 was a HUGE TOLERANCE VALUE (TolReached > 10). +# See test "bugs moddata_2 bug496" in case of doubt. + +set ExpTol 1.3609186093470008e-005 restore [locate_data_file OCC496a.brep] a restore [locate_data_file OCC496b.brep] b @@ -19,15 +22,4 @@ set log [bopcurves a_10 b_4 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv -if {${NbCurv} != ${GoodNbCurv}} { - puts "Error: Number of curves is bad!" -} - -checkreal TolReached $Toler $ExpTol 0.0 0.1 - -smallview -don c_* -fit -disp a_10 b_4 - -checkview -screenshot -2d -path ${imagedir}/${test_image}.png +checkreal TolReached $Toler $ExpTol 0.0 0.1 \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug27856_2 b/tests/bugs/modalg_6/bug27856_2 index 17e72d77ec..aabc7a1671 100644 --- a/tests/bugs/modalg_6/bug27856_2 +++ b/tests/bugs/modalg_6/bug27856_2 @@ -23,7 +23,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_1_2 b_2_2 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 0.00026943844817627679 0.0 1.0e-3 +checkreal TolReached $Toler 0.00026207823091004516 0.0 1.0e-3 # ---- @@ -33,7 +33,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_1_4 b_2_4 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 6.5039065434503992e-005 0.0 1.0e-2 +checkreal TolReached $Toler 6.5053102894636701e-005 0.0 1.0e-2 # ---- @@ -50,7 +50,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_3_2 b_4_2 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 0.00030603795647549098 0.0 1.0e-3 +checkreal TolReached $Toler 0.00029706239430643614 0.0 1.0e-3 # ---- @@ -60,7 +60,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_3_4 b_4_4 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 0.00029242900088525842 0.0 1.0e-3 +checkreal TolReached $Toler 0.00029242389138280588 0.0 1.0e-3 # ---- @@ -77,7 +77,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_5_2 b_6_2 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 2.0312181042800029e-005 0.0 1.0e-2 +checkreal TolReached $Toler 1.4980089259007279e-005 0.0 1.0e-2 # ---- @@ -87,7 +87,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_5_4 b_6_4 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 0.00023415774730871651 0.0 1.0e-3 +checkreal TolReached $Toler 0.00023417493528435788 0.0 1.0e-3 # ---- @@ -104,7 +104,7 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_7_2 b_8_2 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 0.00028209392756607551 0.0 1.0e-3 +checkreal TolReached $Toler 0.00027445924390073518 0.0 1.0e-3 # ---- @@ -114,5 +114,5 @@ regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b_7_4 b_8_4 if {${NbCurv} != 1} { puts "Error: Number of curves is bad!" } -checkreal TolReached $Toler 2.497244318171703e-005 0.0 1.0e-2 +checkreal TolReached $Toler 1.867918118939262e-005 0.0 1.0e-2 diff --git a/tests/bugs/modalg_6/bug28009_2 b/tests/bugs/modalg_6/bug28009_2 index f5b68179a0..4a80364132 100644 --- a/tests/bugs/modalg_6/bug28009_2 +++ b/tests/bugs/modalg_6/bug28009_2 @@ -7,7 +7,7 @@ puts "" ####################################################################### set NbCurvGood 1 -set ExpToler 9.0002189481237598e-008 +set ExpToler 7.1928004468800293e-008 restore [locate_data_file bug28009_shape.brep] a diff --git a/tests/bugs/modalg_6/bug28222_1 b/tests/bugs/modalg_6/bug28222_1 new file mode 100644 index 0000000000..d6bf565cb7 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_1 @@ -0,0 +1,45 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +dsetsignal 1 + +set GoodNbCurv 4 + +foreach c [directory result*] { + unset $c +} + +restore [locate_data_file bug28222_s1_cyl_read_d2.draw] s1 +restore [locate_data_file bug28222_s2_cyl_read_d2.draw] s2 + +intersect result s1 s2 + +foreach c [directory result*] { + bounds $c U1 U2 + + if {[dval U2-U1] < 1.0e-9} { + puts "Error: Wrong curve's range!" + } + + xdistcs $c s1 U1 U2 10 2.0e-7 + xdistcs $c s2 U1 U2 10 2.0e-7 +} + +set NbCurv [llength [directory result*]] + +if { $NbCurv == $GoodNbCurv } { + puts "OK: Number of curves is good!" +} else { + puts "Error: $GoodNbCurv is expected but $NbCurv is found!" +} + +smallview +don result* +fit +disp s1 s2 +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug28222_2 b/tests/bugs/modalg_6/bug28222_2 new file mode 100644 index 0000000000..3fd838d958 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_2 @@ -0,0 +1,45 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +dsetsignal 1 + +set GoodNbCurv 4 + +foreach c [directory result*] { + unset $c +} + +cylinder s1 -35 13.3706576198285 30.5814570420266 0 -0.258819045102521 -0.965925826289068 0 0.965925826289068 -0.258819045102521 11 +cylinder s2 0 0 0 1 0 0 0 0 -1 16.5 + +intersect result s1 s2 + +foreach c [directory result*] { + bounds $c U1 U2 + + if {[dval U2-U1] < 1.0e-9} { + puts "Error: Wrong curve's range!" + } + + xdistcs $c s1 U1 U2 10 2.0e-7 + xdistcs $c s2 U1 U2 10 2.0e-7 +} + +set NbCurv [llength [directory result*]] + +if { $NbCurv == $GoodNbCurv } { + puts "OK: Number of curves is good!" +} else { + puts "Error: $GoodNbCurv is expected but $NbCurv is found!" +} + +smallview +don result* +fit +disp s1 s2 +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug28222_3 b/tests/bugs/modalg_6/bug28222_3 new file mode 100644 index 0000000000..3e1f0ac0f4 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_3 @@ -0,0 +1,46 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +dsetsignal 1 + +set GoodNbCurv 2 + +foreach c [directory result*] { + unset $c +} + +cylinder s1 -9 -5 -2.2058 0 -1 0 0.001 +cylinder s2 0 0 -2.2058 0 0 -1 9 + +intersect result s1 s2 + +foreach c [directory result*] { + bounds $c U1 U2 + + if {[dval U2-U1] < 1.0e-9} { + puts "Error: Wrong curve's range!" + } + + xdistcs $c s1 U1 U2 10 2.0e-7 + xdistcs $c s2 U1 U2 10 2.0e-7 +} + +set NbCurv [llength [directory result*]] + +if { $NbCurv == $GoodNbCurv } { + puts "OK: Number of curves is good!" +} else { + puts "Error: $GoodNbCurv is expected but $NbCurv is found!" +} + +smallview +don result* +fit +don s1 s2 +disp result* +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug28706 b/tests/bugs/modalg_6/bug28706 new file mode 100644 index 0000000000..6c8fdf1008 --- /dev/null +++ b/tests/bugs/modalg_6/bug28706 @@ -0,0 +1,32 @@ +puts "================" +puts "OCC28706" +puts "================" +puts "" +####################################################################### +# Incomplete result of section operation between attached shapes +####################################################################### + +dsetsignal 1 + +# Before the fix, section curve was incomplete + +restore [locate_data_file bug28706_ar_shape.brep] s1 +restore [locate_data_file bug28706_Prism.brep] s2 + +bsection result s1 s2 + +regexp {nb alone Vertices : ([-0-9.+eE]+)} [checksection result] full nbv + +if { $nbv != 0 } { + puts "Error : Section is incorrect" +} else { + puts "Section is correct" +} + +checkprops result -l 6.16832 + +smallview +don result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_2/bug235 b/tests/bugs/moddata_2/bug235 index 22a8029e69..81d1fa032a 100755 --- a/tests/bugs/moddata_2/bug235 +++ b/tests/bugs/moddata_2/bug235 @@ -36,6 +36,9 @@ if { $nb_result != 2 } { } } -checkview -display result -2d -path ${imagedir}/${test_image}.png +smallview +don result* +fit +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/perf/modalg/bug26310_1 b/tests/perf/modalg/bug26310_1 index 826d18203b..eda200db04 100644 --- a/tests/perf/modalg/bug26310_1 +++ b/tests/perf/modalg/bug26310_1 @@ -6,27 +6,32 @@ puts "" # Very slow boolean cut operations on cylinders ################################################# -if { [regexp {Debug mode} [dversion]] } { - set max_time 0.3 -} else { - set max_time 0.15 -} +set ExpTol1 3.2300230820477792e-007 +set ExpTol2 3.2198007889220219e-007 -set maxToler 1.5e-5 +set GoodNbCurv 4 restore [locate_data_file OCC26310-b1.brep] b1 -restore [locate_data_file OCC26310-b2.brep] b2 +restore [locate_data_file OCC26310-b2.brep] b2 explode b1 f explode b2 f -dchrono cr restart -set log1 [bopcurves b1_1 b2_1 -2d] -dchrono cr stop counter bopcurves +set log [bopcurves b1_1 b2_1 -2d] +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv -regexp {Tolerance Reached=+([-0-9.+eE]+)} ${log1} full Toler -puts "TolReached = $Toler" +checkreal ToleranceReached ${Toler} ${ExpTol1} 0.0 0.01 + +if {${NbCurv} != ${GoodNbCurv}} { + puts "Error: Number of curves is bad!" +} + +set log [bopcurves b2_1 b1_1 -2d] +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv + +checkreal ToleranceReached ${Toler} ${ExpTol2} 0.0 0.01 + +if {${NbCurv} != ${GoodNbCurv}} { + puts "Error: Number of curves is bad!" +} -if { $Toler > $maxToler } { - puts "Error: Tolerance is too big ($Toler > $maxToler)" -} \ No newline at end of file