Logo Search packages:      
Sourcecode: opencascade version File versions  Download package

Approx_SameParameter.cxx

// File:    Approx_SameParameter.cxx
// Created: Tue Jun  6 09:51:17 1995
// Author:  Xavier BENVENISTE
//          <xab@nonox>

//  Modified by skv - Wed Jun  2 11:49:59 2004 OCC5898

#include <Approx_SameParameter.ixx>
#include <TColStd_Array1OfReal.hxx>
#include <BSplCLib.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
//#include <GCPnts_UniformDeflection.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
#include <Extrema_LocateExtPC.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <GeomLib_MakeCurvefromApprox.hxx>
#include <Precision.hxx>

static TColStd_Array1OfReal         *LocalFlatKnotsPtr, *LocalPolesPtr;
static Handle(Adaptor2d_HCurve2d)     LocalHCurve2d;
static Handle(GeomAdaptor_HCurve)   LocalHCurve;
static Handle(GeomAdaptor_HSurface) LocalHSurface;

#define MAX_ARRAY_SIZE 1000 // IFV, Jan 2000

#ifdef DEB
#ifdef DRAW
#include <DrawTrSurf.hxx>
#endif
#include <Geom2d_BSplineCurve.hxx>
#include <stdio.h>
static Standard_Boolean Voir     = Standard_False;
static Standard_Boolean AffichFw = Standard_False;
static Standard_Integer NbCurve = 0;
#endif
//
//   sert a tester si Extrema raconte pas des betises
//


static void ProjectPointOnCurve(const Standard_Real      InitValue,
                        const gp_Pnt             APoint,
                        const Standard_Real      Tolerance,
                        const Standard_Integer   NumIteration,
                        const Adaptor3d_Curve&     Curve,
                        Standard_Boolean&        Status,
                        Standard_Real&           Result)
{
  Standard_Integer num_iter = 0,
  not_done = 1,
  ii ;
  
  gp_Pnt a_point ;
  gp_Vec   vector,
  d1,
  d2 ;
  Standard_Real func,
  func_derivative,
  param = InitValue ;
  Status = Standard_False ;
  Standard_Real Toler = 1.0e-12;
  do {
    num_iter += 1 ;
    Curve.D2(param,
            a_point,
           d1,
           d2) ;
    for (ii = 1 ; ii <= 3 ; ii++) {
      vector.SetCoord(ii, APoint.Coord(ii) - a_point.Coord(ii)) ;
    }
    func = vector.Dot(d1) ;
    func_derivative = vector.Dot(d2) ;
    func_derivative -= d1.Dot(d1) ;
    if ( Abs(func) < Tolerance * d1.Magnitude()) {
      not_done = 0 ;
      Status = Standard_True ;
    }
    else
      { // fixing a bug PRO18577 : avoid divizion by zero
      if( Abs(func_derivative) > Toler )  {
        param -= func / func_derivative ;
      }
      param = Max(param,Curve.FirstParameter()) ;
      param = Min(param,Curve.LastParameter())  ;
      Status = Standard_True ;
      }
  } 
  while (not_done && num_iter <= NumIteration) ;
  Result = param ;
}  
     


//=======================================================================
//function : SameParameterEvaluator
//purpose  : 
//=======================================================================
//
// uses above static variables
//
//extern "C"   void  SameParameterEvaluator(Standard_Integer *Dimension,
extern "C"   void  SameParameterEvaluator(Standard_Integer *,
//                              Standard_Real    *DebutFin,
                                Standard_Real    *,
                                Standard_Real    *Parameter,
                                Standard_Integer *DerivativeRequest,
                                Standard_Real    *Result,
                                Standard_Integer *ReturnCode) 
{ 
  gp_Pnt2d Point ;
  gp_Vec2d Vector ;
  Standard_Integer extrap_mode[2] ;
  extrap_mode[0] = extrap_mode[1] = 3;
  Standard_Real eval_result[2] ;
  Standard_Real *PolesArray =
    (Standard_Real *) &(*LocalPolesPtr)((*LocalPolesPtr).Lower()) ;
  //
  // evaluate the 1D bspline that represents the change in parameterization
  //
  BSplCLib::Eval(*Parameter,
             Standard_False,
             *DerivativeRequest,
             extrap_mode[0],
             3,
             *LocalFlatKnotsPtr,
             1,
             PolesArray[0],
                 eval_result[0]) ;
  
  
  if (*DerivativeRequest == 0){
    LocalHCurve2d->D0(eval_result[0],Point) ;
    Point.Coord(Result[0],Result[1]) ;
  }
  else if (*DerivativeRequest == 1){
    LocalHCurve2d->D1(eval_result[0], Point, Vector) ;
    Vector.Multiply(eval_result[1]);
    Vector.Coord(Result[0],Result[1]);
  }
  ReturnCode[0] = 0 ;
}

static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
                               const Adaptor3d_CurveOnSurface& cons,
                               const Standard_Integer        nbp)
{
  Standard_Real d2 = 0.;
  Standard_Integer nn = nbp;
  Standard_Real unsurnn = 1./nn;
  Standard_Real first = c3d->FirstParameter();
  Standard_Real last  = c3d->LastParameter();
  for(Standard_Integer i = 0; i <= nn; i++){
    Standard_Real t = unsurnn*i;
    Standard_Real u = first*(1.-t) + last*t;
    gp_Pnt Pc3d = c3d->Value(u);
    gp_Pnt Pcons = cons.Value(u);
    if (Precision::IsInfinite(Pcons.X()) ||
      Precision::IsInfinite(Pcons.Y()) ||
      Precision::IsInfinite(Pcons.Z())) {
      d2=Precision::Infinite();
      break;
    }
    Standard_Real temp = Pc3d.SquareDistance(Pcons);
    if(temp > d2) d2 = temp;
  }
  d2 = 1.5*sqrt(d2);
  if(d2<1.e-7) d2 = 1.e-7;
  return d2;
}

static Standard_Boolean Check(const Standard_Integer nbp,
                        const TColStd_Array1OfReal& pc3d,
//                      const TColStd_Array1OfReal& pcons,
                        const TColStd_Array1OfReal& ,
                        const Handle(Adaptor3d_HCurve)& c3d,
                        const Adaptor3d_CurveOnSurface& cons,
                        Standard_Real& tol,
                        const Standard_Real oldtol)
{
  Standard_Real d = tol;
  Standard_Integer extrap_mode[2] ;
  extrap_mode[0] = extrap_mode[1] = 3;
  Standard_Integer i;
#ifdef DEB
  if (Voir) {
    cout<<endl;
    cout<<"Controle du changement de variable : "<<endl;
    cout<<"baillement mesure par projection : "<<d<<endl;
    cout<<"Nombre de points : "<<nbp<<endl;
  }
#endif
#if 0
  Standard_Real glis = 0., dglis = 0.;
  for(i = 1; i <= nbp; i++){
    Standard_Real tc3d = pc3d(i);
    gp_Pnt Pc3d = c3d->Value(tc3d);
    Standard_Real tcons;
    BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
               3,*LocalFlatKnotsPtr,1,
               (*LocalPolesPtr)(1),tcons);
    gp_Pnt Pcons = cons.Value(tcons);
    Standard_Real temp = Pc3d.SquareDistance(Pcons);
    if(temp >= dglis) dglis = temp;
    temp = Abs(tcons-pcons(i));
    if(temp >= glis) glis = temp;
  }
  dglis = sqrt(dglis);
#ifdef DEB
  if ( Voir) {
    cout<<"glissement de parametre aux points imposes : "<<glis<<endl;
    cout<<"distance de glissement aux points imposes : "<<dglis<<endl;
  }
#endif
  dglis = 0.;
  for(i = 1; i < nbp; i++){
    Standard_Real tc3d = 0.5*(pc3d(i)+pc3d(i+1));
    gp_Pnt Pc3d = c3d->Value(tc3d);
    Standard_Real tcons;
    BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
               3,*LocalFlatKnotsPtr,1,
               (*LocalPolesPtr)(1),tcons);
    gp_Pnt Pcons = cons.Value(tcons);
    Standard_Real temp = Pc3d.SquareDistance(Pcons);
    if(temp >= dglis) dglis = temp;
  }
  dglis = sqrt(dglis);
#ifdef DEB
  if (Voir)
    cout<<"distance de glissement en milieu d intervals : "<<dglis<<endl;
#endif
#endif

  Standard_Real d2 = 0.;
  Standard_Integer nn = 2*nbp;
  Standard_Real unsurnn = 1./nn;
//  Modified by skv - Wed Jun  2 11:49:59 2004 OCC5898 Begin
// Correction of the interval of valid values. This condition has no sensible
// grounds. But it is better then the old one (which is commented out) because
// it fixes the bug OCC5898. To develop more or less sensible criterion it is
// necessary to deeply investigate this problem which is not possible in frames
// of debugging.

//   Standard_Real firstborne= 2*pc3d(1)-pc3d(nbp);
//   Standard_Real lastborne= 2*pc3d(nbp)-pc3d(1);
  Standard_Real firstborne= 3.*pc3d(1)   - 2.*pc3d(nbp);
  Standard_Real lastborne = 3.*pc3d(nbp) - 2.*pc3d(1);
//  Modified by skv - Wed Jun  2 11:50:03 2004 OCC5898 End
  for(i = 0; i <= nn; i++){
    Standard_Real t = unsurnn*i;
    Standard_Real tc3d = pc3d(1)*(1.-t) + pc3d(nbp)*t;
    gp_Pnt Pc3d = c3d->Value(tc3d);
    Standard_Real tcons;
    BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
               3,*LocalFlatKnotsPtr,1,
               (*LocalPolesPtr)(1),tcons);
    if (tcons < firstborne || tcons > lastborne) {
      tol=Precision::Infinite();
      return Standard_False;
    }
    gp_Pnt Pcons = cons.Value(tcons);
    Standard_Real temp = Pc3d.SquareDistance(Pcons);
    if(temp > d2) d2 = temp;
  }
  tol = sqrt(d2);
#ifdef DEB
  if (Voir)
    cout<<"distance max sur "<<nn<<" points : "<<tol<<endl<<endl;
#endif
  return ((tol <= d) || (tol > 0.8 * oldtol));
}


//=======================================================================
//function : Approx_SameParameter
//purpose  : 
//=======================================================================

00284 Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)&   C3D,
                                 const Handle(Geom2d_Curve)& C2D,
                                 const Handle(Geom_Surface)& S,
                                 const Standard_Real         Tol):
 mySameParameter(Standard_True) , myDone(Standard_False)
{
  if (LocalHCurve.IsNull()) LocalHCurve = new GeomAdaptor_HCurve(C3D);
  else LocalHCurve->ChangeCurve().Load(C3D);
  LocalHCurve2d = new Geom2dAdaptor_HCurve(C2D);
  if (LocalHSurface.IsNull()) LocalHSurface = new GeomAdaptor_HSurface(S);
  else LocalHSurface->ChangeSurface().Load(S);
  myC3d  = LocalHCurve;
  mySurf = LocalHSurface;
  Build(Tol);
}


//=======================================================================
//function : Approx_SameParameter
//purpose  : 
//=======================================================================

Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)&   C3D,
                                 const Handle(Geom2d_Curve)&     C2D,
                                 const Handle(Adaptor3d_HSurface)& S,
                                 const Standard_Real            Tol):
 mySameParameter(Standard_True) , myDone(Standard_False)
{
  myC3d = C3D;
  mySurf = S;
  LocalHCurve2d = new Geom2dAdaptor_HCurve(C2D);
  Build(Tol);
}


//=======================================================================
//function : Approx_SameParameter
//purpose  : 
//=======================================================================

00324 Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)&   C3D,
                                 const Handle(Adaptor2d_HCurve2d)& C2D,
                                 const Handle(Adaptor3d_HSurface)& S,
                                 const Standard_Real            Tol):
 mySameParameter(Standard_True) , myDone(Standard_False)
{
  myC3d = C3D;
  mySurf = S;
  LocalHCurve2d = C2D;
  Build(Tol);
}


//=======================================================================
//function : Build
//purpose  : 
//=======================================================================

00342 void Approx_SameParameter::Build(const Standard_Real Tolerance)
{
  Standard_Integer ii ;
  Adaptor3d_CurveOnSurface  CurveOnSurface(LocalHCurve2d,mySurf);
  Standard_Real fcons = CurveOnSurface.FirstParameter();
  Standard_Real lcons = CurveOnSurface.LastParameter();
  Standard_Real fc3d = myC3d->FirstParameter();
  Standard_Real lc3d = myC3d->LastParameter();

  GeomAbs_Shape Continuity = LocalHCurve2d->Continuity();

  if(Continuity > GeomAbs_C1) Continuity = GeomAbs_C1;

  //On controle les tangentes aux extremites pour savoir si le
  //reparametrage est possible et on calcule les tangentes aux
  //extremites de la fonction de changement de variable.
  Standard_Real tangent[2];
  gp_Pnt Pcons,Pc3d;
  gp_Vec Vcons,Vc3d;

  Standard_Real Tol = Tolerance;
  Standard_Real Tol2 = Tol * Tol;
  Standard_Real Tolp = myC3d->Resolution(Tol), deltamin = 50*Tolp;

  Standard_Real besttol = Tol;
  Standard_Boolean extrok = 0;

  extrok = 1;
  CurveOnSurface.D1(fcons,Pcons,Vcons);
  myC3d->D1(fc3d,Pc3d,Vc3d);
  Standard_Real dist2 = Pcons.SquareDistance(Pc3d);
  Standard_Real dmax2 = dist2;

  Standard_Real magVcons = Vcons.Magnitude();
  if (magVcons > 1.e-12){
    tangent[0] = Vc3d.Magnitude() / magVcons;
  }
  else extrok = 0;

  CurveOnSurface.D1(lcons,Pcons,Vcons);
  myC3d->D1(lc3d,Pc3d,Vc3d);
  dist2 = Pcons.SquareDistance(Pc3d);

  if(dist2 > dmax2) dmax2 = dist2;
  magVcons = Vcons.Magnitude();
  if (magVcons > 1.e-12){
    tangent[1] = Vc3d.Magnitude() / magVcons;
  }
  else extrok = 0;


  Standard_Real dmax = sqrt(dmax2);
  if(dmax > besttol) besttol = dmax;

  //On prend un multiple de l echantillon du CheckShape,
  //au moins les points de controle seront bons. No comment!!!

  Standard_Integer NCONTROL = 22;
#ifdef DEB
  Standard_Integer nbcoups = 0;
#endif
  
  Standard_Boolean interpolok = 0;
  Standard_Real tolsov = 1.e200;
  //On prend des parametres a pas constant sur la curve on surface
  //et sur la courbe 3d.
  Standard_Real deltacons = lcons - fcons;
  deltacons /= (NCONTROL);
  Standard_Real deltac3d = lc3d - fc3d;
  deltac3d /= (NCONTROL);

  Standard_Real wcons = fcons;
  Standard_Real wc3d  = fc3d;
  
  Standard_Real qpcons[MAX_ARRAY_SIZE], qnewpcons[MAX_ARRAY_SIZE], 
                qpc3d[MAX_ARRAY_SIZE], qnewpc3d[MAX_ARRAY_SIZE];
  Standard_Real * pcons = qpcons; Standard_Real * newpcons = qnewpcons;
  Standard_Real * pc3d = qpc3d; Standard_Real * newpc3d = qnewpc3d;

  for ( ii = 0 ; ii < NCONTROL; ii++) {
    pcons[ii] = wcons;
    pc3d[ii]  = wc3d;
    wcons += deltacons;
    wc3d  += deltac3d;
  }
  pcons[NCONTROL] = lcons;
  pc3d[NCONTROL]  = lc3d;

  Standard_Integer New_NCONTROL = NCONTROL;
  if(Continuity < GeomAbs_C1) {
     Standard_Integer NbInt = LocalHCurve2d->NbIntervals(GeomAbs_C1) + 1;
     TColStd_Array1OfReal Param_de_decoupeC1 (1, NbInt);
     LocalHCurve2d->Intervals(Param_de_decoupeC1, GeomAbs_C1);
     TColStd_SequenceOfReal new_par;
     Standard_Integer inter = 1;
     ii =1;
     new_par.Append(fcons);

     while(Param_de_decoupeC1(inter) <= fcons + deltamin) inter++;
     while(Param_de_decoupeC1(NbInt) >= lcons - deltamin) NbInt--;

     while(inter <= NbInt || ii < NCONTROL) {
       if(Param_de_decoupeC1(inter) < pcons[ii]) {
       new_par.Append(Param_de_decoupeC1(inter));
       if((pcons[ii] - Param_de_decoupeC1(inter)) <= deltamin) {
         ii++;
         if(ii > NCONTROL) {ii = NCONTROL;}
       }
       inter++;
       }
       else {
       if((Param_de_decoupeC1(inter) - pcons[ii]) > deltamin) {
         new_par.Append(pcons[ii]);
       }
       ii++;
       }
     }
     
     new_par.Append(lcons);
     New_NCONTROL = new_par.Length() - 1;
     //simple protection if New_NCONTROL > allocated elements in array
     if (New_NCONTROL > MAX_ARRAY_SIZE) {
       mySameParameter = Standard_False;
       return;
     }
     for(ii = 1; ii <= New_NCONTROL; ii++){
       pcons[ii] = pc3d[ii] = new_par.Value(ii + 1);
     }
     pc3d[New_NCONTROL]  = lc3d;
   }

  
  Extrema_LocateExtPC Projector;
  Projector.Initialize(myC3d->Curve(),fc3d,lc3d,Tol);
  
  Standard_Integer count = 1;
  Standard_Real previousp = fc3d, initp=0, curp;//, deltamin = 50*Tolp;
  Standard_Real bornesup = lc3d - deltamin;
  Standard_Boolean projok = 0, 
    use_parameter ;
  for (ii = 1; ii < New_NCONTROL; ii++){    
    CurveOnSurface.D0(pcons[ii],Pcons);
    myC3d->D0(pc3d[ii],Pc3d);
    dist2 = Pcons.SquareDistance(Pc3d);
    use_parameter = (dist2 <= Tol2  && (pc3d[ii] > pc3d[count-1] + deltamin)) ;
    if(use_parameter) {
      
      if(dist2 > dmax2) dmax2 = dist2;
      initp = previousp = pc3d[count] = pc3d[ii];
      pcons[count] = pcons[ii];
      count++;
    }
    else {
      if(!projok) initp = pc3d[ii];
      projok = mySameParameter = Standard_False;
      Projector.Perform(Pcons, initp);
      if (Projector.IsDone()) {
      curp = Projector.Point().Parameter();
      Standard_Real dist = Projector.Value();
      if(dist > besttol) besttol = dist;
      projok = 1;
      }
      else {
      ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp);
      }
      if(projok){
      if(curp > previousp + deltamin && curp < bornesup){
        initp = previousp = pc3d[count] = curp;
        pcons[count] = pcons[ii];
        count++;
      }
      }
      else {
#ifdef DEB 
      // JAG
      cout << "Projection not done" << endl;
#endif
      }
    }
  }
  if(mySameParameter){
    myTolReached = 1.5*sqrt(dmax2);
    return;
  }
 
  if(!extrok) { // Si pas deja SameP et tgte aux fraise, on abandonne.
    mySameParameter = Standard_False;
#ifdef DEB
    cout<<"SameParameter probleme  : tangente nulle aux extremites"<<endl;
#endif
    return;
  }

  pcons[count] = lcons;
  pc3d[count]  = lc3d;

#ifdef DEB
  if (AffichFw) {
    char Name[17];
    Name[0]='\0';
    TColgp_Array1OfPnt2d    DEBP2d  (0,count);
    TColStd_Array1OfInteger DEBMults(0,count); 
    DEBMults.Init(1); DEBMults(0) = 2; DEBMults(count) = 2;
    TColStd_Array1OfReal    DEBKnots(0,count);
    for (Standard_Integer DEBi = 0; DEBi <= count; DEBi++) {
      DEBKnots(DEBi) = DEBi;
      DEBP2d  (DEBi) = gp_Pnt2d(pc3d[DEBi],pcons[DEBi]);
    }
    Handle(Geom2d_BSplineCurve) DEBBS = 
      new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
    sprintf(Name,"DEBC2d_%d",++NbCurve);
#ifdef DRAW
    DrawTrSurf::Set(Name,DEBBS);
#endif
  }
#endif
    
  while(!interpolok){
    // Les tableaux et leurs bornes pour l interpolation.
    Standard_Integer num_knots = count + 7;
    Standard_Integer num_poles = count + 3;
    TColStd_Array1OfReal    Paramc3d(*pc3d,1,count+1);
    TColStd_Array1OfReal    Paramcons(*pcons,1,count+1);
    TColStd_Array1OfInteger ContactOrder(1,num_poles) ;
    TColStd_Array1OfReal    Poles(1,num_poles) ;
    TColStd_Array1OfReal    InterpolationParameters(1,num_poles) ;
    TColStd_Array1OfReal    FlatKnots(1,num_knots) ; 
    
    // On remplit les tableaux en faisant attention aux valeurs des bouts.
    ContactOrder.Init(0);
    ContactOrder(2) = ContactOrder(num_poles - 1) = 1;
    
    FlatKnots(1) = FlatKnots(2) = FlatKnots(3) = FlatKnots(4) = fc3d;
    FlatKnots(num_poles + 1) = FlatKnots(num_poles + 2) = 
      FlatKnots(num_poles + 3) = FlatKnots(num_poles + 4) = lc3d;
    
    Poles(1) = fcons; Poles(num_poles) = lcons;
    Poles(2) = tangent[0]; Poles(num_poles - 1) = tangent[1];
    
    InterpolationParameters(1) = InterpolationParameters(2) = fc3d;
    InterpolationParameters(num_poles - 1) = InterpolationParameters(num_poles) = lc3d;
    
    for (ii = 3; ii <= num_poles - 2; ii++) {
      Poles(ii) = Paramcons(ii - 1);
      InterpolationParameters(ii) = FlatKnots(ii+2) = Paramc3d(ii - 1);
    }
    Standard_Integer inversion_problem;
    BSplCLib::Interpolate(3,FlatKnots,InterpolationParameters,ContactOrder,
                    1,Poles(1),inversion_problem);
    if(inversion_problem) {
      Standard_ConstructionError::Raise();
    }
    LocalPolesPtr = &Poles ;
    LocalFlatKnotsPtr = &FlatKnots ;
//-------------------------------------------
#ifdef DEB
  if (AffichFw) {
    nbcoups ++;
    char Name[17];
    Name[0] = '\0';
    Standard_Integer nnn = 100;
    TColgp_Array1OfPnt2d    DEBP2d  (0,nnn);
    TColStd_Array1OfInteger DEBMults(0,nnn); 
    DEBMults.Init(1); DEBMults(0) = 2; DEBMults(nnn) = 2;
    TColStd_Array1OfReal    DEBKnots(0,nnn);
    Standard_Real du = (lc3d - fc3d) / nnn;
    Standard_Real u3d = fc3d, ucons;
    Standard_Integer extrap_mode[2] ;
    extrap_mode[0] = extrap_mode[1] = 3;
    Standard_Real eval_result[2] ;
    Standard_Integer DerivativeRequest = 0;
    Standard_Real *PolesArray =
      (Standard_Real *) &(*LocalPolesPtr)((*LocalPolesPtr).Lower()) ;

    for (Standard_Integer DEBi = 0; DEBi <= nnn; DEBi++) {
      DEBKnots(DEBi) = DEBi;
      BSplCLib::Eval(u3d,
                 Standard_False,
                 DerivativeRequest,
                 extrap_mode[0],
                 3,
                 *LocalFlatKnotsPtr,
                 1,
                 PolesArray[0],
                 eval_result[0]) ;

      DEBP2d  (DEBi) = gp_Pnt2d(u3d,eval_result[0]);
      u3d += du;
    }

    Handle(Geom2d_BSplineCurve) DEBBS = 
      new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
    sprintf(Name,"DEBC2d_%d_%d",NbCurve,nbcoups );
#ifdef DRAW
    DrawTrSurf::Set(Name,DEBBS);
#endif
  }
#endif
//-------------------------------------------    

//-------------------------------------------
    // Test if par2d(par3d) is monotonous function or not           ----- IFV, Jan 2000
    // and try to insert new point to improve BSpline interpolation

    Standard_Integer extrap_mode[2] ;
    extrap_mode[0] = extrap_mode[1] = 3;
    Standard_Real eval_result[2] ;
    Standard_Integer DerivativeRequest = 0;
    Standard_Real *PolesArray =
      (Standard_Real *) &(*LocalPolesPtr)((*LocalPolesPtr).Lower()) ;

    Standard_Integer newcount = 0;
    for (ii = 0; ii < count; ii++) {
      
      newpcons[newcount] = pcons[ii];
      newpc3d[newcount] = pc3d[ii];
      newcount++;

      if(count - ii + newcount == MAX_ARRAY_SIZE) continue;

      BSplCLib::Eval(.5*(pc3d[ii]+pc3d[ii+1]), Standard_False, DerivativeRequest,
                 extrap_mode[0], 3, *LocalFlatKnotsPtr, 1, PolesArray[0], eval_result[0]);
                 
      if(eval_result[0] < pcons[ii] || eval_result[0] > pcons[ii+1]) {
      Standard_Real ucons = 0.5*(pcons[ii]+pcons[ii+1]);
      Standard_Real uc3d  = 0.5*(pc3d[ii]+pc3d[ii+1]);
      
      CurveOnSurface.D0(ucons,Pcons);
      Projector.Perform(Pcons, uc3d);
      if (Projector.IsDone()) {
        curp = Projector.Point().Parameter();
        Standard_Real dist = Projector.Value();
        if(dist > besttol) besttol = dist;
        projok = 1;
      }
      else {
        ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
      }
      if(projok){
        if(curp > pc3d[ii] + deltamin && curp < pc3d[ii+1] - deltamin){
          newpc3d[newcount] = curp;
          newpcons[newcount] = ucons;
          newcount ++;
        }
      }
      else {
#ifdef DEB 
        // JAG
        cout << "Projection not done" << endl;
#endif
      }
      }
     
    }

    newpc3d[newcount] = pc3d[count];
    newpcons[newcount] = pcons[count];
    Standard_Real * temp;
    temp = pc3d;
    pc3d = newpc3d;
    newpc3d = temp;
    temp = pcons;
    pcons = newpcons;
    newpcons = temp;

    if((count != newcount) && newcount < MAX_ARRAY_SIZE) { count = newcount; continue;}

    count = newcount;

    Standard_Real algtol = besttol;

    interpolok = Check(count+1,Paramc3d,Paramcons,myC3d,CurveOnSurface,algtol,tolsov);

    if (Precision::IsInfinite(algtol)) {
      mySameParameter = Standard_False;
#ifdef DEB
      cout<<"SameParameter probleme  : fonction d'interpolation du parametrage aux fraises !!"<<endl;
#endif
      return;
    }

    tolsov = algtol;

    interpolok = (interpolok || count >= MAX_ARRAY_SIZE);

    if(interpolok) {
#ifdef DEB
      if (Voir) {
      if(algtol > besttol){
        cout<<"SameParameter : Tol non atteinte avant approx"<<endl;
      }
      }
#endif
      Handle(TColStd_HArray1OfReal) tol1d,tol2d,tol3d;
      tol1d = new TColStd_HArray1OfReal(1,2) ;
      tol1d->SetValue(1, mySurf->UResolution(besttol));
      tol1d->SetValue(2, mySurf->VResolution(besttol));
      AdvApprox_EvaluatorFunction ev =SameParameterEvaluator; 

 //     AdvApprox_ApproxAFunction  anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d,
      //                            GeomAbs_C1,11,40,ev);

      AdvApprox_ApproxAFunction  anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d,
                                    Continuity,11,40,ev);

      if (anApproximator.IsDone() || anApproximator.HasResult()) {
      GeomLib_MakeCurvefromApprox  aCurveBuilder(anApproximator) ;
      myCurve2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ;
      LocalHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d);
      CurveOnSurface.Load(LocalHCurve2d);
      myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL);
      myDone = Standard_True ;

      } 
    }
    else {
#ifdef DEB
      if (Voir)
      cout<<"SameParameter : Pas assez de points, on enrichit"<<endl;
#endif

      Standard_Integer newcount = 0;
      for(Standard_Integer n = 0; n < count; n++){
      newpc3d[newcount] = pc3d[n];
      newpcons[newcount] = pcons[n];
      newcount ++;

      if(count - n + newcount == MAX_ARRAY_SIZE) continue;

      Standard_Real ucons = 0.5*(pcons[n]+pcons[n+1]);
      Standard_Real uc3d  = 0.5*(pc3d[n]+pc3d[n+1]);
      
      CurveOnSurface.D0(ucons,Pcons);
      Projector.Perform(Pcons, uc3d);
      if (Projector.IsDone()) {
        curp = Projector.Point().Parameter();
        Standard_Real dist = Projector.Value();
        if(dist > besttol) besttol = dist;
        projok = 1;
      }
      else {
        ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
      }
      if(projok){
        if(curp > pc3d[n] + deltamin && curp < pc3d[n+1] - deltamin){
          newpc3d[newcount] = curp;
          newpcons[newcount] = ucons;
          newcount ++;
        }
      }
      else {
#ifdef DEB 
        // JAG
        cout << "Projection not done" << endl;
#endif
      }
      }
      newpc3d[newcount] = pc3d[count];
      newpcons[newcount] = pcons[count];
      Standard_Real * temp;
      temp = pc3d;
      pc3d = newpc3d;
      newpc3d = temp;
      temp = pcons;
      pcons = newpcons;
      newpcons = temp;
      count = newcount;
    }
  }
}

Generated by  Doxygen 1.6.0   Back to index