From ba165db3d3fa8a370a5a779c4701d5bee5784f80 Mon Sep 17 00:00:00 2001 From: emv Date: Thu, 22 Aug 2019 13:54:53 +0300 Subject: [PATCH] 0030880: Modeling Algorithms - Bug in BRepExtrema_ExtCF Use the BRepTopAdaptor_FClass2d instead of BRepClass_FaceClassifier in BRepExtrema_ExtCF for classification of the found intersection points. --- src/BRepExtrema/BRepExtrema_ExtCF.cxx | 15 ++++-- src/QABugs/QABugs_20.cxx | 74 +++++++++++++++++++++++++++ tests/bugs/modalg_7/bug30880_1 | 13 +++++ tests/bugs/modalg_7/bug30880_2 | 10 ++++ 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 tests/bugs/modalg_7/bug30880_1 create mode 100644 tests/bugs/modalg_7/bug30880_2 diff --git a/src/BRepExtrema/BRepExtrema_ExtCF.cxx b/src/BRepExtrema/BRepExtrema_ExtCF.cxx index 59d67b3c44..109ce3237e 100644 --- a/src/BRepExtrema/BRepExtrema_ExtCF.cxx +++ b/src/BRepExtrema/BRepExtrema_ExtCF.cxx @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -94,8 +94,14 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2) else { // Exploration of points and classification - BRepClass_FaceClassifier classifier; - const Standard_Real Tol = BRep_Tool::Tolerance(F2); + const Standard_Real Tol = BRep_Tool::Tolerance (F2); + BRepTopAdaptor_FClass2d classifier (F2, Tol); + + // If the underlying surface of the face is periodic + // Extrema should return the point within the period, + // so there is no point to adjust it in classifier. + Standard_Boolean isAdjustPeriodic = Standard_False; + Extrema_POnCurv P1; Extrema_POnSurf P2; @@ -104,8 +110,7 @@ void BRepExtrema_ExtCF::Perform(const TopoDS_Edge& E, const TopoDS_Face& F2) myExtCS.Points(i, P1, P2); P2.Parameter(U1, U2); const gp_Pnt2d Puv(U1, U2); - classifier.Perform(F2, Puv, Tol); - const TopAbs_State state = classifier.State(); + const TopAbs_State state = classifier.Perform (Puv, isAdjustPeriodic); if (state == TopAbs_ON || state == TopAbs_IN) { mySqDist.Append(myExtCS.SquareDistance(i)); diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx index b9c898e43f..d2e0bd841e 100644 --- a/src/QABugs/QABugs_20.cxx +++ b/src/QABugs/QABugs_20.cxx @@ -3239,6 +3239,76 @@ static Standard_Integer OCC30869 (Draw_Interpretor& theDI, Standard_Integer theA return 0; } +#include +//======================================================================= +//function : OCC30880 +//purpose : +//======================================================================= +static Standard_Integer OCC30880 (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv) +{ + if (theArgc != 3) + { + theDI.PrintHelp (theArgv[0]); + return 1; + } + + TopoDS_Shape anEdge = DBRep::Get (theArgv[1]); + if (anEdge.IsNull() || anEdge.ShapeType() != TopAbs_EDGE) + { + theDI << theArgv[1] << " is not an edge.\n"; + return 1; + } + + TopoDS_Shape aFace = DBRep::Get (theArgv[2]); + if (aFace.IsNull() || aFace.ShapeType() != TopAbs_FACE) + { + theDI << theArgv[2] << " is not a face.\n"; + return 1; + } + + BRepExtrema_ExtCF anExtCF (TopoDS::Edge (anEdge), + TopoDS::Face (aFace)); + if (!anExtCF.IsDone()) + { + theDI << "Not done\n"; + return 0; + } + + if (!anExtCF.NbExt()) + { + theDI << "No solutions\n"; + return 0; + } + + if (anExtCF.IsParallel()) + { + theDI << "Infinite number of solutions, distance - " << Sqrt (anExtCF.SquareDistance (1)) << "\n"; + return 0; + } + + Standard_Real aDistMin = RealLast(); + Standard_Integer aSolMin = -1; + // Look for the minimal solution + for (int i = 1; i <= anExtCF.NbExt(); ++i) + { + Standard_Real aDist = anExtCF.SquareDistance (i); + if (aDist < aDistMin) + { + aDistMin = aDist; + aSolMin = i; + } + } + + if (aSolMin < 0) + { + theDI << "Failed\n"; + return 0; + } + + theDI << "Minimal distance - " << Sqrt (aDistMin) << "\n"; + return 0; +} + #include static Standard_Integer OCC30704(Draw_Interpretor& di, Standard_Integer, const char**) { @@ -3328,6 +3398,10 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) { "Usage: OCC30869 wire", __FILE__, OCC30869, group); + theCommands.Add ("OCC30880", "Looks for extrema between edge and face.\n" + "Usage: OCC30880 edge face", + __FILE__, OCC30880, group); + theCommands.Add("OCC30704", "OCC30704", __FILE__, OCC30704, group); theCommands.Add("OCC30704_1", "OCC30704_1", __FILE__, OCC30704_1, group); diff --git a/tests/bugs/modalg_7/bug30880_1 b/tests/bugs/modalg_7/bug30880_1 new file mode 100644 index 0000000000..0bf8006385 --- /dev/null +++ b/tests/bugs/modalg_7/bug30880_1 @@ -0,0 +1,13 @@ +puts "========" +puts "0030880: Bug in BRepExtrema_ExtCF" +puts "========" +puts "" + +pload QAcommands + +restore [locate_data_file bug30880_edge.brep] e +restore [locate_data_file bug30880_face.brep] f + +if {![regexp "No solutions" [OCC30880 e f]]} { + puts "Error: Incorrect extrema solutions" +} diff --git a/tests/bugs/modalg_7/bug30880_2 b/tests/bugs/modalg_7/bug30880_2 new file mode 100644 index 0000000000..c75dcb0b48 --- /dev/null +++ b/tests/bugs/modalg_7/bug30880_2 @@ -0,0 +1,10 @@ +puts "========" +puts "0030880: Bug in BRepExtrema_ExtCF" +puts "========" +puts "" + +restore [locate_data_file bug30880_face.brep] f +point p2d -0.0034857302428251678 0.016350559703980902 +if {![regexp "OUT" [b2dclassifx f p2d -tol 1.e-7]]} { + puts "Error: Incorrect classification of the point" +}