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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <GeomAdaptor_SurfaceOfRevolution.hxx>
19 #include <Adaptor3d_HCurve.hxx>
21 #include <GeomAdaptor_HSurfaceOfRevolution.hxx>
22 #include <GeomEvaluator_SurfaceOfRevolution.hxx>
23 #include <Standard_NoSuchObject.hxx>
25 //=======================================================================
26 //function : GeomAdaptor_SurfaceOfRevolution
28 //=======================================================================
29 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution()
30 : myHaveAxis(Standard_False)
33 //=======================================================================
34 //function : GeomAdaptor_SurfaceOfRevolution
36 //=======================================================================
38 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution(
39 const Handle(Adaptor3d_HCurve)& C)
40 : myHaveAxis(Standard_False)
45 //=======================================================================
46 //function : GeomAdaptor_SurfaceOfRevolution
48 //=======================================================================
50 GeomAdaptor_SurfaceOfRevolution::GeomAdaptor_SurfaceOfRevolution(
51 const Handle(Adaptor3d_HCurve)& C,
53 : myHaveAxis(Standard_False)
59 //=======================================================================
62 //=======================================================================
64 void GeomAdaptor_SurfaceOfRevolution::Load(const Handle(Adaptor3d_HCurve)& C)
68 Load(myAxis); // to evaluate the new myAxeRev.
71 //=======================================================================
74 //=======================================================================
76 void GeomAdaptor_SurfaceOfRevolution::Load(const gp_Ax1& V)
78 myHaveAxis = Standard_True;
81 mySurfaceType = GeomAbs_SurfaceOfRevolution;
82 myNestedEvaluator = new GeomEvaluator_SurfaceOfRevolution(myBasisCurve,
83 myAxis.Direction(), myAxis.Location());
85 // Eval myAxeRev : axe of revolution ( Determination de Ox).
87 gp_Pnt O = myAxis.Location();
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.){
98 if (myBasisCurve->GetType() == GeomAbs_Circle) {
99 Q = P = (myBasisCurve->Circle()).Location();
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());
110 else if (Precision::IsInfinite(First))
113 Q = Value( 0., First);
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());
122 Standard_Real First = myBasisCurve->FirstParameter();
123 Standard_Real Last = myBasisCurve->LastParameter();
124 Standard_Integer Ratio = 1;
128 PP = myBasisCurve->Value(First+(Last-First)/Ratio);
129 Dist = gp_Lin(myAxis).Distance(PP);
132 while ( Dist < Precision::Confusion() && Ratio < 100);
134 if ( Ratio >= 100 ) {
135 Standard_ConstructionError::Raise("Adaptor3d_SurfaceOfRevolution : Axe and meridian are confused");
137 Ox = ( (Oz^gp_Vec(PP.XYZ()-O.XYZ()))^Oz);
140 myAxeRev = gp_Ax3(O,Oz,Ox);
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();
151 //=======================================================================
152 //function : AxeOfRevolution
154 //=======================================================================
156 gp_Ax1 GeomAdaptor_SurfaceOfRevolution::AxeOfRevolution() const
161 //=======================================================================
162 //function : FirstUParameter
164 //=======================================================================
166 Standard_Real GeomAdaptor_SurfaceOfRevolution::FirstUParameter() const
171 //=======================================================================
172 //function : LastUParameter
174 //=======================================================================
176 Standard_Real GeomAdaptor_SurfaceOfRevolution::LastUParameter() const
181 //=======================================================================
182 //function : FirstVParameter
184 //=======================================================================
186 Standard_Real GeomAdaptor_SurfaceOfRevolution::FirstVParameter() const
188 return myBasisCurve->FirstParameter();
191 //=======================================================================
192 //function : LastVParameter
194 //=======================================================================
196 Standard_Real GeomAdaptor_SurfaceOfRevolution::LastVParameter() const
198 return myBasisCurve->LastParameter();
201 //=======================================================================
202 //function : UContinuity
204 //=======================================================================
206 GeomAbs_Shape GeomAdaptor_SurfaceOfRevolution::UContinuity() const
211 //=======================================================================
212 //function : VContinuity
214 //=======================================================================
216 GeomAbs_Shape GeomAdaptor_SurfaceOfRevolution::VContinuity() const
218 return myBasisCurve->Continuity();
221 //=======================================================================
222 //function : NbUIntervals
224 //=======================================================================
226 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbUIntervals(const GeomAbs_Shape ) const
231 //=======================================================================
232 //function : NbVIntervals
234 //=======================================================================
236 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVIntervals(const GeomAbs_Shape S) const
238 return myBasisCurve->NbIntervals(S);
241 //=======================================================================
242 //function : UIntervals
244 //=======================================================================
246 void GeomAdaptor_SurfaceOfRevolution::UIntervals(TColStd_Array1OfReal& T,
247 const GeomAbs_Shape ) const
250 T(T.Lower()+1) = 2*M_PI;
254 //=======================================================================
255 //function : VIntervals
257 //=======================================================================
259 void GeomAdaptor_SurfaceOfRevolution::VIntervals(TColStd_Array1OfReal& T,
260 const GeomAbs_Shape S) const
262 myBasisCurve->Intervals(T,S);
266 //=======================================================================
269 //=======================================================================
271 Handle(Adaptor3d_HSurface) GeomAdaptor_SurfaceOfRevolution::UTrim
284 Standard_Real Eps = Precision::PConfusion();
286 Standard_OutOfRange_Raise_if
287 ( Abs(First) > Eps || Abs(Last - 2.*M_PI) > Eps,
288 "GeomAdaptor_SurfaceOfRevolution : UTrim : Parameters out of range");
290 Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
291 GeomAdaptor_SurfaceOfRevolution(myBasisCurve, myAxis));
296 //=======================================================================
299 //=======================================================================
301 Handle(Adaptor3d_HSurface) GeomAdaptor_SurfaceOfRevolution::VTrim
302 (const Standard_Real First,
303 const Standard_Real Last,
304 const Standard_Real Tol) const
306 Handle(Adaptor3d_HCurve) HC = BasisCurve()->Trim(First,Last,Tol);
307 Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
308 GeomAdaptor_SurfaceOfRevolution(HC, myAxis));
313 //=======================================================================
314 //function : IsUClosed
316 //=======================================================================
318 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUClosed() const
320 return Standard_True;
323 //=======================================================================
324 //function : IsVClosed
326 //=======================================================================
328 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVClosed() const
330 return myBasisCurve->IsClosed();
333 //=======================================================================
334 //function : IsUPeriodic
336 //=======================================================================
338 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUPeriodic() const
340 return Standard_True;
343 //=======================================================================
346 //=======================================================================
348 Standard_Real GeomAdaptor_SurfaceOfRevolution::UPeriod() const
353 //=======================================================================
354 //function : IsVPeriodic
356 //=======================================================================
358 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVPeriodic() const
360 return myBasisCurve->IsPeriodic();
363 //=======================================================================
366 //=======================================================================
368 Standard_Real GeomAdaptor_SurfaceOfRevolution::VPeriod() const
370 return myBasisCurve->Period();
373 //=======================================================================
374 //function : UResolution
376 //=======================================================================
378 Standard_Real GeomAdaptor_SurfaceOfRevolution::UResolution
379 (const Standard_Real R3d) const
381 return Precision::Parametric(R3d);
384 //=======================================================================
385 //function : VResolution
387 //=======================================================================
389 Standard_Real GeomAdaptor_SurfaceOfRevolution::VResolution
390 (const Standard_Real R3d) const
392 return myBasisCurve->Resolution(R3d);
395 //=======================================================================
398 //=======================================================================
400 GeomAbs_SurfaceType GeomAdaptor_SurfaceOfRevolution::GetType() const
402 Standard_Real TolConf = Precision::Confusion();
403 Standard_Real TolAng = Precision::Angular();
405 switch (myBasisCurve->GetType()) {
407 gp_Ax1 Axe = myBasisCurve->Line().Position();
409 if (myAxis.IsParallel(Axe, TolAng))
410 return GeomAbs_Cylinder;
411 else if (myAxis.IsNormal(Axe, TolAng))
412 return GeomAbs_Plane;
415 Standard_Real uf = myBasisCurve->FirstParameter();
416 Standard_Real ul = myBasisCurve->LastParameter();
417 Standard_Boolean istrim = (!Precision::IsInfinite(uf) &&
418 !Precision::IsInfinite(ul));
421 gp_Pnt pf = myBasisCurve->Value(uf);
422 gp_Pnt pl = myBasisCurve->Value(ul);
423 Standard_Real len = pf.Distance(pl);
424 //on calcule la distance projetee sur l axe.
426 gp_Vec vaxe(myAxis.Direction());
427 Standard_Real projlen = Abs(vaxe.Dot(vlin));
428 Standard_Real aTolConf = len*TolAng;
429 if ((len - projlen) <= aTolConf)
430 return GeomAbs_Cylinder;
431 else if (projlen <= aTolConf)
432 return GeomAbs_Plane;
434 gp_Vec V(myAxis.Location(), myBasisCurve->Line().Location());
435 gp_Vec W(Axe.Direction());
436 if (Abs(V.DotCross(myAxis.Direction(), W)) <= TolConf)
440 }//case GeomAbs_Line:
442 case GeomAbs_Circle: {
443 Standard_Real MajorRadius, aR;
446 gp_Circ C = myBasisCurve->Circle();
447 const gp_Pnt& aLC = C.Location();
451 if (!C.Position().IsCoplanar(myAxis, TolConf, TolAng))
452 return GeomAbs_SurfaceOfRevolution;
453 else if(aLin.Distance(aLC) <= TolConf)
454 return GeomAbs_Sphere;
457 MajorRadius = aLin.Distance(aLC);
460 Standard_Real aT = 0., aDx, dX;
463 aPx = ElCLib::Value(aT, C);
464 aDx = aLin.Distance(aPx);
465 dX = aDx - MajorRadius - aR;
469 return GeomAbs_Torus;
479 return GeomAbs_SurfaceOfRevolution;
482 //=======================================================================
485 //=======================================================================
487 gp_Pln GeomAdaptor_SurfaceOfRevolution::Plane() const
489 Standard_NoSuchObject_Raise_if
490 (GetType() != GeomAbs_Plane, "GeomAdaptor_SurfaceOfRevolution:Plane");
492 gp_Ax3 Axe = myAxeRev;
493 gp_Pnt aPonCurve = Value(0., 0.);
494 Standard_Real aDot = (aPonCurve.XYZ() - myAxis.Location().XYZ()).Dot(myAxis.Direction().XYZ());
496 gp_Pnt P(myAxis.Location().XYZ() + aDot * myAxis.Direction().XYZ());
498 if (Axe.XDirection().Dot(myBasisCurve->Line().Direction()) >= -Precision::Confusion())
504 //=======================================================================
505 //function : Cylinder
507 //=======================================================================
509 gp_Cylinder GeomAdaptor_SurfaceOfRevolution::Cylinder() const
511 Standard_NoSuchObject_Raise_if
512 (GetType() != GeomAbs_Cylinder, "GeomAdaptor_SurfaceOfRevolution::Cylinder");
514 gp_Pnt P = Value(0., 0.);
515 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
516 return gp_Cylinder(myAxeRev, R);
519 //=======================================================================
522 //=======================================================================
524 gp_Cone GeomAdaptor_SurfaceOfRevolution::Cone() const
526 Standard_NoSuchObject_Raise_if
527 ( GetType() != GeomAbs_Cone, "GeomAdaptor_SurfaceOfRevolution:Cone");
529 gp_Ax3 Axe = myAxeRev;
530 gp_Dir ldir = (myBasisCurve->Line()).Direction();
531 Standard_Real Angle = (Axe.Direction()).Angle(ldir);
532 gp_Pnt P0 = Value(0., 0.);
533 Standard_Real R = (Axe.Location()).Distance(P0);
534 if ( R >= Precision::Confusion()) {
535 gp_Pnt O = Axe.Location();
537 Standard_Real t = OP0.Dot(Axe.XDirection());
538 t /= ldir.Dot(Axe.XDirection());
539 OP0.Add(-t * gp_Vec(ldir));
540 if ( OP0.Dot(Axe.Direction()) > 0.) Angle = -Angle;
542 return gp_Cone( Axe, Angle, R);
546 //=======================================================================
549 //=======================================================================
551 gp_Sphere GeomAdaptor_SurfaceOfRevolution::Sphere() const
553 Standard_NoSuchObject_Raise_if
554 ( GetType() != GeomAbs_Sphere, "GeomAdaptor_SurfaceOfRevolution:Sphere");
556 gp_Circ C = myBasisCurve->Circle();
557 gp_Ax3 Axe = myAxeRev;
558 Axe.SetLocation(C.Location());
559 return gp_Sphere(Axe, C.Radius());
563 //=======================================================================
566 //=======================================================================
568 gp_Torus GeomAdaptor_SurfaceOfRevolution::Torus() const
570 Standard_NoSuchObject_Raise_if
571 (GetType() != GeomAbs_Torus, "GeomAdaptor_SurfaceOfRevolution:Torus");
573 gp_Circ C = myBasisCurve->Circle();
574 Standard_Real MajorRadius = gp_Lin(myAxis).Distance(C.Location());
575 return gp_Torus(myAxeRev, MajorRadius, C.Radius());
578 //=======================================================================
581 //=======================================================================
583 Standard_Integer GeomAdaptor_SurfaceOfRevolution::VDegree() const
585 return myBasisCurve->Degree();
588 //=======================================================================
589 //function : NbVPoles
591 //=======================================================================
593 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVPoles() const
595 return myBasisCurve->NbPoles();
598 //=======================================================================
599 //function : NbVKnots
601 //=======================================================================
603 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVKnots() const
605 Standard_NoSuchObject::Raise("GeomAdaptor_SurfaceOfRevolution::NbVKnots");
611 //=======================================================================
612 //function : IsURational
614 //=======================================================================
616 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsURational() const
618 Standard_NoSuchObject::Raise("GeomAdaptor_SurfaceOfRevolution::IsURational");
619 return Standard_False;
622 //=======================================================================
623 //function : IsVRational
625 //=======================================================================
627 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVRational() const
629 Standard_NoSuchObject::Raise("GeomAdaptor_SurfaceOfRevolution::IsVRational");
630 return Standard_False;
634 //=======================================================================
637 //=======================================================================
639 Handle(Geom_BezierSurface) GeomAdaptor_SurfaceOfRevolution::Bezier() const
641 Standard_NoSuchObject::Raise("GeomAdaptor_SurfaceOfRevolution::Bezier");
642 return Handle(Geom_BezierSurface)();
646 //=======================================================================
649 //=======================================================================
651 Handle(Geom_BSplineSurface) GeomAdaptor_SurfaceOfRevolution::BSpline() const
653 Standard_NoSuchObject::Raise("GeomAdaptor_SurfaceOfRevolution::BSpline");
654 return Handle(Geom_BSplineSurface)();
657 //=======================================================================
660 //=======================================================================
662 const gp_Ax3& GeomAdaptor_SurfaceOfRevolution::Axis() const
667 //=======================================================================
668 //function : BasisCurve
670 //=======================================================================
672 Handle(Adaptor3d_HCurve) GeomAdaptor_SurfaceOfRevolution::BasisCurve() const