]> OCCT Git - occt-copy.git/commitdiff
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 005f2e3b8009a93cf22666aa3d8aec56df170f6c..9118233252ddcbdd689e6c4c22a38012afa5dea3 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 0c9733485a2bc6327adb1a9295d3255b15275a4e..b587af4f826fc021f746708deac92d54507f3372 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 84e84e08325e962f0bc4be1c3e33dd68635c8711..9beb501c32b0b7802f3ef5aed7ba97169d87472f 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"
+        }
+      }
+    }    
+  }
+}