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