0024710: Avoid including Handle_Class.hxx headers except where necessary
[occt.git] / src / ProjLib / ProjLib_ProjectOnPlane.cxx
CommitLineData
b311480e 1// Created on: 1994-09-05
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 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>
28#include <PLib.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>
35#include <ElCLib.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>
47
48
49
50//=======================================================================
51//function : OnPlane_Value
52//purpose : Evaluate current point of the projected curve
53//=======================================================================
54
55static gp_Pnt OnPlane_Value(const Standard_Real U,
56 const Handle(Adaptor3d_HCurve)& aCurvePtr,
57 const gp_Ax3& Pl,
58 const gp_Dir& D)
59{
60 // PO . Z / Z = Pl.Direction()
61 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
62 // D . Z
63
64 gp_Pnt Point = aCurvePtr->Value(U);
65
66 gp_Vec PO(Point,Pl.Location());
67
68 Standard_Real Alpha = PO * gp_Vec(Pl.Direction());
69 Alpha /= D * Pl.Direction();
70 Point.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
71
72 return Point;
73}
74
75//=======================================================================
76//function : OnPlane_DN
77//purpose : Evaluate current point of the projected curve
78//=======================================================================
79
80static gp_Vec OnPlane_DN(const Standard_Real U,
81 const Standard_Integer DerivativeRequest,
82 const Handle(Adaptor3d_HCurve)& aCurvePtr,
83 const gp_Ax3& Pl,
84 const gp_Dir& D)
85{
86 // PO . Z / Z = Pl.Direction()
87 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
88 // D . Z
89
90 gp_Vec Vector = aCurvePtr->DN(U,DerivativeRequest);
91
92 gp_Dir Z = Pl.Direction();
93
94 Standard_Real
95 Alpha = Vector * gp_Vec(Z);
96 Alpha /= D * Z;
97
98 Vector.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
99 return Vector ;
100}
101
102//=======================================================================
103//function : OnPlane_D1
104//purpose :
105//=======================================================================
106
107static Standard_Boolean OnPlane_D1(const Standard_Real U,
108 gp_Pnt& P,
109 gp_Vec& V,
110 const Handle(Adaptor3d_HCurve)& aCurvePtr,
111 const gp_Ax3& Pl,
112 const gp_Dir& D)
113{
114 Standard_Real Alpha;
115 gp_Pnt Point;
116 gp_Vec Vector;
117
118 gp_Dir Z = Pl.Direction();
119
120 aCurvePtr->D1(U, Point, Vector);
121
122 // evaluate the point as in `OnPlane_Value`
123 gp_Vec PO(Point,Pl.Location());
124 Alpha = PO * gp_Vec(Z);
125 Alpha /= D * Z;
126 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
127
128
129 // evaluate the derivative.
130 //
131 // d(Proj) d(P) 1 d(P)
132 // ------ = --- - -------- * ( --- . Z ) * D
133 // dU dU ( D . Z) dU
134 //
135
136 Alpha = Vector * gp_Vec(Z);
137 Alpha /= D * Z;
138
139 V.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
140
141 return Standard_True;
142}
143//=======================================================================
144//function : OnPlane_D2
145//purpose :
146//=======================================================================
147
148static Standard_Boolean OnPlane_D2(const Standard_Real U,
149 gp_Pnt& P,
150 gp_Vec& V1,
151 gp_Vec& V2,
152 const Handle(Adaptor3d_HCurve) & aCurvePtr,
153 const gp_Ax3& Pl,
154 const gp_Dir& D)
155{
156 Standard_Real Alpha;
157 gp_Pnt Point;
158 gp_Vec Vector1,
159 Vector2;
160
161 gp_Dir Z = Pl.Direction();
162
163 aCurvePtr->D2(U, Point, Vector1, Vector2);
164
165 // evaluate the point as in `OnPlane_Value`
166 gp_Vec PO(Point,Pl.Location());
167 Alpha = PO * gp_Vec(Z);
168 Alpha /= D * Z;
169 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
170
171 // evaluate the derivative.
172 //
173 // d(Proj) d(P) 1 d(P)
174 // ------ = --- - -------- * ( --- . Z ) * D
175 // dU dU ( D . Z) dU
176 //
177
178 Alpha = Vector1 * gp_Vec(Z);
179 Alpha /= D * Z;
180
181 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
182
183 Alpha = Vector2 * gp_Vec(Z);
184 Alpha /= D * Z;
185
186 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
187 return Standard_True;
188}
189
190//=======================================================================
191//function : OnPlane_D3
192//purpose :
193//=======================================================================
194
195static Standard_Boolean OnPlane_D3(const Standard_Real U,
196 gp_Pnt& P,
197 gp_Vec& V1,
198 gp_Vec& V2,
199 gp_Vec& V3,
200 const Handle(Adaptor3d_HCurve)& aCurvePtr,
201 const gp_Ax3& Pl,
202 const gp_Dir& D)
203{
204 Standard_Real Alpha;
205 gp_Pnt Point;
206 gp_Vec Vector1,
207 Vector2,
208 Vector3;
209
210 gp_Dir Z = Pl.Direction();
211
212 aCurvePtr->D3(U, Point, Vector1, Vector2, Vector3);
213
214 // evaluate the point as in `OnPlane_Value`
215 gp_Vec PO(Point,Pl.Location());
216 Alpha = PO * gp_Vec(Z);
217 Alpha /= D * Z;
218 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
219
220 // evaluate the derivative.
221 //
222 // d(Proj) d(P) 1 d(P)
223 // ------ = --- - -------- * ( --- . Z ) * D
224 // dU dU ( D . Z) dU
225 //
226
227 Alpha = Vector1 * gp_Vec(Z);
228 Alpha /= D * Z;
229
230 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
231
232 Alpha = Vector2 * gp_Vec(Z);
233 Alpha /= D * Z;
234
235 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
236 Alpha = Vector3 * gp_Vec(Z);
237 Alpha /= D * Z;
238
239 V3.SetXYZ( Vector3.XYZ() - Alpha * D.XYZ());
240 return Standard_True;
241}
242
243//=======================================================================
244// class : ProjLib_OnPlane
245//purpose : Use to approximate the projection on a plane
246//=======================================================================
247
248class ProjLib_OnPlane : public AppCont_Function
249
250{
251 Handle(Adaptor3d_HCurve) myCurve;
252 gp_Ax3 myPlane;
253 gp_Dir myDirection;
254
255 public :
256
257 ProjLib_OnPlane(const Handle(Adaptor3d_HCurve)& C,
258 const gp_Ax3& Pl,
259 const gp_Dir& D)
260 : myCurve(C), myPlane(Pl), myDirection(D)
261 {}
262
263 Standard_Real FirstParameter() const
264 {return myCurve->FirstParameter();}
265
266 Standard_Real LastParameter() const
267 {return myCurve->LastParameter();}
268
269 gp_Pnt Value( const Standard_Real t) const
270 {return OnPlane_Value(t,myCurve,myPlane,myDirection);}
271
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);}
274};
275
276
277
278
279//=====================================================================//
280// //
281// D E S C R I P T I O N O F T H E C L A S S : //
282// //
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 //
284// //
285//=====================================================================//
286
287
288
289//=======================================================================
290//function : PerformApprox
291//purpose :
292//=======================================================================
293
294static void PerformApprox (const Handle(Adaptor3d_HCurve)& C,
295 const gp_Ax3& Pl,
296 const gp_Dir& D,
297 Handle(Geom_BSplineCurve) &BSplineCurvePtr)
298
299{
300 ProjLib_OnPlane F(C,Pl,D);
301
302 Standard_Integer Deg1, Deg2;
303 Deg1 = 8; Deg2 = 8;
304
305 Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
306 Precision::PApproximation(),Standard_True);
307 Standard_Integer i;
308 Standard_Integer NbCurves = Fit.NbMultiCurves();
309 Standard_Integer MaxDeg = 0;
310
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);
317 }
318 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
319
320 TColgp_Array1OfPnt Poles( 1, NbPoles);
321
322 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
323
324 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
325
326 Standard_Integer Compt = 1;
327 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
328 Fit.Parameters(i, Knots(i), Knots(i+1));
329
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);
333
334 //Augmentation eventuelle du degre
335 Standard_Integer Inc = MaxDeg - MC.Degree();
336 if ( Inc > 0) {
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));
342 Compt++;
343 }
344 }
345 else {
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));
349 Compt++;
350 }
351 }
352
353 Compt--;
354 }
355
356 //mise a jour des fields de ProjLib_Approx
357
358 Standard_Integer
359 NbKnots = NbCurves + 1;
360
361 TColStd_Array1OfInteger Mults(1, NbKnots);
362 Mults.SetValue( 1, MaxDeg + 1);
363 for ( i = 2; i <= NbCurves; i++) {
364 Mults.SetValue( i, MaxDeg);
365 }
366 Mults.SetValue( NbKnots, MaxDeg + 1);
367 BSplineCurvePtr =
368 new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
369}
370
371
372//=======================================================================
373//function : ProjectOnPlane
374//purpose :
375//=======================================================================
376
377ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
c24d4017 378myKeepParam(Standard_False),
379myFirstPar(0.),
380myLastPar(0.),
381myTolerance(0.),
7fd59977 382myType (GeomAbs_OtherCurve),
383myIsApprox (Standard_False)
384{
385}
386
387//=======================================================================
388//function : ProjLib_ProjectOnPlane
389//purpose :
390//=======================================================================
391
392ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) :
393myPlane (Pl) ,
394myDirection (Pl.Direction()) ,
c24d4017 395myKeepParam(Standard_False),
396myFirstPar(0.),
397myLastPar(0.),
398myTolerance(0.),
7fd59977 399myType (GeomAbs_OtherCurve),
400myIsApprox (Standard_False)
401{
402}
403
404//=======================================================================
405//function : ProjLib_ProjectOnPlane
406//purpose :
407//=======================================================================
408
409ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
410 const gp_Dir& D ) :
411myPlane (Pl) ,
412myDirection (D) ,
c24d4017 413myKeepParam(Standard_False),
414myFirstPar(0.),
415myLastPar(0.),
416myTolerance(0.),
7fd59977 417myType (GeomAbs_OtherCurve),
418myIsApprox (Standard_False)
419{
420// if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
421// Standard_ConstructionError::Raise
422// ("ProjLib_ProjectOnPlane: The Direction and the Plane are parallel");
423// }
424}
425
426//=======================================================================
427//function : Project
428//purpose : Returns the projection of a point <Point> on a plane
429// <ThePlane> along a direction <TheDir>.
430//=======================================================================
431
432static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
433 const gp_Dir& TheDir,
434 const gp_Pnt& Point)
435{
436 gp_Vec PO(Point,ThePlane.Location());
437
438 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
439 Alpha /= TheDir * ThePlane.Direction();
440
441 gp_Pnt P;
442 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
443
444 return P;
445}
446
447
448//=======================================================================
449//function : Project
450//purpose : Returns the projection of a Vector <Vec> on a plane
451// <ThePlane> along a direction <TheDir>.
452//=======================================================================
453
454static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
455 const gp_Dir& TheDir,
456 const gp_Vec& Vec)
457{
458 gp_Vec D = Vec;
459 gp_Vec Z = ThePlane.Direction();
460
461 D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
462
463 return D;
464}
465
466//=======================================================================
467//function : Load
468//purpose :
469//=======================================================================
470
471void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
472 const Standard_Real Tolerance,
473 const Standard_Boolean KeepParametrization)
474
475{
476 myCurve = C;
477 myType = GeomAbs_OtherCurve;
478 myIsApprox = Standard_False;
479 myTolerance = Tolerance ;
480
481 Handle(Geom_BSplineCurve) ApproxCurve;
482 Handle(GeomAdaptor_HCurve) aGAHCurve;
483
484 Handle(Geom_Line) GeomLinePtr;
485 Handle(Geom_Circle) GeomCirclePtr ;
486 Handle(Geom_Ellipse) GeomEllipsePtr ;
487 Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
488
489 gp_Lin aLine;
490 gp_Elips Elips;
491// gp_Hypr Hypr ;
492
493 Standard_Integer num_knots ;
494 GeomAbs_CurveType Type = C->GetType();
495
496 gp_Ax2 Axis;
7fd59977 497 Standard_Real R1 =0., R2 =0.;
7fd59977 498
499 if ( Type != GeomAbs_Line) // on garde le parametrage
500 myKeepParam = Standard_True;
501 else // on prend le choix utilisateur.
502 myKeepParam = KeepParametrization;
503
504 switch ( Type) {
505 case GeomAbs_Line:
506 {
507 // P(u) = O + u * Xc
508 // ==> Q(u) = f(P(u))
509 // = f(O) + u * f(Xc)
510
511 gp_Lin L = myCurve->Line();
512 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
513
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);
524
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
529 }
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);
537
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
544 }
545 else {
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;
550
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);
561 if (!myKeepParam) {
562// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
563 GeomAdaptor_Curve aGACurve(GeomLinePtr,
564 myFirstPar,
565 myLastPar) ;
566 myResult = new GeomAdaptor_HCurve(aGACurve);
567// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
568 }
569 else {
570 myType = GeomAbs_BSplineCurve;
571 //
572 // make a linear BSpline of degree 1 between the end points of
573 // the projected line
574 //
575 Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
576 new Geom_TrimmedCurve(GeomLinePtr,
577 myFirstPar,
578 myLastPar) ;
579
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) ;
585
586 BSplCLib::Reparametrize(myCurve->FirstParameter(),
587 myCurve->LastParameter(),
588 BsplineKnots) ;
589
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
595 }
596 }
597 break;
598 }
599 case GeomAbs_Circle:
600 {
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)
606
607 gp_Circ Circ = myCurve->Circle();
608 Axis = Circ.Position();
609 R1 = R2 = Circ.Radius();
610
611 }
612 case GeomAbs_Ellipse:
613 {
614 if ( Type == GeomAbs_Ellipse) {
615 gp_Elips E = myCurve->Ellipse();
616 Axis = E.Position();
617 R1 = E.MajorRadius();
618 R2 = E.MinorRadius();
619 }
620
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);
626 gp_Dir Dx,Dy;
627
628 Standard_Real Tol2 = myTolerance*myTolerance;
629 if (VDx.SquareMagnitude() < Tol2 ||
630 VDy.SquareMagnitude() < Tol2 ) {
631 myIsApprox = Standard_True;
632 }
633
634 if (!myIsApprox &&
635 gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
636 Dx = gp_Dir(VDx);
637 Dy = gp_Dir(VDy);
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);
645
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
654 }
655 else if ( Major > Minor) {
656 myType = GeomAbs_Ellipse;
657 Elips = gp_Elips( Axe, Major, Minor);
658
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
664 }
665 else {
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
673 }
674 }
675 else {
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
683 }
684 }
685 break;
686 case GeomAbs_Parabola:
687 {
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)
691
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()));
696
697 // fix for case when no one action is done. 28.03.2002
698 Standard_Boolean alocalIsDone = Standard_False;
699
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));
705
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;
712 }
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;
724 }
725 }
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
734 }
735 }
736 break;
737 case GeomAbs_Hyperbola:
738 {
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)
742
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();
751
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());
756 GeomHyperbolaPtr =
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
762 }
763 else if ( Yc.Magnitude() < Precision::Confusion()) {
764 myType = GeomAbs_Hyperbola;
765 Hypr =
766 gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
767 GeomHyperbolaPtr =
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
773 }
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() );
778 GeomHyperbolaPtr =
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
784 }
785 else {
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
793 }
794 }
795 break;
796 case GeomAbs_BezierCurve:
797 {
798 Handle(Geom_BezierCurve) BezierCurvePtr =
799 myCurve->Bezier() ;
800 Standard_Integer NbPoles =
801 BezierCurvePtr->NbPoles() ;
802
803 Handle(Geom_BezierCurve) ProjCu =
804 Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
805
806 myIsApprox = Standard_False;
807 myType = Type;
808 for ( Standard_Integer i = 1; i <= NbPoles; i++) {
809 ProjCu->SetPole
810 (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
811 }
812
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
817 }
818 break ;
819 case GeomAbs_BSplineCurve:
820 {
821 Handle(Geom_BSplineCurve) BSplineCurvePtr =
822 myCurve->BSpline() ;
823 //
824 // make a copy of the curve and projects its poles
825 //
826 Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
827 Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
828
829 myIsApprox = Standard_False;
830 myType = Type;
831 for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
832 ProjectedBSplinePtr->SetPole
833 (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
834 }
835
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
840 }
841 break;
842 default:
843 {
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
851 }
852 break;
853 }
854}
855
856//=======================================================================
857//function : GetPlane
858//purpose :
859//=======================================================================
860
861const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const
862{
863 return myPlane;
864}
865
866//=======================================================================
867//function : GetDirection
868//purpose :
869//=======================================================================
870
871const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const
872{
873 return myDirection;
874}
875
876//=======================================================================
877//function : GetCurve
878//purpose :
879//=======================================================================
880
881const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
882{
883 return myCurve;
884}
885
886
887//=======================================================================
888//function : FirstParameter
889//purpose :
890//=======================================================================
891
892Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const
893{
894 if ( myKeepParam || myIsApprox)
895 return myCurve->FirstParameter();
896 else
897 return myFirstPar;
898}
899
900
901//=======================================================================
902//function : LastParameter
903//purpose :
904//=======================================================================
905
906Standard_Real ProjLib_ProjectOnPlane::LastParameter() const
907{
908 if ( myKeepParam || myIsApprox)
909 return myCurve->LastParameter();
910 else
911 return myLastPar;
912}
913
914
915//=======================================================================
916//function : Continuity
917//purpose :
918//=======================================================================
919
920GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
921{
922 return myCurve->Continuity() ;
923}
924
925
926//=======================================================================
927//function : NbIntervals
928//purpose :
929//=======================================================================
930
931Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S)
932{
933 return myCurve->NbIntervals(S) ;
934}
935
936
937//=======================================================================
938//function : Intervals
939//purpose :
940//=======================================================================
941
942void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T,
943 const GeomAbs_Shape S)
944{
945 myCurve->Intervals(T,S) ;
946}
947
948//=======================================================================
949//function : Trim
950//purpose :
951//=======================================================================
952
953Handle(Adaptor3d_HCurve)
954ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
955 const Standard_Real Last,
956 const Standard_Real Tolerance) const
957{
958 if (myType != GeomAbs_OtherCurve){
959 return myResult->Trim(First,Last,Tolerance) ;
960 }
961 else {
962 Standard_NotImplemented::Raise("");
963 }
964
965 // portage WNT
966 Handle(Adaptor3d_HCurve) dummy;
967 return dummy;
968}
969
970
971//=======================================================================
972//function : IsClosed
973//purpose :
974//=======================================================================
975
976Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
977{
978 return myCurve->IsClosed() ;
979}
980
981
982//=======================================================================
983//function : IsPeriodic
984//purpose :
985//=======================================================================
986
987Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
988{
989 if ( myIsApprox)
990 return Standard_False;
991 else
992 return myCurve->IsPeriodic();
993}
994
995
996//=======================================================================
997//function : Period
998//purpose :
999//=======================================================================
1000
1001Standard_Real ProjLib_ProjectOnPlane::Period() const
1002{
1003 if ( !IsPeriodic()) {
1004 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
1005 }
1006
1007 if ( myIsApprox)
1008 return Standard_False;
1009 else
1010 return myCurve->Period();
1011}
1012
1013
1014//=======================================================================
1015//function : Value
1016//purpose :
1017//=======================================================================
1018
1019gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const
1020{
1021 if (myType != GeomAbs_OtherCurve) {
1022 return myResult->Value(U);
1023 }
1024 else {
1025 return OnPlane_Value(U,
1026 myCurve,
1027 myPlane,
1028 myDirection);
1029
1030 }
1031}
1032
1033
1034//=======================================================================
1035//function : D0
1036//purpose :
1037//=======================================================================
1038
1039void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1040{
1041 if (myType != GeomAbs_OtherCurve) {
1042 myResult->D0(U,P) ;
1043 }
1044 else {
1045 P = OnPlane_Value(U,
1046 myCurve,
1047 myPlane,
1048 myDirection);
1049 }
1050}
1051
1052
1053//=======================================================================
1054//function : D1
1055//purpose :
1056//=======================================================================
1057
1058void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1059 gp_Pnt& P ,
1060 gp_Vec& V ) const
1061{
1062 if (myType != GeomAbs_OtherCurve) {
1063 myResult->D1(U,P,V) ;
1064 }
1065 else {
1066 OnPlane_D1(U,
1067 P,
1068 V,
1069 myCurve,
1070 myPlane,
1071 myDirection);
1072 }
1073}
1074
1075
1076//=======================================================================
1077//function : D2
1078//purpose :
1079//=======================================================================
1080
1081void ProjLib_ProjectOnPlane::D2(const Standard_Real U,
1082 gp_Pnt& P,
1083 gp_Vec& V1,
1084 gp_Vec& V2) const
1085{
1086 if (myType != GeomAbs_OtherCurve) {
1087 myResult->D2(U,P,V1,V2) ;
1088 }
1089 else {
1090 OnPlane_D2(U,
1091 P,
1092 V1,
1093 V2,
1094 myCurve,
1095 myPlane,
1096 myDirection);
1097 }
1098}
1099
1100
1101//=======================================================================
1102//function : D3
1103//purpose :
1104//=======================================================================
1105
1106void ProjLib_ProjectOnPlane::D3(const Standard_Real U,
1107 gp_Pnt& P,
1108 gp_Vec& V1,
1109 gp_Vec& V2,
1110 gp_Vec& V3) const
1111{
1112 if (myType != GeomAbs_OtherCurve) {
1113 myResult->D3(U,P,V1,V2,V3) ;
1114 }
1115 else {
1116 OnPlane_D3(U,
1117 P,
1118 V1,
1119 V2,
1120 V3,
1121 myCurve,
1122 myPlane,
1123 myDirection);
1124 }
1125}
1126
1127
1128//=======================================================================
1129//function : DN
1130//purpose :
1131//=======================================================================
1132
1133gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U,
1134 const Standard_Integer DerivativeRequest)
1135 const
1136{
1137 if (myType != GeomAbs_OtherCurve) {
1138 return myResult->DN(U,DerivativeRequest) ;
1139 }
1140 else {
1141 return OnPlane_DN(U,
1142 DerivativeRequest,
1143 myCurve,
1144 myPlane,
1145 myDirection);
1146 }
1147}
1148
1149
1150//=======================================================================
1151//function : Resolution
1152//purpose :
1153//=======================================================================
1154
1155Standard_Real ProjLib_ProjectOnPlane::Resolution
1156(const Standard_Real Tolerance) const
1157{
1158 if (myType != GeomAbs_OtherCurve) {
1159 return myResult->Resolution(Tolerance) ;
1160 }
1161 else {
1162 return 0;
1163 }
1164}
1165
1166
1167//=======================================================================
1168//function : GetType
1169//purpose :
1170//=======================================================================
1171
1172GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1173{
1174 return myType;
1175}
1176
1177
1178//=======================================================================
1179//function : Line
1180//purpose :
1181//=======================================================================
1182
1183gp_Lin ProjLib_ProjectOnPlane::Line() const
1184{
1185 if (myType != GeomAbs_Line)
1186 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");
1187
1188 return myResult->Line();
1189}
1190
1191
1192//=======================================================================
1193//function : Circle
1194//purpose :
1195//=======================================================================
1196
1197gp_Circ ProjLib_ProjectOnPlane::Circle() const
1198{
1199 if (myType != GeomAbs_Circle)
1200 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");
1201
1202 return myResult->Circle();
1203}
1204
1205
1206//=======================================================================
1207//function : Ellipse
1208//purpose :
1209//=======================================================================
1210
1211gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1212{
1213 if (myType != GeomAbs_Ellipse)
1214 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");
1215
1216 return myResult->Ellipse();
1217}
1218
1219
1220//=======================================================================
1221//function : Hyperbola
1222//purpose :
1223//=======================================================================
1224
1225gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1226{
1227 if (myType != GeomAbs_Hyperbola)
1228 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");
1229
1230 return myResult->Hyperbola() ;
1231}
1232
1233
1234//=======================================================================
1235//function : Parabola
1236//purpose :
1237//=======================================================================
1238
1239gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1240{
1241 if (myType != GeomAbs_Parabola)
1242 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
1243
1244 return myResult->Parabola() ;
1245}
1246
1247//=======================================================================
1248//function : Degree
1249//purpose :
1250//=======================================================================
1251
1252Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1253{
1254 if ((GetType() != GeomAbs_BSplineCurve) &&
1255 (GetType() != GeomAbs_BezierCurve))
1256 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");
1257
1258 if ( myIsApprox)
1259 return myResult->Degree();
1260 else
1261 return myCurve->Degree();
1262}
1263
1264//=======================================================================
1265//function : IsRational
1266//purpose :
1267//=======================================================================
1268
1269Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const
1270{
1271 if ((GetType() != GeomAbs_BSplineCurve) &&
1272 (GetType() != GeomAbs_BezierCurve))
1273 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
1274
1275 if ( myIsApprox)
1276 return myResult->IsRational();
1277 else
1278 return myCurve->IsRational();
1279}
1280
1281//=======================================================================
1282//function : NbPoles
1283//purpose :
1284//=======================================================================
1285
1286Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1287{
1288 if ((GetType() != GeomAbs_BSplineCurve) &&
1289 (GetType() != GeomAbs_BezierCurve))
1290 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
1291
1292 if ( myIsApprox)
1293 return myResult->NbPoles();
1294 else
1295 return myCurve->NbPoles();
1296}
1297
1298//=======================================================================
1299//function : NbKnots
1300//purpose :
1301//=======================================================================
1302
1303Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const
1304{
1305 if ( GetType() != GeomAbs_BSplineCurve)
1306 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
1307
1308 if ( myIsApprox)
1309 return myResult->NbKnots();
1310 else
1311 return myCurve->NbKnots();
1312}
1313
1314
1315//=======================================================================
1316//function : Bezier
1317//purpose :
1318//=======================================================================
1319
1320Handle(Geom_BezierCurve) ProjLib_ProjectOnPlane::Bezier() const
1321{
1322 if (myType != GeomAbs_BezierCurve)
1323 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");
1324
1325 return myResult->Bezier() ;
1326}
1327
1328//=======================================================================
1329//function : Bezier
1330//purpose :
1331//=======================================================================
1332
1333Handle(Geom_BSplineCurve) ProjLib_ProjectOnPlane::BSpline() const
1334{
1335 if (myType != GeomAbs_BSplineCurve)
1336 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");
1337
1338 return myResult->BSpline() ;
1339}
1340