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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user