1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00

0023043: Wrong results of BRepExtrema_DistShapeShape: non-null minimum distance between intersecting line and cylinder

This commit is contained in:
jgv 2012-04-06 14:25:44 +04:00
parent 10d41e29b3
commit f34cd0d18a

View File

@ -30,6 +30,8 @@
#include <ElSLib.hxx> #include <ElSLib.hxx>
#include <ElCLib.hxx> #include <ElCLib.hxx>
#include <gp_Vec.hxx> #include <gp_Vec.hxx>
#include <IntAna_Quadric.hxx>
#include <IntAna_IntConicQuad.hxx>
Extrema_ExtElCS::Extrema_ExtElCS() Extrema_ExtElCS::Extrema_ExtElCS()
@ -82,51 +84,55 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
myIsPar = Standard_False; myIsPar = Standard_False;
gp_Ax3 Pos = S.Position(); gp_Ax3 Pos = S.Position();
#ifdef DEB gp_Pnt Origin = Pos.Location();
gp_Pnt O = Pos.Location(); gp_Pnt LineOrig = C.Location();
#else
Pos.Location();
#endif
Standard_Real radius = S.Radius(); Standard_Real radius = S.Radius();
Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular()); Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
if (Extrem.IsParallel()) { if (Extrem.IsParallel()) {
mySqDist = new TColStd_HArray1OfReal(1, 1); mySqDist = new TColStd_HArray1OfReal(1, 1);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
Standard_Real aDist = sqrt(Extrem.SquareDistance(1)) - radius; Standard_Real aDist = sqrt(Extrem.SquareDistance(1)) - radius;
mySqDist->SetValue(1, aDist * aDist); mySqDist->SetValue(1, aDist * aDist);
Standard_Real u, v, w;
gp_Vec aVec(LineOrig, Origin);
gp_Vec aDirVec(C.Direction());
w = aVec*aDirVec;
gp_Pnt LinPoint = LineOrig.Translated(w * aDirVec);
Extrema_POnCurv PonC(w, LinPoint);
myPoint1->SetValue(1, PonC);
gp_Pnt CylPoint;
gp_Vec OrigToLine(Origin, LinPoint);
if (OrigToLine.Magnitude() <= gp::Resolution())
{
u = 0.;
v = 0.;
CylPoint = ElSLib::Value(u, v, S);
}
else
{
OrigToLine.Normalize();
CylPoint = Origin.Translated(radius * OrigToLine);
ElSLib::CylinderParameters(Pos, radius, CylPoint, u, v);
}
Extrema_POnSurf PonS(u, v, CylPoint);
myPoint2->SetValue(1, PonS);
myDone = Standard_True; myDone = Standard_True;
myIsPar = Standard_True; myIsPar = Standard_True;
} }
else { else {
Standard_Integer i; Standard_Integer i;
if (Extrem.IsDone()) {
Extrema_POnCurv myPOnC1, myPOnC2; Extrema_POnCurv myPOnC1, myPOnC2;
Extrem.Points(1, myPOnC1, myPOnC2); Extrem.Points(1, myPOnC1, myPOnC2);
gp_Pnt PonAxis = myPOnC1.Value();
gp_Pnt PC = myPOnC2.Value(); gp_Pnt PC = myPOnC2.Value();
if ((gp_Lin(Pos.Axis())).Contains(PC, Precision::Confusion())) { // line is tangent or outside of the cylunder -- single solution
gp_Dir D = C.Direction(); if (radius - PonAxis.Distance(PC) < Precision::PConfusion())
gp_Vec Dp(-D.Dot(Pos.YDirection()), D.Dot(Pos.XDirection()), 0.0); {
Standard_Real U, V; Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
gp_Pnt P1(PC.Translated(radius*Dp));
gp_Pnt P2(PC.Translated(-radius*Dp));
myNbExt = 2;
mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
ElSLib::CylinderParameters(Pos, radius, P1, U, V);
Extrema_POnSurf P1S(U, V, P1);
ElSLib::CylinderParameters(Pos, radius, P2, U, V);
Extrema_POnSurf P2S(U, V, P2);
mySqDist->SetValue(1, PC.SquareDistance(P1));
mySqDist->SetValue(2, PC.SquareDistance(P2));
myPoint1->SetValue(1, myPOnC2);
myPoint1->SetValue(2, myPOnC2);
myPoint2->SetValue(1, P1S);
myPoint2->SetValue(2, P2S);
}
else {
Extrema_ExtPElS ExPS(myPOnC2.Value(), S, Precision::Confusion());
if (ExPS.IsDone()) { if (ExPS.IsDone()) {
myNbExt = ExPS.NbExt(); myNbExt = ExPS.NbExt();
mySqDist = new TColStd_HArray1OfReal(1, myNbExt); mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
@ -139,9 +145,36 @@ void Extrema_ExtElCS::Perform(const gp_Lin& C,
} }
} }
} }
myDone = Standard_True; // line intersects the cylinder
else
{
IntAna_Quadric theQuadric(S);
IntAna_IntConicQuad Inters(C, theQuadric);
if (Inters.IsDone())
{
myNbExt = Inters.NbPoints();
if (myNbExt > 0)
{
mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
Standard_Real u, v, w;
for (i = 1; i <= myNbExt; i++)
{
mySqDist->SetValue(i, 0.);
gp_Pnt P_int = Inters.Point(i);
w = Inters.ParamOnConic(i);
Extrema_POnCurv PonC(w, P_int);
myPoint1->SetValue(i, PonC);
ElSLib::CylinderParameters(Pos, radius, P_int, u, v);
Extrema_POnSurf PonS(u, v, P_int);
myPoint2->SetValue(i, PonS);
} }
} }
}
}
myDone = Standard_True;
}
} }