From f24f542856ed0c021775b906e90ecadc857e1ce1 Mon Sep 17 00:00:00 2001 From: ifv Date: Fri, 3 Mar 2017 15:34:11 +0300 Subject: [PATCH] 0028490: Point located outside the solid is classified as inside New method for building surface polyhedron (class IntCurveSurface_Polyhedron), which takes in account intervals of discontinuity of surface is added for constructor IntCurvesFace_Intersector. Bug in methods NbU(V)Intervals and U(V)Intervals for Offset surfaces is fixed. --- src/GeomAdaptor/GeomAdaptor_Surface.cxx | 8 +- .../IntCurvesFace_Intersector.cxx | 98 ++++++++++++++++++- tests/bugs/modalg_6/bug28490_1 | 21 ++++ tests/bugs/modalg_6/bug28490_2 | 21 ++++ tests/bugs/step/bug24055 | 2 - 5 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 tests/bugs/modalg_6/bug28490_1 create mode 100644 tests/bugs/modalg_6/bug28490_2 diff --git a/src/GeomAdaptor/GeomAdaptor_Surface.cxx b/src/GeomAdaptor/GeomAdaptor_Surface.cxx index 24e054270b..04a7b35a6c 100644 --- a/src/GeomAdaptor/GeomAdaptor_Surface.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Surface.cxx @@ -353,7 +353,7 @@ Standard_Integer GeomAdaptor_Surface::NbUIntervals(const GeomAbs_Shape S) const case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); - GeomAdaptor_Surface Sur(myOffSurf->BasisSurface()); + GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); return Sur.NbUIntervals(BaseS); } case GeomAbs_Plane: @@ -406,7 +406,7 @@ Standard_Integer GeomAdaptor_Surface::NbVIntervals(const GeomAbs_Shape S) const case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); - GeomAdaptor_Surface Sur(myOffSurf->BasisSurface()); + GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); return Sur.NbVIntervals(BaseS); } case GeomAbs_Plane: @@ -465,7 +465,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); - GeomAdaptor_Surface Sur(myOffSurf->BasisSurface()); + GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); myNbUIntervals = Sur.NbUIntervals(BaseS); Sur.UIntervals(T, BaseS); } @@ -528,7 +528,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap case GeomAbs_CN: break; } Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface); - GeomAdaptor_Surface Sur(myOffSurf->BasisSurface()); + GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast); myNbVIntervals = Sur.NbVIntervals(BaseS); Sur.VIntervals(T, BaseS); } diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx index b43438ab3b..02417ea231 100644 --- a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx +++ b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx @@ -43,6 +43,75 @@ #include #include #include +// +static void ComputeSamplePars(const Handle(Adaptor3d_HSurface)& Hsurface, + const Standard_Integer nbsu, + const Standard_Integer nbsv, + Handle(TColStd_HArray1OfReal)& UPars, + Handle(TColStd_HArray1OfReal)& VPars) +{ + Standard_Integer NbUInts = Hsurface->NbUIntervals(GeomAbs_C2); + Standard_Integer NbVInts = Hsurface->NbVIntervals(GeomAbs_C2); + TColStd_Array1OfReal UInts(1, NbUInts + 1); + TColStd_Array1OfReal VInts(1, NbVInts + 1); + Hsurface->UIntervals(UInts, GeomAbs_C2); + Hsurface->VIntervals(VInts, GeomAbs_C2); + // + TColStd_Array1OfInteger NbUSubInts(1, NbUInts); + TColStd_Array1OfInteger NbVSubInts(1, NbVInts); + // + Standard_Integer i, j, ind, NbU, NbV; + Standard_Real t, dt; + t = UInts(NbUInts + 1) - UInts(1); + t = 1. / t; + NbU = 0; + for(i = 1; i <= NbUInts; ++i) + { + dt = (UInts(i+1) - UInts(i)); + NbUSubInts(i) = RealToInt(nbsu * dt * t) + 1; + NbU += NbUSubInts(i); + } + t = VInts(NbVInts + 1) - VInts(1); + t = 1. / t; + NbV = 0; + for(i = 1; i <= NbVInts; ++i) + { + dt = (VInts(i+1) - VInts(i)); + NbVSubInts(i) = RealToInt(nbsv * dt * t) + 1; + NbV += NbVSubInts(i); + } + UPars = new TColStd_HArray1OfReal(1, NbU + 1); + VPars = new TColStd_HArray1OfReal(1, NbV + 1); + // + ind = 1; + for(i = 1; i <= NbUInts; ++i) + { + UPars->SetValue(ind++, UInts(i)); + dt = (UInts(i+1) - UInts(i)) / NbUSubInts(i); + t = UInts(i); + for(j = 1; j < NbUSubInts(i); ++j) + { + t += dt; + UPars->SetValue(ind++, t); + } + } + UPars->SetValue(ind, UInts(NbUInts + 1)); + // + ind = 1; + for(i = 1; i <= NbVInts; ++i) + { + VPars->SetValue(ind++, VInts(i)); + dt = (VInts(i+1) - VInts(i)) / NbVSubInts(i); + t = VInts(i); + for(j = 1; j < NbVSubInts(i); ++j) + { + t += dt; + VPars->SetValue(ind++, t); + } + } + VPars->SetValue(ind, VInts(NbVInts + 1)); +} +// //======================================================================= //function : SurfaceType //purpose : @@ -86,24 +155,28 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, U1 = Hsurface->LastUParameter(); V0 = Hsurface->FirstVParameter(); V1 = Hsurface->LastVParameter(); - + // + nbsu = myTopolTool->NbSamplesU(); + nbsv = myTopolTool->NbSamplesV(); + // Standard_Real aURes = Hsurface->UResolution(1.0); Standard_Real aVRes = Hsurface->VResolution(1.0); // Checking correlation between number of samples and length of the face along each axis const Standard_Real aTresh = 100.0; - const Standard_Integer aMinSamples = 10; + Standard_Integer aMinSamples = 20; const Standard_Integer aMaxSamples = 40; const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples; Standard_Real dU = (U1 - U0) / aURes; Standard_Real dV = (V1 - V0) / aVRes; - nbsu = myTopolTool->NbSamplesU(); - nbsv = myTopolTool->NbSamplesV(); + if (nbsu < aMinSamples) nbsu = aMinSamples; + if (nbsv < aMinSamples) nbsv = aMinSamples; if (nbsu > aMaxSamples) nbsu = aMaxSamples; if (nbsv > aMaxSamples) nbsv = aMaxSamples; if (Max(dU, dV) > Min(dU, dV) * aTresh) { + aMinSamples = 10; nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples); if (nbsu < aMinSamples) nbsu = aMinSamples; nbsv = aMaxSamples2 / nbsu; @@ -113,8 +186,23 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, nbsu = aMaxSamples2 / aMinSamples; } } - PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) + + Standard_Integer NbUOnS = Hsurface->NbUIntervals(GeomAbs_C2); + Standard_Integer NbVOnS = Hsurface->NbVIntervals(GeomAbs_C2); + + if(NbUOnS > 1 || NbVOnS > 1) + { + Handle(TColStd_HArray1OfReal) UPars, VPars; + ComputeSamplePars(Hsurface, nbsu, nbsv, UPars, VPars); + PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) + new IntCurveSurface_ThePolyhedronOfHInter(Hsurface, UPars->ChangeArray1(), + VPars->ChangeArray1()); + } + else + { + PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1); + } } } //======================================================================= diff --git a/tests/bugs/modalg_6/bug28490_1 b/tests/bugs/modalg_6/bug28490_1 new file mode 100644 index 0000000000..c83c93b993 --- /dev/null +++ b/tests/bugs/modalg_6/bug28490_1 @@ -0,0 +1,21 @@ +puts "========" +puts "OCC28490" +puts "========" +puts "" +########################################################### +# Point located outside the solid is classified as inside +########################################################### + +restore [locate_data_file bug28490_solid_vertex1.brep] a +explode a +mkpoint p a_2 +set case_output [string trim [bclassify a_1 p]] + +if {$case_output != "The point is OUT of shape"} { + puts "ERROR: OCC28490 is reproduced. Point is classified as INNER." +} + +smallview +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_6/bug28490_2 b/tests/bugs/modalg_6/bug28490_2 new file mode 100644 index 0000000000..cb4e1190c1 --- /dev/null +++ b/tests/bugs/modalg_6/bug28490_2 @@ -0,0 +1,21 @@ +puts "========" +puts "OCC28490" +puts "========" +puts "" +########################################################### +# Point located outside the solid is classified as inside +########################################################### + +restore [locate_data_file bug28490_solid_vertex2.brep] a +explode a +mkpoint p a_2 +set case_output [string trim [bclassify a_1 p]] + +if {$case_output != "The point is OUT of shape"} { + puts "ERROR: OCC28490 is reproduced. Point is classified as INNER." +} + +smallview +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/step/bug24055 b/tests/bugs/step/bug24055 index 88a1105022..dda9296c02 100644 --- a/tests/bugs/step/bug24055 +++ b/tests/bugs/step/bug24055 @@ -1,5 +1,3 @@ -puts "TODO OCC25555 ALL: Faulty shapes in variables faulty_1 to faulty_" - puts "============" puts "OCC24055" puts "============"