1 // Created on: 1993-08-25
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 // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272
19 #include <Standard_NoSuchObject.hxx>
20 #include <Standard_NotImplemented.hxx>
21 #include <ProjLib_ProjectedCurve.hxx>
22 #include <ProjLib_HCompProjectedCurve.hxx>
23 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
24 #include <ProjLib_ComputeApprox.hxx>
25 #include <ProjLib_Projector.hxx>
26 #include <Adaptor3d_Curve.hxx>
27 #include <Adaptor3d_Surface.hxx>
28 #include <Approx_CurveOnSurface.hxx>
29 #include <ProjLib_Plane.hxx>
30 #include <ProjLib_Cylinder.hxx>
31 #include <ProjLib_Cone.hxx>
32 #include <ProjLib_Sphere.hxx>
33 #include <ProjLib_Torus.hxx>
34 #include <Precision.hxx>
35 #include <Geom2d_BezierCurve.hxx>
36 #include <gp_Vec2d.hxx>
37 #include <StdFail_NotDone.hxx>
38 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
39 #include <Geom2dConvert.hxx>
40 #include <TColStd_Array1OfReal.hxx>
41 #include <GeomAbs_IsoType.hxx>
42 #include <Geom2d_Line.hxx>
43 #include <Geom2d_TrimmedCurve.hxx>
44 #include <GeomLib.hxx>
45 #include <Extrema_ExtPC.hxx>
46 #include <NCollection_DataMap.hxx>
50 IMPLEMENT_STANDARD_RTTIEXT(ProjLib_ProjectedCurve, Adaptor2d_Curve2d)
52 //=======================================================================
53 //function : ComputeTolU
55 //=======================================================================
57 static Standard_Real ComputeTolU(const Handle(Adaptor3d_Surface)& theSurf,
58 const Standard_Real theTolerance)
60 Standard_Real aTolU = theSurf->UResolution(theTolerance);
61 if (theSurf->IsUPeriodic())
63 aTolU = Min(aTolU, 0.01*theSurf->UPeriod());
69 //=======================================================================
70 //function : ComputeTolV
72 //=======================================================================
74 static Standard_Real ComputeTolV(const Handle(Adaptor3d_Surface)& theSurf,
75 const Standard_Real theTolerance)
77 Standard_Real aTolV = theSurf->VResolution(theTolerance);
78 if (theSurf->IsVPeriodic())
80 aTolV = Min(aTolV, 0.01*theSurf->VPeriod());
86 //=======================================================================
89 //=======================================================================
91 static Standard_Boolean IsoIsDeg (const Adaptor3d_Surface& S,
92 const Standard_Real Param,
93 const GeomAbs_IsoType IT,
94 const Standard_Real TolMin,
95 const Standard_Real TolMax)
97 Standard_Real U1=0.,U2=0.,V1=0.,V2=0.,T;
98 Standard_Boolean Along = Standard_True;
99 U1 = S.FirstUParameter();
100 U2 = S.LastUParameter();
101 V1 = S.FirstVParameter();
102 V2 = S.LastVParameter();
105 Standard_Real Step,D1NormMax;
106 if (IT == GeomAbs_IsoV)
110 for (T=U1;T<=U2;T=T+Step)
112 S.D1(T,Param,P,D1U,D1V);
113 D1NormMax=Max(D1NormMax,D1U.Magnitude());
116 if (D1NormMax >TolMax || D1NormMax < TolMin )
117 Along = Standard_False;
123 for (T=V1;T<=V2;T=T+Step)
125 S.D1(Param,T,P,D1U,D1V);
126 D1NormMax=Max(D1NormMax,D1V.Magnitude());
129 if (D1NormMax >TolMax || D1NormMax < TolMin )
130 Along = Standard_False;
137 //=======================================================================
140 //=======================================================================
142 static void TrimC3d(Handle(Adaptor3d_Curve)& myCurve,
143 Standard_Boolean* IsTrimmed,
144 const Standard_Real dt,
146 Standard_Integer* SingularCase,
147 const Standard_Integer NumberOfSingularCase,
148 const Standard_Real TolConf)
150 Standard_Real f = myCurve->FirstParameter();
151 Standard_Real l = myCurve->LastParameter();
153 gp_Pnt P = myCurve->Value(f);
155 if(P.Distance(Pole) <= TolConf) {
156 IsTrimmed[0] = Standard_True;
158 myCurve = myCurve->Trim(f, l, Precision::Confusion());
159 SingularCase[0] = NumberOfSingularCase;
162 P = myCurve->Value(l);
163 if(P.Distance(Pole) <= TolConf) {
164 IsTrimmed[1] = Standard_True;
166 myCurve = myCurve->Trim(f, l, Precision::Confusion());
167 SingularCase[1] = NumberOfSingularCase;
171 //=======================================================================
172 //function : ExtendC2d
174 //=======================================================================
176 static void ExtendC2d (Handle(Geom2d_BSplineCurve)& aRes,
177 const Standard_Real /*t*/,
178 const Standard_Real /*dt*/,
179 const Standard_Real u1,
180 const Standard_Real u2,
181 const Standard_Real v1,
182 const Standard_Real v2,
183 const Standard_Integer FirstOrLast,
184 const Standard_Integer NumberOfSingularCase)
186 Standard_Real theParam = (FirstOrLast == 0)? aRes->FirstParameter()
187 : aRes->LastParameter();
192 Handle(Geom2d_TrimmedCurve) aSegment;
193 Geom2dConvert_CompCurveToBSplineCurve aCompCurve(aRes, Convert_RationalC1);
194 Standard_Real aTol = Precision::Confusion();
196 aRes->D1(theParam, aPBnd, aVBnd);
197 aDBnd.SetXY(aVBnd.XY());
198 gp_Lin2d aLin(aPBnd, aDBnd); //line in direction of derivative
201 gp_Dir2d theBoundDir;
202 switch (NumberOfSingularCase)
206 thePole.SetCoord(u1, v1);
207 theBoundDir.SetCoord(0., 1.);
212 thePole.SetCoord(u2, v1);
213 theBoundDir.SetCoord(0., 1.);
218 thePole.SetCoord(u1, v1);
219 theBoundDir.SetCoord(1., 0.);
224 thePole.SetCoord(u1, v2);
225 theBoundDir.SetCoord(1., 0.);
229 gp_Lin2d BoundLin(thePole, theBoundDir); //one of the bounds of rectangle
230 Standard_Real ParOnLin = 0.;
231 if (theBoundDir.IsParallel(aDBnd, 100.*Precision::Angular()))
233 ParOnLin = ElCLib::Parameter(aLin, thePole);
237 Standard_Real U1x = BoundLin.Direction().X();
238 Standard_Real U1y = BoundLin.Direction().Y();
239 Standard_Real U2x = aLin.Direction().X();
240 Standard_Real U2y = aLin.Direction().Y();
241 Standard_Real Uo21x = aLin.Location().X() - BoundLin.Location().X();
242 Standard_Real Uo21y = aLin.Location().Y() - BoundLin.Location().Y();
244 Standard_Real D = U1y*U2x - U1x*U2y;
246 ParOnLin = (Uo21y * U1x - Uo21x * U1y) / D; //parameter of intersection point
249 Handle(Geom2d_Line) aSegLine = new Geom2d_Line(aLin);
250 aSegment = (FirstOrLast == 0)?
251 new Geom2d_TrimmedCurve(aSegLine, ParOnLin, 0.) :
252 new Geom2d_TrimmedCurve(aSegLine, 0., ParOnLin);
254 Standard_Boolean anAfter = FirstOrLast != 0;
255 aCompCurve.Add(aSegment, aTol, anAfter);
256 aRes = aCompCurve.BSplineCurve();
259 //=======================================================================
262 //=======================================================================
264 static void Project(ProjLib_Projector& P, Handle(Adaptor3d_Curve)& C)
266 GeomAbs_CurveType CType = C->GetType();
269 P.Project(C->Line());
272 P.Project(C->Circle());
274 case GeomAbs_Ellipse:
275 P.Project(C->Ellipse());
277 case GeomAbs_Hyperbola:
278 P.Project(C->Hyperbola());
280 case GeomAbs_Parabola:
281 P.Project(C->Parabola());
283 case GeomAbs_BSplineCurve:
284 case GeomAbs_BezierCurve:
285 case GeomAbs_OffsetCurve:
286 case GeomAbs_OtherCurve: // try the approximation
289 throw Standard_NoSuchObject(" ");
293 //=======================================================================
294 //function : ProjLib_ProjectedCurve
296 //=======================================================================
298 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve() :
299 myTolerance(Precision::Confusion()),
300 myDegMin(-1), myDegMax(-1),
303 myBndPnt(AppParCurves_TangencyPoint)
308 //=======================================================================
309 //function : ProjLib_ProjectedCurve
311 //=======================================================================
313 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
314 (const Handle(Adaptor3d_Surface)& S) :
315 myTolerance(Precision::Confusion()),
316 myDegMin(-1), myDegMax(-1),
319 myBndPnt(AppParCurves_TangencyPoint)
325 //=======================================================================
326 //function : ProjLib_ProjectedCurve
328 //=======================================================================
330 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
331 (const Handle(Adaptor3d_Surface)& S,
332 const Handle(Adaptor3d_Curve)& C) :
333 myTolerance(Precision::Confusion()),
334 myDegMin(-1), myDegMax(-1),
337 myBndPnt(AppParCurves_TangencyPoint)
344 //=======================================================================
345 //function : ProjLib_ProjectedCurve
347 //=======================================================================
349 ProjLib_ProjectedCurve::ProjLib_ProjectedCurve
350 (const Handle(Adaptor3d_Surface)& S,
351 const Handle(Adaptor3d_Curve)& C,
352 const Standard_Real Tol) :
353 myTolerance(Max(Tol, Precision::Confusion())),
354 myDegMin(-1), myDegMax(-1),
357 myBndPnt(AppParCurves_TangencyPoint)
363 //=======================================================================
364 //function : ShallowCopy
366 //=======================================================================
368 Handle(Adaptor2d_Curve2d) ProjLib_ProjectedCurve::ShallowCopy() const
370 Handle(ProjLib_ProjectedCurve) aCopy = new ProjLib_ProjectedCurve();
372 aCopy->myTolerance = myTolerance;
373 if (!mySurface.IsNull())
375 aCopy->mySurface = mySurface->ShallowCopy();
377 if (!myCurve.IsNull())
379 aCopy->myCurve = myCurve->ShallowCopy();
381 aCopy->myResult = myResult;
382 aCopy->myDegMin = myDegMin;
383 aCopy->myDegMax = myDegMax;
384 aCopy->myMaxSegments = myMaxSegments;
385 aCopy->myMaxDist = myMaxDist;
386 aCopy->myBndPnt = myBndPnt;
391 //=======================================================================
394 //=======================================================================
396 void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_Surface)& S)
401 //=======================================================================
404 //=======================================================================
406 void ProjLib_ProjectedCurve::Load(const Standard_Real theTol)
408 myTolerance = theTol;
411 //=======================================================================
414 //=======================================================================
416 void ProjLib_ProjectedCurve::Perform(const Handle(Adaptor3d_Curve)& C)
418 myTolerance = Max(myTolerance, Precision::Confusion());
420 Standard_Real FirstPar = C->FirstParameter();
421 Standard_Real LastPar = C->LastParameter();
422 GeomAbs_SurfaceType SType = mySurface->GetType();
423 GeomAbs_CurveType CType = myCurve->GetType();
424 Standard_Boolean isAnalyticalSurf = Standard_True;
425 Standard_Boolean IsTrimmed[2] = { Standard_False, Standard_False };
426 Standard_Integer SingularCase[2];
427 const Standard_Real eps = 0.01;
428 Standard_Real TolConf = Precision::Confusion();
429 Standard_Real dt = (LastPar - FirstPar) * eps;
430 Standard_Real U1 = 0.0, U2 = 0.0, V1 = 0.0, V2 = 0.0;
431 U1 = mySurface->FirstUParameter();
432 U2 = mySurface->LastUParameter();
433 V1 = mySurface->FirstVParameter();
434 V2 = mySurface->LastVParameter();
440 ProjLib_Plane P(mySurface->Plane());
446 case GeomAbs_Cylinder:
448 ProjLib_Cylinder P(mySurface->Cylinder());
456 ProjLib_Cone P(mySurface->Cone());
464 ProjLib_Sphere P(mySurface->Sphere());
468 // on met dans la pseudo-periode ( car Sphere n'est pas
469 // periodique en V !)
470 P.SetInBounds(myCurve->FirstParameter());
474 const Standard_Real Vmax = M_PI / 2.;
475 const Standard_Real Vmin = -Vmax;
476 const Standard_Real minang = 1.e-5 * M_PI;
477 gp_Sphere aSph = mySurface->Sphere();
478 Standard_Real anR = aSph.Radius();
479 Standard_Real f = myCurve->FirstParameter();
480 Standard_Real l = myCurve->LastParameter();
482 gp_Pnt Pf = myCurve->Value(f);
483 gp_Pnt Pl = myCurve->Value(l);
484 gp_Pnt aLoc = aSph.Position().Location();
485 Standard_Real maxdist = Max(Pf.Distance(aLoc), Pl.Distance(aLoc));
486 TolConf = Max(anR * minang, Abs(anR - maxdist));
488 //Surface has pole at V = Vmin and Vmax
489 gp_Pnt Pole = mySurface->Value(U1, Vmin);
490 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
491 Pole = mySurface->Value(U1, Vmax);
492 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
500 ProjLib_Torus P(mySurface->Torus());
506 case GeomAbs_BezierSurface:
507 case GeomAbs_BSplineSurface:
509 isAnalyticalSurf = Standard_False;
511 f = myCurve->FirstParameter();
512 l = myCurve->LastParameter();
515 const Adaptor3d_Surface& S = *mySurface;
516 U1 = S.FirstUParameter();
517 U2 = S.LastUParameter();
518 V1 = S.FirstVParameter();
519 V2 = S.LastVParameter();
521 if(IsoIsDeg(S, U1, GeomAbs_IsoU, 0., myTolerance))
523 //Surface has pole at U = Umin
524 gp_Pnt Pole = mySurface->Value(U1, V1);
525 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 1, TolConf);
528 if(IsoIsDeg(S, U2, GeomAbs_IsoU, 0., myTolerance))
530 //Surface has pole at U = Umax
531 gp_Pnt Pole = mySurface->Value(U2, V1);
532 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 2, TolConf);
535 if(IsoIsDeg(S, V1, GeomAbs_IsoV, 0., myTolerance))
537 //Surface has pole at V = Vmin
538 gp_Pnt Pole = mySurface->Value(U1, V1);
539 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 3, TolConf);
542 if(IsoIsDeg(S, V2, GeomAbs_IsoV, 0., myTolerance))
544 //Surface has pole at V = Vmax
545 gp_Pnt Pole = mySurface->Value(U1, V2);
546 TrimC3d(myCurve, IsTrimmed, dt, Pole, SingularCase, 4, TolConf);
549 ProjLib_ComputeApproxOnPolarSurface polar;
550 polar.SetTolerance(myTolerance);
551 polar.SetDegree(myDegMin, myDegMax);
552 polar.SetMaxSegments(myMaxSegments);
553 polar.SetBndPnt(myBndPnt);
554 polar.SetMaxDist(myMaxDist);
555 polar.Perform(myCurve, mySurface);
557 Handle(Geom2d_BSplineCurve) aRes = polar.BSpline();
561 myTolerance = polar.Tolerance();
562 if( (IsTrimmed[0] || IsTrimmed[1]))
566 //Add segment before start of curve
567 f = myCurve->FirstParameter();
568 ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
572 //Add segment after end of curve
573 l = myCurve->LastParameter();
574 ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
576 Handle(Geom2d_Curve) NewCurve2d;
577 GeomLib::SameRange(Precision::PConfusion(), aRes,
578 aRes->FirstParameter(), aRes->LastParameter(),
579 FirstPar, LastPar, NewCurve2d);
580 aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
582 myResult.SetBSpline(aRes);
584 myResult.SetType(GeomAbs_BSplineCurve);
591 isAnalyticalSurf = Standard_False;
592 Standard_Real Vsingular[2] = {0.0 , 0.0}; //for surfaces of revolution
593 Standard_Real f = 0.0, l = 0.0;
596 if(mySurface->GetType() == GeomAbs_SurfaceOfRevolution)
598 //Check possible singularity
600 gp_Pnt P = mySurface->AxeOfRevolution().Location();
601 gp_Dir N = mySurface->AxeOfRevolution().Direction();
605 f = myCurve->FirstParameter();
606 l = myCurve->LastParameter();
609 P = myCurve->Value(f);
610 if(L.Distance(P) < Precision::Confusion())
612 IsTrimmed[0] = Standard_True;
614 myCurve = myCurve->Trim(f, l, Precision::Confusion());
615 // Searching the parameter on the basis curve for surface of revolution
616 Extrema_ExtPC anExtr(P, *mySurface->BasisCurve(), myTolerance);
619 Standard_Real aMinDist = RealLast();
620 for(Standard_Integer anIdx = 1; anIdx <= anExtr.NbExt(); anIdx++)
622 if (anExtr.IsMin(anIdx) &&
623 anExtr.SquareDistance(anIdx) < aMinDist)
625 aMinDist = anExtr.SquareDistance(anIdx);
626 Vsingular[0] = anExtr.Point(anIdx).Parameter();
631 Vsingular[0] = ElCLib::Parameter(L, P);
632 //SingularCase[0] = 3;
635 P = myCurve->Value(l);
636 if(L.Distance(P) < Precision::Confusion())
638 IsTrimmed[1] = Standard_True;
640 myCurve = myCurve->Trim(f, l, Precision::Confusion());
641 // Searching the parameter on the basis curve for surface of revolution
642 Extrema_ExtPC anExtr(P, *mySurface->BasisCurve(), myTolerance);
645 Standard_Real aMinDist = RealLast();
646 for(Standard_Integer anIdx = 1; anIdx <= anExtr.NbExt(); anIdx++)
648 if (anExtr.IsMin(anIdx) &&
649 anExtr.SquareDistance(anIdx) < aMinDist)
651 aMinDist = anExtr.SquareDistance(anIdx);
652 Vsingular[1] = anExtr.Point(anIdx).Parameter();
657 Vsingular[1] = ElCLib::Parameter(L, P);
658 //SingularCase[1] = 4;
662 Standard_Real aTolU = Max(ComputeTolU(mySurface, myTolerance), Precision::Confusion());
663 Standard_Real aTolV = Max(ComputeTolV(mySurface, myTolerance), Precision::Confusion());
664 Standard_Real aTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
666 Standard_Real aMaxDist = 100. * myTolerance;
669 aMaxDist = myMaxDist;
671 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve (mySurface,myCurve, aTolU, aTolV, aMaxDist);
673 // Normalement, dans le cadre de ProjLib, le resultat
674 // doit etre une et une seule courbe !!!
675 // De plus, cette courbe ne doit pas etre Single point
676 Standard_Integer NbCurves = HProjector->NbCurves();
677 Standard_Real Udeb = 0.0,Ufin = 0.0;
680 HProjector->Bounds(1, Udeb, Ufin);
686 // Approximons cette courbe algorithmique.
687 Standard_Boolean Only3d = Standard_False;
688 Standard_Boolean Only2d = Standard_True;
689 GeomAbs_Shape Continuity = GeomAbs_C1;
690 if(myBndPnt == AppParCurves_PassPoint)
692 Continuity = GeomAbs_C0;
694 Standard_Integer MaxDegree = 14;
697 MaxDegree = myDegMax;
699 Standard_Integer MaxSeg = 16;
700 if(myMaxSegments > 0)
702 MaxSeg = myMaxSegments;
705 Approx_CurveOnSurface appr(HProjector, mySurface, Udeb, Ufin, myTolerance);
706 appr.Perform(MaxSeg, MaxDegree, Continuity, Only3d, Only2d);
708 Handle(Geom2d_BSplineCurve) aRes = appr.Curve2d();
712 aTolU = appr.MaxError2dU();
713 aTolV = appr.MaxError2dV();
714 Standard_Real aNewTol2d = Sqrt(aTolU*aTolU + aTolV*aTolV);
715 myTolerance *= (aNewTol2d / aTol2d);
716 if(IsTrimmed[0] || IsTrimmed[1])
718 // Treatment only for surface of revolution
719 Standard_Real u1, u2, v1, v2;
720 u1 = mySurface->FirstUParameter();
721 u2 = mySurface->LastUParameter();
722 v1 = mySurface->FirstVParameter();
723 v2 = mySurface->LastVParameter();
727 //Add segment before start of curve
728 ExtendC2d(aRes, f, -dt, u1, u2, Vsingular[0], v2, 0, 3);
732 //Add segment after end of curve
733 ExtendC2d(aRes, l, dt, u1, u2, v1, Vsingular[1], 1, 4);
735 Handle(Geom2d_Curve) NewCurve2d;
736 GeomLib::SameRange(Precision::PConfusion(), aRes,
737 aRes->FirstParameter(), aRes->LastParameter(),
738 FirstPar, LastPar, NewCurve2d);
739 aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
740 if(Continuity == GeomAbs_C0)
742 // try to smoother the Curve GeomAbs_C1.
743 Standard_Integer aDeg = aRes->Degree();
744 Standard_Boolean OK = Standard_True;
745 Standard_Real aSmoothTol = Max(Precision::Confusion(), aNewTol2d);
746 for (Standard_Integer ij = 2; ij < aRes->NbKnots(); ij++) {
747 OK = OK && aRes->RemoveKnot(ij, aDeg-1, aSmoothTol);
752 myResult.SetBSpline(aRes);
754 myResult.SetType(GeomAbs_BSplineCurve);
759 if ( !myResult.IsDone() && isAnalyticalSurf)
761 // Use advanced analytical projector if base analytical projection failed.
762 ProjLib_ComputeApprox Comp;
763 Comp.SetTolerance(myTolerance);
764 Comp.SetDegree(myDegMin, myDegMax);
765 Comp.SetMaxSegments(myMaxSegments);
766 Comp.SetBndPnt(myBndPnt);
767 Comp.Perform(myCurve, mySurface);
768 if (Comp.Bezier().IsNull() && Comp.BSpline().IsNull())
769 return; // advanced projector has been failed too
771 Handle(Geom2d_BSplineCurve) aRes;
772 if (Comp.BSpline().IsNull())
774 aRes = Geom2dConvert::CurveToBSplineCurve(Comp.Bezier());
778 aRes = Comp.BSpline();
780 if ((IsTrimmed[0] || IsTrimmed[1]))
784 //Add segment before start of curve
785 Standard_Real f = myCurve->FirstParameter();
786 ExtendC2d(aRes, f, -dt, U1, U2, V1, V2, 0, SingularCase[0]);
790 //Add segment after end of curve
791 Standard_Real l = myCurve->LastParameter();
792 ExtendC2d(aRes, l, dt, U1, U2, V1, V2, 1, SingularCase[1]);
794 Handle(Geom2d_Curve) NewCurve2d;
795 GeomLib::SameRange(Precision::PConfusion(), aRes,
796 aRes->FirstParameter(), aRes->LastParameter(),
797 FirstPar, LastPar, NewCurve2d);
798 aRes = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve2d);
799 myResult.SetBSpline(aRes);
800 myResult.SetType(GeomAbs_BSplineCurve);
805 if (SType == GeomAbs_Plane && CType == GeomAbs_BezierCurve)
807 myResult.SetType(GeomAbs_BezierCurve);
808 myResult.SetBezier(Comp.Bezier());
812 myResult.SetType(GeomAbs_BSplineCurve);
813 myResult.SetBSpline(Comp.BSpline());
816 // set the periodicity flag
817 if (SType == GeomAbs_Plane &&
818 CType == GeomAbs_BSplineCurve &&
819 myCurve->IsPeriodic())
821 myResult.SetPeriodic();
823 myTolerance = Comp.Tolerance();
826 Standard_Boolean isPeriodic[] = {mySurface->IsUPeriodic(),
827 mySurface->IsVPeriodic()};
828 if (myResult.IsDone() &&
829 (isPeriodic[0] || isPeriodic[1]))
831 // Check result curve to be in params space.
833 // U and V parameters space correspondingly.
834 const Standard_Real aSurfFirstPar[2] = {mySurface->FirstUParameter(),
835 mySurface->FirstVParameter()};
836 Standard_Real aSurfPeriod[2] = {0.0, 0.0};
838 aSurfPeriod[0] = mySurface->UPeriod();
840 aSurfPeriod[1] = mySurface->VPeriod();
842 for(Standard_Integer anIdx = 1; anIdx <= 2; anIdx++)
844 if (!isPeriodic[anIdx - 1])
847 if (myResult.GetType() == GeomAbs_BSplineCurve)
849 NCollection_DataMap<Standard_Integer, Standard_Integer> aMap;
850 Handle(Geom2d_BSplineCurve) aRes = myResult.BSpline();
851 const Standard_Integer aDeg = aRes->Degree();
853 for(Standard_Integer aKnotIdx = aRes->FirstUKnotIndex();
854 aKnotIdx < aRes->LastUKnotIndex();
857 const Standard_Real aFirstParam = aRes->Knot(aKnotIdx);
858 const Standard_Real aLastParam = aRes->Knot(aKnotIdx + 1);
860 for(Standard_Integer anIntIdx = 0; anIntIdx <= aDeg; anIntIdx++)
862 const Standard_Real aCurrParam = aFirstParam + (aLastParam - aFirstParam) * anIntIdx / (aDeg + 1.0);
864 aRes->D0(aCurrParam, aPnt2d);
866 Standard_Integer aMapKey = Standard_Integer ((aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1]) / aSurfPeriod[anIdx - 1]);
868 if (aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1] < 0.0)
871 if (aMap.IsBound(aMapKey))
872 aMap.ChangeFind(aMapKey)++;
874 aMap.Bind(aMapKey, 1);
878 Standard_Integer aMaxPoints = 0, aMaxIdx = 0;
879 NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator aMapIter(aMap);
880 for( ; aMapIter.More(); aMapIter.Next())
882 if (aMapIter.Value() > aMaxPoints)
884 aMaxPoints = aMapIter.Value();
885 aMaxIdx = aMapIter.Key();
890 gp_Pnt2d aFirstPnt = aRes->Value(aRes->FirstParameter());
891 gp_Pnt2d aSecondPnt = aFirstPnt;
892 aSecondPnt.SetCoord(anIdx, aFirstPnt.Coord(anIdx) - aSurfPeriod[anIdx - 1] * aMaxIdx);
893 aRes->Translate(gp_Vec2d(aFirstPnt, aSecondPnt));
897 if (myResult.GetType() == GeomAbs_Line)
899 Standard_Real aT1 = myCurve->FirstParameter();
900 Standard_Real aT2 = myCurve->LastParameter();
905 myResult.UFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]);
910 myResult.VFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]);
917 //=======================================================================
918 //function : SetDegree
920 //=======================================================================
921 void ProjLib_ProjectedCurve::SetDegree(const Standard_Integer theDegMin,
922 const Standard_Integer theDegMax)
924 myDegMin = theDegMin;
925 myDegMax = theDegMax;
927 //=======================================================================
928 //function : SetMaxSegments
930 //=======================================================================
931 void ProjLib_ProjectedCurve::SetMaxSegments(const Standard_Integer theMaxSegments)
933 myMaxSegments = theMaxSegments;
936 //=======================================================================
937 //function : SetBndPnt
939 //=======================================================================
940 void ProjLib_ProjectedCurve::SetBndPnt(const AppParCurves_Constraint theBndPnt)
942 myBndPnt = theBndPnt;
945 //=======================================================================
946 //function : SetMaxDist
948 //=======================================================================
949 void ProjLib_ProjectedCurve::SetMaxDist(const Standard_Real theMaxDist)
951 myMaxDist = theMaxDist;
954 //=======================================================================
955 //function : GetSurface
957 //=======================================================================
959 const Handle(Adaptor3d_Surface)& ProjLib_ProjectedCurve::GetSurface() const
965 //=======================================================================
966 //function : GetCurve
968 //=======================================================================
970 const Handle(Adaptor3d_Curve)& ProjLib_ProjectedCurve::GetCurve() const
976 //=======================================================================
977 //function : GetTolerance
979 //=======================================================================
981 Standard_Real ProjLib_ProjectedCurve::GetTolerance() const
987 //=======================================================================
988 //function : FirstParameter
990 //=======================================================================
992 Standard_Real ProjLib_ProjectedCurve::FirstParameter() const
994 return myCurve->FirstParameter();
998 //=======================================================================
999 //function : LastParameter
1001 //=======================================================================
1003 Standard_Real ProjLib_ProjectedCurve::LastParameter() const
1005 return myCurve->LastParameter();
1009 //=======================================================================
1010 //function : Continuity
1012 //=======================================================================
1014 GeomAbs_Shape ProjLib_ProjectedCurve::Continuity() const
1016 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Continuity() - method is not implemented");
1020 //=======================================================================
1021 //function : NbIntervals
1023 //=======================================================================
1025 Standard_Integer ProjLib_ProjectedCurve::NbIntervals(const GeomAbs_Shape ) const
1027 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::NbIntervals() - method is not implemented");
1031 //=======================================================================
1032 //function : Intervals
1034 //=======================================================================
1036 //void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& T,
1037 void ProjLib_ProjectedCurve::Intervals(TColStd_Array1OfReal& ,
1038 const GeomAbs_Shape ) const
1040 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Intervals() - method is not implemented");
1044 //=======================================================================
1045 //function : IsClosed
1047 //=======================================================================
1049 Standard_Boolean ProjLib_ProjectedCurve::IsClosed() const
1051 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::IsClosed() - method is not implemented");
1055 //=======================================================================
1056 //function : IsPeriodic
1058 //=======================================================================
1060 Standard_Boolean ProjLib_ProjectedCurve::IsPeriodic() const
1062 return myResult.IsPeriodic();
1066 //=======================================================================
1069 //=======================================================================
1071 Standard_Real ProjLib_ProjectedCurve::Period() const
1073 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Period() - method is not implemented");
1077 //=======================================================================
1080 //=======================================================================
1082 gp_Pnt2d ProjLib_ProjectedCurve::Value(const Standard_Real ) const
1084 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Value() - method is not implemented");
1088 //=======================================================================
1091 //=======================================================================
1093 void ProjLib_ProjectedCurve::D0(const Standard_Real , gp_Pnt2d& ) const
1095 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D0() - method is not implemented");
1099 //=======================================================================
1102 //=======================================================================
1104 void ProjLib_ProjectedCurve::D1(const Standard_Real ,
1108 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D1() - method is not implemented");
1112 //=======================================================================
1115 //=======================================================================
1117 void ProjLib_ProjectedCurve::D2(const Standard_Real ,
1122 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D2() - method is not implemented");
1126 //=======================================================================
1129 //=======================================================================
1131 void ProjLib_ProjectedCurve::D3(const Standard_Real,
1137 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::D3() - method is not implemented");
1141 //=======================================================================
1144 //=======================================================================
1146 gp_Vec2d ProjLib_ProjectedCurve::DN(const Standard_Real,
1147 const Standard_Integer) const
1149 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::DN() - method is not implemented");
1153 //=======================================================================
1154 //function : Resolution
1156 //=======================================================================
1158 Standard_Real ProjLib_ProjectedCurve::Resolution(const Standard_Real) const
1160 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Resolution() - method is not implemented");
1164 //=======================================================================
1165 //function : GetType
1167 //=======================================================================
1169 GeomAbs_CurveType ProjLib_ProjectedCurve::GetType() const
1171 return myResult.GetType();
1175 //=======================================================================
1178 //=======================================================================
1180 gp_Lin2d ProjLib_ProjectedCurve::Line() const
1182 return myResult.Line();
1186 //=======================================================================
1189 //=======================================================================
1191 gp_Circ2d ProjLib_ProjectedCurve::Circle() const
1193 return myResult.Circle();
1197 //=======================================================================
1198 //function : Ellipse
1200 //=======================================================================
1202 gp_Elips2d ProjLib_ProjectedCurve::Ellipse() const
1204 return myResult.Ellipse();
1208 //=======================================================================
1209 //function : Hyperbola
1211 //=======================================================================
1213 gp_Hypr2d ProjLib_ProjectedCurve::Hyperbola() const
1215 return myResult.Hyperbola();
1219 //=======================================================================
1220 //function : Parabola
1222 //=======================================================================
1224 gp_Parab2d ProjLib_ProjectedCurve::Parabola() const
1226 return myResult.Parabola();
1231 //=======================================================================
1234 //=======================================================================
1236 Standard_Integer ProjLib_ProjectedCurve::Degree() const
1238 Standard_NoSuchObject_Raise_if
1239 ( (GetType() != GeomAbs_BSplineCurve) &&
1240 (GetType() != GeomAbs_BezierCurve),
1241 "ProjLib_ProjectedCurve:Degree");
1242 if (GetType() == GeomAbs_BSplineCurve) {
1243 return myResult.BSpline()->Degree();
1245 else if (GetType() == GeomAbs_BezierCurve) {
1246 return myResult.Bezier()->Degree();
1253 //=======================================================================
1254 //function : IsRational
1256 //=======================================================================
1258 Standard_Boolean ProjLib_ProjectedCurve::IsRational() const
1260 Standard_NoSuchObject_Raise_if
1261 ( (GetType() != GeomAbs_BSplineCurve) &&
1262 (GetType() != GeomAbs_BezierCurve),
1263 "ProjLib_ProjectedCurve:IsRational");
1264 if (GetType() == GeomAbs_BSplineCurve) {
1265 return myResult.BSpline()->IsRational();
1267 else if (GetType() == GeomAbs_BezierCurve) {
1268 return myResult.Bezier()->IsRational();
1271 return Standard_False;
1274 //=======================================================================
1275 //function : NbPoles
1277 //=======================================================================
1279 Standard_Integer ProjLib_ProjectedCurve::NbPoles() const
1281 Standard_NoSuchObject_Raise_if
1282 ( (GetType() != GeomAbs_BSplineCurve) &&
1283 (GetType() != GeomAbs_BezierCurve)
1284 ,"ProjLib_ProjectedCurve:NbPoles" );
1285 if (GetType() == GeomAbs_BSplineCurve) {
1286 return myResult.BSpline()->NbPoles();
1288 else if (GetType() == GeomAbs_BezierCurve) {
1289 return myResult.Bezier()->NbPoles();
1296 //=======================================================================
1297 //function : NbKnots
1299 //=======================================================================
1301 Standard_Integer ProjLib_ProjectedCurve::NbKnots() const
1303 Standard_NoSuchObject_Raise_if ( GetType() != GeomAbs_BSplineCurve,
1304 "ProjLib_ProjectedCurve:NbKnots");
1305 return myResult.BSpline()->NbKnots();
1308 //=======================================================================
1311 //=======================================================================
1313 Handle(Geom2d_BezierCurve) ProjLib_ProjectedCurve::Bezier() const
1315 return myResult.Bezier() ;
1318 //=======================================================================
1319 //function : BSpline
1321 //=======================================================================
1323 Handle(Geom2d_BSplineCurve) ProjLib_ProjectedCurve::BSpline() const
1325 return myResult.BSpline() ;
1327 //=======================================================================
1330 //=======================================================================
1332 Handle(Adaptor2d_Curve2d) ProjLib_ProjectedCurve::Trim
1333 //(const Standard_Real First,
1334 // const Standard_Real Last,
1335 // const Standard_Real Tolerance) const
1336 (const Standard_Real ,
1337 const Standard_Real ,
1338 const Standard_Real ) const
1340 throw Standard_NotImplemented ("ProjLib_ProjectedCurve::Trim() - method is not implemented");