1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <Adaptor3d_IsoCurve.ixx>
16 #include <Adaptor3d_HIsoCurve.hxx>
17 #include <Adaptor3d_HSurfaceOfRevolution.hxx>
18 #include <Geom_BezierSurface.hxx>
19 #include <Geom_BSplineSurface.hxx>
20 #include <GeomAbs_SurfaceType.hxx>
21 #include <Standard_NoSuchObject.hxx>
22 #include <Standard_NotImplemented.hxx>
26 #include <BSplCLib.hxx>
27 #include <BSplSLib.hxx>
28 #include <Precision.hxx>
29 #include <TColgp_Array1OfPnt.hxx>
30 #include <TColgp_Array2OfPnt.hxx>
33 //=======================================================================
34 //function : Adaptor3d_IsoCurve
36 //=======================================================================
38 Adaptor3d_IsoCurve::Adaptor3d_IsoCurve()
39 : myIso (GeomAbs_NoneIso),
46 //=======================================================================
47 //function : Adaptor3d_IsoCurve
49 //=======================================================================
51 Adaptor3d_IsoCurve::Adaptor3d_IsoCurve(const Handle(Adaptor3d_HSurface)& S)
53 myIso (GeomAbs_NoneIso),
60 //=======================================================================
61 //function : Adaptor3d_IsoCurve
63 //=======================================================================
65 Adaptor3d_IsoCurve::Adaptor3d_IsoCurve(const Handle(Adaptor3d_HSurface)& S,
66 const GeomAbs_IsoType theIso,
67 const Standard_Real theParam)
69 myIso (GeomAbs_NoneIso),
74 Load(theIso, theParam);
77 //=======================================================================
78 //function : Adaptor3d_IsoCurve
80 //=======================================================================
82 Adaptor3d_IsoCurve::Adaptor3d_IsoCurve(const Handle(Adaptor3d_HSurface)& theS,
83 const GeomAbs_IsoType theIso,
84 const Standard_Real theParam,
85 const Standard_Real theWFirst,
86 const Standard_Real theWLast)
93 Load(theIso, theParam, theWFirst, theWLast);
96 //=======================================================================
99 //=======================================================================
101 void Adaptor3d_IsoCurve::Load(const Handle(Adaptor3d_HSurface)& S )
104 myIso = GeomAbs_NoneIso;
107 //=======================================================================
110 //=======================================================================
112 void Adaptor3d_IsoCurve::Load(const GeomAbs_IsoType Iso,
113 const Standard_Real Param)
119 mySurface->FirstVParameter(),
120 mySurface->LastVParameter());
125 mySurface->FirstUParameter(),
126 mySurface->LastUParameter());
129 case GeomAbs_NoneIso:
130 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
135 //=======================================================================
138 //=======================================================================
140 void Adaptor3d_IsoCurve::Load(const GeomAbs_IsoType Iso,
141 const Standard_Real Param,
142 const Standard_Real WFirst,
143 const Standard_Real WLast)
151 if (myIso == GeomAbs_IsoU) {
152 myFirst = Max(myFirst, mySurface->FirstVParameter());
153 myLast = Min(myLast, mySurface->LastVParameter());
156 myFirst = Max(myFirst, mySurface->FirstUParameter());
157 myLast = Min(myLast, mySurface->LastUParameter());
160 // Adjust the parameters on periodic surfaces
162 Standard_Real dummy = myParameter;
164 if (mySurface->IsUPeriodic()) {
166 if (myIso == GeomAbs_IsoU) {
167 ElCLib::AdjustPeriodic
168 (mySurface->FirstUParameter(),
169 mySurface->FirstUParameter()+
170 mySurface->UPeriod(),
171 mySurface->UResolution(Precision::Confusion()),
175 ElCLib::AdjustPeriodic
176 (mySurface->FirstUParameter(),
177 mySurface->FirstUParameter()+
178 mySurface->UPeriod(),
179 mySurface->UResolution(Precision::Confusion()),
184 if (mySurface->IsVPeriodic()) {
186 if (myIso == GeomAbs_IsoV) {
187 ElCLib::AdjustPeriodic
188 (mySurface->FirstVParameter(),
189 mySurface->FirstVParameter() +
190 mySurface->VPeriod(),
191 mySurface->VResolution(Precision::Confusion()),
195 ElCLib::AdjustPeriodic
196 (mySurface->FirstVParameter(),
197 mySurface->FirstVParameter() +
198 mySurface->VPeriod(),
199 mySurface->VResolution(Precision::Confusion()),
206 //=======================================================================
207 //function : Continuity
209 //=======================================================================
211 GeomAbs_Shape Adaptor3d_IsoCurve::Continuity() const
215 return mySurface->VContinuity();
217 return mySurface->UContinuity();
218 case GeomAbs_NoneIso:
223 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
227 //=======================================================================
228 //function : NbIntervals
230 //=======================================================================
232 Standard_Integer Adaptor3d_IsoCurve::NbIntervals(const GeomAbs_Shape S) const
234 if (myIso == GeomAbs_NoneIso) Standard_NoSuchObject::Raise();
235 Standard_Boolean UIso = (myIso == GeomAbs_IsoU);
237 Standard_Integer nbInter = UIso ?
238 mySurface->NbVIntervals(S) :
239 mySurface->NbUIntervals(S);
241 TColStd_Array1OfReal T(1,nbInter+1);
244 mySurface->VIntervals(T,S);
246 mySurface->UIntervals(T,S);
248 if(nbInter == 1) return nbInter;
250 Standard_Integer first = 1;
251 while (T(first) <= myFirst) first++;
252 Standard_Integer last = nbInter+1;
253 while (T(last) >= myLast) last--;
254 return (last - first + 2);
257 //=======================================================================
258 //function : Intervals
260 //=======================================================================
262 void Adaptor3d_IsoCurve::Intervals(TColStd_Array1OfReal& TI,
263 const GeomAbs_Shape S) const
265 if (myIso == GeomAbs_NoneIso) Standard_NoSuchObject::Raise();
266 Standard_Boolean UIso = (myIso == GeomAbs_IsoU);
268 Standard_Integer nbInter = UIso ?
269 mySurface->NbVIntervals(S) :
270 mySurface->NbUIntervals(S);
272 TColStd_Array1OfReal T(1,nbInter+1);
275 mySurface->VIntervals(T,S);
277 mySurface->UIntervals(T,S);
280 TI(TI.Lower()) = myFirst ;
281 TI(TI.Lower() + 1) = myLast ;
285 Standard_Integer first = 1;
286 while (T(first) <= myFirst) first++;
287 Standard_Integer last = nbInter+1;
288 while (T(last) >= myLast) last--;
290 Standard_Integer i = TI.Lower(), j;
291 for (j = first-1; j <= last+1; j++) {
295 TI(TI.Lower()) = myFirst ;
296 TI(TI.Lower() + last-first + 2) = myLast ;
299 //=======================================================================
302 //=======================================================================
304 Handle(Adaptor3d_HCurve) Adaptor3d_IsoCurve::Trim
305 (const Standard_Real First,
306 const Standard_Real Last,
307 const Standard_Real) const
309 Handle(Adaptor3d_HIsoCurve) HI = new Adaptor3d_HIsoCurve(*this);
310 ((Adaptor3d_IsoCurve *)&(HI->Curve()))->Load(myIso,myParameter,First,Last);
314 //=======================================================================
315 //function : IsClosed
317 //=======================================================================
319 Standard_Boolean Adaptor3d_IsoCurve::IsClosed() const
323 return mySurface->IsVClosed();
325 return mySurface->IsUClosed();
326 case GeomAbs_NoneIso:
331 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
332 return Standard_False;
335 //=======================================================================
336 //function : IsPeriodic
338 //=======================================================================
340 Standard_Boolean Adaptor3d_IsoCurve::IsPeriodic() const
344 return mySurface->IsVPeriodic();
346 return mySurface->IsUPeriodic();
347 case GeomAbs_NoneIso:
352 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
353 return Standard_False;
356 //=======================================================================
359 //=======================================================================
361 Standard_Real Adaptor3d_IsoCurve::Period() const
365 return mySurface->VPeriod();
367 return mySurface->UPeriod();
368 case GeomAbs_NoneIso:
373 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
377 //=======================================================================
380 //=======================================================================
382 gp_Pnt Adaptor3d_IsoCurve::Value(const Standard_Real T) const
387 return mySurface->Value(myParameter,T);
390 return mySurface->Value(T,myParameter);
392 case GeomAbs_NoneIso:
394 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
403 //=======================================================================
406 //=======================================================================
408 void Adaptor3d_IsoCurve::D0(const Standard_Real T, gp_Pnt& P) const
413 mySurface->D0(myParameter,T,P);
417 mySurface->D0(T,myParameter,P);
420 case GeomAbs_NoneIso:
421 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
426 //=======================================================================
429 //=======================================================================
431 void Adaptor3d_IsoCurve::D1(const Standard_Real T, gp_Pnt& P, gp_Vec& V) const
437 mySurface->D1(myParameter,T,P,dummy,V);
441 mySurface->D1(T,myParameter,P,V,dummy);
444 case GeomAbs_NoneIso:
445 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
450 //=======================================================================
453 //=======================================================================
455 void Adaptor3d_IsoCurve::D2(const Standard_Real T, gp_Pnt& P,
456 gp_Vec& V1, gp_Vec& V2) const
458 gp_Vec dummy1,dummy2,dummy3;
462 mySurface->D2(myParameter,T,P,
463 dummy1,V1,dummy2,V2,dummy3);
466 mySurface->D2(T,myParameter,
467 P,V1,dummy1,V2,dummy2,dummy3);
469 case GeomAbs_NoneIso:
470 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
475 //=======================================================================
478 //=======================================================================
480 void Adaptor3d_IsoCurve::D3(const Standard_Real T, gp_Pnt& P,
481 gp_Vec& V1, gp_Vec& V2, gp_Vec& V3) const
487 mySurface->D3(myParameter,T,P,dummy[0],V1,dummy[1],
488 V2,dummy[2],dummy[3],V3,dummy[4],dummy[5]);
492 mySurface->D3(T,myParameter,P,V1,dummy[0],V2,dummy[1],
493 dummy[2],V3,dummy[3],dummy[4],dummy[5]);
496 case GeomAbs_NoneIso:
497 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
502 //=======================================================================
505 //=======================================================================
507 gp_Vec Adaptor3d_IsoCurve::DN(const Standard_Real T,
508 const Standard_Integer N) const
513 return mySurface->DN(myParameter,T,0,N);
515 return mySurface->DN(T,myParameter,N,0);
516 case GeomAbs_NoneIso:
518 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
528 //=======================================================================
529 //function : Resolution
531 //=======================================================================
533 Standard_Real Adaptor3d_IsoCurve::Resolution(const Standard_Real R3D) const
535 // Peut-on faire mieux ??
536 return Precision::Parametric(R3D);
541 //=======================================================================
544 //=======================================================================
546 GeomAbs_CurveType Adaptor3d_IsoCurve::GetType() const {
548 switch (mySurface->GetType()) {
553 case GeomAbs_Cylinder:
561 return GeomAbs_Circle;
563 case GeomAbs_NoneIso:
565 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
567 return GeomAbs_OtherCurve;
575 return GeomAbs_Circle;
577 case GeomAbs_BezierSurface:
578 return GeomAbs_BezierCurve;
580 case GeomAbs_BSplineSurface:
581 return GeomAbs_BSplineCurve;
583 case GeomAbs_SurfaceOfRevolution:
587 return mySurface->BasisCurve()->GetType();
590 return GeomAbs_Circle;
592 case GeomAbs_NoneIso:
593 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
595 return GeomAbs_OtherCurve;
601 case GeomAbs_SurfaceOfExtrusion:
608 return mySurface->BasisCurve()->GetType();
610 case GeomAbs_NoneIso:
611 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
613 return GeomAbs_OtherCurve;
619 return GeomAbs_OtherCurve;
623 return GeomAbs_OtherCurve;
626 //=======================================================================
629 //=======================================================================
631 gp_Lin Adaptor3d_IsoCurve::Line() const
639 //=======================================================================
640 //function : computeHR
642 //=======================================================================
644 static void computeHR(const gp_Ax3& axes,
647 Standard_Real& radius)
649 gp_Vec V(axes.Location(),P);
650 h = V * axes.Direction();
651 radius = V * axes.XDirection();
654 //=======================================================================
657 //=======================================================================
659 gp_Circ Adaptor3d_IsoCurve::Circle() const
662 Standard_Real radius,h = 0.;
664 switch (mySurface->GetType()) {
666 case GeomAbs_Cylinder:
668 gp_Cylinder cyl = mySurface->Cylinder();
674 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:UIso");
679 return ElSLib::CylinderVIso(cyl.Position(),cyl.Radius(),myParameter);
681 case GeomAbs_NoneIso:
683 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
692 gp_Cone cone = mySurface->Cone();
698 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:UIso");
703 return ElSLib::ConeVIso(cone.Position(),cone.RefRadius(),
704 cone.SemiAngle(),myParameter);
706 case GeomAbs_NoneIso:
708 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
717 gp_Sphere sph = mySurface->Sphere();
723 return ElSLib::SphereUIso(sph.Position(),sph.Radius(),myParameter);
728 return ElSLib::SphereVIso(sph.Position(),sph.Radius(),myParameter);
731 case GeomAbs_NoneIso:
733 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
740 case GeomAbs_Torus: {
741 gp_Torus tor = mySurface->Torus();
747 return ElSLib::TorusUIso(tor.Position(),tor.MajorRadius(),
748 tor.MinorRadius(),myParameter);
753 return ElSLib::TorusVIso(tor.Position(),tor.MajorRadius(),
754 tor.MinorRadius(),myParameter);
757 case GeomAbs_NoneIso:
759 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
766 case GeomAbs_SurfaceOfRevolution:
768 if (myIso == GeomAbs_IsoV) {
769 gp_Ax1 Ax1 = mySurface->AxeOfRevolution();
770 gp_Vec DX(Ax1.Location(), Value(0));
771 if(DX.IsParallel(Ax1.Direction(),Precision::Angular())) {
772 return gp_Circ(gp_Ax2(Value(0), Ax1.Direction()),0);
775 axes = gp_Ax3(Ax1.Location(), Ax1.Direction(), DX);
776 computeHR(axes,Value(0),h,radius);
777 gp_Vec VT = axes.Direction();
778 axes.Translate(VT * h);
779 return gp_Circ(axes.Ax2(),radius);
783 return mySurface->BasisCurve()->Circle().Rotated
784 (mySurface->AxeOfRevolution(),myParameter);
788 case GeomAbs_SurfaceOfExtrusion: {
789 return mySurface->BasisCurve()->Circle().Translated
790 (myParameter * gp_Vec(mySurface->Direction()));
794 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:Circle");
803 //=======================================================================
806 //=======================================================================
808 gp_Elips Adaptor3d_IsoCurve::Ellipse() const
810 switch (mySurface->GetType()) {
812 case GeomAbs_SurfaceOfExtrusion: {
813 return mySurface->BasisCurve()->Ellipse().Translated
814 (myParameter * gp_Vec(mySurface->Direction()));
818 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:Ellipse");
824 //=======================================================================
825 //function : Hyperbola
827 //=======================================================================
829 gp_Hypr Adaptor3d_IsoCurve::Hyperbola() const
831 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:Hyperbola");
835 //=======================================================================
836 //function : Parabola
838 //=======================================================================
840 gp_Parab Adaptor3d_IsoCurve::Parabola() const
842 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:Parabola");
846 //=======================================================================
849 //=======================================================================
851 Standard_Integer Adaptor3d_IsoCurve::Degree() const
853 Standard_Integer degree = 0 ;
854 GeomAbs_SurfaceType type = mySurface->GetType() ;
856 case GeomAbs_BezierSurface:
857 case GeomAbs_BSplineSurface:
861 degree = mySurface->VDegree() ;
864 degree = mySurface->UDegree() ;
867 case GeomAbs_NoneIso:
869 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
873 case GeomAbs_SurfaceOfRevolution:
877 degree = mySurface->BasisCurve()->Degree();
880 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
884 case GeomAbs_SurfaceOfExtrusion:
888 degree = mySurface->BasisCurve()->Degree();
891 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
896 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
902 //=======================================================================
903 //function : IsRational
905 //=======================================================================
907 Standard_Boolean Adaptor3d_IsoCurve::IsRational() const
909 Standard_Integer is_rational = Standard_False ;
910 GeomAbs_SurfaceType type = mySurface->GetType() ;
912 case GeomAbs_BezierSurface:
913 case GeomAbs_BSplineSurface:
917 is_rational = mySurface->IsVRational() ;
920 is_rational = mySurface->IsURational() ;
923 case GeomAbs_NoneIso:
925 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
929 case GeomAbs_SurfaceOfRevolution:
933 is_rational = mySurface->BasisCurve()->IsRational();
936 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
940 case GeomAbs_SurfaceOfExtrusion:
944 is_rational = mySurface->BasisCurve()->IsRational();
947 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
952 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
958 //=======================================================================
961 //=======================================================================
963 Standard_Integer Adaptor3d_IsoCurve::NbPoles() const
965 Standard_Integer nb_poles = 0 ;
966 GeomAbs_SurfaceType type = mySurface->GetType() ;
968 case GeomAbs_BezierSurface:
969 case GeomAbs_BSplineSurface:
972 nb_poles = mySurface->NbVPoles() ;
975 nb_poles = mySurface->NbUPoles() ;
978 case GeomAbs_NoneIso:
980 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
983 case GeomAbs_SurfaceOfRevolution:
988 nb_poles = mySurface->BasisCurve()->NbPoles();
992 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
996 case GeomAbs_SurfaceOfExtrusion:
1001 nb_poles = mySurface->BasisCurve()->NbPoles();
1005 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1011 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1017 //=======================================================================
1018 //function : NbKnots
1020 //=======================================================================
1022 Standard_Integer Adaptor3d_IsoCurve::NbKnots() const
1024 Standard_Integer nb_knots = 0 ;
1025 GeomAbs_SurfaceType type = mySurface->GetType() ;
1027 case GeomAbs_BSplineSurface:
1031 nb_knots = mySurface->NbVKnots() ;
1034 nb_knots = mySurface->NbUKnots() ;
1037 case GeomAbs_NoneIso:
1039 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1043 case GeomAbs_SurfaceOfRevolution:
1048 nb_knots = mySurface->BasisCurve()->NbKnots() ;
1052 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1056 case GeomAbs_SurfaceOfExtrusion:
1061 nb_knots = mySurface->BasisCurve()->NbKnots() ;
1065 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1070 Standard_NoSuchObject::Raise("Adaptor3d_IsoCurve:NoneIso");
1076 //=======================================================================
1079 //=======================================================================
1081 Handle(Geom_BezierCurve) Adaptor3d_IsoCurve::Bezier() const
1083 Handle(Geom_BezierCurve) C;
1084 if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution) {
1085 C = mySurface->BasisCurve()->Bezier();
1086 C = Handle(Geom_BezierCurve)::DownCast(C->Copy());
1087 C->Rotate(mySurface->AxeOfRevolution(),myParameter);
1089 else if (mySurface->GetType() == GeomAbs_SurfaceOfExtrusion) {
1090 C = mySurface->BasisCurve()->Bezier();
1091 C = Handle(Geom_BezierCurve)::DownCast(C->Copy());
1092 C->Translate(myParameter * gp_Vec(mySurface->Direction()));
1094 else if (myIso == GeomAbs_IsoU) {
1095 C = Handle(Geom_BezierCurve)::DownCast
1096 (mySurface->Bezier()->UIso(myParameter)) ;
1099 C = Handle(Geom_BezierCurve)::DownCast
1100 (mySurface->Bezier()->VIso(myParameter));
1102 // C->Segment(myFirst,myLast);
1106 //=======================================================================
1107 //function : BSpline
1109 //=======================================================================
1111 Handle(Geom_BSplineCurve) Adaptor3d_IsoCurve::BSpline() const
1113 Handle(Geom_BSplineCurve) C;
1114 if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution) {
1115 C = mySurface->BasisCurve()->BSpline();
1116 C = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
1117 C->Rotate(mySurface->AxeOfRevolution(),myParameter);
1119 else if (mySurface->GetType() == GeomAbs_SurfaceOfExtrusion) {
1120 C = mySurface->BasisCurve()->BSpline();
1121 C = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
1122 C->Translate(myParameter * gp_Vec(mySurface->Direction()));
1124 else if (myIso == GeomAbs_IsoU) {
1125 C = Handle(Geom_BSplineCurve)::DownCast
1126 (mySurface->BSpline()->UIso(myParameter)) ;
1129 C = Handle(Geom_BSplineCurve)::DownCast
1130 (mySurface->BSpline()->VIso(myParameter));
1132 // C->Segment(myFirst,myLast);