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 439008f1f8..6adc880193 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 cdd1640b14..2078f2dcfd 100644 --- a/src/ElCLib/ElCLib.cxx +++ b/src/ElCLib/ElCLib.cxx @@ -28,6 +28,22 @@ static Standard_Real PIPI = M_PI + M_PI; //======================================================================= //function : InPeriod //purpose : +// 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 U, diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx index e2f049e236..0a014fbd89 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_1.gxx @@ -71,17 +71,16 @@ static void ProcessBounds(const Handle(IntPatch_ALine)&, static Standard_Boolean 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); + 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); static Standard_Boolean IntCySp(const IntSurf_Quadric&, diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx index 145b17d3b2..14d1bf691d 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_2.gxx @@ -152,59 +152,39 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1, case 22: { // Cylinder/Cylinder Standard_Boolean isDONE = Standard_False; - Bnd_Box2d aBox1, aBox2; + Bnd_Box2d aBox1, aBox2; - const Standard_Real aU1f = S1->FirstUParameter(); - Standard_Real aU1l = S1->LastUParameter(); - const Standard_Real aU2f = S2->FirstUParameter(); - Standard_Real aU2l = S2->LastUParameter(); + const Standard_Real aU1f = S1->FirstUParameter(); + Standard_Real aU1l = S1->LastUParameter(); + const Standard_Real aU2f = S2->FirstUParameter(); + Standard_Real aU2l = S2->LastUParameter(); - const Standard_Real anUperiod = 2.0*M_PI; + const Standard_Real anUperiod = 2.0*M_PI; - if(aU1l - aU1f > anUperiod) - aU1l = aU1f + anUperiod; + if (aU1l - aU1f > anUperiod) + aU1l = aU1f + anUperiod; - if(aU2l - aU2f > anUperiod) - aU2l = aU2f + anUperiod; + if (aU2l - aU2f > anUperiod) + aU2l = aU2f + anUperiod; - aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter())); - aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter())); - aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter())); - aBox2.Add(gp_Pnt2d(aU2l, S2->LastVParameter())); + aBox1.Add(gp_Pnt2d(aU1f, S1->FirstVParameter())); + aBox1.Add(gp_Pnt2d(aU1l, S1->LastVParameter())); + aBox2.Add(gp_Pnt2d(aU2f, S2->FirstVParameter())); + 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)); + isDONE = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2, + empt, SameSurf, multpoint, slin, spnt); - if(isReversed) - { - isDONE = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1, - Standard_True, empt, SameSurf, multpoint, slin, spnt); - } - else - { - isDONE = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2, - Standard_False, empt, SameSurf, multpoint, slin, spnt); - } - - if(!isDONE) - { + if (!isDONE) + { return; - } + } bEmpty = empt; if(!slin.IsEmpty()) diff --git a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx index a5b67544bd..a994a4592a 100644 --- a/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx +++ b/src/IntPatch/IntPatch_ImpImpIntersection_4.gxx @@ -22,6 +22,7 @@ #include #include +#include //If Abs(a) <= aNulValue then it is considered that a = 0. static const Standard_Real aNulValue = 1.0e-11; @@ -335,7 +336,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; @@ -376,8 +377,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, @@ -388,8 +436,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, @@ -835,21 +884,21 @@ void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne coura //======================================================================= //function : CyCyAnalyticalIntersect -//purpose : +//purpose : Checks if intersection curve is analytical (line, circle, ellipse) +// and returns these curves. //======================================================================= Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, - const IntSurf_Quadric& Quad2, + 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, - IntPatch_SequenceOfLine& slin, - IntPatch_SequenceOfPoint& spnt) + const Standard_Real Tol, + Standard_Boolean& Empty, + Standard_Boolean& Same, + Standard_Boolean& Multpoint, + IntPatch_SequenceOfLine& slin, + IntPatch_SequenceOfPoint& spnt) { IntPatch_Point ptsol; - + Standard_Integer i; IntSurf_TypeTrans trans1,trans2; @@ -879,24 +928,15 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, Same = Standard_True; } break; - + case IntAna_Point: { gp_Pnt psol(theInter.Point(1)); 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); @@ -1030,46 +1070,28 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, gp_Vec Tgt; gp_Pnt ptref; IntPatch_Point pmult1, pmult2; - + elipsol = theInter.Ellipse(1); - + gp_Pnt pttang1(ElCLib::Value(0.5*M_PI, elipsol)); gp_Pnt pttang2(ElCLib::Value(1.5*M_PI, elipsol)); - + Multpoint = Standard_True; pmult1.SetValue(pttang1,Tol,Standard_True); pmult2.SetValue(pttang2,Tol,Standard_True); pmult1.SetMultiple(Standard_True); 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); - } + Standard_Real oU1,oV1,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); - } pmult2.SetParameters(oU1,oV1,oU2,oV2); - + // on traite la premiere ellipse //-- Calcul de la Transition de la ligne @@ -1088,7 +1110,7 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, trans2 = IntSurf_Out; } else - { + { trans1=trans2=IntSurf_Undecided; } @@ -1104,17 +1126,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); - } aIP.SetParameters(aU1, aV1, aU2, aV2); // @@ -1188,16 +1201,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); + Quad1.Parameters(aP, aU1, aV1); Quad2.Parameters(aP, aU2, aV2); - } aIP.SetParameters(aU1, aV1, aU2, aV2); // @@ -1219,8 +1224,8 @@ Standard_Boolean CyCyAnalyticalIntersect( const IntSurf_Quadric& Quad1, case IntAna_Parabola: case IntAna_Hyperbola: - Standard_Failure::Raise("IntCyCy(): Wrong intersection type!"); - + throw Standard_Failure("IntCyCy(): Wrong intersection type!"); + case IntAna_Circle: // Circle is useful when we will work with trimmed surfaces // (two cylinders can be tangent by their basises, e.g. circle) @@ -1293,10 +1298,10 @@ static void ShortCosForm( const Standard_Real theCosFactor, //purpose : Determines, if U2(U1) function is increasing. //======================================================================= Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real theU1par, - const Standard_Integer theWLIndex, - const stCoeffsValue& theCoeffs, - const Standard_Real thePeriod, - Standard_Boolean& theIsIncreasing) + const Standard_Integer theWLIndex, + const stCoeffsValue& theCoeffs, + const Standard_Real thePeriod, + Standard_Boolean& theIsIncreasing) { // U2(U1) = FI2 + (+/-)acos(B*cos(U1 - FI1) + C); //Accordingly, @@ -1331,7 +1336,7 @@ Standard_Boolean ComputationMethods::CylCylMonotonicity(const Standard_Real theU isPlus = Standard_False; break; default: - //Standard_Failure::Raise("Error. Range Error!!!!"); + //throw Standard_Failure("Error. Range Error!!!!"); return Standard_False; } @@ -1361,7 +1366,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, @@ -1382,14 +1387,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; @@ -1437,6 +1442,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, @@ -1456,7 +1465,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, @@ -1664,38 +1677,49 @@ Standard_Boolean InscribePoint( const Standard_Real theUfTarget, const Standard_Real aUl = aUf + thePeriod; theUGiven = ElCLib::InPeriod(theUGiven, aUf, aUl); - + return ((theUfTarget - theUGiven <= theTol2D) && (theUGiven - theUlTarget <= theTol2D)); } //======================================================================= //function : InscribeInterval -//purpose : Adjusts theUfGiven and after that fits theUlGiven to 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 { @@ -1737,7 +1761,7 @@ static Standard_Boolean ExcludeNearElements(Standard_Real theArr[], if((anA-anB) < theTol) { if((anB != 0.0) && (anB != theUSurf1f) && (anB != theUSurf1l)) - anA = (anA + anB)/2.0; + anA = (anA + anB)/2.0; else anA = anB; @@ -1754,6 +1778,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, @@ -1775,17 +1804,48 @@ 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. + gp_Pnt aPt1(theQuad1.Value(thePntOnSurf1.X(), thePntOnSurf1.Y())), 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)) @@ -1799,6 +1859,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, if((aV2par - theVlSurf2 > theTol2D) || (theVfSurf2 - aV2par > theTol2D)) return Standard_False; + //Get intersection point and add it in the WL IntSurf_PntOn2S aPnt; if(isTheReverse) @@ -1827,7 +1888,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 @@ -1838,10 +1899,13 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, //New aU1par is out of target interval. //Go back to old value. - return Standard_False; - } + return Standard_False; + } } + 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, @@ -1853,6 +1917,9 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, } } + if (theOnlyCheck) + return Standard_True; + theLine->Add(aPnt); if(!isThePrecise) @@ -1883,6 +1950,7 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, if((1 < aDeltaStep) && (aDeltaStep < 2000)) { + //Add new points in case of non-uniform distribution of existing points SeekAdditionalPoints( theQuad1, theQuad2, theLine, theCoeffs, theWLIndex, aDeltaStep, aNbPnts-2, aNbPnts-1, theTol2D, thePeriodOfSurf1, isTheReverse); @@ -1894,10 +1962,11 @@ static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1, //======================================================================= //function : AddBoundaryPoint -//purpose : +//purpose : Find intersection point on V-boundary. //======================================================================= 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, @@ -1919,7 +1988,7 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, myUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l); myUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l); - + const Standard_Integer aSize = 4; const Standard_Real anArrVzad[aSize] = {aVSurf1f, aVSurf1l, aVSurf2f, aVSurf2l}; @@ -1933,30 +2002,39 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, const SearchBoundType aTS = (anIDSurf == 0) ? SearchV1 : SearchV2; for(Standard_Integer anIDBound = 0; anIDBound < 2; anIDBound++) - { - + { const Standard_Integer anIndex = anIDSurf+anIDBound; aUVPoint[anIndex].mySurfID = anIDSurf; if((Abs(aVf-anArrVzad[anIndex]) > myTol2D) && ((aVf-anArrVzad[anIndex])*(aVl-anArrVzad[anIndex]) > 0.0)) - { + { continue; } - + + //Segment [aVf, aVl] intersects at least one V-boundary (first or last) + // (in general, case is possible, when aVf > aVl). + + // Precise intersection point const Standard_Boolean aRes = SearchOnVBounds(aTS, anArrVzad[anIndex], (anIDSurf == 0) ? theV2 : theV1, 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(); continue; } - else - { + else + { + //intersection point is found + Standard_Real &aU1 = aUVPoint[anIndex].myU1, &aU2 = aUVPoint[anIndex].myU2, &aV1 = aUVPoint[anIndex].myV1, @@ -1967,25 +2045,29 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, if(!ComputationMethods:: CylCylComputeParameters(aU1, theWLIndex, myCoeffs, aU2, aV1, aV2)) - { + { + // Found point is wrong aU1 = RealLast(); continue; - } + } + //Point on true V-boundary. if(aTS == SearchV1) aV1 = anArrVzad[anIndex]; else //if(aTS[anIndex] == SearchV2) aV2 = anArrVzad[anIndex]; } } - } + } + // Sort with acceding U1-parameter. std::sort(aUVPoint, aUVPoint+aSize); - + isTheFound1 = isTheFound2 = Standard_False; + //Adding found points on boundary in the WLine. for(Standard_Integer i = 0; i < aSize; i++) - { + { if(aUVPoint[i].myU1 == RealLast()) break; @@ -1997,12 +2079,12 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, theWL->Curve(), theWLIndex, myTol3D, myTol2D, theFlForce)) { continue; - } + } if(aUVPoint[i].mySurfID == 0) - { + { isTheFound1 = Standard_True; - } + } else { isTheFound2 = Standard_True; @@ -2012,7 +2094,10 @@ void WorkWithBoundaries::AddBoundaryPoint(const Handle(IntPatch_WLine)& theWL, //======================================================================= //function : SeekAdditionalPoints -//purpose : +//purpose : Inserts additional intersection points between neighbor points. +// This action is bone with several iterations. During every iteration, +// new point is inserted in middle of every interval. +// The process will be finished if NbPoints >= theMinNbPoints. //======================================================================= static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1, const IntSurf_Quadric& theQuad2, @@ -2143,55 +2228,55 @@ 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[]) { - if(myCoeffs.mB > 0.0) + if (theCoeffs.mB > 0.0) { - if(myCoeffs.mB + Abs(myCoeffs.mC) < -1.0) + if (theCoeffs.mB + Abs(theCoeffs.mC) < -1.0) {//There is NOT intersection return Standard_False; } - else if(myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0) - {//U=[0;2*PI]+aFI1 - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = myPeriod + myCoeffs.mFI1; - } - else if((1 + myCoeffs.mC <= myCoeffs.mB) && - (myCoeffs.mB <= 1 - myCoeffs.mC)) + else if (theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0) { - Standard_Real anArg = -(myCoeffs.mC + 1) / myCoeffs.mB; + //(1-C)/B >= 1 and -(1+C)/B <= -1 ==> U=[0;2*PI]+aFI1 + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(thePeriod + theCoeffs.mFI1); + } + else if ((1 + theCoeffs.mC <= theCoeffs.mB) && + (theCoeffs.mB <= 1 - theCoeffs.mC)) + { + 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); - //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1) - 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)) { - 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); - //U=[aDAngle;2*PI-aDAngle]+aFI1 - - 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) { - 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) @@ -2205,64 +2290,60 @@ 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) { - if(myCoeffs.mB + Abs(myCoeffs.mC) > 1.0) + if (theCoeffs.mB + Abs(theCoeffs.mC) > 1.0) {//There is NOT intersection return Standard_False; } - else if(-myCoeffs.mB + Abs(myCoeffs.mC) <= 1.0) - {//U=[0;2*PI]+aFI1 - theU1f[0] = myCoeffs.mFI1; - theU1l[0] = myPeriod + myCoeffs.mFI1; - } - else if((-myCoeffs.mC - 1 <= myCoeffs.mB) && - ( myCoeffs.mB <= myCoeffs.mC - 1)) + else if (-theCoeffs.mB + Abs(theCoeffs.mC) <= 1.0) { - Standard_Real anArg = (1 - myCoeffs.mC) / myCoeffs.mB; + // -(1+C)/B >= 1 and (1-C)/B <= -1 ==> U=[0;2*PI]+aFI1 + theURange[0].Add(theCoeffs.mFI1); + theURange[0].Add(thePeriod + theCoeffs.mFI1); + } + else if ((-theCoeffs.mC - 1 <= theCoeffs.mB) && + (theCoeffs.mB <= theCoeffs.mC - 1)) + { + 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); - //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1) - - 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)) { - 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); - //U=[aDAngle;2*PI-aDAngle]+aFI1 - - 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) { - 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) @@ -2274,13 +2355,10 @@ Standard_Boolean WorkWithBoundaries::BoundariesComputing(Standard_Real theU1f[], anArg2 = -1.0; 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 { @@ -2310,13 +2388,13 @@ static void CriticalPointsComputing(const ComputationMethods::stCoeffsValue& the Standard_Integer& theNbCritPointsMax, Standard_Real theU1crit[]) { - //[0...1] - in these points parameter U1 goes through - // the seam-edge of the first cylinder. - //[2...3] - First and last U1 parameter. - //[4...5] - in these points parameter U2 goes through - // the seam-edge of the second cylinder. - //[6...9] - in these points an intersection line goes through - // U-boundaries of the second surface. + //[0...1] - in these points parameter U1 goes through + // the seam-edge of the first cylinder. + //[2...3] - First and last U1 parameter. + //[4...5] - in these points parameter U2 goes through + // the seam-edge of the second cylinder. + //[6...9] - in these points an intersection line goes through + // U-boundaries of the second surface. //[10...11] - Boundary of monotonicity interval of U2(U1) function // (see CylCylMonotonicity() function) @@ -2486,161 +2564,126 @@ void WorkWithBoundaries::BoundaryEstimation(const gp_Cylinder& theCy1, } //======================================================================= -//function : IntCyCy +//function : CyCyNoGeometric //purpose : //======================================================================= -Standard_Boolean 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) +Standard_Boolean 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 Standard_False; - } - - if(anInter.TypeInter() != IntAna_NoGeometricSolution) - { - return CyCyAnalyticalIntersect( theQuad1, theQuad2, anInter, - theTol3D, isTheReverse, isTheEmpty, - isTheSameSurface, isTheMultiplePoint, - theSlin, theSPnt); - } - - 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 Standard_True; - //Boundaries - 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 Standard_True; + 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; - for(Standard_Integer i = 0; i < aNbOfBoundaries; i++) + //The main idea of the algorithm is to change U1-parameter + //(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 < 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 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() }; Standard_Integer aNbCritPoints = aNbCritPointsMax; CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l, - aPeriod, theTol2D, aNbCritPoints, anU1crit); + aPeriod, aTol2D, aNbCritPoints, anU1crit); //Getting Walking-line enum WLFStatus { + // No points have been added in WL WLFStatus_Absent = 0, - WLFStatus_Exist = 1, + // WL contains at least one point + 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++) { - if(Precision::IsInfinite(aU1f[aCurInterval]) && Precision::IsInfinite(aU1l[aCurInterval])) - continue; - + //Process every continuous region 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). + //Step is computed adaptively (see comments below). + Standard_Real aU2[aNbWLines], aV1[aNbWLines], aV2[aNbWLines]; WLFStatus aWLFindStatus[aNbWLines]; Standard_Real aV1Prev[aNbWLines], aV2Prev[aNbWLines]; @@ -2649,7 +2692,7 @@ Standard_Boolean 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); @@ -2659,27 +2702,33 @@ Standard_Boolean 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++) - { //We are not intersted in elements of aCriticalDelta array + + 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) { - for(Standard_Integer i = 0; i < aNbCritPoints; i++) + //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++) { - 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; @@ -2689,14 +2738,14 @@ Standard_Boolean 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 @@ -2710,57 +2759,57 @@ Standard_Boolean 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 @@ -2775,7 +2824,7 @@ Standard_Boolean 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; } @@ -2787,19 +2836,19 @@ Standard_Boolean 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; @@ -2810,7 +2859,7 @@ Standard_Boolean 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]; @@ -2821,36 +2870,36 @@ Standard_Boolean 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; } @@ -2860,19 +2909,19 @@ Standard_Boolean IntCyCy( const IntSurf_Quadric& theQuad1, } } - 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); + // True if the current point already in the domain + 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 @@ -2883,52 +2932,52 @@ Standard_Boolean 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; } @@ -2939,47 +2988,47 @@ Standard_Boolean 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; } @@ -2988,28 +3037,28 @@ Standard_Boolean 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; } @@ -3020,30 +3069,35 @@ Standard_Boolean 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). + //Therefore, we take the point last added in some WL + //(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); @@ -3052,29 +3106,29 @@ Standard_Boolean 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); } } @@ -3084,21 +3138,27 @@ Standard_Boolean IntCyCy( const IntSurf_Quadric& theQuad1, //Step computing { - const Standard_Real aDeltaV1 = aRangeS1.Delta()/IntToReal(aNbPoints), - aDeltaV2 = aRangeS2.Delta()/IntToReal(aNbPoints); - + //Step of aU1-parameter is computed adaptively. The algorithm + //aims to provide given aDeltaV1 and aDeltaV2 values (if it is + //possible because the intersection line can go along V-isoline) + //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); + 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]); @@ -3120,7 +3180,23 @@ Standard_Boolean IntCyCy( const IntSurf_Quadric& theQuad1, anEquationCoeffs.mVecA2*aCosU2 + anEquationCoeffs.mVecB2*aSinU2 + anEquationCoeffs.mVecD); - if(!StepComputing(aMatr, aV1[i], aV2[i], aDeltaV1, aDeltaV2, aStepTmp)) + //The main idea is in solving of linearized system (2) + //(see description to ComputationMethods class) in order to find new U1-value + //to provide new value V1 or V2, which differs from current one by aDeltaV1 or + //aDeltaV2 respectively. + + //While linearizing, following Taylor formulas are used: + // cos(x0+dx) = cos(x0) - sin(x0)*dx + // sin(x0+dx) = sin(x0) + cos(x0)*dx + + //Consequently cos(U1), cos(U2), sin(U1) and sin(U2) in the system (2) + //must be substituted by corresponding values. + + //ATTENTION!!! + //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)) { //To avoid cycling-up anUexpect[i] += aStepMax; @@ -3129,10 +3205,10 @@ Standard_Boolean 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; @@ -3142,26 +3218,26 @@ Standard_Boolean 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; @@ -3169,34 +3245,34 @@ Standard_Boolean 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]); } } @@ -3215,19 +3291,19 @@ Standard_Boolean 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--; @@ -3236,10 +3312,20 @@ Standard_Boolean 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; @@ -3247,81 +3333,328 @@ Standard_Boolean 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 Standard_True; } +//======================================================================= +//function : IntCyCy +//purpose : +//======================================================================= +Standard_Boolean 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 Standard_False; + } + + if (anInter.TypeInter() != IntAna_NoGeometricSolution) + { + return (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter, + theTol3D, isTheEmpty, + isTheSameSurface, isTheMultiplePoint, + theSlin, theSPnt)); + } + + //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 Standard_True; + + if (!WorkWithBoundaries::BoundariesComputing(anEquationCoeffs2, aPeriod, anURange[1])) + return Standard_True; + + //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 20546a04ef..50ba8ecf30 100644 --- a/src/IntPatch/IntPatch_Intersection.cxx +++ b/src/IntPatch/IntPatch_Intersection.cxx @@ -1367,19 +1367,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the if ((typs1 == GeomAbs_Cylinder) && (typs2 == 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); } } } diff --git a/src/IntPatch/IntPatch_PointLine.cdl b/src/IntPatch/IntPatch_PointLine.cdl index 02d293d746..f6c38992e1 100644 --- a/src/IntPatch/IntPatch_PointLine.cdl +++ b/src/IntPatch/IntPatch_PointLine.cdl @@ -27,7 +27,8 @@ inherits Line from IntPatch uses TypeTrans from IntSurf, Situation from IntSurf, - PntOn2S from IntSurf + PntOn2S from IntSurf, + HSurface from Adaptor3d raises DomainError from Standard, @@ -70,6 +71,12 @@ is is deferred; + CurvatureRadiusOfIntersLine(myclass; theS1, theS2 : HSurface from Adaptor3d; theUVPoint : PntOn2S from IntSurf) + ---Purpose: Returns the radius of curvature of the intersection line in given point. + -- Returns negative value if computation is not possible. + + returns Real from Standard; + -- fields end Line; diff --git a/src/IntPatch/IntPatch_PointLine.cxx b/src/IntPatch/IntPatch_PointLine.cxx index 0025d9a721..50e7c0107f 100644 --- a/src/IntPatch/IntPatch_PointLine.cxx +++ b/src/IntPatch/IntPatch_PointLine.cxx @@ -15,6 +15,8 @@ // commercial license or contractual agreement. #include +#include +#include IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang, @@ -33,4 +35,166 @@ IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang) : IntPatch_Line(Tang) {} +//======================================================================= +//function : CurvatureRadiusOfIntersLine +//purpose : +// ATTENTION!!! +// Returns negative value if computation is not possible +//======================================================================= +Standard_Real IntPatch_PointLine:: +CurvatureRadiusOfIntersLine(const Handle(Adaptor3d_HSurface)& theS1, +const Handle(Adaptor3d_HSurface)& theS2, +const IntSurf_PntOn2S& theUVPoint) +{ + const Standard_Real aSmallValue = 1.0 / Precision::Infinite(); + const Standard_Real aSqSmallValue = aSmallValue*aSmallValue; + + Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; + theUVPoint.Parameters(aU1, aV1, aU2, aV2); + gp_Pnt aPt; + gp_Vec aDU1, aDV1, aDUU1, aDUV1, aDVV1; + gp_Vec aDU2, aDV2, aDUU2, aDUV2, aDVV2; + + theS1->D2(aU1, aV1, aPt, aDU1, aDV1, aDUU1, aDVV1, aDUV1); + theS2->D2(aU2, aV2, aPt, aDU2, aDV2, aDUU2, aDVV2, aDUV2); + +#if 0 + //The code in this block contains TEST CASES for + //this algorithm only. It is stupedly to create OCCT-test for + //the method, which will be changed possibly never. + //However, if we do something in this method we can check its + //functionality easily. For that: + // 1. Initialyze aTestID variable by the correct value; + // 2. Compile this test code fragment. + + int aTestID = 0; + Standard_Real anExpectedSqRad = -1.0; + switch (aTestID) + { + case 1: + //Intersection between two spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 3 + //and O2(5.0, 0.0, 0.0), R2 = 5.0. + //Considered point has coordinates: (0.9, 0.0, 0.3*sqrt(91.0)). + + aDU1.SetCoord(0.00000000000000000, 0.90000000000000002, 0.00000000000000000); + aDV1.SetCoord(-2.8618176042508372, 0.00000000000000000, 0.90000000000000002); + aDUU1.SetCoord(-0.90000000000000002, 0.00000000000000000, 0.00000000000000000); + aDUV1.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000); + aDVV1.SetCoord(-0.90000000000000002, 0.00000000000000000, -2.8618176042508372); + aDU2.SetCoord(0.00000000000000000, -4.0999999999999996, 0.00000000000000000); + aDV2.SetCoord(-2.8618176042508372, 0.00000000000000000, -4.0999999999999996); + aDUU2.SetCoord(4.0999999999999996, 0.00000000000000000, 0.00000000000000000); + aDUV2.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000); + aDVV2.SetCoord(4.0999999999999996, 0.00000000000000000, -2.8618176042508372); + anExpectedSqRad = 819.0 / 100.0; + break; + case 2: + //Intersection between spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 10 + //and the plane 3*x+4*y+z=26. + //Considered point has coordinates: (-1.68, 5.76, 8.0). + + aDU1.SetCoord(-5.76, -1.68, 0.0); + aDV1.SetCoord(2.24, -7.68, 6.0); + aDUU1.SetCoord(1.68, -5.76, 0.0); + aDUV1.SetCoord(7.68, 2.24, 0.0); + aDVV1.SetCoord(1.68, -5.76, -8.0); + aDU2.SetCoord(1.0, 0.0, -3.0); + aDV2.SetCoord(0.0, 1.0, -4.0); + aDUU2.SetCoord(0.0, 0.0, 0.0); + aDUV2.SetCoord(0.0, 0.0, 0.0); + aDVV2.SetCoord(0.0, 0.0, 0.0); + anExpectedSqRad = 74.0; + break; + default: + aTestID = 0; + break; + } +#endif + + const gp_Vec aN1(aDU1.Crossed(aDV1)), aN2(aDU2.Crossed(aDV2)); + //Tangent vactor to the intersection curve + const gp_Vec aCTan(aN1.Crossed(aN2)); + const Standard_Real aSqMagnFDer = aCTan.SquareMagnitude(); + + if (aSqMagnFDer < aSqSmallValue) + return -1.0; + + Standard_Real aDuS1 = 0.0, aDvS1 = 0.0, aDuS2 = 0.0, aDvS2 = 1.0; + + { + //This algorithm is described in NonSingularProcessing() function + //in ApproxInt_ImpPrmSvSurfaces.gxx file + Standard_Real aSqNMagn = aN1.SquareMagnitude(); + gp_Vec aTgU(aCTan.Crossed(aDU1)), aTgV(aCTan.Crossed(aDV1)); + Standard_Real aDeltaU = aTgV.SquareMagnitude() / aSqNMagn; + Standard_Real aDeltaV = aTgU.SquareMagnitude() / aSqNMagn; + + aDuS1 = Sign(sqrt(aDeltaU), aTgV.Dot(aN1)); + aDvS1 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN1)); + + aSqNMagn = aN2.SquareMagnitude(); + aTgU.SetXYZ(aCTan.Crossed(aDU2).XYZ()); + aTgV.SetXYZ(aCTan.Crossed(aDV2).XYZ()); + aDeltaU = aTgV.SquareMagnitude() / aSqNMagn; + aDeltaV = aTgU.SquareMagnitude() / aSqNMagn; + + aDuS2 = Sign(sqrt(aDeltaU), aTgV.Dot(aN2)); + aDvS2 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN2)); + } + + //According to "Marching along surface/surface intersection curves + //with an adaptive step length" + //by Tz.E.Stoyagov + //(http://www.sciencedirect.com/science/article/pii/016783969290046R) + //we obtain the system: + // {A*a+B*b=F1 + // {B*a+C*b=F2 + //where a and b should be found. + //After that, 2nd derivative of the intersection curve can be computed as + // r''(t)=a*aN1+b*aN2. + + const Standard_Real aA = aN1.Dot(aN1), aB = aN1.Dot(aN2), aC = aN2.Dot(aN2); + const Standard_Real aDetSyst = aB*aB - aA*aC; + + if (Abs(aDetSyst) < aSmallValue) + {//Indetermined system solution + return -1.0; + } + + const Standard_Real aF1 = aDuS1*aDuS1*aDUU1.Dot(aN1) + + 2.0*aDuS1*aDvS1*aDUV1.Dot(aN1) + + aDvS1*aDvS1*aDVV1.Dot(aN1); + const Standard_Real aF2 = aDuS2*aDuS2*aDUU2.Dot(aN2) + + 2.0*aDuS2*aDvS2*aDUV2.Dot(aN2) + + aDvS2*aDvS2*aDVV2.Dot(aN2); + + //Principal normal to the intersection curve + const gp_Vec aCNorm((aF1*aC - aF2*aB) / aDetSyst*aN1 + (aA*aF2 - aF1*aB) / aDetSyst*aN2); + const Standard_Real aSqMagnSDer = aCNorm.CrossSquareMagnitude(aCTan); + + if (aSqMagnSDer < aSqSmallValue) + {//Intersection curve has null curvature in observed point + return Precision::Infinite(); + } + + //square of curvature radius + const Standard_Real aFactSqRad = aSqMagnFDer*aSqMagnFDer*aSqMagnFDer / aSqMagnSDer; + +#if 0 + if (aTestID) + { + if (Abs(aFactSqRad - anExpectedSqRad) < Precision::Confusion()) + { + printf("OK: Curvature radius is equal to expected (%5.10g)", anExpectedSqRad); + } + else + { + printf("Error: Curvature radius is not equal to expected: %5.10g != %5.10g", + aFactSqRad, anExpectedSqRad); + } + } +#endif + + return sqrt(aFactSqRad); +} diff --git a/src/IntPatch/IntPatch_WLineTool.cxx b/src/IntPatch/IntPatch_WLineTool.cxx index 25bf5aaf59..c95693f31f 100644 --- a/src/IntPatch/IntPatch_WLineTool.cxx +++ b/src/IntPatch/IntPatch_WLineTool.cxx @@ -15,8 +15,11 @@ #include #include +#include #include #include +#include +#include // It is pure empirical value. const Standard_Real IntPatch_WLineTool::myMaxConcatAngle = M_PI/6; @@ -475,64 +478,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" @@ -542,129 +487,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; } @@ -897,13 +803,86 @@ Standard_Boolean CheckArgumentsToExtend(const IntSurf_Quadric& theS1, Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0, aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0; - thePtWL1.Parameters(aU11, aV11, aU21, aV21); - thePtWL2.Parameters(aU12, aV12, aU22, aV22); + Bnd_Range aR1, aR2; - if(IsOnPeriod(aU11 - aU1f, aU12 - aU1f, theU1Period) || - IsOnPeriod(aV11 - aV1f, aV12 - aV1f, theV1Period) || - IsOnPeriod(aU21 - aU2f, aU22 - aU2f, theU2Period) || - IsOnPeriod(aV21 - aV2f, aV22 - aV2f, theV2Period)) + Standard_Boolean isOnBoundary = Standard_False; + for(Standard_Integer i = 0; i < 4; 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(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] + + 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] + + const Standard_Real aPar = aParWL2[i] - + theArrPeriods[i]*Ceiling((aParWL2[i]-aNewPar[i])/theArrPeriods[i]); + aParWL2[i] = aParWL1[i]; + aParWL1[i] = aPar; + } + + 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; + } + else + { + isOnBoundary = Standard_True; + } + } + } + + if(isOnBoundary) { return Standard_False; } @@ -916,13 +895,15 @@ Standard_Boolean CheckArgumentsToExtend(const IntSurf_Quadric& theS1, //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); } #if 0 @@ -1338,33 +1319,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 @@ -1372,183 +1358,168 @@ 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 02e4584a10..b2780cbfa7 100644 --- a/src/IntPatch/IntPatch_WLineTool.hxx +++ b/src/IntPatch/IntPatch_WLineTool.hxx @@ -19,6 +19,8 @@ #include #include #include +#include +#include class TopoDS_Face; class GeomAdaptor_HSurface; class GeomInt_LineConstructor; @@ -49,7 +51,7 @@ public: //! Returns new WLine or null WLine if the number //! of the points is less than 2. Standard_EXPORT static - Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, + Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine) &theWLine, const Handle(Adaptor3d_HSurface) &theS1, const Handle(Adaptor3d_HSurface) &theS2, const Handle(Adaptor3d_TopolTool) &theDom1, @@ -65,27 +67,20 @@ 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). //! As result, some gaps between two lines will vanish. //! The Walking lines are supposed (algorithm will do nothing for not-Walking line) -//! to be computed as a result of intersection of two quadrics. -//! The quadrics definition is accepted in input parameters. +//! 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 (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 ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin, const IntSurf_Quadric& theS1, const IntSurf_Quadric& theS2, @@ -97,7 +92,7 @@ public: const Bnd_Box2d& theBoxS1, const Bnd_Box2d& theBoxS2); -//! Max angle to concatenate two WLines to avoid result with C0-continuity + //! Max angle to concatenate two WLines to avoid result with C0-continuity static const Standard_Real myMaxConcatAngle; }; diff --git a/tests/bugs/modalg_5/bug24915 b/tests/bugs/modalg_5/bug24915 index f33a47d3ac..2589d9f918 100755 --- a/tests/bugs/modalg_5/bug24915 +++ b/tests/bugs/modalg_5/bug24915 @@ -1,4 +1,5 @@ -puts "TODO OCC25929 ALL: Error: Tolerance is too big!" +puts "TODO OCC26927 ALL: Error: Tolerance is too big!" + puts "=========" puts "CR24915" puts "=========" @@ -23,42 +24,24 @@ bbuild r checkshape r # 2. geometry -set MaxTol 5.0e-7 -set log [bopcurves b1 b2] +set MaxTol 1.0e-7 +set GoodNBCurv 3 -mksurface s1 b1 -mksurface s2 b2 +set log [bopcurves b1 b2 -2d] -regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv +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!" } -for {set i 1} {$i <= ${NbCurv}} {incr i} { - bounds c_$i U1 U2 - dlog reset - dlog on - xdistcs c_$i s1 U1 U2 100 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 2.0e-5 - set Limit_Tol 1.0e-7 - set D_good 0. - catch {checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}} - - dlog reset - dlog on - xdistcs c_$i s2 U1 U2 100 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 2.0e-5 - set Limit_Tol 1.0e-7 - set D_good 0. - catch {checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}} -} - smallview donly b2 c_2 fit -set only_screen_axo 1 +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/modalg_5/bug25292_11 b/tests/bugs/modalg_5/bug25292_11 index 1c667efb50..62df134785 100644 --- a/tests/bugs/modalg_5/bug25292_11 +++ b/tests/bugs/modalg_5/bug25292_11 @@ -29,7 +29,7 @@ set log [bopcurves f1 f2 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv #This value must be equal to the analogical value in bug25292_11 and bug25292_12 of "bugs modalg_5" testgrid. -set MaxTol 1.5e-7 +set MaxTol 2.0e-7 #This value must be equal to the analogical value in bug25292_11, bug25292_12, bug25292_15 and bug25292_16 of "bugs modalg_5" testgrid. set GoodNbCurv 4 @@ -44,57 +44,25 @@ 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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } v2d 2dfit -set only_screen_axo 1 +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/modalg_5/bug25292_12 b/tests/bugs/modalg_5/bug25292_12 index dfc8dad4ef..c7569fb5dd 100644 --- a/tests/bugs/modalg_5/bug25292_12 +++ b/tests/bugs/modalg_5/bug25292_12 @@ -29,7 +29,7 @@ set log [bopcurves f2 f1 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv #This value must be equal to the analogical value in bug25292_11 and bug25292_12 of "bugs modalg_5" testgrid. -set MaxTol 1.5e-7 +set MaxTol 2.0e-7 #This value must be equal to the analogical value in bug25292_11, bug25292_12, bug25292_15 and bug25292_16 of "bugs modalg_5" testgrid. set GoodNbCurv 4 @@ -44,55 +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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + 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 5d4d3d1faa..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,96 +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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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 62fb6b039b..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,92 +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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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 73af821249..aa844ff962 100644 --- a/tests/bugs/modalg_5/bug25292_21 +++ b/tests/bugs/modalg_5/bug25292_21 @@ -44,52 +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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + 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 6f9aa87781..40d876603a 100644 --- a/tests/bugs/modalg_5/bug25292_22 +++ b/tests/bugs/modalg_5/bug25292_22 @@ -44,52 +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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + 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 1ca2d190b3..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,93 +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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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 eb41d95fe1..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,92 +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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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 ed1b9dac5e..9b4b4e9b1e 100644 --- a/tests/bugs/modalg_5/bug25292_31 +++ b/tests/bugs/modalg_5/bug25292_31 @@ -24,7 +24,7 @@ set log [bopcurves f1 f2 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv #This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. -set MaxTol 1.0e-8 +set MaxTol 1.3e-7 #This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. set GoodNbCurv 1 @@ -38,54 +38,25 @@ 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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-8 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-8 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + xdistcs c_$i s1 U1 U2 10 ${Toler} + xdistcs c_$i s2 U1 U2 10 ${Toler} } smallview fit -set only_screen_axo 1 +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/modalg_5/bug25292_32 b/tests/bugs/modalg_5/bug25292_32 index 5dad932ed7..5edfdcdebb 100644 --- a/tests/bugs/modalg_5/bug25292_32 +++ b/tests/bugs/modalg_5/bug25292_32 @@ -24,7 +24,7 @@ set log [bopcurves f2 f1 -2d] regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv #This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. -set MaxTol 1.0e-8 +set MaxTol 1.3e-7 #This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. set GoodNbCurv 1 @@ -38,52 +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!" } - dlog reset - dlog on - xdistcs c_$i s1 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-8 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs c_$i s2 ${U1} ${U2} 10 - set Log2 [dlog get] - set List2 [split ${Log2} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-8 - set D_good 0. - checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol} + 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 e089f70b76..4dc56b478e 100644 --- a/tests/bugs/modalg_5/bug25292_33 +++ b/tests/bugs/modalg_5/bug25292_33 @@ -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,92 +30,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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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_34 b/tests/bugs/modalg_5/bug25292_34 index 536cb00872..628a446c4f 100644 --- a/tests/bugs/modalg_5/bug25292_34 +++ b/tests/bugs/modalg_5/bug25292_34 @@ -1,3 +1,4 @@ + puts "================" puts "OCC25292" puts "================" @@ -6,27 +7,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,92 +31,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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-6 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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_35 b/tests/bugs/modalg_5/bug25292_35 index bd5998f1ba..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,43 +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!" } - dlog reset - dlog on - xdistcs res_$ic s1 U1 U2 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 U1 U2 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} + 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 340567c185..dd3cac81cb 100644 --- a/tests/bugs/modalg_5/bug25292_36 +++ b/tests/bugs/modalg_5/bug25292_36 @@ -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 "##############################" @@ -58,92 +37,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!" - } - - dlog reset - dlog on - xdistcs res s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res s2 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} -} 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!" - } - - dlog reset - dlog on - xdistcs res_$ic s1 ${U1} ${U2} 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - dlog reset - dlog on - xdistcs res_$ic s2 0 1 10 - set Log1 [dlog get] - set List1 [split ${Log1} {TD= \t\n}] - set Tolerance 1.0e-7 - set Limit_Tol 1.0e-7 - set D_good 0. - checkList ${List1} ${Tolerance} ${D_good} ${Limit_Tol} - - 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_6/bug23178 b/tests/bugs/modalg_6/bug23178 index a16ee989dc..54cbfd0e2f 100644 --- a/tests/bugs/modalg_6/bug23178 +++ b/tests/bugs/modalg_6/bug23178 @@ -40,4 +40,4 @@ smallview don result* fit disp s1 s2 -checkview -screenshot -2d -path ${imagedir}/${test_image}.png +set only_screen_axo 1 diff --git a/tests/bugs/modalg_6/bug26310_1 b/tests/bugs/modalg_6/bug26310_1 index 394cfad094..3d5224783f 100644 --- a/tests/bugs/modalg_6/bug26310_1 +++ b/tests/bugs/modalg_6/bug26310_1 @@ -7,30 +7,55 @@ puts "" ################################################# if { [regexp {Debug mode} [dversion]] } { - set max_time 0.3 + set max_time 1.0 } else { - set max_time 0.15 + set max_time 0.5 } -set maxToler 1.5e-5 +set ExpTol1 1.3823335207427231e-006 +set ExpTol2 1.818012742776421e-006 + +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 reset dchrono cr start -set log1 [bopcurves b1_1 b2_1 -2d] +set log [bopcurves b1_1 b2_1 -2d] dchrono cr stop +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv -regexp {Tolerance Reached=+([-0-9.+eE]+)} ${log1} full Toler +checkreal ToleranceReached ${Toler} ${ExpTol1} 0.0 0.01 -puts "TolReached = $Toler" - -if { $Toler > $maxToler } { - puts "Error: Tolerance is too big ($Toler > $maxToler)" +if {${NbCurv} != ${GoodNbCurv}} { + puts "Error: Number of curves is bad!" +} + +set log2 [dchrono cr show] + +regexp {CPU user time: ([-0-9.+eE]+) seconds} $log2 full sec + +if { $sec > ${max_time} } { + puts "Error: CPU user time is more than ${max_time} seconds" +} else { + puts "OK: CPU user time is less than ${max_time} seconds" +} + +dchrono cr reset +dchrono cr start +set log [bopcurves b2_1 b1_1 -2d] +dchrono cr stop + +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!" } set log2 [dchrono cr show] diff --git a/tests/bugs/modalg_6/bug26310_3 b/tests/bugs/modalg_6/bug26310_3 index 3879f7ca43..97d6d5eb8b 100644 --- a/tests/bugs/modalg_6/bug26310_3 +++ b/tests/bugs/modalg_6/bug26310_3 @@ -1,3 +1,8 @@ +puts "TODO OCC25929 ALL: ERROR in bopargcheck res1" +puts "TODO OCC25929 ALL: ERROR. res1 with continuity C0" +puts "TODO OCC25929 ALL: ERROR in bopargcheck res2" +puts "TODO OCC25929 ALL: ERROR. res2 with continuity C0" + puts "========" puts "OCC26310" puts "========" @@ -9,10 +14,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 @@ -20,17 +36,29 @@ checkshape res2 set log1 [bopargcheck res1 #F] set log2 [bopargcheck res2 #F] -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 "Faulties for FIRST shape found : 2" $log1] >= 0 } { + puts "ERROR in bopargcheck res1" } -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 "Shapes with Continuity C0 : YES Cases(2) Total shapes(2)" $log1] >= 0 } { + puts "ERROR. res1 with continuity C0." } +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 +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 57c6dfa91f..81f4bb7daf 100644 --- a/tests/bugs/modalg_6/bug26310_4 +++ b/tests/bugs/modalg_6/bug26310_4 @@ -14,10 +14,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 @@ -41,10 +52,14 @@ if { [string first "Shapes with Continuity C0 : YES Cases(2) Total shape 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..a279b41923 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 ################################################# -set ExpTol 1.0e-7 -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 3.5704330589399866e-014 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 30e5754f8d..0bb3da943f 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 7.7015195151142059e-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 9.2281075162771769e-009 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_1 b/tests/bugs/modalg_6/bug28009_1 index a71eb2c0a8..eaeb6fd812 100644 --- a/tests/bugs/modalg_6/bug28009_1 +++ b/tests/bugs/modalg_6/bug28009_1 @@ -17,11 +17,9 @@ checkshape result # Check number of topological entities in the result. checknbshapes result -solid 1 -shell 1 -face 12 -wire 12 -edge 28 -vertex 17 -# Check result area. -checkprops result -s 4347.99 +set square 4347.99 smallview don result fit - -checkview -screenshot -2d -path ${imagedir}/${test_image}.png +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug28009_2 b/tests/bugs/modalg_6/bug28009_2 index f5b68179a0..dd1546b405 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 6.4823254544358038e-008 restore [locate_data_file bug28009_shape.brep] a @@ -28,4 +28,4 @@ don c_* fit display a_1_6 a_2_1 -checkview -screenshot -2d -path ${imagedir}/${test_image}.png +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/modalg_6/bug28222_1 b/tests/bugs/modalg_6/bug28222_1 new file mode 100644 index 0000000000..6ac80d7b96 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_1 @@ -0,0 +1,43 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +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 +set only_screen_axo 1 diff --git a/tests/bugs/modalg_6/bug28222_2 b/tests/bugs/modalg_6/bug28222_2 new file mode 100644 index 0000000000..3bcd391470 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_2 @@ -0,0 +1,43 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +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 +set only_screen_axo 1 diff --git a/tests/bugs/modalg_6/bug28222_3 b/tests/bugs/modalg_6/bug28222_3 new file mode 100644 index 0000000000..6e5cf4fc13 --- /dev/null +++ b/tests/bugs/modalg_6/bug28222_3 @@ -0,0 +1,44 @@ +puts "================" +puts "OCC28222" +puts "================" +puts "" +####################################################################### +# Intersection of two cylinders fails +####################################################################### + +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* +set only_screen_axo 1 diff --git a/tests/bugs/modalg_6/bug28706 b/tests/bugs/modalg_6/bug28706 new file mode 100644 index 0000000000..64b03ec3d2 --- /dev/null +++ b/tests/bugs/modalg_6/bug28706 @@ -0,0 +1,30 @@ +puts "================" +puts "OCC28706" +puts "================" +puts "" +####################################################################### +# Incomplete result of section operation between attached shapes +####################################################################### + +# 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" +} + +set length 6.16832 + +smallview +don result +fit + +set only_screen_axo 1 \ No newline at end of file diff --git a/tests/bugs/moddata_2/bug235 b/tests/bugs/moddata_2/bug235 index 02d4cd1f0c..b61b50f376 100755 --- a/tests/bugs/moddata_2/bug235 +++ b/tests/bugs/moddata_2/bug235 @@ -36,6 +36,8 @@ if { $nb_result != 2 } { } } -set 2dviewer 0 - +smallview +don result* +fit +set only_screen_axo 1