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,
260 : myCurve(C), myPlane(Pl), myDirection(D)
263 Standard_Real FirstParameter() const
264 {return myCurve->FirstParameter();}
266 Standard_Real LastParameter() const
267 {return myCurve->LastParameter();}
269 gp_Pnt Value( const Standard_Real t) const
270 {return OnPlane_Value(t,myCurve,myPlane,myDirection);}
272 Standard_Boolean D1(const Standard_Real t, gp_Pnt& P, gp_Vec& V) const
273 {return OnPlane_D1(t,P,V,myCurve,myPlane,myDirection);}
279 //=====================================================================//
281 // D E S C R I P T I O N O F T H E C L A S S : //
283 // 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 //
285 //=====================================================================//
289 //=======================================================================
290 //function : PerformApprox
292 //=======================================================================
294 static void PerformApprox (const Handle(Adaptor3d_HCurve)& C,
297 Handle(Geom_BSplineCurve) &BSplineCurvePtr)
300 ProjLib_OnPlane F(C,Pl,D);
302 Standard_Integer Deg1, Deg2;
305 Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
306 Precision::PApproximation(),Standard_True);
308 Standard_Integer NbCurves = Fit.NbMultiCurves();
309 Standard_Integer MaxDeg = 0;
311 // Pour transformer la MultiCurve en BSpline, il faut que toutes
312 // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
313 Standard_Integer NbPoles = 1;
314 for (i = 1; i <= NbCurves; i++) {
315 Standard_Integer Deg = Fit.Value(i).Degree();
316 MaxDeg = Max ( MaxDeg, Deg);
318 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
320 TColgp_Array1OfPnt Poles( 1, NbPoles);
322 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
324 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
326 Standard_Integer Compt = 1;
327 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
328 Fit.Parameters(i, Knots(i), Knots(i+1));
330 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
331 TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
332 MC.Curve(1, LocalPoles);
334 //Augmentation eventuelle du degre
335 Standard_Integer Inc = MaxDeg - MC.Degree();
337 BSplCLib::IncreaseDegree(Inc, Poles, PLib::NoWeights(),
338 TempPoles, PLib::NoWeights());
339 //mise a jour des poles de la PCurve
340 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
341 Poles.SetValue( Compt, TempPoles( j));
346 //mise a jour des poles de la PCurve
347 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
348 Poles.SetValue( Compt, LocalPoles( j));
356 //mise a jour des fields de ProjLib_Approx
359 NbKnots = NbCurves + 1;
361 TColStd_Array1OfInteger Mults(1, NbKnots);
362 Mults.SetValue( 1, MaxDeg + 1);
363 for ( i = 2; i <= NbCurves; i++) {
364 Mults.SetValue( i, MaxDeg);
366 Mults.SetValue( NbKnots, MaxDeg + 1);
368 new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
372 //=======================================================================
373 //function : ProjectOnPlane
375 //=======================================================================
377 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
378 myKeepParam(Standard_False),
382 myType (GeomAbs_OtherCurve),
383 myIsApprox (Standard_False)
387 //=======================================================================
388 //function : ProjLib_ProjectOnPlane
390 //=======================================================================
392 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) :
394 myDirection (Pl.Direction()) ,
395 myKeepParam(Standard_False),
399 myType (GeomAbs_OtherCurve),
400 myIsApprox (Standard_False)
404 //=======================================================================
405 //function : ProjLib_ProjectOnPlane
407 //=======================================================================
409 ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
413 myKeepParam(Standard_False),
417 myType (GeomAbs_OtherCurve),
418 myIsApprox (Standard_False)
420 // if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
421 // Standard_ConstructionError::Raise
422 // ("ProjLib_ProjectOnPlane: The Direction and the Plane are parallel");
426 //=======================================================================
428 //purpose : Returns the projection of a point <Point> on a plane
429 // <ThePlane> along a direction <TheDir>.
430 //=======================================================================
432 static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
433 const gp_Dir& TheDir,
436 gp_Vec PO(Point,ThePlane.Location());
438 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
439 Alpha /= TheDir * ThePlane.Direction();
442 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
448 //=======================================================================
450 //purpose : Returns the projection of a Vector <Vec> on a plane
451 // <ThePlane> along a direction <TheDir>.
452 //=======================================================================
454 static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
455 const gp_Dir& TheDir,
459 gp_Vec Z = ThePlane.Direction();
461 D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
466 //=======================================================================
469 //=======================================================================
471 void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
472 const Standard_Real Tolerance,
473 const Standard_Boolean KeepParametrization)
477 myType = GeomAbs_OtherCurve;
478 myIsApprox = Standard_False;
479 myTolerance = Tolerance ;
481 Handle(Geom_BSplineCurve) ApproxCurve;
482 Handle(GeomAdaptor_HCurve) aGAHCurve;
484 Handle(Geom_Line) GeomLinePtr;
485 Handle(Geom_Circle) GeomCirclePtr ;
486 Handle(Geom_Ellipse) GeomEllipsePtr ;
487 Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
493 Standard_Integer num_knots ;
494 GeomAbs_CurveType Type = C->GetType();
497 Standard_Real R1 =0., R2 =0.;
499 if ( Type != GeomAbs_Line) // on garde le parametrage
500 myKeepParam = Standard_True;
501 else // on prend le choix utilisateur.
502 myKeepParam = KeepParametrization;
508 // ==> Q(u) = f(P(u))
509 // = f(O) + u * f(Xc)
511 gp_Lin L = myCurve->Line();
512 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
514 if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
515 myType = GeomAbs_BSplineCurve;
516 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
517 TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
518 TColgp_Array1OfPnt Poles(1,2); Poles.Init(P);
519 TColStd_Array1OfReal Knots(1,2);
520 Knots(1) = myCurve->FirstParameter();
521 Knots(2) = myCurve->LastParameter();
522 Handle(Geom_BSplineCurve) BSP =
523 new Geom_BSplineCurve(Poles,Knots,Mults,1);
525 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
526 GeomAdaptor_Curve aGACurve(BSP);
527 myResult = new GeomAdaptor_HCurve(aGACurve);
528 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
530 else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
531 myType = GeomAbs_Line;
532 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
533 myFirstPar = myCurve->FirstParameter();
534 myLastPar = myCurve->LastParameter();
535 aLine = gp_Lin(P,gp_Dir(Xc));
536 GeomLinePtr = new Geom_Line(aLine);
538 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
539 GeomAdaptor_Curve aGACurve(GeomLinePtr,
540 myCurve->FirstParameter(),
541 myCurve->LastParameter() );
542 myResult = new GeomAdaptor_HCurve(aGACurve);
543 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
546 myType = GeomAbs_Line;
547 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
548 aLine = gp_Lin(P,gp_Dir(Xc));
549 Standard_Real Udeb, Ufin;
551 // eval the first and last parameters of the projected curve
552 Udeb = myCurve->FirstParameter();
553 Ufin = myCurve->LastParameter();
554 gp_Pnt P1 = ProjectPnt(myPlane,myDirection,
555 myCurve->Value(Udeb));
556 gp_Pnt P2 = ProjectPnt(myPlane,myDirection,
557 myCurve->Value(Ufin));
558 myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
559 myLastPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
560 GeomLinePtr = new Geom_Line(aLine);
562 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
563 GeomAdaptor_Curve aGACurve(GeomLinePtr,
566 myResult = new GeomAdaptor_HCurve(aGACurve);
567 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
570 myType = GeomAbs_BSplineCurve;
572 // make a linear BSpline of degree 1 between the end points of
573 // the projected line
575 Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
576 new Geom_TrimmedCurve(GeomLinePtr,
580 Handle(Geom_BSplineCurve) NewCurvePtr =
581 GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
582 num_knots = NewCurvePtr->NbKnots() ;
583 TColStd_Array1OfReal BsplineKnots(1,num_knots) ;
584 NewCurvePtr->Knots(BsplineKnots) ;
586 BSplCLib::Reparametrize(myCurve->FirstParameter(),
587 myCurve->LastParameter(),
590 NewCurvePtr->SetKnots(BsplineKnots) ;
591 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
592 GeomAdaptor_Curve aGACurve(NewCurvePtr);
593 myResult = new GeomAdaptor_HCurve(aGACurve);
594 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
601 // Pour le cercle et l ellipse on a les relations suivantes:
602 // ( Rem : pour le cercle R1 = R2 = R)
603 // P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
604 // ==> Q(u) = f(P(u))
605 // = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
607 gp_Circ Circ = myCurve->Circle();
608 Axis = Circ.Position();
609 R1 = R2 = Circ.Radius();
612 case GeomAbs_Ellipse:
614 if ( Type == GeomAbs_Ellipse) {
615 gp_Elips E = myCurve->Ellipse();
617 R1 = E.MajorRadius();
618 R2 = E.MinorRadius();
621 // Common Code for CIRCLE & ELLIPSE begin here
622 gp_Dir X = Axis.XDirection();
623 gp_Dir Y = Axis.YDirection();
624 gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
625 gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
628 Standard_Real Tol2 = myTolerance*myTolerance;
629 if (VDx.SquareMagnitude() < Tol2 ||
630 VDy.SquareMagnitude() < Tol2 ) {
631 myIsApprox = Standard_True;
635 gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
638 gp_Pnt O = Axis.Location();
639 gp_Pnt P = ProjectPnt(myPlane,myDirection,O);
640 gp_Pnt Px = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
641 gp_Pnt Py = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
642 Standard_Real Major = P.Distance(Px);
643 Standard_Real Minor = P.Distance(Py);
644 gp_Ax2 Axe( P, Dx^Dy,Dx);
646 if ( Abs( Major - Minor) < Precision::Confusion()) {
647 myType = GeomAbs_Circle;
648 gp_Circ Circ(Axe, Major);
649 GeomCirclePtr = new Geom_Circle(Circ);
650 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
651 GeomAdaptor_Curve aGACurve(GeomCirclePtr);
652 myResult = new GeomAdaptor_HCurve(aGACurve);
653 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
655 else if ( Major > Minor) {
656 myType = GeomAbs_Ellipse;
657 Elips = gp_Elips( Axe, Major, Minor);
659 GeomEllipsePtr = new Geom_Ellipse(Elips) ;
660 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
661 GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
662 myResult = new GeomAdaptor_HCurve(aGACurve);
663 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
666 myIsApprox = Standard_True;
667 myType = GeomAbs_BSplineCurve;
668 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
669 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
670 GeomAdaptor_Curve aGACurve(ApproxCurve);
671 myResult = new GeomAdaptor_HCurve(aGACurve);
672 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
676 myIsApprox = Standard_True;
677 myType = GeomAbs_BSplineCurve;
678 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
679 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
680 GeomAdaptor_Curve aGACurve(ApproxCurve);
681 myResult = new GeomAdaptor_HCurve(aGACurve);
682 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
686 case GeomAbs_Parabola:
688 // P(u) = O + (u*u)/(4*f) * Xc + u * Yc
689 // ==> Q(u) = f(P(u))
690 // = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
692 gp_Parab Parab = myCurve->Parabola();
693 gp_Ax2 AxeRef = Parab.Position();
694 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
695 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
697 // fix for case when no one action is done. 28.03.2002
698 Standard_Boolean alocalIsDone = Standard_False;
700 if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
701 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
702 if ( Xc.Magnitude() < Precision::Confusion()) {
703 myType = GeomAbs_Line;
704 aLine = gp_Lin( P, gp_Dir(Yc));
706 GeomLinePtr = new Geom_Line(aLine) ;
707 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
708 GeomAdaptor_Curve aGACurve(GeomLinePtr);
709 myResult = new GeomAdaptor_HCurve(aGACurve);
710 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
711 alocalIsDone = Standard_True;
713 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
714 myType = GeomAbs_Parabola;
715 Standard_Real F = Parab.Focal() / Xc.Magnitude();
716 gp_Parab Parab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
717 Handle(Geom_Parabola) GeomParabolaPtr =
718 new Geom_Parabola(Parab) ;
719 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
720 GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
721 myResult = new GeomAdaptor_HCurve(aGACurve);
722 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
723 alocalIsDone = Standard_True;
726 if (!alocalIsDone)/*else*/ {
727 myIsApprox = Standard_True;
728 myType = GeomAbs_BSplineCurve;
729 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
730 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
731 GeomAdaptor_Curve aGACurve(ApproxCurve);
732 myResult = new GeomAdaptor_HCurve(aGACurve);
733 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
737 case GeomAbs_Hyperbola:
739 // P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
740 // ==> Q(u) = f(P(u))
741 // = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
743 gp_Hypr Hypr = myCurve->Hyperbola();
744 gp_Ax2 AxeRef = Hypr.Position();
745 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
746 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
747 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
748 Standard_Real R1 = Hypr.MajorRadius();
749 Standard_Real R2 = Hypr.MinorRadius();
750 gp_Dir Z = myPlane.Direction();
752 if ( Xc.Magnitude() < Precision::Confusion()) {
753 myType = GeomAbs_Hyperbola;
754 gp_Dir X = gp_Dir(Yc) ^ Z;
755 Hypr = gp_Hypr(gp_Ax2( P, Z, X), 0., R2 * Yc.Magnitude());
757 new Geom_Hyperbola(Hypr) ;
758 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
759 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
760 myResult = new GeomAdaptor_HCurve(aGACurve);
761 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
763 else if ( Yc.Magnitude() < Precision::Confusion()) {
764 myType = GeomAbs_Hyperbola;
766 gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
768 new Geom_Hyperbola(Hypr) ;
769 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
770 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
771 myResult = new GeomAdaptor_HCurve(aGACurve);
772 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
774 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
775 myType = GeomAbs_Hyperbola;
776 Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
777 R1 * Xc.Magnitude(), R2 * Yc.Magnitude() );
779 new Geom_Hyperbola(Hypr) ;
780 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
781 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
782 myResult = new GeomAdaptor_HCurve(aGACurve);
783 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
786 myIsApprox = Standard_True;
787 myType = GeomAbs_BSplineCurve;
788 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
789 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
790 GeomAdaptor_Curve aGACurve(ApproxCurve);
791 myResult = new GeomAdaptor_HCurve(aGACurve);
792 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
796 case GeomAbs_BezierCurve:
798 Handle(Geom_BezierCurve) BezierCurvePtr =
800 Standard_Integer NbPoles =
801 BezierCurvePtr->NbPoles() ;
803 Handle(Geom_BezierCurve) ProjCu =
804 Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
806 myIsApprox = Standard_False;
808 for ( Standard_Integer i = 1; i <= NbPoles; i++) {
810 (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
813 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
814 GeomAdaptor_Curve aGACurve(ProjCu);
815 myResult = new GeomAdaptor_HCurve(aGACurve);
816 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
819 case GeomAbs_BSplineCurve:
821 Handle(Geom_BSplineCurve) BSplineCurvePtr =
824 // make a copy of the curve and projects its poles
826 Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
827 Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
829 myIsApprox = Standard_False;
831 for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
832 ProjectedBSplinePtr->SetPole
833 (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
836 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
837 GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
838 myResult = new GeomAdaptor_HCurve(aGACurve);
839 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
844 myIsApprox = Standard_True;
845 myType = GeomAbs_BSplineCurve;
846 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
847 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
848 GeomAdaptor_Curve aGACurve(ApproxCurve);
849 myResult = new GeomAdaptor_HCurve(aGACurve);
850 // Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
856 //=======================================================================
857 //function : GetPlane
859 //=======================================================================
861 const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const
866 //=======================================================================
867 //function : GetDirection
869 //=======================================================================
871 const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const
876 //=======================================================================
877 //function : GetCurve
879 //=======================================================================
881 const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
887 //=======================================================================
888 //function : FirstParameter
890 //=======================================================================
892 Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const
894 if ( myKeepParam || myIsApprox)
895 return myCurve->FirstParameter();
901 //=======================================================================
902 //function : LastParameter
904 //=======================================================================
906 Standard_Real ProjLib_ProjectOnPlane::LastParameter() const
908 if ( myKeepParam || myIsApprox)
909 return myCurve->LastParameter();
915 //=======================================================================
916 //function : Continuity
918 //=======================================================================
920 GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
922 return myCurve->Continuity() ;
926 //=======================================================================
927 //function : NbIntervals
929 //=======================================================================
931 Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S)
933 return myCurve->NbIntervals(S) ;
937 //=======================================================================
938 //function : Intervals
940 //=======================================================================
942 void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T,
943 const GeomAbs_Shape S)
945 myCurve->Intervals(T,S) ;
948 //=======================================================================
951 //=======================================================================
953 Handle(Adaptor3d_HCurve)
954 ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
955 const Standard_Real Last,
956 const Standard_Real Tolerance) const
958 if (myType != GeomAbs_OtherCurve){
959 return myResult->Trim(First,Last,Tolerance) ;
962 Standard_NotImplemented::Raise("");
966 Handle(Adaptor3d_HCurve) dummy;
971 //=======================================================================
972 //function : IsClosed
974 //=======================================================================
976 Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
978 return myCurve->IsClosed() ;
982 //=======================================================================
983 //function : IsPeriodic
985 //=======================================================================
987 Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
990 return Standard_False;
992 return myCurve->IsPeriodic();
996 //=======================================================================
999 //=======================================================================
1001 Standard_Real ProjLib_ProjectOnPlane::Period() const
1003 if ( !IsPeriodic()) {
1004 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
1008 return Standard_False;
1010 return myCurve->Period();
1014 //=======================================================================
1017 //=======================================================================
1019 gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const
1021 if (myType != GeomAbs_OtherCurve) {
1022 return myResult->Value(U);
1025 return OnPlane_Value(U,
1034 //=======================================================================
1037 //=======================================================================
1039 void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1041 if (myType != GeomAbs_OtherCurve) {
1045 P = OnPlane_Value(U,
1053 //=======================================================================
1056 //=======================================================================
1058 void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1062 if (myType != GeomAbs_OtherCurve) {
1063 myResult->D1(U,P,V) ;
1076 //=======================================================================
1079 //=======================================================================
1081 void ProjLib_ProjectOnPlane::D2(const Standard_Real U,
1086 if (myType != GeomAbs_OtherCurve) {
1087 myResult->D2(U,P,V1,V2) ;
1101 //=======================================================================
1104 //=======================================================================
1106 void ProjLib_ProjectOnPlane::D3(const Standard_Real U,
1112 if (myType != GeomAbs_OtherCurve) {
1113 myResult->D3(U,P,V1,V2,V3) ;
1128 //=======================================================================
1131 //=======================================================================
1133 gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U,
1134 const Standard_Integer DerivativeRequest)
1137 if (myType != GeomAbs_OtherCurve) {
1138 return myResult->DN(U,DerivativeRequest) ;
1141 return OnPlane_DN(U,
1150 //=======================================================================
1151 //function : Resolution
1153 //=======================================================================
1155 Standard_Real ProjLib_ProjectOnPlane::Resolution
1156 (const Standard_Real Tolerance) const
1158 if (myType != GeomAbs_OtherCurve) {
1159 return myResult->Resolution(Tolerance) ;
1167 //=======================================================================
1168 //function : GetType
1170 //=======================================================================
1172 GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1178 //=======================================================================
1181 //=======================================================================
1183 gp_Lin ProjLib_ProjectOnPlane::Line() const
1185 if (myType != GeomAbs_Line)
1186 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");
1188 return myResult->Line();
1192 //=======================================================================
1195 //=======================================================================
1197 gp_Circ ProjLib_ProjectOnPlane::Circle() const
1199 if (myType != GeomAbs_Circle)
1200 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");
1202 return myResult->Circle();
1206 //=======================================================================
1207 //function : Ellipse
1209 //=======================================================================
1211 gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1213 if (myType != GeomAbs_Ellipse)
1214 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");
1216 return myResult->Ellipse();
1220 //=======================================================================
1221 //function : Hyperbola
1223 //=======================================================================
1225 gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1227 if (myType != GeomAbs_Hyperbola)
1228 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");
1230 return myResult->Hyperbola() ;
1234 //=======================================================================
1235 //function : Parabola
1237 //=======================================================================
1239 gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1241 if (myType != GeomAbs_Parabola)
1242 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
1244 return myResult->Parabola() ;
1247 //=======================================================================
1250 //=======================================================================
1252 Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1254 if ((GetType() != GeomAbs_BSplineCurve) &&
1255 (GetType() != GeomAbs_BezierCurve))
1256 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");
1259 return myResult->Degree();
1261 return myCurve->Degree();
1264 //=======================================================================
1265 //function : IsRational
1267 //=======================================================================
1269 Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const
1271 if ((GetType() != GeomAbs_BSplineCurve) &&
1272 (GetType() != GeomAbs_BezierCurve))
1273 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
1276 return myResult->IsRational();
1278 return myCurve->IsRational();
1281 //=======================================================================
1282 //function : NbPoles
1284 //=======================================================================
1286 Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1288 if ((GetType() != GeomAbs_BSplineCurve) &&
1289 (GetType() != GeomAbs_BezierCurve))
1290 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
1293 return myResult->NbPoles();
1295 return myCurve->NbPoles();
1298 //=======================================================================
1299 //function : NbKnots
1301 //=======================================================================
1303 Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const
1305 if ( GetType() != GeomAbs_BSplineCurve)
1306 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
1309 return myResult->NbKnots();
1311 return myCurve->NbKnots();
1315 //=======================================================================
1318 //=======================================================================
1320 Handle(Geom_BezierCurve) ProjLib_ProjectOnPlane::Bezier() const
1322 if (myType != GeomAbs_BezierCurve)
1323 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");
1325 return myResult->Bezier() ;
1328 //=======================================================================
1331 //=======================================================================
1333 Handle(Geom_BSplineCurve) ProjLib_ProjectOnPlane::BSpline() const
1335 if (myType != GeomAbs_BSplineCurve)
1336 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");
1338 return myResult->BSpline() ;