From b60e8432dd68f987271c225460fb65ed056216b3 Mon Sep 17 00:00:00 2001 From: isn Date: Tue, 14 Feb 2017 18:42:54 +0300 Subject: [PATCH] 0028456: BRepBuilderAPI_MakeFace modifies the input shape 1) BRepLib::UpdateTolerances(..) & BRepLib::SameParameter(..) functions now support non-mutable input feature. reshaper is used to store modified copies of subshapes of original (input) shape(s) as substitutions. 2) IsNewShape(..) method has been added to BRepTools_ReShape to check if the given shape has been recorded as a value --- dox/dev_guides/tests/tests.md | 2 + .../shape_healing/shape_healing.md | 2 + src/BRepLib/BRepLib.cxx | 461 ++++++++++++++---- src/BRepLib/BRepLib.hxx | 44 +- src/BRepTest/BRepTest_BasicCommands.cxx | 80 ++- src/BRepTools/BRepTools_ReShape.cxx | 7 + src/BRepTools/BRepTools_ReShape.hxx | 6 + tests/bugs/modalg_1/buc60896 | 4 +- tests/heal/grids.list | 2 + tests/heal/same_parameter_locked/A1 | 1 + tests/heal/same_parameter_locked/A2 | 1 + tests/heal/same_parameter_locked/A3 | 1 + tests/heal/same_parameter_locked/A4 | 1 + tests/heal/same_parameter_locked/A5 | 1 + tests/heal/same_parameter_locked/A6 | 1 + tests/heal/same_parameter_locked/A7 | 1 + tests/heal/same_parameter_locked/end | 3 + tests/heal/update_tolerance_locked/A1 | 1 + tests/heal/update_tolerance_locked/A2 | 1 + tests/heal/update_tolerance_locked/A3 | 1 + tests/heal/update_tolerance_locked/A4 | 1 + tests/heal/update_tolerance_locked/end | 3 + 22 files changed, 498 insertions(+), 127 deletions(-) create mode 100644 tests/heal/same_parameter_locked/A1 create mode 100644 tests/heal/same_parameter_locked/A2 create mode 100644 tests/heal/same_parameter_locked/A3 create mode 100644 tests/heal/same_parameter_locked/A4 create mode 100644 tests/heal/same_parameter_locked/A5 create mode 100644 tests/heal/same_parameter_locked/A6 create mode 100644 tests/heal/same_parameter_locked/A7 create mode 100644 tests/heal/same_parameter_locked/end create mode 100644 tests/heal/update_tolerance_locked/A1 create mode 100644 tests/heal/update_tolerance_locked/A2 create mode 100644 tests/heal/update_tolerance_locked/A3 create mode 100644 tests/heal/update_tolerance_locked/A4 create mode 100644 tests/heal/update_tolerance_locked/end diff --git a/dox/dev_guides/tests/tests.md b/dox/dev_guides/tests/tests.md index dc9ef55b75..2e371b3e3c 100644 --- a/dox/dev_guides/tests/tests.md +++ b/dox/dev_guides/tests/tests.md @@ -895,6 +895,7 @@ DRAW module: XSDRAW | fix_shape | fixshape | Shape healing | | fix_gaps | fixwgaps | Fixing gaps between edges on a wire | | same_parameter | sameparameter | Fixing non-sameparameter edges | +| same_parameter_locked | sameparameter | Fixing non-sameparameter edges | | fix_face_size | DT_ApplySeq | Removal of small faces | | elementary_to_revolution | DT_ApplySeq | Conversion of elementary surfaces to revolution | | direct_faces | directfaces | Correction of axis of elementary surfaces | @@ -910,6 +911,7 @@ DRAW module: XSDRAW | split_continuity_standard | DT_ShapeDivide | Split surfaces by continuity criterion | | surface_to_revolution_advanced | DT_ShapeConvertRev | Convert elementary surfaces to revolutions, complex cases | | surface_to_revolution_standard | DT_ShapeConvertRev | Convert elementary surfaces to revolutions, simple cases | +| update_tolerance_locked | updatetolerance | Update the tolerance of shape so that it satisfy the rule: toler(face)<=toler(edge)<=toler(vertex) | @subsubsection testmanual_5_1_11 mesh diff --git a/dox/user_guides/shape_healing/shape_healing.md b/dox/user_guides/shape_healing/shape_healing.md index 3501349ece..848c8c2369 100644 --- a/dox/user_guides/shape_healing/shape_healing.md +++ b/dox/user_guides/shape_healing/shape_healing.md @@ -1494,6 +1494,8 @@ For a sub-shape it is recommended to use method *Apply* before methods *Replace* 3. Use method *Apply* for the initial shape again to get the resulting shape after all modifications have been made. 4. Use method *Apply* to obtain the history of sub-shape modification. +Additional method *IsNewShape* can be used to check if the shape has been recorded by *BRepTools_ReShape* tool as a value. + **Note** that in fact class *ShapeBuild_ReShape* is an alias for class *BRepTools_ReShape*. They differ only in queries of statuses in the *ShapeBuild_ReShape* class. Let us use the tool to get the result shape after modification of sub-shapes of the initial shape: diff --git a/src/BRepLib/BRepLib.cxx b/src/BRepLib/BRepLib.cxx index a2f2d951cb..7ac087cc3d 100644 --- a/src/BRepLib/BRepLib.cxx +++ b/src/BRepLib/BRepLib.cxx @@ -90,6 +90,9 @@ #include #include #include +#include +#include +#include #include @@ -97,6 +100,9 @@ static Standard_Real thePrecision = Precision::Confusion(); static Handle(Geom_Plane) thePlane; +static void InternalUpdateTolerances(const TopoDS_Shape& theOldShape, + const Standard_Boolean IsVerifyTolerance, const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper); + //======================================================================= // function: BRepLib_ComparePoints // purpose: implementation of IsLess() function for two points @@ -725,7 +731,6 @@ Standard_Boolean BRepLib::UpdateEdgeTol(const TopoDS_Edge& AnEdge, //function : UpdateEdgeTolerance //purpose : //======================================================================= - Standard_Boolean BRepLib::UpdateEdgeTolerance(const TopoDS_Shape& S, const Standard_Real MinToleranceRequested, const Standard_Real MaxToleranceToCheck) @@ -752,19 +757,18 @@ Standard_Boolean BRepLib::UpdateEdgeTolerance(const TopoDS_Shape& S, } //======================================================================= -//function : SetEdgeTol +//function : GetEdgeTol //purpose : //======================================================================= - -static void SetEdgeTol(const TopoDS_Edge& E, - const TopoDS_Face& F) +static void GetEdgeTol(const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace, Standard_Real& theEdTol) { TopLoc_Location L; - const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,L); - TopLoc_Location l = L.Predivided(E.Location()); + const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace,L); + TopLoc_Location l = L.Predivided(theEdge.Location()); - const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); - BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->ChangeCurves()); + const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&theEdge.TShape()); + BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); while (itcr.More()) { const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); @@ -786,7 +790,7 @@ static void SetEdgeTol(const TopoDS_Edge& E, TopLoc_Location LC; Standard_Real First, Last; GeomAdaptor_Curve& GAC = HC->ChangeCurve(); - GAC.Load(BRep_Tool::Curve(E,LC,First,Last)); + GAC.Load(BRep_Tool::Curve(theEdge,LC,First,Last)); LC = L.Predivided(LC); if (!LC.IsIdentity()) { @@ -819,35 +823,161 @@ static void SetEdgeTol(const TopoDS_Edge& E, if(temp > d2) d2 = temp; } d2 = 1.5*sqrt(d2); - TE->UpdateTolerance(d2); + theEdTol = d2; } //======================================================================= -//function : SameParameter +//function : UpdTolMap +//purpose : Update map ShToTol (shape to tolerance) +//======================================================================= +static void UpdTolMap(const TopoDS_Shape& theSh, Standard_Real theNewTol, + TopTools_DataMapOfShapeReal& theShToTol) +{ + TopAbs_ShapeEnum aSt = theSh.ShapeType(); + Standard_Real aShTol; + if (aSt == TopAbs_VERTEX) + aShTol = BRep_Tool::Tolerance(TopoDS::Vertex(theSh)); + else if (aSt == TopAbs_EDGE) + aShTol = BRep_Tool::Tolerance(TopoDS::Edge(theSh)); + else + return; + // + if (theNewTol > aShTol) + { + const Standard_Real* anOldtol = theShToTol.Seek(theSh); + if (!anOldtol) + theShToTol.Bind(theSh, theNewTol); + else + theShToTol(theSh) = Max(*anOldtol, theNewTol); + } +} + +//======================================================================= +//function : UpdShTol +//purpose : Update vertices/edges/faces according to ShToTol map (create copies of necessary) +//======================================================================= +static void UpdShTol(const TopTools_DataMapOfShapeReal& theShToTol, + const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper, + Standard_Boolean theVForceUpdate) +{ + BRep_Builder aB; + TopTools_DataMapIteratorOfDataMapOfShapeReal SHToTolit(theShToTol); + for (;SHToTolit.More();SHToTolit.Next()) + { + const TopoDS_Shape& aSh = SHToTolit.Key(); + Standard_Real aTol = SHToTolit.Value(); + // + TopoDS_Shape aNsh; + const TopoDS_Shape& aVsh = theReshaper.Value(aSh); + Standard_Boolean UseOldSh = IsMutableInput || theReshaper.IsNewShape(aSh) || !aVsh.IsSame(aSh); + if (UseOldSh) + aNsh = aVsh; + else + { + aNsh = aSh.EmptyCopied(); + //add subshapes from the original shape + TopoDS_Iterator sit(aSh); + for (;sit.More();sit.Next()) + aB.Add(aNsh, sit.Value()); + // + aNsh.Free(aSh.Free()); + aNsh.Checked(aSh.Checked()); + aNsh.Orientable(aSh.Orientable()); + aNsh.Closed(aSh.Closed()); + aNsh.Infinite(aSh.Infinite()); + aNsh.Convex(aSh.Convex()); + // + } + // + switch (aSh.ShapeType()) + { + case TopAbs_FACE: + { + aB.UpdateFace(TopoDS::Face(aNsh), aTol); + break; + } + case TopAbs_EDGE: + { + aB.UpdateEdge(TopoDS::Edge(aNsh), aTol); + break; + } + case TopAbs_VERTEX: + { + const Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aNsh.TShape()); + // + if(aTV->Locked()) + throw TopoDS_LockedShape("BRep_Builder::UpdateVertex"); + // + if (theVForceUpdate) + aTV->Tolerance(aTol); + else + aTV->UpdateTolerance(aTol); + aTV->Modified(Standard_True); + break; + } + default: + break; + } + // + if (!UseOldSh) + theReshaper.Replace(aSh, aNsh); + } +} + +//======================================================================= +//function : InternalSameParameter //purpose : //======================================================================= -void BRepLib::SameParameter(const TopoDS_Shape& S, - const Standard_Real Tolerance, - const Standard_Boolean forced) +static void InternalSameParameter(const TopoDS_Shape& theSh, BRepTools_ReShape& theReshaper, + const Standard_Real theTol, const Standard_Boolean IsForced, const Standard_Boolean IsMutableInput ) { - TopExp_Explorer ex(S,TopAbs_EDGE); + TopExp_Explorer ex(theSh,TopAbs_EDGE); TopTools_MapOfShape Done; - BRep_Builder brB; - - while (ex.More()) { - if (Done.Add(ex.Current())) { - if (forced) { - brB.SameRange(TopoDS::Edge(ex.Current()), Standard_False); - brB.SameParameter(TopoDS::Edge(ex.Current()), Standard_False); + BRep_Builder aB; + TopTools_DataMapOfShapeReal aShToTol; + + while (ex.More()) + { + const TopoDS_Edge& aCE = TopoDS::Edge(ex.Current()); + if (Done.Add(aCE)) + { + TopoDS_Edge aNE = TopoDS::Edge(theReshaper.Value(aCE)); + Standard_Boolean UseOldEdge = IsMutableInput || theReshaper.IsNewShape(aCE) || !aNE.IsSame(aCE); + if (IsForced && (BRep_Tool::SameRange(aCE) || BRep_Tool::SameParameter(aCE))) + { + if (!UseOldEdge) + { + aNE = TopoDS::Edge(aCE.EmptyCopied()); + TopoDS_Iterator sit(aCE); + for (;sit.More();sit.Next()) + aB.Add(aNE, sit.Value()); + theReshaper.Replace(aCE, aNE); + UseOldEdge = Standard_True; + } + aB.SameRange(aNE, Standard_False); + aB.SameParameter(aNE, Standard_False); + } + Standard_Real aNewTol = -1; + TopoDS_Edge aResEdge = BRepLib::SameParameter(aNE, theTol, aNewTol, UseOldEdge); + if (!UseOldEdge && !aResEdge.IsNull()) + //NE have been empty-copied + theReshaper.Replace(aNE, aResEdge); + if (aNewTol > 0) + { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aCE,aV1,aV2); + if (!aV1.IsNull()) + UpdTolMap(aV1, aNewTol, aShToTol); + if (!aV2.IsNull()) + UpdTolMap(aV2, aNewTol, aShToTol); } - BRepLib::SameParameter(TopoDS::Edge(ex.Current()),Tolerance); } ex.Next(); } - + Done.Clear(); BRepAdaptor_Surface BS; - for(ex.Init(S,TopAbs_FACE); ex.More(); ex.Next()){ + for(ex.Init(theSh,TopAbs_FACE); ex.More(); ex.Next()){ const TopoDS_Face& curface = TopoDS::Face(ex.Current()); if(!Done.Add(curface)) continue; BS.Initialize(curface); @@ -855,10 +985,18 @@ void BRepLib::SameParameter(const TopoDS_Shape& S, TopExp_Explorer ex2; for(ex2.Init(curface,TopAbs_EDGE); ex2.More(); ex2.Next()){ const TopoDS_Edge& E = TopoDS::Edge(ex2.Current()); - SetEdgeTol(E,curface); + TopoDS_Shape aNe = theReshaper.Value(E); + Standard_Real aNewEtol = -1; + GetEdgeTol(TopoDS::Edge(aNe), curface, aNewEtol); + if (aNewEtol >= 0) //not equal to -1 + UpdTolMap(E, aNewEtol, aShToTol); } } - BRepLib::UpdateTolerances(S); + + // + UpdShTol(aShToTol, IsMutableInput, theReshaper, Standard_False ); + + InternalUpdateTolerances(theSh, Standard_False, IsMutableInput, theReshaper ); } //================================================================ @@ -867,6 +1005,28 @@ void BRepLib::SameParameter(const TopoDS_Shape& S, // Recode in the edge the best tolerance found, // for vertex extremities it is required to find something else //================================================================ +void BRepLib::SameParameter(const TopoDS_Shape& S, + const Standard_Real Tolerance, + const Standard_Boolean forced) +{ + BRepTools_ReShape reshaper; + InternalSameParameter( S, reshaper, Tolerance, forced, Standard_True); +} + +//======================================================================= +//function : SameParameter +//purpose : +//======================================================================= +void BRepLib::SameParameter(const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, + const Standard_Real Tolerance, const Standard_Boolean forced ) +{ + InternalSameParameter( S, theReshaper, Tolerance, forced, Standard_False); +} + +//======================================================================= +//function : EvalTol +//purpose : +//======================================================================= static Standard_Boolean EvalTol(const Handle(Geom2d_Curve)& pc, const Handle(Geom_Surface)& s, const GeomAdaptor_Curve& gac, @@ -896,6 +1056,10 @@ static Standard_Boolean EvalTol(const Handle(Geom2d_Curve)& pc, return (ok > 2); } +//======================================================================= +//function : ComputeTol +//purpose : +//======================================================================= static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d, const Handle(Adaptor2d_HCurve2d)& c2d, const Handle(Adaptor3d_HSurface)& surf, @@ -1017,10 +1181,96 @@ static Standard_Real ComputeTol(const Handle(Adaptor3d_HCurve)& c3d, return d2; } -void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, - const Standard_Real Tolerance) +//======================================================================= +//function : GetCurve3d +//purpose : +//======================================================================= +static void GetCurve3d(const TopoDS_Edge& theEdge, Handle(Geom_Curve)& theC3d, Standard_Real& theF3d, + Standard_Real& theL3d, TopLoc_Location& theLoc3d, BRep_ListOfCurveRepresentation& theCList) { - if (BRep_Tool::SameParameter(AnEdge)) return; + const Handle(BRep_TEdge)& aTE = *((Handle(BRep_TEdge)*) &theEdge.TShape()); + theCList = aTE->ChangeCurves(); // current function (i.e. GetCurve3d()) will not change any of this curves + BRep_ListIteratorOfListOfCurveRepresentation anIt(theCList); + Standard_Boolean NotDone = Standard_True; + while (NotDone && anIt.More()) { + Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(anIt.Value()); + if (!GCurve.IsNull() && GCurve->IsCurve3D()) { + theC3d = GCurve->Curve3D() ; + theF3d = GCurve->First(); + theL3d = GCurve->Last(); + theLoc3d = GCurve->Location() ; + NotDone = Standard_False; + } + anIt.Next() ; + } +} + +//======================================================================= +//function : UpdateVTol +//purpose : +//======================================================================= +void UpdateVTol(const TopoDS_Vertex theV1, const TopoDS_Vertex& theV2, Standard_Real theTol) +{ + BRep_Builder aB; + if (!theV1.IsNull()) + aB.UpdateVertex(theV1,theTol); + if (!theV2.IsNull()) + aB.UpdateVertex(theV2,theTol); +} + +//======================================================================= +//function : SameParameter +//purpose : +//======================================================================= +void BRepLib::SameParameter(const TopoDS_Edge& theEdge, + const Standard_Real theTolerance) +{ + Standard_Real aNewTol = -1; + SameParameter(theEdge, theTolerance, aNewTol, Standard_True); + if (aNewTol > 0) + { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(theEdge,aV1,aV2); + UpdateVTol(aV1, aV2, aNewTol); + } +} + +//======================================================================= +//function : SameParameter +//purpose : +//======================================================================= +TopoDS_Edge BRepLib::SameParameter(const TopoDS_Edge& theEdge, + const Standard_Real theTolerance, Standard_Real& theNewTol, Standard_Boolean IsUseOldEdge) +{ + if (BRep_Tool::SameParameter(theEdge)) + return TopoDS_Edge(); + Standard_Real f3d =0.,l3d =0.; + TopLoc_Location L3d; + Handle(Geom_Curve) C3d; + BRep_ListOfCurveRepresentation CList; + GetCurve3d(theEdge, C3d, f3d, l3d, L3d, CList); + if(C3d.IsNull()) + return TopoDS_Edge(); + + BRep_Builder B; + TopoDS_Edge aNE; + Handle(BRep_TEdge) aNTE; + if (IsUseOldEdge) + { + aNE = theEdge; + aNTE = *((Handle(BRep_TEdge)*) &theEdge.TShape()); + } + else + { + aNE = TopoDS::Edge(theEdge.EmptyCopied()); //will be modified a little bit later, so copy anyway + GetCurve3d(aNE, C3d, f3d, l3d, L3d, CList); //C3d pointer and CList will be differ after copying + aNTE = *((Handle(BRep_TEdge)*) &aNE.TShape()); + TopoDS_Iterator sit(theEdge); + for (;sit.More();sit.Next()) //add vertices from old edge to the new ones + B.Add(aNE, sit.Value()); + } + + BRep_ListIteratorOfListOfCurveRepresentation It(CList); const Standard_Integer NCONTROL = 22; @@ -1029,30 +1279,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(); GeomAdaptor_Curve& GAC = HC->ChangeCurve(); Geom2dAdaptor_Curve& GAC2d = HC2d->ChangeCurve2d(); - GeomAdaptor_Surface& GAS = HS->ChangeSurface(); - Standard_Real f3d =0.,l3d =0.; - TopLoc_Location L3d; - Handle(Geom_Curve) C3d; - - const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &AnEdge.TShape()); - BRep_ListOfCurveRepresentation& CList = TE->ChangeCurves(); - BRep_ListIteratorOfListOfCurveRepresentation It(CList); - - Standard_Boolean NotDone = Standard_True; - - while (NotDone && It.More()) { - Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value()); - if (!GCurve.IsNull() && GCurve->IsCurve3D()) { - C3d = GCurve->Curve3D() ; - f3d = GCurve->First(); - l3d = GCurve->Last(); - L3d = GCurve->Location() ; - NotDone = Standard_False; - } - It.Next() ; - } - - if(C3d.IsNull()) return; + GeomAdaptor_Surface& GAS = HS->ChangeSurface(); // modified by NIZHNY-OCC486 Tue Aug 27 17:15:13 2002 : Standard_Boolean m_TrimmedPeriodical = Standard_False; @@ -1064,7 +1291,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, } // modified by NIZHNY-OCC486 Tue Aug 27 17:15:17 2002 . - BRep_Builder B; + if(!C3d->IsPeriodic()) { Standard_Real Udeb = C3d->FirstParameter(); Standard_Real Ufin = C3d->LastParameter(); @@ -1087,14 +1314,15 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, Standard_Real maxdist = 0.; // Modified by skv - Thu Jun 3 12:39:19 2004 OCC5898 Begin - Standard_Real anEdgeTol = BRep_Tool::Tolerance(AnEdge); + Standard_Real anEdgeTol = BRep_Tool::Tolerance(aNE); // Modified by skv - Thu Jun 3 12:39:20 2004 OCC5898 End - Standard_Boolean SameRange = BRep_Tool::SameRange(AnEdge); + Standard_Boolean SameRange = BRep_Tool::SameRange(aNE); Standard_Boolean YaPCu = Standard_False; const Standard_Real BigError = 1.e10; It.Initialize(CList); while (It.More()) { + Standard_Boolean isANA = Standard_False; Standard_Boolean isBSP = Standard_False; Handle(BRep_GCurve) GCurve = Handle(BRep_GCurve)::DownCast(It.Value()); @@ -1115,8 +1343,8 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, } // Eval tol2d to compute SameRange - Standard_Real UResol = Max(GAS.UResolution(Tolerance), Precision::PConfusion()); - Standard_Real VResol = Max(GAS.VResolution(Tolerance), Precision::PConfusion()); + Standard_Real UResol = Max(GAS.UResolution(theTolerance), Precision::PConfusion()); + Standard_Real VResol = Max(GAS.VResolution(theTolerance), Precision::PConfusion()); Standard_Real Tol2d = Min(UResol, VResol); for(Standard_Integer i = 0; i < 2; i++){ Handle(Geom2d_Curve) curPC = PC[i]; @@ -1174,7 +1402,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, if(bs2d->Continuity() == GeomAbs_C0) { Standard_Real tolbail; - if(EvalTol(curPC,S,GAC,Tolerance,tolbail)){ + if(EvalTol(curPC,S,GAC,theTolerance,tolbail)){ bs2d = bs2dsov; Standard_Real UResbail = GAS.UResolution(tolbail); Standard_Real VResbail = GAS.VResolution(tolbail); @@ -1257,7 +1485,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, GeomAbs_Shape cont = bs2d->Continuity(); Standard_Boolean IsBad = Standard_False; - if(cont > GeomAbs_C0 && error > Max(1.e-3,Tolerance)) { + if(cont > GeomAbs_C0 && error > Max(1.e-3,theTolerance)) { Standard_Integer NbKnots = bs2d->NbKnots(); TColStd_Array1OfReal Knots(1,NbKnots); bs2d->Knots(Knots); @@ -1279,7 +1507,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, } if(IsBad) { // To avoid failures in Approx_CurvilinearParameter - bs2d->Resolution(Max(1.e-3,Tolerance), dtcur); + bs2d->Resolution(Max(1.e-3,theTolerance), dtcur); if(dtmin < dtcur) IsBad = Standard_False; } } @@ -1292,7 +1520,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, if(cont > GeomAbs_C2) cont = GeomAbs_C2; Standard_Integer maxdeg = bs2d->Degree(); if(maxdeg == 1) maxdeg = 14; - Approx_CurvilinearParameter AppCurPar(HC2d, HS, Max(1.e-3,Tolerance), + Approx_CurvilinearParameter AppCurPar(HC2d, HS, Max(1.e-3,theTolerance), cont, maxdeg, 10); if(AppCurPar.IsDone() || AppCurPar.HasResult()) { bs2d = AppCurPar.Curve2d1(); @@ -1321,7 +1549,7 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, if(goodpc){ // Approx_SameParameter SameP(HC,HC2d,HS,Tolerance); - Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : Tolerance; + Standard_Real aTol = (isANA && isBSP) ? 1.e-7 : theTolerance; const Handle(Adaptor3d_HCurve)& aHCurv = HC; // to avoid ambiguity const Handle(Adaptor2d_HCurve2d)& aHCurv2d = HC2d; // to avoid ambiguity Approx_SameParameter SameP(aHCurv,aHCurv2d,HS,aTol); @@ -1378,8 +1606,8 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, } It.Next() ; } - B.Range(AnEdge,f3d,l3d); - B.SameRange(AnEdge,Standard_True); + B.Range(aNE,f3d,l3d); + B.SameRange(aNE,Standard_True); if ( IsSameP) { // Reduce eventually the tolerance of the edge, as // all its representations are processed (except for some associated @@ -1389,39 +1617,35 @@ void BRepLib::SameParameter(const TopoDS_Edge& AnEdge, if (YaPCu) { // Avoid setting too small tolerances. maxdist = Max(maxdist,Precision::Confusion()); - TopoDS_Vertex V1,V2; - TopExp::Vertices(AnEdge,V1,V2); - if (!V1.IsNull()) - B.UpdateVertex(V1,maxdist); - if (!V2.IsNull()) - B.UpdateVertex(V2,maxdist); - TE->Modified(Standard_True); - TE->Tolerance(maxdist); + theNewTol = maxdist; + aNTE->Modified(Standard_True); + aNTE->Tolerance(maxdist); } - B.SameParameter(AnEdge,Standard_True); + B.SameParameter(aNE,Standard_True); } + + return aNE; } //======================================================================= -//function : UpdateTolerances +//function : InternalUpdateTolerances //purpose : //======================================================================= -void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, - const Standard_Boolean verifyTolerance) +static void InternalUpdateTolerances(const TopoDS_Shape& theOldShape, + const Standard_Boolean IsVerifyTolerance, const Standard_Boolean IsMutableInput, BRepTools_ReShape& theReshaper) { - + TopTools_DataMapOfShapeReal aShToTol; // Harmonize tolerances // with rule Tolerance(VERTEX)>=Tolerance(EDGE)>=Tolerance(FACE) - BRep_Builder B; Standard_Real tol=0; - if (verifyTolerance) { + if (IsVerifyTolerance) { // Set tolerance to its minimum value Handle(Geom_Surface) S; TopLoc_Location l; TopExp_Explorer ex; Bnd_Box aB; Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dMax; - for (ex.Init(aShape, TopAbs_FACE); ex.More(); ex.Next()) { + for (ex.Init(theOldShape, TopAbs_FACE); ex.More(); ex.Next()) { const TopoDS_Face& curf=TopoDS::Face(ex.Current()); S = BRep_Tool::Surface(curf, l); if (!S.IsNull()) { @@ -1460,31 +1684,40 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, // Do not process tolerances > 1. if (tol>1.) tol=0.99; } - const Handle(BRep_TFace)& Tf = *((Handle(BRep_TFace)*)&curf.TShape()); - Tf->Tolerance(tol); + aShToTol.Bind(curf, tol); } } } //Process edges TopTools_IndexedDataMapOfShapeListOfShape parents; - TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, parents); + TopExp::MapShapesAndAncestors(theOldShape, TopAbs_EDGE, TopAbs_FACE, parents); TopTools_ListIteratorOfListOfShape lConx; Standard_Integer iCur; for (iCur=1; iCur<=parents.Extent(); iCur++) { tol=0; - for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) { - tol=Max(tol, BRep_Tool::Tolerance(TopoDS::Face(lConx.Value()))); + for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) + { + const TopoDS_Face& FF = TopoDS::Face(lConx.Value()); + Standard_Real Ftol; + if (IsVerifyTolerance && aShToTol.IsBound(FF)) //first condition for speed-up + Ftol = aShToTol(FF); + else + Ftol = BRep_Tool::Tolerance(FF); //tolerance have not been updated + tol=Max(tol, Ftol); } // Update can only increase tolerance, so if the edge has a greater // tolerance than its faces it is not concerned - B.UpdateEdge(TopoDS::Edge(parents.FindKey(iCur)), tol); + const TopoDS_Edge& EK = TopoDS::Edge(parents.FindKey(iCur)); + if (tol > BRep_Tool::Tolerance(EK)) + aShToTol.Bind(EK, tol); } //Vertices are processed const Standard_Real BigTol = 1.e10; parents.Clear(); - TopExp::MapShapesAndUniqueAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, parents); + + TopExp::MapShapesAndUniqueAncestors(theOldShape, TopAbs_VERTEX, TopAbs_EDGE, parents); TColStd_MapOfTransient Initialized; Standard_Integer nbV = parents.Extent(); for (iCur=1; iCur<=nbV; iCur++) { @@ -1495,7 +1728,8 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, gp_Pnt p3d; for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) { const TopoDS_Edge& E = TopoDS::Edge(lConx.Value()); - tol=Max(tol, BRep_Tool::Tolerance(E)); + const Standard_Real* aNtol = aShToTol.Seek(E); + tol=Max(tol, aNtol ? *aNtol : BRep_Tool::Tolerance(E)); if(tol > BigTol) continue; if(!BRep_Tool::SameRange(E)) continue; Standard_Real par = BRep_Tool::Parameter(V,E); @@ -1541,21 +1775,42 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, aXmax -= aXmin; aYmax -= aYmin; aZmax -= aZmin; tol = Max(tol,sqrt(aXmax*aXmax+aYmax*aYmax+aZmax*aZmax)); tol += 2.*Epsilon(tol); - if (verifyTolerance) { + // + Standard_Real aVTol = BRep_Tool::Tolerance(V); + Standard_Boolean anUpdTol = tol > aVTol; + const Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&V.TShape()); + Standard_Boolean toAdd = Standard_False; + if (IsVerifyTolerance) + { // ASet minimum value of the tolerance - // Attention to sharing of the vertex by other shapes - const Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*)&V.TShape()); - if (Initialized.Add(TV)) - TV->Tolerance(tol); - else - B.UpdateVertex(V, tol); - } - else { - // Update can only increase tolerance, so if the edge has a greater - // tolerance than its faces it is not concerned - B.UpdateVertex(V, tol); + // Attention to sharing of the vertex by other shapes + toAdd = Initialized.Add(aTV) && aVTol != tol; //if Vtol == tol => no need to update toler } + //'Initialized' map is not used anywhere outside this block + if (anUpdTol || toAdd) + aShToTol.Bind(V, tol); } + + UpdShTol(aShToTol, IsMutableInput, theReshaper, Standard_True); +} + +//======================================================================= +//function : UpdateTolerances +//purpose : +//======================================================================= +void BRepLib::UpdateTolerances (const TopoDS_Shape& S, const Standard_Boolean verifyFaceTolerance) +{ + BRepTools_ReShape aReshaper; + InternalUpdateTolerances(S, verifyFaceTolerance, Standard_True, aReshaper); +} + +//======================================================================= +//function : UpdateTolerances +//purpose : +//======================================================================= +void BRepLib::UpdateTolerances (const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, const Standard_Boolean verifyFaceTolerance ) +{ + InternalUpdateTolerances(S, verifyFaceTolerance, Standard_False, theReshaper); } //======================================================================= diff --git a/src/BRepLib/BRepLib.hxx b/src/BRepLib/BRepLib.hxx index c711e34526..4d4b89c242 100644 --- a/src/BRepLib/BRepLib.hxx +++ b/src/BRepLib/BRepLib.hxx @@ -45,6 +45,7 @@ class BRepLib_MakeSolid; class BRepLib_FindSurface; class BRepLib_FuseEdges; class BRepLib_CheckCurveOnSurface; +class BRepTools_ReShape; //! The BRepLib package provides general utilities for @@ -130,23 +131,58 @@ public: //! Use only in interfaces or processing assimilate batch Standard_EXPORT static Standard_Boolean UpdateEdgeTolerance (const TopoDS_Shape& S, const Standard_Real MinToleranceRequest, const Standard_Real MaxToleranceToCheck); - //! Computes new 2d curve(s) for the edge to have + //! Computes new 2d curve(s) for the edge to have //! the same parameter as the 3d curve. //! The algorithm is not done if the flag SameParameter //! was True on the Edge. - Standard_EXPORT static void SameParameter (const TopoDS_Edge& E, const Standard_Real Tolerance = 1.0e-5); + Standard_EXPORT static void SameParameter (const TopoDS_Edge& theEdge, const Standard_Real Tolerance = 1.0e-5); + + //! Computes new 2d curve(s) for the edge to have + //! the same parameter as the 3d curve. + //! The algorithm is not done if the flag SameParameter + //! was True on the Edge.
+ //! theNewTol is a new tolerance of vertices of the input edge + //! (not applied inside the algorithm, but pre-computed). + //! If IsUseOldEdge is true then the input edge will be modified, + //! otherwise the new copy of input edge will be created. + //! Returns the new edge as a result, can be ignored if IsUseOldEdge is true. + Standard_EXPORT static TopoDS_Edge SameParameter(const TopoDS_Edge& theEdge, + const Standard_Real theTolerance, Standard_Real& theNewTol, const Standard_Boolean IsUseOldEdge); //! Computes new 2d curve(s) for all the edges of //! to have the same parameter as the 3d curve. //! The algorithm is not done if the flag SameParameter //! was True on an Edge. - Standard_EXPORT static void SameParameter (const TopoDS_Shape& S, const Standard_Real Tolerance = 1.0e-5, const Standard_Boolean forced = Standard_False); - + Standard_EXPORT static void SameParameter(const TopoDS_Shape& S, + const Standard_Real Tolerance = 1.0e-5, const Standard_Boolean forced = Standard_False); + + //! Computes new 2d curve(s) for all the edges of + //! to have the same parameter as the 3d curve. + //! The algorithm is not done if the flag SameParameter + //! was True on an Edge.
+ //! theReshaper is used to record the modifications of input shape to prevent any + //! modifications on the shape itself. + //! Thus the input shape (and its subshapes) will not be modified, instead the reshaper will + //! contain a modified empty-copies of original subshapes as substitutions. + Standard_EXPORT static void SameParameter(const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, + const Standard_Real Tolerance = 1.0e-5, const Standard_Boolean forced = Standard_False ); + //! Replaces tolerance of FACE EDGE VERTEX by the //! tolerance Max of their connected handling shapes. //! It is not necessary to use this call after //! SameParameter. (called in) Standard_EXPORT static void UpdateTolerances (const TopoDS_Shape& S, const Standard_Boolean verifyFaceTolerance = Standard_False); + + //! Replaces tolerance of FACE EDGE VERTEX by the + //! tolerance Max of their connected handling shapes. + //! It is not necessary to use this call after + //! SameParameter. (called in)
+ //! theReshaper is used to record the modifications of input shape to prevent any + //! modifications on the shape itself. + //! Thus the input shape (and its subshapes) will not be modified, instead the reshaper will + //! contain a modified empty-copies of original subshapes as substitutions. + Standard_EXPORT static void UpdateTolerances (const TopoDS_Shape& S, BRepTools_ReShape& theReshaper, + const Standard_Boolean verifyFaceTolerance = Standard_False ); //! Checks tolerances of edges (including inner points) and vertices //! of a shape and updates them to satisfy "SameParameter" condition diff --git a/src/BRepTest/BRepTest_BasicCommands.cxx b/src/BRepTest/BRepTest_BasicCommands.cxx index 0d0a9ff496..b5200855b6 100644 --- a/src/BRepTest/BRepTest_BasicCommands.cxx +++ b/src/BRepTest/BRepTest_BasicCommands.cxx @@ -305,36 +305,80 @@ static Standard_Integer mkedgecurve (Draw_Interpretor& ,Standard_Integer n,const // sameparameter //======================================================================= -static Standard_Integer sameparameter(Draw_Interpretor& ,Standard_Integer n,const char** a) +static Standard_Integer sameparameter(Draw_Interpretor& di,Standard_Integer n,const char** a) { - if (n < 2) return 1; - Standard_Real tol = 1.e-7; - TopoDS_Shape S = DBRep::Get(a[1]); - if (S.IsNull()) return 1; + if (n < 2) + { + di << "Use sameparameter [result] shape [toler]\n"; + di << "shape is an initial shape\n"; + di << "result is a result shape. if skipped = > initial shape will be modified\n"; + di << "toler is tolerance (default is 1.e-7)"; + return 1; + } + Standard_Real aTol = 1.e-7; Standard_Boolean force = !strcmp(a[0],"fsameparameter"); - if (n == 3) tol = Draw::Atof(a[2]); - BRepLib::SameParameter(S,tol,force); + Standard_Real aTol1 = Draw::Atof(a[n-1]); + Standard_Boolean IsUseTol = aTol1>0; + if (IsUseTol) + aTol = aTol1; + + TopoDS_Shape anInpS = DBRep::Get(IsUseTol ? a[n-2] : a[n-1]); + if (anInpS.IsNull()) + return 1; + + if ((n == 4 && IsUseTol) || (n == 3 && !IsUseTol)) + { + TopoDS_Shape aResultSh; + BRepTools_ReShape aResh; + BRepLib::SameParameter(anInpS,aResh,aTol,force); + aResultSh = aResh.Apply(anInpS); + DBRep::Set(a[1],aResultSh); + } + else + { + BRepLib::SameParameter(anInpS,aTol,force); + DBRep::Set(a[1],anInpS); + } - DBRep::Set(a[1],S); return 0; } //======================================================================= //function : updatetol //purpose : //======================================================================= -static Standard_Integer updatetol(Draw_Interpretor& ,Standard_Integer n,const char** a) +static Standard_Integer updatetol(Draw_Interpretor& di,Standard_Integer n,const char** a) { - if (n < 2) return 1; + if (n < 2) + { + di << "Use updatetololerance [result] shape [param]\n"; + di << "shape is an initial shape\n"; + di << "result is a result shape. if skipped = > initial shape will be modified\n"; + di << "if [param] is absent - not verify of face tolerance, else - perform it"; + return 1; + } + TopoDS_Shape aSh1 = DBRep::Get(a[n-1]); + Standard_Boolean IsF = aSh1.IsNull(); - TopoDS_Shape S = DBRep::Get(a[1]); - if (S.IsNull()) return 1; + TopoDS_Shape anInpS = IsF ? DBRep::Get(a[n-2]) : aSh1; + if (anInpS.IsNull()) + return 1; + + if ((n == 4 && IsF) || (n == 3 && !IsF)) + { + TopoDS_Shape aResultSh; + BRepTools_ReShape aResh; + BRepLib::UpdateTolerances(anInpS,aResh, IsF); + aResultSh = aResh.Apply(anInpS); + DBRep::Set(a[1],aResultSh); + } + else + { + BRepLib::UpdateTolerances(anInpS, IsF); + DBRep::Set(a[1],anInpS); + } - if (n==2) BRepLib::UpdateTolerances(S); - else BRepLib::UpdateTolerances(S,Standard_True); - DBRep::Set(a[1],S); return 0; - } //======================================================================= @@ -1145,12 +1189,12 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands) sameparameter,g); theCommands.Add("sameparameter", - "sameparameter shapename [tol (default 1.e-7)]", + "sameparameter [result] shape [tol]", __FILE__, sameparameter,g); theCommands.Add("updatetolerance", - "updatetolerance myShape [param] \n if [param] is absent - not verify of face tolerance, else - perform it", + "updatetolerance [result] shape [param] \n if [param] is absent - not verify of face tolerance, else - perform it", __FILE__, updatetol,g); diff --git a/src/BRepTools/BRepTools_ReShape.cxx b/src/BRepTools/BRepTools_ReShape.cxx index c59bdf7a8d..319469449e 100644 --- a/src/BRepTools/BRepTools_ReShape.cxx +++ b/src/BRepTools/BRepTools_ReShape.cxx @@ -104,6 +104,7 @@ void BRepTools_ReShape::Clear() { myNMap.Clear(); myRMap.Clear(); + myNewShapes.Clear(); } @@ -154,6 +155,7 @@ void BRepTools_ReShape::Replace (const TopoDS_Shape& ashape, } else myNMap.Bind (shape,newshape); + myNewShapes.Add (newshape); } else { // protect against INTERNAL or EXTERNAL shape @@ -622,3 +624,8 @@ TopoDS_Vertex BRepTools_ReShape::CopyVertex(const TopoDS_Vertex& theV, return aVertexCopy; } + +Standard_Boolean BRepTools_ReShape::IsNewShape(const TopoDS_Shape& theShape) const +{ + return myNewShapes.Contains(theShape); +} diff --git a/src/BRepTools/BRepTools_ReShape.hxx b/src/BRepTools/BRepTools_ReShape.hxx index c97cebe994..eb1e5f1c9e 100644 --- a/src/BRepTools/BRepTools_ReShape.hxx +++ b/src/BRepTools/BRepTools_ReShape.hxx @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -138,6 +139,10 @@ public: const gp_Pnt& theNewPos, const Standard_Real aTol); + //! Checks if shape has been recorded by reshaper as a value + //@param theShape is the given shape + Standard_EXPORT Standard_Boolean IsNewShape(const TopoDS_Shape& theShape) const; + DEFINE_STANDARD_RTTIEXT(BRepTools_ReShape,MMgt_TShared) @@ -146,6 +151,7 @@ protected: TopTools_DataMapOfShapeShape myNMap; TopTools_DataMapOfShapeShape myRMap; + TopTools_MapOfShape myNewShapes; Standard_Integer myStatus; diff --git a/tests/bugs/modalg_1/buc60896 b/tests/bugs/modalg_1/buc60896 index 8c8df50d6b..b78ce15041 100755 --- a/tests/bugs/modalg_1/buc60896 +++ b/tests/bugs/modalg_1/buc60896 @@ -11,8 +11,8 @@ restore [locate_data_file BUC60896_edge.rle] result # checkshape res sameparameter result -sameparameter result tol 1.e-2 -sameparameter result tol 1000 +sameparameter result 1.e-2 +sameparameter result 1000 checkprops result -l 48288.3 checkshape result diff --git a/tests/heal/grids.list b/tests/heal/grids.list index 929f032428..2e75e21581 100644 --- a/tests/heal/grids.list +++ b/tests/heal/grids.list @@ -21,3 +21,5 @@ 021 wire_tails_real 022 reshape 023 unify_same_domain +014 same_parameter_locked +015 update_tolerance_locked \ No newline at end of file diff --git a/tests/heal/same_parameter_locked/A1 b/tests/heal/same_parameter_locked/A1 new file mode 100644 index 0000000000..42f78468aa --- /dev/null +++ b/tests/heal/same_parameter_locked/A1 @@ -0,0 +1 @@ +restore [locate_data_file CFE903_ger60ggw.rle] s diff --git a/tests/heal/same_parameter_locked/A2 b/tests/heal/same_parameter_locked/A2 new file mode 100644 index 0000000000..3ab25b8d60 --- /dev/null +++ b/tests/heal/same_parameter_locked/A2 @@ -0,0 +1 @@ +restore [locate_data_file CNP001_projoien.rle] s diff --git a/tests/heal/same_parameter_locked/A3 b/tests/heal/same_parameter_locked/A3 new file mode 100644 index 0000000000..fa64472c3d --- /dev/null +++ b/tests/heal/same_parameter_locked/A3 @@ -0,0 +1 @@ +restore [locate_data_file CTS18868-1.rle] s diff --git a/tests/heal/same_parameter_locked/A4 b/tests/heal/same_parameter_locked/A4 new file mode 100644 index 0000000000..3b56438755 --- /dev/null +++ b/tests/heal/same_parameter_locked/A4 @@ -0,0 +1 @@ +restore [locate_data_file CTS18868-2.rle] s diff --git a/tests/heal/same_parameter_locked/A5 b/tests/heal/same_parameter_locked/A5 new file mode 100644 index 0000000000..74caf9e6d9 --- /dev/null +++ b/tests/heal/same_parameter_locked/A5 @@ -0,0 +1 @@ +restore [locate_data_file BUC50070-#53168-good.rle] s diff --git a/tests/heal/same_parameter_locked/A6 b/tests/heal/same_parameter_locked/A6 new file mode 100644 index 0000000000..0d0a980372 --- /dev/null +++ b/tests/heal/same_parameter_locked/A6 @@ -0,0 +1 @@ +restore [locate_data_file self-int.rle] s diff --git a/tests/heal/same_parameter_locked/A7 b/tests/heal/same_parameter_locked/A7 new file mode 100644 index 0000000000..6a165f1b13 --- /dev/null +++ b/tests/heal/same_parameter_locked/A7 @@ -0,0 +1 @@ +restore [locate_data_file shell_orient.rle] s diff --git a/tests/heal/same_parameter_locked/end b/tests/heal/same_parameter_locked/end new file mode 100644 index 0000000000..1c1332ce83 --- /dev/null +++ b/tests/heal/same_parameter_locked/end @@ -0,0 +1,3 @@ +setflags s locked +sameparameter result s 0.001 +puts [checkshape result] diff --git a/tests/heal/update_tolerance_locked/A1 b/tests/heal/update_tolerance_locked/A1 new file mode 100644 index 0000000000..42f78468aa --- /dev/null +++ b/tests/heal/update_tolerance_locked/A1 @@ -0,0 +1 @@ +restore [locate_data_file CFE903_ger60ggw.rle] s diff --git a/tests/heal/update_tolerance_locked/A2 b/tests/heal/update_tolerance_locked/A2 new file mode 100644 index 0000000000..3ab25b8d60 --- /dev/null +++ b/tests/heal/update_tolerance_locked/A2 @@ -0,0 +1 @@ +restore [locate_data_file CNP001_projoien.rle] s diff --git a/tests/heal/update_tolerance_locked/A3 b/tests/heal/update_tolerance_locked/A3 new file mode 100644 index 0000000000..74caf9e6d9 --- /dev/null +++ b/tests/heal/update_tolerance_locked/A3 @@ -0,0 +1 @@ +restore [locate_data_file BUC50070-#53168-good.rle] s diff --git a/tests/heal/update_tolerance_locked/A4 b/tests/heal/update_tolerance_locked/A4 new file mode 100644 index 0000000000..0d0a980372 --- /dev/null +++ b/tests/heal/update_tolerance_locked/A4 @@ -0,0 +1 @@ +restore [locate_data_file self-int.rle] s diff --git a/tests/heal/update_tolerance_locked/end b/tests/heal/update_tolerance_locked/end new file mode 100644 index 0000000000..6ba457be5f --- /dev/null +++ b/tests/heal/update_tolerance_locked/end @@ -0,0 +1,3 @@ +setflags s locked +updatetolerance result s 1 +puts [checkshape result]