Warnings on vc14 were eliminated
[occt.git] / src / GeomAdaptor / GeomAdaptor_SurfaceOfRevolution.cxx
1 // Created on: 1993-04-21
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <GeomAdaptor_SurfaceOfRevolution.hxx>
18
19 #include <Adaptor3d_HCurve.hxx>
20 #include <ElCLib.hxx>
21 #include <GeomAdaptor_HSurfaceOfRevolution.hxx>
22 #include <GeomEvaluator_SurfaceOfRevolution.hxx>
23 #include <Standard_NoSuchObject.hxx>
24
25 //=======================================================================
26 //function : GeomAdaptor_SurfaceOfRevolution
27 //purpose  : 
28 //=======================================================================
29 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution()
30   : myHaveAxis(Standard_False)
31 {}
32
33 //=======================================================================
34 //function : GeomAdaptor_SurfaceOfRevolution
35 //purpose  : 
36 //=======================================================================
37
38 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution(
39     const Handle(Adaptor3d_HCurve)& C)
40   : myHaveAxis(Standard_False)
41 {
42   Load(C);
43 }
44
45 //=======================================================================
46 //function : GeomAdaptor_SurfaceOfRevolution
47 //purpose  : 
48 //=======================================================================
49
50 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution(
51     const Handle(Adaptor3d_HCurve)& C,
52     const gp_Ax1& V)
53   : myHaveAxis(Standard_False)
54 {
55   Load(C);
56   Load(V);
57 }
58
59 //=======================================================================
60 //function : Load
61 //purpose  : 
62 //=======================================================================
63
64 void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_HCurve)& C)
65 {
66   myBasisCurve = C;
67   if (myHaveAxis)
68     Load(myAxis); // to evaluate the new myAxeRev.
69 }
70
71 //=======================================================================
72 //function : Load
73 //purpose  : 
74 //=======================================================================
75
76 void GeomAdaptor_SurfaceOfRevolution::Load(const gp_Ax1& V)
77 {
78   myHaveAxis = Standard_True;
79   myAxis = V;
80
81   mySurfaceType = GeomAbs_SurfaceOfRevolution;
82   myNestedEvaluator = new GeomEvaluator_SurfaceOfRevolution(myBasisCurve,
83       myAxis.Direction(), myAxis.Location());
84
85   // Eval myAxeRev : axe of revolution ( Determination de Ox).
86   gp_Pnt P,Q;
87   gp_Pnt O = myAxis.Location();
88   gp_Dir Ox;
89   gp_Dir Oz = myAxis.Direction();
90   Standard_Boolean yrev = Standard_False;
91   if (myBasisCurve->GetType() == GeomAbs_Line) {
92     if((myBasisCurve->Line().Direction()).Dot(Oz) < 0.){
93       yrev = Standard_True;
94       Oz.Reverse();
95     }
96   }
97
98   if (myBasisCurve->GetType() == GeomAbs_Circle) {
99     Q = P = (myBasisCurve->Circle()).Location();
100   }
101   else {
102     Standard_Real First = myBasisCurve->FirstParameter();
103     P = Value( 0., 0.);// ce qui ne veut pas dire grand chose
104     if ( GetType() == GeomAbs_Cone) {
105       if ( gp_Lin(myAxis).Distance(P) <= Precision::Confusion())
106         Q = ElCLib::Value(1.,myBasisCurve->Line());
107       else 
108         Q = P;
109     }
110     else if (Precision::IsInfinite(First))
111       Q = P; 
112     else 
113       Q = Value( 0., First);
114   }
115   
116   gp_Dir DZ = myAxis.Direction();
117   O.SetXYZ( O.XYZ() + ( gp_Vec(O,P) * DZ) * DZ.XYZ());
118   if ( gp_Lin(myAxis).Distance(Q) > Precision::Confusion()) {
119     Ox = gp_Dir(Q.XYZ() - O.XYZ());
120   }
121   else {
122     Standard_Real First = myBasisCurve->FirstParameter();
123     Standard_Real Last  = myBasisCurve->LastParameter();
124     Standard_Integer Ratio = 1;
125     Standard_Real Dist; 
126     gp_Pnt PP;
127     do {
128       PP = myBasisCurve->Value(First+(Last-First)/Ratio);
129       Dist = gp_Lin(myAxis).Distance(PP);
130       Ratio++;
131     }
132     while ( Dist < Precision::Confusion() && Ratio < 100);
133
134     if ( Ratio >= 100 ) {
135       throw Standard_ConstructionError("Adaptor3d_SurfaceOfRevolution : Axe and meridian are confused");
136     }
137     Ox = ( (Oz^gp_Vec(PP.XYZ()-O.XYZ()))^Oz); 
138   }
139
140   myAxeRev = gp_Ax3(O,Oz,Ox);
141
142   if (yrev) {
143     myAxeRev.YReverse();
144   }
145   else if (myBasisCurve->GetType() == GeomAbs_Circle) {
146     gp_Dir DC = (myBasisCurve->Circle()).Axis().Direction();
147     if ((Ox.Crossed(Oz)).Dot(DC) < 0.)  myAxeRev.ZReverse(); 
148   }
149 }
150
151 //=======================================================================
152 //function : AxeOfRevolution
153 //purpose  : 
154 //=======================================================================
155
156 gp_Ax1 GeomAdaptor_SurfaceOfRevolution::AxeOfRevolution() const
157 {
158   return myAxis;
159 }
160
161 //=======================================================================
162 //function : FirstUParameter
163 //purpose  : 
164 //=======================================================================
165
166 Standard_Real GeomAdaptor_SurfaceOfRevolution::FirstUParameter() const 
167 {
168   return 0.;
169 }
170
171 //=======================================================================
172 //function : LastUParameter
173 //purpose  : 
174 //=======================================================================
175
176 Standard_Real GeomAdaptor_SurfaceOfRevolution::LastUParameter() const 
177 {
178   return 2*M_PI;
179 }
180
181 //=======================================================================
182 //function : FirstVParameter
183 //purpose  : 
184 //=======================================================================
185
186 Standard_Real GeomAdaptor_SurfaceOfRevolution::FirstVParameter() const 
187 {
188   return myBasisCurve->FirstParameter();
189 }
190
191 //=======================================================================
192 //function : LastVParameter
193 //purpose  : 
194 //=======================================================================
195
196 Standard_Real GeomAdaptor_SurfaceOfRevolution::LastVParameter() const 
197 {
198   return myBasisCurve->LastParameter();
199 }
200
201 //=======================================================================
202 //function : UContinuity
203 //purpose  : 
204 //=======================================================================
205
206 GeomAbs_Shape GeomAdaptor_SurfaceOfRevolution::UContinuity() const 
207 {
208   return GeomAbs_CN;
209 }
210
211 //=======================================================================
212 //function : VContinuity
213 //purpose  : 
214 //=======================================================================
215
216 GeomAbs_Shape GeomAdaptor_SurfaceOfRevolution::VContinuity() const 
217 {
218   return myBasisCurve->Continuity();
219 }
220
221 //=======================================================================
222 //function : NbUIntervals
223 //purpose  : 
224 //=======================================================================
225
226 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbUIntervals(const GeomAbs_Shape ) const
227 {
228   return 1;
229 }
230
231 //=======================================================================
232 //function : NbVIntervals
233 //purpose  : 
234 //=======================================================================
235
236 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVIntervals(const GeomAbs_Shape S) const
237 {
238   return myBasisCurve->NbIntervals(S);
239 }
240
241 //=======================================================================
242 //function : UIntervals
243 //purpose  : 
244 //=======================================================================
245
246 void GeomAdaptor_SurfaceOfRevolution::UIntervals(TColStd_Array1OfReal& T,
247                                                  const GeomAbs_Shape ) const
248 {
249   T(T.Lower()  ) = 0.;
250   T(T.Lower()+1) = 2*M_PI;
251 }
252
253
254 //=======================================================================
255 //function : VIntervals
256 //purpose  : 
257 //=======================================================================
258
259 void GeomAdaptor_SurfaceOfRevolution::VIntervals(TColStd_Array1OfReal& T,
260                                                  const GeomAbs_Shape S) const 
261 {
262   myBasisCurve->Intervals(T,S);
263 }
264
265
266 //=======================================================================
267 //function : UTrim
268 //purpose  : 
269 //=======================================================================
270
271 Handle(Adaptor3d_HSurface) GeomAdaptor_SurfaceOfRevolution::UTrim
272 (const Standard_Real 
273 #ifndef No_Exception
274                      First
275 #endif
276  ,const Standard_Real 
277 #ifndef No_Exception
278                      Last
279 #endif
280  ,const Standard_Real 
281                          ) const 
282 {
283 #ifndef No_Exception
284   Standard_Real Eps = Precision::PConfusion();
285 #endif
286   Standard_OutOfRange_Raise_if
287     (  Abs(First) > Eps || Abs(Last - 2.*M_PI) > Eps,
288      "GeomAdaptor_SurfaceOfRevolution : UTrim : Parameters out of range");
289
290   Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
291       GeomAdaptor_SurfaceOfRevolution(myBasisCurve, myAxis));
292   return HR;
293 }
294
295
296 //=======================================================================
297 //function : VTrim
298 //purpose  : 
299 //=======================================================================
300
301 Handle(Adaptor3d_HSurface) GeomAdaptor_SurfaceOfRevolution::VTrim
302 (const Standard_Real First,
303  const Standard_Real Last,
304  const Standard_Real Tol) const 
305 {
306   Handle(Adaptor3d_HCurve) HC = BasisCurve()->Trim(First,Last,Tol);
307   Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
308       GeomAdaptor_SurfaceOfRevolution(HC, myAxis));
309   return HR;
310 }
311
312
313 //=======================================================================
314 //function : IsUClosed
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUClosed() const 
319 {
320   return Standard_True;
321 }
322
323 //=======================================================================
324 //function : IsVClosed
325 //purpose  : 
326 //=======================================================================
327
328 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVClosed() const 
329 {
330   return myBasisCurve->IsClosed();
331 }
332
333 //=======================================================================
334 //function : IsUPeriodic
335 //purpose  : 
336 //=======================================================================
337
338 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUPeriodic() const
339 {
340   return Standard_True;
341 }
342
343 //=======================================================================
344 //function : UPeriod
345 //purpose  : 
346 //=======================================================================
347
348 Standard_Real GeomAdaptor_SurfaceOfRevolution::UPeriod() const
349 {
350   return 2*M_PI;
351 }
352
353 //=======================================================================
354 //function : IsVPeriodic
355 //purpose  : 
356 //=======================================================================
357
358 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVPeriodic() const
359 {
360   return myBasisCurve->IsPeriodic();
361 }
362
363 //=======================================================================
364 //function : VPeriod
365 //purpose  : 
366 //=======================================================================
367
368 Standard_Real GeomAdaptor_SurfaceOfRevolution::VPeriod() const 
369 {
370   return myBasisCurve->Period();
371 }
372
373 //=======================================================================
374 //function : UResolution
375 //purpose  : 
376 //=======================================================================
377
378 Standard_Real GeomAdaptor_SurfaceOfRevolution::UResolution
379 (const Standard_Real R3d) const 
380 {
381   return Precision::Parametric(R3d);
382 }
383
384 //=======================================================================
385 //function : VResolution
386 //purpose  : 
387 //=======================================================================
388
389 Standard_Real GeomAdaptor_SurfaceOfRevolution::VResolution
390 (const Standard_Real R3d) const 
391 {
392   return myBasisCurve->Resolution(R3d);
393 }
394
395 //=======================================================================
396 //function : GetType
397 //purpose  : 
398 //=======================================================================
399
400 GeomAbs_SurfaceType GeomAdaptor_SurfaceOfRevolution::GetType() const 
401 {
402   Standard_Real TolConf = Precision::Confusion();
403   Standard_Real TolAng  = Precision::Angular();
404   Standard_Real TolConeSemiAng = Precision::Confusion();
405
406   switch (myBasisCurve->GetType()) {
407   case GeomAbs_Line:    {
408     gp_Ax1 Axe = myBasisCurve->Line().Position();
409     
410     if (myAxis.IsParallel(Axe, TolAng))
411     {
412       gp_Pnt P = Value(0., 0.);
413       Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
414       if (R > TolConf)
415       {
416         return GeomAbs_Cylinder;
417       }
418     }
419     else if (myAxis.IsNormal(Axe, TolAng))
420       return GeomAbs_Plane;
421     else
422     {
423       Standard_Real uf = myBasisCurve->FirstParameter();
424       Standard_Real ul = myBasisCurve->LastParameter();
425       Standard_Boolean istrim = (!Precision::IsInfinite(uf) && 
426                                  !Precision::IsInfinite(ul));
427       if(istrim)
428       {
429         gp_Pnt pf = myBasisCurve->Value(uf);
430         gp_Pnt pl = myBasisCurve->Value(ul);
431         Standard_Real len = pf.Distance(pl);
432         //on calcule la distance projetee sur l axe.
433         gp_Vec vlin(pf,pl);
434         gp_Vec vaxe(myAxis.Direction());
435         Standard_Real projlen = Abs(vaxe.Dot(vlin));
436         if ((len - projlen) <= TolConf)
437         {
438           gp_Pnt P = Value(0., 0.);
439           Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
440           if (R > TolConf)
441           {
442             return GeomAbs_Cylinder;
443           }
444         }
445         else if (projlen <= TolConf)
446           return GeomAbs_Plane;
447       }
448       gp_Vec V(myAxis.Location(), myBasisCurve->Line().Location());
449       gp_Vec W(Axe.Direction());
450       gp_Vec AxisDir(myAxis.Direction());
451       Standard_Real proj = Abs(W.Dot(AxisDir));
452       if (Abs(V.DotCross(AxisDir, W)) <= TolConf &&
453         (proj >= TolConeSemiAng && proj <= 1. - TolConeSemiAng))
454       {
455         return GeomAbs_Cone;
456       }
457     }
458     break;
459   }//case GeomAbs_Line: 
460   //
461   case GeomAbs_Circle:   {
462     Standard_Real MajorRadius, aR;
463     gp_Lin aLin(myAxis);
464     //
465     gp_Circ C = myBasisCurve->Circle();
466     const gp_Pnt& aLC = C.Location();
467     aR=C.Radius();
468     //
469    
470     if (!C.Position().IsCoplanar(myAxis, TolConf, TolAng))
471       return GeomAbs_SurfaceOfRevolution;
472     else if(aLin.Distance(aLC) <= TolConf)
473       return GeomAbs_Sphere;
474     else
475     {
476       MajorRadius = aLin.Distance(aLC);
477       if(MajorRadius > aR)
478       {
479         Standard_Real aT = 0., aDx, dX;
480         gp_Pnt aPx;
481
482         aPx = ElCLib::Value(aT, C);
483         aDx = aLin.Distance(aPx);
484         dX = aDx - MajorRadius - aR;
485         if (dX < 0.)
486           dX = -dX;
487         if (dX < TolConf)
488           return GeomAbs_Torus;
489       }
490     }
491     break;
492   }
493   //  
494   default:
495     break;
496   }
497   
498   return GeomAbs_SurfaceOfRevolution;
499 }
500
501 //=======================================================================
502 //function : Plane
503 //purpose  : 
504 //=======================================================================
505
506 gp_Pln GeomAdaptor_SurfaceOfRevolution::Plane() const 
507
508   Standard_NoSuchObject_Raise_if
509     (GetType() != GeomAbs_Plane, "GeomAdaptor_SurfaceOfRevolution:Plane");
510
511   gp_Ax3 Axe = myAxeRev;
512   gp_Pnt aPonCurve = Value(0., 0.);
513   Standard_Real aDot = (aPonCurve.XYZ() - myAxis.Location().XYZ()).Dot(myAxis.Direction().XYZ());
514
515   gp_Pnt P(myAxis.Location().XYZ() + aDot * myAxis.Direction().XYZ());
516   Axe.SetLocation(P);
517   if (Axe.XDirection().Dot(myBasisCurve->Line().Direction()) >= -Precision::Confusion())
518     Axe.XReverse();
519
520   return gp_Pln( Axe);
521 }
522
523 //=======================================================================
524 //function : Cylinder
525 //purpose  : 
526 //=======================================================================
527
528 gp_Cylinder GeomAdaptor_SurfaceOfRevolution::Cylinder() const
529 {
530   Standard_NoSuchObject_Raise_if
531     (GetType() != GeomAbs_Cylinder, "GeomAdaptor_SurfaceOfRevolution::Cylinder");
532
533   gp_Pnt P = Value(0., 0.);
534   Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
535   return gp_Cylinder(myAxeRev, R);
536 }
537
538 //=======================================================================
539 //function : Cone
540 //purpose  : 
541 //=======================================================================
542
543 gp_Cone GeomAdaptor_SurfaceOfRevolution::Cone() const
544 {
545   Standard_NoSuchObject_Raise_if
546     ( GetType() != GeomAbs_Cone, "GeomAdaptor_SurfaceOfRevolution:Cone");
547
548   gp_Ax3 Axe = myAxeRev;
549   gp_Dir ldir = (myBasisCurve->Line()).Direction();
550   Standard_Real Angle = (Axe.Direction()).Angle(ldir);
551   gp_Pnt P0 = Value(0., 0.);
552   Standard_Real R = (Axe.Location()).Distance(P0);
553   if ( R >= Precision::Confusion()) {
554     gp_Pnt O = Axe.Location();
555     gp_Vec OP0(O,P0);
556     Standard_Real t = OP0.Dot(Axe.XDirection());
557     t /= ldir.Dot(Axe.XDirection());
558     OP0.Add(-t * gp_Vec(ldir));
559     if ( OP0.Dot(Axe.Direction()) > 0.) Angle = -Angle;
560   }
561   return gp_Cone( Axe, Angle, R);
562 }
563
564
565 //=======================================================================
566 //function : Sphere
567 //purpose  : 
568 //=======================================================================
569
570 gp_Sphere GeomAdaptor_SurfaceOfRevolution::Sphere() const 
571 {
572   Standard_NoSuchObject_Raise_if
573     ( GetType() != GeomAbs_Sphere, "GeomAdaptor_SurfaceOfRevolution:Sphere");
574
575   gp_Circ C = myBasisCurve->Circle();
576   gp_Ax3 Axe = myAxeRev;
577   Axe.SetLocation(C.Location());
578   return gp_Sphere(Axe, C.Radius());
579 }
580
581
582 //=======================================================================
583 //function : Torus
584 //purpose  : 
585 //=======================================================================
586
587 gp_Torus GeomAdaptor_SurfaceOfRevolution::Torus() const 
588 {
589   Standard_NoSuchObject_Raise_if
590     (GetType() != GeomAbs_Torus, "GeomAdaptor_SurfaceOfRevolution:Torus");
591
592   gp_Circ C = myBasisCurve->Circle();
593   Standard_Real MajorRadius = gp_Lin(myAxis).Distance(C.Location());
594   return gp_Torus(myAxeRev, MajorRadius, C.Radius());
595 }
596
597 //=======================================================================
598 //function : VDegree
599 //purpose  : 
600 //=======================================================================
601
602 Standard_Integer GeomAdaptor_SurfaceOfRevolution::VDegree() const 
603 {
604   return myBasisCurve->Degree();
605 }
606
607 //=======================================================================
608 //function : NbVPoles
609 //purpose  : 
610 //=======================================================================
611
612 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVPoles() const
613 {
614   return myBasisCurve->NbPoles();
615 }
616
617 //=======================================================================
618 //function : NbVKnots
619 //purpose  : 
620 //=======================================================================
621
622 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVKnots() const 
623 {
624   throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::NbVKnots");
625 }
626
627
628
629 //=======================================================================
630 //function : IsURational
631 //purpose  : 
632 //=======================================================================
633
634 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsURational() const 
635 {
636   throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::IsURational");
637 }
638
639 //=======================================================================
640 //function : IsVRational
641 //purpose  : 
642 //=======================================================================
643
644 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVRational() const 
645 {
646   throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::IsVRational");
647 }
648
649
650 //=======================================================================
651 //function : Bezier
652 //purpose  : 
653 //=======================================================================
654
655 Handle(Geom_BezierSurface) GeomAdaptor_SurfaceOfRevolution::Bezier() const 
656 {
657   throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::Bezier");
658 }
659
660
661 //=======================================================================
662 //function : BSpline
663 //purpose  : 
664 //=======================================================================
665
666 Handle(Geom_BSplineSurface) GeomAdaptor_SurfaceOfRevolution::BSpline() const 
667 {
668   throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::BSpline");
669 }
670
671 //=======================================================================
672 //function : Axis
673 //purpose  : 
674 //=======================================================================
675
676 const gp_Ax3& GeomAdaptor_SurfaceOfRevolution::Axis() const 
677 {
678   return myAxeRev;
679 }
680
681 //=======================================================================
682 //function : BasisCurve
683 //purpose  : 
684 //=======================================================================
685
686 Handle(Adaptor3d_HCurve) GeomAdaptor_SurfaceOfRevolution::BasisCurve() const 
687 {
688   return myBasisCurve;
689 }