diff --git a/src/ProjLib/ProjLib_Cylinder.cxx b/src/ProjLib/ProjLib_Cylinder.cxx index e3a37e980f..5c40eeac91 100644 --- a/src/ProjLib/ProjLib_Cylinder.cxx +++ b/src/ProjLib/ProjLib_Cylinder.cxx @@ -134,6 +134,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); @@ -157,23 +163,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 e78f04f9b8..8dd1817065 100644 --- a/src/ProjLib/ProjLib_ProjectedCurve.cxx +++ b/src/ProjLib/ProjLib_ProjectedCurve.cxx @@ -607,6 +607,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 diff --git a/tests/bugs/modalg_6/bug27677 b/tests/bugs/modalg_6/bug27677 new file mode 100644 index 0000000000..faa01cc91d --- /dev/null +++ b/tests/bugs/modalg_6/bug27677 @@ -0,0 +1,28 @@ +puts "================" +puts "OCC27677" +puts "================" +puts "" +####################################################################### +# Incorrect CUT of a solid by semi-infinite solid +####################################################################### + +restore [locate_data_file bug27677_solid_halfspace.brep] s +restore [locate_data_file bug27677_real_frame_shape.brep] f + +bop s f +boptuc result + +# Check result validity. +checkshape result + +# Check number of topological entities in the result. +checknbshapes result -solid 1 -shell 1 -face 11 -wire 12 -edge 32 -vertex 22 + +# Check result area. +checkprops result -s 2.82114 + +smallview +don result +fit + +checkview -screenshot -2d -path ${imagedir}/${test_image}.png