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

0031203: SENR-21-037 SenerAlgo_ProjectWire fails when projecting wire to face (691 and 720)

This commit is contained in:
ifv 2019-12-02 12:11:41 +03:00
parent 77676f1b6d
commit 52a5d7a61d

View File

@ -27,6 +27,7 @@
#include <Precision.hxx> #include <Precision.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Face.hxx> #include <TopoDS_Face.hxx>
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
static const Standard_Real Probing_Start = 0.123; static const Standard_Real Probing_Start = 0.123;
static const Standard_Real Probing_End = 0.7; static const Standard_Real Probing_End = 0.7;
@ -41,10 +42,11 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
myFace(F), myFace(F),
myCurEdgeInd(1), myCurEdgeInd(1),
myCurEdgePar(Probing_Start) myCurEdgePar(Probing_Start)
{ {
myFace.Orientation(TopAbs_FORWARD); myFace.Orientation(TopAbs_FORWARD);
} }
//======================================================================= //=======================================================================
//function : CheckPoint //function : CheckPoint
//purpose : //purpose :
@ -71,14 +73,14 @@ Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
Standard_Real aDistance = aCenterPnt.Distance(thePoint); Standard_Real aDistance = aCenterPnt.Distance(thePoint);
if (Precision::IsInfinite(aDistance)) if (Precision::IsInfinite(aDistance))
{ {
thePoint.SetCoord(anUMin - ( anUMax - anUMin ), thePoint.SetCoord (anUMin - (anUMax - anUMin ),
aVMin - ( aVMax - aVMin )); aVMin - (aVMax - aVMin ));
return Standard_False; return Standard_False;
} }
else else
{ {
Standard_Real anEpsilon = Epsilon(aDistance); Standard_Real anEpsilon = Epsilon(aDistance);
if (anEpsilon > Max(anUMax - anUMin, aVMax - aVMin)) if (anEpsilon > Max (anUMax - anUMin, aVMax - aVMin))
{ {
gp_Vec2d aLinVec(aCenterPnt, thePoint); gp_Vec2d aLinVec(aCenterPnt, thePoint);
gp_Dir2d aLinDir(aLinVec); gp_Dir2d aLinDir(aLinVec);
@ -124,7 +126,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
gp_Lin2d& L, gp_Lin2d& L,
Standard_Real& Par) Standard_Real& Par)
{ {
TopExp_Explorer anExpF(myFace,TopAbs_EDGE); TopExp_Explorer anExpF(myFace, TopAbs_EDGE);
Standard_Integer i; Standard_Integer i;
Standard_Real aFPar; Standard_Real aFPar;
Standard_Real aLPar; Standard_Real aLPar;
@ -151,13 +153,15 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
if (Precision::IsPositiveInfinite(aLPar)) { if (Precision::IsPositiveInfinite(aLPar)) {
aFPar = -1.; aFPar = -1.;
aLPar = 1.; aLPar = 1.;
} else { }
else {
aFPar = aLPar - 1.; aFPar = aLPar - 1.;
} }
} else if (Precision::IsPositiveInfinite(aLPar)) }
else if (Precision::IsPositiveInfinite(aLPar))
aLPar = aFPar + 1.; aLPar = aFPar + 1.;
for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) { for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) {
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar; aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
gp_Vec2d aTanVec; gp_Vec2d aTanVec;
@ -174,8 +178,10 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
aTanVec /= Sqrt(aTanMod); aTanVec /= Sqrt(aTanMod);
Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY()); Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
const Standard_Real SmallAngle = 0.001; const Standard_Real SmallAngle = 0.001;
Standard_Boolean isSmallAngle = Standard_False;
if (Abs(aSinA) < SmallAngle) if (Abs(aSinA) < SmallAngle)
{ {
isSmallAngle = Standard_True;
// The line from the input point P to the current point on edge // The line from the input point P to the current point on edge
// is tangent to the edge curve. This condition is bad for classification. // is tangent to the edge curve. This condition is bad for classification.
// Therefore try to go to another point in the hope that there will be // Therefore try to go to another point in the hope that there will be
@ -189,13 +195,47 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
// Check if ends of a curve lie on a line. // Check if ends of a curve lie on a line.
aC2d->D0(aFPar, aPOnC); aC2d->D0(aFPar, aPOnC);
Standard_Real aFDist = P.SquareDistance(aPOnC);
if (L.SquareDistance(aPOnC) > aTolParConf2) { if (L.SquareDistance(aPOnC) > aTolParConf2) {
aC2d->D0(aLPar, aPOnC); aC2d->D0(aLPar, aPOnC);
if (L.SquareDistance(aPOnC) > aTolParConf2) { if (L.SquareDistance(aPOnC) > aTolParConf2) {
myCurEdgePar += Probing_Step; Standard_Real aLDist = P.SquareDistance(aPOnC);
if (isSmallAngle)
{
//Try to find minimal distance between curve and line
Geom2dAPI_ProjectPointOnCurve aProj;
aProj.Init(P, aC2d, aFPar, aLPar);
if (aProj.NbPoints() > 0)
{
Standard_Real aMinDist = aProj.LowerDistance();
aMinDist *= aMinDist;
Standard_Real aTMin = aProj.LowerDistanceParameter();
if (aMinDist > aFDist)
{
aMinDist = aFDist;
aTMin = aFPar;
}
if (aMinDist > aLDist)
{
aMinDist = aLDist;
aTMin = aLPar;
}
if (aMinDist < Par)
{
Par = aMinDist;
if (Par < aTolParConf2)
{
continue;
}
aC2d->D1(aTMin, aPOnC, aTanVec);
aLinDir.SetXY(aTanVec.XY());
L = gp_Lin2d(P, aLinDir);
}
}
}
myCurEdgePar += Probing_Step;
if (myCurEdgePar >= Probing_End) { if (myCurEdgePar >= Probing_End) {
myCurEdgeInd++; myCurEdgeInd++;
myCurEdgePar = Probing_Start; myCurEdgePar = Probing_Start;
@ -217,7 +257,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
// nothing found, return an horizontal line // nothing found, return an horizontal line
Par = RealLast(); Par = RealLast();
L = gp_Lin2d(P,gp_Dir2d(1,0)); L = gp_Lin2d(P, gp_Dir2d(1, 0));
return Standard_False; return Standard_False;
} }