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

GeomConvert.cxx

// File GeomConvert.cxx 
// Jean-Claude Vauthier Novembre 1991
// Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline + Debug
// Modif JCV correction bug le 2/08/1993

#include <GeomConvert.ixx>

#include <BSplCLib.hxx>
#include <Convert_ConicToBSplineCurve.hxx>
#include <Convert_CircleToBSplineCurve.hxx>
#include <Convert_EllipseToBSplineCurve.hxx>
#include <Convert_HyperbolaToBSplineCurve.hxx>
#include <Convert_ParabolaToBSplineCurve.hxx>


#include <gp.hxx>

#include <gp_Circ2d.hxx>
#include <gp_Elips2d.hxx>
#include <gp_Parab2d.hxx>
#include <gp_Hypr2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Lin.hxx>
#include <gp_Ax3.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>

#include <Geom2d_BSplineCurve.hxx>

#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <GeomLProp.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_Parabola.hxx>
#include <Geom_Geometry.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Conic.hxx>
#include <GeomConvert_CompCurveToBSplineCurve.hxx>

#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_Array1OfBoolean.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColGeom_Array1OfCurve.hxx>

#include <Hermit.hxx>

#include <PLib.hxx>

#include <Precision.hxx>

#include <Standard_DomainError.hxx>
#include <Standard_ConstructionError.hxx>
#include <Geom_OffsetCurve.hxx>
#include <GeomConvert_ApproxCurve.hxx>

#include <ElCLib.hxx>

//=======================================================================
//function : BSplineCurveBuilder
//purpose  : 
//=======================================================================

static Handle(Geom_BSplineCurve) BSplineCurveBuilder 
       (const Handle(Geom_Conic)&          TheConic,
      const Convert_ConicToBSplineCurve& Convert) 

{
  Handle(Geom_BSplineCurve) TheCurve;
  Standard_Integer NbPoles = Convert.NbPoles();
  Standard_Integer NbKnots = Convert.NbKnots();
  TColgp_Array1OfPnt      Poles   (1, NbPoles);
  TColStd_Array1OfReal    Weights (1, NbPoles);
  TColStd_Array1OfReal    Knots   (1, NbKnots);
  TColStd_Array1OfInteger Mults   (1, NbKnots);
  Standard_Integer i;
  gp_Pnt2d P2d;
  gp_Pnt   P3d;
  for (i = 1; i <= NbPoles; i++) {
    P2d = Convert.Pole (i);
    P3d.SetCoord (P2d.X(), P2d.Y(), 0.0);
    Poles (i) = P3d;
    Weights (i) = Convert.Weight (i);         
  }
  for (i = 1; i <= NbKnots; i++) {
    Knots (i) = Convert.Knot (i);
    Mults (i) = Convert.Multiplicity (i);
  }
  TheCurve = 
    new Geom_BSplineCurve (Poles, Weights, Knots, Mults, 
                     Convert.Degree(), Convert.IsPeriodic());
  gp_Trsf T;
  T.SetTransformation (TheConic->Position(), gp::XOY());
  Handle(Geom_BSplineCurve) Cres;
  Cres = Handle(Geom_BSplineCurve)::DownCast(TheCurve->Transformed (T));
  return Cres;
}



//=======================================================================
//function : SplitBSplineCurve
//purpose  : 
//=======================================================================

Handle(Geom_BSplineCurve) GeomConvert::SplitBSplineCurve 
  (const Handle(Geom_BSplineCurve)& C,
   const Standard_Integer               FromK1, 
   const Standard_Integer               ToK2,
   const Standard_Boolean               SameOrientation) 
{
  Standard_Integer TheFirst = C->FirstUKnotIndex ();
  Standard_Integer TheLast  = C->LastUKnotIndex ();
  if (FromK1 == ToK2)  Standard_DomainError::Raise();
  Standard_Integer FirstK = Min (FromK1, ToK2);
  Standard_Integer LastK  = Max (FromK1, ToK2);
  if (FirstK < TheFirst || LastK > TheLast) Standard_DomainError::Raise();

  Handle(Geom_BSplineCurve) C1
    = Handle(Geom_BSplineCurve)::DownCast(C->Copy ());

  C1->Segment( C->Knot(FirstK),C->Knot(LastK));

  if (C->IsPeriodic()) {
    if (!SameOrientation) C1->Reverse();
  }
  else {
    if (FromK1 > ToK2)    C1->Reverse();
  }
  return C1;
}


//=======================================================================
//function : SplitBSplineCurve
//purpose  : 
//=======================================================================

Handle(Geom_BSplineCurve) GeomConvert::SplitBSplineCurve 
  (const Handle(Geom_BSplineCurve)& C, 
   const Standard_Real              FromU1, 
   const Standard_Real              ToU2,
   const Standard_Real              , //ParametricTolerance,
   const Standard_Boolean            SameOrientation    ) 
{
  Standard_Real FirstU = Min( FromU1, ToU2);
  Standard_Real LastU  = Max( FromU1, ToU2);

  Handle (Geom_BSplineCurve) C1 
    = Handle(Geom_BSplineCurve)::DownCast(C->Copy());

  C1->Segment(FirstU, LastU);

  if (C->IsPeriodic()) {
     if (!SameOrientation) C1->Reverse();
   }
  else {
    if (FromU1 > ToU2)    C1->Reverse();
  }

  return C1;
}




//=======================================================================
//function : CurveToBSplineCurve
//purpose  : 
//=======================================================================

Handle(Geom_BSplineCurve)  GeomConvert::CurveToBSplineCurve 
  (const Handle(Geom_Curve)&          C,
   const Convert_ParameterisationType Parameterisation) 
{
  Handle (Geom_BSplineCurve) TheCurve;

  if (C->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
    Handle(Geom_Curve) Curv;
    Handle(Geom_TrimmedCurve) Ctrim = Handle(Geom_TrimmedCurve)::DownCast(C);
    Curv = Ctrim->BasisCurve();
    Standard_Real U1 = Ctrim->FirstParameter();
    Standard_Real U2 = Ctrim->LastParameter();

    // Si la courbe n'est pas vraiment restreinte, on ne risque pas 
    // le Raise dans le BS->Segment.
    if (!Curv->IsPeriodic()) {
      if (U1 < Curv->FirstParameter())
      U1 =  Curv->FirstParameter();
      if (U2 > Curv->LastParameter())
      U2 = Curv->LastParameter();
    }

    if (Curv->IsKind(STANDARD_TYPE(Geom_Line))) {
       gp_Pnt Pdeb = Ctrim->StartPoint();
       gp_Pnt Pfin = Ctrim->EndPoint();
       TColgp_Array1OfPnt Poles (1, 2);
       Poles (1) = Pdeb;
       Poles (2) = Pfin;
       TColStd_Array1OfReal Knots (1, 2);
       Knots (1) = Ctrim->FirstParameter ();
       Knots (2) = Ctrim->LastParameter  ();
       TColStd_Array1OfInteger Mults (1, 2);
       Mults (1) = 2;
       Mults (2) = 2;
       Standard_Integer Degree = 1;
       TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
    }

    else if (Curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
      Handle(Geom_Circle) TheConic = Handle(Geom_Circle)::DownCast(Curv);
      gp_Circ2d C2d (gp::OX2d(), TheConic->Radius());
      if(Parameterisation != Convert_RationalC1) {
      Convert_CircleToBSplineCurve Convert (C2d,
                                    U1, 
                                    U2, 
                                    Parameterisation);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
      }
      else {
      if(U2 - U1 < 6.) {
        Convert_CircleToBSplineCurve Convert (C2d,
                                    U1, 
                                    U2, 
                                    Parameterisation);
        TheCurve = BSplineCurveBuilder (TheConic, Convert);
      }
      else { // split circle to avoide numerical 
             // overflow when U2 - U1 =~ 2*PI

        Standard_Real Umed = (U1 + U2) * .5;
        Convert_CircleToBSplineCurve Convert1 (C2d, 
                                     U1, 
                                     Umed, 
                                     Parameterisation);

        Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);

        Convert_CircleToBSplineCurve Convert2 (C2d, 
                                     Umed, 
                                     U2, 
                                     Parameterisation);

        Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);

        GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
                                          Parameterisation);

        CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);

        
        TheCurve = CCTBSpl.BSplineCurve();
      }
      }

    }

    else if (Curv->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
      Handle(Geom_Ellipse) TheConic = Handle(Geom_Ellipse)::DownCast(Curv);
      gp_Elips2d E2d (gp::OX2d(),
                  TheConic->MajorRadius(),
                  TheConic->MinorRadius());
      if(Parameterisation != Convert_RationalC1) {
      Convert_EllipseToBSplineCurve Convert (E2d, 
                                     U1, 
                                     U2,
                                     Parameterisation);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
      }
      else {
      if(U2 - U1 < 6.) {
        Convert_EllipseToBSplineCurve Convert (E2d, 
                                     U1, 
                                     U2,
                                     Parameterisation);
        TheCurve = BSplineCurveBuilder (TheConic, Convert);
      }     
      else { // split ellipse to avoide numerical 
             // overflow when U2 - U1 =~ 2*PI

        Standard_Real Umed = (U1 + U2) * .5;
        Convert_EllipseToBSplineCurve Convert1 (E2d, 
                                      U1, 
                                      Umed, 
                                      Parameterisation);

        Handle (Geom_BSplineCurve) TheCurve1 = BSplineCurveBuilder (TheConic, Convert1);

        Convert_EllipseToBSplineCurve Convert2 (E2d, 
                                    Umed, 
                                    U2, 
                                    Parameterisation);

        Handle (Geom_BSplineCurve) TheCurve2 = BSplineCurveBuilder (TheConic, Convert2);

        GeomConvert_CompCurveToBSplineCurve CCTBSpl(TheCurve1,
                                          Parameterisation);

        CCTBSpl.Add(TheCurve2, Precision::PConfusion(), Standard_True);

        
        TheCurve = CCTBSpl.BSplineCurve();
      }
      }
    }

    else if (Curv->IsKind(STANDARD_TYPE(Geom_Hyperbola))) {
      Handle(Geom_Hyperbola) TheConic = Handle(Geom_Hyperbola)::DownCast(Curv);
      gp_Hypr2d H2d (gp::OX2d(), 
                 TheConic->MajorRadius(), TheConic->MinorRadius());
      Convert_HyperbolaToBSplineCurve Convert (H2d, U1, U2);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
    }

    else if (Curv->IsKind(STANDARD_TYPE(Geom_Parabola))) {
      Handle(Geom_Parabola) TheConic = Handle(Geom_Parabola)::DownCast(Curv);
      gp_Parab2d Prb2d (gp::OX2d(), TheConic->Focal());
      Convert_ParabolaToBSplineCurve Convert (Prb2d, U1, U2);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
    }

    else if (Curv->IsKind (STANDARD_TYPE(Geom_BezierCurve))) {
 
      Handle(Geom_BezierCurve) CBez 
      = Handle(Geom_BezierCurve)::DownCast(Curv->Copy());
      CBez->Segment (U1, U2);
      Standard_Integer NbPoles = CBez->NbPoles();
      Standard_Integer Degree  = CBez->Degree();
      TColgp_Array1OfPnt     Poles   (1, NbPoles);
      TColStd_Array1OfReal    Knots   (1, 2);
      TColStd_Array1OfInteger Mults   (1, 2);
      Knots (1) = 0.0;
      Knots (2) = 1.0;
      Mults (1) = Degree + 1;
      Mults (2) = Degree + 1;
      CBez->Poles (Poles);
      if (CBez->IsRational()) {    
        TColStd_Array1OfReal    Weights (1, NbPoles);
        CBez->Weights (Weights);
        TheCurve = 
        new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
      }
      else {
        TheCurve = 
        new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
      }
    }
    else if (Curv->IsKind (STANDARD_TYPE(Geom_BSplineCurve))) {
      TheCurve = Handle(Geom_BSplineCurve)::DownCast(Curv->Copy());
      //// modified by jgv, 14.01.05 for OCC7355 ////
      if (TheCurve->IsPeriodic())
      {
        Standard_Real Uf = TheCurve->FirstParameter();
        Standard_Real Ul = TheCurve->LastParameter();
        ElCLib::AdjustPeriodic( Uf, Ul, Precision::Confusion(), U1, U2 );
        if (Abs(U1 - Uf) <= Precision::Confusion() &&
            Abs(U2 - Ul) <= Precision::Confusion())
          TheCurve->SetNotPeriodic();
      }
      ///////////////////////////////////////////////
      TheCurve->Segment(U1,U2);
    }
    else if (Curv->IsKind (STANDARD_TYPE(Geom_OffsetCurve))) {
     Standard_Real Tol3d = 1.e-4;
     GeomAbs_Shape Order = GeomAbs_C2;
     Standard_Integer MaxSegments = 16, MaxDegree = 14; 
     GeomConvert_ApproxCurve ApprCOffs(C, Tol3d, Order, 
                               MaxSegments, MaxDegree);
     if (ApprCOffs.HasResult())
       TheCurve = ApprCOffs.Curve();
     else  Standard_ConstructionError::Raise();
    }
    else { Standard_DomainError::Raise("No such curve"); }
  }

  else { 
    if (C->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
      Handle(Geom_Ellipse) TheConic= Handle(Geom_Ellipse)::DownCast(C);
      gp_Elips2d E2d (gp::OX2d(), 
                  TheConic->MajorRadius(), TheConic->MinorRadius());
/*      if (Parameterisation == Convert_TgtThetaOver2_1 ||
        Parameterisation == Convert_TgtThetaOver2_2) {
      Standard_DomainError::Raise(); }
 
      else if ( Parameterisation == Convert_QuasiAngular) {
      Convert_EllipseToBSplineCurve Convert (E2d,
                                     0.0e0,
                                     2.0e0 * PI,
                                     Parameterisation);

      TheCurve = BSplineCurveBuilder (TheConic, Convert);
      TheCurve->SetPeriodic();
      }
      else {*/
      Convert_EllipseToBSplineCurve Convert (E2d,
                                    Parameterisation);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
        TheCurve->SetPeriodic(); // pour polynomial et quasi angular
//      }
    }
    
    else if (C->IsKind(STANDARD_TYPE(Geom_Circle))) {
      Handle(Geom_Circle) TheConic = Handle(Geom_Circle)::DownCast(C);
      gp_Circ2d C2d (gp::OX2d(), TheConic->Radius());
/*      if (Parameterisation == Convert_TgtThetaOver2_1 ||
        Parameterisation == Convert_TgtThetaOver2_2) {
      Standard_DomainError::Raise(); }
 
      else if ( Parameterisation == Convert_QuasiAngular) {
      Convert_CircleToBSplineCurve Convert (C2d,
                                    0.0e0,
                                    2.0e0 * PI,
                                    Parameterisation);
      
      TheCurve = BSplineCurveBuilder (TheConic, Convert);                          
      }
      else {*/
      Convert_CircleToBSplineCurve Convert (C2d,
                                    Parameterisation);
      TheCurve = BSplineCurveBuilder (TheConic, Convert);
      TheCurve->SetPeriodic();
//      }
    }
    
    else if (C->IsKind (STANDARD_TYPE(Geom_BezierCurve))) {
      Handle(Geom_BezierCurve) CBez= Handle(Geom_BezierCurve)::DownCast(C);
      Standard_Integer NbPoles = CBez->NbPoles();
      Standard_Integer Degree  = CBez->Degree();
      TColgp_Array1OfPnt     Poles   (1, NbPoles);
      TColStd_Array1OfReal    Knots   (1, 2);
      TColStd_Array1OfInteger Mults   (1, 2);
      Knots (1) = 0.0;
      Knots (2) = 1.0;
      Mults (1) = Degree + 1;
      Mults (2) = Degree + 1;
      CBez->Poles (Poles);
      if (CBez->IsRational()) {    
      TColStd_Array1OfReal    Weights (1, NbPoles);
      CBez->Weights (Weights);
      TheCurve = 
        new Geom_BSplineCurve (Poles, Weights, Knots, Mults, Degree);
      }
      else {
      TheCurve = new Geom_BSplineCurve (Poles, Knots, Mults, Degree);
      }
    }
    
    else if (C->IsKind (STANDARD_TYPE(Geom_BSplineCurve))) {
      TheCurve = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
    }

    else if (C->IsKind (STANDARD_TYPE(Geom_OffsetCurve))) {
     Standard_Real Tol3d = 1.e-4;
     GeomAbs_Shape Order = GeomAbs_C2;
     Standard_Integer MaxSegments = 16, MaxDegree = 14; 
     GeomConvert_ApproxCurve ApprCOffs(C, Tol3d, Order, 
                               MaxSegments, MaxDegree);
     if (ApprCOffs.HasResult())
       TheCurve = ApprCOffs.Curve();
     else  Standard_ConstructionError::Raise();
   }
    else { Standard_DomainError::Raise("No such curve"); }
  }
  
  return TheCurve;
}


//=======================================================================
//function : law_evaluator
//purpose  : usefull to estimate the value of a function
//=======================================================================

static Handle(Geom2d_BSplineCurve) Ancore = NULL ;

static void law_evaluator(const Standard_Integer  DerivativeRequest,
                    const Standard_Real    *StartEnd,
                    const Standard_Real     Parameter,
                    Standard_Real &         Result,
                    Standard_Integer &      ErrorCode)
{ErrorCode = 0 ; 
 if (!Ancore.IsNull() && 
     Parameter >= StartEnd[0] &&
     Parameter <= StartEnd[1] && 
     DerivativeRequest == 0){
   gp_Pnt2d a_point ;
   Ancore->D0(Parameter,
            a_point) ;
   Result = a_point.Coord(2) ;
 }    
 else 
   ErrorCode = 1 ;
}

//=======================================================================
//function : MultNumandDenom
//purpose  : Multiply two BSpline curves to make one
//=======================================================================


static Handle(Geom_BSplineCurve) MultNumandDenom(const Handle(Geom2d_BSplineCurve)& a ,
                                     const Handle(Geom_BSplineCurve)&   BS )
     
{ TColStd_Array1OfReal               aKnots(1,a->NbKnots());
  TColStd_Array1OfReal               BSKnots(1,BS->NbKnots());
  TColStd_Array1OfReal               BSFlatKnots(1,BS->NbPoles()+BS->Degree()+1);
  TColStd_Array1OfReal               BSWeights(1,BS->NbPoles()); 
  TColStd_Array1OfInteger            aMults(1,a->NbKnots());
  TColStd_Array1OfInteger            BSMults(1,BS->NbKnots());
  TColgp_Array1OfPnt2d               aPoles(1,a->NbPoles());
  TColgp_Array1OfPnt                 BSPoles(1,BS->NbPoles());
  Handle(Geom_BSplineCurve)          res;
  Handle(TColStd_HArray1OfReal)      resKnots;
  Handle(TColStd_HArray1OfInteger)   resMults; 
  Standard_Real                      start_value,end_value;
  Standard_Real                      tolerance=Precision::PConfusion();
  Standard_Integer                   resNbPoles,degree,
                                     ii,jj,
                             Status;
  
  BS->Knots(BSKnots);            //storage of the two BSpline 
  BS->Multiplicities(BSMults);   //features
  BS->Poles(BSPoles);
  BS->Weights(BSWeights);
  BS->KnotSequence(BSFlatKnots);
  start_value = BSKnots(1);
  end_value = BSKnots(BS->NbKnots());
  if ((end_value - start_value)/5 < tolerance) 
    tolerance = (end_value - start_value)/5;

  a->Knots(aKnots);
  a->Poles(aPoles);
  a->Multiplicities(aMults);
  BSplCLib::Reparametrize(BS->FirstParameter(),BS->LastParameter(),aKnots);
  Ancore= new Geom2d_BSplineCurve(aPoles,aKnots,aMults,a->Degree());     //call of the law-evaluator

  BSplCLib::MergeBSplineKnots(tolerance,start_value,end_value, //merge of the knots
                        a->Degree(),aKnots,aMults,
                        BS->Degree(),BSKnots,BSMults,
                        resNbPoles,resKnots,resMults);
  degree=BS->Degree()+a->Degree();
  TColgp_Array1OfPnt resNumPoles(1,resNbPoles);
  TColStd_Array1OfReal resDenPoles(1,resNbPoles);
  TColgp_Array1OfPnt resPoles(1,resNbPoles);
  TColStd_Array1OfReal resFlatKnots(1,resNbPoles+degree+1);
  BSplCLib::KnotSequence(resKnots->Array1(),resMults->Array1(),resFlatKnots);
  for (ii=1;ii<=BS->NbPoles();ii++)
    for (jj=1;jj<=3;jj++)
      BSPoles(ii).SetCoord(jj,BSPoles(ii).Coord(jj)*BSWeights(ii));
//POP pour WNT
  BSplCLib_EvaluatorFunction ev = law_evaluator;
                            
  BSplCLib::FunctionMultiply(ev,                             
                       BS->Degree(),
                       BSFlatKnots,
                       BSPoles,
                       resFlatKnots,
                       degree,
                       resNumPoles,
                       Status);

  BSplCLib::FunctionMultiply(ev,
                       BS->Degree(),
                       BSFlatKnots,
                       BSWeights,
                       resFlatKnots,
                       degree,
                       resDenPoles,
                       Status);
  for (ii=1;ii<=resNbPoles;ii++)
    for(jj=1;jj<=3;jj++) 
      resPoles(ii).SetCoord(jj,resNumPoles(ii).Coord(jj)/resDenPoles(ii));
  res = new Geom_BSplineCurve(resPoles,resDenPoles,resKnots->Array1(),resMults->Array1(),degree);
  return res;
}

//=======================================================================
//function : Pretreatment 
//purpose  : Put the two first and two last weigths at one if they are 
//           equal
//=======================================================================

static void Pretreatment(TColGeom_Array1OfBSplineCurve& tab)

{Standard_Integer i,j;
 Standard_Real a;

 for (i=0;i<=(tab.Length()-1);i++){
   if (tab(i)->IsRational()) {
     a=tab(i)->Weight(1);                                 
     if ((tab(i)->Weight(2)==a)&&
       (tab(i)->Weight(tab(i)->NbPoles()-1)==a)&&
       (tab(i)->Weight(tab(i)->NbPoles())==a))
       
       for (j=1;j<=tab(i)->NbPoles();j++)
       tab(i)->SetWeight(j,tab(i)->Weight(j)/a);
   }
 }
}
       
//=======================================================================
//function : NeedToBeTreated
//purpose  : Say if the BSpline is rationnal and if the two first and two
//           last weigths are different
//=======================================================================    

static Standard_Boolean NeedToBeTreated(const Handle(Geom_BSplineCurve)& BS)

{
  TColStd_Array1OfReal  tabWeights(1,BS->NbPoles());
  if (BS->IsRational()) {
    BS->Weights(tabWeights);
    if ((BSplCLib::IsRational(tabWeights,1,BS->NbPoles()))&&
      ((BS->Weight(1)<(1-Precision::Confusion()))||
       (BS->Weight(1)>(1+Precision::Confusion()))||
       (BS->Weight(2)<(1-Precision::Confusion()))||
       (BS->Weight(2)>(1+Precision::Confusion()))||
       (BS->Weight(BS->NbPoles()-1)<(1-Precision::Confusion()))||
       (BS->Weight(BS->NbPoles()-1)>(1+Precision::Confusion()))||
       (BS->Weight(BS->NbPoles())<(1-Precision::Confusion()))||
       (BS->Weight(BS->NbPoles())>(1+Precision::Confusion()))))
      return Standard_True;
    else
      return Standard_False;
  }
  else 
    return Standard_False ;
 
}

//=======================================================================
//function : Need2DegRepara
//purpose  : in the case of wire closed G1 it says if you will to use a 
//           two degree reparametrisation to close it C1
//=======================================================================

static Standard_Boolean Need2DegRepara(const TColGeom_Array1OfBSplineCurve& tab)

{Standard_Integer        i;
 gp_Vec                  Vec1,Vec2;
 gp_Pnt                  Pint;
 Standard_Real           Rapport=1.0e0;

 for (i=0;i<=tab.Length()-2;i++){
   tab(i+1)->D1(tab(i+1)->FirstParameter(),Pint,Vec1);
   tab(i)->D1(tab(i)->LastParameter(),Pint,Vec2);
   Rapport=Rapport*Vec2.Magnitude()/Vec1.Magnitude();
 }
 if ((Rapport<=(1.0e0+Precision::Confusion()))&&(Rapport>=(1.0e0-Precision::Confusion())))
   return Standard_False;
 else
   return Standard_True;
}

//=======================================================================
//function : Indexmin
//purpose  : Give the index of the curve which has the lowest degree
//=======================================================================

static Standard_Integer Indexmin(const TColGeom_Array1OfBSplineCurve& tab)
{
  Standard_Integer i = 0, index = 0, degree = 0;
  
  degree=tab(0)->Degree();
  for (i=0;i<=tab.Length()-1;i++)
    if (tab(i)->Degree()<=degree){
      degree=tab(i)->Degree();
      index=i;
    }
  return index;
}

//=======================================================================
//function : NewTabClosedG1
//purpose  : Sort the array of BSplines to start at the nb_vertex_group0 index
//=======================================================================

static void ReorderArrayOfG1Curves(TColGeom_Array1OfBSplineCurve&    ArrayOfCurves, 
                     TColStd_Array1OfReal&             ArrayOfToler,
                     TColStd_Array1OfBoolean&          tabG1,
                     const Standard_Integer            StartIndex,
                     const Standard_Real               ClosedTolerance)

{Standard_Integer i;
 TColGeom_Array1OfBSplineCurve  ArraybisOfCurves(0,ArrayOfCurves.Length()-1);  //temporary
 TColStd_Array1OfReal           ArraybisOfToler(0,ArrayOfToler.Length()-1);    //arrays
 TColStd_Array1OfBoolean        tabbisG1(0,tabG1.Length()-1);

 for (i=0;i<=ArrayOfCurves.Length()-1;i++){
   if (i!=ArrayOfCurves.Length()-1){
     ArraybisOfCurves(i)=ArrayOfCurves(i);
     ArraybisOfToler(i)=ArrayOfToler(i);
     tabbisG1(i)=tabG1(i);
   }
   else
     ArraybisOfCurves(i)=ArrayOfCurves(i);
 }

 for (i=0;i<=(ArrayOfCurves.Length()-(StartIndex+2));i++){
   ArrayOfCurves(i)=ArraybisOfCurves(i+StartIndex+1);
   if (i!=(ArrayOfCurves.Length()-(StartIndex+2))){
     ArrayOfToler(i)=ArraybisOfToler(i+StartIndex+1);
     tabG1(i)=tabbisG1(i+StartIndex+1);
   }
 }

 ArrayOfToler(ArrayOfCurves.Length()-(StartIndex+2))=ClosedTolerance;
 tabG1(ArrayOfCurves.Length()-(StartIndex+2))=Standard_True;

 for (i=(ArrayOfCurves.Length()-(StartIndex+1));i<=(ArrayOfCurves.Length()-1);i++){
   if (i!=ArrayOfCurves.Length()-1){
     ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
     ArrayOfToler(i)=ArraybisOfToler(i-(ArrayOfCurves.Length()-(StartIndex+1)));
     tabG1(i)=tabbisG1(i-(ArrayOfCurves.Length()-(StartIndex+1)));
   }
   else
     ArrayOfCurves(i)=ArraybisOfCurves(i-(ArrayOfCurves.Length()-(StartIndex+1)));
 }
}

//=======================================================================
//function :reparameterise_evaluator 
//purpose  : 
//=======================================================================

static  Standard_Real  polynomial_coefficient[3] ;

static void reparameterise_evaluator(
                    const Standard_Integer  DerivativeRequest,
//                  const Standard_Real    *StartEnd,
                    const Standard_Real    *,
                    const Standard_Real     Parameter,
                    Standard_Real &         Result,
                    Standard_Integer &      ErrorCode) {
  ErrorCode = 0 ;
 PLib::EvalPolynomial(Parameter,
                  DerivativeRequest,
                  2,
                  1,
                  polynomial_coefficient[0],
                  Result) ;
}

//=======================================================================
//function : ConcatG1
//purpose  : 
//=======================================================================

00757  void  GeomConvert::ConcatG1(TColGeom_Array1OfBSplineCurve&           ArrayOfCurves, 
                       const TColStd_Array1OfReal&              ArrayOfToler,
                       Handle(TColGeom_HArray1OfBSplineCurve) & ArrayOfConcatenated,
                       const Standard_Boolean                   ClosedG1Flag,
                       const Standard_Real                      ClosedTolerance) 

{Standard_Integer             nb_curve=ArrayOfCurves.Length(),
                              nb_vertexG1=0,
                              nb_group=0,
                              index=0,i,ii,j,jj,
                              indexmin,
                              nb_vertex_group0=0;
 Standard_Real                lambda,                      //G1 coefficient
                              First;
 Standard_Real PreLast = 0.;
 GeomAbs_Shape                Cont;
 gp_Vec                       Vec1,Vec2;                   //concecutive tangential vectors 
 gp_Pnt                       Pint;
 Handle(Geom_BSplineCurve)    Curve1,Curve2;                       
 TColStd_Array1OfBoolean      tabG1(0,nb_curve-2);         //array of the G1 continuity at the intersections
 TColStd_Array1OfReal         local_tolerance(0,
                                    ArrayOfToler.Length()-1) ;
 
 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
   local_tolerance(i) = ArrayOfToler(i) ;
 }
 for (i=0 ;i<nb_curve; i++){
   if (i >= 1){
     First=ArrayOfCurves(i)->FirstParameter();
     Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
                          ArrayOfCurves(i),
                          PreLast,First,
                          Standard_True,Standard_True);
     if (Cont<GeomAbs_C0)
       Standard_ConstructionError::Raise("GeomConvert curves not C0") ;                
     else{
       if (Cont>=GeomAbs_G1)
       tabG1(i-1)=Standard_True;                   //True=G1 continuity
       else 
       tabG1(i-1)=Standard_False;
     }
   }
   PreLast=ArrayOfCurves(i)->LastParameter();     
 }
 

 while (index<=nb_curve-1){ //determination of the Wire features
   nb_vertexG1=0;
   while(((index+nb_vertexG1)<=nb_curve-2)&&
       (tabG1(index+nb_vertexG1)==Standard_True))
     nb_vertexG1++;
   nb_group++;
   if (index==0)
     nb_vertex_group0=nb_vertexG1;
   index=index+1+nb_vertexG1;
 }

 if ((ClosedG1Flag)&&(nb_group!=1)){                            //sort of the array
   nb_group--;
   ReorderArrayOfG1Curves(ArrayOfCurves,
              local_tolerance,
              tabG1,
              nb_vertex_group0,
              ClosedTolerance);
 }

 ArrayOfConcatenated = new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);
 Standard_Boolean       fusion;

 index=0;
 Pretreatment(ArrayOfCurves);

 if ((nb_group==1) && (ClosedG1Flag)){ //treatment of a particular case
   indexmin=Indexmin(ArrayOfCurves);
   if (indexmin!=(ArrayOfCurves.Length()-1))
     ReorderArrayOfG1Curves(ArrayOfCurves,
                local_tolerance,
                tabG1,
                indexmin,
                ClosedTolerance);
   Curve2=ArrayOfCurves(0);
   for (j=1;j<=nb_curve-1;j++){                          //secondary loop inside each group
     Curve1=ArrayOfCurves(j);
     if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){ 
       Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
       Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
       lambda=Vec2.Magnitude()/Vec1.Magnitude();
       TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
       Curve1->Knots(KnotC1);
       Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
       ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
       Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
       Standard_Real tmax,a,b,c,
       umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
       tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
       a=(lambda*lambda2-1)/(2*lambda*tmax);
       polynomial_coefficient[2]=a;              
       b=(1/lambda); 
       polynomial_coefficient[1]=b;
       c=umin;
       polynomial_coefficient[0]=c;
       TColStd_Array1OfReal  Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
       TColStd_Array1OfInteger  KnotC1Mults(1,Curve1->NbKnots());
       Curve1->Multiplicities(KnotC1Mults);
       BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
       KnotC1(1)=0.0;
       for (ii=2;ii<=KnotC1.Length();ii++) {
//     KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
       KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
       }
       TColgp_Array1OfPnt  Curve1Poles(1,Curve1->NbPoles());
       Curve1->Poles(Curve1Poles);
       
       for (ii=1;ii<=Curve1->NbKnots();ii++)
       KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
       
       TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
       
       BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
       TColgp_Array1OfPnt  NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
       Standard_Integer      Status;
       TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
       Curve1->Weights(Curve1Weights);
       for (ii=1;ii<=Curve1->NbPoles();ii++)
       for (jj=1;jj<=3;jj++)
         Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
//POP pour WNT
       BSplCLib_EvaluatorFunction ev = reparameterise_evaluator;
//       BSplCLib::FunctionReparameterise(reparameterise_evaluator,
       BSplCLib::FunctionReparameterise(ev,
                              Curve1->Degree(),
                              Curve1FlatKnots,
                              Curve1Poles,
                              FlatKnots,
                              2*Curve1->Degree(),
                              NewPoles,
                              Status
                              );
       TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
//       BSplCLib::FunctionReparameterise(reparameterise_evaluator,
       BSplCLib::FunctionReparameterise(ev,
                              Curve1->Degree(),
                              Curve1FlatKnots,
                              Curve1Weights,
                              FlatKnots,
                              2*Curve1->Degree(),
                              NewWeights,
                              Status
                              );
       for (ii=1;ii<=NewPoles.Length();ii++)
       for (jj=1;jj<=3;jj++)
         NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
       Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
     }
     GeomConvert_CompCurveToBSplineCurve   C(Handle(Geom_BSplineCurve)::DownCast(Curve2));
     fusion=C.Add(Curve1,
              local_tolerance(j-1));                //merge of two consecutive curves               
     if (fusion==Standard_False)
       Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
     Curve2=C.BSplineCurve();
   }
   Standard_Boolean   rm;
   Curve2->SetPeriodic();      
   rm=Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
                   Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
                   Precision::Confusion());
   ArrayOfConcatenated->SetValue(0,Curve2);
 }
 
 else
   for (i=0;i<=nb_group-1;i++){                             //principal loop on each G1 continuity 
     nb_vertexG1=0;                                         //group
     
     while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
       nb_vertexG1++;
      
     for (j=index;j<=index+nb_vertexG1;j++){                //secondary loop inside each group
       Curve1=ArrayOfCurves(j);
       
       if (index==j)                                        //initialisation at the begining of the loop
       ArrayOfConcatenated->SetValue(i,Curve1);
       else{
       GeomConvert_CompCurveToBSplineCurve   C(Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(i)));
       fusion=C.Add(Curve1,ArrayOfToler(j-1));            //merge of two consecutive curves               
       if (fusion==Standard_False)
         Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
       ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
       }
     }
     index=index+1+nb_vertexG1;
   }
}  
//=======================================================================
//function : ConcatC1
//purpose  : 
//=======================================================================

00954 void  GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve&           ArrayOfCurves, 
                      const TColStd_Array1OfReal&              ArrayOfToler,
                      Handle(TColStd_HArray1OfInteger)&        ArrayOfIndices,
                      Handle(TColGeom_HArray1OfBSplineCurve)&  ArrayOfConcatenated,
                      const Standard_Boolean                   ClosedG1Flag,
                      const Standard_Real                      ClosedTolerance) 
{
  ConcatC1(ArrayOfCurves,
         ArrayOfToler,
         ArrayOfIndices,
         ArrayOfConcatenated,
         ClosedG1Flag,
         ClosedTolerance,
         Precision::Angular()) ;
}
//=======================================================================
//function : ConcatC1
//purpose  : 
//=======================================================================

00974 void  GeomConvert::ConcatC1(TColGeom_Array1OfBSplineCurve&           ArrayOfCurves, 
                      const TColStd_Array1OfReal&              ArrayOfToler,
                      Handle(TColStd_HArray1OfInteger)&        ArrayOfIndices,
                      Handle(TColGeom_HArray1OfBSplineCurve)&  ArrayOfConcatenated,
                      const Standard_Boolean                   ClosedG1Flag,
                      const Standard_Real                      ClosedTolerance,
                      const Standard_Real                      AngularTolerance)

{Standard_Integer             nb_curve=ArrayOfCurves.Length(),
                              nb_vertexG1,
                              nb_group=0,
                              index=0,i,ii,j,jj,
                              indexmin,
                              nb_vertex_group0=0;
 Standard_Real                lambda,                      //G1 coefficient
                              First;
 Standard_Real PreLast = 0.;

 GeomAbs_Shape                Cont;
 gp_Vec                       Vec1,Vec2;                   //concecutive tangential vectors
 gp_Pnt                       Pint;
 Handle(Geom_BSplineCurve)    Curve1,Curve2;                       
 TColStd_Array1OfBoolean      tabG1(0,nb_curve-2);         //array of the G1 continuity at the intersections
 TColStd_Array1OfReal         local_tolerance(0,
                                    ArrayOfToler.Length()-1) ;
 
 for (i=0 ; i < ArrayOfToler.Length() ; i++) {
   local_tolerance(i) = ArrayOfToler(i) ;
 }
 for (i=0 ;i<nb_curve; i++){
   if (i >= 1){
     First=ArrayOfCurves(i)->FirstParameter();
     Cont = GeomLProp::Continuity(ArrayOfCurves(i-1),
                         ArrayOfCurves(i),
                         PreLast,
                         First,
                         Standard_True,
                         Standard_True,
                         local_tolerance(i-1),
                         AngularTolerance);
     if (Cont<GeomAbs_C0)
       Standard_ConstructionError::Raise("GeomConvert curves not C0");
     else{
       if (Cont>=GeomAbs_G1)
       tabG1(i-1)=Standard_True;                   //True=G1 continuity
       else 
       tabG1(i-1)=Standard_False;
     }
   }
   PreLast=ArrayOfCurves(i)->LastParameter();     
 }
 

 while (index<=nb_curve-1){                                 //determination of the Wire features
   nb_vertexG1=0;
   while(((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
     nb_vertexG1++;
   nb_group++;
   if (index==0)
     nb_vertex_group0=nb_vertexG1;
   index=index+1+nb_vertexG1;
 }

 if ((ClosedG1Flag)&&(nb_group!=1)){                            //sort of the array
   nb_group--;
   ReorderArrayOfG1Curves(ArrayOfCurves,
                    local_tolerance,
                    tabG1,
                    nb_vertex_group0,
                    ClosedTolerance);
 }

 ArrayOfIndices = 
   new TColStd_HArray1OfInteger(0,nb_group);
 ArrayOfConcatenated = 
   new TColGeom_HArray1OfBSplineCurve(0,nb_group-1);

 Standard_Boolean       fusion;
 Standard_Integer       k=0;
 index=0;
 Pretreatment(ArrayOfCurves);

 if ((nb_group==1) && (ClosedG1Flag)){                       //treatment of a particular case
   ArrayOfIndices->SetValue(0,0);
   ArrayOfIndices->SetValue(1,0);
   indexmin=Indexmin(ArrayOfCurves);
   if (indexmin!=(ArrayOfCurves.Length()-1))
     ReorderArrayOfG1Curves(ArrayOfCurves,
                      local_tolerance,
                      tabG1,
                      indexmin,
                      ClosedTolerance);
   for (j=0;j<=nb_curve-1;j++){                          //secondary loop inside each group
     if (NeedToBeTreated(ArrayOfCurves(j)))
       Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
     else
       Curve1=ArrayOfCurves(j);
     
     if (j==0)                                           //initialisation at the begining of the loop
       Curve2=Curve1;
     else{
       if ( (j==(nb_curve-1)) &&(Need2DegRepara(ArrayOfCurves))){ 
       Curve2->D1(Curve2->LastParameter(),Pint,Vec1);
       Curve1->D1(Curve1->FirstParameter(),Pint,Vec2);
       lambda=Vec2.Magnitude()/Vec1.Magnitude();
       TColStd_Array1OfReal KnotC1 (1, Curve1->NbKnots());
       Curve1->Knots(KnotC1);
       Curve1->D1(Curve1->LastParameter(),Pint,Vec2);
       ArrayOfCurves(0)->D1(ArrayOfCurves(0)->FirstParameter(),Pint,Vec1);
       Standard_Real lambda2=Vec1.Magnitude()/Vec2.Magnitude();
       Standard_Real tmax,a,b,c,
       umin=Curve1->FirstParameter(),umax=Curve1->LastParameter();
       tmax=2*lambda*(umax-umin)/(1+lambda*lambda2);
       a=(lambda*lambda2-1)/(2*lambda*tmax);
       polynomial_coefficient[2]=a;              
       b=(1/lambda); 
       polynomial_coefficient[1]=b;
       c=umin;
       polynomial_coefficient[0]=c;
       TColStd_Array1OfReal  Curve1FlatKnots(1,Curve1->NbPoles()+Curve1->Degree()+1);
       TColStd_Array1OfInteger  KnotC1Mults(1,Curve1->NbKnots());
       Curve1->Multiplicities(KnotC1Mults);
       BSplCLib::KnotSequence(KnotC1,KnotC1Mults,Curve1FlatKnots);
       KnotC1(1)=0.0;
       for (ii=2;ii<=KnotC1.Length();ii++) {
//       KnotC1(ii)=(-b+Abs(a)/a*Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a);
         KnotC1(ii)=(-b+Sqrt(b*b-4*a*(c-KnotC1(ii))))/(2*a); // ifv 17.05.00 buc60667
       }
       TColgp_Array1OfPnt  Curve1Poles(1,Curve1->NbPoles());
       Curve1->Poles(Curve1Poles);
       
       for (ii=1;ii<=Curve1->NbKnots();ii++)
         KnotC1Mults(ii)=(Curve1->Degree()+KnotC1Mults(ii));
       
       TColStd_Array1OfReal FlatKnots(1,Curve1FlatKnots.Length()+(Curve1->Degree()*Curve1->NbKnots()));
       
       BSplCLib::KnotSequence(KnotC1,KnotC1Mults,FlatKnots);
       TColgp_Array1OfPnt  NewPoles(1,FlatKnots.Length()-(2*Curve1->Degree()+1));
       Standard_Integer      Status;
       TColStd_Array1OfReal Curve1Weights(1,Curve1->NbPoles());
       Curve1->Weights(Curve1Weights);
       for (ii=1;ii<=Curve1->NbPoles();ii++)
         for (jj=1;jj<=3;jj++)
           Curve1Poles(ii).SetCoord(jj,Curve1Poles(ii).Coord(jj)*Curve1Weights(ii));
//POP pour WNT
       BSplCLib_EvaluatorFunction ev = reparameterise_evaluator;

       BSplCLib::FunctionReparameterise(ev,
                                Curve1->Degree(),
                                Curve1FlatKnots,
                                Curve1Poles,
                                FlatKnots,
                                2*Curve1->Degree(),
                                NewPoles,
                                Status
                                );
       TColStd_Array1OfReal NewWeights(1,FlatKnots.Length()-(2*Curve1->Degree()+1));

       BSplCLib::FunctionReparameterise(ev,
                                Curve1->Degree(),
                                Curve1FlatKnots,
                                Curve1Weights,
                                FlatKnots,
                                2*Curve1->Degree(),
                                NewWeights,
                                Status
                                );
       for (ii=1;ii<=NewPoles.Length();ii++)
         for (jj=1;jj<=3;jj++)
           NewPoles(ii).SetCoord(jj,NewPoles(ii).Coord(jj)/NewWeights(ii));
       Curve1= new Geom_BSplineCurve(NewPoles,NewWeights,KnotC1,KnotC1Mults,2*Curve1->Degree());
       }
       GeomConvert_CompCurveToBSplineCurve   C(Handle(Geom_BSplineCurve)::DownCast(Curve2));
       fusion=C.Add(Curve1,
                local_tolerance(j-1));          //merge of two consecutive curves               
       if (fusion==Standard_False)
       Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
       Curve2=C.BSplineCurve();
     }
   }
   Standard_Boolean   rm;
   Curve2->SetPeriodic();                               //only one C1 curve
   rm=Curve2->RemoveKnot(Curve2->LastUKnotIndex(),
                   Curve2->Multiplicity(Curve2->LastUKnotIndex())-1,
                   Precision::Confusion());
   ArrayOfConcatenated->SetValue(0,Curve2);
 }
 
 else
   for (i=0;i<=nb_group-1;i++){                             //principal loop on each G1 continuity 
     nb_vertexG1=0;                                         //group
      
     while (((index+nb_vertexG1)<=nb_curve-2)&&(tabG1(index+nb_vertexG1)==Standard_True))
       nb_vertexG1++;
      
     if ((!ClosedG1Flag)||(nb_group==1)){                        //filling of the array of index which are kept
       k++;
       ArrayOfIndices->SetValue(k-1,index);
       if (k==nb_group)
       ArrayOfIndices->SetValue(k,0);
     }
     else{
       k++;
       ArrayOfIndices->SetValue(k-1,index+nb_vertex_group0+1);
       if (k==nb_group)
       ArrayOfIndices->SetValue(k,nb_vertex_group0+1);
     }
      
     for (j=index;j<=index+nb_vertexG1;j++){                //secondary loop inside each group
       if (NeedToBeTreated(ArrayOfCurves(j)))
       Curve1=MultNumandDenom(Hermit::Solution(ArrayOfCurves(j)),ArrayOfCurves(j));
       else
       Curve1=ArrayOfCurves(j);
       
       if (index==j)                                      //initialisation at the begining of the loop
       ArrayOfConcatenated->SetValue(i,Curve1);
       else{
       GeomConvert_CompCurveToBSplineCurve   C(Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(i)));
       fusion=C.Add(Curve1,
                  local_tolerance(j-1));          //merge of two consecutive curves               
       if (fusion==Standard_False)
         Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
       ArrayOfConcatenated->SetValue(i,C.BSplineCurve());
       }
     }
     index=index+1+nb_vertexG1;
   }
}
         
//=======================================================================
//function : C0BSplineToC1BSplineCurve
//purpose  : 
//=======================================================================

01208 void GeomConvert::C0BSplineToC1BSplineCurve(Handle(Geom_BSplineCurve)& BS,
                                    const Standard_Real tolerance, 
                                  const Standard_Real AngularTol)

{
  Standard_Boolean fusion;
  Handle(TColGeom_HArray1OfBSplineCurve) ArrayOfConcatenated; 
  //the array with the resulting curves
    
  GeomConvert::C0BSplineToArrayOfC1BSplineCurve(BS, ArrayOfConcatenated, 
                                    AngularTol, tolerance);
    
  GeomConvert_CompCurveToBSplineCurve   C
    (Handle(Geom_BSplineCurve)::DownCast(ArrayOfConcatenated->Value(0)));
  if (ArrayOfConcatenated->Length()>=2){
    Standard_Integer i;
    for (i=1;i<ArrayOfConcatenated->Length();i++){
      fusion=C.Add(ArrayOfConcatenated->Value(i),tolerance);
      if (fusion==Standard_False)
      Standard_ConstructionError::Raise("GeomConvert Concatenation Error") ;
    }
  }
  BS=C.BSplineCurve();
}

//=======================================================================
//function : C0BSplineToArrayOfC1BSplineCurve
//purpose  : 
//=======================================================================

01238 void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
                        const Handle(Geom_BSplineCurve) &        BS,
                        Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
                        const Standard_Real                      tolerance)
{
   C0BSplineToArrayOfC1BSplineCurve(BS,
                            tabBS,
                            Precision::Angular(),
                            tolerance) ;
}

//=======================================================================
//function : C0BSplineToArrayOfC1BSplineCurve
//purpose  : 
//=======================================================================

01254 void GeomConvert::C0BSplineToArrayOfC1BSplineCurve(
                        const Handle(Geom_BSplineCurve) &        BS,
                        Handle(TColGeom_HArray1OfBSplineCurve) & tabBS,
                        const Standard_Real                      AngularTolerance,
                        const Standard_Real                      tolerance)

{TColStd_Array1OfInteger          BSMults(1,BS->NbKnots());
 TColStd_Array1OfReal             BSKnots(1,BS->NbKnots());
 Standard_Integer                 i,j,nbcurveC1=1;
 Standard_Real                    U1,U2;
 Standard_Boolean                 closed_flag= Standard_False ;
 gp_Pnt                           point;
 gp_Vec                           V1,V2;
// Standard_Boolean                 fusion;

 BS->Knots(BSKnots);
 BS->Multiplicities(BSMults);
 for (i=BS->FirstUKnotIndex() ;i<=(BS->LastUKnotIndex()-1);i++){                                 //give the number of C1 curves
   if (BSMults(i)==BS->Degree())
     nbcurveC1++;   
 }

 if (nbcurveC1>1){
   TColGeom_Array1OfBSplineCurve    ArrayOfCurves(0,nbcurveC1-1);
   TColStd_Array1OfReal             ArrayOfToler(0,nbcurveC1-2);
   
   for (i=0;i<=nbcurveC1-2;i++)                                      
     //filling of the array of tolerances  
     ArrayOfToler(i)=tolerance;                                      
   //with the variable tolerance
   U2=BS->FirstParameter() ;
   j=BS->FirstUKnotIndex() + 1;
   for (i=0;i<nbcurveC1;i++){                                        
     //filling of the array of curves
     U1=U2;                                                          
     //with the curves C1 segmented
     while (BSMults(j)<BS->Degree() && j < BS->LastUKnotIndex())
       j++;
     U2=BSKnots(j);
     j++;
     Handle(Geom_BSplineCurve) 
       BSbis=Handle(Geom_BSplineCurve::DownCast(BS->Copy()));
     BSbis->Segment(U1,U2);
     ArrayOfCurves(i)=BSbis;
   }
    
   Handle(TColStd_HArray1OfInteger) ArrayOfIndices;
     
   BS->D1(BS->FirstParameter(),point,V1);  
   BS->D1(BS->LastParameter(),point,V2);
    
   if ((BS->IsClosed())&&(V1.IsParallel(V2,AngularTolerance))){
     //check if the BSpline is closed G1
     closed_flag = Standard_True ;
   }
    
   GeomConvert::ConcatC1(ArrayOfCurves,
                   ArrayOfToler,
                   ArrayOfIndices,
                   tabBS,
                   closed_flag,
                   tolerance,
                   AngularTolerance);
 }
 else{
   tabBS = new TColGeom_HArray1OfBSplineCurve(0,0);
   tabBS->SetValue(0,BS);
 }
}  






Generated by  Doxygen 1.6.0   Back to index