1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0029606: [Regression vs 7.0] BRepClass3d_SolidClassifier classifies the point as IN while it is ON

Simple treatment of some analytical cases when curve is parallel or belongs surface is added in curve - face/surface intersection algorithm
Treatment such cases is added in classifier algorithm
Test case added
This commit is contained in:
ifv
2018-03-28 17:00:50 +03:00
committed by bugmaster
parent d051064495
commit f84edf5816
8 changed files with 185 additions and 82 deletions

View File

@@ -33,6 +33,8 @@
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopExp.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <Extrema_ExtPS.hxx>
#include <vector>
@@ -338,87 +340,136 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer,
{
if(SolidExplorer.RejectShell(L) == Standard_False)
{
for(SolidExplorer.InitFace();
SolidExplorer.MoreFace() && !isFaultyLine;
SolidExplorer.NextFace())
for (SolidExplorer.InitFace();
SolidExplorer.MoreFace() && !isFaultyLine;
SolidExplorer.NextFace())
{
if(SolidExplorer.RejectFace(L) == Standard_False)
if (SolidExplorer.RejectFace(L) == Standard_False)
{
TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
TopoDS_Face f = TopoDS::Face(aLocalShape);
IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
// Prolong segment, since there are cases when
// the intersector does not find intersection points with the original
// segment due to rough triangulation of a parameterized surface.
Standard_Real addW = Max(10 * Tol, 0.01*Par);
Standard_Real AddW = addW;
Bnd_Box aBoxF = Intersector3d.Bounding();
// The box must be finite in order to correctly prolong the segment to its bounds.
if (!aBoxF.IsVoid() && !aBoxF.IsWhole())
{
TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
TopoDS_Face f = TopoDS::Face(aLocalShape);
IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
// Prolong segment, since there are cases when
// the intersector does not find intersection points with the original
// segment due to rough triangulation of a parameterized surface.
Standard_Real addW = Max(10*Tol, 0.01*Par);
Standard_Real AddW = addW;
Bnd_Box aBoxF = Intersector3d.Bounding();
// The box must be finite in order to correctly prolong the segment to its bounds.
if (!aBoxF.IsVoid() && !aBoxF.IsWhole())
{
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF);
addW = Max(addW,boxaddW);
}
Standard_Real minW = -AddW;
Standard_Real maxW = Min(Par*10,Par+addW);
Intersector3d.Perform(L,minW,maxW);
if(Intersector3d.IsDone())
{
for (Standard_Integer i = 1; i <= Intersector3d.NbPnt(); i++)
{
if(Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion())
{
parmin = Intersector3d.WParameter(i);
TopAbs_State aState = Intersector3d.State(i);
if(Abs(parmin)<=Tol)
{
myState = 2;
myFace = f;
}
// Treatment of case TopAbs_ON separately.
else if(aState==TopAbs_IN)
{
//-- The intersection point between the line and a face F
// -- of the solid is in the face F
IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
if (tran == IntCurveSurface_Tangent)
{
#ifdef OCCT_DEBUG
cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
#endif
continue; // ignore this point
}
Trans(parmin, tran, myState);
myFace = f;
}
// If the state is TopAbs_ON, it is necessary to chose
// another line and to repeat the whole procedure.
else if(aState==TopAbs_ON)
{
isFaultyLine = Standard_True;
break;
}
}
else
{
//-- No point has been found by the Intersector3d.
//-- Or a Point has been found with a greater parameter.
}
} //-- loop by intersection points
} //-- Face has not been rejected
else
myState = 1;
Standard_Real boxaddW = GetAddToParam(L, Par, aBoxF);
addW = Max(addW, boxaddW);
}
} //-- Exploration of the faces
Standard_Real minW = -AddW;
Standard_Real maxW = Min(Par * 10, Par + addW);
Intersector3d.Perform(L, minW, maxW);
if (Intersector3d.IsDone())
{
if (Intersector3d.NbPnt() == 0)
{
if (Intersector3d.IsParallel())
{
//Check distance between surface and point
BRepAdaptor_Surface aBAS(f, Standard_False);
Extrema_ExtPS aProj(P, aBAS, Precision::PConfusion(), Precision::PConfusion());
if (aProj.IsDone() && aProj.NbExt() > 0)
{
Standard_Integer i, indmin = 0;
Standard_Real d = RealLast();
for (i = 1; i <= aProj.NbExt(); ++i)
{
if (aProj.SquareDistance(i) < d)
{
d = aProj.SquareDistance(i);
indmin = i;
}
}
if (indmin > 0)
{
if (d <= Tol * Tol)
{
const Extrema_POnSurf& aPonS = aProj.Point(indmin);
Standard_Real anU, anV;
aPonS.Parameter(anU, anV);
gp_Pnt2d aP2d(anU, anV);
TopAbs_State aSt = Intersector3d.ClassifyUVPoint(aP2d);
if (aSt == TopAbs_IN || aSt == TopAbs_ON)
{
myState = 2;
myFace = f;
parmin = 0.;
break;
}
}
}
}
}
}
for (Standard_Integer i = 1; i <= Intersector3d.NbPnt(); i++)
{
if (Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion())
{
parmin = Intersector3d.WParameter(i);
TopAbs_State aState = Intersector3d.State(i);
if (Abs(parmin) <= Tol)
{
myState = 2;
myFace = f;
break;
}
// Treatment of case TopAbs_ON separately.
else if (aState == TopAbs_IN)
{
//-- The intersection point between the line and a face F
// -- of the solid is in the face F
IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
if (tran == IntCurveSurface_Tangent)
{
#ifdef OCCT_DEBUG
cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
#endif
continue; // ignore this point
}
Trans(parmin, tran, myState);
myFace = f;
}
// If the state is TopAbs_ON, it is necessary to chose
// another line and to repeat the whole procedure.
else if (aState == TopAbs_ON)
{
isFaultyLine = Standard_True;
break;
}
}
else
{
//-- No point has been found by the Intersector3d.
//-- Or a Point has been found with a greater parameter.
}
} //-- loop by intersection points
if (myState == 2)
{
break;
}
} //-- Face has not been rejected
else
myState = 1;
}
}//-- Exploration of the faces
if (myState == 2)
{
break;
}
} //-- Shell has not been rejected
else
myState = 1;