Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Adaptor3d / Adaptor3d_OffsetCurve.cxx
CommitLineData
7fd59977 1#include <Adaptor3d_OffsetCurve.ixx>
2
3#include <Adaptor3d_HOffsetCurve.hxx>
4#include <GeomAbs_SurfaceType.hxx>
5#include <Standard_NoSuchObject.hxx>
6#include <Standard_NotImplemented.hxx>
7#include <gp_VectorWithNullMagnitude.hxx>
8#include <Precision.hxx>
9#include <gp_Ax22d.hxx>
10#include <gp_Dir2d.hxx>
11#include <gp.hxx>
12
13//=======================================================================
14//function : Adaptor3d_OffsetCurve
15//purpose :
16//=======================================================================
17
18Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve() :
19 myOffset( 0.)
20{}
21
22//=======================================================================
23//function : Adaptor3d_OffsetCurve
24//purpose :
25//=======================================================================
26
27Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C)
28{
29 Load(C);
30}
31
32//=======================================================================
33//function : Adaptor3d_OffsetCurve
34//purpose :
35//=======================================================================
36
37Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C,
38 const Standard_Real Offset)
39{
40 Load(C);
41 Load(Offset);
42}
43
44//=======================================================================
45//function : Adaptor3d_OffsetCurve
46//purpose :
47//=======================================================================
48
49Adaptor3d_OffsetCurve::Adaptor3d_OffsetCurve(const Handle(Adaptor2d_HCurve2d)& C,
50 const Standard_Real Offset,
51 const Standard_Real WFirst,
52 const Standard_Real WLast)
53{
54 Load(C);
55 Load(Offset,WFirst,WLast);
56}
57
58//=======================================================================
59//function : Load
60//purpose :
61//=======================================================================
62
63void Adaptor3d_OffsetCurve::Load(const Handle(Adaptor2d_HCurve2d)& C )
64{
65 myCurve = C;
66 myOffset = 0.;
67}
68
69//=======================================================================
70//function : Load
71//purpose :
72//=======================================================================
73
74void Adaptor3d_OffsetCurve::Load( const Standard_Real Offset)
75{
76 myOffset = Offset;
77 myFirst = myCurve->FirstParameter();
78 myLast = myCurve->LastParameter();
79
80}
81
82//=======================================================================
83//function : Load
84//purpose :
85//=======================================================================
86
87void Adaptor3d_OffsetCurve::Load(const Standard_Real Offset,
88 const Standard_Real WFirst,
89 const Standard_Real WLast)
90{
91 myOffset = Offset;
92 myFirst = WFirst;
93 myLast = WLast;
94}
95
96//=======================================================================
97//function : Continuity
98//purpose :
99//=======================================================================
100
101GeomAbs_Shape Adaptor3d_OffsetCurve::Continuity() const
102{
103 switch (myCurve->Continuity()) {
104 case GeomAbs_CN: return GeomAbs_CN;
105 case GeomAbs_C3: return GeomAbs_C2;
106 case GeomAbs_C2: return GeomAbs_G2;
107 case GeomAbs_G2: return GeomAbs_C1;
108 case GeomAbs_C1: return GeomAbs_G1;
109 case GeomAbs_G1: return GeomAbs_C0;
110 case GeomAbs_C0:
111// No Continuity !!
112 Standard_TypeMismatch::Raise("Adaptor3d_OffsetCurve::IntervalContinuity");
113 break;
114 }
115
116 //portage WNT
117 return GeomAbs_C0;
118}
119
120//=======================================================================
121//function : NbIntervals
122//purpose :
123//=======================================================================
124
125Standard_Integer Adaptor3d_OffsetCurve::NbIntervals(const GeomAbs_Shape S) const
126{
127 GeomAbs_Shape Sh;
128 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
129 else
130 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
131
132 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
133
134 if(nbInter == 1) return nbInter;
135
136 TColStd_Array1OfReal T(1,nbInter+1);
137
138 myCurve->Intervals(T,Sh);
139
140 Standard_Integer first = 1;
141 while (T(first) <= myFirst) first++;
142 Standard_Integer last = nbInter+1;
143 while (T(last) >= myLast) last--;
144 return (last - first + 2);
145}
146
147//=======================================================================
148//function : Intervals
149//purpose :
150//=======================================================================
151
152void Adaptor3d_OffsetCurve::Intervals(TColStd_Array1OfReal& TI,
153 const GeomAbs_Shape S) const
154{
155 GeomAbs_Shape Sh;
156 if ( S >= GeomAbs_C2) Sh = GeomAbs_CN;
157 else
158 Sh = (GeomAbs_Shape)((Standard_Integer)S + 2);
159
160 Standard_Integer nbInter = myCurve->NbIntervals(Sh);
161
162
163 if(nbInter == 1) {
164 TI(TI.Lower()) = myFirst ;
165 TI(TI.Lower() + 1) = myLast ;
166 return;
167 }
168
169 TColStd_Array1OfReal T(1,nbInter+1);
170 myCurve->Intervals(T,Sh);
171
172 Standard_Integer first = 1;
173 while (T(first) <= myFirst) first++;
174 Standard_Integer last = nbInter+1;
175 while (T(last) >= myLast) last--;
176
177 Standard_Integer i = TI.Lower(), j;
178 for (j = first-1; j <= last+1; j++) {
179 TI(i) = T(j);
180 i++;
181 }
182
183 TI(TI.Lower()) = myFirst ;
184 TI(TI.Lower() + last-first + 2) = myLast ;
185
186}
187
188
189//=======================================================================
190//function : Trim
191//purpose :
192//=======================================================================
193
194Handle(Adaptor2d_HCurve2d) Adaptor3d_OffsetCurve::Trim
195(const Standard_Real First,
196 const Standard_Real Last,
197 const Standard_Real) const
198{
199 Handle(Adaptor3d_HOffsetCurve) HO = new Adaptor3d_HOffsetCurve(*this);
200 HO->ChangeCurve2d().Load(myOffset,First,Last);
201 return HO;
202}
203
204
205//=======================================================================
206//function : IsClosed
207//purpose :
208//=======================================================================
209
210Standard_Boolean Adaptor3d_OffsetCurve::IsClosed() const
211{
212 if ( myOffset == 0.) {
213 return myCurve->IsClosed();
214 }
215 else {
216 if (myCurve->Continuity() == GeomAbs_C0)
217 return Standard_False;
218 else {
219 if ( myCurve->IsClosed()) {
220 gp_Vec2d Dummy[2];
221 gp_Pnt2d P;
222 myCurve->D1
223 (myCurve->FirstParameter(),P,Dummy[0]);
224 myCurve->D1
225 (myCurve->LastParameter(),P,Dummy[1]);
226 if (Dummy[0].IsParallel(Dummy[1],Precision::Angular()) &&
227 !(Dummy[0].IsOpposite(Dummy[1],Precision::Angular())))
228 return Standard_True;
229 else
230 return Standard_False;
231 }
232 else
233 return Standard_False;
234 }
235 }
236}
237
238//=======================================================================
239//function : IsPeriodic
240//purpose :
241//=======================================================================
242
243Standard_Boolean Adaptor3d_OffsetCurve::IsPeriodic() const
244{
245 return myCurve->IsPeriodic();
246}
247
248//=======================================================================
249//function : Period
250//purpose :
251//=======================================================================
252
253Standard_Real Adaptor3d_OffsetCurve::Period() const
254{
255 return myCurve->Period();
256}
257
258//=======================================================================
259//function : Value
260//purpose :
261//=======================================================================
262
263gp_Pnt2d Adaptor3d_OffsetCurve::Value(const Standard_Real U) const
264{
265 if ( myOffset != 0.) {
266 gp_Pnt2d P;
267 gp_Vec2d V;
268 Standard_Real Norme;
269 myCurve->D1(U, P, V);
270 Norme = V.Magnitude();
271 V.SetCoord(-V.Y(),V.X());
272 if (Norme >= gp::Resolution()) {
273 return gp_Pnt2d(P.XY()+myOffset*V.XY()/Norme);
274 }
275 else {
276 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::Value");
277 return gp_Pnt2d();
278 }
279 }
280 else {
281 return myCurve->Value(U);
282 }
283}
284
285//=======================================================================
286//function : D0
287//purpose :
288//=======================================================================
289
290void Adaptor3d_OffsetCurve::D0(const Standard_Real U, gp_Pnt2d& P) const
291{
292 P = Value( U);
293}
294
295//=======================================================================
296//function : D1
297//purpose :
298//=======================================================================
299
300void Adaptor3d_OffsetCurve::D1
301 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V) const
302{
303 gp_Vec2d V1,V2,V3;
304 gp_Pnt2d PP;
305 Standard_Real Norme;
306 if ( myOffset != 0. ) {
307 myCurve->D2(U,PP,V1,V2);
308 Norme = V1.Magnitude();
309 V3.SetCoord( -V1.Y(),V1.X());
310 V2.SetCoord( -V2.Y(),V2.X());
311 if ( Norme >= gp::Resolution()) {
312 P = gp_Pnt2d( PP.XY()+myOffset*V3.XY()/Norme);
313 V = gp_Vec2d( V1.XY()+
314 (myOffset/Norme)*(V2.XY()-V3.XY()*
315 (V2.XY()*V3.XY())/(Norme*Norme)));
316 }
317 else {
318 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::D1");
319 }
320 }
321 else {
322 myCurve->D1(U,P,V);
323 }
324}
325
326//=======================================================================
327//function : D2
328//purpose :
329//=======================================================================
330
331void Adaptor3d_OffsetCurve::D2
332 (const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2) const
333{
334 if ( myOffset != 0.) {
335 gp_Vec2d T1,T2,T3;
336 gp_Pnt2d PP;
337 Standard_Real Norme;
338 myCurve->D3(U,PP,T1,T2,T3);
339
340 Norme = T1.Magnitude();
341 if ( Norme >= gp::Resolution()) {
342 gp_Vec2d N1,N2,N3; // Ni = Z ^ Ti
343 N1.SetCoord( -T1.Y(), T1.X());
344 N2.SetCoord( -T2.Y(), T2.X());
345 N3.SetCoord( -T3.Y(), T3.X());
346 Standard_Real d12,d13,d22,Nor3,Nor11;
347 d12 = T1*T2;
348 d22 = T2*T2;
349 d13 = T1*T3;
350 Nor3 = Norme*Norme*Norme;
351 Nor11 = Nor3*Nor3*Nor3*Norme*Norme;
352 V2 = gp_Vec2d( -1 * ( (d22+d13)/Nor3 + 3*d12*d12/Nor11) * N1.XY());
353 V2 = gp_Vec2d( V2.XY() - (2*d12/Nor3)*N2.XY() + N3.XY()/Norme);
354 V2 = gp_Vec2d( myOffset*V2.XY() + T2.XY());
355
356 D1( U,P,V1);
357 }
358 else {
359 gp_VectorWithNullMagnitude::Raise("Adaptor3d_OffsetCurve::D2");
360 }
361 }
362 else {
363 myCurve->D2(U,P,V1,V2);
364 }
365}
366
367//=======================================================================
368//function : D3
369//purpose :
370//=======================================================================
371
372//void Adaptor3d_OffsetCurve::D3
373// (const Standard_Real T,
374// gp_Pnt2d& P, gp_Vec2d& V1, gp_Vec2d& V2, gp_Vec2d& V3) const
375void Adaptor3d_OffsetCurve::D3
376 (const Standard_Real ,
377 gp_Pnt2d& , gp_Vec2d& , gp_Vec2d& , gp_Vec2d& ) const
378{
379 Standard_NotImplemented::Raise("Adaptor3d_OffsetCurve::D3");
380}
381
382//=======================================================================
383//function : DN
384//purpose :
385//=======================================================================
386
387gp_Vec2d Adaptor3d_OffsetCurve::DN
388// (const Standard_Real T, const Standard_Integer N) const
389 (const Standard_Real , const Standard_Integer ) const
390{
391 Standard_NotImplemented::Raise("Adaptor3d_OffsetCurve::DN");
392 return gp_Vec2d();
393}
394
395
396//=======================================================================
397//function : Resolution
398//purpose :
399//=======================================================================
400
401Standard_Real Adaptor3d_OffsetCurve::Resolution(const Standard_Real R3d) const
402{
403 return Precision::PConfusion(R3d);
404}
405
406
407//=======================================================================
408//function : GetType
409//purpose :
410//=======================================================================
411
412GeomAbs_CurveType Adaptor3d_OffsetCurve::GetType() const {
413
414 if ( myOffset == 0.) {
415 return myCurve->GetType();
416 }
417 else {
418 switch (myCurve->GetType()) {
419
420 case GeomAbs_Line:
421 return GeomAbs_Line;
422
423 case GeomAbs_Circle:
424 return GeomAbs_Circle;
425
426 default:
427 return GeomAbs_OtherCurve;
428
429 }
430 }
431}
432
433//=======================================================================
434//function : Line
435//purpose :
436//=======================================================================
437
438gp_Lin2d Adaptor3d_OffsetCurve::Line() const
439{
440 if ( GetType() == GeomAbs_Line) {
441 gp_Pnt2d P;
442 gp_Vec2d V;
443 D1(0,P,V);
444 return gp_Lin2d(P,V);
445 }
446 else {
447 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Line");
448 return gp_Lin2d();
449 }
450}
451
452
453//=======================================================================
454//function : Circle
455//purpose :
456//=======================================================================
457
458gp_Circ2d Adaptor3d_OffsetCurve::Circle() const
459{
460 if ( GetType() == GeomAbs_Circle) {
461 if (myOffset == 0.) {
462 return myCurve->Circle();
463 }
464 else {
465 gp_Circ2d C1( myCurve->Circle());
466 Standard_Real radius = C1.Radius();
467 gp_Ax22d axes( C1.Axis());
468 gp_Dir2d Xd = axes.XDirection();
469 gp_Dir2d Yd = axes.YDirection();
470 Standard_Real Crossed = Xd.X()*Yd.Y()-Xd.Y()*Yd.X();
471 Standard_Real Signe = ( Crossed > 0.) ? 1. : -1.;
472
473 radius += Signe*myOffset;
474 if ( radius > 0.) {
475 return gp_Circ2d( axes,radius);
476 }
477 else if ( radius < 0.) {
478 radius = - radius;
479 axes.SetXDirection( (axes.XDirection()).Reversed());
480 return gp_Circ2d( axes,radius);
481 }
482 else { // Cercle de rayon Nul
483 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Circle");
484 }
485 }
486 }
487 else {
488 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::Circle");
489 }
490 // portage WNT
491 return gp_Circ2d();
492}
493
494//=======================================================================
495//function : Ellipse
496//purpose :
497//=======================================================================
498
499gp_Elips2d Adaptor3d_OffsetCurve::Ellipse() const
500{
501 if (myCurve->GetType() == GeomAbs_Ellipse && myOffset == 0.) {
502 return myCurve->Ellipse();;
503 }
504 else {
505 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Ellipse");
506 }
507 // portage WNT
508 return gp_Elips2d();
509}
510
511//=======================================================================
512//function : Hyperbola
513//purpose :
514//=======================================================================
515
516gp_Hypr2d Adaptor3d_OffsetCurve::Hyperbola() const
517{
518 if (myCurve->GetType()==GeomAbs_Hyperbola && myOffset==0.) {
519 return myCurve->Hyperbola();
520 }
521 else {
522 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Hyperbola");
523 }
524 // portage WNT
525 return gp_Hypr2d();
526}
527
528//=======================================================================
529//function : Parabola
530//purpose :
531//=======================================================================
532
533gp_Parab2d Adaptor3d_OffsetCurve::Parabola() const
534{
535 if (myCurve->GetType() == GeomAbs_Parabola && myOffset == 0.) {
536 return myCurve->Parabola();
537 }
538 else {
539 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve:Parabola");
540 }
541 // portage WNT
542 return gp_Parab2d();
543}
544//=======================================================================
545//function : Degree
546//purpose :
547//=======================================================================
548
549Standard_Integer Adaptor3d_OffsetCurve::Degree() const
550{
551 GeomAbs_CurveType type = myCurve->GetType();
552 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
553 && myOffset == 0.) {
554 return myCurve->Degree();
555 }
556 else {
557 Standard_NoSuchObject::Raise("Adaptor3d_offsetCurve::Degree");
558 return 0;
559 }
560}
561//=======================================================================
562//function : IsRational
563//purpose :
564//=======================================================================
565
566Standard_Boolean Adaptor3d_OffsetCurve::IsRational() const
567{
568 if ( myOffset == 0.) {
569 return myCurve->IsRational();
570 }
571 return Standard_False;
572}
573//=======================================================================
574//function : NbPoles
575//purpose :
576//=======================================================================
577
578Standard_Integer Adaptor3d_OffsetCurve::NbPoles() const
579{
580 GeomAbs_CurveType type = myCurve->GetType();
581 if ( (type==GeomAbs_BezierCurve || type==GeomAbs_BSplineCurve)
582 && myOffset == 0.) {
583 return myCurve->NbPoles();
584 }
585 else {
586 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::NbPoles");
587 return 0;
588 }
589}
590
591//=======================================================================
592//function : NbKnots
593//purpose :
594//=======================================================================
595
596Standard_Integer Adaptor3d_OffsetCurve::NbKnots() const
597{
598 if( myOffset == 0.) {
599 return myCurve->NbKnots();
600 }
601 else {
602 Standard_NoSuchObject::Raise("Adaptor3d_OffsetCurve::NbKnots");
603 return 0;
604 }
605}
606
607//=======================================================================
608//function : Bezier
609//purpose :
610//=======================================================================
611
612Handle(Geom2d_BezierCurve) Adaptor3d_OffsetCurve::Bezier() const
613{
614 Standard_NoSuchObject_Raise_if
615 ( myOffset != 0.0e0 || GetType() != GeomAbs_BezierCurve, "");
616 return myCurve->Bezier();
617}
618
619
620//=======================================================================
621//function : BSpline
622//purpose :
623//=======================================================================
624
625Handle(Geom2d_BSplineCurve) Adaptor3d_OffsetCurve::BSpline() const
626{
627 Standard_NoSuchObject_Raise_if
628 ( myOffset != 0.0e0 || GetType() != GeomAbs_BSplineCurve, "");
629
630 return myCurve->BSpline();
631}
632
633