1 // Created on: 1994-09-05
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // 09-Aug-95 : xab : changed the ProjLib_ProjectOnPlane in the case
18 // of the line and the parameteriation is kept
19 #include <ProjLib_ProjectOnPlane.hxx>
20 #include <AppCont_Function.hxx>
21 #include <Approx_FitAndDivide.hxx>
22 #include <AppParCurves_MultiCurve.hxx>
23 #include <Standard_ConstructionError.hxx>
24 #include <Standard_NoSuchObject.hxx>
25 #include <Standard_NotImplemented.hxx>
26 #include <Precision.hxx>
27 #include <BSplCLib.hxx>
29 #include <Geom_BSplineCurve.hxx>
30 #include <Geom_BezierCurve.hxx>
31 #include <TColgp_HArray1OfPnt.hxx>
32 #include <TColStd_HArray1OfReal.hxx>
33 #include <TColStd_HArray1OfInteger.hxx>
34 #include <Precision.hxx>
36 #include <Adaptor3d_Curve.hxx>
37 #include <Adaptor3d_HCurve.hxx>
38 #include <GeomAdaptor_HCurve.hxx>
39 #include <Geom_Line.hxx>
40 #include <GeomConvert.hxx>
41 #include <BSplCLib.hxx>
42 #include <Geom_TrimmedCurve.hxx>
43 #include <Geom_Circle.hxx>
44 #include <Geom_Parabola.hxx>
45 #include <Geom_Hyperbola.hxx>
46 #include <Geom_Ellipse.hxx>
50 //=======================================================================
51 //function : OnPlane_Value
52 //purpose : Evaluate current point of the projected curve
53 //=======================================================================
55 static gp_Pnt OnPlane_Value(const Standard_Real U,
56 const Handle(Adaptor3d_HCurve)& aCurvePtr,
60 // PO . Z / Z = Pl.Direction()
61 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
64 gp_Pnt Point = aCurvePtr->Value(U);
66 gp_Vec PO(Point,Pl.Location());
68 Standard_Real Alpha = PO * gp_Vec(Pl.Direction());
69 Alpha /= D * Pl.Direction();
70 Point.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
75 //=======================================================================
76 //function : OnPlane_DN
77 //purpose : Evaluate current point of the projected curve
78 //=======================================================================
80 static gp_Vec OnPlane_DN(const Standard_Real U,
81 const Standard_Integer DerivativeRequest,
82 const Handle(Adaptor3d_HCurve)& aCurvePtr,
86 // PO . Z / Z = Pl.Direction()
87 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
90 gp_Vec Vector = aCurvePtr->DN(U,DerivativeRequest);
92 gp_Dir Z = Pl.Direction();
95 Alpha = Vector * gp_Vec(Z);
98 Vector.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
102 //=======================================================================
103 //function : OnPlane_D1
105 //=======================================================================
107 static Standard_Boolean OnPlane_D1(const Standard_Real U,
110 const Handle(Adaptor3d_HCurve)& aCurvePtr,
118 gp_Dir Z = Pl.Direction();
120 aCurvePtr->D1(U, Point, Vector);
122 // evaluate the point as in `OnPlane_Value`
123 gp_Vec PO(Point,Pl.Location());
124 Alpha = PO * gp_Vec(Z);
126 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
129 // evaluate the derivative.
131 // d(Proj) d(P) 1 d(P)
132 // ------ = --- - -------- * ( --- . Z ) * D
136 Alpha = Vector * gp_Vec(Z);
139 V.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
141 return Standard_True;
143 //=======================================================================
144 //function : OnPlane_D2
146 //=======================================================================
148 static Standard_Boolean OnPlane_D2(const Standard_Real U,
152 const Handle(Adaptor3d_HCurve) & aCurvePtr,
161 gp_Dir Z = Pl.Direction();
163 aCurvePtr->D2(U, Point, Vector1, Vector2);
165 // evaluate the point as in `OnPlane_Value`
166 gp_Vec PO(Point,Pl.Location());
167 Alpha = PO * gp_Vec(Z);
169 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
171 // evaluate the derivative.
173 // d(Proj) d(P) 1 d(P)
174 // ------ = --- - -------- * ( --- . Z ) * D
178 Alpha = Vector1 * gp_Vec(Z);
181 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
183 Alpha = Vector2 * gp_Vec(Z);
186 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
187 return Standard_True;
190 //=======================================================================
191 //function : OnPlane_D3
193 //=======================================================================
195 static Standard_Boolean OnPlane_D3(const Standard_Real U,
200 const Handle(Adaptor3d_HCurve)& aCurvePtr,
210 gp_Dir Z = Pl.Direction();
212 aCurvePtr->D3(U, Point, Vector1, Vector2, Vector3);
214 // evaluate the point as in `OnPlane_Value`
215 gp_Vec PO(Point,Pl.Location());
216 Alpha = PO * gp_Vec(Z);
218 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
220 // evaluate the derivative.
222 // d(Proj) d(P) 1 d(P)
223 // ------ = --- - -------- * ( --- . Z ) * D
227 Alpha = Vector1 * gp_Vec(Z);
230 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
232 Alpha = Vector2 * gp_Vec(Z);
235 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
236 Alpha = Vector3 * gp_Vec(Z);
239 V3.SetXYZ( Vector3.XYZ() - Alpha * D.XYZ());
240 return Standard_True;
243 //=======================================================================
244 // class : ProjLib_OnPlane
245 //purpose : Use to approximate the projection on a plane
246 //=======================================================================
248 class ProjLib_OnPlane : public AppCont_Function
251 Handle(Adaptor3d_HCurve) myCurve;
257 ProjLib_OnPlane(const Handle(Adaptor3d_HCurve)& C,
268 Standard_Real FirstParameter() const
269 {return myCurve->FirstParameter();}
271 Standard_Real LastParameter() const
272 {return myCurve->LastParameter();}
274 Standard_Boolean Value(const Standard_Real theT,
275 NCollection_Array1<gp_Pnt2d>& /*thePnt2d*/,
276 NCollection_Array1<gp_Pnt>& thePnt) const
278 thePnt(1) = OnPlane_Value(theT, myCurve, myPlane, myDirection);
279 return Standard_True;
282 Standard_Boolean D1(const Standard_Real theT,
283 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
284 NCollection_Array1<gp_Vec>& theVec) const
287 return OnPlane_D1(theT, aDummyPnt, theVec(1),myCurve,myPlane,myDirection);
294 //=====================================================================//
296 // D E S C R I P T I O N O F T H E C L A S S : //
298 // 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 //
300 //=====================================================================//
304 //=======================================================================
305 //function : PerformApprox
307 //=======================================================================
309 static void PerformApprox (const Handle(Adaptor3d_HCurve)& C,
312 Handle(Geom_BSplineCurve) &BSplineCurvePtr)
315 ProjLib_OnPlane F(C,Pl,D);
317 Standard_Integer Deg1, Deg2;
320 Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
321 Precision::PApproximation(),Standard_True);
323 Standard_Integer NbCurves = Fit.NbMultiCurves();
324 Standard_Integer MaxDeg = 0;
326 // Pour transformer la MultiCurve en BSpline, il faut que toutes
327 // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
328 Standard_Integer NbPoles = 1;
329 for (i = 1; i <= NbCurves; i++) {
330 Standard_Integer Deg = Fit.Value(i).Degree();
331 MaxDeg = Max ( MaxDeg, Deg);
333 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
335 TColgp_Array1OfPnt Poles( 1, NbPoles);
337 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
339 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
341 Standard_Integer Compt = 1;
342 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
343 Fit.Parameters(i, Knots(i), Knots(i+1));
345 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
346 TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
347 MC.Curve(1, LocalPoles);
349 //Augmentation eventuelle du degre
350 Standard_Integer Inc = MaxDeg - MC.Degree();
352 BSplCLib::IncreaseDegree(Inc, Poles, PLib::NoWeights(),
353 TempPoles, PLib::NoWeights());
354 //mise a jour des poles de la PCurve
355 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
356 Poles.SetValue( Compt, TempPoles( j));
361 //mise a jour des poles de la PCurve
362 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
363 Poles.SetValue( Compt, LocalPoles( j));
371 //mise a jour des fields de ProjLib_Approx
374 NbKnots = NbCurves + 1;
376 TColStd_Array1OfInteger Mults(1, NbKnots);
377 Mults.SetValue( 1, MaxDeg + 1);
378 for ( i = 2; i <= NbCurves; i++) {
379 Mults.SetValue( i, MaxDeg);
381 Mults.SetValue( NbKnots, MaxDeg + 1);
383 new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
387 //=======================================================================
388 //function : ProjectOnPlane
390 //=======================================================================
392 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
393 myKeepParam(Standard_False),
397 myType (GeomAbs_OtherCurve),
398 myIsApprox (Standard_False)
402 //=======================================================================
403 //function : ProjLib_ProjectOnPlane
405 //=======================================================================
407 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) :
409 myDirection (Pl.Direction()) ,
410 myKeepParam(Standard_False),
414 myType (GeomAbs_OtherCurve),
415 myIsApprox (Standard_False)
419 //=======================================================================
420 //function : ProjLib_ProjectOnPlane
422 //=======================================================================
424 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
428 myKeepParam(Standard_False),
432 myType (GeomAbs_OtherCurve),
433 myIsApprox (Standard_False)
435 // if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
436 // Standard_ConstructionError::Raise
437 // ("ProjLib_ProjectOnPlane: The Direction and the Plane are parallel");
441 //=======================================================================
443 //purpose : Returns the projection of a point <Point> on a plane
444 // <ThePlane> along a direction <TheDir>.
445 //=======================================================================
447 static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
448 const gp_Dir& TheDir,
451 gp_Vec PO(Point,ThePlane.Location());
453 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
454 Alpha /= TheDir * ThePlane.Direction();
457 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
463 //=======================================================================
465 //purpose : Returns the projection of a Vector <Vec> on a plane
466 // <ThePlane> along a direction <TheDir>.
467 //=======================================================================
469 static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
470 const gp_Dir& TheDir,
474 gp_Vec Z = ThePlane.Direction();
476 D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
481 //=======================================================================
484 //=======================================================================
486 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
487 const Standard_Real Tolerance,
488 const Standard_Boolean KeepParametrization)
492 myType = GeomAbs_OtherCurve;
493 myIsApprox = Standard_False;
494 myTolerance = Tolerance ;
496 Handle(Geom_BSplineCurve) ApproxCurve;
497 Handle(GeomAdaptor_HCurve) aGAHCurve;
499 Handle(Geom_Line) GeomLinePtr;
500 Handle(Geom_Circle) GeomCirclePtr ;
501 Handle(Geom_Ellipse) GeomEllipsePtr ;
502 Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
508 Standard_Integer num_knots ;
509 GeomAbs_CurveType Type = C->GetType();
512 Standard_Real R1 =0., R2 =0.;
514 if ( Type != GeomAbs_Line) // on garde le parametrage
515 myKeepParam = Standard_True;
516 else // on prend le choix utilisateur.
517 myKeepParam = KeepParametrization;
523 // ==> Q(u) = f(P(u))
524 // = f(O) + u * f(Xc)
526 gp_Lin L = myCurve->Line();
527 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
529 if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
530 myType = GeomAbs_BSplineCurve;
531 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
532 TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
533 TColgp_Array1OfPnt Poles(1,2); Poles.Init(P);
534 TColStd_Array1OfReal Knots(1,2);
535 Knots(1) = myCurve->FirstParameter();
536 Knots(2) = myCurve->LastParameter();
537 Handle(Geom_BSplineCurve) BSP =
538 new Geom_BSplineCurve(Poles,Knots,Mults,1);
540 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
541 GeomAdaptor_Curve aGACurve(BSP);
542 myResult = new GeomAdaptor_HCurve(aGACurve);
543 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
545 else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
546 myType = GeomAbs_Line;
547 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
548 myFirstPar = myCurve->FirstParameter();
549 myLastPar = myCurve->LastParameter();
550 aLine = gp_Lin(P,gp_Dir(Xc));
551 GeomLinePtr = new Geom_Line(aLine);
553 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
554 GeomAdaptor_Curve aGACurve(GeomLinePtr,
555 myCurve->FirstParameter(),
556 myCurve->LastParameter() );
557 myResult = new GeomAdaptor_HCurve(aGACurve);
558 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
561 myType = GeomAbs_Line;
562 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
563 aLine = gp_Lin(P,gp_Dir(Xc));
564 Standard_Real Udeb, Ufin;
566 // eval the first and last parameters of the projected curve
567 Udeb = myCurve->FirstParameter();
568 Ufin = myCurve->LastParameter();
569 gp_Pnt P1 = ProjectPnt(myPlane,myDirection,
570 myCurve->Value(Udeb));
571 gp_Pnt P2 = ProjectPnt(myPlane,myDirection,
572 myCurve->Value(Ufin));
573 myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
574 myLastPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
575 GeomLinePtr = new Geom_Line(aLine);
577 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
578 GeomAdaptor_Curve aGACurve(GeomLinePtr,
581 myResult = new GeomAdaptor_HCurve(aGACurve);
582 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
585 myType = GeomAbs_BSplineCurve;
587 // make a linear BSpline of degree 1 between the end points of
588 // the projected line
590 Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
591 new Geom_TrimmedCurve(GeomLinePtr,
595 Handle(Geom_BSplineCurve) NewCurvePtr =
596 GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
597 num_knots = NewCurvePtr->NbKnots() ;
598 TColStd_Array1OfReal BsplineKnots(1,num_knots) ;
599 NewCurvePtr->Knots(BsplineKnots) ;
601 BSplCLib::Reparametrize(myCurve->FirstParameter(),
602 myCurve->LastParameter(),
605 NewCurvePtr->SetKnots(BsplineKnots) ;
606 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
607 GeomAdaptor_Curve aGACurve(NewCurvePtr);
608 myResult = new GeomAdaptor_HCurve(aGACurve);
609 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
616 // Pour le cercle et l ellipse on a les relations suivantes:
617 // ( Rem : pour le cercle R1 = R2 = R)
618 // P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
619 // ==> Q(u) = f(P(u))
620 // = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
622 gp_Circ Circ = myCurve->Circle();
623 Axis = Circ.Position();
624 R1 = R2 = Circ.Radius();
627 case GeomAbs_Ellipse:
629 if ( Type == GeomAbs_Ellipse) {
630 gp_Elips E = myCurve->Ellipse();
632 R1 = E.MajorRadius();
633 R2 = E.MinorRadius();
636 // Common Code for CIRCLE & ELLIPSE begin here
637 gp_Dir X = Axis.XDirection();
638 gp_Dir Y = Axis.YDirection();
639 gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
640 gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
643 Standard_Real Tol2 = myTolerance*myTolerance;
644 if (VDx.SquareMagnitude() < Tol2 ||
645 VDy.SquareMagnitude() < Tol2 ) {
646 myIsApprox = Standard_True;
650 gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
653 gp_Pnt O = Axis.Location();
654 gp_Pnt P = ProjectPnt(myPlane,myDirection,O);
655 gp_Pnt Px = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
656 gp_Pnt Py = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
657 Standard_Real Major = P.Distance(Px);
658 Standard_Real Minor = P.Distance(Py);
659 gp_Ax2 Axe( P, Dx^Dy,Dx);
661 if ( Abs( Major - Minor) < Precision::Confusion()) {
662 myType = GeomAbs_Circle;
663 gp_Circ Circ(Axe, Major);
664 GeomCirclePtr = new Geom_Circle(Circ);
665 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
666 GeomAdaptor_Curve aGACurve(GeomCirclePtr);
667 myResult = new GeomAdaptor_HCurve(aGACurve);
668 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
670 else if ( Major > Minor) {
671 myType = GeomAbs_Ellipse;
672 Elips = gp_Elips( Axe, Major, Minor);
674 GeomEllipsePtr = new Geom_Ellipse(Elips) ;
675 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
676 GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
677 myResult = new GeomAdaptor_HCurve(aGACurve);
678 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
681 myIsApprox = Standard_True;
682 myType = GeomAbs_BSplineCurve;
683 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
684 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
685 GeomAdaptor_Curve aGACurve(ApproxCurve);
686 myResult = new GeomAdaptor_HCurve(aGACurve);
687 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
691 myIsApprox = Standard_True;
692 myType = GeomAbs_BSplineCurve;
693 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
694 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
695 GeomAdaptor_Curve aGACurve(ApproxCurve);
696 myResult = new GeomAdaptor_HCurve(aGACurve);
697 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
701 case GeomAbs_Parabola:
703 // P(u) = O + (u*u)/(4*f) * Xc + u * Yc
704 // ==> Q(u) = f(P(u))
705 // = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
707 gp_Parab Parab = myCurve->Parabola();
708 gp_Ax2 AxeRef = Parab.Position();
709 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
710 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
712 // fix for case when no one action is done. 28.03.2002
713 Standard_Boolean alocalIsDone = Standard_False;
715 if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
716 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
717 if ( Xc.Magnitude() < Precision::Confusion()) {
718 myType = GeomAbs_Line;
719 aLine = gp_Lin( P, gp_Dir(Yc));
721 GeomLinePtr = new Geom_Line(aLine) ;
722 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
723 GeomAdaptor_Curve aGACurve(GeomLinePtr);
724 myResult = new GeomAdaptor_HCurve(aGACurve);
725 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
726 alocalIsDone = Standard_True;
728 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
729 myType = GeomAbs_Parabola;
730 Standard_Real F = Parab.Focal() / Xc.Magnitude();
731 gp_Parab Parab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
732 Handle(Geom_Parabola) GeomParabolaPtr =
733 new Geom_Parabola(Parab) ;
734 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
735 GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
736 myResult = new GeomAdaptor_HCurve(aGACurve);
737 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
738 alocalIsDone = Standard_True;
741 if (!alocalIsDone)/*else*/ {
742 myIsApprox = Standard_True;
743 myType = GeomAbs_BSplineCurve;
744 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
745 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
746 GeomAdaptor_Curve aGACurve(ApproxCurve);
747 myResult = new GeomAdaptor_HCurve(aGACurve);
748 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
752 case GeomAbs_Hyperbola:
754 // P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
755 // ==> Q(u) = f(P(u))
756 // = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
758 gp_Hypr Hypr = myCurve->Hyperbola();
759 gp_Ax2 AxeRef = Hypr.Position();
760 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
761 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
762 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
763 Standard_Real R1 = Hypr.MajorRadius();
764 Standard_Real R2 = Hypr.MinorRadius();
765 gp_Dir Z = myPlane.Direction();
767 if ( Xc.Magnitude() < Precision::Confusion()) {
768 myType = GeomAbs_Hyperbola;
769 gp_Dir X = gp_Dir(Yc) ^ Z;
770 Hypr = gp_Hypr(gp_Ax2( P, Z, X), 0., R2 * Yc.Magnitude());
772 new Geom_Hyperbola(Hypr) ;
773 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
774 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
775 myResult = new GeomAdaptor_HCurve(aGACurve);
776 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
778 else if ( Yc.Magnitude() < Precision::Confusion()) {
779 myType = GeomAbs_Hyperbola;
781 gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
783 new Geom_Hyperbola(Hypr) ;
784 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
785 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
786 myResult = new GeomAdaptor_HCurve(aGACurve);
787 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
789 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
790 myType = GeomAbs_Hyperbola;
791 Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
792 R1 * Xc.Magnitude(), R2 * Yc.Magnitude() );
794 new Geom_Hyperbola(Hypr) ;
795 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
796 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
797 myResult = new GeomAdaptor_HCurve(aGACurve);
798 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
801 myIsApprox = Standard_True;
802 myType = GeomAbs_BSplineCurve;
803 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
804 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
805 GeomAdaptor_Curve aGACurve(ApproxCurve);
806 myResult = new GeomAdaptor_HCurve(aGACurve);
807 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
811 case GeomAbs_BezierCurve:
813 Handle(Geom_BezierCurve) BezierCurvePtr =
815 Standard_Integer NbPoles =
816 BezierCurvePtr->NbPoles() ;
818 Handle(Geom_BezierCurve) ProjCu =
819 Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
821 myIsApprox = Standard_False;
823 for ( Standard_Integer i = 1; i <= NbPoles; i++) {
825 (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
828 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
829 GeomAdaptor_Curve aGACurve(ProjCu);
830 myResult = new GeomAdaptor_HCurve(aGACurve);
831 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
834 case GeomAbs_BSplineCurve:
836 Handle(Geom_BSplineCurve) BSplineCurvePtr =
839 // make a copy of the curve and projects its poles
841 Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
842 Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
844 myIsApprox = Standard_False;
846 for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
847 ProjectedBSplinePtr->SetPole
848 (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
851 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
852 GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
853 myResult = new GeomAdaptor_HCurve(aGACurve);
854 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
859 myIsApprox = Standard_True;
860 myType = GeomAbs_BSplineCurve;
861 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
862 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
863 GeomAdaptor_Curve aGACurve(ApproxCurve);
864 myResult = new GeomAdaptor_HCurve(aGACurve);
865 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
871 //=======================================================================
872 //function : GetPlane
874 //=======================================================================
876 const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const
881 //=======================================================================
882 //function : GetDirection
884 //=======================================================================
886 const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const
891 //=======================================================================
892 //function : GetCurve
894 //=======================================================================
896 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
902 //=======================================================================
903 //function : FirstParameter
905 //=======================================================================
907 Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const
909 if ( myKeepParam || myIsApprox)
910 return myCurve->FirstParameter();
916 //=======================================================================
917 //function : LastParameter
919 //=======================================================================
921 Standard_Real ProjLib_ProjectOnPlane::LastParameter() const
923 if ( myKeepParam || myIsApprox)
924 return myCurve->LastParameter();
930 //=======================================================================
931 //function : Continuity
933 //=======================================================================
935 GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
937 return myCurve->Continuity() ;
941 //=======================================================================
942 //function : NbIntervals
944 //=======================================================================
946 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S)
948 return myCurve->NbIntervals(S) ;
952 //=======================================================================
953 //function : Intervals
955 //=======================================================================
957 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T,
958 const GeomAbs_Shape S)
960 myCurve->Intervals(T,S) ;
963 //=======================================================================
966 //=======================================================================
968 Handle(Adaptor3d_HCurve)
969 ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
970 const Standard_Real Last,
971 const Standard_Real Tolerance) const
973 if (myType != GeomAbs_OtherCurve){
974 return myResult->Trim(First,Last,Tolerance) ;
977 Standard_NotImplemented::Raise("");
981 Handle(Adaptor3d_HCurve) dummy;
986 //=======================================================================
987 //function : IsClosed
989 //=======================================================================
991 Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
993 return myCurve->IsClosed() ;
997 //=======================================================================
998 //function : IsPeriodic
1000 //=======================================================================
1002 Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
1005 return Standard_False;
1007 return myCurve->IsPeriodic();
1011 //=======================================================================
1014 //=======================================================================
1016 Standard_Real ProjLib_ProjectOnPlane::Period() const
1018 if ( !IsPeriodic()) {
1019 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
1023 return Standard_False;
1025 return myCurve->Period();
1029 //=======================================================================
1032 //=======================================================================
1034 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const
1036 if (myType != GeomAbs_OtherCurve) {
1037 return myResult->Value(U);
1040 return OnPlane_Value(U,
1049 //=======================================================================
1052 //=======================================================================
1054 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1056 if (myType != GeomAbs_OtherCurve) {
1060 P = OnPlane_Value(U,
1068 //=======================================================================
1071 //=======================================================================
1073 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1077 if (myType != GeomAbs_OtherCurve) {
1078 myResult->D1(U,P,V) ;
1091 //=======================================================================
1094 //=======================================================================
1096 void ProjLib_ProjectOnPlane::D2(const Standard_Real U,
1101 if (myType != GeomAbs_OtherCurve) {
1102 myResult->D2(U,P,V1,V2) ;
1116 //=======================================================================
1119 //=======================================================================
1121 void ProjLib_ProjectOnPlane::D3(const Standard_Real U,
1127 if (myType != GeomAbs_OtherCurve) {
1128 myResult->D3(U,P,V1,V2,V3) ;
1143 //=======================================================================
1146 //=======================================================================
1148 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U,
1149 const Standard_Integer DerivativeRequest)
1152 if (myType != GeomAbs_OtherCurve) {
1153 return myResult->DN(U,DerivativeRequest) ;
1156 return OnPlane_DN(U,
1165 //=======================================================================
1166 //function : Resolution
1168 //=======================================================================
1170 Standard_Real ProjLib_ProjectOnPlane::Resolution
1171 (const Standard_Real Tolerance) const
1173 if (myType != GeomAbs_OtherCurve) {
1174 return myResult->Resolution(Tolerance) ;
1182 //=======================================================================
1183 //function : GetType
1185 //=======================================================================
1187 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1193 //=======================================================================
1196 //=======================================================================
1198 gp_Lin ProjLib_ProjectOnPlane::Line() const
1200 if (myType != GeomAbs_Line)
1201 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");
1203 return myResult->Line();
1207 //=======================================================================
1210 //=======================================================================
1212 gp_Circ ProjLib_ProjectOnPlane::Circle() const
1214 if (myType != GeomAbs_Circle)
1215 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");
1217 return myResult->Circle();
1221 //=======================================================================
1222 //function : Ellipse
1224 //=======================================================================
1226 gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1228 if (myType != GeomAbs_Ellipse)
1229 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");
1231 return myResult->Ellipse();
1235 //=======================================================================
1236 //function : Hyperbola
1238 //=======================================================================
1240 gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1242 if (myType != GeomAbs_Hyperbola)
1243 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");
1245 return myResult->Hyperbola() ;
1249 //=======================================================================
1250 //function : Parabola
1252 //=======================================================================
1254 gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1256 if (myType != GeomAbs_Parabola)
1257 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
1259 return myResult->Parabola() ;
1262 //=======================================================================
1265 //=======================================================================
1267 Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1269 if ((GetType() != GeomAbs_BSplineCurve) &&
1270 (GetType() != GeomAbs_BezierCurve))
1271 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");
1274 return myResult->Degree();
1276 return myCurve->Degree();
1279 //=======================================================================
1280 //function : IsRational
1282 //=======================================================================
1284 Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const
1286 if ((GetType() != GeomAbs_BSplineCurve) &&
1287 (GetType() != GeomAbs_BezierCurve))
1288 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
1291 return myResult->IsRational();
1293 return myCurve->IsRational();
1296 //=======================================================================
1297 //function : NbPoles
1299 //=======================================================================
1301 Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1303 if ((GetType() != GeomAbs_BSplineCurve) &&
1304 (GetType() != GeomAbs_BezierCurve))
1305 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
1308 return myResult->NbPoles();
1310 return myCurve->NbPoles();
1313 //=======================================================================
1314 //function : NbKnots
1316 //=======================================================================
1318 Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const
1320 if ( GetType() != GeomAbs_BSplineCurve)
1321 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
1324 return myResult->NbKnots();
1326 return myCurve->NbKnots();
1330 //=======================================================================
1333 //=======================================================================
1335 Handle(Geom_BezierCurve) ProjLib_ProjectOnPlane::Bezier() const
1337 if (myType != GeomAbs_BezierCurve)
1338 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");
1340 return myResult->Bezier() ;
1343 //=======================================================================
1346 //=======================================================================
1348 Handle(Geom_BSplineCurve) ProjLib_ProjectOnPlane::BSpline() const
1350 if (myType != GeomAbs_BSplineCurve)
1351 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");
1353 return myResult->BSpline() ;