0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / ProjLib / ProjLib_ComputeApproxOnPolarSurface.cxx
index 989f262..02179dc 100755 (executable)
@@ -1,5 +1,22 @@
-// Author:     Bruno DUMORTIER
-//             <dub@fuegox>
+// Created by: Bruno DUMORTIER
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
 #include <AppCont_Function2d.hxx>
 #include <ElSLib.hxx>
@@ -102,7 +119,7 @@ static gp_Pnt2d Function_Value(const Standard_Real U,
   if((Type != GeomAbs_BSplineSurface) && 
      (Type != GeomAbs_BezierSurface)  &&
      (Type != GeomAbs_OffsetSurface)    ) {
-    Standard_Real S, T;
+    Standard_Real S = 0., T = 0.;
     switch (Type) {
 //    case GeomAbs_Plane:
 //      {
@@ -114,36 +131,36 @@ static gp_Pnt2d Function_Value(const Standard_Real U,
       {
        gp_Cylinder Cylinder = Surf->Cylinder();
        ElSLib::Parameters( Cylinder, p, S, T);
-       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*PI))-1;
-       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*PI))+1;
-       S += decalU*2*PI;
+       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
+       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
+       S += decalU*2*M_PI;
        break;
       }
     case GeomAbs_Cone:
       {
        gp_Cone Cone = Surf->Cone();
        ElSLib::Parameters( Cone, p, S, T);
-       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*PI))-1;
-       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*PI))+1;
-       S += decalU*2*PI;
+       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
+       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
+       S += decalU*2*M_PI;
        break;
       }
     case GeomAbs_Sphere:
       {
        gp_Sphere Sphere = Surf->Sphere();
        ElSLib::Parameters( Sphere, p, S, T);
-       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*PI))-1;
-       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*PI))+1;
-       S += decalU*2*PI;
-       if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*PI))-1;
-       if(V0 > (Vsup+(Vsup-Vinf))) decalV =  int((V0 - Vsup+(Vsup-Vinf))/(2*PI))+1;
-       T += decalV*2*PI;
-       if(0.4*PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*PI) {
-         T = PI - T;
+       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
+       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
+       S += decalU*2*M_PI;
+       if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
+       if(V0 > (Vsup+(Vsup-Vinf))) decalV =  int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
+       T += decalV*2*M_PI;
+       if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI) {
+         T = M_PI - T;
          if(U0 < S)
-           S -= PI;
+           S -= M_PI;
          else
-           S += PI;
+           S += M_PI;
        }
        break;
       }
@@ -151,11 +168,11 @@ static gp_Pnt2d Function_Value(const Standard_Real U,
       {
        gp_Torus Torus = Surf->Torus();
        ElSLib::Parameters( Torus, p, S, T);
-       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*PI))-1;
-       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*PI))+1;
-       if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*PI))-1;
-       if(V0 > Vsup) decalV =  int((V0 - Vsup)/(2*PI))+1;
-       S += decalU*2*PI; T += decalV*2*PI;
+       if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
+       if(U0 > Usup) decalU =  int((U0 - Usup)/(2*M_PI))+1;
+       if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
+       if(V0 > Vsup) decalV =  int((V0 - Vsup)/(2*M_PI))+1;
+       S += decalU*2*M_PI; T += decalV*2*M_PI;
        break;
       }
     default:
@@ -182,34 +199,38 @@ static gp_Pnt2d Function_Value(const Standard_Real U,
   if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
     vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
   } 
-  if(U0 < Uinf)
+  if(U0 < Uinf) {
     if(!uperiod)
       U0 = Uinf;
     else {
       decalU = int((Uinf - U0)/uperiod)+1;
       U0 += decalU*uperiod;
     }
-  if(U0 > Usup)
+  }
+  if(U0 > Usup) {
     if(!uperiod)
       U0 = Usup;
     else {
       decalU = -(int((U0 - Usup)/uperiod)+1);
       U0 += decalU*uperiod;
     }
-  if(V0 < Vinf)
+  }
+  if(V0 < Vinf) {
     if(!vperiod)
       V0 = Vinf;
     else {
       decalV = int((Vinf - V0)/vperiod)+1;
       V0 += decalV*vperiod;
     }
-  if(V0 > Vsup)
+  }
+  if(V0 > Vsup) {
     if(!vperiod)
       V0 = Vsup;
     else {
       decalV = -int((V0 - Vsup)/vperiod)-1;
       V0 += decalV*vperiod;
     }
+  }
   
   // The surface around U0 is reduced
   Standard_Real uLittle = (Usup - Uinf)/10, vLittle = (Vsup - Vinf)/10;
@@ -303,10 +324,10 @@ class ProjLib_PolarFunction : public AppCont_Function2d
   ~ProjLib_PolarFunction() {}
   
   Standard_Real FirstParameter() const
-    {return (myCurve->FirstParameter()+1.e-9);}
+  {return (myCurve->FirstParameter()/*+1.e-9*/);}
   
   Standard_Real LastParameter() const
-    {return (myCurve->LastParameter()-1.e-9);}
+  {return (myCurve->LastParameter()/*-1.e-9*/);}
   
   gp_Pnt2d Value(const Standard_Real t) const {
     return Function_Value
@@ -690,6 +711,14 @@ Handle(Adaptor2d_HCurve2d)
   Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
   Standard_Real DistTol3d = 100.0*Tol3d;
 
+  Standard_Real uperiod = 0., vperiod = 0.;
+  if(Surf->IsUPeriodic() || Surf->IsUClosed())
+    uperiod = Surf->LastUParameter() - Surf->FirstUParameter(); 
+  
+  if(Surf->IsVPeriodic() || Surf->IsVClosed())
+    vperiod = Surf->LastVParameter() - Surf->FirstVParameter(); 
+
+  
   // NO myTol is Tol2d !!!!
   //Standard_Real TolU = myTolerance, TolV = myTolerance;
   //Standard_Real Tol3d = 100*myTolerance; // At random Balthazar.
@@ -709,7 +738,9 @@ Handle(Adaptor2d_HCurve2d)
   Mult.Init(1);
   Mult(1) = Mult(NbOfPnts) = 2;
   
-  Standard_Real Vinf, Vsup;
+  Standard_Real Uinf, Usup, Vinf, Vsup;
+  Uinf = Surf->Surface().FirstUParameter();
+  Usup = Surf->Surface().LastUParameter();
   Vinf = Surf->Surface().FirstVParameter();
   Vsup = Surf->Surface().LastVParameter();
   GeomAbs_SurfaceType Type = Surf->GetType();
@@ -732,44 +763,46 @@ Handle(Adaptor2d_HCurve2d)
     case GeomAbs_Cylinder:
       {
 //     Standard_Real Sloc, Tloc;
-       Standard_Real Sloc;
-       Standard_Integer usens = 0;
-       gp_Cylinder Cylinder = Surf->Cylinder();
-       ElSLib::Parameters( Cylinder, Pts(1), S, T);
-       Pts2d(1).SetCoord(S,T);
-       for ( i = 2 ; i <= NbOfPnts ; i++) { 
-         Sloc = S;
-         ElSLib::Parameters( Cylinder, Pts(i), S, T);
-         if(Abs(Sloc - S) > PI)
-           if(Sloc > S)
-             usens++;
-           else
-             usens--;
-         Pts2d(i).SetCoord(S+usens*2*PI,T);
-       }
-       myProjIsDone = Standard_True;
-       break;
+        Standard_Real Sloc;
+        Standard_Integer usens = 0;
+        gp_Cylinder Cylinder = Surf->Cylinder();
+        ElSLib::Parameters( Cylinder, Pts(1), S, T);
+        Pts2d(1).SetCoord(S,T);
+        for ( i = 2 ; i <= NbOfPnts ; i++) { 
+          Sloc = S;
+          ElSLib::Parameters( Cylinder, Pts(i), S, T);
+          if(Abs(Sloc - S) > M_PI) {
+            if(Sloc > S)
+              usens++;
+            else
+              usens--;
+          }
+          Pts2d(i).SetCoord(S+usens*2*M_PI,T);
+        }
+        myProjIsDone = Standard_True;
+        break;
       }
     case GeomAbs_Cone:
       {
 //     Standard_Real Sloc, Tloc;
-       Standard_Real Sloc;
-       Standard_Integer usens = 0;
-       gp_Cone Cone = Surf->Cone();
-       ElSLib::Parameters( Cone, Pts(1), S, T);
-       Pts2d(1).SetCoord(S,T);
-       for ( i = 2 ; i <= NbOfPnts ; i++) { 
-         Sloc = S;
-         ElSLib::Parameters( Cone, Pts(i), S, T);
-         if(Abs(Sloc - S) > PI)
-           if(Sloc > S)
-             usens++;
-           else
-             usens--;
-         Pts2d(i).SetCoord(S+usens*2*PI,T);
-       }
-       myProjIsDone = Standard_True;
-       break;
+        Standard_Real Sloc;
+        Standard_Integer usens = 0;
+        gp_Cone Cone = Surf->Cone();
+        ElSLib::Parameters( Cone, Pts(1), S, T);
+        Pts2d(1).SetCoord(S,T);
+        for ( i = 2 ; i <= NbOfPnts ; i++) { 
+          Sloc = S;
+          ElSLib::Parameters( Cone, Pts(i), S, T);
+          if(Abs(Sloc - S) > M_PI) {
+            if(Sloc > S)
+              usens++;
+            else
+              usens--;
+          }
+          Pts2d(i).SetCoord(S+usens*2*M_PI,T);
+        }
+        myProjIsDone = Standard_True;
+        break;
       }
     case GeomAbs_Sphere:
       {
@@ -782,12 +815,13 @@ Handle(Adaptor2d_HCurve2d)
        for ( i = 2 ; i <= NbOfPnts ; i++) { 
          Sloc = S;Tloc = T;
          ElSLib::Parameters( Sphere, Pts(i), S, T);
-         if(1.6*PI < Abs(Sloc - S))
+         if(1.6*M_PI < Abs(Sloc - S)) {
            if(Sloc > S)
              usens += 2;
            else
              usens -= 2;
-         if(1.6*PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*PI) {
+    }
+         if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
            vparit = !vparit;
            if(Sloc > S)
              usens++;
@@ -799,10 +833,10 @@ Handle(Adaptor2d_HCurve2d)
              vsens--;
          }
          if(vparit) {
-           Pts2d(i).SetCoord(S+usens*PI,(PI - T)*(vsens-1));
+           Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
          }       
          else {
-           Pts2d(i).SetCoord(S+usens*PI,T+vsens*PI);
+           Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
            
          }
        }
@@ -819,17 +853,19 @@ Handle(Adaptor2d_HCurve2d)
        for ( i = 2 ; i <= NbOfPnts ; i++) { 
          Sloc = S; Tloc = T;
          ElSLib::Parameters( Torus, Pts(i), S, T);
-         if(Abs(Sloc - S) > PI)
+         if(Abs(Sloc - S) > M_PI) {
            if(Sloc > S)
              usens++;
            else
              usens--;
-         if(Abs(Tloc - T) > PI)
+    }
+         if(Abs(Tloc - T) > M_PI) {
            if(Tloc > T)
              vsens++;
            else
              vsens--;
-         Pts2d(i).SetCoord(S+usens*2*PI,T+vsens*2*PI);
+    }
+         Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
        }
        myProjIsDone = Standard_True;
        break;
@@ -839,9 +875,6 @@ Handle(Adaptor2d_HCurve2d)
     }
   }
   else {
-    Standard_Real Uinf = Surf->Surface().FirstUParameter();
-    Standard_Real Usup = Surf->Surface().LastUParameter();
-    
     myProjIsDone = Standard_False;
     Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
     gp_Pnt pntproj;
@@ -851,6 +884,26 @@ Handle(Adaptor2d_HCurve2d)
     
     Curve->D0(Param.Value(1), pntproj) ;
     Extrema_ExtPS  aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
+    Standard_Real aMinSqDist = RealLast();
+    if (aExtPS.IsDone())
+    {
+      for (i = 1; i <= aExtPS.NbExt(); i++)
+      {
+        Standard_Real aSqDist = aExtPS.SquareDistance(i);
+        if (aSqDist < aMinSqDist)
+          aMinSqDist = aSqDist;
+      }
+    }
+    if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
+    {
+      TolU = Min(TolU, Precision::PConfusion());
+      TolV = Min(TolV, Precision::PConfusion());
+      aExtPS.Initialize(Surf->Surface(),
+                        Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(), 
+                        Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
+                        TolU, TolV);
+      aExtPS.Perform(pntproj);
+    }
 
     if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
 
@@ -996,20 +1049,11 @@ Handle(Adaptor2d_HCurve2d)
       // (and store the result and each parameter in a sequence)
       Standard_Integer usens = 0, vsens = 0; 
       // to know the position relatively to the period
-      Standard_Real U0 = u, V0 = v, U1 = u, V1 = v, uperiod =0, vperiod = 0;
+      Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
       // U0 and V0 are the points in the initialized period 
       // (period with u and v),
       // U1 and V1 are the points for construction of poles
 
-
-      if(Surf->IsUPeriodic() || Surf->IsUClosed()) {
-       uperiod = Surf->LastUParameter() - Surf->FirstUParameter(); 
-      }
-
-      if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
-       vperiod = Surf->LastVParameter() - Surf->FirstVParameter(); 
-      } 
-      
       for ( i = 2 ; i <= NbOfPnts ; i++) 
        if(myProjIsDone) {
          myProjIsDone = Standard_False;
@@ -1124,7 +1168,7 @@ Handle(Adaptor2d_HCurve2d)
              if (Dist2Min < DistTol3d * DistTol3d) {
              //if (Dist2Min < Tol3d * Tol3d) {
                (ext.Point(GoodValue)).Parameter(u,v);
-               if(uperiod)
+               if(uperiod) {
                  if((U0 - u) > (2*uperiod/3)) {
                    usens++;
                  }
@@ -1132,7 +1176,8 @@ Handle(Adaptor2d_HCurve2d)
                    if((u - U0) > (2*uperiod/3)) {
                      usens--;
                    }
-               if(vperiod)
+    }
+               if(vperiod) {
                  if((V0 - v) > (vperiod/2)) {
                    vsens++;
                  }
@@ -1140,6 +1185,7 @@ Handle(Adaptor2d_HCurve2d)
                    if((v - V0) > (vperiod/2)) {
                      vsens--;
                    }
+      }
                U0 = u; V0 = v;
                U1 = U0 + usens*uperiod;
                V1 = V0 + vsens*vperiod;
@@ -1155,6 +1201,34 @@ Handle(Adaptor2d_HCurve2d)
   // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
   if(myProjIsDone) {
     myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
+    //jgv: put the curve into parametric range
+    gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
+    Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
+    Standard_Real sense = 0.;
+    if (uperiod)
+    {
+      if (TestU < Uinf - TolU)
+        sense = 1.;
+      else if (TestU > Usup + TolU)
+        sense = -1;
+      while (TestU < Uinf - TolU || TestU > Usup + TolU)
+        TestU += sense * uperiod;
+    }
+    if (vperiod)
+    {
+      sense = 0.;
+      if (TestV < Vinf - TolV)
+        sense = 1.;
+      else if (TestV > Vsup + TolV)
+        sense = -1.;
+      while (TestV < Vinf - TolV || TestV > Vsup + TolV)
+        TestV += sense * vperiod;
+    }
+    gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
+    if (Abs(Offset.X()) > gp::Resolution() ||
+        Abs(Offset.Y()) > gp::Resolution())
+      myBSpline->Translate(Offset);
+    //////////////////////////////////////////
     Geom2dAdaptor_Curve GAC(myBSpline);
     Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
 #ifdef DEB
@@ -1170,11 +1244,10 @@ Handle(Adaptor2d_HCurve2d)
 //  Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
     return Handle(Adaptor2d_HCurve2d)();
   }
-  myProjIsDone = Standard_False;
+//  myProjIsDone = Standard_False;
 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
 //   Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
 //  Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
-  return Handle(Adaptor2d_HCurve2d)();
 }
 
 
@@ -1259,8 +1332,8 @@ Handle(Geom2d_BSplineCurve)
       gp_Pnt p22 = BSS->Pole(2,2);
       gp_Vec V1(p11,p12);
       gp_Vec V2(p21,p22);
-      if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/PI))){  //OCC217
-      //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/PI))){
+      if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){  //OCC217
+      //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
        //  so the polar surface is plane
        //  and if it is enough to projet the  poles of Curve
        Standard_Integer Dist2Min = IntegerLast();
@@ -1360,8 +1433,8 @@ Handle(Geom2d_BSplineCurve)
       gp_Pnt p22 = BS->Pole(2,2);
       gp_Vec V1(p11,p12);
       gp_Vec V2(p21,p22);
-      if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/PI))){ //OCC217
-      //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/PI))){ 
+      if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
+      //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){ 
        //    and if it is enough to project the poles of Curve
        Standard_Integer Dist2Min = IntegerLast();
        Standard_Real u,v;
@@ -1553,8 +1626,8 @@ Handle(Geom2d_BSplineCurve)
     Standard_Integer NbKnots = NbCurves + 1;
     
     // The start and end nodes are not correct : Cf: opening of the interval
-    Knots( 1) -= 1.e-9;
-    Knots(NbKnots) += 1.e-9; 
+    //Knots( 1) -= 1.e-9;
+    //Knots(NbKnots) += 1.e-9; 
     
     
     TColStd_Array1OfInteger   Mults( 1, NbKnots);