1 // Created on: 1993-04-21
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <Adaptor3d_SurfaceOfRevolution.ixx>
24 #include <Adaptor3d_HSurfaceOfRevolution.hxx>
26 #include <Precision.hxx>
27 #include <Standard_ConstructionError.hxx>
29 //=======================================================================
30 //function : Adaptor3d_SurfaceOfRevolution
32 //=======================================================================
34 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution()
35 :myHaveAxis(Standard_False)
38 //=======================================================================
39 //function : Adaptor3d_SurfaceOfRevolution
41 //=======================================================================
43 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution
44 (const Handle(Adaptor3d_HCurve)& C)
45 :myHaveAxis(Standard_False)
50 //=======================================================================
51 //function : Adaptor3d_SurfaceOfRevolution
53 //=======================================================================
55 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution
56 (const Handle(Adaptor3d_HCurve)& C,
58 :myHaveAxis(Standard_False)
64 //=======================================================================
67 //=======================================================================
69 void Adaptor3d_SurfaceOfRevolution::Load( const Handle(Adaptor3d_HCurve)& C)
72 if ( myHaveAxis) Load(myAxis); // to evaluate the new myAxeRev.
75 //=======================================================================
78 //=======================================================================
80 void Adaptor3d_SurfaceOfRevolution::Load( const gp_Ax1& V)
82 myHaveAxis = Standard_True;
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
136 ("Adaptor3d_SurfaceOfRevolution : Axe and meridian are confused");
138 Ox = ( (Oz^gp_Vec(PP.XYZ()-O.XYZ()))^Oz);
141 myAxeRev = gp_Ax3(O,Oz,Ox);
146 else if (myBasisCurve->GetType() == GeomAbs_Circle) {
147 gp_Dir DC = (myBasisCurve->Circle()).Axis().Direction();
148 if ((Ox.Crossed(Oz)).Dot(DC) < 0.) myAxeRev.ZReverse();
152 //=======================================================================
153 //function : AxeOfRevolution
155 //=======================================================================
157 gp_Ax1 Adaptor3d_SurfaceOfRevolution::AxeOfRevolution() const
162 //=======================================================================
163 //function : FirstUParameter
165 //=======================================================================
167 Standard_Real Adaptor3d_SurfaceOfRevolution::FirstUParameter() const
172 //=======================================================================
173 //function : LastUParameter
175 //=======================================================================
177 Standard_Real Adaptor3d_SurfaceOfRevolution::LastUParameter() const
182 //=======================================================================
183 //function : FirstVParameter
185 //=======================================================================
187 Standard_Real Adaptor3d_SurfaceOfRevolution::FirstVParameter() const
189 return myBasisCurve->FirstParameter();
192 //=======================================================================
193 //function : LastVParameter
195 //=======================================================================
197 Standard_Real Adaptor3d_SurfaceOfRevolution::LastVParameter() const
199 return myBasisCurve->LastParameter();
202 //=======================================================================
203 //function : UContinuity
205 //=======================================================================
207 GeomAbs_Shape Adaptor3d_SurfaceOfRevolution::UContinuity() const
212 //=======================================================================
213 //function : VContinuity
215 //=======================================================================
217 GeomAbs_Shape Adaptor3d_SurfaceOfRevolution::VContinuity() const
219 return myBasisCurve->Continuity();
222 //=======================================================================
223 //function : NbUIntervals
225 //=======================================================================
227 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUIntervals
228 //(const GeomAbs_Shape S) const
229 (const GeomAbs_Shape ) const
234 //=======================================================================
235 //function : NbVIntervals
237 //=======================================================================
239 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVIntervals
240 ( const GeomAbs_Shape S) const
242 return myBasisCurve->NbIntervals(S);
245 //=======================================================================
246 //function : UIntervals
248 //=======================================================================
250 void Adaptor3d_SurfaceOfRevolution::UIntervals (TColStd_Array1OfReal& T,
251 // const GeomAbs_Shape S) const
252 const GeomAbs_Shape ) const
255 T(T.Lower()+1) = 2*M_PI;
259 //=======================================================================
260 //function : VIntervals
262 //=======================================================================
264 void Adaptor3d_SurfaceOfRevolution::VIntervals(TColStd_Array1OfReal& T,
265 const GeomAbs_Shape S) const
267 myBasisCurve->Intervals(T,S);
271 //=======================================================================
274 //=======================================================================
276 Handle(Adaptor3d_HSurface) Adaptor3d_SurfaceOfRevolution::UTrim
289 Standard_Real Eps = Precision::PConfusion();
291 Standard_OutOfRange_Raise_if
292 ( Abs(First) > Eps || Abs(Last - 2.*M_PI) > Eps,
293 "Adaptor3d_SurfaceOfRevolution : UTrim : Parameters out of range");
295 Handle(Adaptor3d_HSurfaceOfRevolution) HR =
296 new Adaptor3d_HSurfaceOfRevolution(*this);
301 //=======================================================================
304 //=======================================================================
306 Handle(Adaptor3d_HSurface) Adaptor3d_SurfaceOfRevolution::VTrim
307 (const Standard_Real First,
308 const Standard_Real Last,
309 const Standard_Real Tol) const
311 Handle(Adaptor3d_HSurfaceOfRevolution) HR =
312 new Adaptor3d_HSurfaceOfRevolution(*this);
313 Handle(Adaptor3d_HCurve) HC = BasisCurve()->Trim(First,Last,Tol);
320 //=======================================================================
321 //function : IsUClosed
323 //=======================================================================
325 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsUClosed() const
327 return Standard_True;
330 //=======================================================================
331 //function : IsVClosed
333 //=======================================================================
335 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVClosed() const
337 return myBasisCurve->IsClosed();
340 //=======================================================================
341 //function : IsUPeriodic
343 //=======================================================================
345 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsUPeriodic() const
347 return Standard_True;
350 //=======================================================================
353 //=======================================================================
355 Standard_Real Adaptor3d_SurfaceOfRevolution::UPeriod() const
360 //=======================================================================
361 //function : IsVPeriodic
363 //=======================================================================
365 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVPeriodic() const
367 return myBasisCurve->IsPeriodic();
370 //=======================================================================
373 //=======================================================================
375 Standard_Real Adaptor3d_SurfaceOfRevolution::VPeriod() const
377 return myBasisCurve->Period();
380 //=======================================================================
383 //=======================================================================
385 gp_Pnt Adaptor3d_SurfaceOfRevolution::Value(const Standard_Real U,
386 const Standard_Real V) const
389 myBasisCurve->D0(V,P);
390 P.Rotate( myAxis, U);
394 //=======================================================================
397 //=======================================================================
399 void Adaptor3d_SurfaceOfRevolution::D0(const Standard_Real U,
400 const Standard_Real V,
403 myBasisCurve->D0(V,P);
404 P.Rotate( myAxis, U);
407 //=======================================================================
410 //=======================================================================
412 void Adaptor3d_SurfaceOfRevolution::D1(const Standard_Real U,
413 const Standard_Real V,
414 gp_Pnt& P, gp_Vec& D1U,
417 myBasisCurve->D1(V,P,D1V);
418 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
421 D1V.Rotate( myAxis, U);
422 D1U = R*(myAxeRev.YDirection());
423 D1U.Rotate( myAxis, U);
426 //=======================================================================
429 //=======================================================================
431 void Adaptor3d_SurfaceOfRevolution::D2(const Standard_Real U,
432 const Standard_Real V,
433 gp_Pnt& P, gp_Vec& D1U,
435 gp_Vec& D2U, gp_Vec& D2V,
438 myBasisCurve->D2(V,P,D1V,D2V);
440 gp_Vec D1 = (myAxeRev.YDirection()).Rotated( myAxis, U);
441 gp_Vec D2 = (myAxeRev.XDirection()).Rotated( myAxis, U);
443 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
444 Standard_Real D1R = D1V * myAxeRev.XDirection(); // D1R = dR/dV
445 // et R=AP*XDirection
448 D1V.Rotate( myAxis, U);
449 D2V.Rotate( myAxis, U);
455 //=======================================================================
458 //=======================================================================
460 void Adaptor3d_SurfaceOfRevolution::D3(const Standard_Real U,
461 const Standard_Real V,
462 gp_Pnt& P,gp_Vec& D1U, gp_Vec& D1V,
463 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
464 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV,
467 myBasisCurve->D3(V,P,D1V,D2V,D3V);
469 gp_Vec D1 = (myAxeRev.YDirection()).Rotated( myAxis, U);
470 gp_Vec D2 = (myAxeRev.XDirection()).Rotated( myAxis, U);
472 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
473 Standard_Real D1R = D1V * myAxeRev.XDirection(); // D1R = dR/dV et
475 Standard_Real D2R = D2V * myAxeRev.XDirection();
478 D1V.Rotate( myAxis, U);
479 D2V.Rotate( myAxis, U);
480 D3V.Rotate( myAxis, U);
489 //=======================================================================
492 //=======================================================================
494 gp_Vec Adaptor3d_SurfaceOfRevolution::DN(const Standard_Real U,
495 const Standard_Real V,
496 const Standard_Integer NU,
497 const Standard_Integer NV) const
499 if ( (NU+NV)<1 || NU<0 || NV<0) {
500 Standard_DomainError::Raise("Adaptor3d_SurfaceOfRevolution::DN");
503 gp_Vec DNv = myBasisCurve->DN( V, NV);
505 return DNv.Rotated( myAxis, U);
508 Standard_Real DNR = DNv * myAxeRev.XDirection();
509 gp_Vec DNu = ( myAxeRev.XDirection()).Rotated( myAxis, U + NU*M_PI/2);
517 //=======================================================================
518 //function : UResolution
520 //=======================================================================
522 Standard_Real Adaptor3d_SurfaceOfRevolution::UResolution
523 (const Standard_Real R3d) const
525 return Precision::Parametric(R3d);
528 //=======================================================================
529 //function : VResolution
531 //=======================================================================
533 Standard_Real Adaptor3d_SurfaceOfRevolution::VResolution
534 (const Standard_Real R3d) const
536 return myBasisCurve->Resolution(R3d);
539 //=======================================================================
542 //=======================================================================
544 GeomAbs_SurfaceType Adaptor3d_SurfaceOfRevolution::GetType() const
546 Standard_Real TolConf, TolAng;
547 GeomAbs_SurfaceType bRet;
549 bRet=GeomAbs_SurfaceOfRevolution;
550 TolConf = Precision::Confusion();
551 TolAng = Precision::Angular();
553 switch ( myBasisCurve->GetType()) {
555 const gp_Ax1& Axe = (myBasisCurve->Line()).Position();
557 if (myAxis.IsParallel(Axe, TolAng)) {
558 bRet=GeomAbs_Cylinder;
561 else if (myAxis.IsNormal( Axe, TolAng)) {
566 Standard_Real uf = myBasisCurve->FirstParameter();
567 Standard_Real ul = myBasisCurve->LastParameter();
568 Standard_Boolean istrim = (!Precision::IsInfinite(uf) &&
569 !Precision::IsInfinite(ul));
571 gp_Pnt pf = myBasisCurve->Value(uf);
572 gp_Pnt pl = myBasisCurve->Value(ul);
573 Standard_Real len = pf.Distance(pl);
574 //on calcule la distance projetee sur l axe.
576 gp_Vec vaxe(myAxis.Direction());
577 Standard_Real projlen = Abs(vaxe.Dot(vlin));
578 Standard_Real aTolConf = len*TolAng;
579 if ((len - projlen) <= aTolConf) {
580 bRet=GeomAbs_Cylinder;
583 else if (projlen <= aTolConf) {
588 gp_Vec V(myAxis.Location(),
589 myBasisCurve->Line().Location());
590 gp_Vec W(Axe.Direction());
591 if (Abs(V.DotCross(myAxis.Direction(),W)) <= TolConf){
600 }//case GeomAbs_Line:
602 case GeomAbs_Circle: {
604 Standard_Real MajorRadius, aR;
607 const gp_Circ& C=myBasisCurve->Circle();
608 const gp_Pnt& aLC=C.Location();
612 if (!C.Position().IsCoplanar(myAxis, TolConf, TolAng)) {
615 else if(aLin.Distance(aLC) <= TolConf) {
620 MajorRadius = aLin.Distance(aLC);
622 //modified by NIZNHY-PKV Thu Feb 24 09:46:29 2011f
623 Standard_Real aT, aDx, dX;
627 aPx=ElCLib::Value(aT, C);
628 aDx=aLin.Distance(aPx);
629 dX=aDx-MajorRadius-aR;
636 //bRet=GeomAbs_Torus;
638 //modified by NIZNHY-PKV Thu Feb 24 09:52:29 2011t
652 //=======================================================================
655 //=======================================================================
657 gp_Pln Adaptor3d_SurfaceOfRevolution::Plane() const
659 Standard_NoSuchObject_Raise_if
660 (GetType() != GeomAbs_Plane, "Adaptor3d_SurfaceOfRevolution:Plane");
662 gp_Ax3 Axe = myAxeRev;
665 // P = Projection du Point Debut de la generatrice sur l axe de rotation.
666 P.SetXYZ((myAxis.Location()).XYZ() +
667 (Value(0.,0.).XYZ()-(myAxis.Location()).XYZ()).
668 Dot((myAxis.Direction()).XYZ())
669 *(myAxis.Direction()).XYZ());
671 //// modified by jgv, 8.01.03 for OCC1226 ////
672 if (Axe.XDirection().
673 Dot(myBasisCurve->Line().Direction()) >= -Precision::Confusion()) // > 0.
675 //////////////////////////////////////////////
680 //=======================================================================
681 //function : Cylinder
683 //=======================================================================
685 gp_Cylinder Adaptor3d_SurfaceOfRevolution::Cylinder() const
687 Standard_NoSuchObject_Raise_if
688 (GetType() != GeomAbs_Cylinder, "Adaptor3d_SurfaceOfRevolution::Cylinder");
690 gp_Pnt P = Value( 0., 0.);
691 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
692 return gp_Cylinder( myAxeRev, R);
695 //=======================================================================
698 //=======================================================================
700 gp_Cone Adaptor3d_SurfaceOfRevolution::Cone() const
702 Standard_NoSuchObject_Raise_if
703 ( GetType() != GeomAbs_Cone, "Adaptor3d_SurfaceOfRevolution:Cone");
705 gp_Ax3 Axe = myAxeRev;
706 gp_Dir ldir = (myBasisCurve->Line()).Direction();
707 Standard_Real Angle = (Axe.Direction()).Angle(ldir);
708 gp_Pnt P0 = Value(0., 0.);
709 Standard_Real R = (Axe.Location()).Distance(P0);
710 if ( R >= Precision::Confusion()) {
711 gp_Pnt O = Axe.Location();
713 Standard_Real t = OP0.Dot(Axe.XDirection());
714 t /= ldir.Dot(Axe.XDirection());
715 OP0.Add(-t * gp_Vec(ldir));
716 if ( OP0.Dot(Axe.Direction()) > 0.) Angle = -Angle;
718 return gp_Cone( Axe, Angle, R);
722 //=======================================================================
725 //=======================================================================
727 gp_Sphere Adaptor3d_SurfaceOfRevolution::Sphere() const
729 Standard_NoSuchObject_Raise_if
730 ( GetType() != GeomAbs_Sphere, "Adaptor3d_SurfaceOfRevolution:Sphere");
732 gp_Circ C = myBasisCurve->Circle();
733 gp_Ax3 Axe = myAxeRev;
734 Axe.SetLocation( C.Location());
735 return gp_Sphere( Axe, C.Radius());
739 //=======================================================================
742 //=======================================================================
744 gp_Torus Adaptor3d_SurfaceOfRevolution::Torus() const
746 Standard_NoSuchObject_Raise_if
747 (GetType() != GeomAbs_Torus, "Adaptor3d_SurfaceOfRevolution:Torus");
749 gp_Circ C = myBasisCurve->Circle();
750 Standard_Real MajorRadius = gp_Lin(myAxis).Distance(C.Location());
751 return gp_Torus( myAxeRev, MajorRadius, C.Radius());
754 //=======================================================================
757 //=======================================================================
759 Standard_Integer Adaptor3d_SurfaceOfRevolution::UDegree() const
761 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::UDegree");
765 //=======================================================================
766 //function : NbUPoles
768 //=======================================================================
770 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUPoles() const
772 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbUPoles");
776 //=======================================================================
779 //=======================================================================
781 Standard_Integer Adaptor3d_SurfaceOfRevolution::VDegree() const
783 return myBasisCurve->Degree();
786 //=======================================================================
787 //function : NbVPoles
789 //=======================================================================
791 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVPoles() const
793 return myBasisCurve -> NbPoles();
796 //=======================================================================
797 //function : NbUKnots
799 //=======================================================================
801 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUKnots() const
803 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbUKnots");
808 //=======================================================================
809 //function : NbVKnots
811 //=======================================================================
813 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVKnots() const
815 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbVKnots");
821 //=======================================================================
822 //function : IsURational
824 //=======================================================================
826 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsURational() const
828 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::IsURational");
829 return Standard_False;
832 //=======================================================================
833 //function : IsVRational
835 //=======================================================================
837 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVRational() const
839 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::IsVRational");
840 return Standard_False;
844 //=======================================================================
847 //=======================================================================
849 Handle(Geom_BezierSurface) Adaptor3d_SurfaceOfRevolution::Bezier() const
851 Standard_NoSuchObject::Raise("");
852 Handle(Geom_BezierSurface) Dummy;
857 //=======================================================================
860 //=======================================================================
862 Handle(Geom_BSplineSurface) Adaptor3d_SurfaceOfRevolution::BSpline() const
864 Standard_NoSuchObject::Raise("");
865 Handle(Geom_BSplineSurface) Dummy;
870 //=======================================================================
873 //=======================================================================
875 gp_Ax3 Adaptor3d_SurfaceOfRevolution::Axis() const
880 //=======================================================================
881 //function : Direction
883 //=======================================================================
885 gp_Dir Adaptor3d_SurfaceOfRevolution::Direction() const
887 Standard_NoSuchObject::Raise("");
892 //=======================================================================
893 //function : BasisCurve
895 //=======================================================================
897 Handle(Adaptor3d_HCurve) Adaptor3d_SurfaceOfRevolution::BasisCurve() const