mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-26 10:19:45 +03:00
0023777: 2D-Classifier algorithm produces wrong results for a point and face.
Adding test case for this fix
This commit is contained in:
parent
e187cc0ac0
commit
8f9a9b9d10
@ -40,6 +40,12 @@
|
|||||||
#include <IntRes2d_Transition.hxx>
|
#include <IntRes2d_Transition.hxx>
|
||||||
#include <IntRes2d_IntersectionPoint.hxx>
|
#include <IntRes2d_IntersectionPoint.hxx>
|
||||||
|
|
||||||
|
static
|
||||||
|
void RefineTolerance(const TopoDS_Face& aF,
|
||||||
|
const BRepAdaptor_Curve2d& aC,
|
||||||
|
const Standard_Real aT,
|
||||||
|
Standard_Real& aTolZ);
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : BRepClass_Intersector
|
//function : BRepClass_Intersector
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -53,91 +59,86 @@ BRepClass_Intersector::BRepClass_Intersector()
|
|||||||
//function : Perform
|
//function : Perform
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void BRepClass_Intersector::Perform(const gp_Lin2d& L,
|
void BRepClass_Intersector::Perform(const gp_Lin2d& L,
|
||||||
const Standard_Real P,
|
const Standard_Real P,
|
||||||
const Standard_Real Tol,
|
const Standard_Real Tol,
|
||||||
const BRepClass_Edge& E)
|
const BRepClass_Edge& E)
|
||||||
{
|
{
|
||||||
|
Standard_Real deb, fin, aTolZ;
|
||||||
Standard_Real pfbid,plbid;
|
Handle(Geom2d_Curve) aC2D;
|
||||||
if (BRep_Tool::CurveOnSurface(E.Edge(),E.Face(),pfbid,plbid).IsNull()) {
|
//
|
||||||
done = Standard_False; // !IsDone()
|
aTolZ=Tol;
|
||||||
}
|
|
||||||
else {
|
|
||||||
IntRes2d_Domain DL;
|
|
||||||
if(P!=RealLast())
|
|
||||||
DL.SetValues(L.Location(),0.,Tol,ElCLib::Value(P,L),P,Tol);
|
|
||||||
else
|
|
||||||
DL.SetValues(L.Location(),0.,Tol,Standard_True);
|
|
||||||
|
|
||||||
const TopoDS_Edge& EE = E.Edge();
|
const TopoDS_Edge& EE = E.Edge();
|
||||||
const TopoDS_Face& F = E.Face();
|
const TopoDS_Face& F = E.Face();
|
||||||
TopoDS_Vertex Vdeb, Vfin;
|
//
|
||||||
TopExp::Vertices(EE, Vdeb, Vfin);
|
aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
|
||||||
|
if (aC2D.IsNull()) {
|
||||||
|
done = Standard_False; // !IsDone()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//
|
||||||
BRepAdaptor_Curve2d C(EE, F);
|
BRepAdaptor_Curve2d C(EE, F);
|
||||||
Standard_Real deb = C.FirstParameter(), fin = C.LastParameter();
|
//
|
||||||
|
deb = C.FirstParameter();
|
||||||
|
fin = C.LastParameter();
|
||||||
|
//
|
||||||
// Case of "ON": direct check of belonging to edge
|
// Case of "ON": direct check of belonging to edge
|
||||||
// taking into account the tolerance
|
// taking into account the tolerance
|
||||||
Extrema_ExtPC2d theExtPC2d(L.Location(), C);
|
Extrema_ExtPC2d theExtPC2d(L.Location(), C);
|
||||||
Standard_Real MinDist = RealLast(), aDist;
|
Standard_Real MinDist = RealLast(), aDist;
|
||||||
Standard_Integer MinInd = 0, i;
|
Standard_Integer MinInd = 0, i;
|
||||||
if (theExtPC2d.IsDone())
|
if (theExtPC2d.IsDone()) {
|
||||||
{
|
for (i = 1; i <= theExtPC2d.NbExt(); ++i) {
|
||||||
for (i = 1; i <= theExtPC2d.NbExt(); i++)
|
|
||||||
{
|
|
||||||
aDist = theExtPC2d.SquareDistance(i);
|
aDist = theExtPC2d.SquareDistance(i);
|
||||||
if (aDist < MinDist)
|
if (aDist < MinDist) {
|
||||||
{
|
|
||||||
MinDist = aDist;
|
MinDist = aDist;
|
||||||
MinInd = i;
|
MinInd = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MinInd)
|
if (MinInd) {
|
||||||
MinDist = sqrt(MinDist);
|
MinDist = sqrt(MinDist);
|
||||||
if (MinDist <= Tol)
|
}
|
||||||
{
|
if (MinDist <= aTolZ) {
|
||||||
gp_Pnt2d pnt_exact = (theExtPC2d.Point(MinInd)).Value();
|
gp_Pnt2d pnt_exact = (theExtPC2d.Point(MinInd)).Value();
|
||||||
Standard_Real par = (theExtPC2d.Point(MinInd)).Parameter();
|
Standard_Real par = (theExtPC2d.Point(MinInd)).Parameter();
|
||||||
|
//
|
||||||
|
RefineTolerance(F, C, par, aTolZ);
|
||||||
|
//
|
||||||
|
if (MinDist <= aTolZ) {
|
||||||
IntRes2d_Transition tr_on_lin(IntRes2d_Head);
|
IntRes2d_Transition tr_on_lin(IntRes2d_Head);
|
||||||
IntRes2d_Position pos_on_curve = IntRes2d_Middle;
|
IntRes2d_Position pos_on_curve = IntRes2d_Middle;
|
||||||
if (Abs(par - deb) <= Precision::Confusion())
|
if (Abs(par - deb) <= Precision::Confusion()) {
|
||||||
pos_on_curve = IntRes2d_Head;
|
pos_on_curve = IntRes2d_Head;
|
||||||
else if (Abs(par - fin) <= Precision::Confusion())
|
}
|
||||||
|
else if (Abs(par - fin) <= Precision::Confusion()) {
|
||||||
pos_on_curve = IntRes2d_End;
|
pos_on_curve = IntRes2d_End;
|
||||||
|
}
|
||||||
|
//
|
||||||
IntRes2d_Transition tr_on_curve(pos_on_curve);
|
IntRes2d_Transition tr_on_curve(pos_on_curve);
|
||||||
IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
|
IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
|
||||||
tr_on_lin, tr_on_curve, Standard_False);
|
tr_on_lin, tr_on_curve,
|
||||||
this->Append(pnt_inter);
|
Standard_False);
|
||||||
|
//
|
||||||
|
Append(pnt_inter);
|
||||||
done = Standard_True;
|
done = Standard_True;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
///////////////
|
}
|
||||||
|
//
|
||||||
gp_Pnt2d pdeb,pfin;
|
gp_Pnt2d pdeb,pfin;
|
||||||
C.D0(deb,pdeb);
|
C.D0(deb,pdeb);
|
||||||
C.D0(fin,pfin);
|
C.D0(fin,pfin);
|
||||||
Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
|
Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
|
||||||
#if 0
|
|
||||||
// essai de calcul juste des tolerances du domaine
|
IntRes2d_Domain DL;
|
||||||
// qui ne couche pas avec les modeles pourris de
|
//
|
||||||
// styler !!
|
if(P!=RealLast()) {
|
||||||
BRepAdaptor_Surface S(F);
|
DL.SetValues(L.Location(),0.,aTolZ,ElCLib::Value(P,L),P,aTolZ);
|
||||||
gp_Vec2d vdeb,vfin;
|
}
|
||||||
C.D1(deb,pdeb,vdeb);
|
else {
|
||||||
C.D1(fin,pfin,vfin);
|
DL.SetValues(L.Location(),0.,aTolZ,Standard_True);
|
||||||
gp_Pnt P; gp_Vec DU, DV;
|
}
|
||||||
S.D1(pdeb.X(),pdeb.Y(),P,DU,DV);
|
|
||||||
Standard_Real scaldeb = (vdeb.X()*DU + vdeb.Y()*DV).Magnitude();
|
|
||||||
scaldeb = Max(scaldeb, 1.e-5);
|
|
||||||
toldeb = BRep_Tool::Tolerance(Vdeb)/scaldeb;
|
|
||||||
S.D1(pfin.X(),pfin.Y(),P,DU,DV);
|
|
||||||
Standard_Real scalfin = (vfin.X()*DU + vfin.Y()*DV).Magnitude();
|
|
||||||
scalfin = Max(scalfin, 1.e-5);
|
|
||||||
tolfin = BRep_Tool::Tolerance(Vfin)/scalfin;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
|
IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
|
||||||
// temporary periodic domain
|
// temporary periodic domain
|
||||||
@ -153,15 +154,14 @@ void BRepClass_Intersector::Perform(const gp_Lin2d& L,
|
|||||||
Geom2dInt_GInter Inter(CGA,DL,C,DE,
|
Geom2dInt_GInter Inter(CGA,DL,C,DE,
|
||||||
Precision::PConfusion(),
|
Precision::PConfusion(),
|
||||||
Precision::PIntersection());
|
Precision::PIntersection());
|
||||||
this->SetValues(Inter);
|
//
|
||||||
}
|
SetValues(Inter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : LocalGeometry
|
//function : LocalGeometry
|
||||||
//purpose :
|
//purpose :
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
|
||||||
void BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E,
|
void BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E,
|
||||||
const Standard_Real U,
|
const Standard_Real U,
|
||||||
gp_Dir2d& Tang,
|
gp_Dir2d& Tang,
|
||||||
@ -179,7 +179,40 @@ void BRepClass_Intersector::LocalGeometry(const BRepClass_Edge& E,
|
|||||||
Norm.SetCoord(Tang.Y(),-Tang.X());
|
Norm.SetCoord(Tang.Y(),-Tang.X());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : RefineTolerance
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
void RefineTolerance(const TopoDS_Face& aF,
|
||||||
|
const BRepAdaptor_Curve2d& aC,
|
||||||
|
const Standard_Real aT,
|
||||||
|
Standard_Real& aTolZ)
|
||||||
|
{
|
||||||
|
GeomAbs_SurfaceType aTypeS;
|
||||||
|
//
|
||||||
|
BRepAdaptor_Surface aBAS(aF, Standard_False);
|
||||||
|
//
|
||||||
|
aTypeS=aBAS.GetType();
|
||||||
|
if (aTypeS==GeomAbs_Cylinder) {
|
||||||
|
Standard_Real aURes, aVRes, aTolX;
|
||||||
|
gp_Pnt2d aP2D;
|
||||||
|
gp_Vec2d aV2D;
|
||||||
|
//
|
||||||
|
aURes=aBAS.UResolution(aTolZ);
|
||||||
|
aVRes=aBAS.VResolution(aTolZ);
|
||||||
|
//
|
||||||
|
aC.D1(aT, aP2D, aV2D);
|
||||||
|
gp_Dir2d aD2D(aV2D);
|
||||||
|
//
|
||||||
|
aTolX=aURes*aD2D.Y()+aVRes*aD2D.X();
|
||||||
|
if (aTolX<0.) {
|
||||||
|
aTolX=-aTolX;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (aTolX<aTolZ) {
|
||||||
|
aTolZ=aTolX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
22
tests/bugs/modalg_5/bug23777
Executable file
22
tests/bugs/modalg_5/bug23777
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
puts "================"
|
||||||
|
puts "OCC23777"
|
||||||
|
puts "================"
|
||||||
|
puts ""
|
||||||
|
#######################################################################
|
||||||
|
# 2D-Classifier algorithm produces wrong results for a point and face.
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
set BugNumber OCC23777
|
||||||
|
|
||||||
|
restore [locate_data_file bug23777_b1.brep] b1
|
||||||
|
|
||||||
|
point p2D 0.062260538576946696 249583.00418413401
|
||||||
|
|
||||||
|
set info [b2dclassify b1 p2D]
|
||||||
|
set check [regexp "IN" $info]
|
||||||
|
|
||||||
|
if { ${check} == 1 } {
|
||||||
|
puts "OK ${BugNumber}"
|
||||||
|
} else {
|
||||||
|
puts "Faulty ${BugNumber}"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user