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(Deg1,Deg2,Precision::Approximation(),
321 Precision::PApproximation(),Standard_True);
322 Fit.SetMaxSegments(100);
324 if (!Fit.IsAllApproximated())
329 Standard_Integer NbCurves = Fit.NbMultiCurves();
330 Standard_Integer MaxDeg = 0;
332 // Pour transformer la MultiCurve en BSpline, il faut que toutes
333 // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
334 Standard_Integer NbPoles = 1;
335 for (i = 1; i <= NbCurves; i++) {
336 Standard_Integer Deg = Fit.Value(i).Degree();
337 MaxDeg = Max ( MaxDeg, Deg);
339 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
341 TColgp_Array1OfPnt Poles( 1, NbPoles);
343 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
345 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
347 Standard_Integer Compt = 1;
348 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
349 Fit.Parameters(i, Knots(i), Knots(i+1));
351 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
352 TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
353 MC.Curve(1, LocalPoles);
355 //Augmentation eventuelle du degre
356 if (MaxDeg > MC.Degree() ) {
357 BSplCLib::IncreaseDegree(MaxDeg, LocalPoles, BSplCLib::NoWeights(),
358 TempPoles, BSplCLib::NoWeights());
359 //mise a jour des poles de la PCurve
360 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
361 Poles.SetValue( Compt, TempPoles( j));
366 //mise a jour des poles de la PCurve
367 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
368 Poles.SetValue( Compt, LocalPoles( j));
376 //mise a jour des fields de ProjLib_Approx
379 NbKnots = NbCurves + 1;
381 TColStd_Array1OfInteger Mults(1, NbKnots);
382 Mults.SetValue( 1, MaxDeg + 1);
383 for ( i = 2; i <= NbCurves; i++) {
384 Mults.SetValue( i, MaxDeg);
386 Mults.SetValue( NbKnots, MaxDeg + 1);
388 new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
392 //=======================================================================
393 //function : ProjectOnPlane
395 //=======================================================================
397 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
398 myKeepParam(Standard_False),
402 myType (GeomAbs_OtherCurve),
403 myIsApprox (Standard_False)
407 //=======================================================================
408 //function : ProjLib_ProjectOnPlane
410 //=======================================================================
412 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) :
414 myDirection (Pl.Direction()) ,
415 myKeepParam(Standard_False),
419 myType (GeomAbs_OtherCurve),
420 myIsApprox (Standard_False)
424 //=======================================================================
425 //function : ProjLib_ProjectOnPlane
427 //=======================================================================
429 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
433 myKeepParam(Standard_False),
437 myType (GeomAbs_OtherCurve),
438 myIsApprox (Standard_False)
440 // if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
441 // throw Standard_ConstructionError
442 // ("ProjLib_ProjectOnPlane: The Direction and the Plane are parallel");
446 //=======================================================================
448 //purpose : Returns the projection of a point <Point> on a plane
449 // <ThePlane> along a direction <TheDir>.
450 //=======================================================================
452 static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
453 const gp_Dir& TheDir,
456 gp_Vec PO(Point,ThePlane.Location());
458 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
459 Alpha /= TheDir * ThePlane.Direction();
462 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
468 //=======================================================================
470 //purpose : Returns the projection of a Vector <Vec> on a plane
471 // <ThePlane> along a direction <TheDir>.
472 //=======================================================================
474 static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
475 const gp_Dir& TheDir,
479 gp_Vec Z = ThePlane.Direction();
481 D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
486 //=======================================================================
489 //=======================================================================
491 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
492 const Standard_Real Tolerance,
493 const Standard_Boolean KeepParametrization)
497 myType = GeomAbs_OtherCurve;
498 myIsApprox = Standard_False;
499 myTolerance = Tolerance ;
501 Handle(Geom_BSplineCurve) ApproxCurve;
502 Handle(GeomAdaptor_HCurve) aGAHCurve;
504 Handle(Geom_Line) GeomLinePtr;
505 Handle(Geom_Circle) GeomCirclePtr ;
506 Handle(Geom_Ellipse) GeomEllipsePtr ;
507 Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
513 Standard_Integer num_knots ;
514 GeomAbs_CurveType Type = C->GetType();
517 Standard_Real R1 =0., R2 =0.;
519 if ( Type != GeomAbs_Line) // on garde le parametrage
520 myKeepParam = Standard_True;
521 else // on prend le choix utilisateur.
522 myKeepParam = KeepParametrization;
528 // ==> Q(u) = f(P(u))
529 // = f(O) + u * f(Xc)
531 gp_Lin L = myCurve->Line();
532 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
534 if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
535 myType = GeomAbs_BSplineCurve;
536 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
537 TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
538 TColgp_Array1OfPnt Poles(1,2); Poles.Init(P);
539 TColStd_Array1OfReal Knots(1,2);
540 Knots(1) = myCurve->FirstParameter();
541 Knots(2) = myCurve->LastParameter();
542 Handle(Geom_BSplineCurve) BSP =
543 new Geom_BSplineCurve(Poles,Knots,Mults,1);
545 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
546 GeomAdaptor_Curve aGACurve(BSP);
547 myResult = new GeomAdaptor_HCurve(aGACurve);
548 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
550 else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
551 myType = GeomAbs_Line;
552 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
553 myFirstPar = myCurve->FirstParameter();
554 myLastPar = myCurve->LastParameter();
555 aLine = gp_Lin(P,gp_Dir(Xc));
556 GeomLinePtr = new Geom_Line(aLine);
558 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
559 GeomAdaptor_Curve aGACurve(GeomLinePtr,
560 myCurve->FirstParameter(),
561 myCurve->LastParameter() );
562 myResult = new GeomAdaptor_HCurve(aGACurve);
563 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
566 myType = GeomAbs_Line;
567 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
568 aLine = gp_Lin(P,gp_Dir(Xc));
569 Standard_Real Udeb, Ufin;
571 // eval the first and last parameters of the projected curve
572 Udeb = myCurve->FirstParameter();
573 Ufin = myCurve->LastParameter();
574 gp_Pnt P1 = ProjectPnt(myPlane,myDirection,
575 myCurve->Value(Udeb));
576 gp_Pnt P2 = ProjectPnt(myPlane,myDirection,
577 myCurve->Value(Ufin));
578 myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
579 myLastPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
580 GeomLinePtr = new Geom_Line(aLine);
582 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
583 GeomAdaptor_Curve aGACurve(GeomLinePtr,
586 myResult = new GeomAdaptor_HCurve(aGACurve);
587 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
590 myType = GeomAbs_BSplineCurve;
592 // make a linear BSpline of degree 1 between the end points of
593 // the projected line
595 Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
596 new Geom_TrimmedCurve(GeomLinePtr,
600 Handle(Geom_BSplineCurve) NewCurvePtr =
601 GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
602 num_knots = NewCurvePtr->NbKnots() ;
603 TColStd_Array1OfReal BsplineKnots(1,num_knots) ;
604 NewCurvePtr->Knots(BsplineKnots) ;
606 BSplCLib::Reparametrize(myCurve->FirstParameter(),
607 myCurve->LastParameter(),
610 NewCurvePtr->SetKnots(BsplineKnots) ;
611 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
612 GeomAdaptor_Curve aGACurve(NewCurvePtr);
613 myResult = new GeomAdaptor_HCurve(aGACurve);
614 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
621 // Pour le cercle et l ellipse on a les relations suivantes:
622 // ( Rem : pour le cercle R1 = R2 = R)
623 // P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
624 // ==> Q(u) = f(P(u))
625 // = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
627 gp_Circ Circ = myCurve->Circle();
628 Axis = Circ.Position();
629 R1 = R2 = Circ.Radius();
633 case GeomAbs_Ellipse:
635 if ( Type == GeomAbs_Ellipse) {
636 gp_Elips E = myCurve->Ellipse();
638 R1 = E.MajorRadius();
639 R2 = E.MinorRadius();
642 // Common Code for CIRCLE & ELLIPSE begin here
643 gp_Dir X = Axis.XDirection();
644 gp_Dir Y = Axis.YDirection();
645 gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
646 gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
649 Standard_Real Tol2 = myTolerance*myTolerance;
650 if (VDx.SquareMagnitude() < Tol2 ||
651 VDy.SquareMagnitude() < Tol2 ) {
652 myIsApprox = Standard_True;
656 gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
659 gp_Pnt O = Axis.Location();
660 gp_Pnt P = ProjectPnt(myPlane,myDirection,O);
661 gp_Pnt Px = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
662 gp_Pnt Py = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
663 Standard_Real Major = P.Distance(Px);
664 Standard_Real Minor = P.Distance(Py);
665 gp_Ax2 Axe( P, Dx^Dy,Dx);
667 if ( Abs( Major - Minor) < Precision::Confusion()) {
668 myType = GeomAbs_Circle;
669 gp_Circ Circ(Axe, Major);
670 GeomCirclePtr = new Geom_Circle(Circ);
671 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
672 GeomAdaptor_Curve aGACurve(GeomCirclePtr);
673 myResult = new GeomAdaptor_HCurve(aGACurve);
674 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
676 else if ( Major > Minor) {
677 myType = GeomAbs_Ellipse;
678 Elips = gp_Elips( Axe, Major, Minor);
680 GeomEllipsePtr = new Geom_Ellipse(Elips) ;
681 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
682 GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
683 myResult = new GeomAdaptor_HCurve(aGACurve);
684 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
687 myIsApprox = Standard_True;
688 myType = GeomAbs_BSplineCurve;
689 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
690 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
691 GeomAdaptor_Curve aGACurve(ApproxCurve);
692 myResult = new GeomAdaptor_HCurve(aGACurve);
693 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
697 myIsApprox = Standard_True;
698 myType = GeomAbs_BSplineCurve;
699 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
700 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
701 GeomAdaptor_Curve aGACurve(ApproxCurve);
702 myResult = new GeomAdaptor_HCurve(aGACurve);
703 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
707 case GeomAbs_Parabola:
709 // P(u) = O + (u*u)/(4*f) * Xc + u * Yc
710 // ==> Q(u) = f(P(u))
711 // = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
713 gp_Parab Parab = myCurve->Parabola();
714 gp_Ax2 AxeRef = Parab.Position();
715 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
716 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
718 // fix for case when no one action is done. 28.03.2002
719 Standard_Boolean alocalIsDone = Standard_False;
721 if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
722 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
723 if ( Xc.Magnitude() < Precision::Confusion()) {
724 myType = GeomAbs_Line;
725 aLine = gp_Lin( P, gp_Dir(Yc));
727 GeomLinePtr = new Geom_Line(aLine) ;
728 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
729 GeomAdaptor_Curve aGACurve(GeomLinePtr);
730 myResult = new GeomAdaptor_HCurve(aGACurve);
731 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
732 alocalIsDone = Standard_True;
734 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
735 myType = GeomAbs_Parabola;
736 Standard_Real F = Parab.Focal() / Xc.Magnitude();
737 gp_Parab aParab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
738 Handle(Geom_Parabola) GeomParabolaPtr =
739 new Geom_Parabola(aParab) ;
740 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
741 GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
742 myResult = new GeomAdaptor_HCurve(aGACurve);
743 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
744 alocalIsDone = Standard_True;
747 if (!alocalIsDone)/*else*/ {
748 myIsApprox = Standard_True;
749 myType = GeomAbs_BSplineCurve;
750 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
751 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
752 GeomAdaptor_Curve aGACurve(ApproxCurve);
753 myResult = new GeomAdaptor_HCurve(aGACurve);
754 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
758 case GeomAbs_Hyperbola:
760 // P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
761 // ==> Q(u) = f(P(u))
762 // = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
764 gp_Hypr Hypr = myCurve->Hyperbola();
765 gp_Ax2 AxeRef = Hypr.Position();
766 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
767 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
768 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
769 Standard_Real aR1 = Hypr.MajorRadius();
770 Standard_Real aR2 = Hypr.MinorRadius();
771 gp_Dir Z = myPlane.Direction();
773 if ( Xc.Magnitude() < Precision::Confusion()) {
774 myType = GeomAbs_Hyperbola;
775 gp_Dir X = gp_Dir(Yc) ^ Z;
776 Hypr = gp_Hypr(gp_Ax2( P, Z, X), 0., aR2 * Yc.Magnitude());
778 new Geom_Hyperbola(Hypr) ;
779 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
780 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
781 myResult = new GeomAdaptor_HCurve(aGACurve);
782 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
784 else if ( Yc.Magnitude() < Precision::Confusion()) {
785 myType = GeomAbs_Hyperbola;
787 gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), aR1 * Xc.Magnitude(), 0.);
789 new Geom_Hyperbola(Hypr) ;
790 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
791 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
792 myResult = new GeomAdaptor_HCurve(aGACurve);
793 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
795 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
796 myType = GeomAbs_Hyperbola;
797 Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
798 aR1 * Xc.Magnitude(), aR2 * Yc.Magnitude() );
800 new Geom_Hyperbola(Hypr) ;
801 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
802 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
803 myResult = new GeomAdaptor_HCurve(aGACurve);
804 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
807 myIsApprox = Standard_True;
808 myType = GeomAbs_BSplineCurve;
809 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
810 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
811 GeomAdaptor_Curve aGACurve(ApproxCurve);
812 myResult = new GeomAdaptor_HCurve(aGACurve);
813 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
817 case GeomAbs_BezierCurve:
819 Handle(Geom_BezierCurve) BezierCurvePtr =
821 Standard_Integer NbPoles =
822 BezierCurvePtr->NbPoles() ;
824 Handle(Geom_BezierCurve) ProjCu =
825 Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
827 myIsApprox = Standard_False;
829 for ( Standard_Integer i = 1; i <= NbPoles; i++) {
831 (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
834 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
835 GeomAdaptor_Curve aGACurve(ProjCu);
836 myResult = new GeomAdaptor_HCurve(aGACurve);
837 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
840 case GeomAbs_BSplineCurve:
842 Handle(Geom_BSplineCurve) BSplineCurvePtr =
845 // make a copy of the curve and projects its poles
847 Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
848 Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
850 myIsApprox = Standard_False;
852 for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
853 ProjectedBSplinePtr->SetPole
854 (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
857 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
858 GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
859 myResult = new GeomAdaptor_HCurve(aGACurve);
860 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
865 myIsApprox = Standard_True;
866 myType = GeomAbs_BSplineCurve;
867 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
868 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
869 GeomAdaptor_Curve aGACurve(ApproxCurve);
870 myResult = new GeomAdaptor_HCurve(aGACurve);
871 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
877 //=======================================================================
878 //function : GetPlane
880 //=======================================================================
882 const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const
887 //=======================================================================
888 //function : GetDirection
890 //=======================================================================
892 const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const
897 //=======================================================================
898 //function : GetCurve
900 //=======================================================================
902 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
907 //=======================================================================
908 //function : GetResult
910 //=======================================================================
912 const Handle(GeomAdaptor_HCurve)& ProjLib_ProjectOnPlane::GetResult() const
918 //=======================================================================
919 //function : FirstParameter
921 //=======================================================================
923 Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const
925 if ( myKeepParam || myIsApprox)
926 return myCurve->FirstParameter();
932 //=======================================================================
933 //function : LastParameter
935 //=======================================================================
937 Standard_Real ProjLib_ProjectOnPlane::LastParameter() const
939 if ( myKeepParam || myIsApprox)
940 return myCurve->LastParameter();
946 //=======================================================================
947 //function : Continuity
949 //=======================================================================
951 GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
953 return myCurve->Continuity() ;
957 //=======================================================================
958 //function : NbIntervals
960 //=======================================================================
962 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S) const
964 return myCurve->NbIntervals(S) ;
968 //=======================================================================
969 //function : Intervals
971 //=======================================================================
973 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T,
974 const GeomAbs_Shape S) const
976 myCurve->Intervals(T,S) ;
979 //=======================================================================
982 //=======================================================================
984 Handle(Adaptor3d_HCurve)
985 ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
986 const Standard_Real Last,
987 const Standard_Real Tolerance) const
989 if (myType != GeomAbs_OtherCurve){
990 return myResult->Trim(First,Last,Tolerance) ;
993 throw Standard_NotImplemented ("ProjLib_ProjectOnPlane::Trim() - curve of unsupported type");
998 //=======================================================================
999 //function : IsClosed
1001 //=======================================================================
1003 Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
1005 return myCurve->IsClosed() ;
1009 //=======================================================================
1010 //function : IsPeriodic
1012 //=======================================================================
1014 Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
1017 return Standard_False;
1019 return myCurve->IsPeriodic();
1023 //=======================================================================
1026 //=======================================================================
1028 Standard_Real ProjLib_ProjectOnPlane::Period() const
1030 if ( !IsPeriodic()) {
1031 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane::Period");
1035 return Standard_False;
1037 return myCurve->Period();
1041 //=======================================================================
1044 //=======================================================================
1046 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const
1048 if (myType != GeomAbs_OtherCurve) {
1049 return myResult->Value(U);
1052 return OnPlane_Value(U,
1061 //=======================================================================
1064 //=======================================================================
1066 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1068 if (myType != GeomAbs_OtherCurve) {
1072 P = OnPlane_Value(U,
1080 //=======================================================================
1083 //=======================================================================
1085 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1089 if (myType != GeomAbs_OtherCurve) {
1090 myResult->D1(U,P,V) ;
1103 //=======================================================================
1106 //=======================================================================
1108 void ProjLib_ProjectOnPlane::D2(const Standard_Real U,
1113 if (myType != GeomAbs_OtherCurve) {
1114 myResult->D2(U,P,V1,V2) ;
1128 //=======================================================================
1131 //=======================================================================
1133 void ProjLib_ProjectOnPlane::D3(const Standard_Real U,
1139 if (myType != GeomAbs_OtherCurve) {
1140 myResult->D3(U,P,V1,V2,V3) ;
1155 //=======================================================================
1158 //=======================================================================
1160 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U,
1161 const Standard_Integer DerivativeRequest)
1164 if (myType != GeomAbs_OtherCurve) {
1165 return myResult->DN(U,DerivativeRequest) ;
1168 return OnPlane_DN(U,
1177 //=======================================================================
1178 //function : Resolution
1180 //=======================================================================
1182 Standard_Real ProjLib_ProjectOnPlane::Resolution
1183 (const Standard_Real Tolerance) const
1185 if (myType != GeomAbs_OtherCurve) {
1186 return myResult->Resolution(Tolerance) ;
1194 //=======================================================================
1195 //function : GetType
1197 //=======================================================================
1199 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1205 //=======================================================================
1208 //=======================================================================
1210 gp_Lin ProjLib_ProjectOnPlane::Line() const
1212 if (myType != GeomAbs_Line)
1213 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Line");
1215 return myResult->Line();
1219 //=======================================================================
1222 //=======================================================================
1224 gp_Circ ProjLib_ProjectOnPlane::Circle() const
1226 if (myType != GeomAbs_Circle)
1227 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Circle");
1229 return myResult->Circle();
1233 //=======================================================================
1234 //function : Ellipse
1236 //=======================================================================
1238 gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1240 if (myType != GeomAbs_Ellipse)
1241 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Ellipse");
1243 return myResult->Ellipse();
1247 //=======================================================================
1248 //function : Hyperbola
1250 //=======================================================================
1252 gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1254 if (myType != GeomAbs_Hyperbola)
1255 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Hyperbola");
1257 return myResult->Hyperbola() ;
1261 //=======================================================================
1262 //function : Parabola
1264 //=======================================================================
1266 gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1268 if (myType != GeomAbs_Parabola)
1269 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Parabola");
1271 return myResult->Parabola() ;
1274 //=======================================================================
1277 //=======================================================================
1279 Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1281 if ((GetType() != GeomAbs_BSplineCurve) &&
1282 (GetType() != GeomAbs_BezierCurve))
1283 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Degree");
1286 return myResult->Degree();
1288 return myCurve->Degree();
1291 //=======================================================================
1292 //function : IsRational
1294 //=======================================================================
1296 Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const
1298 if ((GetType() != GeomAbs_BSplineCurve) &&
1299 (GetType() != GeomAbs_BezierCurve))
1300 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:IsRational");
1303 return myResult->IsRational();
1305 return myCurve->IsRational();
1308 //=======================================================================
1309 //function : NbPoles
1311 //=======================================================================
1313 Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1315 if ((GetType() != GeomAbs_BSplineCurve) &&
1316 (GetType() != GeomAbs_BezierCurve))
1317 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:NbPoles");
1320 return myResult->NbPoles();
1322 return myCurve->NbPoles();
1325 //=======================================================================
1326 //function : NbKnots
1328 //=======================================================================
1330 Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const
1332 if ( GetType() != GeomAbs_BSplineCurve)
1333 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:NbKnots");
1336 return myResult->NbKnots();
1338 return myCurve->NbKnots();
1342 //=======================================================================
1345 //=======================================================================
1347 Handle(Geom_BezierCurve) ProjLib_ProjectOnPlane::Bezier() const
1349 if (myType != GeomAbs_BezierCurve)
1350 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:Bezier");
1352 return myResult->Bezier() ;
1355 //=======================================================================
1358 //=======================================================================
1360 Handle(Geom_BSplineCurve) ProjLib_ProjectOnPlane::BSpline() const
1362 if (myType != GeomAbs_BSplineCurve)
1363 throw Standard_NoSuchObject("ProjLib_ProjectOnPlane:BSpline");
1365 return myResult->BSpline() ;