0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / GeomFill / GeomFill_LocationGuide.cxx
old mode 100755 (executable)
new mode 100644 (file)
index cb50d9d..ef26645
@@ -1,62 +1,80 @@
-// File:       GeomFill_LocationGuide.cxx
-// Created:    Wed Jul  8 15:16:45 1998
-// Author:     Stephanie HUMEAU
-//             <shu@sun17>
-
-
-#include <GeomFill_LocationGuide.ixx>
-#include <gp.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Vec.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Trsf.hxx>
-#include <gp_GTrsf.hxx>
-#include <gp_XYZ.hxx>
-#include <gp_Ax1.hxx>
-#include <gp_Pnt2d.hxx>
-
-#include <math_Vector.hxx>
-#include <math_Gauss.hxx>
-#include <math_FunctionSetRoot.hxx>
-#include <Precision.hxx>
-
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_Curve.hxx>
-
-#include <Adaptor3d_SurfaceOfRevolution.hxx>
+// Created on: 1998-07-08
+// Created by: Stephanie HUMEAU
+// Copyright (c) 1998-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <Adaptor3d_HCurve.hxx>
 #include <Adaptor3d_HSurface.hxx>
-
-#include <IntCurveSurface_IntersectionPoint.hxx>
-#include <IntCurveSurface_HInter.hxx>
 #include <Adaptor3d_Surface.hxx>
+#include <ElCLib.hxx>
+#include <Extrema_ExtCS.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_SurfaceOfRevolution.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAdaptor.hxx>
-#include <GeomAdaptor_HSurface.hxx>
 #include <GeomAdaptor_HCurve.hxx>
-
-
-#include <GeomFill_FunctionGuide.ixx>
-#include <GeomFill_UniformSection.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomFill_FunctionGuide.hxx>
+#include <GeomFill_LocationGuide.hxx>
+#include <GeomFill_LocationLaw.hxx>
+#include <GeomFill_SectionLaw.hxx>
 #include <GeomFill_SectionPlacement.hxx>
-#include <Geom_TrimmedCurve.hxx>
+#include <GeomFill_TrihedronWithGuide.hxx>
+#include <GeomFill_UniformSection.hxx>
 #include <GeomLib.hxx>
-#include <ElCLib.hxx>
-
+#include <gp.hxx>
+#include <gp_Ax1.hxx>
+#include <gp_Dir.hxx>
+#include <gp_GTrsf.hxx>
+#include <gp_Mat.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
+#include <IntCurveSurface_IntersectionPoint.hxx>
+#include <math_FunctionSetRoot.hxx>
+#include <math_Gauss.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+#include <Precision.hxx>
+#include <Standard_ConstructionError.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <Standard_Type.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 #include <TColStd_HArray1OfReal.hxx>
-#include <TColgp_HArray1OfPnt.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(GeomFill_LocationGuide,GeomFill_LocationLaw)
 
 #if DRAW
 static Standard_Integer Affich = 0;
 #include <Approx_Curve3d.hxx>
 #include <DrawTrSurf.hxx>
+#include <GeomFill_TrihedronWithGuide.hxx>
 #endif
 
 //=======================================================================
 //function : TraceRevol
 //purpose  : Trace la surface de revolution (Debug)
 //=======================================================================
-#if DEB
+#ifdef OCCT_DEBUG
 static void TraceRevol(const Standard_Real t,
                        const Standard_Real s,
                       const Handle(GeomFill_TrihedronWithGuide)& Law,
@@ -67,11 +85,10 @@ static void TraceRevol(const Standard_Real t,
 {
   gp_Vec T, N, B;
   gp_Pnt P;
-  Standard_Boolean Ok;
   gp_Ax3 Rep(gp::Origin(), gp::DZ(), gp::DX());
 
   Curve->D0(t, P);
-  Ok = Law->D0(t, T, N, B);
+  Law->D0(t, T, N, B);
 
   gp_Mat M(N.XYZ(), B.XYZ(), T.XYZ());
   M *= Trans;
@@ -211,14 +228,13 @@ static void InGoodPeriod(const Standard_Real Prec,
   gp_Vec T,N,B;
   Standard_Integer ii, Deg;
   Standard_Boolean isconst, israt=Standard_False;
-  Standard_Real t, v,w, OldAngle=0, Angle, DeltaG, DeltaU, Diff;
-  Standard_Real CurAngle =  PrecAngle, a1, a2;
+  Standard_Real t, v,w, OldAngle=0, Angle, DeltaG, Diff;
+  Standard_Real CurAngle =  PrecAngle, a1/*, a2*/;
   gp_Pnt2d p1,p2;
   Handle(Geom_SurfaceOfRevolution) Revol; // surface de revolution
   Handle(GeomAdaptor_HSurface) Pl; // = Revol
   Handle(Geom_TrimmedCurve) S;
   IntCurveSurface_IntersectionPoint PInt; // intersection guide/Revol
-  IntCurveSurface_HInter Int; 
   Handle(TColStd_HArray1OfInteger) Mult;
   Handle(TColStd_HArray1OfReal) Knots, Weights;
   Handle(TColgp_HArray1OfPnt)  Poles;
@@ -264,15 +280,14 @@ static void InGoodPeriod(const Standard_Real Prec,
   Inf(1) =  myGuide->FirstParameter() - Delta/10;
   Sup(1) =  myGuide->LastParameter() + Delta/10; 
 
-  Inf(2) = -PI;
-  Sup(2) = 3*PI;
+  Inf(2) = -M_PI;
+  Sup(2) = 3*M_PI;
  
   Delta =  Ul - Uf;
   Inf(3) = Uf - Delta/10;
   Sup(3) = Ul + Delta/10;
 
   // JALONNEMENT
-  DeltaU = (Ul-Uf)/(2+NbKnots);
   if (uperiodic) UPeriod = Ul-Uf;
 
   for (ii=1; ii<=myNbPts; ii++) {
@@ -322,45 +337,52 @@ static void InGoodPeriod(const Standard_Real Prec,
        (Handle(Geom_Curve)::DownCast(mySection->Copy()), Uf, Ul);
     }
     S->Transform(Transfo);
-      
+
     // Surface de revolution
     Revol = new(Geom_SurfaceOfRevolution) (S, Ax); 
     
-    Pl = new (GeomAdaptor_HSurface)(Revol);
-    Int.Perform(myGuide, Pl); // intersection  surf. revol / guide 
-    if (Int.NbPoints() == 0) {
-#if DEB
+    GeomAdaptor_Surface GArevol(Revol);
+    Extrema_ExtCS DistMini(myGuide->Curve(), GArevol,
+                           Precision::Confusion(), Precision::Confusion());
+    Extrema_POnCurv Pc;
+    Extrema_POnSurf Ps;
+    Standard_Real theU = 0., theV = 0.;
+    
+    if (!DistMini.IsDone() || DistMini.NbExt() == 0) {
+#ifdef OCCT_DEBUG
       cout <<"LocationGuide : Pas d'intersection"<<endl;
       TraceRevol(t, U, myLaw, mySec, myCurve, Trans);
 #endif 
       Standard_Boolean SOS=Standard_False;
       if (ii>1) {
-       // Intersection de secour entre surf revol et guide
-       // equation 
-       X(1) = myPoles2d->Value(1,ii-1).Y();
-       X(2) = myPoles2d->Value(2,ii-1).X();
-       X(3) = myPoles2d->Value(2,ii-1).Y();
-       GeomFill_FunctionGuide E (mySec, myGuide, U);
-       E.SetParam(U, P, T.XYZ(), N.XYZ()); 
-       // resolution   =>  angle
-       math_FunctionSetRoot Result(E, X, TolRes, 
-                                   Inf, Sup); 
-       
-       if (Result.IsDone() && 
-           (Result.FunctionSetErrors().Norm() < TolRes(1)*TolRes(1)) ) {
-#if DEB
-         cout << "Ratrappage Reussi !" << endl;
+        // Intersection de secour entre surf revol et guide
+        // equation 
+        X(1) = myPoles2d->Value(1,ii-1).Y();
+        X(2) = myPoles2d->Value(2,ii-1).X();
+        X(3) = myPoles2d->Value(2,ii-1).Y();
+        GeomFill_FunctionGuide E (mySec, myGuide, U);
+        E.SetParam(U, P, T.XYZ(), N.XYZ()); 
+        // resolution   =>  angle
+        math_FunctionSetRoot Result(E, TolRes);
+        Result.Perform(E, X, Inf, Sup);
+
+        if (Result.IsDone() && 
+          (Result.FunctionSetErrors().Norm() < TolRes(1)*TolRes(1)) ) {
+#ifdef OCCT_DEBUG
+            cout << "Ratrappage Reussi !" << endl;
 #endif
-         SOS = Standard_True;
-         math_Vector RR(1,3);
-         Result.Root(RR);
-         PInt.SetValues(P, RR(2), RR(3), RR(1), IntCurveSurface_Out); 
-       }  
-       else {
-#if DEB
-         cout << "Echec du Ratrappage !" << endl;
+            SOS = Standard_True;
+            math_Vector RR(1,3);
+            Result.Root(RR);
+            PInt.SetValues(P, RR(2), RR(3), RR(1), IntCurveSurface_Out);
+            theU = PInt.U();
+            theV = PInt.V();
+        }
+        else {
+#ifdef OCCT_DEBUG
+          cout << "Echec du Ratrappage !" << endl;
 #endif
-       }
+        }
       }
       if (!SOS) {
        myStatus = GeomFill_ImpossibleContact;
@@ -369,22 +391,30 @@ static void InGoodPeriod(const Standard_Real Prec,
     } 
     else { // on prend le point d'intersection 
       // d'angle le plus proche de P
-      PInt = Int.Point(1);
-      a1 = PInt.U();
-      InGoodPeriod (CurAngle, 2*PI, a1);
-      Standard_Real Dmin = Abs(a1-CurAngle);
-      for (Standard_Integer jj=2;jj<=Int.NbPoints();jj++) {
-       a2 = Int.Point(jj).U();
-       InGoodPeriod (CurAngle, 2*PI, a2);
-       if (Abs(a2-CurAngle) < Dmin) {
-         PInt = Int.Point(jj);
-         Dmin = Abs(a2-CurAngle);
-       }//if
-      }//for
+      
+      Standard_Real MinDist = RealLast();
+      Standard_Integer jref = 0;
+      for (Standard_Integer j = 1; j <= DistMini.NbExt(); j++)
+      {
+        Standard_Real aDist = DistMini.SquareDistance(j);
+        if (aDist < MinDist)
+        {
+          MinDist = aDist;
+          jref = j;
+        }
+      }
+      MinDist = Sqrt(MinDist);
+      DistMini.Points(jref, Pc, Ps);
+      
+      Ps.Parameter(theU, theV);
+      a1 = theU;
+      
+      InGoodPeriod (CurAngle, 2*M_PI, a1);
     }//else
     
     // Controle de w 
-    w = PInt.W();
+    w = Pc.Parameter();
+    
     if (ii>1) {
       Diff = w -  myPoles2d->Value(1, ii-1).Y();
       if (Abs(Diff) > DeltaG) {
@@ -395,7 +425,7 @@ static void InGoodPeriod(const Standard_Real Prec,
        }
       }
       
-#if DEB                
+#ifdef OCCT_DEBUG
       if (Abs(Diff) > DeltaG) {
        cout << "Location :: Diff on Guide : " << 
          Diff << endl;
@@ -403,15 +433,16 @@ static void InGoodPeriod(const Standard_Real Prec,
 #endif
     }
     //Recadrage de l'angle.
-    Angle = PInt.U();
+    Angle = theU;
+    
     if (ii > 1) {
       Diff = Angle - OldAngle;
-       if (Abs(Diff) > PI) {
-         InGoodPeriod (OldAngle, 2*PI, Angle);
+       if (Abs(Diff) > M_PI) {
+         InGoodPeriod (OldAngle, 2*M_PI, Angle);
          Diff = Angle - OldAngle;
        }
-#if DEB
-      if (Abs(Diff) > PI/4) {
+#ifdef OCCT_DEBUG
+      if (Abs(Diff) > M_PI/4) {
        cout << "Diff d'angle trop grand !!" << endl;
       } 
 #endif
@@ -419,14 +450,15 @@ static void InGoodPeriod(const Standard_Real Prec,
 
 
     //Recadrage du V
-    v = PInt.V();
+    v = theV;
+    
     if (ii > 1) {
       if (uperiodic) {
        InGoodPeriod (myPoles2d->Value(2, ii-1).Y(), UPeriod, v);
       }
       Diff = v -  myPoles2d->Value(2, ii-1).Y();
-#if DEB
-      if (Abs(Diff) > DeltaU) {
+#ifdef OCCT_DEBUG
+      if (Abs(Diff) > (Ul-Uf)/(2+NbKnots)) {
        cout << "Diff sur section trop grand !!" << endl;
       } 
 #endif
@@ -588,8 +620,8 @@ static void InGoodPeriod(const Standard_Real Prec,
     GeomFill_FunctionGuide E (mySec, myGuide, U);
     E.SetParam(Param, P, t, n); 
     // resolution   =>  angle
-    math_FunctionSetRoot Result(E, X, TolRes, 
-                               Inf, Sup, Iter); 
+    math_FunctionSetRoot Result(E, TolRes, Iter);
+    Result.Perform(E, X, Inf, Sup);
 
     if (Result.IsDone()) {
       // solution
@@ -604,7 +636,7 @@ static void InGoodPeriod(const Standard_Real Prec,
       M.SetCols(n, b, t);
     }
     else {
-#if DEB
+#ifdef OCCT_DEBUG
       cout << "LocationGuide::D0 : No Result !"<<endl;
       TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
 #endif
@@ -629,12 +661,6 @@ static void InGoodPeriod(const Standard_Real Prec,
   gp_Vec T, N, B;
   gp_Pnt P;
   Standard_Boolean Ok;
-#ifdef DEB
-  Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
-#else
-  myCurve->FirstParameter() ;
-#endif
-    
 
   myCurve->D0(Param, P);
   V.SetXYZ(P.XYZ());
@@ -650,12 +676,6 @@ static void InGoodPeriod(const Standard_Real Prec,
   }
   
   if (rotation) {
-#ifdef DEB
-    Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
-#else
-    myCurve->FirstParameter() ;
-#endif
-      
     //initialisation du germe
     InitX(Param);    
     Standard_Integer Iter = 100;
@@ -668,11 +688,11 @@ static void InGoodPeriod(const Standard_Real Prec,
     GeomFill_FunctionGuide E (mySec, myGuide, myFirstS + 
                                (Param-myCurve->FirstParameter())*ratio);
     E.SetParam(Param, P, t, n);
-      
+
     // resolution
-    math_FunctionSetRoot Result(E, X, TolRes, 
-                               Inf, Sup, Iter); 
-    
+    math_FunctionSetRoot Result(E, TolRes, Iter);
+    Result.Perform(E, X, Inf, Sup);
+
     if (Result.IsDone()) {
       // solution 
       Result.Root(R);   
@@ -688,7 +708,8 @@ static void InGoodPeriod(const Standard_Real Prec,
       M.SetCols(n, b, t);
     }
     else {
-#if DEB
+#ifdef OCCT_DEBUG
+      Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
       cout << "LocationGuide::D0 : No Result !"<<endl;
       TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
 #endif
@@ -738,8 +759,8 @@ static void InGoodPeriod(const Standard_Real Prec,
 
   if (rotation) {  
     return Standard_False;
-    
-#ifdef DEB
+ /*   
+#ifdef OCCT_DEBUG
     Standard_Real U = myFirstS + ratio*(Param-myCurve->FirstParameter());
 #else
     myCurve->FirstParameter() ;
@@ -786,7 +807,7 @@ static void InGoodPeriod(const Standard_Real Prec,
              Ga.Solve (DEDT.Opposite(), DSDT);// resolution du syst. 
            }//if
          else {
-#if DEB
+#ifdef OCCT_DEBUG
            cout << "DEDX = " << DEDX << endl;
            cout << "DEDT = " << DEDT << endl;
 #endif
@@ -817,7 +838,7 @@ static void InGoodPeriod(const Standard_Real Prec,
          Standard_Real A = R(2);
          Standard_Real Aprim = DSDT(2);  
 
-#ifdef DEB       
+#ifdef OCCT_DEBUG        
          gp_Mat M2 (Cos(A), -Sin(A),0,  // rotation autour de T
                     Sin(A), Cos(A),0,
                     0,0,1);      
@@ -850,14 +871,14 @@ static void InGoodPeriod(const Standard_Real Prec,
        }//if_Result
 
       else {
-#if DEB
+#ifdef OCCT_DEBUG
        cout << "LocationGuide::D1 : No Result !!"<<endl;
        TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
 #endif
        myStatus = GeomFill_ImpossibleContact;
        return Standard_False;
       }
-
+*/
     }//if_rotation
   
 
@@ -1101,7 +1122,7 @@ Standard_Boolean GeomFill_LocationGuide::D2(const Standard_Real Param,
 
        }//if_result
       else {
-#if DEB
+#ifdef OCCT_DEBUG
        cout << "LocationGuide::D2 : No Result !!" <<endl;
        TraceRevol(Param, U, myLaw, mySec, myCurve, Trans);
 #endif
@@ -1419,7 +1440,7 @@ void GeomFill_LocationGuide::InitX(const Standard_Real Param) const
     X(1) = ElCLib::InPeriod(X(1), myGuide->FirstParameter(), 
                                  myGuide->LastParameter());
   }
-  X(2) = ElCLib::InPeriod(X(2), 0, 2*PI);
+  X(2) = ElCLib::InPeriod(X(2), 0, 2*M_PI);
   if (mySec->IsUPeriodic()) {
     X(3) = ElCLib::InPeriod(X(3), Uf, Ul);
   } 
@@ -1437,3 +1458,40 @@ void GeomFill_LocationGuide::SetOrigine(const Standard_Real Param1,
   OrigParam2 = Param2;
 }
 
+//==================================================================
+//Function : ComputeAutomaticLaw
+//Purpose :
+//==================================================================
+GeomFill_PipeError GeomFill_LocationGuide::ComputeAutomaticLaw(Handle(TColgp_HArray1OfPnt2d)& ParAndRad) const
+{
+  gp_Pnt P;
+  gp_Vec T,N,B;
+  Standard_Integer ii;
+  Standard_Real t;
+
+  GeomFill_PipeError theStatus = GeomFill_PipeOk;
+
+  Standard_Real f = myCurve->FirstParameter();
+  Standard_Real l = myCurve->LastParameter();
+
+  ParAndRad = new TColgp_HArray1OfPnt2d(1, myNbPts);
+  for (ii = 1; ii <= myNbPts; ii++)
+  {
+    t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
+    t /= (myNbPts-1); 
+    myCurve->D0(t, P);
+    Standard_Boolean Ok = myLaw->D0(t, T, N, B);
+    if (!Ok)
+    {
+      theStatus = myLaw->ErrorStatus();
+      return theStatus;
+    }
+    gp_Pnt PointOnGuide = myLaw->CurrentPointOnGuide();
+    Standard_Real CurWidth = P.Distance(PointOnGuide);
+
+    gp_Pnt2d aParamWithRadius(t, CurWidth);
+    ParAndRad->SetValue(ii, aParamWithRadius);
+  }
+
+  return theStatus;
+}