diff --git a/src/Geom/Geom_BSplineCurve.cdl b/src/Geom/Geom_BSplineCurve.cdl index 83711c391f..faf46d553c 100755 --- a/src/Geom/Geom_BSplineCurve.cdl +++ b/src/Geom/Geom_BSplineCurve.cdl @@ -992,6 +992,9 @@ is is static private; ---Purpose : updates the cache and validates it + IsEqual(me; theOther : BSplineCurve from Geom; + thePreci : Real from Standard ) returns Boolean; + ---Purpose : Comapare two Bspline curve on identity; diff --git a/src/Geom/Geom_BSplineCurve_1.cxx b/src/Geom/Geom_BSplineCurve_1.cxx index bdd16cc365..f7c6405005 100755 --- a/src/Geom/Geom_BSplineCurve_1.cxx +++ b/src/Geom/Geom_BSplineCurve_1.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #define POLES (poles->Array1()) #define KNOTS (knots->Array1()) @@ -827,3 +828,56 @@ void Geom_BSplineCurve::Resolution(const Standard_Real Tolerance3D, } UTolerance = Tolerance3D * maxderivinv; } + +//======================================================================= +//function : IsEqual +//purpose : +//======================================================================= + +Standard_Boolean Geom_BSplineCurve::IsEqual(const Handle(Geom_BSplineCurve)& theOther, + const Standard_Real thePreci) const +{ + if( knots.IsNull() || poles.IsNull() || mults.IsNull() ) + return Standard_False; + if( deg != theOther->Degree()) + return Standard_False; + if( knots->Length() != theOther->NbKnots() || + poles->Length() != theOther->NbPoles()) + return Standard_False; + + Standard_Integer i = 1; + for( i = 1 ; i <= poles->Length(); i++ ) + { + const gp_Pnt& aPole1 = poles->Value(i); + const gp_Pnt& aPole2 =theOther->Pole(i); + if( fabs( aPole1.X() - aPole2.X() ) > thePreci || + fabs( aPole1.Y() - aPole2.Y() ) > thePreci || + fabs( aPole1.Z() - aPole2.Z() ) > thePreci ) + return Standard_False; + } + + for( ; i <= knots->Length(); i++ ) + { + if( fabs(knots->Value(i) - theOther->Knot(i)) > Precision::Parametric(thePreci) ) + return Standard_False; + } + + for( i = 1 ; i <= mults->Length(); i++ ) + { + if( mults->Value(i) != theOther->Multiplicity(i) ) + return Standard_False; + } + + if( rational != theOther->IsRational()) + return Standard_False; + + if(!rational) + return Standard_True; + + for( i = 1 ; i <= weights->Length(); i++ ) + { + if( fabs( Standard_Real(weights->Value(i) - theOther->Weight(i))) > Epsilon(weights->Value(i)) ) + return Standard_False; + } + return Standard_True; +} diff --git a/src/Geom/Geom_BSplineSurface_1.cxx b/src/Geom/Geom_BSplineSurface_1.cxx index 9ffc3a17d8..864c997f00 100755 --- a/src/Geom/Geom_BSplineSurface_1.cxx +++ b/src/Geom/Geom_BSplineSurface_1.cxx @@ -1283,38 +1283,15 @@ Standard_Boolean Geom_BSplineSurface::IsUClosed () const if (uperiodic) return Standard_True; - Standard_Boolean Closed = Standard_True; - TColgp_Array2OfPnt & VPoles = poles->ChangeArray2(); - Standard_Integer PLower = VPoles.LowerRow(); - Standard_Integer PUpper = VPoles.UpperRow(); - Standard_Integer PLength = VPoles.RowLength(); - Standard_Integer j = VPoles.LowerCol(); - if ( urational || vrational) { - TColStd_Array2OfReal & VWeights = weights->ChangeArray2(); - Standard_Integer WLower = VWeights.LowerRow(); - Standard_Integer WUpper = VWeights.UpperRow(); - Standard_Real Alfa = VWeights(WLower,VWeights.LowerCol()); - Alfa /= VWeights(WUpper,VWeights.LowerCol()); - - Standard_Integer k = VWeights.LowerCol(); - while (Closed && j <= PLength) { - Closed = - (VPoles (PLower, j).Distance (VPoles (PUpper, j)) <= Precision::Confusion()); - j++; - Closed = (Closed && - ((VWeights(WLower,k) / VWeights(WUpper,k)) - Alfa) - < Epsilon(Alfa)); - k++; - } - } - else { - while (Closed && j <= PLength) { - Closed = - (VPoles (PLower, j).Distance (VPoles (PUpper, j)) <= Precision::Confusion()); - j++; - } - } - return Closed; + Standard_Real aU1, aU2, aV1, aV2; + Bounds( aU1, aU2, aV1, aV2 ); + Handle(Geom_Curve) aCUF = UIso( aU1 ); + Handle(Geom_Curve) aCUL = UIso( aU2 ); + if(aCUF.IsNull() || aCUL.IsNull()) + return Standard_False; + Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCUF); + Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCUL); + return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual( aBsL, Precision::Confusion()) ); } //======================================================================= @@ -1326,39 +1303,16 @@ Standard_Boolean Geom_BSplineSurface::IsVClosed () const { if (vperiodic) return Standard_True; - - Standard_Boolean Closed = Standard_True; - TColgp_Array2OfPnt & VPoles = poles->ChangeArray2(); - Standard_Integer PLower = VPoles.LowerCol(); - Standard_Integer PUpper = VPoles.UpperCol(); - Standard_Integer PLength = VPoles.ColLength(); - Standard_Integer i = VPoles.LowerRow(); - if ( urational || vrational) { - TColStd_Array2OfReal & VWeights = weights->ChangeArray2(); - Standard_Integer WLower = VWeights.LowerCol(); - Standard_Integer WUpper = VWeights.UpperCol(); - Standard_Real Alfa = VWeights(VWeights.LowerRow(),WLower); - Alfa /= VWeights(VWeights.LowerRow(),WUpper); - - Standard_Integer k = VWeights.LowerRow(); - while (Closed && i <= PLength) { - Closed = - (VPoles (i, PLower).Distance (VPoles (i, PUpper)) <= Precision::Confusion()); - i++; - Closed = (Closed && - ((VWeights(k,WLower) / VWeights(k,WUpper)) - Alfa) - < Epsilon(Alfa)); - k++; - } - } - else { - while (Closed && i <= PLength) { - Closed = - (VPoles (i, PLower).Distance (VPoles (i, PUpper)) <= Precision::Confusion()); - i++; - } - } - return Closed; + + Standard_Real aU1, aU2, aV1, aV2; + Bounds( aU1, aU2, aV1, aV2 ); + Handle(Geom_Curve) aCVF = VIso( aV1 ); + Handle(Geom_Curve) aCVL = VIso( aV2 ); + if(aCVF.IsNull() || aCVL.IsNull()) + return Standard_False; + Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCVF); + Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCVL); + return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual(aBsL, Precision::Confusion())); } //======================================================================= diff --git a/src/GeomliteTest/GeomliteTest_SurfaceCommands.cxx b/src/GeomliteTest/GeomliteTest_SurfaceCommands.cxx index 566ae9e3bd..ed4529530f 100755 --- a/src/GeomliteTest/GeomliteTest_SurfaceCommands.cxx +++ b/src/GeomliteTest/GeomliteTest_SurfaceCommands.cxx @@ -1842,5 +1842,6 @@ void GeomliteTest::SurfaceCommands(Draw_Interpretor& theCommands) __FILE__, surface_radius,g); theCommands.Add("compBsplSur","BsplSurf1 BSplSurf2",__FILE__,compBsplSur,g); - + + } diff --git a/tests/bugs/moddata/bug23475 b/tests/bugs/moddata/bug23475 new file mode 100755 index 0000000000..30150d5383 --- /dev/null +++ b/tests/bugs/moddata/bug23475 @@ -0,0 +1,16 @@ +puts "============" +puts "CR23475" +puts "===========" +puts "" +############################################################################### +# Wrong result of Geom_BSpline_Surface::IsVClosed() +############################################################################### + +restore [locate_data_file bug23475.brep] s1 +set info [dump s1] + +if { [regexp "BSplineSurface vclosed" $info] != 1} { + puts "Error : surface is not closed by V" +} + +