From 420f79f8bcac33bc927bf2a09650f68db8d7f745 Mon Sep 17 00:00:00 2001 From: jgv Date: Tue, 10 Nov 2015 14:25:56 +0300 Subject: [PATCH] 0026681: BRepPrimAPI_MakeRevol creates faulty shape Correction according to remarks More precise processing of non-SameParameter edges Correction of mistake Test cases for issue CR26681 --- src/BRepLib/BRepLib.cxx | 94 +++++++++++++++++++++++ src/BRepLib/BRepLib.hxx | 4 + src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx | 2 + tests/bugs/modalg_6/bug26681 | 19 +++++ 4 files changed, 119 insertions(+) create mode 100644 tests/bugs/modalg_6/bug26681 diff --git a/src/BRepLib/BRepLib.cxx b/src/BRepLib/BRepLib.cxx index ecd0eb9933..98e3e0c005 100644 --- a/src/BRepLib/BRepLib.cxx +++ b/src/BRepLib/BRepLib.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1456,6 +1457,99 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape, } } +//======================================================================= +//function : UpdateInnerTolerances +//purpose : +//======================================================================= +void BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape) +{ + TopTools_IndexedDataMapOfShapeListOfShape EFmap; + TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, EFmap); + BRep_Builder BB; + for (Standard_Integer i = 1; i <= EFmap.Extent(); i++) + { + TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i)); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + Standard_Real fpar, lpar; + BRep_Tool::Range(anEdge, fpar, lpar); + Standard_Real TolEdge = BRep_Tool::Tolerance(anEdge); + gp_Pnt Pnt1, Pnt2; + Handle(BRepAdaptor_HCurve) anHCurve = new BRepAdaptor_HCurve(); + anHCurve->ChangeCurve().Initialize(anEdge); + if (!V1.IsNull()) + Pnt1 = BRep_Tool::Pnt(V1); + if (!V2.IsNull()) + Pnt2 = BRep_Tool::Pnt(V2); + + if (!BRep_Tool::Degenerated(anEdge) && + EFmap(i).Extent() > 0) + { + NCollection_Sequence theRep; + theRep.Append(anHCurve); + TopTools_ListIteratorOfListOfShape itl(EFmap(i)); + for (; itl.More(); itl.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face(itl.Value()); + Handle(BRepAdaptor_HCurve) anHCurvOnSurf = new BRepAdaptor_HCurve(); + anHCurvOnSurf->ChangeCurve().Initialize(anEdge, aFace); + theRep.Append(anHCurvOnSurf); + } + + const Standard_Integer NbSamples = (BRep_Tool::SameParameter(anEdge))? 23 : 2; + Standard_Real delta = (lpar - fpar)/(NbSamples-1); + Standard_Real MaxDist = 0.; + for (Standard_Integer j = 2; j <= theRep.Length(); j++) + { + for (Standard_Integer k = 0; k <= NbSamples; k++) + { + Standard_Real ParamOnCenter = (k == NbSamples)? lpar : + fpar + k*delta; + gp_Pnt Center = theRep(1)->Value(ParamOnCenter); + Standard_Real ParamOnCurve = (BRep_Tool::SameParameter(anEdge))? ParamOnCenter + : ((k == 0)? theRep(j)->FirstParameter() : theRep(j)->LastParameter()); + gp_Pnt aPoint = theRep(j)->Value(ParamOnCurve); + Standard_Real aDist = Center.Distance(aPoint); + //aDist *= 1.1; + aDist += 2.*Epsilon(aDist); + if (aDist > MaxDist) + MaxDist = aDist; + + //Update tolerances of vertices + if (k == 0 && !V1.IsNull()) + { + Standard_Real aDist1 = Pnt1.Distance(aPoint); + aDist1 += 2.*Epsilon(aDist1); + BB.UpdateVertex(V1, aDist1); + } + if (k == NbSamples && !V2.IsNull()) + { + Standard_Real aDist2 = Pnt2.Distance(aPoint); + aDist2 += 2.*Epsilon(aDist2); + BB.UpdateVertex(V2, aDist2); + } + } + } + BB.UpdateEdge(anEdge, MaxDist); + } + TolEdge = BRep_Tool::Tolerance(anEdge); + if (!V1.IsNull()) + { + gp_Pnt End1 = anHCurve->Value(fpar); + Standard_Real dist1 = Pnt1.Distance(End1); + dist1 += 2.*Epsilon(dist1); + BB.UpdateVertex(V1, Max(dist1, TolEdge)); + } + if (!V2.IsNull()) + { + gp_Pnt End2 = anHCurve->Value(lpar); + Standard_Real dist2 = Pnt2.Distance(End2); + dist2 += 2.*Epsilon(dist2); + BB.UpdateVertex(V2, Max(dist2, TolEdge)); + } + } +} + //======================================================================= //function : OrientClosedSolid //purpose : diff --git a/src/BRepLib/BRepLib.hxx b/src/BRepLib/BRepLib.hxx index a1e8788609..7e44fdf017 100644 --- a/src/BRepLib/BRepLib.hxx +++ b/src/BRepLib/BRepLib.hxx @@ -147,6 +147,10 @@ public: //! SameParameter. (called in) Standard_EXPORT static void UpdateTolerances (const TopoDS_Shape& S, 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 + Standard_EXPORT static void UpdateInnerTolerances (const TopoDS_Shape& S); + //! Orients the solid forward and the shell with the //! orientation to have matter in the solid. Returns //! False if the solid is unOrientable (open or incoherent) diff --git a/src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx b/src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx index c92acc8158..0cdce676b7 100644 --- a/src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx +++ b/src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx @@ -80,6 +80,8 @@ const BRepSweep_Revol& BRepPrimAPI_MakeRevol::Revol() const void BRepPrimAPI_MakeRevol::Build() { myShape = myRevol.Shape(); + BRepLib::UpdateInnerTolerances(myShape); + Done(); // Modified by skv - Fri Mar 4 15:50:09 2005 Begin myDegenerated.Clear(); diff --git a/tests/bugs/modalg_6/bug26681 b/tests/bugs/modalg_6/bug26681 new file mode 100644 index 0000000000..4e4ee6c511 --- /dev/null +++ b/tests/bugs/modalg_6/bug26681 @@ -0,0 +1,19 @@ +puts "========" +puts "OCC26681" +puts "========" +puts "" +############################################################# +# BRepPrimAPI_MakeRevol creates faulty shape +############################################################# + +smallview + +restore [locate_data_file bug26681_ab.brep] aB + +revol aR aB 0 0 0 0 1 0 75 + +checkshape aR + +donly aR +fit +set only_screen_axo 1