diff --git a/src/BRepOffset/BRepOffset.cxx b/src/BRepOffset/BRepOffset.cxx index 6270a8bfae..7fac35f35f 100644 --- a/src/BRepOffset/BRepOffset.cxx +++ b/src/BRepOffset/BRepOffset.cxx @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -31,15 +32,24 @@ #include #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include //======================================================================= //function : Surface //purpose : //======================================================================= Handle(Geom_Surface) BRepOffset::Surface(const Handle(Geom_Surface)& Surface, - const Standard_Real Offset, - BRepOffset_Status& theStatus) + const Standard_Real Offset, + BRepOffset_Status& theStatus, + Standard_Boolean allowC0) { Standard_Real Tol = Precision::Confusion(); @@ -152,17 +162,158 @@ Handle(Geom_Surface) BRepOffset::Surface(const Handle(Geom_Surface)& Surface, Handle(Geom_RectangularTrimmedSurface)::DownCast(Surface); Standard_Real U1,U2,V1,V2; S->Bounds(U1,U2,V1,V2); - Handle(Geom_Surface) Off = BRepOffset::Surface (S->BasisSurface(), Offset, theStatus); + Handle(Geom_Surface) Off = BRepOffset::Surface (S->BasisSurface(), Offset, theStatus, allowC0); Result = new Geom_RectangularTrimmedSurface (Off,U1,U2,V1,V2); } else if (TheType == STANDARD_TYPE(Geom_OffsetSurface)) { } if ( Result.IsNull()) { - Result = new Geom_OffsetSurface( Surface, Offset); + Result = new Geom_OffsetSurface( Surface, Offset, allowC0); } return Result; } +//======================================================================= +//function : CollapseSingularities +//purpose : +//======================================================================= +Handle(Geom_Surface) BRepOffset::CollapseSingularities (const Handle(Geom_Surface)& theSurface, + const TopoDS_Face& theFace, + Standard_Real thePrecision) +{ + // check surface type to see if it can be processed + Handle(Standard_Type) aType = theSurface->DynamicType(); + if (aType != STANDARD_TYPE(Geom_BSplineSurface)) + { + // for the moment, only bspline surfaces are treated; + // in the future, bezier surfaces and surfaces of revolution can be also handled + return theSurface; + } + // find singularities (vertices of degenerated edges) + NCollection_List aDegenPnt; + NCollection_List aDegenTol; + for (TopExp_Explorer anExp (theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge (anExp.Current()); + if (! BRep_Tool::Degenerated (anEdge)) + { + continue; + } + TopoDS_Vertex aV1, aV2; + TopExp::Vertices (anEdge, aV1, aV2); + if (! aV1.IsSame (aV2)) + { + continue; + } + + aDegenPnt.Append (BRep_Tool::Pnt (aV1)); + aDegenTol.Append (BRep_Tool::Tolerance (aV1)); + } + + // iterate by sides of the surface + if (aType == STANDARD_TYPE(Geom_BSplineSurface)) + { + Handle(Geom_BSplineSurface) aBSpline = Handle(Geom_BSplineSurface)::DownCast (theSurface); + const TColgp_Array2OfPnt& aPoles = aBSpline->Poles(); + + Handle(Geom_BSplineSurface) aCopy; + + // iterate by sides: {U=0; V=0; U=1; V=1} + Standard_Integer RowStart[4] = {aPoles.LowerRow(), aPoles.LowerRow(), aPoles.UpperRow(), aPoles.LowerRow()}; + Standard_Integer ColStart[4] = {aPoles.LowerCol(), aPoles.LowerCol(), aPoles.LowerCol(), aPoles.UpperCol()}; + Standard_Integer RowStep[4] = {0, 1, 0, 1}; + Standard_Integer ColStep[4] = {1, 0, 1, 0}; + Standard_Integer NbSteps[4] = {aPoles.RowLength(), aPoles.ColLength(), aPoles.RowLength(), aPoles.ColLength()}; + for (Standard_Integer iSide = 0; iSide < 4; iSide++) + { + // compute center of gravity of side poles + gp_XYZ aSum; + for (int iPole = 0; iPole < NbSteps[iSide]; iPole++) + { + aSum += aPoles (RowStart[iSide] + iPole * RowStep[iSide], ColStart[iSide] + iPole * ColStep[iSide]).XYZ(); + } + gp_Pnt aCenter (aSum / NbSteps[iSide]); + + // determine if all poles of the side fit into: + Standard_Boolean isCollapsed = Standard_True; // aCenter precisely (with gp::Resolution()) + Standard_Boolean isSingular = Standard_True; // aCenter with thePrecision + NCollection_LocalArray isDegenerated (aDegenPnt.Extent()); // degenerated vertex + for (size_t iDegen = 0; iDegen < isDegenerated.Size(); ++iDegen) isDegenerated[iDegen] = Standard_True; + for (int iPole = 0; iPole < NbSteps[iSide]; iPole++) + { + const gp_Pnt& aPole = aPoles (RowStart[iSide] + iPole * RowStep[iSide], ColStart[iSide] + iPole * ColStep[iSide]); + + // distance from CG + Standard_Real aDistCG = aCenter.Distance (aPole); + if (aDistCG > gp::Resolution()) + isCollapsed = Standard_False; + if (aDistCG > thePrecision) + isSingular = Standard_False; + + // distances from degenerated points + NCollection_List::Iterator aDegPntIt (aDegenPnt); + NCollection_List::Iterator aDegTolIt(aDegenTol); + for (size_t iDegen = 0; iDegen < isDegenerated.Size(); aDegPntIt.Next(), aDegTolIt.Next(), ++iDegen) + { + if (isDegenerated[iDegen] && aDegPntIt.Value().Distance (aPole) >= aDegTolIt.Value()) + { + isDegenerated[iDegen] = Standard_False; + } + } + } + if (isCollapsed) + { + continue; // already Ok, nothing to be done + } + + // decide to collapse the side: either if it is singular with thePrecision, + // or if it fits into one (and only one) degenerated point + if (! isSingular) + { + Standard_Integer aNbFit = 0; + NCollection_List::Iterator aDegPntIt (aDegenPnt); + NCollection_List::Iterator aDegTolIt(aDegenTol); + for (size_t iDegen = 0; iDegen < isDegenerated.Size(); ++iDegen) + { + if (isDegenerated[iDegen]) + { + // remove degenerated point as soon as it fits at least one side, to prevent total collapse + aDegenPnt.Remove (aDegPntIt); + aDegenTol.Remove (aDegTolIt); + aNbFit++; + } + else + { + aDegPntIt.Next(); + aDegTolIt.Next(); + } + } + + // if side fits more than one degenerated vertex, do not collapse it + // to be on the safe side + isSingular = (aNbFit == 1); + } + + // do collapse + if (isSingular) + { + if (aCopy.IsNull()) + { + aCopy = Handle(Geom_BSplineSurface)::DownCast (theSurface->Copy()); + } + for (int iPole = 0; iPole < NbSteps[iSide]; iPole++) + { + aCopy->SetPole (RowStart[iSide] + iPole * RowStep[iSide], ColStart[iSide] + iPole * ColStep[iSide], aCenter); + } + } + } + + if (! aCopy.IsNull()) + return aCopy; + } + + return theSurface; +} diff --git a/src/BRepOffset/BRepOffset.hxx b/src/BRepOffset/BRepOffset.hxx index e037d03fa3..09fde55d0b 100644 --- a/src/BRepOffset/BRepOffset.hxx +++ b/src/BRepOffset/BRepOffset.hxx @@ -21,27 +21,17 @@ #include #include -#include #include + class Geom_Surface; -class BRepOffset_MakeOffset; -class BRepOffset_Inter3d; -class BRepOffset_Inter2d; -class BRepOffset_Offset; -class BRepOffset_Analyse; -class BRepOffset_MakeLoops; -class BRepOffset_Tool; -class BRepOffset_Interval; - +class TopoDS_Face; +//! Auxiliary tools for offset algorithms class BRepOffset { public: - DEFINE_STANDARD_ALLOC - - //! returns the Offset surface computed from the //! surface at an OffsetDistance . //! @@ -50,37 +40,29 @@ public: //! //! If no particular case is detected, the returned //! surface will have the Type Geom_OffsetSurface. - Standard_EXPORT static Handle(Geom_Surface) Surface (const Handle(Geom_Surface)& Surface, const Standard_Real Offset, BRepOffset_Status& theStatus); + //! Parameter allowC0 is then passed as last argument to + //! constructor of Geom_OffsetSurface. + Standard_EXPORT static Handle(Geom_Surface) Surface (const Handle(Geom_Surface)& Surface, + const Standard_Real Offset, + BRepOffset_Status& theStatus, + Standard_Boolean allowC0 = Standard_False); - - - -protected: - - - - - -private: - - - - -friend class BRepOffset_MakeOffset; -friend class BRepOffset_Inter3d; -friend class BRepOffset_Inter2d; -friend class BRepOffset_Offset; -friend class BRepOffset_Analyse; -friend class BRepOffset_MakeLoops; -friend class BRepOffset_Tool; -friend class BRepOffset_Interval; + //! Preprocess surface to be offset (bspline, bezier, or revolution based on + //! bspline or bezier curve), by collapsing each singular side to single point. + //! + //! This is to avoid possible flipping of normal at the singularity + //! of the surface due to non-zero distance between the poles that + //! logically should be in one point (singularity). + //! + //! The (parametric) side of the surface is considered to be singularity if face + //! has degenerated edge whose vertex encompasses (by its tolerance) all points on that side, + //! or if all poles defining that side fit into sphere with radius thePrecision. + //! + //! Returns either original surface or its modified copy (if some poles have been moved). + Standard_EXPORT static Handle(Geom_Surface) CollapseSingularities (const Handle(Geom_Surface)& theSurface, + const TopoDS_Face& theFace, + Standard_Real thePrecision); }; - - - - - - #endif // _BRepOffset_HeaderFile diff --git a/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx b/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx index 3b89a5a92d..e48a05c91c 100644 --- a/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeSimpleOffset.cxx @@ -50,7 +50,9 @@ //purpose : Constructor //============================================================================= BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset() -: myIsBuildSolid(Standard_False), +: myOffsetValue(0.), + myTolerance(Precision::Confusion()), + myIsBuildSolid(Standard_False), myMaxAngle(0.0), myError(BRepOffsetSimple_OK), myIsDone(Standard_False) @@ -66,6 +68,7 @@ BRepOffset_MakeSimpleOffset::BRepOffset_MakeSimpleOffset(const TopoDS_Shape& the const Standard_Real theOffsetValue) : myInputShape(theInputShape), myOffsetValue(theOffsetValue), + myTolerance(Precision::Confusion()), myIsBuildSolid(Standard_False), myMaxAngle(0.0), myError(BRepOffsetSimple_OK), @@ -177,7 +180,7 @@ void BRepOffset_MakeSimpleOffset::Perform() ComputeMaxAngle(); myBuilder.Init(myInputShape); - Handle(BRepOffset_SimpleOffset) aMapper = new BRepOffset_SimpleOffset(myInputShape, myOffsetValue); + Handle(BRepOffset_SimpleOffset) aMapper = new BRepOffset_SimpleOffset(myInputShape, myOffsetValue, myTolerance); myBuilder.Perform(aMapper); if (!myBuilder.IsDone()) diff --git a/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx b/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx index 83d3fc2b8a..ab89b7e511 100644 --- a/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx +++ b/src/BRepOffset/BRepOffset_MakeSimpleOffset.hxx @@ -95,6 +95,12 @@ public: //! Sets offset value. void SetOffsetValue(const Standard_Real theOffsetValue) { myOffsetValue = theOffsetValue; } + //! Gets tolerance (used for handling singularities). + Standard_Real GetTolerance() const { return myTolerance; } + + //! Sets tolerance (used for handling singularities). + void SetTolerance (const Standard_Real theValue) { myTolerance = theValue; } + //! Gets done state. Standard_Boolean IsDone() const { return myIsDone; } @@ -134,6 +140,9 @@ private: //! Offset value. Standard_Real myOffsetValue; + //! Tolerance (for singularities) + Standard_Real myTolerance; + //! Solid building flag. True means solid construction. Standard_Boolean myIsBuildSolid; diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.cxx b/src/BRepOffset/BRepOffset_SimpleOffset.cxx index 6b63c84a87..ff585e5153 100644 --- a/src/BRepOffset/BRepOffset_SimpleOffset.cxx +++ b/src/BRepOffset/BRepOffset_SimpleOffset.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,10 @@ static const Standard_Integer NCONTROL=22; //purpose : Constructor //============================================================================= BRepOffset_SimpleOffset::BRepOffset_SimpleOffset(const TopoDS_Shape& theInputShape, - const Standard_Real theOffsetValue) -: myOffsetValue(theOffsetValue) + const Standard_Real theOffsetValue, + const Standard_Real theTolerance) +: myOffsetValue(theOffsetValue), + myTolerance(theTolerance) { FillOffsetData(theInputShape); } @@ -223,6 +226,7 @@ void BRepOffset_SimpleOffset::FillFaceData(const TopoDS_Face& theFace) // Any existing transformation is applied to the surface. // New face will have null transformation. Handle(Geom_Surface) aS = BRep_Tool::Surface(theFace); + aS = BRepOffset::CollapseSingularities (aS, theFace, myTolerance); // Take into account face orientation. Standard_Real aMult = 1.0; diff --git a/src/BRepOffset/BRepOffset_SimpleOffset.hxx b/src/BRepOffset/BRepOffset_SimpleOffset.hxx index 423f1fd8a6..ea45b2ae1d 100644 --- a/src/BRepOffset/BRepOffset_SimpleOffset.hxx +++ b/src/BRepOffset/BRepOffset_SimpleOffset.hxx @@ -46,8 +46,12 @@ public: DEFINE_STANDARD_RTTI_INLINE(BRepOffset_SimpleOffset, BRepTools_Modification) //! Constructor. + //! @param theInputShape shape to be offset + //! @param theOffsetValue offset distance (signed) + //! @param theTolerance tolerance for handling singular points Standard_EXPORT BRepOffset_SimpleOffset(const TopoDS_Shape& theInputShape, - const Standard_Real theOffsetValue); + const Standard_Real theOffsetValue, + const Standard_Real theTolerance); //! Returns Standard_True if the face has been //! modified. In this case, is the new geometric @@ -178,6 +182,9 @@ private: //! Offset value. Standard_Real myOffsetValue; + + //! Tolerance. + Standard_Real myTolerance; }; #endif // _BRepOffset_SimpleOffset_HeaderFile diff --git a/src/BRepTest/BRepTest_FeatureCommands.cxx b/src/BRepTest/BRepTest_FeatureCommands.cxx index 7f5f4d1755..4dfa14a06a 100644 --- a/src/BRepTest/BRepTest_FeatureCommands.cxx +++ b/src/BRepTest/BRepTest_FeatureCommands.cxx @@ -2247,9 +2247,9 @@ static Standard_Integer ComputeSimpleOffset(Draw_Interpretor& theCommands, Standard_Integer narg, const char** a) { - if (narg != 4 && narg != 5) + if (narg < 4) { - theCommands << "offsetshapesimple result shape offsetvalue [solid]\n"; + theCommands << "offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]\n"; return 1; } @@ -2267,12 +2267,13 @@ static Standard_Integer ComputeSimpleOffset(Draw_Interpretor& theCommands, return 0; } - BRepOffset_MakeSimpleOffset aMaker(aShape, anOffsetValue); - if (narg == 5 && !strcasecmp(a[4],"solid") ) - { - aMaker.SetBuildSolidFlag(Standard_True); - } + Standard_Boolean makeSolid = (narg > 4 && !strcasecmp(a[4],"solid")); + int iTolArg = (makeSolid ? 5 : 4); + Standard_Real aTol = (narg > iTolArg ? Draw::Atof(a[iTolArg]) : Precision::Confusion()); + BRepOffset_MakeSimpleOffset aMaker(aShape, anOffsetValue); + aMaker.SetTolerance (aTol); + aMaker.SetBuildSolidFlag(makeSolid); aMaker.Perform(); if (!aMaker.IsDone()) @@ -2432,6 +2433,6 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands) __FILE__,BOSS); theCommands.Add("offsetshapesimple", - "offsetshapesimple result shape offsetvalue [solid]", + "offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]", __FILE__, ComputeSimpleOffset); } diff --git a/src/BRepTest/BRepTest_OtherCommands.cxx b/src/BRepTest/BRepTest_OtherCommands.cxx index 8ba26a7e72..eccd3eb3e6 100644 --- a/src/BRepTest/BRepTest_OtherCommands.cxx +++ b/src/BRepTest/BRepTest_OtherCommands.cxx @@ -72,7 +72,6 @@ #include #include -#include #include #include #include diff --git a/src/DrawResources/CheckCommands.tcl b/src/DrawResources/CheckCommands.tcl index c6a06c8cf3..b9acbb100d 100644 --- a/src/DrawResources/CheckCommands.tcl +++ b/src/DrawResources/CheckCommands.tcl @@ -359,15 +359,18 @@ proc checkfreebounds {shape ref_value args} { } help checkmaxtol { - Compare max tolerance of shape with reference value. - Command returns max tolerance of the shape. + Returns max tolerance of the shape and prints error message if specified + criteria are not satisfied. Use: checkmaxtol shape [options...] - Allowed options are: - -ref: reference value of maximum tolerance. - -source: list of shapes to compare with, e.g.: -source {shape1 shape2 shape3} - -min_tol: minimum tolerance for comparison. - -multi_tol: tolerance multiplier. + + Options specify criteria for checking the maximal tolerance value: + -ref : check it to be equal to reference value. + -min_tol : check it to be not greater than specified value. + -source : check it to be not greater than + maximal tolerance of specified shape(s) + -multi_tol : additional multiplier for value specified by -min_tol + or -shapes options. } proc checkmaxtol {shape args} { @@ -764,9 +767,10 @@ help checkview { -display shapename: display shape with name 'shapename' -3d: display shape in 3d viewer -2d [ v2d / smallview ]: display shape in 2d viewer (default viewer is a 'smallview') - -path PATH: location of saved screenshot of viewer -vdispmode N: it is possible to set vdispmode for 3d viewer (default value is 1) -screenshot: procedure will try to make screenshot of already created viewer + -path : location of saved screenshot of viewer + Procedure can check some property of shape (length, area or volume) and compare it with some value N: -l [N] -s [N] diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index c290f62284..b61329afbf 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -420,7 +420,6 @@ void GetTypeAndSignfromString (const char* name,AIS_KindOfInteractive& TheType,S #include #include #include -#include //============================================================================== // VIEWER OBJECT MANAGEMENT GLOBAL VARIABLES diff --git a/tests/bugs/modalg_7/bug28968 b/tests/bugs/modalg_7/bug28968 new file mode 100644 index 0000000000..fd124994b3 --- /dev/null +++ b/tests/bugs/modalg_7/bug28968 @@ -0,0 +1,46 @@ +puts "# ====================================================================" +puts "# 0028968: Incorrect offset for the faces with singularities " +puts "# ====================================================================" +puts "" +puts "# This test checks that offset does not fail and produces valid shape with" +puts "# reasonable tolerance; however the real check for the problem is to be" +puts "# made visually using generated images that should have no loops" +puts "# (see images attached to Mantis issue)" +puts "" + +set models { +bug28968_HA-3828b-31.brep +bug28968_HA-3781-31.brep +bug28968_HA-3781-25.brep +bug28968_HA-3781-01.brep +bug28968_HA-3623g-31.brep +bug28968_HA-3623g-22.brep +bug28968_HA-3623c-20.brep +bug28968_HA-3623c-19.brep +bug28968_HA-3623c-15.brep +bug28968_HA-3623b-31.brep +bug28968_HA-3623b-22.brep +bug28968_HA-3623a-28.brep +bug28968_HA-3623a-27.brep +bug28968_HA-3623a-26.brep +bug28968_HA-3623a-17.brep +} + +set i 0 +foreach file $models { + incr i + restore [locate_data_file $file] s$i + + foreach command {offsetshapesimple} { + catch {$command res$i s$i 20. 0.01} + checkmaxtol res$i -min_tol 0.002 + checkshape res$i + + smallview + donly s$i res$i + fit + + xwd "${imagedir}/${casename}_${command}_${i}_[file rootname $file].png" +# checkview -2d smallview -display face$i -display res$i -screenshot -path $savepath + } +} diff --git a/tests/offset/simple/A04 b/tests/offset/simple/A04 index 4e0f1aa1d9..98c8d1bd66 100644 --- a/tests/offset/simple/A04 +++ b/tests/offset/simple/A04 @@ -5,4 +5,4 @@ set OffsetValue 20.0 # Reference data. set ExpectedMass 2.96921e+006 -set ExpectedMaxTol 1.02 \ No newline at end of file +set ExpectedMaxTol 0.683 diff --git a/tests/offset/simple/A11 b/tests/offset/simple/A11 index d93bb44a00..0cb386d65c 100644 --- a/tests/offset/simple/A11 +++ b/tests/offset/simple/A11 @@ -5,4 +5,4 @@ set OffsetValue 80.0 # Reference data. set ExpectedMass 2.94956e+006 -set ExpectedMaxTol 4.06 \ No newline at end of file +set ExpectedMaxTol 2.76 \ No newline at end of file diff --git a/tests/offset/simple/F01 b/tests/offset/simple/F01 new file mode 100644 index 0000000000..a32cadb22e --- /dev/null +++ b/tests/offset/simple/F01 @@ -0,0 +1,11 @@ +# Test data: +puts "USER GUID: HA-3623a" + +restore [locate_data_file bug28968_HA-3623a-plate.brep] s + +set OffsetValue 20.0 +set SingularTol 0.01 + +# Reference data. +set ExpectedMass 3.15463e+007 +set ExpectedMaxTol 11.945619 diff --git a/tests/offset/simple/F02 b/tests/offset/simple/F02 new file mode 100644 index 0000000000..73fa2298c5 --- /dev/null +++ b/tests/offset/simple/F02 @@ -0,0 +1,10 @@ +# Test data: +puts "USER GUID: HA-3623b" + +restore [locate_data_file bug28968_HA-3623b-hull.brep] s + +set OffsetValue 20.0 + +# Reference data. +set ExpectedMass 5.21983e+007 +set ExpectedMaxTol 0.29 diff --git a/tests/offset/simple/F03 b/tests/offset/simple/F03 new file mode 100644 index 0000000000..2ee6339785 --- /dev/null +++ b/tests/offset/simple/F03 @@ -0,0 +1,11 @@ +# Test data: +puts "USER GUID: HA-3623c" + +restore [locate_data_file bug28968_HA-3623c-hull.brep] s + +set OffsetValue 20.0 +set SingularTol 0.01 + +# Reference data. +set ExpectedMass 2.35078e+007 +set ExpectedMaxTol 0.139 diff --git a/tests/offset/simple/F04 b/tests/offset/simple/F04 new file mode 100644 index 0000000000..6655195b00 --- /dev/null +++ b/tests/offset/simple/F04 @@ -0,0 +1,11 @@ +# Test data: +puts "USER GUID: HA-3781" + +restore [locate_data_file bug28968_HA-3781-plate.brep] s + +set OffsetValue 20.0 +set SingularTol 0.01 + +# Reference data. +set ExpectedMass 2.7118e+007 +set ExpectedMaxTol 0.539 diff --git a/tests/offset/simple/F05 b/tests/offset/simple/F05 new file mode 100644 index 0000000000..a556aad22e --- /dev/null +++ b/tests/offset/simple/F05 @@ -0,0 +1,11 @@ +# Test data: +puts "USER GUID: HA-3781" + +restore [locate_data_file bug26528_shell.brep] s + +set OffsetValue -20.0 +#set SingularTol 0.01 + +# Reference data. +set ExpectedMass 6.29528e+006 +set ExpectedMaxTol 10.03 diff --git a/tests/offset/simple/begin b/tests/offset/simple/begin index fd3b5f71f4..5f8f7b3db8 100644 --- a/tests/offset/simple/begin +++ b/tests/offset/simple/begin @@ -5,4 +5,7 @@ cpulimit 100 # "B" letter 26577 # "C" letter 26578 # "D" letter 26587, 27907, 27908, 27909, 27910, 27911, 27912, 27913 -# "E" letter SPE 2016_Oct pack \ No newline at end of file +# "E" letter SPE 2016_Oct pack + +# default tolerance for detecting singularities +set SingularTol 1.e-7 diff --git a/tests/offset/simple/end b/tests/offset/simple/end index 4bd90b996e..ae6829d492 100644 --- a/tests/offset/simple/end +++ b/tests/offset/simple/end @@ -1,5 +1,5 @@ # Compute offset. -offsetshapesimple result s $OffsetValue +offsetshapesimple result s $OffsetValue $SingularTol # 1% relative tolerance set TolRel 1.0e-2