0024275: Cppcheck warnings on uninitialized class members
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21// 09-Aug-95 : xab : changed the ProjLib_ProjectOnPlane in the case
22// of the line and the parameteriation is kept
23#include <ProjLib_ProjectOnPlane.hxx>
24#include <AppCont_Function.hxx>
25#include <Approx_FitAndDivide.hxx>
26#include <AppParCurves_MultiCurve.hxx>
27#include <Standard_ConstructionError.hxx>
28#include <Standard_NoSuchObject.hxx>
29#include <Standard_NotImplemented.hxx>
30#include <Precision.hxx>
31#include <BSplCLib.hxx>
32#include <PLib.hxx>
33#include <Geom_BSplineCurve.hxx>
34#include <Geom_BezierCurve.hxx>
35#include <TColgp_HArray1OfPnt.hxx>
36#include <TColStd_HArray1OfReal.hxx>
37#include <TColStd_HArray1OfInteger.hxx>
38#include <Precision.hxx>
39#include <ElCLib.hxx>
40#include <Adaptor3d_Curve.hxx>
41#include <Adaptor3d_HCurve.hxx>
42#include <GeomAdaptor_HCurve.hxx>
43#include <Geom_Line.hxx>
44#include <GeomConvert.hxx>
45#include <BSplCLib.hxx>
46#include <Geom_TrimmedCurve.hxx>
47#include <Geom_Circle.hxx>
48#include <Geom_Parabola.hxx>
49#include <Geom_Hyperbola.hxx>
50#include <Geom_Ellipse.hxx>
51
52
53
54//=======================================================================
55//function : OnPlane_Value
56//purpose : Evaluate current point of the projected curve
57//=======================================================================
58
59static gp_Pnt OnPlane_Value(const Standard_Real U,
60 const Handle(Adaptor3d_HCurve)& aCurvePtr,
61 const gp_Ax3& Pl,
62 const gp_Dir& D)
63{
64 // PO . Z / Z = Pl.Direction()
65 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
66 // D . Z
67
68 gp_Pnt Point = aCurvePtr->Value(U);
69
70 gp_Vec PO(Point,Pl.Location());
71
72 Standard_Real Alpha = PO * gp_Vec(Pl.Direction());
73 Alpha /= D * Pl.Direction();
74 Point.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
75
76 return Point;
77}
78
79//=======================================================================
80//function : OnPlane_DN
81//purpose : Evaluate current point of the projected curve
82//=======================================================================
83
84static gp_Vec OnPlane_DN(const Standard_Real U,
85 const Standard_Integer DerivativeRequest,
86 const Handle(Adaptor3d_HCurve)& aCurvePtr,
87 const gp_Ax3& Pl,
88 const gp_Dir& D)
89{
90 // PO . Z / Z = Pl.Direction()
91 // Proj(u) = P(u) + ------- * D avec \ O = Pl.Location()
92 // D . Z
93
94 gp_Vec Vector = aCurvePtr->DN(U,DerivativeRequest);
95
96 gp_Dir Z = Pl.Direction();
97
98 Standard_Real
99 Alpha = Vector * gp_Vec(Z);
100 Alpha /= D * Z;
101
102 Vector.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
103 return Vector ;
104}
105
106//=======================================================================
107//function : OnPlane_D1
108//purpose :
109//=======================================================================
110
111static Standard_Boolean OnPlane_D1(const Standard_Real U,
112 gp_Pnt& P,
113 gp_Vec& V,
114 const Handle(Adaptor3d_HCurve)& aCurvePtr,
115 const gp_Ax3& Pl,
116 const gp_Dir& D)
117{
118 Standard_Real Alpha;
119 gp_Pnt Point;
120 gp_Vec Vector;
121
122 gp_Dir Z = Pl.Direction();
123
124 aCurvePtr->D1(U, Point, Vector);
125
126 // evaluate the point as in `OnPlane_Value`
127 gp_Vec PO(Point,Pl.Location());
128 Alpha = PO * gp_Vec(Z);
129 Alpha /= D * Z;
130 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
131
132
133 // evaluate the derivative.
134 //
135 // d(Proj) d(P) 1 d(P)
136 // ------ = --- - -------- * ( --- . Z ) * D
137 // dU dU ( D . Z) dU
138 //
139
140 Alpha = Vector * gp_Vec(Z);
141 Alpha /= D * Z;
142
143 V.SetXYZ( Vector.XYZ() - Alpha * D.XYZ());
144
145 return Standard_True;
146}
147//=======================================================================
148//function : OnPlane_D2
149//purpose :
150//=======================================================================
151
152static Standard_Boolean OnPlane_D2(const Standard_Real U,
153 gp_Pnt& P,
154 gp_Vec& V1,
155 gp_Vec& V2,
156 const Handle(Adaptor3d_HCurve) & aCurvePtr,
157 const gp_Ax3& Pl,
158 const gp_Dir& D)
159{
160 Standard_Real Alpha;
161 gp_Pnt Point;
162 gp_Vec Vector1,
163 Vector2;
164
165 gp_Dir Z = Pl.Direction();
166
167 aCurvePtr->D2(U, Point, Vector1, Vector2);
168
169 // evaluate the point as in `OnPlane_Value`
170 gp_Vec PO(Point,Pl.Location());
171 Alpha = PO * gp_Vec(Z);
172 Alpha /= D * Z;
173 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
174
175 // evaluate the derivative.
176 //
177 // d(Proj) d(P) 1 d(P)
178 // ------ = --- - -------- * ( --- . Z ) * D
179 // dU dU ( D . Z) dU
180 //
181
182 Alpha = Vector1 * gp_Vec(Z);
183 Alpha /= D * Z;
184
185 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
186
187 Alpha = Vector2 * gp_Vec(Z);
188 Alpha /= D * Z;
189
190 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
191 return Standard_True;
192}
193
194//=======================================================================
195//function : OnPlane_D3
196//purpose :
197//=======================================================================
198
199static Standard_Boolean OnPlane_D3(const Standard_Real U,
200 gp_Pnt& P,
201 gp_Vec& V1,
202 gp_Vec& V2,
203 gp_Vec& V3,
204 const Handle(Adaptor3d_HCurve)& aCurvePtr,
205 const gp_Ax3& Pl,
206 const gp_Dir& D)
207{
208 Standard_Real Alpha;
209 gp_Pnt Point;
210 gp_Vec Vector1,
211 Vector2,
212 Vector3;
213
214 gp_Dir Z = Pl.Direction();
215
216 aCurvePtr->D3(U, Point, Vector1, Vector2, Vector3);
217
218 // evaluate the point as in `OnPlane_Value`
219 gp_Vec PO(Point,Pl.Location());
220 Alpha = PO * gp_Vec(Z);
221 Alpha /= D * Z;
222 P.SetXYZ(Point.XYZ() + Alpha * D.XYZ());
223
224 // evaluate the derivative.
225 //
226 // d(Proj) d(P) 1 d(P)
227 // ------ = --- - -------- * ( --- . Z ) * D
228 // dU dU ( D . Z) dU
229 //
230
231 Alpha = Vector1 * gp_Vec(Z);
232 Alpha /= D * Z;
233
234 V1.SetXYZ( Vector1.XYZ() - Alpha * D.XYZ());
235
236 Alpha = Vector2 * gp_Vec(Z);
237 Alpha /= D * Z;
238
239 V2.SetXYZ( Vector2.XYZ() - Alpha * D.XYZ());
240 Alpha = Vector3 * gp_Vec(Z);
241 Alpha /= D * Z;
242
243 V3.SetXYZ( Vector3.XYZ() - Alpha * D.XYZ());
244 return Standard_True;
245}
246
247//=======================================================================
248// class : ProjLib_OnPlane
249//purpose : Use to approximate the projection on a plane
250//=======================================================================
251
252class ProjLib_OnPlane : public AppCont_Function
253
254{
255 Handle(Adaptor3d_HCurve) myCurve;
256 gp_Ax3 myPlane;
257 gp_Dir myDirection;
258
259 public :
260
261 ProjLib_OnPlane(const Handle(Adaptor3d_HCurve)& C,
262 const gp_Ax3& Pl,
263 const gp_Dir& D)
264 : myCurve(C), myPlane(Pl), myDirection(D)
265 {}
266
267 Standard_Real FirstParameter() const
268 {return myCurve->FirstParameter();}
269
270 Standard_Real LastParameter() const
271 {return myCurve->LastParameter();}
272
273 gp_Pnt Value( const Standard_Real t) const
274 {return OnPlane_Value(t,myCurve,myPlane,myDirection);}
275
276 Standard_Boolean D1(const Standard_Real t, gp_Pnt& P, gp_Vec& V) const
277 {return OnPlane_D1(t,P,V,myCurve,myPlane,myDirection);}
278};
279
280
281
282
283//=====================================================================//
284// //
285// D E S C R I P T I O N O F T H E C L A S S : //
286// //
287// 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 //
288// //
289//=====================================================================//
290
291
292
293//=======================================================================
294//function : PerformApprox
295//purpose :
296//=======================================================================
297
298static void PerformApprox (const Handle(Adaptor3d_HCurve)& C,
299 const gp_Ax3& Pl,
300 const gp_Dir& D,
301 Handle(Geom_BSplineCurve) &BSplineCurvePtr)
302
303{
304 ProjLib_OnPlane F(C,Pl,D);
305
306 Standard_Integer Deg1, Deg2;
307 Deg1 = 8; Deg2 = 8;
308
309 Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
310 Precision::PApproximation(),Standard_True);
311 Standard_Integer i;
312 Standard_Integer NbCurves = Fit.NbMultiCurves();
313 Standard_Integer MaxDeg = 0;
314
315 // Pour transformer la MultiCurve en BSpline, il faut que toutes
316 // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
317 Standard_Integer NbPoles = 1;
318 for (i = 1; i <= NbCurves; i++) {
319 Standard_Integer Deg = Fit.Value(i).Degree();
320 MaxDeg = Max ( MaxDeg, Deg);
321 }
322 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
323
324 TColgp_Array1OfPnt Poles( 1, NbPoles);
325
326 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
327
328 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
329
330 Standard_Integer Compt = 1;
331 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
332 Fit.Parameters(i, Knots(i), Knots(i+1));
333
334 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
335 TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
336 MC.Curve(1, LocalPoles);
337
338 //Augmentation eventuelle du degre
339 Standard_Integer Inc = MaxDeg - MC.Degree();
340 if ( Inc > 0) {
341 BSplCLib::IncreaseDegree(Inc, Poles, PLib::NoWeights(),
342 TempPoles, PLib::NoWeights());
343 //mise a jour des poles de la PCurve
344 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
345 Poles.SetValue( Compt, TempPoles( j));
346 Compt++;
347 }
348 }
349 else {
350 //mise a jour des poles de la PCurve
351 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
352 Poles.SetValue( Compt, LocalPoles( j));
353 Compt++;
354 }
355 }
356
357 Compt--;
358 }
359
360 //mise a jour des fields de ProjLib_Approx
361
362 Standard_Integer
363 NbKnots = NbCurves + 1;
364
365 TColStd_Array1OfInteger Mults(1, NbKnots);
366 Mults.SetValue( 1, MaxDeg + 1);
367 for ( i = 2; i <= NbCurves; i++) {
368 Mults.SetValue( i, MaxDeg);
369 }
370 Mults.SetValue( NbKnots, MaxDeg + 1);
371 BSplineCurvePtr =
372 new Geom_BSplineCurve(Poles,Knots,Mults,MaxDeg,Standard_False);
373}
374
375
376//=======================================================================
377//function : ProjectOnPlane
378//purpose :
379//=======================================================================
380
381ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane() :
c24d4017 382myKeepParam(Standard_False),
383myFirstPar(0.),
384myLastPar(0.),
385myTolerance(0.),
7fd59977 386myType (GeomAbs_OtherCurve),
387myIsApprox (Standard_False)
388{
389}
390
391//=======================================================================
392//function : ProjLib_ProjectOnPlane
393//purpose :
394//=======================================================================
395
396ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl) :
397myPlane (Pl) ,
398myDirection (Pl.Direction()) ,
c24d4017 399myKeepParam(Standard_False),
400myFirstPar(0.),
401myLastPar(0.),
402myTolerance(0.),
7fd59977 403myType (GeomAbs_OtherCurve),
404myIsApprox (Standard_False)
405{
406}
407
408//=======================================================================
409//function : ProjLib_ProjectOnPlane
410//purpose :
411//=======================================================================
412
413ProjLib_ProjectOnPlane::ProjLib_ProjectOnPlane(const gp_Ax3& Pl,
414 const gp_Dir& D ) :
415myPlane (Pl) ,
416myDirection (D) ,
c24d4017 417myKeepParam(Standard_False),
418myFirstPar(0.),
419myLastPar(0.),
420myTolerance(0.),
7fd59977 421myType (GeomAbs_OtherCurve),
422myIsApprox (Standard_False)
423{
424// if ( Abs(D * Pl.Direction()) < Precision::Confusion()) {
425// Standard_ConstructionError::Raise
426// ("ProjLib_ProjectOnPlane: The Direction and the Plane are parallel");
427// }
428}
429
430//=======================================================================
431//function : Project
432//purpose : Returns the projection of a point <Point> on a plane
433// <ThePlane> along a direction <TheDir>.
434//=======================================================================
435
436static gp_Pnt ProjectPnt(const gp_Ax3& ThePlane,
437 const gp_Dir& TheDir,
438 const gp_Pnt& Point)
439{
440 gp_Vec PO(Point,ThePlane.Location());
441
442 Standard_Real Alpha = PO * gp_Vec(ThePlane.Direction());
443 Alpha /= TheDir * ThePlane.Direction();
444
445 gp_Pnt P;
446 P.SetXYZ(Point.XYZ() + Alpha * TheDir.XYZ());
447
448 return P;
449}
450
451
452//=======================================================================
453//function : Project
454//purpose : Returns the projection of a Vector <Vec> on a plane
455// <ThePlane> along a direction <TheDir>.
456//=======================================================================
457
458static gp_Vec ProjectVec(const gp_Ax3& ThePlane,
459 const gp_Dir& TheDir,
460 const gp_Vec& Vec)
461{
462 gp_Vec D = Vec;
463 gp_Vec Z = ThePlane.Direction();
464
465 D -= ( (Vec * Z) / (TheDir * Z)) * TheDir;
466
467 return D;
468}
469
470//=======================================================================
471//function : Load
472//purpose :
473//=======================================================================
474
475void ProjLib_ProjectOnPlane::Load(const Handle(Adaptor3d_HCurve)& C,
476 const Standard_Real Tolerance,
477 const Standard_Boolean KeepParametrization)
478
479{
480 myCurve = C;
481 myType = GeomAbs_OtherCurve;
482 myIsApprox = Standard_False;
483 myTolerance = Tolerance ;
484
485 Handle(Geom_BSplineCurve) ApproxCurve;
486 Handle(GeomAdaptor_HCurve) aGAHCurve;
487
488 Handle(Geom_Line) GeomLinePtr;
489 Handle(Geom_Circle) GeomCirclePtr ;
490 Handle(Geom_Ellipse) GeomEllipsePtr ;
491 Handle(Geom_Hyperbola) GeomHyperbolaPtr ;
492
493 gp_Lin aLine;
494 gp_Elips Elips;
495// gp_Hypr Hypr ;
496
497 Standard_Integer num_knots ;
498 GeomAbs_CurveType Type = C->GetType();
499
500 gp_Ax2 Axis;
7fd59977 501 Standard_Real R1 =0., R2 =0.;
7fd59977 502
503 if ( Type != GeomAbs_Line) // on garde le parametrage
504 myKeepParam = Standard_True;
505 else // on prend le choix utilisateur.
506 myKeepParam = KeepParametrization;
507
508 switch ( Type) {
509 case GeomAbs_Line:
510 {
511 // P(u) = O + u * Xc
512 // ==> Q(u) = f(P(u))
513 // = f(O) + u * f(Xc)
514
515 gp_Lin L = myCurve->Line();
516 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(L.Direction()));
517
518 if ( Xc.Magnitude() < Precision::Confusion()) { // line orthog au plan
519 myType = GeomAbs_BSplineCurve;
520 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
521 TColStd_Array1OfInteger Mults(1,2); Mults.Init(2);
522 TColgp_Array1OfPnt Poles(1,2); Poles.Init(P);
523 TColStd_Array1OfReal Knots(1,2);
524 Knots(1) = myCurve->FirstParameter();
525 Knots(2) = myCurve->LastParameter();
526 Handle(Geom_BSplineCurve) BSP =
527 new Geom_BSplineCurve(Poles,Knots,Mults,1);
528
529// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
530 GeomAdaptor_Curve aGACurve(BSP);
531 myResult = new GeomAdaptor_HCurve(aGACurve);
532// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
533 }
534 else if ( Abs( Xc.Magnitude() - 1.) < Precision::Confusion()) {
535 myType = GeomAbs_Line;
536 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
537 myFirstPar = myCurve->FirstParameter();
538 myLastPar = myCurve->LastParameter();
539 aLine = gp_Lin(P,gp_Dir(Xc));
540 GeomLinePtr = new Geom_Line(aLine);
541
542// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
543 GeomAdaptor_Curve aGACurve(GeomLinePtr,
544 myCurve->FirstParameter(),
545 myCurve->LastParameter() );
546 myResult = new GeomAdaptor_HCurve(aGACurve);
547// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
548 }
549 else {
550 myType = GeomAbs_Line;
551 gp_Pnt P = ProjectPnt(myPlane,myDirection,L.Location());
552 aLine = gp_Lin(P,gp_Dir(Xc));
553 Standard_Real Udeb, Ufin;
554
555 // eval the first and last parameters of the projected curve
556 Udeb = myCurve->FirstParameter();
557 Ufin = myCurve->LastParameter();
558 gp_Pnt P1 = ProjectPnt(myPlane,myDirection,
559 myCurve->Value(Udeb));
560 gp_Pnt P2 = ProjectPnt(myPlane,myDirection,
561 myCurve->Value(Ufin));
562 myFirstPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P1));
563 myLastPar = gp_Vec(aLine.Direction()).Dot(gp_Vec(P,P2));
564 GeomLinePtr = new Geom_Line(aLine);
565 if (!myKeepParam) {
566// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
567 GeomAdaptor_Curve aGACurve(GeomLinePtr,
568 myFirstPar,
569 myLastPar) ;
570 myResult = new GeomAdaptor_HCurve(aGACurve);
571// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
572 }
573 else {
574 myType = GeomAbs_BSplineCurve;
575 //
576 // make a linear BSpline of degree 1 between the end points of
577 // the projected line
578 //
579 Handle(Geom_TrimmedCurve) NewTrimCurvePtr =
580 new Geom_TrimmedCurve(GeomLinePtr,
581 myFirstPar,
582 myLastPar) ;
583
584 Handle(Geom_BSplineCurve) NewCurvePtr =
585 GeomConvert::CurveToBSplineCurve(NewTrimCurvePtr) ;
586 num_knots = NewCurvePtr->NbKnots() ;
587 TColStd_Array1OfReal BsplineKnots(1,num_knots) ;
588 NewCurvePtr->Knots(BsplineKnots) ;
589
590 BSplCLib::Reparametrize(myCurve->FirstParameter(),
591 myCurve->LastParameter(),
592 BsplineKnots) ;
593
594 NewCurvePtr->SetKnots(BsplineKnots) ;
595// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
596 GeomAdaptor_Curve aGACurve(NewCurvePtr);
597 myResult = new GeomAdaptor_HCurve(aGACurve);
598// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
599 }
600 }
601 break;
602 }
603 case GeomAbs_Circle:
604 {
605 // Pour le cercle et l ellipse on a les relations suivantes:
606 // ( Rem : pour le cercle R1 = R2 = R)
607 // P(u) = O + R1 * Cos(u) * Xc + R2 * Sin(u) * Yc
608 // ==> Q(u) = f(P(u))
609 // = f(O) + R1 * Cos(u) * f(Xc) + R2 * Sin(u) * f(Yc)
610
611 gp_Circ Circ = myCurve->Circle();
612 Axis = Circ.Position();
613 R1 = R2 = Circ.Radius();
614
615 }
616 case GeomAbs_Ellipse:
617 {
618 if ( Type == GeomAbs_Ellipse) {
619 gp_Elips E = myCurve->Ellipse();
620 Axis = E.Position();
621 R1 = E.MajorRadius();
622 R2 = E.MinorRadius();
623 }
624
625 // Common Code for CIRCLE & ELLIPSE begin here
626 gp_Dir X = Axis.XDirection();
627 gp_Dir Y = Axis.YDirection();
628 gp_Vec VDx = ProjectVec(myPlane,myDirection,X);
629 gp_Vec VDy = ProjectVec(myPlane,myDirection,Y);
630 gp_Dir Dx,Dy;
631
632 Standard_Real Tol2 = myTolerance*myTolerance;
633 if (VDx.SquareMagnitude() < Tol2 ||
634 VDy.SquareMagnitude() < Tol2 ) {
635 myIsApprox = Standard_True;
636 }
637
638 if (!myIsApprox &&
639 gp_Dir(VDx).IsNormal(gp_Dir(VDy),Precision::Angular())) {
640 Dx = gp_Dir(VDx);
641 Dy = gp_Dir(VDy);
642 gp_Pnt O = Axis.Location();
643 gp_Pnt P = ProjectPnt(myPlane,myDirection,O);
644 gp_Pnt Px = ProjectPnt(myPlane,myDirection,O.Translated(R1*gp_Vec(X)));
645 gp_Pnt Py = ProjectPnt(myPlane,myDirection,O.Translated(R2*gp_Vec(Y)));
646 Standard_Real Major = P.Distance(Px);
647 Standard_Real Minor = P.Distance(Py);
648 gp_Ax2 Axe( P, Dx^Dy,Dx);
649
650 if ( Abs( Major - Minor) < Precision::Confusion()) {
651 myType = GeomAbs_Circle;
652 gp_Circ Circ(Axe, Major);
653 GeomCirclePtr = new Geom_Circle(Circ);
654// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
655 GeomAdaptor_Curve aGACurve(GeomCirclePtr);
656 myResult = new GeomAdaptor_HCurve(aGACurve);
657// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
658 }
659 else if ( Major > Minor) {
660 myType = GeomAbs_Ellipse;
661 Elips = gp_Elips( Axe, Major, Minor);
662
663 GeomEllipsePtr = new Geom_Ellipse(Elips) ;
664// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
665 GeomAdaptor_Curve aGACurve(GeomEllipsePtr);
666 myResult = new GeomAdaptor_HCurve(aGACurve);
667// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
668 }
669 else {
670 myIsApprox = Standard_True;
671 myType = GeomAbs_BSplineCurve;
672 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
673// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
674 GeomAdaptor_Curve aGACurve(ApproxCurve);
675 myResult = new GeomAdaptor_HCurve(aGACurve);
676// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
677 }
678 }
679 else {
680 myIsApprox = Standard_True;
681 myType = GeomAbs_BSplineCurve;
682 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
683// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
684 GeomAdaptor_Curve aGACurve(ApproxCurve);
685 myResult = new GeomAdaptor_HCurve(aGACurve);
686// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
687 }
688 }
689 break;
690 case GeomAbs_Parabola:
691 {
692 // P(u) = O + (u*u)/(4*f) * Xc + u * Yc
693 // ==> Q(u) = f(P(u))
694 // = f(O) + (u*u)/(4*f) * f(Xc) + u * f(Yc)
695
696 gp_Parab Parab = myCurve->Parabola();
697 gp_Ax2 AxeRef = Parab.Position();
698 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
699 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
700
701 // fix for case when no one action is done. 28.03.2002
702 Standard_Boolean alocalIsDone = Standard_False;
703
704 if ( Abs( Yc.Magnitude() - 1.) < Precision::Confusion()) {
705 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
706 if ( Xc.Magnitude() < Precision::Confusion()) {
707 myType = GeomAbs_Line;
708 aLine = gp_Lin( P, gp_Dir(Yc));
709
710 GeomLinePtr = new Geom_Line(aLine) ;
711// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
712 GeomAdaptor_Curve aGACurve(GeomLinePtr);
713 myResult = new GeomAdaptor_HCurve(aGACurve);
714// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
715 alocalIsDone = Standard_True;
716 }
717 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
718 myType = GeomAbs_Parabola;
719 Standard_Real F = Parab.Focal() / Xc.Magnitude();
720 gp_Parab Parab = gp_Parab( gp_Ax2(P,Xc^Yc,Xc), F);
721 Handle(Geom_Parabola) GeomParabolaPtr =
722 new Geom_Parabola(Parab) ;
723// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
724 GeomAdaptor_Curve aGACurve(GeomParabolaPtr);
725 myResult = new GeomAdaptor_HCurve(aGACurve);
726// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
727 alocalIsDone = Standard_True;
728 }
729 }
730 if (!alocalIsDone)/*else*/ {
731 myIsApprox = Standard_True;
732 myType = GeomAbs_BSplineCurve;
733 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
734// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
735 GeomAdaptor_Curve aGACurve(ApproxCurve);
736 myResult = new GeomAdaptor_HCurve(aGACurve);
737// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
738 }
739 }
740 break;
741 case GeomAbs_Hyperbola:
742 {
743 // P(u) = O + R1 * Cosh(u) * Xc + R2 * Sinh(u) * Yc
744 // ==> Q(u) = f(P(u))
745 // = f(O) + R1 * Cosh(u) * f(Xc) + R2 * Sinh(u) * f(Yc)
746
747 gp_Hypr Hypr = myCurve->Hyperbola();
748 gp_Ax2 AxeRef = Hypr.Position();
749 gp_Vec Xc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.XDirection()));
750 gp_Vec Yc = ProjectVec(myPlane,myDirection,gp_Vec(AxeRef.YDirection()));
751 gp_Pnt P = ProjectPnt(myPlane,myDirection,AxeRef.Location());
752 Standard_Real R1 = Hypr.MajorRadius();
753 Standard_Real R2 = Hypr.MinorRadius();
754 gp_Dir Z = myPlane.Direction();
755
756 if ( Xc.Magnitude() < Precision::Confusion()) {
757 myType = GeomAbs_Hyperbola;
758 gp_Dir X = gp_Dir(Yc) ^ Z;
759 Hypr = gp_Hypr(gp_Ax2( P, Z, X), 0., R2 * Yc.Magnitude());
760 GeomHyperbolaPtr =
761 new Geom_Hyperbola(Hypr) ;
762// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
763 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
764 myResult = new GeomAdaptor_HCurve(aGACurve);
765// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
766 }
767 else if ( Yc.Magnitude() < Precision::Confusion()) {
768 myType = GeomAbs_Hyperbola;
769 Hypr =
770 gp_Hypr(gp_Ax2(P, Z, gp_Dir(Xc)), R1 * Xc.Magnitude(), 0.);
771 GeomHyperbolaPtr =
772 new Geom_Hyperbola(Hypr) ;
773// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
774 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
775 myResult = new GeomAdaptor_HCurve(aGACurve);
776// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
777 }
778 else if ( Xc.IsNormal(Yc,Precision::Angular())) {
779 myType = GeomAbs_Hyperbola;
780 Hypr = gp_Hypr( gp_Ax2( P, gp_Dir( Xc ^ Yc), gp_Dir( Xc)),
781 R1 * Xc.Magnitude(), R2 * Yc.Magnitude() );
782 GeomHyperbolaPtr =
783 new Geom_Hyperbola(Hypr) ;
784// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
785 GeomAdaptor_Curve aGACurve(GeomHyperbolaPtr);
786 myResult = new GeomAdaptor_HCurve(aGACurve);
787// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
788 }
789 else {
790 myIsApprox = Standard_True;
791 myType = GeomAbs_BSplineCurve;
792 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
793// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
794 GeomAdaptor_Curve aGACurve(ApproxCurve);
795 myResult = new GeomAdaptor_HCurve(aGACurve);
796// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
797 }
798 }
799 break;
800 case GeomAbs_BezierCurve:
801 {
802 Handle(Geom_BezierCurve) BezierCurvePtr =
803 myCurve->Bezier() ;
804 Standard_Integer NbPoles =
805 BezierCurvePtr->NbPoles() ;
806
807 Handle(Geom_BezierCurve) ProjCu =
808 Handle(Geom_BezierCurve)::DownCast(BezierCurvePtr->Copy());
809
810 myIsApprox = Standard_False;
811 myType = Type;
812 for ( Standard_Integer i = 1; i <= NbPoles; i++) {
813 ProjCu->SetPole
814 (i,ProjectPnt(myPlane,myDirection,BezierCurvePtr->Pole(i)));
815 }
816
817// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
818 GeomAdaptor_Curve aGACurve(ProjCu);
819 myResult = new GeomAdaptor_HCurve(aGACurve);
820// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
821 }
822 break ;
823 case GeomAbs_BSplineCurve:
824 {
825 Handle(Geom_BSplineCurve) BSplineCurvePtr =
826 myCurve->BSpline() ;
827 //
828 // make a copy of the curve and projects its poles
829 //
830 Handle(Geom_BSplineCurve) ProjectedBSplinePtr =
831 Handle(Geom_BSplineCurve)::DownCast(BSplineCurvePtr->Copy()) ;
832
833 myIsApprox = Standard_False;
834 myType = Type;
835 for ( Standard_Integer i = 1; i <= BSplineCurvePtr->NbPoles(); i++) {
836 ProjectedBSplinePtr->SetPole
837 (i,ProjectPnt(myPlane,myDirection,BSplineCurvePtr->Pole(i)));
838 }
839
840// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
841 GeomAdaptor_Curve aGACurve(ProjectedBSplinePtr);
842 myResult = new GeomAdaptor_HCurve(aGACurve);
843// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
844 }
845 break;
846 default:
847 {
848 myIsApprox = Standard_True;
849 myType = GeomAbs_BSplineCurve;
850 PerformApprox(myCurve,myPlane,myDirection,ApproxCurve);
851// Modified by Sergey KHROMOV - Tue Jan 29 16:57:29 2002 Begin
852 GeomAdaptor_Curve aGACurve(ApproxCurve);
853 myResult = new GeomAdaptor_HCurve(aGACurve);
854// Modified by Sergey KHROMOV - Tue Jan 29 16:57:30 2002 End
855 }
856 break;
857 }
858}
859
860//=======================================================================
861//function : GetPlane
862//purpose :
863//=======================================================================
864
865const gp_Ax3& ProjLib_ProjectOnPlane::GetPlane() const
866{
867 return myPlane;
868}
869
870//=======================================================================
871//function : GetDirection
872//purpose :
873//=======================================================================
874
875const gp_Dir& ProjLib_ProjectOnPlane::GetDirection() const
876{
877 return myDirection;
878}
879
880//=======================================================================
881//function : GetCurve
882//purpose :
883//=======================================================================
884
885const Handle(Adaptor3d_HCurve)& ProjLib_ProjectOnPlane::GetCurve() const
886{
887 return myCurve;
888}
889
890
891//=======================================================================
892//function : FirstParameter
893//purpose :
894//=======================================================================
895
896Standard_Real ProjLib_ProjectOnPlane::FirstParameter() const
897{
898 if ( myKeepParam || myIsApprox)
899 return myCurve->FirstParameter();
900 else
901 return myFirstPar;
902}
903
904
905//=======================================================================
906//function : LastParameter
907//purpose :
908//=======================================================================
909
910Standard_Real ProjLib_ProjectOnPlane::LastParameter() const
911{
912 if ( myKeepParam || myIsApprox)
913 return myCurve->LastParameter();
914 else
915 return myLastPar;
916}
917
918
919//=======================================================================
920//function : Continuity
921//purpose :
922//=======================================================================
923
924GeomAbs_Shape ProjLib_ProjectOnPlane::Continuity() const
925{
926 return myCurve->Continuity() ;
927}
928
929
930//=======================================================================
931//function : NbIntervals
932//purpose :
933//=======================================================================
934
935Standard_Integer ProjLib_ProjectOnPlane::NbIntervals(const GeomAbs_Shape S)
936{
937 return myCurve->NbIntervals(S) ;
938}
939
940
941//=======================================================================
942//function : Intervals
943//purpose :
944//=======================================================================
945
946void ProjLib_ProjectOnPlane::Intervals(TColStd_Array1OfReal& T,
947 const GeomAbs_Shape S)
948{
949 myCurve->Intervals(T,S) ;
950}
951
952//=======================================================================
953//function : Trim
954//purpose :
955//=======================================================================
956
957Handle(Adaptor3d_HCurve)
958ProjLib_ProjectOnPlane::Trim(const Standard_Real First,
959 const Standard_Real Last,
960 const Standard_Real Tolerance) const
961{
962 if (myType != GeomAbs_OtherCurve){
963 return myResult->Trim(First,Last,Tolerance) ;
964 }
965 else {
966 Standard_NotImplemented::Raise("");
967 }
968
969 // portage WNT
970 Handle(Adaptor3d_HCurve) dummy;
971 return dummy;
972}
973
974
975//=======================================================================
976//function : IsClosed
977//purpose :
978//=======================================================================
979
980Standard_Boolean ProjLib_ProjectOnPlane::IsClosed() const
981{
982 return myCurve->IsClosed() ;
983}
984
985
986//=======================================================================
987//function : IsPeriodic
988//purpose :
989//=======================================================================
990
991Standard_Boolean ProjLib_ProjectOnPlane::IsPeriodic() const
992{
993 if ( myIsApprox)
994 return Standard_False;
995 else
996 return myCurve->IsPeriodic();
997}
998
999
1000//=======================================================================
1001//function : Period
1002//purpose :
1003//=======================================================================
1004
1005Standard_Real ProjLib_ProjectOnPlane::Period() const
1006{
1007 if ( !IsPeriodic()) {
1008 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane::Period");
1009 }
1010
1011 if ( myIsApprox)
1012 return Standard_False;
1013 else
1014 return myCurve->Period();
1015}
1016
1017
1018//=======================================================================
1019//function : Value
1020//purpose :
1021//=======================================================================
1022
1023gp_Pnt ProjLib_ProjectOnPlane::Value(const Standard_Real U) const
1024{
1025 if (myType != GeomAbs_OtherCurve) {
1026 return myResult->Value(U);
1027 }
1028 else {
1029 return OnPlane_Value(U,
1030 myCurve,
1031 myPlane,
1032 myDirection);
1033
1034 }
1035}
1036
1037
1038//=======================================================================
1039//function : D0
1040//purpose :
1041//=======================================================================
1042
1043void ProjLib_ProjectOnPlane::D0(const Standard_Real U , gp_Pnt& P) const
1044{
1045 if (myType != GeomAbs_OtherCurve) {
1046 myResult->D0(U,P) ;
1047 }
1048 else {
1049 P = OnPlane_Value(U,
1050 myCurve,
1051 myPlane,
1052 myDirection);
1053 }
1054}
1055
1056
1057//=======================================================================
1058//function : D1
1059//purpose :
1060//=======================================================================
1061
1062void ProjLib_ProjectOnPlane::D1(const Standard_Real U,
1063 gp_Pnt& P ,
1064 gp_Vec& V ) const
1065{
1066 if (myType != GeomAbs_OtherCurve) {
1067 myResult->D1(U,P,V) ;
1068 }
1069 else {
1070 OnPlane_D1(U,
1071 P,
1072 V,
1073 myCurve,
1074 myPlane,
1075 myDirection);
1076 }
1077}
1078
1079
1080//=======================================================================
1081//function : D2
1082//purpose :
1083//=======================================================================
1084
1085void ProjLib_ProjectOnPlane::D2(const Standard_Real U,
1086 gp_Pnt& P,
1087 gp_Vec& V1,
1088 gp_Vec& V2) const
1089{
1090 if (myType != GeomAbs_OtherCurve) {
1091 myResult->D2(U,P,V1,V2) ;
1092 }
1093 else {
1094 OnPlane_D2(U,
1095 P,
1096 V1,
1097 V2,
1098 myCurve,
1099 myPlane,
1100 myDirection);
1101 }
1102}
1103
1104
1105//=======================================================================
1106//function : D3
1107//purpose :
1108//=======================================================================
1109
1110void ProjLib_ProjectOnPlane::D3(const Standard_Real U,
1111 gp_Pnt& P,
1112 gp_Vec& V1,
1113 gp_Vec& V2,
1114 gp_Vec& V3) const
1115{
1116 if (myType != GeomAbs_OtherCurve) {
1117 myResult->D3(U,P,V1,V2,V3) ;
1118 }
1119 else {
1120 OnPlane_D3(U,
1121 P,
1122 V1,
1123 V2,
1124 V3,
1125 myCurve,
1126 myPlane,
1127 myDirection);
1128 }
1129}
1130
1131
1132//=======================================================================
1133//function : DN
1134//purpose :
1135//=======================================================================
1136
1137gp_Vec ProjLib_ProjectOnPlane::DN(const Standard_Real U,
1138 const Standard_Integer DerivativeRequest)
1139 const
1140{
1141 if (myType != GeomAbs_OtherCurve) {
1142 return myResult->DN(U,DerivativeRequest) ;
1143 }
1144 else {
1145 return OnPlane_DN(U,
1146 DerivativeRequest,
1147 myCurve,
1148 myPlane,
1149 myDirection);
1150 }
1151}
1152
1153
1154//=======================================================================
1155//function : Resolution
1156//purpose :
1157//=======================================================================
1158
1159Standard_Real ProjLib_ProjectOnPlane::Resolution
1160(const Standard_Real Tolerance) const
1161{
1162 if (myType != GeomAbs_OtherCurve) {
1163 return myResult->Resolution(Tolerance) ;
1164 }
1165 else {
1166 return 0;
1167 }
1168}
1169
1170
1171//=======================================================================
1172//function : GetType
1173//purpose :
1174//=======================================================================
1175
1176GeomAbs_CurveType ProjLib_ProjectOnPlane::GetType() const
1177{
1178 return myType;
1179}
1180
1181
1182//=======================================================================
1183//function : Line
1184//purpose :
1185//=======================================================================
1186
1187gp_Lin ProjLib_ProjectOnPlane::Line() const
1188{
1189 if (myType != GeomAbs_Line)
1190 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Line");
1191
1192 return myResult->Line();
1193}
1194
1195
1196//=======================================================================
1197//function : Circle
1198//purpose :
1199//=======================================================================
1200
1201gp_Circ ProjLib_ProjectOnPlane::Circle() const
1202{
1203 if (myType != GeomAbs_Circle)
1204 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Circle");
1205
1206 return myResult->Circle();
1207}
1208
1209
1210//=======================================================================
1211//function : Ellipse
1212//purpose :
1213//=======================================================================
1214
1215gp_Elips ProjLib_ProjectOnPlane::Ellipse() const
1216{
1217 if (myType != GeomAbs_Ellipse)
1218 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Ellipse");
1219
1220 return myResult->Ellipse();
1221}
1222
1223
1224//=======================================================================
1225//function : Hyperbola
1226//purpose :
1227//=======================================================================
1228
1229gp_Hypr ProjLib_ProjectOnPlane::Hyperbola() const
1230{
1231 if (myType != GeomAbs_Hyperbola)
1232 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Hyperbola");
1233
1234 return myResult->Hyperbola() ;
1235}
1236
1237
1238//=======================================================================
1239//function : Parabola
1240//purpose :
1241//=======================================================================
1242
1243gp_Parab ProjLib_ProjectOnPlane::Parabola() const
1244{
1245 if (myType != GeomAbs_Parabola)
1246 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Parabola");
1247
1248 return myResult->Parabola() ;
1249}
1250
1251//=======================================================================
1252//function : Degree
1253//purpose :
1254//=======================================================================
1255
1256Standard_Integer ProjLib_ProjectOnPlane::Degree() const
1257{
1258 if ((GetType() != GeomAbs_BSplineCurve) &&
1259 (GetType() != GeomAbs_BezierCurve))
1260 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Degree");
1261
1262 if ( myIsApprox)
1263 return myResult->Degree();
1264 else
1265 return myCurve->Degree();
1266}
1267
1268//=======================================================================
1269//function : IsRational
1270//purpose :
1271//=======================================================================
1272
1273Standard_Boolean ProjLib_ProjectOnPlane::IsRational() const
1274{
1275 if ((GetType() != GeomAbs_BSplineCurve) &&
1276 (GetType() != GeomAbs_BezierCurve))
1277 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:IsRational");
1278
1279 if ( myIsApprox)
1280 return myResult->IsRational();
1281 else
1282 return myCurve->IsRational();
1283}
1284
1285//=======================================================================
1286//function : NbPoles
1287//purpose :
1288//=======================================================================
1289
1290Standard_Integer ProjLib_ProjectOnPlane::NbPoles() const
1291{
1292 if ((GetType() != GeomAbs_BSplineCurve) &&
1293 (GetType() != GeomAbs_BezierCurve))
1294 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbPoles");
1295
1296 if ( myIsApprox)
1297 return myResult->NbPoles();
1298 else
1299 return myCurve->NbPoles();
1300}
1301
1302//=======================================================================
1303//function : NbKnots
1304//purpose :
1305//=======================================================================
1306
1307Standard_Integer ProjLib_ProjectOnPlane::NbKnots() const
1308{
1309 if ( GetType() != GeomAbs_BSplineCurve)
1310 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:NbKnots");
1311
1312 if ( myIsApprox)
1313 return myResult->NbKnots();
1314 else
1315 return myCurve->NbKnots();
1316}
1317
1318
1319//=======================================================================
1320//function : Bezier
1321//purpose :
1322//=======================================================================
1323
1324Handle(Geom_BezierCurve) ProjLib_ProjectOnPlane::Bezier() const
1325{
1326 if (myType != GeomAbs_BezierCurve)
1327 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:Bezier");
1328
1329 return myResult->Bezier() ;
1330}
1331
1332//=======================================================================
1333//function : Bezier
1334//purpose :
1335//=======================================================================
1336
1337Handle(Geom_BSplineCurve) ProjLib_ProjectOnPlane::BSpline() const
1338{
1339 if (myType != GeomAbs_BSplineCurve)
1340 Standard_NoSuchObject::Raise("ProjLib_ProjectOnPlane:BSpline");
1341
1342 return myResult->BSpline() ;
1343}
1344