0027322: geom/revolution_00/A1: Incorrect pcurve creation
authorifv <ifv@opencascade.com>
Thu, 7 Apr 2016 12:35:39 +0000 (15:35 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 14 Apr 2016 08:50:33 +0000 (11:50 +0300)
ProjLib_Cone.cxx - correction wrong calculation of projection line on cone
GeomInt_IntSS_1.cxx - modification of method BuildPCurves(...) - adjusting first or last knots of 2d Curve
ProjLib_ComputeApprox.cxx - modification of method Function_SetUVBounds(...) for case projecting line on cone.
Modification of tests - removing first TODO

Test case for issue #27322

src/GeomInt/GeomInt_IntSS_1.cxx
src/ProjLib/ProjLib_ComputeApprox.cxx
src/ProjLib/ProjLib_Cone.cxx
tests/bugs/modalg_4/bug6272_1
tests/bugs/modalg_4/bug6272_2
tests/bugs/modalg_6/bug27322 [new file with mode: 0644]

index dbabd3d..1a3f583 100644 (file)
@@ -1167,12 +1167,28 @@ void GeomInt_IntSS::BuildPCurves (Standard_Real f,
   // in class ProjLib_Function the range of parameters is shrank by 1.e-09
   if((l - f) > 2.e-09) {
     C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
   // in class ProjLib_Function the range of parameters is shrank by 1.e-09
   if((l - f) > 2.e-09) {
     C2d = GeomProjLib::Curve2d(C,f,l,S,umin,umax,vmin,vmax,Tol);
-    //
     if (C2d.IsNull()) {
       // proj. a circle that goes through the pole on a sphere to the sphere     
       Tol += Precision::Confusion();
       C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
     }
     if (C2d.IsNull()) {
       // proj. a circle that goes through the pole on a sphere to the sphere     
       Tol += Precision::Confusion();
       C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
     }
+    const Handle(Standard_Type)& aType = C2d->DynamicType();
+    if ( aType == STANDARD_TYPE(Geom2d_BSplineCurve)) 
+    { 
+      //Check first, last knots to avoid problems with trimming
+      //First, last knots can differ from f, l because of numerical error 
+      //of projection and approximation
+      //The same checking as in Geom2d_TrimmedCurve
+      if((C2d->FirstParameter() - f > Precision::PConfusion()) ||
+        (l - C2d->LastParameter() > Precision::PConfusion()))   
+      {
+        Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
+        TColStd_Array1OfReal aKnots(1, aBspl->NbKnots());
+        aBspl->Knots(aKnots);
+        BSplCLib::Reparametrize(f, l, aKnots);
+        aBspl->SetKnots(aKnots);
+      }
+    }
   }
   else {
     if((l - f) > Epsilon(Abs(f)))
   }
   else {
     if((l - f) > Epsilon(Abs(f)))
index d4c5beb..75966fe 100644 (file)
@@ -225,8 +225,28 @@ static void Function_SetUVBounds(Standard_Real& myU1,
   switch ( mySurface->GetType()) {
 
     case GeomAbs_Cone:    {
   switch ( mySurface->GetType()) {
 
     case GeomAbs_Cone:    {
+      Standard_Real tol = Epsilon(1.);
+      Standard_Real ptol = Precision::PConfusion();
       gp_Cone Cone = mySurface->Cone();
       VCouture = Standard_False;
       gp_Cone Cone = mySurface->Cone();
       VCouture = Standard_False;
+      //Calculation of cone parameters for P == ConeApex often produces wrong
+      //values of U
+      gp_Pnt ConeApex = Cone.Apex();
+      if(ConeApex.XYZ().IsEqual(P1.XYZ(), tol))
+      {
+        W1 += ptol;
+        P1 = myCurve->Value(W1);
+      }
+      if(ConeApex.XYZ().IsEqual(P2.XYZ(), tol))
+      {
+        W2 -= ptol;
+        P2 = myCurve->Value(W2);
+      }
+      if(ConeApex.XYZ().IsEqual(P.XYZ(), tol))
+      {
+        W += ptol;
+        P = myCurve->Value(W);
+      }
 
       switch( myCurve->GetType() ){
       case GeomAbs_Parabola:
 
       switch( myCurve->GetType() ){
       case GeomAbs_Parabola:
@@ -255,6 +275,10 @@ static void Function_SetUVBounds(Standard_Real& myU1,
         myU1 = U1; myU2 = U1; Uf = U1; 
         Standard_Real Step = .1;
         Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
         myU1 = U1; myU2 = U1; Uf = U1; 
         Standard_Real Step = .1;
         Standard_Integer nbp = (Standard_Integer)((W2 - W1) / Step + 1);
+        if(myCurve->GetType() == GeomAbs_Line)
+        {
+          nbp = 3;
+        }
         nbp = Max(nbp, 3);
         Step = (W2 - W1) / (nbp - 1);
         Standard_Boolean isclandper = (!(myCurve->IsClosed()) && !(myCurve->IsPeriodic()));
         nbp = Max(nbp, 3);
         Step = (W2 - W1) / (nbp - 1);
         Standard_Boolean isclandper = (!(myCurve->IsClosed()) && !(myCurve->IsPeriodic()));
index 5ca0fee..005f2e3 100644 (file)
@@ -96,48 +96,24 @@ void  ProjLib_Cone::Project(const gp_Lin& L)
 {
 
   Standard_Real U,V;
 {
 
   Standard_Real U,V;
-  
-  // Compute V
-  V = gp_Vec(myCone.Location(),L.Location())
-    .Dot(gp_Vec(myCone.Position().Direction()));
-  V /= Cos( myCone.SemiAngle());
-
-  // Compute U
-  gp_Ax3 CPos  = myCone.Position();
-  gp_Dir ZCone = CPos.XDirection() ^ CPos.YDirection();
-  
-  gp_Ax3 RightHanded(CPos.Location(), ZCone, CPos.XDirection());
-  gp_Trsf T;
-  T.SetTransformation(RightHanded);
-
-  gp_Dir D = L.Position().Direction();
-  D.Transform(T);
-
-  if ( D.Z() < 0.) D.Reverse();
-  D.SetCoord(3, 0.);
-  U = gp::DX().AngleWithRef( D, gp::DZ());
-
-  Standard_Integer a1 = 
-    (ZCone.IsEqual(CPos.Direction(), Precision::Angular())) ? 1 : -1;
-  Standard_Integer a2 = 
-    (myCone.SemiAngle() > 0) ? 1 : -1;
-  if ( ( a1 * a2) == -1) U -= M_PI;
-
-  if ( U < 0.) U += 2.*M_PI;
-
+  ElSLib::ConeParameters(myCone.Position(), myCone.RefRadius(), myCone.SemiAngle(), L.Location(),
+                                          U, V);
+  //
   gp_Pnt P;
   gp_Vec Vu, Vv;
 
   gp_Pnt P;
   gp_Vec Vu, Vv;
 
-  ElSLib::ConeD1(U, V, CPos, myCone.RefRadius(), myCone.SemiAngle(),
+  ElSLib::ConeD1(U, V, myCone.Position(), myCone.RefRadius(), myCone.SemiAngle(),
                 P, Vu, Vv);
 
                 P, Vu, Vv);
 
-  if(Vv.IsParallel(gp_Vec(L.Position().Direction()), Precision::Angular())) {
+  gp_Dir Dv(Vv);
+  if(Dv.IsParallel(L.Direction(), Precision::Angular())) {
 
     myType = GeomAbs_Line;
 
     gp_Pnt2d P2d(U,V);
   
 
     myType = GeomAbs_Line;
 
     gp_Pnt2d P2d(U,V);
   
-    Standard_Real Signe = L.Direction().Dot(myCone.Position().Direction());
+    Standard_Real Signe = L.Direction().Dot(Dv);
     Signe = (Signe > 0.) ? 1. : -1.;
     gp_Dir2d D2d(0., Signe);
   
     Signe = (Signe > 0.) ? 1. : -1.;
     gp_Dir2d D2d(0., Signe);
   
index 4dd60c0..611091b 100755 (executable)
@@ -1,4 +1,4 @@
-puts "TODO OCC111111 ALL: Faulty shapes in variables faulty_1 to faulty_"
+#puts "TODO OCC111111 ALL: Faulty shapes in variables faulty_1 to faulty_"
 puts "TODO OCC111111 ALL: Error : The area of result shape is"
 pload QAcommands
 
 puts "TODO OCC111111 ALL: Error : The area of result shape is"
 pload QAcommands
 
index ef2b92a..9f89c04 100755 (executable)
@@ -1,4 +1,4 @@
-puts "TODO OCC111111 ALL: Faulty shapes in variables faulty_1 to faulty_"
+#puts "TODO OCC111111 ALL: Faulty shapes in variables faulty_1 to faulty_"
 puts "TODO OCC111111 ALL: Error : The area of result shape is"
 
 pload QAcommands
 puts "TODO OCC111111 ALL: Error : The area of result shape is"
 
 pload QAcommands
diff --git a/tests/bugs/modalg_6/bug27322 b/tests/bugs/modalg_6/bug27322
new file mode 100644 (file)
index 0000000..5cd32ad
--- /dev/null
@@ -0,0 +1,23 @@
+puts "========"
+puts "OCC27322"
+puts "========"
+puts ""
+####################################################
+# geom/revolution_00/A1: Incorrect pcurve creation
+####################################################
+
+restore [locate_data_file bug27325_edge.brep] en
+restore [locate_data_file bug27325_face.brep] f
+
+bhaspc en f do
+mk2dcurve c1 en f
+explode f e
+mk2dcurve c2 f_3 f
+2dcvalue c1 0.0025 x y
+2dproj c2 x y
+
+set bug_info [string trim [length ext_1]]
+set bug_info [string trim [string range $bug_info [expr {[string last " " $bug_info] + 1}] [expr {[string length $bug_info] - 1}]]]
+if {$bug_info >= 1.e-9} {
+  puts "ERROR: OCC27322 is reproduced. Incorrect pcurve creation."
+}