0027677: Incorrect CUT of a solid by semi-infinite solid
authorazv <azv@opencascade.com>
Mon, 18 Jul 2016 06:33:53 +0000 (09:33 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 21 Jul 2016 08:14:57 +0000 (11:14 +0300)
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

Minor correction of test case

src/ProjLib/ProjLib_Cylinder.cxx
src/ProjLib/ProjLib_ProjectedCurve.cxx
tests/bugs/modalg_6/bug27677 [new file with mode: 0644]

index e3a37e9..5c40eea 100644 (file)
@@ -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.);
index e78f04f..8dd1817 100644 (file)
@@ -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 (file)
index 0000000..faa01cc
--- /dev/null
@@ -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