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 throw Standard_ConstructionError("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 (const Standard_Real First, const Standard_Real Last, const Standard_Real Tol) const
273 const Standard_Real Eps = Precision::PConfusion();
274 (void )Eps; (void )First; (void )Last; (void )Tol;
275 Standard_OutOfRange_Raise_if
276 ( Abs(First) > Eps || Abs(Last - 2.*M_PI) > Eps,
277 "GeomAdaptor_SurfaceOfRevolution : UTrim : Parameters out of range");
279 Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
280 GeomAdaptor_SurfaceOfRevolution(myBasisCurve, myAxis));
285 //=======================================================================
288 //=======================================================================
290 Handle(Adaptor3d_HSurface) GeomAdaptor_SurfaceOfRevolution::VTrim
291 (const Standard_Real First,
292 const Standard_Real Last,
293 const Standard_Real Tol) const
295 Handle(Adaptor3d_HCurve) HC = BasisCurve()->Trim(First,Last,Tol);
296 Handle(GeomAdaptor_HSurfaceOfRevolution) HR = new GeomAdaptor_HSurfaceOfRevolution(
297 GeomAdaptor_SurfaceOfRevolution(HC, myAxis));
302 //=======================================================================
303 //function : IsUClosed
305 //=======================================================================
307 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUClosed() const
309 return Standard_True;
312 //=======================================================================
313 //function : IsVClosed
315 //=======================================================================
317 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVClosed() const
319 return myBasisCurve->IsClosed();
322 //=======================================================================
323 //function : IsUPeriodic
325 //=======================================================================
327 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsUPeriodic() const
329 return Standard_True;
332 //=======================================================================
335 //=======================================================================
337 Standard_Real GeomAdaptor_SurfaceOfRevolution::UPeriod() const
342 //=======================================================================
343 //function : IsVPeriodic
345 //=======================================================================
347 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVPeriodic() const
349 return myBasisCurve->IsPeriodic();
352 //=======================================================================
355 //=======================================================================
357 Standard_Real GeomAdaptor_SurfaceOfRevolution::VPeriod() const
359 return myBasisCurve->Period();
362 //=======================================================================
363 //function : UResolution
365 //=======================================================================
367 Standard_Real GeomAdaptor_SurfaceOfRevolution::UResolution
368 (const Standard_Real R3d) const
370 return Precision::Parametric(R3d);
373 //=======================================================================
374 //function : VResolution
376 //=======================================================================
378 Standard_Real GeomAdaptor_SurfaceOfRevolution::VResolution
379 (const Standard_Real R3d) const
381 return myBasisCurve->Resolution(R3d);
384 //=======================================================================
387 //=======================================================================
389 GeomAbs_SurfaceType GeomAdaptor_SurfaceOfRevolution::GetType() const
391 Standard_Real TolConf = Precision::Confusion();
392 Standard_Real TolAng = Precision::Angular();
393 Standard_Real TolConeSemiAng = Precision::Confusion();
395 switch (myBasisCurve->GetType()) {
397 gp_Ax1 Axe = myBasisCurve->Line().Position();
399 if (myAxis.IsParallel(Axe, TolAng))
401 gp_Pnt P = Value(0., 0.);
402 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
405 return GeomAbs_Cylinder;
408 else if (myAxis.IsNormal(Axe, TolAng))
409 return GeomAbs_Plane;
412 Standard_Real uf = myBasisCurve->FirstParameter();
413 Standard_Real ul = myBasisCurve->LastParameter();
414 Standard_Boolean istrim = (!Precision::IsInfinite(uf) &&
415 !Precision::IsInfinite(ul));
418 gp_Pnt pf = myBasisCurve->Value(uf);
419 gp_Pnt pl = myBasisCurve->Value(ul);
420 Standard_Real len = pf.Distance(pl);
421 //on calcule la distance projetee sur l axe.
423 gp_Vec vaxe(myAxis.Direction());
424 Standard_Real projlen = Abs(vaxe.Dot(vlin));
425 if ((len - projlen) <= TolConf)
427 gp_Pnt P = Value(0., 0.);
428 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
431 return GeomAbs_Cylinder;
434 else if (projlen <= TolConf)
435 return GeomAbs_Plane;
437 gp_Vec V(myAxis.Location(), myBasisCurve->Line().Location());
438 gp_Vec W(Axe.Direction());
439 gp_Vec AxisDir(myAxis.Direction());
440 Standard_Real proj = Abs(W.Dot(AxisDir));
441 if (Abs(V.DotCross(AxisDir, W)) <= TolConf &&
442 (proj >= TolConeSemiAng && proj <= 1. - TolConeSemiAng))
448 }//case GeomAbs_Line:
450 case GeomAbs_Circle: {
451 Standard_Real MajorRadius, aR;
454 gp_Circ C = myBasisCurve->Circle();
455 const gp_Pnt& aLC = C.Location();
459 if (!C.Position().IsCoplanar(myAxis, TolConf, TolAng))
460 return GeomAbs_SurfaceOfRevolution;
461 else if(aLin.Distance(aLC) <= TolConf)
462 return GeomAbs_Sphere;
465 MajorRadius = aLin.Distance(aLC);
468 Standard_Real aT = 0., aDx, dX;
471 aPx = ElCLib::Value(aT, C);
472 aDx = aLin.Distance(aPx);
473 dX = aDx - MajorRadius - aR;
477 return GeomAbs_Torus;
487 return GeomAbs_SurfaceOfRevolution;
490 //=======================================================================
493 //=======================================================================
495 gp_Pln GeomAdaptor_SurfaceOfRevolution::Plane() const
497 Standard_NoSuchObject_Raise_if
498 (GetType() != GeomAbs_Plane, "GeomAdaptor_SurfaceOfRevolution:Plane");
500 gp_Ax3 Axe = myAxeRev;
501 gp_Pnt aPonCurve = Value(0., 0.);
502 Standard_Real aDot = (aPonCurve.XYZ() - myAxis.Location().XYZ()).Dot(myAxis.Direction().XYZ());
504 gp_Pnt P(myAxis.Location().XYZ() + aDot * myAxis.Direction().XYZ());
506 if (Axe.XDirection().Dot(myBasisCurve->Line().Direction()) >= -Precision::Confusion())
512 //=======================================================================
513 //function : Cylinder
515 //=======================================================================
517 gp_Cylinder GeomAdaptor_SurfaceOfRevolution::Cylinder() const
519 Standard_NoSuchObject_Raise_if
520 (GetType() != GeomAbs_Cylinder, "GeomAdaptor_SurfaceOfRevolution::Cylinder");
522 gp_Pnt P = Value(0., 0.);
523 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
524 return gp_Cylinder(myAxeRev, R);
527 //=======================================================================
530 //=======================================================================
532 gp_Cone GeomAdaptor_SurfaceOfRevolution::Cone() const
534 Standard_NoSuchObject_Raise_if
535 ( GetType() != GeomAbs_Cone, "GeomAdaptor_SurfaceOfRevolution:Cone");
537 gp_Ax3 Axe = myAxeRev;
538 gp_Dir ldir = (myBasisCurve->Line()).Direction();
539 Standard_Real Angle = (Axe.Direction()).Angle(ldir);
540 gp_Pnt P0 = Value(0., 0.);
541 Standard_Real R = (Axe.Location()).Distance(P0);
542 if ( R >= Precision::Confusion()) {
543 gp_Pnt O = Axe.Location();
545 Standard_Real t = OP0.Dot(Axe.XDirection());
546 t /= ldir.Dot(Axe.XDirection());
547 OP0.Add(-t * gp_Vec(ldir));
548 if ( OP0.Dot(Axe.Direction()) > 0.) Angle = -Angle;
550 return gp_Cone( Axe, Angle, R);
554 //=======================================================================
557 //=======================================================================
559 gp_Sphere GeomAdaptor_SurfaceOfRevolution::Sphere() const
561 Standard_NoSuchObject_Raise_if
562 ( GetType() != GeomAbs_Sphere, "GeomAdaptor_SurfaceOfRevolution:Sphere");
564 gp_Circ C = myBasisCurve->Circle();
565 gp_Ax3 Axe = myAxeRev;
566 Axe.SetLocation(C.Location());
567 return gp_Sphere(Axe, C.Radius());
571 //=======================================================================
574 //=======================================================================
576 gp_Torus GeomAdaptor_SurfaceOfRevolution::Torus() const
578 Standard_NoSuchObject_Raise_if
579 (GetType() != GeomAbs_Torus, "GeomAdaptor_SurfaceOfRevolution:Torus");
581 gp_Circ C = myBasisCurve->Circle();
582 Standard_Real MajorRadius = gp_Lin(myAxis).Distance(C.Location());
583 return gp_Torus(myAxeRev, MajorRadius, C.Radius());
586 //=======================================================================
589 //=======================================================================
591 Standard_Integer GeomAdaptor_SurfaceOfRevolution::VDegree() const
593 return myBasisCurve->Degree();
596 //=======================================================================
597 //function : NbVPoles
599 //=======================================================================
601 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVPoles() const
603 return myBasisCurve->NbPoles();
606 //=======================================================================
607 //function : NbVKnots
609 //=======================================================================
611 Standard_Integer GeomAdaptor_SurfaceOfRevolution::NbVKnots() const
613 throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::NbVKnots");
618 //=======================================================================
619 //function : IsURational
621 //=======================================================================
623 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsURational() const
625 throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::IsURational");
628 //=======================================================================
629 //function : IsVRational
631 //=======================================================================
633 Standard_Boolean GeomAdaptor_SurfaceOfRevolution::IsVRational() const
635 throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::IsVRational");
639 //=======================================================================
642 //=======================================================================
644 Handle(Geom_BezierSurface) GeomAdaptor_SurfaceOfRevolution::Bezier() const
646 throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::Bezier");
650 //=======================================================================
653 //=======================================================================
655 Handle(Geom_BSplineSurface) GeomAdaptor_SurfaceOfRevolution::BSpline() const
657 throw Standard_NoSuchObject("GeomAdaptor_SurfaceOfRevolution::BSpline");
660 //=======================================================================
663 //=======================================================================
665 const gp_Ax3& GeomAdaptor_SurfaceOfRevolution::Axis() const
670 //=======================================================================
671 //function : BasisCurve
673 //=======================================================================
675 Handle(Adaptor3d_HCurve) GeomAdaptor_SurfaceOfRevolution::BasisCurve() const