mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-13 14:27:08 +03:00
0027677: Incorrect CUT of a solid by semi-infinite solid
The problem of incorrect CUT is wrong Pcurve after projection onto cylinder of a small edge orthogonal to cylinder's axis. The result of projection is a line along V direction, but it should be along U. ProjLib_Cylinder has no specific functionality to build projection in most common case, so it should return "not done" flag to start projection based on curve approximation. Following changes are done: 1. ProjLib_Cylinder returns isDone=false in the following cases: * the projected line is not parallel to cylinder's axis * the plane of projected circle is not orthogonal to cylinder's axis 2. Test case added
This commit is contained in:
@@ -129,6 +129,12 @@ static gp_Pnt2d EvalPnt2d( const gp_Pnt& P, const gp_Cylinder& Cy )
|
|||||||
|
|
||||||
void ProjLib_Cylinder::Project(const gp_Lin& L)
|
void ProjLib_Cylinder::Project(const gp_Lin& L)
|
||||||
{
|
{
|
||||||
|
// Check the line is parallel to the axis of cylinder.
|
||||||
|
// In other cases, the projection is wrong.
|
||||||
|
if (L.Direction().XYZ().CrossSquareMagnitude(myCylinder.Position().Direction().XYZ()) >
|
||||||
|
Precision::Angular() * Precision::Angular())
|
||||||
|
return;
|
||||||
|
|
||||||
myType = GeomAbs_Line;
|
myType = GeomAbs_Line;
|
||||||
|
|
||||||
gp_Pnt2d P2d = EvalPnt2d(L.Location(),myCylinder);
|
gp_Pnt2d P2d = EvalPnt2d(L.Location(),myCylinder);
|
||||||
@@ -152,23 +158,26 @@ void ProjLib_Cylinder::Project(const gp_Lin& L)
|
|||||||
|
|
||||||
void ProjLib_Cylinder::Project(const gp_Circ& C)
|
void ProjLib_Cylinder::Project(const gp_Circ& C)
|
||||||
{
|
{
|
||||||
|
// Check the circle's normal is parallel to the axis of cylinder.
|
||||||
|
// In other cases, the projection is wrong.
|
||||||
|
const gp_Ax3& aCylPos = myCylinder.Position();
|
||||||
|
const gp_Ax2& aCircPos = C.Position();
|
||||||
|
if (aCylPos.Direction().XYZ().CrossSquareMagnitude(aCircPos.Direction().XYZ()) >
|
||||||
|
Precision::Angular() * Precision::Angular())
|
||||||
|
return;
|
||||||
|
|
||||||
myType = GeomAbs_Line;
|
myType = GeomAbs_Line;
|
||||||
|
|
||||||
gp_Dir ZCyl = myCylinder.Position().XDirection().Crossed
|
gp_Dir ZCyl = aCylPos.XDirection().Crossed(aCylPos.YDirection());
|
||||||
(myCylinder.Position().YDirection());
|
|
||||||
gp_Dir ZCir = C.Position().XDirection().Crossed
|
|
||||||
(C.Position().YDirection());
|
|
||||||
|
|
||||||
Standard_Real U = myCylinder.Position().XDirection()
|
Standard_Real U = aCylPos.XDirection().AngleWithRef(aCircPos.XDirection(), ZCyl);
|
||||||
.AngleWithRef(C.Position().XDirection(), ZCyl);
|
|
||||||
|
|
||||||
gp_Vec OP( myCylinder.Location(),C.Location());
|
gp_Vec OP( myCylinder.Location(),C.Location());
|
||||||
Standard_Real V = OP.Dot(gp_Vec(myCylinder.Position().Direction()));
|
Standard_Real V = OP.Dot(gp_Vec(aCylPos.Direction()));
|
||||||
|
|
||||||
|
|
||||||
gp_Pnt2d P2d1 (U, V);
|
gp_Pnt2d P2d1 (U, V);
|
||||||
gp_Dir2d D2d;
|
gp_Dir2d D2d;
|
||||||
if ( ZCyl.Dot(ZCir) > 0.)
|
if ( ZCyl.Dot(aCircPos.Direction()) > 0.)
|
||||||
D2d.SetCoord(1., 0.);
|
D2d.SetCoord(1., 0.);
|
||||||
else
|
else
|
||||||
D2d.SetCoord(-1., 0.);
|
D2d.SetCoord(-1., 0.);
|
||||||
|
@@ -606,6 +606,8 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
|
|||||||
{
|
{
|
||||||
// Use advanced analytical projector if base analytical projection failed.
|
// Use advanced analytical projector if base analytical projection failed.
|
||||||
ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
|
ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance);
|
||||||
|
if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull())
|
||||||
|
return; // advanced projector has been failed too
|
||||||
myResult.Done();
|
myResult.Done();
|
||||||
|
|
||||||
// set the type
|
// set the type
|
||||||
|
Reference in New Issue
Block a user