From c58b30780a470cbefd301479df3b85afa0382ec1 Mon Sep 17 00:00:00 2001 From: msv Date: Wed, 21 Sep 2016 11:02:25 +0300 Subject: [PATCH] 0027888: Fuse of valid untouched solids leads to result with faulties Incorrect result of classification of a point relatively a solid leads to faulty interferences between vertices/edges of one solid with another one. Classification has been corrected by checking if an auxiliary point in face coincides with the face boundary in 3D space. Test case has been created. --- src/BRepClass3d/BRepClass3d_SolidExplorer.cxx | 37 +++++++++++++++---- src/BRepClass3d/BRepClass3d_SolidExplorer.hxx | 10 ++--- tests/bugs/modalg_6/bug27888 | 14 +++++++ 3 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 tests/bugs/modalg_6/bug27888 diff --git a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx index 1d81f31177..06802dbf44 100644 --- a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx +++ b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx @@ -225,6 +225,29 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace U1, V1, U2, V2, aVecD1U, aVecD1V); } +//======================================================================= +//function : ClassifyUVPoint +//purpose : +//======================================================================= + +TopAbs_State BRepClass3d_SolidExplorer::ClassifyUVPoint + (const IntCurvesFace_Intersector& theIntersector, + const Handle(BRepAdaptor_HSurface)& theSurf, + const gp_Pnt2d& theP2d) const +{ + // first find if the point is near an edge/vertex + gp_Pnt aP3d = theSurf->Value(theP2d.X(), theP2d.Y()); + BRepClass3d_BndBoxTreeSelectorPoint aSelectorPoint(myMapEV); + aSelectorPoint.SetCurrentPoint(aP3d); + Standard_Integer aSelsVE = myTree.Select(aSelectorPoint); + if (aSelsVE > 0) + { + // The point is inside the tolerance area of vertices/edges => return ON state. + return TopAbs_ON; + } + return theIntersector.ClassifyUVPoint(theP2d); +} + //======================================================================= //function : PointInTheFace //purpose : @@ -264,7 +287,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace if(ptr) { const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr)); // Check if the point is already in the face - if(IsInside && (TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN)) { + if (IsInside && (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u_, v_)) == TopAbs_IN)) { gp_Pnt aPnt; surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V); if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion()) @@ -280,7 +303,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace for(u=du+(U1+U2)*0.5; u=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; @@ -293,7 +316,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases if(++NbPntCalc>=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; @@ -305,7 +328,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases for(v=dv+(V1+V2)*0.5; v=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; @@ -317,7 +340,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace for(u=du+(U1+U2)*0.5; uV1; v-=dv) { //-- 0 X v decreases if(++NbPntCalc>=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; @@ -335,7 +358,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace for(u=du+U1; u=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; @@ -347,7 +370,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace u=(U1+U2)*0.5; v=(V1+V2)*0.5; if(++NbPntCalc>=IndexPoint) { - if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { + if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) { u_=u; v_=v; surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); IndexPoint = NbPntCalc; diff --git a/src/BRepClass3d/BRepClass3d_SolidExplorer.hxx b/src/BRepClass3d/BRepClass3d_SolidExplorer.hxx index 83aa746f74..834e7f0a0d 100644 --- a/src/BRepClass3d/BRepClass3d_SolidExplorer.hxx +++ b/src/BRepClass3d/BRepClass3d_SolidExplorer.hxx @@ -152,14 +152,12 @@ public: Standard_EXPORT void Destroy(); - - - protected: - - - + Standard_EXPORT TopAbs_State ClassifyUVPoint + (const IntCurvesFace_Intersector& theIntersector, + const Handle(BRepAdaptor_HSurface)& theSurf, + const gp_Pnt2d& theP2d) const; private: diff --git a/tests/bugs/modalg_6/bug27888 b/tests/bugs/modalg_6/bug27888 new file mode 100644 index 0000000000..d013661c95 --- /dev/null +++ b/tests/bugs/modalg_6/bug27888 @@ -0,0 +1,14 @@ +puts "============" +puts "OCC27888" +puts "============" +puts "" +###################################################### +# Fuse of valid untouched solids leads to result with faulties +###################################################### + +binrestore [locate_data_file bug27888_cut_2_4.bin] a +explode a +bfuse r a_1 a_2 +checkshape r +checknbshapes r -solid 26 +checkprops r -v 1.85614e+006