From: azv Date: Mon, 18 Jul 2016 12:51:23 +0000 (+0300) Subject: 0027677: Incorrect CUT of a solid by semi-infinite solid X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=239550fbeddfd116801f0fdd5fa2ae3ad681a626;p=occt-copy.git 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 --- diff --git a/src/ProjLib/ProjLib_Cylinder.cxx b/src/ProjLib/ProjLib_Cylinder.cxx index e8f3cae7d7..c67701e438 100644 --- a/src/ProjLib/ProjLib_Cylinder.cxx +++ b/src/ProjLib/ProjLib_Cylinder.cxx @@ -129,6 +129,12 @@ static gp_Pnt2d EvalPnt2d( const gp_Pnt& P, const gp_Cylinder& Cy ) 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; 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) { + // 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; - gp_Dir ZCyl = myCylinder.Position().XDirection().Crossed - (myCylinder.Position().YDirection()); - gp_Dir ZCir = C.Position().XDirection().Crossed - (C.Position().YDirection()); + gp_Dir ZCyl = aCylPos.XDirection().Crossed(aCylPos.YDirection()); - Standard_Real U = myCylinder.Position().XDirection() - .AngleWithRef(C.Position().XDirection(), ZCyl); + Standard_Real U = aCylPos.XDirection().AngleWithRef(aCircPos.XDirection(), ZCyl); 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_Dir2d D2d; - if ( ZCyl.Dot(ZCir) > 0.) + if ( ZCyl.Dot(aCircPos.Direction()) > 0.) D2d.SetCoord(1., 0.); else D2d.SetCoord(-1., 0.); diff --git a/src/ProjLib/ProjLib_ProjectedCurve.cxx b/src/ProjLib/ProjLib_ProjectedCurve.cxx index 625766b69a..f35ad02cbc 100644 --- a/src/ProjLib/ProjLib_ProjectedCurve.cxx +++ b/src/ProjLib/ProjLib_ProjectedCurve.cxx @@ -606,6 +606,8 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) { // Use advanced analytical projector if base analytical projection failed. ProjLib_ComputeApprox Comp( myCurve, mySurface, myTolerance); + if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull()) + return; // advanced projector has been failed too myResult.Done(); // set the type