mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
[Salome issue 45822] Pipe feature errors
This commit is contained in:
@@ -646,6 +646,15 @@ void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
|
||||
Precision::Confusion(),
|
||||
theUt11,
|
||||
theUt12);
|
||||
// if (!ExtPCir.IsDone())
|
||||
// {
|
||||
// // The point is in the center of the circle => there are infinite solutions
|
||||
// ClearSolutions();
|
||||
// const Standard_Real aRadius = Extrema_CurveTool::Circle(*myC[0]).Radius();
|
||||
// mySqDist.Append(aRadius * aRadius);
|
||||
// myIsParallel = Standard_True;
|
||||
// break;
|
||||
// }
|
||||
if (ExtPCir.NbExt() < 1)
|
||||
{
|
||||
continue;
|
||||
@@ -702,6 +711,15 @@ void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
|
||||
Precision::Confusion(),
|
||||
theUt11,
|
||||
theUt12);
|
||||
// if (!ExtPCir.IsDone())
|
||||
// {
|
||||
// // The point is in the center of the circle => there are infinite solutions
|
||||
// ClearSolutions();
|
||||
// const Standard_Real aRadius = Extrema_CurveTool::Circle(*myC[0]).Radius();
|
||||
// mySqDist.Append(aRadius * aRadius);
|
||||
// myIsParallel = Standard_True;
|
||||
// break;
|
||||
// }
|
||||
|
||||
Standard_Boolean isFound = !myIsParallel;
|
||||
|
||||
@@ -809,13 +827,13 @@ void Extrema_ExtCC::PrepareResults(const Extrema_ExtElC& AlgExt,
|
||||
if (myDone)
|
||||
{
|
||||
myIsParallel = AlgExt.IsParallel();
|
||||
if (myIsParallel)
|
||||
NbExt = AlgExt.NbExt();
|
||||
if (myIsParallel && NbExt == 0)
|
||||
{
|
||||
PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
|
||||
}
|
||||
else
|
||||
{
|
||||
NbExt = AlgExt.NbExt();
|
||||
for (i = 1; i <= NbExt; i++)
|
||||
{
|
||||
// Verification de la validite des parametres
|
||||
@@ -833,11 +851,25 @@ void Extrema_ExtCC::PrepareResults(const Extrema_ExtElC& AlgExt,
|
||||
|
||||
if (Extrema_CurveTool::IsPeriodic(*myC[0]))
|
||||
{
|
||||
U = ElCLib::InPeriod(U, Ut11, Ut11 + Extrema_CurveTool::Period(*myC[0]));
|
||||
if (Abs(U - Ut11) < Precision::Confusion())
|
||||
{
|
||||
U = Ut11;
|
||||
}
|
||||
else
|
||||
{
|
||||
U = ElCLib::InPeriod(U, Ut11, Ut11 + Extrema_CurveTool::Period(*myC[0]));
|
||||
}
|
||||
}
|
||||
if (Extrema_CurveTool::IsPeriodic(*myC[1]))
|
||||
{
|
||||
U2 = ElCLib::InPeriod(U2, Ut21, Ut21 + Extrema_CurveTool::Period(*myC[1]));
|
||||
if (Abs(U2 - Ut21) < Precision::Confusion())
|
||||
{
|
||||
U2 = Ut21;
|
||||
}
|
||||
else
|
||||
{
|
||||
U2 = ElCLib::InPeriod(U2, Ut21, Ut21 + Extrema_CurveTool::Period(*myC[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if ((U >= Ut11 - RealEpsilon()) && (U <= Ut12 + RealEpsilon())
|
||||
|
@@ -436,6 +436,137 @@ Standard_Boolean Extrema_ExtElC::PlanarLineCircleExtrema(const gp_Lin& theLin,
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_Boolean Extrema_ExtElC::PerpendicularCirclesExtrema(const gp_Circ& C1,
|
||||
const gp_Circ& C2,
|
||||
const gp_Pln& aPlc1,
|
||||
const gp_Pln& aPlc2,
|
||||
const Standard_Real aTolD,
|
||||
const Standard_Real angPlanes)
|
||||
{
|
||||
if (angPlanes <= M_PI_4)
|
||||
{
|
||||
return Standard_False; // The planes are more "parallel" than "perpendicular"
|
||||
}
|
||||
|
||||
Standard_Real aTolD2 = aTolD * aTolD;
|
||||
gp_Pnt aPc1 = C1.Location();
|
||||
gp_Pnt aPc2 = C2.Location();
|
||||
Standard_Real aD1 = aPlc2.SquareDistance(aPc1);
|
||||
if (aD1 < aTolD2)
|
||||
{
|
||||
// The center of the first circle is on the plane of the second circle,
|
||||
// and the center of the second circle is on the plane of the first circle.
|
||||
// => the intersection line of the two planes is along the connection of the circles' centers.
|
||||
// Compute the number of extremes based on the distance between the centers of the circles.
|
||||
Standard_Real aDist = aPc1.Distance(aPc2);
|
||||
Standard_Real aMinR = Min(C1.Radius(), C2.Radius());
|
||||
Standard_Real aMaxR = Max(C1.Radius(), C2.Radius());
|
||||
if (aDist >= aMaxR + aMinR - aTolD)
|
||||
{
|
||||
// The circles are either far apart or just touching.
|
||||
// There is one solution for the closest points on the circles.
|
||||
myNbExt = 1;
|
||||
gp_Vec aVec(aPc1, aPc2);
|
||||
aVec.Normalize();
|
||||
gp_Pnt aP1 = aPc1.Translated(aVec * C1.Radius());
|
||||
gp_Pnt aP2 = aPc2.Translated(-aVec * C2.Radius());
|
||||
aDist -= aMaxR + aMinR;
|
||||
mySqDist[0] = aDist * aDist;
|
||||
myPoint[0][0].SetValues(ElCLib::Parameter(C1, aP1), aP1);
|
||||
myPoint[0][1].SetValues(ElCLib::Parameter(C2, aP2), aP2);
|
||||
myIsPar = Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (Abs(aDist - aMaxR) < aTolD)
|
||||
{
|
||||
// The bigger circle is going through the center of the smaller circle.
|
||||
// There are infinite solutions on the small circle.
|
||||
myNbExt = 1;
|
||||
gp_Vec aVec(aPc1, aPc2);
|
||||
aVec.Normalize();
|
||||
gp_Pnt aP1 = aPc1.Translated(aVec * C1.Radius());
|
||||
gp_Pnt aP2 = aPc2.Translated(-aVec * C2.Radius());
|
||||
aDist = aMinR;
|
||||
mySqDist[0] = aDist * aDist;
|
||||
myPoint[0][0].SetValues(ElCLib::Parameter(C1, aP1), aP1);
|
||||
myPoint[0][1].SetValues(ElCLib::Parameter(C2, aP2), aP2);
|
||||
myIsPar = Standard_True; // indicator for infinite solutions
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (aDist <= aMaxR - aMinR + aTolD)
|
||||
{
|
||||
// The smaller circle is completely inside the bigger circle.
|
||||
// There is one solution for the closest points on the circles.
|
||||
myNbExt = 1;
|
||||
gp_Vec aVec(aPc1, aPc2);
|
||||
if (aVec.Magnitude() < aTolD)
|
||||
{
|
||||
// Both circle centers are coincident.
|
||||
aVec = aPlc1.Axis().Direction().Crossed(aPlc2.Axis().Direction());
|
||||
myNbExt++;
|
||||
}
|
||||
aVec.Normalize();
|
||||
if (C1.Radius() < C2.Radius())
|
||||
{
|
||||
aVec.Reverse();
|
||||
}
|
||||
gp_Pnt aP1 = aPc1.Translated(aVec * C1.Radius());
|
||||
gp_Pnt aP2 = aPc2.Translated(aVec * C2.Radius());
|
||||
Standard_Real aD = aMaxR - aDist - aMinR;
|
||||
mySqDist[0] = aD * aD;
|
||||
myPoint[0][0].SetValues(ElCLib::Parameter(C1, aP1), aP1);
|
||||
myPoint[0][1].SetValues(ElCLib::Parameter(C2, aP2), aP2);
|
||||
if (myNbExt > 1)
|
||||
{
|
||||
gp_Pnt aP3 = aPc1.Translated(-aVec * C1.Radius());
|
||||
gp_Pnt aP4 = aPc2.Translated(-aVec * C2.Radius());
|
||||
mySqDist[1] = mySqDist[0];
|
||||
myPoint[1][0].SetValues(ElCLib::Parameter(C1, aP3), aP3);
|
||||
myPoint[1][1].SetValues(ElCLib::Parameter(C2, aP4), aP4);
|
||||
}
|
||||
myIsPar = Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (aDist < aMaxR + aMinR - aTolD)
|
||||
{
|
||||
// The circles are intersecting.
|
||||
// There is one solution for the closest points on the circles.
|
||||
myNbExt = 1;
|
||||
gp_Vec aVec(aPc2, aPc1);
|
||||
if (aVec.Magnitude() < aMaxR)
|
||||
{
|
||||
// The center of the small circle is inside the big circle.
|
||||
aVec.Reverse();
|
||||
}
|
||||
aVec.Normalize();
|
||||
if (C1.Radius() < C2.Radius())
|
||||
{
|
||||
aVec.Reverse();
|
||||
}
|
||||
gp_Pnt aP1 = aPc1.Translated(aVec * C1.Radius());
|
||||
gp_Pnt aP2 = aPc2.Translated(aVec * C2.Radius());
|
||||
Standard_Real aD = (aMaxR + aMinR - aDist);
|
||||
mySqDist[0] = aD * aD;
|
||||
myPoint[0][0].SetValues(ElCLib::Parameter(C1, aP1), aP1);
|
||||
myPoint[0][1].SetValues(ElCLib::Parameter(C2, aP2), aP2);
|
||||
myIsPar = Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// std::cout << "====> Extrema_ExtElC: unsupported case for circles in different planes." << std::endl;
|
||||
// std::cout << " Distance between centers: " << aDist << std::endl;
|
||||
// std::cout << " Angle between planes ...: " << angPlanes * 180.0 / M_PI << " deg" << std::endl;
|
||||
// std::cout << " Radius Circle 1 ........: " << C1.Radius() << std::endl;
|
||||
// std::cout << " Radius Circle 2 ........: " << C2.Radius() << std::endl;
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function : Extrema_ExtElC
|
||||
// purpose :
|
||||
@@ -973,6 +1104,22 @@ Extrema_ExtElC::Extrema_ExtElC(const gp_Circ& C1, const gp_Circ& C2)
|
||||
bIsSamePlane = aDc1.IsParallel(aDc2, aTolA) && aD2 < aTolD2;
|
||||
if (!bIsSamePlane)
|
||||
{
|
||||
// Handle the specific case:
|
||||
// * where both planes are "almost perpendicular" (=> angle between planes > 45 deg)
|
||||
// * where the center of each circle is on the plane of the other circle
|
||||
// (=> the circle centers are on the intersection line of the two planes)
|
||||
const Standard_Real angPlanes = aDc1.Angle(aDc2);
|
||||
if (aD2 < aTolD2 && angPlanes > M_PI_4)
|
||||
{
|
||||
// The center of the second circle is on the plane of the first circle and
|
||||
// both planes are "almost perpendicular".
|
||||
gp_Pln aPlc2(aPc2, aDc2);
|
||||
if (PerpendicularCirclesExtrema(C1, C2, aPlc1, aPlc2, aTolD, angPlanes))
|
||||
{
|
||||
myDone = Standard_True;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@ class gp_Circ;
|
||||
class gp_Elips;
|
||||
class gp_Hypr;
|
||||
class gp_Parab;
|
||||
class gp_Pln;
|
||||
|
||||
//! It calculates all the distance between two elementary
|
||||
//! curves.
|
||||
@@ -85,7 +86,13 @@ public:
|
||||
protected:
|
||||
//! Computes extrema in case when considered line and circle are in one plane
|
||||
Standard_EXPORT Standard_Boolean PlanarLineCircleExtrema(const gp_Lin& C1, const gp_Circ& C2);
|
||||
|
||||
//! Computes extrema in case when two circles are in almost perpendicular planes
|
||||
//! and their centers are on the intersection line of these planes
|
||||
//! (angle between planes > 45 degrees)
|
||||
Standard_EXPORT Standard_Boolean PerpendicularCirclesExtrema(const gp_Circ& C1, const gp_Circ& C2,
|
||||
const gp_Pln& aPlc1, const gp_Pln& aPlc2,
|
||||
const Standard_Real aTolD,
|
||||
const Standard_Real angPlanes);
|
||||
private:
|
||||
Standard_Boolean myDone;
|
||||
Standard_Boolean myIsPar;
|
||||
|
Reference in New Issue
Block a user