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

ProjLib_ProjectOnPlane.cxx

// File:    ProjLib_ProjectOnPlane.gxx
// Created: Mon Sep  5 10:43:08 1994
// Author:  Bruno DUMORTIER
//          <dub@fuegox>
// 09-Aug-95 : xab : changed the ProjLib_ProjectOnPlane in the case
//                   of the line and the parameteriation is kept
#include <ProjLib_ProjectOnPlane.hxx>
#include <AppCont_Function.hxx>
#include <Approx_FitAndDivide.hxx>
#include <AppParCurves_MultiCurve.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NoSuchObject.hxx>
#include <Standard_NotImplemented.hxx>
#include <Precision.hxx>
#include <BSplCLib.hxx>
#include <PLib.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <Adaptor3d_Curve.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <Geom_Line.hxx>
#include <GeomConvert.hxx>
#include <BSplCLib.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Parabola.hxx>
#include <Geom_Hyperbola.hxx>
#include <Geom_Ellipse.hxx>



//=======================================================================
//function : OnPlane_Value
//purpose  : Evaluate current point of the projected curve
//=======================================================================

static gp_Pnt OnPlane_Value(const Standard_Real U,
                      const Handle(Adaptor3d_HCurve)& aCurvePtr,
                      const gp_Ax3& Pl,
                      const gp_Dir& D)
{
  //                   PO . Z                /  Z = Pl.Direction()
  // Proj(u) = P(u) + -------  * D     avec  \  O = Pl.Location()
  //                   D  . Z

  gp_Pnt Point = aCurvePtr->Value(U);
  
  gp_Vec PO(Point,Pl.Location());
  
  Standard_Real Alpha = PO * gp_Vec(Pl.Direction());
  Alpha /= D * Pl.Direction();
  Point.SetXYZ(Point.XYZ() + Alpha * D.XYZ());

  return Point;
}

//=======================================================================
//function : OnPlane_DN
//purpose  : Evaluate current point of the projected curve
//=======================================================================

static gp_Vec OnPlane_DN(const Standard_Real U,
                   const Standard_Integer DerivativeRequest,
                   const Handle(Adaptor3d_HCurve)& aCurvePtr,
                   const gp_Ax3& Pl,
                   const gp_Dir& D)
{
  //                   PO . Z                /  Z = Pl.Direction()
  // Proj(u) = P(u) + -------  * D     avec  \  O = Pl.Location()
  //                   D  . Z

  gp_Vec Vector = aCurvePtr->DN(U,DerivativeRequest);

  gp_Dir Z = Pl.Direction();
  
  Standard_Real
  Alpha  = Vector * gp_Vec(Z);
  Alpha /=  D * Z;

  Vector.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
  return Vector ;
}

//=======================================================================
//function : OnPlane_D1
//purpose  : 
//=======================================================================

static Standard_Boolean OnPlane_D1(const Standard_Real U,
                                 gp_Pnt& P,
                                 gp_Vec& V,
                           const Handle(Adaptor3d_HCurve)& aCurvePtr,
                           const gp_Ax3& Pl,
                           const gp_Dir& D)
{
  Standard_Real Alpha;
  gp_Pnt Point;
  gp_Vec Vector;
  
  gp_Dir Z = Pl.Direction();

  aCurvePtr->D1(U, Point, Vector);

  // evaluate the point as in `OnPlane_Value`
  gp_Vec PO(Point,Pl.Location());
  Alpha  = PO * gp_Vec(Z);
  Alpha /= D * Z;
  P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());

  
  // evaluate the derivative.
  // 
  //   d(Proj)  d(P)       1        d(P)
  //   ------ = ---  - -------- * ( --- . Z ) * D
  //     dU     dU     ( D . Z)     dU  
  //

  Alpha  = Vector * gp_Vec(Z);
  Alpha /=  D * Z;

  V.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());

  return Standard_True;
}
//=======================================================================
//function : OnPlane_D2
//purpose  : 
//=======================================================================

static Standard_Boolean OnPlane_D2(const Standard_Real U,
                                 gp_Pnt& P,
                                 gp_Vec& V1,
                                 gp_Vec& V2,
                           const Handle(Adaptor3d_HCurve) & aCurvePtr,
                           const gp_Ax3& Pl,
                           const gp_Dir& D)
{
  Standard_Real Alpha;
  gp_Pnt Point;
  gp_Vec Vector1,
  Vector2;
  
  gp_Dir Z = Pl.Direction();

  aCurvePtr->D2(U, Point, Vector1, Vector2);

  // evaluate the point as in `OnPlane_Value`
  gp_Vec PO(Point,Pl.Location());
  Alpha  = PO * gp_Vec(Z);
  Alpha /= D * Z;
  P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());

  // evaluate the derivative.
  // 
  //   d(Proj)  d(P)       1        d(P)
  //   ------ = ---  - -------- * ( --- . Z ) * D
  //     dU     dU     ( D . Z)     dU  
  //

  Alpha  = Vector1 * gp_Vec(Z);
  Alpha /=  D * Z;

  V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());

  Alpha  = Vector2 * gp_Vec(Z);
  Alpha /=  D * Z;

  V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
  return Standard_True;
}

//=======================================================================
//function : OnPlane_D3
//purpose  : 
//=======================================================================

static Standard_Boolean OnPlane_D3(const Standard_Real U,
                                 gp_Pnt& P,
                                 gp_Vec& V1,
                                 gp_Vec& V2,
                                 gp_Vec& V3,
                           const Handle(Adaptor3d_HCurve)& aCurvePtr,
                           const gp_Ax3& Pl,
                           const gp_Dir& D)
{
  Standard_Real Alpha;
  gp_Pnt Point;
  gp_Vec Vector1,
  Vector2,
  Vector3;
  
  gp_Dir Z = Pl.Direction();

  aCurvePtr->D3(U, Point, Vector1, Vector2, Vector3);

  // evaluate the point as in `OnPlane_Value`
  gp_Vec PO(Point,Pl.Location());
  Alpha  = PO * gp_Vec(Z);
  Alpha /= D * Z;
  P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
  
  // evaluate the derivative.
  // 
  //   d(Proj)  d(P)       1        d(P)
  //   ------ = ---  - -------- * ( --- . Z ) * D
  //     dU     dU     ( D . Z)     dU  
  //

  Alpha  = Vector1 * gp_Vec(Z);
  Alpha /=  D * Z;

  V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());

  Alpha  = Vector2 * gp_Vec(Z);
  Alpha /=  D * Z;

  V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
  Alpha  = Vector3 * gp_Vec(Z);
  Alpha /=  D * Z;

  V3.SetXYZ( Vector3.XYZ() - Alpha * D.XYZ());
  return Standard_True;
}

//=======================================================================
//  class  : ProjLib_OnPlane
//purpose  : Use to approximate the projection on a plane
//=======================================================================

class ProjLib_OnPlane : public AppCont_Function

{
  Handle(Adaptor3d_HCurve) myCurve;
  gp_Ax3 myPlane;
  gp_Dir myDirection;
  
  public :
  
  ProjLib_OnPlane(const Handle(Adaptor3d_HCurve)& C, 
              const gp_Ax3& Pl, 
              const gp_Dir& D) 
    : myCurve(C), myPlane(Pl), myDirection(D)
      {}

  Standard_Real FirstParameter() const
    {return myCurve->FirstParameter();}
  
  Standard_Real LastParameter() const
    {return myCurve->LastParameter();}

  gp_Pnt Value( const Standard_Real t) const
    {return OnPlane_Value(t,myCurve,myPlane,myDirection);}
  
  Standard_Boolean D1(const Standard_Real t, gp_Pnt& P, gp_Vec& V) const
    {return OnPlane_D1(t,P,V,myCurve,myPlane,myDirection);}
};




//=====================================================================//
//                                                                     //
//  D E S C R I P T I O N   O F   T H E   C L A S S  :                 // 
//                                                                     //
//         P r o j L i b _ A p p r o x P r o j e c t O n P l a n e     //
//                                                                     //
//=====================================================================//



//=======================================================================
//function : PerformApprox
//purpose  : 
//=======================================================================

static void  PerformApprox (const Handle(Adaptor3d_HCurve)& C,
                      const gp_Ax3& Pl,
                      const gp_Dir& D,
                      Handle(Geom_BSplineCurve) &BSplineCurvePtr) 

{
  ProjLib_OnPlane F(C,Pl,D);

  Standard_Integer Deg1, Deg2;
  Deg1 = 8; Deg2 = 8;
  
  Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
                    Precision::PApproximation(),Standard_True);
  Standard_Integer i;
  Standard_Integer NbCurves = Fit.NbMultiCurves();
  Standard_Integer MaxDeg = 0;
  
  // Pour transformer la MultiCurve en BSpline, il faut que toutes 
  // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
  Standard_Integer NbPoles  = 1;
  for (i = 1; i <= NbCurves; i++) {
    Standard_Integer Deg = Fit.Value(i).Degree();
    MaxDeg = Max ( MaxDeg, Deg);
  }
  NbPoles = MaxDeg * NbCurves + 1;               //Poles sur la BSpline

  TColgp_Array1OfPnt    Poles( 1, NbPoles);
  
  TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1);  //pour augmentation du degre
  
  TColStd_Array1OfReal Knots( 1, NbCurves + 1);  //Noeuds de la BSpline
  
  Standard_Integer Compt = 1;
  for (i = 1; i <= Fit.NbMultiCurves(); i++) {
    Fit.Parameters(i, Knots(i), Knots(i+1)); 
    
    AppParCurves_MultiCurve MC = Fit.Value( i);   //Charge la Ieme Curve
    TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
    MC.Curve(1, LocalPoles);
    
    //Augmentation eventuelle du degre
    Standard_Integer Inc = MaxDeg - MC.Degree();
    if ( Inc > 0) {
      BSplCLib::IncreaseDegree(Inc, Poles, PLib::NoWeights(),
                         TempPoles, PLib::NoWeights());
      //mise a jour des poles de la PCurve
      for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
      Poles.SetValue( Compt, TempPoles( j));
      Compt++;
      }
    }
    else {
      //mise a jour des poles de la PCurve
      for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
      Poles.SetValue( Compt, LocalPoles( j));
      Compt++;
      }
    } 
    
    Compt--;
  }
  
  //mise a jour des fields de ProjLib_Approx

  Standard_Integer 
  NbKnots = NbCurves + 1;

  TColStd_Array1OfInteger    Mults(1, NbKnots);
  Mults.SetValue( 1, MaxDeg + 1);
  for ( i = 2; i <= NbCurves; i++) {
    Mults.SetValue( i, MaxDeg);
  }
  Mults.SetValue( NbKnots, MaxDeg + 1);
  BSplineCurvePtr = 
    new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
}


//=======================================================================
//function : ProjectOnPlane
//purpose  : 
//=======================================================================

00365 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
myType     (GeomAbs_OtherCurve),
myIsApprox (Standard_False)
{
}

//=======================================================================
//function : ProjLib_ProjectOnPlane
//purpose  : 
//=======================================================================

00376 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) : 
myPlane     (Pl)                ,
myDirection (Pl.Direction())    ,
myType      (GeomAbs_OtherCurve),
myIsApprox  (Standard_False)
{
}

//=======================================================================
//function : ProjLib_ProjectOnPlane
//purpose  : 
//=======================================================================

00389 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
                                     const gp_Dir& D  ) :
myPlane     (Pl)                ,
myDirection (D)                 ,
myType      (GeomAbs_OtherCurve),
myIsApprox  (Standard_False)
{
#ifdef DEB
  Standard_Real scal =
#endif
                       Abs(D * Pl.Direction());
//  if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
//    Standard_ConstructionError::Raise
//      ("ProjLib_ProjectOnPlane:  The Direction and the Plane are parallel");
//  }
}

//=======================================================================
//function : Project
//purpose  : Returns the projection of a point <Point> on a plane 
//           <ThePlane>  along a direction <TheDir>.
//=======================================================================

static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
                   const gp_Dir& TheDir,
                   const gp_Pnt& Point) 
{
  gp_Vec PO(Point,ThePlane.Location());

  Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
  Alpha /= TheDir * ThePlane.Direction();
  
  gp_Pnt P;
  P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());

  return P;
}


//=======================================================================
//function : Project
//purpose  : Returns the projection of a Vector <Vec> on a plane 
//           <ThePlane> along a direction <TheDir>.
//=======================================================================

static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
                   const gp_Dir& TheDir,
                   const gp_Vec& Vec) 
{
  gp_Vec D = Vec;
  gp_Vec Z = ThePlane.Direction();

  D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;

  return D;
}


//=======================================================================
//function : Project
//purpose  : Returns the projection of a Direction <Dir> on a plane 
//           <ThePlane> along a direction <TheDir>.
//=======================================================================

#ifdef DEB
static gp_Dir ProjectDir(const gp_Ax3& ThePlane,
                   const gp_Dir& TheDir,
                   const gp_Dir& Dir) 
{
  return gp_Dir(ProjectVec(ThePlane,TheDir,gp_Vec(Dir)));
}
#endif

//=======================================================================
//function : Load
//purpose  : 
//=======================================================================

00467 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)&    C,
                          const Standard_Real Tolerance,
                          const Standard_Boolean KeepParametrization) 
                          
{
  myCurve      = C;
  myType       = GeomAbs_OtherCurve;
  myIsApprox   = Standard_False;
  myTolerance  = Tolerance ;

  Handle(Geom_BSplineCurve)  ApproxCurve;
  Handle(GeomAdaptor_HCurve) aGAHCurve;

  Handle(Geom_Line)      GeomLinePtr;
  Handle(Geom_Circle)    GeomCirclePtr ;
  Handle(Geom_Ellipse)   GeomEllipsePtr ;
  Handle(Geom_Hyperbola) GeomHyperbolaPtr ;

  gp_Lin   aLine; 
  gp_Elips Elips;
//  gp_Hypr  Hypr ;

  Standard_Integer num_knots ;
  GeomAbs_CurveType Type = C->GetType();

  gp_Ax2 Axis;
#ifndef DEB
  Standard_Real R1 =0., R2 =0.;
#else 
  Standard_Real R1, R2;
#endif

  if ( Type != GeomAbs_Line)  // on garde le parametrage
    myKeepParam = Standard_True;
  else                        // on prend le choix utilisateur.
    myKeepParam = KeepParametrization;

  switch ( Type) {
  case GeomAbs_Line: 
    {
      //     P(u) = O + u * Xc
      // ==> Q(u) = f(P(u)) 
      //          = f(O) + u * f(Xc)

      gp_Lin L  = myCurve->Line();
      gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));

      if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
      myType = GeomAbs_BSplineCurve;
      gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
      TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
      TColgp_Array1OfPnt      Poles(1,2); Poles.Init(P);
      TColStd_Array1OfReal    Knots(1,2); 
      Knots(1) = myCurve->FirstParameter();
      Knots(2) = myCurve->LastParameter();
      Handle(Geom_BSplineCurve) BSP = 
        new Geom_BSplineCurve(Poles,Knots,Mults,1);

//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(BSP);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
      myType      = GeomAbs_Line;
      gp_Pnt P    = ProjectPnt(myPlane,myDirection,L.Location());
        myFirstPar  = myCurve->FirstParameter();
        myLastPar   = myCurve->LastParameter();
        aLine       = gp_Lin(P,gp_Dir(Xc));
        GeomLinePtr = new Geom_Line(aLine);
      
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(GeomLinePtr,
                           myCurve->FirstParameter(),
                           myCurve->LastParameter() );
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else {
      myType     = GeomAbs_Line;
      gp_Pnt P   = ProjectPnt(myPlane,myDirection,L.Location());
        aLine      = gp_Lin(P,gp_Dir(Xc));
      Standard_Real Udeb, Ufin;
      
      // eval the first and last parameters of the projected curve
      Udeb = myCurve->FirstParameter();
      Ufin = myCurve->LastParameter();
      gp_Pnt P1  = ProjectPnt(myPlane,myDirection,
                        myCurve->Value(Udeb)); 
      gp_Pnt P2  = ProjectPnt(myPlane,myDirection,
                        myCurve->Value(Ufin)); 
      myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
      myLastPar  = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
        GeomLinePtr = new Geom_Line(aLine);
      if (!myKeepParam) {
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(GeomLinePtr,
                             myFirstPar,
                             myLastPar) ;
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else {
        myType     = GeomAbs_BSplineCurve;
        //
        // make a linear BSpline of degree 1 between the end points of
        // the projected line 
        //
        Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
          new Geom_TrimmedCurve(GeomLinePtr,
                          myFirstPar,
                          myLastPar) ;
        
        Handle(Geom_BSplineCurve) NewCurvePtr =
          GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
        num_knots = NewCurvePtr->NbKnots() ;
        TColStd_Array1OfReal    BsplineKnots(1,num_knots)  ;
        NewCurvePtr->Knots(BsplineKnots) ;
        
        BSplCLib::Reparametrize(myCurve->FirstParameter(), 
                          myCurve->LastParameter(),
                          BsplineKnots) ;
        
        NewCurvePtr->SetKnots(BsplineKnots) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(NewCurvePtr);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      }
      break;
    }
  case GeomAbs_Circle:
    {
      // Pour le cercle et l ellipse on a les relations suivantes:
      // ( Rem : pour le cercle R1 = R2 = R)
      //     P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
      // ==> Q(u) = f(P(u)) 
      //          = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
      
      gp_Circ Circ = myCurve->Circle();
      Axis = Circ.Position();
      R1 = R2 = Circ.Radius();

    }
  case GeomAbs_Ellipse:
    {
      if ( Type == GeomAbs_Ellipse) {
      gp_Elips E = myCurve->Ellipse();
      Axis = E.Position();
      R1 = E.MajorRadius();
      R2 = E.MinorRadius();
      }

      // Common Code  for CIRCLE & ELLIPSE begin here
      gp_Dir X  = Axis.XDirection();
      gp_Dir Y  = Axis.YDirection();
      gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
      gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
      gp_Dir Dx,Dy;

      Standard_Real Tol2 = myTolerance*myTolerance;
      if (VDx.SquareMagnitude() < Tol2 ||
        VDy.SquareMagnitude() < Tol2    ) {
      myIsApprox = Standard_True;
      }

      if (!myIsApprox && 
        gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
      Dx = gp_Dir(VDx);
      Dy = gp_Dir(VDy);
      gp_Pnt O    = Axis.Location();
      gp_Pnt P    = ProjectPnt(myPlane,myDirection,O);
      gp_Pnt Px   = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
      gp_Pnt Py   = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
      Standard_Real Major = P.Distance(Px);
      Standard_Real Minor = P.Distance(Py);
      gp_Ax2 Axe( P, Dx^Dy,Dx);

      if ( Abs( Major - Minor) < Precision::Confusion()) {
        myType = GeomAbs_Circle;
        gp_Circ Circ(Axe, Major);
        GeomCirclePtr  = new Geom_Circle(Circ);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(GeomCirclePtr);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else if ( Major > Minor) {
        myType = GeomAbs_Ellipse;
        Elips  = gp_Elips( Axe, Major, Minor);
        
          GeomEllipsePtr = new Geom_Ellipse(Elips) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else {
        myIsApprox = Standard_True;
        myType = GeomAbs_BSplineCurve;
          PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(ApproxCurve);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      }
      else {
      myIsApprox = Standard_True;
      myType     = GeomAbs_BSplineCurve;
        PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ApproxCurve);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
    }
    break;
  case GeomAbs_Parabola:
    {
      //     P(u) = O + (u*u)/(4*f) * Xc + u * Yc
      // ==> Q(u) = f(P(u)) 
      //          = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)

      gp_Parab Parab  = myCurve->Parabola();
      gp_Ax2   AxeRef = Parab.Position();
      gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
      gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));

      // fix for case when no one action is done. 28.03.2002
      Standard_Boolean alocalIsDone = Standard_False;

      if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
      gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
      if ( Xc.Magnitude() < Precision::Confusion()) {
        myType = GeomAbs_Line;
        aLine  = gp_Lin( P, gp_Dir(Yc));
          
          GeomLinePtr    = new Geom_Line(aLine) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(GeomLinePtr);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
          alocalIsDone = Standard_True;
      }
      else if ( Xc.IsNormal(Yc,Precision::Angular())) {
        myType = GeomAbs_Parabola;
        Standard_Real F = Parab.Focal() / Xc.Magnitude();
        gp_Parab Parab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
          Handle(Geom_Parabola) GeomParabolaPtr =
          new Geom_Parabola(Parab) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
        GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
        myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
          alocalIsDone = Standard_True;
      }
      }
      if (!alocalIsDone)/*else*/ {
      myIsApprox = Standard_True;
      myType     = GeomAbs_BSplineCurve;
        PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ApproxCurve);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
    }
    break;
  case GeomAbs_Hyperbola:
    {
      //     P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
      // ==> Q(u) = f(P(u)) 
      //          = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)

      gp_Hypr Hypr  = myCurve->Hyperbola();
      gp_Ax2 AxeRef = Hypr.Position();
      gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
      gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
      gp_Pnt P  = ProjectPnt(myPlane,myDirection,AxeRef.Location());
      Standard_Real R1 = Hypr.MajorRadius();
      Standard_Real R2 = Hypr.MinorRadius();
      gp_Dir Z = myPlane.Direction();

      if ( Xc.Magnitude() < Precision::Confusion()) {
      myType   = GeomAbs_Hyperbola;
      gp_Dir X = gp_Dir(Yc) ^ Z;
      Hypr   = gp_Hypr(gp_Ax2( P, Z, X), 0., R2 * Yc.Magnitude());
        GeomHyperbolaPtr =
        new Geom_Hyperbola(Hypr) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else if ( Yc.Magnitude() < Precision::Confusion()) {
      myType = GeomAbs_Hyperbola;
      Hypr = 
         gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
        GeomHyperbolaPtr =
        new Geom_Hyperbola(Hypr) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else if ( Xc.IsNormal(Yc,Precision::Angular())) {
      myType = GeomAbs_Hyperbola;
      Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
                   R1 * Xc.Magnitude(), R2 * Yc.Magnitude() );
      GeomHyperbolaPtr =
        new Geom_Hyperbola(Hypr) ;
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
      else {
      myIsApprox = Standard_True;
      myType     = GeomAbs_BSplineCurve;
        PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ApproxCurve);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
      }
    }
    break;
  case GeomAbs_BezierCurve:
    {
      Handle(Geom_BezierCurve) BezierCurvePtr =
      myCurve->Bezier() ;
      Standard_Integer NbPoles = 
      BezierCurvePtr->NbPoles() ;
      
      Handle(Geom_BezierCurve) ProjCu = 
      Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());

      myIsApprox = Standard_False;
      myType = Type;
      for ( Standard_Integer i = 1; i <= NbPoles; i++) {
      ProjCu->SetPole
        (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
      }
      
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ProjCu);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
    }
    break ;
  case GeomAbs_BSplineCurve:
    {
      Handle(Geom_BSplineCurve) BSplineCurvePtr =
      myCurve->BSpline() ;
      //
      //    make a copy of the curve and projects its poles 
      //
      Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
      Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
      
      myIsApprox = Standard_False;
      myType = Type;
      for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
      ProjectedBSplinePtr->SetPole
        (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
      }
      
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
    }
    break;
  default:
    {
      myIsApprox = Standard_True;
      myType     = GeomAbs_BSplineCurve;
      PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
      GeomAdaptor_Curve aGACurve(ApproxCurve);
      myResult = new GeomAdaptor_HCurve(aGACurve);
//  Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
    }
    break;
  }
}

//=======================================================================
//function : GetPlane
//purpose  : 
//=======================================================================

const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const 
{
  return myPlane;
}

//=======================================================================
//function : GetDirection
//purpose  : 
//=======================================================================

const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const 
{
  return myDirection;
}

//=======================================================================
//function : GetCurve
//purpose  : 
//=======================================================================

const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
{
  return myCurve;
}


//=======================================================================
//function : FirstParameter
//purpose  : 
//=======================================================================

Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const 
{
  if ( myKeepParam || myIsApprox) 
    return myCurve->FirstParameter();
  else
    return myFirstPar;
}


//=======================================================================
//function : LastParameter
//purpose  : 
//=======================================================================

Standard_Real ProjLib_ProjectOnPlane::LastParameter() const 
{
  if ( myKeepParam || myIsApprox) 
    return myCurve->LastParameter();
  else
    return myLastPar;
}


//=======================================================================
//function : Continuity
//purpose  : 
//=======================================================================

GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
{
  return myCurve->Continuity() ;
}


//=======================================================================
//function : NbIntervals
//purpose  : 
//=======================================================================

00931 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S) 
{
  return myCurve->NbIntervals(S) ;
}


//=======================================================================
//function : Intervals
//purpose  : 
//=======================================================================

00942 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T, 
                               const GeomAbs_Shape S) 
{
  myCurve->Intervals(T,S) ;
}

//=======================================================================
//function : Trim
//purpose  : 
//=======================================================================

Handle(Adaptor3d_HCurve)  
ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
                       const Standard_Real Last,
                       const Standard_Real Tolerance) const 
{
  if (myType != GeomAbs_OtherCurve){
    return myResult->Trim(First,Last,Tolerance) ;
  }
  else {
    Standard_NotImplemented::Raise("");
  }

  // portage WNT
  Handle(Adaptor3d_HCurve) dummy;
  return dummy;
}

  
//=======================================================================
//function : IsClosed
//purpose  : 
//=======================================================================

Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
{
 return myCurve->IsClosed() ;
}


//=======================================================================
//function : IsPeriodic
//purpose  : 
//=======================================================================

Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
{
  if ( myIsApprox)
    return Standard_False;
  else 
    return myCurve->IsPeriodic();
}


//=======================================================================
//function : Period
//purpose  : 
//=======================================================================

Standard_Real ProjLib_ProjectOnPlane::Period() const
{
  if ( !IsPeriodic()) {
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
  }
                        
  if ( myIsApprox)
    return Standard_False;
  else 
    return myCurve->Period();
}


//=======================================================================
//function : Value
//purpose  : 
//=======================================================================

01019 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const 
{
  if (myType != GeomAbs_OtherCurve) { 
    return myResult->Value(U);
  }
  else {
    return OnPlane_Value(U,
                   myCurve,
                   myPlane,
                   myDirection);
    
  }
} 


//=======================================================================
//function : D0
//purpose  : 
//=======================================================================

01039 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
{
  if (myType != GeomAbs_OtherCurve) {
    myResult->D0(U,P) ;
  }
  else {
    P = OnPlane_Value(U,
                  myCurve,
                  myPlane,
                  myDirection);
  }
}


//=======================================================================
//function : D1
//purpose  : 
//=======================================================================

01058 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
                                gp_Pnt&    P , 
                                      gp_Vec&    V ) const 
{
  if (myType != GeomAbs_OtherCurve) {
    myResult->D1(U,P,V) ;
  }
  else {
    OnPlane_D1(U,
             P,
             V,
             myCurve,
             myPlane,
             myDirection);
  }
}


//=======================================================================
//function : D2
//purpose  : 
//=======================================================================

01081 void ProjLib_ProjectOnPlane::D2(const Standard_Real U, 
                                gp_Pnt&     P, 
                                      gp_Vec&     V1, 
                                      gp_Vec&     V2) const 
{
  if (myType != GeomAbs_OtherCurve)  {
    myResult->D2(U,P,V1,V2) ;
  }
  else {
    OnPlane_D2(U,
             P,
             V1,
             V2,
             myCurve,
             myPlane,
             myDirection);
  }
}


//=======================================================================
//function : D3
//purpose  : 
//=======================================================================

01106 void ProjLib_ProjectOnPlane::D3(const Standard_Real U, 
                        gp_Pnt& P, 
                        gp_Vec& V1, 
                        gp_Vec& V2, 
                        gp_Vec& V3) const 
{
  if (myType != GeomAbs_OtherCurve)   {
    myResult->D3(U,P,V1,V2,V3) ;
  }
  else   {
    OnPlane_D3(U,
             P,
             V1,
             V2,
             V3,
             myCurve,
             myPlane,
             myDirection); 
  }
}


//=======================================================================
//function : DN
//purpose  : 
//=======================================================================

01133 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U, 
                          const Standard_Integer DerivativeRequest)
     const 
{
  if (myType != GeomAbs_OtherCurve) {
    return myResult->DN(U,DerivativeRequest) ;
  }
  else {
    return OnPlane_DN(U,
                  DerivativeRequest,
                  myCurve,
                  myPlane,
                  myDirection); 
  }   
}


//=======================================================================
//function : Resolution
//purpose  : 
//=======================================================================

Standard_Real ProjLib_ProjectOnPlane::Resolution
01156 (const Standard_Real Tolerance) const 
{
  if (myType != GeomAbs_OtherCurve) {
    return myResult->Resolution(Tolerance) ;
  }
  else {
    return 0;
  }
}
    

//=======================================================================
//function : GetType
//purpose  : 
//=======================================================================

01172 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
{
  return myType;
}


//=======================================================================
//function : Line
//purpose  : 
//=======================================================================

gp_Lin ProjLib_ProjectOnPlane::Line() const
{
  if (myType != GeomAbs_Line)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");

  return myResult->Line();
}


//=======================================================================
//function : Circle
//purpose  : 
//=======================================================================

gp_Circ ProjLib_ProjectOnPlane::Circle() const
{
  if (myType != GeomAbs_Circle)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");

  return myResult->Circle();
}


//=======================================================================
//function : Ellipse
//purpose  : 
//=======================================================================

gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
{
  if (myType != GeomAbs_Ellipse)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");

  return myResult->Ellipse();
}


//=======================================================================
//function : Hyperbola
//purpose  : 
//=======================================================================

gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
{
  if (myType != GeomAbs_Hyperbola)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");

  return myResult->Hyperbola() ;
}


//=======================================================================
//function : Parabola
//purpose  : 
//=======================================================================

gp_Parab ProjLib_ProjectOnPlane::Parabola() const
{
  if (myType != GeomAbs_Parabola)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
  
  return myResult->Parabola() ;
}

//=======================================================================
//function : Degree
//purpose  : 
//=======================================================================

Standard_Integer ProjLib_ProjectOnPlane::Degree() const
{
  if ((GetType() != GeomAbs_BSplineCurve) &&
      (GetType() != GeomAbs_BezierCurve))
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");

  if ( myIsApprox)
    return myResult->Degree();
  else
    return myCurve->Degree();
}

//=======================================================================
//function : IsRational
//purpose  : 
//=======================================================================

Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const 
{
  if ((GetType() != GeomAbs_BSplineCurve) &&
      (GetType() != GeomAbs_BezierCurve))
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
  
  if ( myIsApprox) 
    return myResult->IsRational();
  else
    return myCurve->IsRational();
}

//=======================================================================
//function : NbPoles
//purpose  : 
//=======================================================================

Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
{
  if ((GetType() != GeomAbs_BSplineCurve) &&
      (GetType() != GeomAbs_BezierCurve))
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
  
  if ( myIsApprox)
    return myResult->NbPoles();
  else
    return myCurve->NbPoles();
}

//=======================================================================
//function : NbKnots
//purpose  : 
//=======================================================================

Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const 
{
  if ( GetType() != GeomAbs_BSplineCurve) 
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
  
  if ( myIsApprox) 
    return myResult->NbKnots();
  else
    return myCurve->NbKnots();
}


//=======================================================================
//function : Bezier
//purpose  : 
//=======================================================================

Handle(Geom_BezierCurve)  ProjLib_ProjectOnPlane::Bezier() const
{
  if (myType != GeomAbs_BezierCurve)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");

  return myResult->Bezier() ;
}

//=======================================================================
//function : Bezier
//purpose  : 
//=======================================================================

Handle(Geom_BSplineCurve)  ProjLib_ProjectOnPlane::BSpline() const
{
  if (myType != GeomAbs_BSplineCurve)
    Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");

  return myResult->BSpline() ;
}


Generated by  Doxygen 1.6.0   Back to index