0028054: Regression: Class BRepProj_Projection gives invalid result after projection...
authornbv <nbv@opencascade.com>
Mon, 7 Nov 2016 15:48:37 +0000 (18:48 +0300)
committerabv <abv@opencascade.com>
Tue, 8 Nov 2016 16:29:55 +0000 (19:29 +0300)
Problem of projection of line on the cone in the special case when starting point of the line coincides with the cone apex is fixed (by shifting this point along the source line).

src/ProjLib/ProjLib_Cone.cxx
src/Standard/Standard_Real.cxx
src/Standard/Standard_Real.hxx
tests/bugs/modalg_6/bug28054_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug28054_2 [new file with mode: 0644]

index 005f2e3..9118233 100644 (file)
@@ -94,10 +94,19 @@ void  ProjLib_Cone::Init(const gp_Cone& Co)
 
 void  ProjLib_Cone::Project(const gp_Lin& L)
 {
+  gp_Pnt aPnt = L.Location(), anApex = myCone.Apex();
+
+  Standard_Real aDeltaV = 0.0;
 
   Standard_Real U,V;
+  if (aPnt.IsEqual(anApex, Precision::Confusion()))
+  {
+    //Take another point in the line L, which does not coincide with the cone apex.
+    aPnt.Translate(L.Direction().XYZ());
+    aDeltaV = 1.0; // == ||L.Direction()|| == 1.0
+  }
  
-  ElSLib::ConeParameters(myCone.Position(), myCone.RefRadius(), myCone.SemiAngle(), L.Location(),
+  ElSLib::ConeParameters(myCone.Position(), myCone.RefRadius(), myCone.SemiAngle(), aPnt,
                                           U, V);
   //
   gp_Pnt P;
@@ -107,21 +116,19 @@ void  ProjLib_Cone::Project(const gp_Lin& L)
                 P, Vu, Vv);
 
   gp_Dir Dv(Vv);
-  if(Dv.IsParallel(L.Direction(), Precision::Angular())) {
-
+  if(Dv.IsParallel(L.Direction(), Precision::Angular()))
+  {
+    // L is parallel to U-isoline of the cone.
     myType = GeomAbs_Line;
-
-    gp_Pnt2d P2d(U,V);
   
-    Standard_Real Signe = L.Direction().Dot(Dv);
-    Signe = (Signe > 0.) ? 1. : -1.;
-    gp_Dir2d D2d(0., Signe);
+    const Standard_Real aSign = Sign(1.0, L.Direction().Dot(Dv));
+    gp_Pnt2d P2d(U, V - aDeltaV*aSign);
+    gp_Dir2d D2d(0., aSign);
   
     myLin = gp_Lin2d( P2d, D2d);
 
     isDone = Standard_True;
-  }
-    
+  }    
 }
 
 
index 0c97334..b587af4 100644 (file)
@@ -113,11 +113,9 @@ Standard_Real ATan2 (const Standard_Real Value, const Standard_Real Other)
 
 //-------------------------------------------------------------------
 // Sign : Returns |a| if B >= 0; -|a| if b < 0.
-//             from x in the direction y
 //-------------------------------------------------------------------
 Standard_Real Sign(const Standard_Real a, const Standard_Real b)
 {
-  //==== We use the function "nextafter()" fom library "math.h" ==============
   if (b >= 0.0) {
     return Abs(a);
   } else {
index 84e84e0..9beb501 100644 (file)
@@ -37,7 +37,10 @@ __Standard_API Standard_Real    ACosApprox  (const Standard_Real );
 __Standard_API Standard_Real    ASin        (const Standard_Real );
 __Standard_API Standard_Real    ATan2       (const Standard_Real , const Standard_Real );
 __Standard_API Standard_Real    NextAfter   (const Standard_Real , const Standard_Real );
-__Standard_API Standard_Real    Sign        (const Standard_Real , const Standard_Real );
+
+//! Returns |a| if b >= 0; -|a| if b < 0.
+__Standard_API Standard_Real    Sign(const Standard_Real a, const Standard_Real b);
+
 __Standard_API Standard_Real    ATanh       (const Standard_Real );
 __Standard_API Standard_Real    ACosh       (const Standard_Real );
 __Standard_API Standard_Real    Sinh       (const Standard_Real );
diff --git a/tests/bugs/modalg_6/bug28054_1 b/tests/bugs/modalg_6/bug28054_1
new file mode 100644 (file)
index 0000000..e024183
--- /dev/null
@@ -0,0 +1,33 @@
+puts "========"
+puts "OCC28054"
+puts "========"
+puts ""
+#################################################
+# Regression: Class BRepProj_Projection gives invalid result after projection edge based on the line on the conical surface
+#################################################
+
+set Tol 1.0e-7
+
+dsetsignal 1
+
+restore [locate_data_file bug28054_FaceProj.brep] f1
+restore [locate_data_file bug28054_EdgeProj.brep] e1
+
+set ProjList [prj r e1 f1 0 0 1]
+
+if { [llength $ProjList] < 1 } {
+  puts "Error: no projections are found"
+}
+
+foreach wir $ProjList {
+  set EdgeList [explode $wir e]
+  foreach ed $EdgeList {
+    set dist 1.0e+100
+    regexp {Max Distance = +([-0-9.+eE]+)} [xdistef $ed f1] full dist
+    if { $dist > $Tol } {
+      puts "Error in projection. 3D and 2D curves of edge $ed are not same-parameter"
+    } else {
+      puts "OK: Max Distance is less than $Tol"
+    }
+  }
+}
\ No newline at end of file
diff --git a/tests/bugs/modalg_6/bug28054_2 b/tests/bugs/modalg_6/bug28054_2
new file mode 100644 (file)
index 0000000..89958f9
--- /dev/null
@@ -0,0 +1,60 @@
+puts "========"
+puts "OCC28054"
+puts "========"
+puts ""
+#################################################
+# Regression: Class BRepProj_Projection gives invalid result after
+# projection edge based on the line on the conical surface
+#################################################
+
+set Tol 1.0e-7
+
+dsetsignal 1
+
+cone c 0 0 0 45 0
+trimv c1 c 5 10
+trimv c2 c -10 -5
+mkface f1 c1
+mkface f2 c2
+line l1 0 0 0 1 0 1
+line l2 0 0 0 0 -1 -1
+trim l1 l1 -100 100
+trim l2 l2 -100 100
+mkedge e1 l1
+mkedge e2 l2
+
+# Rotate f1 around e1 by the angle 32 degree
+copy f1 f3
+rotate f3 7 0 7 1 0 1 32
+
+# Rotate f2 around e2 by the angle 81 degree
+copy f2 f4
+rotate f4 0 -6 -6 0 -1 -1 81
+
+for { set i 1 } { $i <= 2 } { incr i } {
+  for { set j 1 } { $j <= 4 } { incr j } {
+    if { $i == 1 && $j == 4 } continue;
+    if { $i == 2 && $j == 3 } continue;
+    
+    puts ""
+    puts "Check e${i} and f${j}"
+
+    set ProjList [prj r e${i} f${j} 0 0 1]
+    if { [llength $ProjList] < 1 } {
+      puts "Error: no projections are found"
+    }
+    
+    foreach wir $ProjList {
+      set EdgeList [explode $wir e]
+      foreach ed $EdgeList {
+        set dist 1.0e+100
+        regexp {Max Distance = +([-0-9.+eE]+)} [xdistef $ed f${j}] full dist
+        if { $dist > $Tol } {
+          puts "Error in projection. 3D and 2D curves of edge $ed are not same-parameter"
+        } else {
+          puts "OK: Max Distance is less than $Tol"
+        }
+      }
+    }    
+  }
+}