1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +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;

View File

@ -1252,9 +1252,11 @@ void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
if(intana_ConicQuad.IsDone()) {
if(intana_ConicQuad.IsInQuadric()) {
//-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
myIsParallel = Standard_True;
}
else if(intana_ConicQuad.IsParallel()) {
//-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
myIsParallel = Standard_True;
}
else {
Standard_Integer nbp = intana_ConicQuad.NbPoints();

View File

@ -25,11 +25,19 @@
#define PARAMEQUAL(a,b) (Abs((a)-(b))< (1e-8))
//================================================================================
IntCurveSurface_Intersection::IntCurveSurface_Intersection(): done(Standard_False) {
IntCurveSurface_Intersection::IntCurveSurface_Intersection():
done(Standard_False),
myIsParallel(Standard_False)
{
}
//================================================================================
Standard_Boolean IntCurveSurface_Intersection::IsDone() const { return(done); }
//================================================================================
Standard_Boolean IntCurveSurface_Intersection::IsParallel() const
{
return(myIsParallel);
}
//================================================================================
Standard_Integer IntCurveSurface_Intersection::NbPoints() const {
if (!done) {throw StdFail_NotDone();}
return lpnt.Length();
@ -116,6 +124,7 @@ void IntCurveSurface_Intersection::ResetFields() {
lseg.Clear();
lpnt.Clear();
done=Standard_False;
myIsParallel = Standard_False;
}
}
//================================================================================

View File

@ -64,7 +64,12 @@ public:
//! the computation has not been done
//! raises OutOfRange if Index is not in the range <1..NbSegment>
Standard_EXPORT const IntCurveSurface_IntersectionSegment& Segment (const Standard_Integer Index) const;
//! Returns true if curve is parallel or belongs surface
//! This case is recognized only for some pairs
//! of analytical curves and surfaces (plane - line, ...)
Standard_EXPORT Standard_Boolean IsParallel() const;
//! Dump all the fields.
Standard_EXPORT void Dump() const;
@ -101,6 +106,9 @@ protected:
Standard_Boolean done;
Standard_Boolean myIsParallel; //Curve is "parallel" surface
//This case is recognized only for some pairs
//of analytical curves and surfaces (plane - line, ...)
private:

View File

@ -135,7 +135,8 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
nbpnt(0),
PtrOnPolyhedron(NULL),
PtrOnBndBounding(NULL),
myUseBoundTol (UseBToler)
myUseBoundTol (UseBToler),
myIsParallel(Standard_False)
{
BRepAdaptor_Surface surface;
face = Face;
@ -336,6 +337,10 @@ void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS,
} //-- classifier state is IN or ON
} //-- Loop on Intersection points.
} //-- HICS.IsDone()
else if (HICS.IsDone())
{
myIsParallel = HICS.IsParallel();
}
}
//=======================================================================
//function : Perform

View File

@ -113,7 +113,12 @@ public:
//! or TopAbs_ON
//! ( the point is on a boudary of the face).
TopAbs_State State (const Standard_Integer I) const;
//! Returns true if curve is parallel or belongs face surface
//! This case is recognized only for some pairs
//! of analytical curves and surfaces (plane - line, ...)
Standard_Boolean IsParallel() const;
//! Returns the significant face used to determine
//! the intersection.
const TopoDS_Face& Face() const;
@ -160,6 +165,9 @@ private:
Standard_Address PtrOnPolyhedron;
Standard_Address PtrOnBndBounding;
Standard_Boolean myUseBoundTol;
Standard_Boolean myIsParallel; //Curve is "parallel" face surface
//This case is recognized only for some pairs
//of analytical curves and surfaces (plane - line, ...)
};

View File

@ -58,7 +58,10 @@ inline TopAbs_State IntCurvesFace_Intersector::State(const Standard_Integer i) c
}
// Modified by skv - Wed Sep 3 15:34:20 2003 OCC578 End
//============================================================================
inline const TopoDS_Face& IntCurvesFace_Intersector::Face() const {
inline Standard_Boolean IntCurvesFace_Intersector::IsParallel() const {
return myIsParallel;
}
inline const TopoDS_Face& IntCurvesFace_Intersector::Face() const {
return(face);
}
//============================================================================

View File

@ -0,0 +1,17 @@
puts "========"
puts "OCC29606"
puts "========"
puts ""
#######################################################
#0029606: [Regression vs 7.0] BRepClass3d_SolidClassifier
#classifies the point as IN while it is ON
#######################################################
restore [locate_data_file bug29606.brep] s
point p1 621.05410336809734 47.416378469999998 111.25010709375
if {![regexp "The point is ON" [bclassify s p1]]} {
puts "Error: The Solid classification algorithm fails to classify the point"
}