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.
18 #include <Adaptor3d_HCurve.hxx>
19 #include <Adaptor3d_HSurface.hxx>
20 #include <Adaptor3d_HSurfaceOfRevolution.hxx>
21 #include <Adaptor3d_SurfaceOfRevolution.hxx>
23 #include <Geom_BezierSurface.hxx>
24 #include <Geom_BSplineSurface.hxx>
27 #include <gp_Cone.hxx>
28 #include <gp_Cylinder.hxx>
32 #include <gp_Sphere.hxx>
33 #include <gp_Torus.hxx>
35 #include <Precision.hxx>
36 #include <Standard_ConstructionError.hxx>
37 #include <Standard_DomainError.hxx>
38 #include <Standard_NoSuchObject.hxx>
39 #include <Standard_OutOfRange.hxx>
41 //=======================================================================
42 //function : Adaptor3d_SurfaceOfRevolution
44 //=======================================================================
45 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution()
46 :myHaveAxis(Standard_False)
49 //=======================================================================
50 //function : Adaptor3d_SurfaceOfRevolution
52 //=======================================================================
54 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution
55 (const Handle(Adaptor3d_HCurve)& C)
56 :myHaveAxis(Standard_False)
61 //=======================================================================
62 //function : Adaptor3d_SurfaceOfRevolution
64 //=======================================================================
66 Adaptor3d_SurfaceOfRevolution::Adaptor3d_SurfaceOfRevolution
67 (const Handle(Adaptor3d_HCurve)& C,
69 :myHaveAxis(Standard_False)
75 //=======================================================================
78 //=======================================================================
80 void Adaptor3d_SurfaceOfRevolution::Load( const Handle(Adaptor3d_HCurve)& C)
83 if ( myHaveAxis) Load(myAxis); // to evaluate the new myAxeRev.
86 //=======================================================================
89 //=======================================================================
91 void Adaptor3d_SurfaceOfRevolution::Load( const gp_Ax1& V)
93 myHaveAxis = Standard_True;
96 // Eval myAxeRev : axe of revolution ( Determination de Ox).
98 gp_Pnt O = myAxis.Location();
100 gp_Dir Oz = myAxis.Direction();
101 Standard_Boolean yrev = Standard_False;
102 if (myBasisCurve->GetType() == GeomAbs_Line) {
103 if((myBasisCurve->Line().Direction()).Dot(Oz) < 0.){
104 yrev = Standard_True;
109 if (myBasisCurve->GetType() == GeomAbs_Circle) {
110 Q = P = (myBasisCurve->Circle()).Location();
113 Standard_Real First = myBasisCurve->FirstParameter();
114 P = Value( 0., 0.);// ce qui ne veut pas dire grand chose
115 if ( GetType() == GeomAbs_Cone) {
116 if ( gp_Lin(myAxis).Distance(P) <= Precision::Confusion())
117 Q = ElCLib::Value(1.,myBasisCurve->Line());
121 else if (Precision::IsInfinite(First))
124 Q = Value( 0., First);
127 gp_Dir DZ = myAxis.Direction();
128 O.SetXYZ( O.XYZ() + ( gp_Vec(O,P) * DZ) * DZ.XYZ());
129 if ( gp_Lin(myAxis).Distance(Q) > Precision::Confusion()) {
130 Ox = gp_Dir(Q.XYZ() - O.XYZ());
133 Standard_Real First = myBasisCurve->FirstParameter();
134 Standard_Real Last = myBasisCurve->LastParameter();
135 Standard_Integer Ratio = 1;
139 PP = myBasisCurve->Value(First+(Last-First)/Ratio);
140 Dist = gp_Lin(myAxis).Distance(PP);
143 while ( Dist < Precision::Confusion() && Ratio < 100);
145 if ( Ratio >= 100 ) {
146 Standard_ConstructionError::Raise
147 ("Adaptor3d_SurfaceOfRevolution : Axe and meridian are confused");
149 Ox = ( (Oz^gp_Vec(PP.XYZ()-O.XYZ()))^Oz);
152 myAxeRev = gp_Ax3(O,Oz,Ox);
157 else if (myBasisCurve->GetType() == GeomAbs_Circle) {
158 gp_Dir DC = (myBasisCurve->Circle()).Axis().Direction();
159 if ((Ox.Crossed(Oz)).Dot(DC) < 0.) myAxeRev.ZReverse();
163 //=======================================================================
164 //function : AxeOfRevolution
166 //=======================================================================
168 gp_Ax1 Adaptor3d_SurfaceOfRevolution::AxeOfRevolution() const
173 //=======================================================================
174 //function : FirstUParameter
176 //=======================================================================
178 Standard_Real Adaptor3d_SurfaceOfRevolution::FirstUParameter() const
183 //=======================================================================
184 //function : LastUParameter
186 //=======================================================================
188 Standard_Real Adaptor3d_SurfaceOfRevolution::LastUParameter() const
193 //=======================================================================
194 //function : FirstVParameter
196 //=======================================================================
198 Standard_Real Adaptor3d_SurfaceOfRevolution::FirstVParameter() const
200 return myBasisCurve->FirstParameter();
203 //=======================================================================
204 //function : LastVParameter
206 //=======================================================================
208 Standard_Real Adaptor3d_SurfaceOfRevolution::LastVParameter() const
210 return myBasisCurve->LastParameter();
213 //=======================================================================
214 //function : UContinuity
216 //=======================================================================
218 GeomAbs_Shape Adaptor3d_SurfaceOfRevolution::UContinuity() const
223 //=======================================================================
224 //function : VContinuity
226 //=======================================================================
228 GeomAbs_Shape Adaptor3d_SurfaceOfRevolution::VContinuity() const
230 return myBasisCurve->Continuity();
233 //=======================================================================
234 //function : NbUIntervals
236 //=======================================================================
238 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUIntervals
239 //(const GeomAbs_Shape S) const
240 (const GeomAbs_Shape ) const
245 //=======================================================================
246 //function : NbVIntervals
248 //=======================================================================
250 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVIntervals
251 ( const GeomAbs_Shape S) const
253 return myBasisCurve->NbIntervals(S);
256 //=======================================================================
257 //function : UIntervals
259 //=======================================================================
261 void Adaptor3d_SurfaceOfRevolution::UIntervals (TColStd_Array1OfReal& T,
262 // const GeomAbs_Shape S) const
263 const GeomAbs_Shape ) const
266 T(T.Lower()+1) = 2*M_PI;
270 //=======================================================================
271 //function : VIntervals
273 //=======================================================================
275 void Adaptor3d_SurfaceOfRevolution::VIntervals(TColStd_Array1OfReal& T,
276 const GeomAbs_Shape S) const
278 myBasisCurve->Intervals(T,S);
282 //=======================================================================
285 //=======================================================================
287 Handle(Adaptor3d_HSurface) Adaptor3d_SurfaceOfRevolution::UTrim
300 Standard_Real Eps = Precision::PConfusion();
302 Standard_OutOfRange_Raise_if
303 ( Abs(First) > Eps || Abs(Last - 2.*M_PI) > Eps,
304 "Adaptor3d_SurfaceOfRevolution : UTrim : Parameters out of range");
306 Handle(Adaptor3d_HSurfaceOfRevolution) HR =
307 new Adaptor3d_HSurfaceOfRevolution(*this);
312 //=======================================================================
315 //=======================================================================
317 Handle(Adaptor3d_HSurface) Adaptor3d_SurfaceOfRevolution::VTrim
318 (const Standard_Real First,
319 const Standard_Real Last,
320 const Standard_Real Tol) const
322 Handle(Adaptor3d_HSurfaceOfRevolution) HR =
323 new Adaptor3d_HSurfaceOfRevolution(*this);
324 Handle(Adaptor3d_HCurve) HC = BasisCurve()->Trim(First,Last,Tol);
331 //=======================================================================
332 //function : IsUClosed
334 //=======================================================================
336 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsUClosed() const
338 return Standard_True;
341 //=======================================================================
342 //function : IsVClosed
344 //=======================================================================
346 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVClosed() const
348 return myBasisCurve->IsClosed();
351 //=======================================================================
352 //function : IsUPeriodic
354 //=======================================================================
356 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsUPeriodic() const
358 return Standard_True;
361 //=======================================================================
364 //=======================================================================
366 Standard_Real Adaptor3d_SurfaceOfRevolution::UPeriod() const
371 //=======================================================================
372 //function : IsVPeriodic
374 //=======================================================================
376 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVPeriodic() const
378 return myBasisCurve->IsPeriodic();
381 //=======================================================================
384 //=======================================================================
386 Standard_Real Adaptor3d_SurfaceOfRevolution::VPeriod() const
388 return myBasisCurve->Period();
391 //=======================================================================
394 //=======================================================================
396 gp_Pnt Adaptor3d_SurfaceOfRevolution::Value(const Standard_Real U,
397 const Standard_Real V) const
400 myBasisCurve->D0(V,P);
401 P.Rotate( myAxis, U);
405 //=======================================================================
408 //=======================================================================
410 void Adaptor3d_SurfaceOfRevolution::D0(const Standard_Real U,
411 const Standard_Real V,
414 myBasisCurve->D0(V,P);
415 P.Rotate( myAxis, U);
418 //=======================================================================
421 //=======================================================================
423 void Adaptor3d_SurfaceOfRevolution::D1(const Standard_Real U,
424 const Standard_Real V,
425 gp_Pnt& P, gp_Vec& D1U,
428 myBasisCurve->D1(V,P,D1V);
429 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
432 D1V.Rotate( myAxis, U);
433 D1U = R*(myAxeRev.YDirection());
434 D1U.Rotate( myAxis, U);
437 //=======================================================================
440 //=======================================================================
442 void Adaptor3d_SurfaceOfRevolution::D2(const Standard_Real U,
443 const Standard_Real V,
444 gp_Pnt& P, gp_Vec& D1U,
446 gp_Vec& D2U, gp_Vec& D2V,
449 myBasisCurve->D2(V,P,D1V,D2V);
451 gp_Vec D1 = (myAxeRev.YDirection()).Rotated( myAxis, U);
452 gp_Vec D2 = (myAxeRev.XDirection()).Rotated( myAxis, U);
454 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
455 Standard_Real D1R = D1V * myAxeRev.XDirection(); // D1R = dR/dV
456 // et R=AP*XDirection
459 D1V.Rotate( myAxis, U);
460 D2V.Rotate( myAxis, U);
466 //=======================================================================
469 //=======================================================================
471 void Adaptor3d_SurfaceOfRevolution::D3(const Standard_Real U,
472 const Standard_Real V,
473 gp_Pnt& P,gp_Vec& D1U, gp_Vec& D1V,
474 gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV,
475 gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV,
478 myBasisCurve->D3(V,P,D1V,D2V,D3V);
480 gp_Vec D1 = (myAxeRev.YDirection()).Rotated( myAxis, U);
481 gp_Vec D2 = (myAxeRev.XDirection()).Rotated( myAxis, U);
483 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
484 Standard_Real D1R = D1V * myAxeRev.XDirection(); // D1R = dR/dV et
486 Standard_Real D2R = D2V * myAxeRev.XDirection();
489 D1V.Rotate( myAxis, U);
490 D2V.Rotate( myAxis, U);
491 D3V.Rotate( myAxis, U);
500 //=======================================================================
503 //=======================================================================
505 gp_Vec Adaptor3d_SurfaceOfRevolution::DN(const Standard_Real U,
506 const Standard_Real V,
507 const Standard_Integer NU,
508 const Standard_Integer NV) const
510 if ( (NU+NV)<1 || NU<0 || NV<0) {
511 Standard_DomainError::Raise("Adaptor3d_SurfaceOfRevolution::DN");
514 gp_Vec DNv = myBasisCurve->DN( V, NV);
516 return DNv.Rotated( myAxis, U);
519 Standard_Real DNR = DNv * myAxeRev.XDirection();
520 gp_Vec DNu = ( myAxeRev.XDirection()).Rotated( myAxis, U + NU*M_PI/2);
528 //=======================================================================
529 //function : UResolution
531 //=======================================================================
533 Standard_Real Adaptor3d_SurfaceOfRevolution::UResolution
534 (const Standard_Real R3d) const
536 return Precision::Parametric(R3d);
539 //=======================================================================
540 //function : VResolution
542 //=======================================================================
544 Standard_Real Adaptor3d_SurfaceOfRevolution::VResolution
545 (const Standard_Real R3d) const
547 return myBasisCurve->Resolution(R3d);
550 //=======================================================================
553 //=======================================================================
555 GeomAbs_SurfaceType Adaptor3d_SurfaceOfRevolution::GetType() const
557 Standard_Real TolConf, TolAng;
558 GeomAbs_SurfaceType bRet;
560 bRet=GeomAbs_SurfaceOfRevolution;
561 TolConf = Precision::Confusion();
562 TolAng = Precision::Angular();
564 switch ( myBasisCurve->GetType()) {
566 const gp_Ax1& Axe = (myBasisCurve->Line()).Position();
568 if (myAxis.IsParallel(Axe, TolAng)) {
569 bRet=GeomAbs_Cylinder;
572 else if (myAxis.IsNormal( Axe, TolAng)) {
577 Standard_Real uf = myBasisCurve->FirstParameter();
578 Standard_Real ul = myBasisCurve->LastParameter();
579 Standard_Boolean istrim = (!Precision::IsInfinite(uf) &&
580 !Precision::IsInfinite(ul));
582 gp_Pnt pf = myBasisCurve->Value(uf);
583 gp_Pnt pl = myBasisCurve->Value(ul);
584 Standard_Real len = pf.Distance(pl);
585 //on calcule la distance projetee sur l axe.
587 gp_Vec vaxe(myAxis.Direction());
588 Standard_Real projlen = Abs(vaxe.Dot(vlin));
589 Standard_Real aTolConf = len*TolAng;
590 if ((len - projlen) <= aTolConf) {
591 bRet=GeomAbs_Cylinder;
594 else if (projlen <= aTolConf) {
599 gp_Vec V(myAxis.Location(),
600 myBasisCurve->Line().Location());
601 gp_Vec W(Axe.Direction());
602 if (Abs(V.DotCross(myAxis.Direction(),W)) <= TolConf){
610 }//case GeomAbs_Line:
612 case GeomAbs_Circle: {
614 Standard_Real MajorRadius, aR;
617 const gp_Circ& C=myBasisCurve->Circle();
618 const gp_Pnt& aLC=C.Location();
622 if (!C.Position().IsCoplanar(myAxis, TolConf, TolAng)) {
625 else if(aLin.Distance(aLC) <= TolConf) {
630 MajorRadius = aLin.Distance(aLC);
632 //modified by NIZNHY-PKV Thu Feb 24 09:46:29 2011f
633 Standard_Real aT, aDx, dX;
637 aPx=ElCLib::Value(aT, C);
638 aDx=aLin.Distance(aPx);
639 dX=aDx-MajorRadius-aR;
646 //bRet=GeomAbs_Torus;
648 //modified by NIZNHY-PKV Thu Feb 24 09:52:29 2011t
661 //=======================================================================
664 //=======================================================================
666 gp_Pln Adaptor3d_SurfaceOfRevolution::Plane() const
668 Standard_NoSuchObject_Raise_if
669 (GetType() != GeomAbs_Plane, "Adaptor3d_SurfaceOfRevolution:Plane");
671 gp_Ax3 Axe = myAxeRev;
674 // P = Projection du Point Debut de la generatrice sur l axe de rotation.
675 P.SetXYZ((myAxis.Location()).XYZ() +
676 (Value(0.,0.).XYZ()-(myAxis.Location()).XYZ()).
677 Dot((myAxis.Direction()).XYZ())
678 *(myAxis.Direction()).XYZ());
680 //// modified by jgv, 8.01.03 for OCC1226 ////
681 if (Axe.XDirection().
682 Dot(myBasisCurve->Line().Direction()) >= -Precision::Confusion()) // > 0.
684 //////////////////////////////////////////////
689 //=======================================================================
690 //function : Cylinder
692 //=======================================================================
694 gp_Cylinder Adaptor3d_SurfaceOfRevolution::Cylinder() const
696 Standard_NoSuchObject_Raise_if
697 (GetType() != GeomAbs_Cylinder, "Adaptor3d_SurfaceOfRevolution::Cylinder");
699 gp_Pnt P = Value( 0., 0.);
700 Standard_Real R = gp_Vec(myAxeRev.Location(), P) * myAxeRev.XDirection();
701 return gp_Cylinder( myAxeRev, R);
704 //=======================================================================
707 //=======================================================================
709 gp_Cone Adaptor3d_SurfaceOfRevolution::Cone() const
711 Standard_NoSuchObject_Raise_if
712 ( GetType() != GeomAbs_Cone, "Adaptor3d_SurfaceOfRevolution:Cone");
714 gp_Ax3 Axe = myAxeRev;
715 gp_Dir ldir = (myBasisCurve->Line()).Direction();
716 Standard_Real Angle = (Axe.Direction()).Angle(ldir);
717 gp_Pnt P0 = Value(0., 0.);
718 Standard_Real R = (Axe.Location()).Distance(P0);
719 if ( R >= Precision::Confusion()) {
720 gp_Pnt O = Axe.Location();
722 Standard_Real t = OP0.Dot(Axe.XDirection());
723 t /= ldir.Dot(Axe.XDirection());
724 OP0.Add(-t * gp_Vec(ldir));
725 if ( OP0.Dot(Axe.Direction()) > 0.) Angle = -Angle;
727 return gp_Cone( Axe, Angle, R);
731 //=======================================================================
734 //=======================================================================
736 gp_Sphere Adaptor3d_SurfaceOfRevolution::Sphere() const
738 Standard_NoSuchObject_Raise_if
739 ( GetType() != GeomAbs_Sphere, "Adaptor3d_SurfaceOfRevolution:Sphere");
741 gp_Circ C = myBasisCurve->Circle();
742 gp_Ax3 Axe = myAxeRev;
743 Axe.SetLocation( C.Location());
744 return gp_Sphere( Axe, C.Radius());
748 //=======================================================================
751 //=======================================================================
753 gp_Torus Adaptor3d_SurfaceOfRevolution::Torus() const
755 Standard_NoSuchObject_Raise_if
756 (GetType() != GeomAbs_Torus, "Adaptor3d_SurfaceOfRevolution:Torus");
758 gp_Circ C = myBasisCurve->Circle();
759 Standard_Real MajorRadius = gp_Lin(myAxis).Distance(C.Location());
760 return gp_Torus( myAxeRev, MajorRadius, C.Radius());
763 //=======================================================================
766 //=======================================================================
768 Standard_Integer Adaptor3d_SurfaceOfRevolution::UDegree() const
770 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::UDegree");
774 //=======================================================================
775 //function : NbUPoles
777 //=======================================================================
779 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUPoles() const
781 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbUPoles");
785 //=======================================================================
788 //=======================================================================
790 Standard_Integer Adaptor3d_SurfaceOfRevolution::VDegree() const
792 return myBasisCurve->Degree();
795 //=======================================================================
796 //function : NbVPoles
798 //=======================================================================
800 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVPoles() const
802 return myBasisCurve -> NbPoles();
805 //=======================================================================
806 //function : NbUKnots
808 //=======================================================================
810 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbUKnots() const
812 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbUKnots");
817 //=======================================================================
818 //function : NbVKnots
820 //=======================================================================
822 Standard_Integer Adaptor3d_SurfaceOfRevolution::NbVKnots() const
824 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::NbVKnots");
830 //=======================================================================
831 //function : IsURational
833 //=======================================================================
835 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsURational() const
837 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::IsURational");
838 return Standard_False;
841 //=======================================================================
842 //function : IsVRational
844 //=======================================================================
846 Standard_Boolean Adaptor3d_SurfaceOfRevolution::IsVRational() const
848 Standard_NoSuchObject::Raise("Adaptor3d_SurfaceOfRevolution::IsVRational");
849 return Standard_False;
853 //=======================================================================
856 //=======================================================================
858 Handle(Geom_BezierSurface) Adaptor3d_SurfaceOfRevolution::Bezier() const
860 Standard_NoSuchObject::Raise("");
861 Handle(Geom_BezierSurface) Dummy;
866 //=======================================================================
869 //=======================================================================
871 Handle(Geom_BSplineSurface) Adaptor3d_SurfaceOfRevolution::BSpline() const
873 Standard_NoSuchObject::Raise("");
874 Handle(Geom_BSplineSurface) Dummy;
879 //=======================================================================
882 //=======================================================================
884 gp_Ax3 Adaptor3d_SurfaceOfRevolution::Axis() const
889 //=======================================================================
890 //function : Direction
892 //=======================================================================
894 gp_Dir Adaptor3d_SurfaceOfRevolution::Direction() const
896 Standard_NoSuchObject::Raise("");
901 //=======================================================================
902 //function : BasisCurve
904 //=======================================================================
906 Handle(Adaptor3d_HCurve) Adaptor3d_SurfaceOfRevolution::BasisCurve() const