1 // Created by: Bruno DUMORTIER
2 // Copyright (c) 1995-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and / or modify it
8 // under the terms of the GNU Lesser General Public version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <ProjLib_ComputeApproxOnPolarSurface.hxx>
17 #include <AppCont_Function2d.hxx>
20 #include <BSplCLib.hxx>
22 #include <Standard_NoSuchObject.hxx>
23 #include <Geom_UndefinedDerivative.hxx>
24 #include <gp_Trsf.hxx>
25 #include <Precision.hxx>
26 #include <Approx_FitAndDivide2d.hxx>
28 #include <AppParCurves_MultiCurve.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom2d_BezierCurve.hxx>
32 #include <Geom2d_Line.hxx>
33 #include <Geom2d_Circle.hxx>
34 #include <Geom2d_Ellipse.hxx>
35 #include <Geom2d_Hyperbola.hxx>
36 #include <Geom2d_Parabola.hxx>
37 #include <Geom2d_TrimmedCurve.hxx>
38 #include <Geom_BSplineSurface.hxx>
39 #include <Geom_BezierSurface.hxx>
40 #include <Geom_BSplineCurve.hxx>
41 #include <Geom_BezierCurve.hxx>
42 #include <Geom_TrimmedCurve.hxx>
44 #include <TColgp_Array1OfPnt2d.hxx>
45 #include <TColgp_Array2OfPnt2d.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
47 #include <TColgp_SequenceOfPnt2d.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_Array1OfInteger.hxx>
50 #include <TColStd_SequenceOfReal.hxx>
51 #include <TColStd_ListOfTransient.hxx>
53 #include <GeomAbs_SurfaceType.hxx>
54 #include <GeomAbs_CurveType.hxx>
55 #include <Handle_Adaptor3d_HCurve.hxx>
56 #include <Handle_Adaptor3d_HSurface.hxx>
57 #include <Adaptor3d_Surface.hxx>
58 #include <Adaptor3d_Curve.hxx>
59 #include <Adaptor3d_HSurface.hxx>
60 #include <Adaptor3d_HCurve.hxx>
61 #include <Adaptor2d_HCurve2d.hxx>
62 #include <Geom2dAdaptor_Curve.hxx>
63 #include <Geom2dAdaptor_HCurve.hxx>
64 #include <GeomAdaptor_HCurve.hxx>
65 #include <GeomAdaptor.hxx>
66 #include <GeomAdaptor_Surface.hxx>
67 #include <TColgp_SequenceOfPnt.hxx>
70 #include <gp_Pnt2d.hxx>
71 #include <gp_Vec2d.hxx>
72 #include <Extrema_GenLocateExtPS.hxx>
73 #include <Extrema_ExtPS.hxx>
74 #include <GCPnts_QuasiUniformAbscissa.hxx>
75 #include <Standard_DomainError.hxx>
76 //#include <GeomLib_IsIso.hxx>
77 //#include <GeomLib_CheckSameParameter.hxx>
81 #include <DrawTrSurf.hxx>
83 //static Standard_Integer compteur = 0;
86 //=======================================================================
88 //purpose : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
89 // <InitCurve2d> use for calculate start 2D point.
90 //=======================================================================
92 static gp_Pnt2d Function_Value(const Standard_Real U,
93 const Handle(Adaptor3d_HSurface)& Surf,
94 const Handle(Adaptor3d_HCurve)& Curve,
95 const Handle(Adaptor2d_HCurve2d)& InitCurve2d,
97 const Standard_Real DistTol3d, const Standard_Real tolU, const Standard_Real tolV)
98 //const Standard_Real Tolerance)
101 //Standard_Real Tol3d = 100*Tolerance;
103 gp_Pnt2d p2d = InitCurve2d->Value(U) ;
104 gp_Pnt p = Curve->Value(U);
106 Standard_Real Uinf, Usup, Vinf, Vsup;
107 Uinf = Surf->Surface().FirstUParameter();
108 Usup = Surf->Surface().LastUParameter();
109 Vinf = Surf->Surface().FirstVParameter();
110 Vsup = Surf->Surface().LastVParameter();
111 Standard_Integer decalU = 0, decalV = 0;
112 Standard_Real U0 = p2d.X(), V0 = p2d.Y();
114 GeomAbs_SurfaceType Type = Surf->GetType();
115 if((Type != GeomAbs_BSplineSurface) &&
116 (Type != GeomAbs_BezierSurface) &&
117 (Type != GeomAbs_OffsetSurface) ) {
118 Standard_Real S = 0., T = 0.;
120 // case GeomAbs_Plane:
122 // gp_Pln Plane = Surf->Plane();
123 // ElSLib::Parameters( Plane, p, S, T);
126 case GeomAbs_Cylinder:
128 gp_Cylinder Cylinder = Surf->Cylinder();
129 ElSLib::Parameters( Cylinder, p, S, T);
130 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
131 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
137 gp_Cone Cone = Surf->Cone();
138 ElSLib::Parameters( Cone, p, S, T);
139 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
140 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
146 gp_Sphere Sphere = Surf->Sphere();
147 ElSLib::Parameters( Sphere, p, S, T);
148 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
149 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
151 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
152 if(V0 > (Vsup+(Vsup-Vinf))) decalV = int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
154 if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI) {
165 gp_Torus Torus = Surf->Torus();
166 ElSLib::Parameters( Torus, p, S, T);
167 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
168 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
169 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
170 if(V0 > Vsup) decalV = int((V0 - Vsup)/(2*M_PI))+1;
171 S += decalU*2*M_PI; T += decalV*2*M_PI;
175 Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::Value");
177 return gp_Pnt2d(S, T);
181 Standard_Real Dist2Min = RealLast();
183 //Standard_Real tolU,tolV ;
187 Standard_Real uperiod =0, vperiod = 0, u, v;
188 // U0 and V0 are the points within the initialized period
189 // (periode with u and v),
190 // U1 and V1 are the points for construction of tops
192 if(Surf->IsUPeriodic() || Surf->IsUClosed()) {
193 uperiod = Surf->LastUParameter() - Surf->FirstUParameter();
195 if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
196 vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
202 decalU = int((Uinf - U0)/uperiod)+1;
203 U0 += decalU*uperiod;
210 decalU = -(int((U0 - Usup)/uperiod)+1);
211 U0 += decalU*uperiod;
218 decalV = int((Vinf - V0)/vperiod)+1;
219 V0 += decalV*vperiod;
226 decalV = -int((V0 - Vsup)/vperiod)-1;
227 V0 += decalV*vperiod;
231 // The surface around U0 is reduced
232 Standard_Real uLittle = (Usup - Uinf)/10, vLittle = (Vsup - Vinf)/10;
233 Standard_Real uInfLi = 0, vInfLi = 0,uSupLi = 0, vSupLi = 0;
234 if((U0 - Uinf) > uLittle) uInfLi = U0 - uLittle; else uInfLi = Uinf;
235 if((V0 - Vinf) > vLittle) vInfLi = V0 - vLittle; else vInfLi = Vinf;
236 if((Usup - U0) > uLittle) uSupLi = U0 + uLittle; else uSupLi = Usup;
237 if((Vsup - V0) > vLittle) vSupLi = V0 + vLittle; else vSupLi = Vsup;
239 // const Adaptor3d_Surface GAS = Surf->Surface();
241 GeomAdaptor_Surface SurfLittle;
242 if (Type == GeomAbs_BSplineSurface) {
243 Handle(Geom_Surface) GBSS(Surf->Surface().BSpline());
244 SurfLittle.Load(GBSS, uInfLi, uSupLi, vInfLi, vSupLi);
246 else if (Type == GeomAbs_BezierSurface) {
247 Handle(Geom_Surface) GS(Surf->Surface().Bezier());
248 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
250 else if (Type == GeomAbs_OffsetSurface) {
251 Handle(Geom_Surface) GS = GeomAdaptor::MakeSurface(Surf->Surface());
252 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
255 Standard_NoSuchObject::Raise("");
258 Extrema_GenLocateExtPS locext(p, SurfLittle, U0, V0, tolU, tolV);
259 if (locext.IsDone()) {
260 Dist2Min = locext.SquareDistance();
261 if (Dist2Min < DistTol3d * DistTol3d) {
262 (locext.Point()).Parameter(u, v);
263 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
268 Extrema_ExtPS ext(p, SurfLittle, tolU, tolV) ;
269 if (ext.IsDone() && ext.NbExt()>=1 ) {
270 Dist2Min = ext.SquareDistance(1);
271 Standard_Integer GoodValue = 1;
272 for ( Standard_Integer i = 2 ; i <= ext.NbExt() ; i++ )
273 if( Dist2Min > ext.SquareDistance(i)) {
274 Dist2Min = ext.SquareDistance(i);
277 if (Dist2Min < DistTol3d * DistTol3d) {
278 (ext.Point(GoodValue)).Parameter(u,v);
279 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
288 //=======================================================================
289 //function : ProjLib_PolarFunction
290 //purpose : (OCC217 - apo)- This class produce interface to call "gp_Pnt2d Function_Value(...)"
291 //=======================================================================
293 class ProjLib_PolarFunction : public AppCont_Function2d
295 Handle(Adaptor3d_HCurve) myCurve;
296 Handle(Adaptor2d_HCurve2d) myInitialCurve2d ;
297 Handle(Adaptor3d_HSurface) mySurface ;
299 Standard_Real myTolU, myTolV;
300 Standard_Real myDistTol3d;
301 //Standard_Real myTolerance ;
305 ProjLib_PolarFunction(const Handle(Adaptor3d_HCurve) & C,
306 const Handle(Adaptor3d_HSurface)& Surf,
307 const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
309 const Standard_Real Tol3d) :
310 //const Standard_Real Tolerance) :
312 myInitialCurve2d(InitialCurve2d),
315 myTolU(Surf->UResolution(Tol3d)),
316 myTolV(Surf->VResolution(Tol3d)),
317 myDistTol3d(100.0*Tol3d){} ;
318 //myTolerance(Tolerance){} ;
320 ~ProjLib_PolarFunction() {}
322 Standard_Real FirstParameter() const
323 {return (myCurve->FirstParameter()/*+1.e-9*/);}
325 Standard_Real LastParameter() const
326 {return (myCurve->LastParameter()/*-1.e-9*/);}
328 gp_Pnt2d Value(const Standard_Real t) const {
329 return Function_Value
330 (t,mySurface,myCurve,myInitialCurve2d,myDistTol3d,myTolU,myTolV) ; //OCC217
331 //(t,mySurface,myCurve,myInitialCurve2d,myTolerance) ;
334 // Standard_Boolean D1(const Standard_Real t, gp_Pnt2d& P, gp_Vec2d& V) const
335 Standard_Boolean D1(const Standard_Real , gp_Pnt2d& , gp_Vec2d& ) const
336 {return Standard_False;}
339 //=======================================================================
340 //function : ProjLib_ComputeApproxOnPolarSurface
342 //=======================================================================
344 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface(){}
347 //=======================================================================
348 //function : ProjLib_ComputeApproxOnPolarSurface
350 //=======================================================================
352 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
353 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
354 const Handle(Adaptor3d_HCurve)& Curve,
355 const Handle(Adaptor3d_HSurface)& S,
356 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
357 //const Standard_Real tolerance):myProjIsDone(Standard_False)
359 myTolerance = tol3d; //OCC217
360 //myTolerance = Max(Tolerance,Precision::PApproximation());
361 myBSpline = Perform(InitialCurve2d,Curve,S);
363 //=======================================================================
364 //function : ProjLib_ComputeApproxOnPolarSurface
365 //purpose : Process the case of sewing
366 //=======================================================================
368 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
369 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
370 const Handle(Adaptor2d_HCurve2d)& InitialCurve2dBis,
371 const Handle(Adaptor3d_HCurve)& Curve,
372 const Handle(Adaptor3d_HSurface)& S,
373 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
374 //const Standard_Real tolerance):myProjIsDone(Standard_False)
375 {// InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing
376 myTolerance = tol3d; //OCC217
377 //myTolerance = Max(tolerance,Precision::PApproximation());
378 Handle(Geom2d_BSplineCurve) bsc = Perform(InitialCurve2d,Curve,S);
380 gp_Pnt2d P2dproj, P2d, P2dBis;
381 P2dproj = bsc->StartPoint();
382 P2d = InitialCurve2d->Value(InitialCurve2d->FirstParameter());
383 P2dBis = InitialCurve2dBis->Value(InitialCurve2dBis->FirstParameter());
385 Standard_Real Dist, DistBis;
386 Dist = P2dproj.Distance(P2d);
387 DistBis = P2dproj.Distance(P2dBis);
388 if( Dist < DistBis) {
389 // myBSpline2d is the pcurve that is found. It is translated to obtain myCurve2d
391 Handle(Geom2d_Geometry) GG = myBSpline->Translated(P2d, P2dBis);
392 my2ndCurve = Handle(Geom2d_Curve)::DownCast(GG);
396 Handle(Geom2d_Geometry) GG = my2ndCurve->Translated(P2dBis, P2d);
397 myBSpline = Handle(Geom2d_BSplineCurve)::DownCast(GG);
402 //=======================================================================
403 //function : ProjLib_ComputeApproxOnPolarSurface
404 //purpose : case without curve of initialization
405 //=======================================================================
407 ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
408 (const Handle(Adaptor3d_HCurve)& Curve,
409 const Handle(Adaptor3d_HSurface)& S,
410 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
411 //const Standard_Real tolerance):myProjIsDone(Standard_False)
413 myTolerance = tol3d; //OCC217
414 //myTolerance = Max(tolerance,Precision::PApproximation());
415 const Handle_Adaptor2d_HCurve2d InitCurve2d ;
416 myBSpline = Perform(InitCurve2d,Curve,S);
419 static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1,
420 Handle(Geom2d_BSplineCurve) C2)
422 Standard_Integer deg, deg1, deg2;
427 C1->IncreaseDegree(deg2);
430 else if ( deg2 < deg1) {
431 C2->IncreaseDegree(deg1);
436 Standard_Integer np1,np2,nk1,nk2,np,nk;
444 TColStd_Array1OfReal K1(1,nk1); C1->Knots(K1);
445 TColStd_Array1OfInteger M1(1,nk1); C1->Multiplicities(M1);
446 TColgp_Array1OfPnt2d P1(1,np1); C1->Poles(P1);
447 TColStd_Array1OfReal K2(1,nk2); C2->Knots(K2);
448 TColStd_Array1OfInteger M2(1,nk2); C2->Multiplicities(M2);
449 TColgp_Array1OfPnt2d P2(1,np2); C2->Poles(P2);
451 // Compute the new BSplineCurve
452 TColStd_Array1OfReal K(1,nk);
453 TColStd_Array1OfInteger M(1,nk);
454 TColgp_Array1OfPnt2d P(1,np);
456 Standard_Integer i, count = 0;
457 // Set Knots and Mults
458 for ( i = 1; i <= nk1; i++) {
464 for ( i = 2; i <= nk2; i++) {
471 for (i = 1; i <= np1; i++) {
475 for (i = 2; i <= np2; i++) {
480 Handle(Geom2d_BSplineCurve) BS =
481 new Geom2d_BSplineCurve(P,K,M,deg);
486 //=======================================================================
489 //=======================================================================
490 Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
491 (const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
492 const Handle(Adaptor3d_HCurve)& Curve,
493 const Handle(Adaptor3d_HSurface)& S)
496 Standard_Real Tol3d = myTolerance;
497 Standard_Real ParamTol = Precision::PApproximation();
499 Handle(Adaptor2d_HCurve2d) AHC2d = InitialCurve2d;
500 Handle(Adaptor3d_HCurve) AHC = Curve;
502 // if the curve 3d is a BSpline with degree C0, it is cut into sections with degree C1
504 GeomAbs_CurveType typeCurve = Curve->GetType();
505 if(typeCurve == GeomAbs_BSplineCurve) {
506 TColStd_ListOfTransient LOfBSpline2d;
507 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
508 Standard_Integer nbInter = Curve->NbIntervals(GeomAbs_C1);
510 Standard_Integer i, j;
511 Handle(Geom_TrimmedCurve) GTC;
512 Handle(Geom2d_TrimmedCurve) G2dTC;
513 TColStd_Array1OfReal Inter(1,nbInter+1);
514 Curve->Intervals(Inter,GeomAbs_C1);
515 Standard_Real firstinter = Inter.Value(1), secondinter = Inter.Value(2);
517 GTC = new Geom_TrimmedCurve(BSC, firstinter, secondinter);
518 AHC = new GeomAdaptor_HCurve(GTC);
520 // if there is an initialization curve:
521 // - either this is a BSpline C0, with discontinuity at the same parameters of nodes
522 // and the sections C1 are taken
523 // - or this is a curve C1 and the sections of intrest are taken otherwise the curve is created.
526 Standard_Integer nbInter2d;
527 Standard_Boolean C2dIsToCompute;
528 C2dIsToCompute = InitialCurve2d.IsNull();
529 Handle(Geom2d_BSplineCurve) BSC2d;
530 Handle(Geom2d_Curve) G2dC;
532 if(!C2dIsToCompute) {
533 nbInter2d = InitialCurve2d->NbIntervals(GeomAbs_C1);
534 TColStd_Array1OfReal Inter2d(1,nbInter2d+1);
535 InitialCurve2d->Intervals(Inter2d,GeomAbs_C1);
537 for(i = 1,j = 1;i <= nbInter;i++)
538 if(Abs(Inter.Value(i) - Inter2d.Value(j)) < ParamTol) { //OCC217
539 //if(Abs(Inter.Value(i) - Inter2d.Value(j)) < myTolerance) {
540 if (j > nbInter2d) break;
543 if(j != (nbInter2d+1)) {
544 C2dIsToCompute = Standard_True;
549 AHC2d = BuildInitialCurve2d(AHC, S);
552 typeCurve = InitialCurve2d->GetType();
555 G2dC = new Geom2d_Line(InitialCurve2d->Line());
558 case GeomAbs_Circle: {
559 G2dC = new Geom2d_Circle(InitialCurve2d->Circle());
562 case GeomAbs_Ellipse: {
563 G2dC = new Geom2d_Ellipse(InitialCurve2d->Ellipse());
566 case GeomAbs_Hyperbola: {
567 G2dC = new Geom2d_Hyperbola(InitialCurve2d->Hyperbola());
570 case GeomAbs_Parabola: {
571 G2dC = new Geom2d_Parabola(InitialCurve2d->Parabola());
574 case GeomAbs_BezierCurve: {
575 G2dC = InitialCurve2d->Bezier();
578 case GeomAbs_BSplineCurve: {
579 G2dC = InitialCurve2d->BSpline();
582 case GeomAbs_OtherCurve:
586 gp_Pnt2d fp2d = G2dC->Value(firstinter), lp2d = G2dC->Value(secondinter);
587 gp_Pnt fps, lps, fpc, lpc;
588 S->D0(fp2d.X(), fp2d.Y(), fps);
589 S->D0(lp2d.X(), lp2d.Y(), lps);
590 Curve->D0(firstinter, fpc);
591 Curve->D0(secondinter, lpc);
593 if((fps.IsEqual(fpc, Tol3d)) &&
594 (lps.IsEqual(lpc, Tol3d))) {
595 //if((fps.IsEqual(fpc, myTolerance)) &&
596 // (lps.IsEqual(lpc, myTolerance))) {
597 G2dTC = new Geom2d_TrimmedCurve(G2dC, firstinter, secondinter);
598 Geom2dAdaptor_Curve G2dAC(G2dTC);
599 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
600 myProjIsDone = Standard_True;
603 AHC2d = BuildInitialCurve2d(AHC, S);
604 C2dIsToCompute = Standard_True;
609 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
610 if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV
611 LOfBSpline2d.Append(BSC2d);
614 return Handle(Geom2d_BSplineCurve)();
619 Standard_Real iinter, ip1inter;
620 Standard_Integer nbK2d, deg;
621 nbK2d = BSC2d->NbKnots(); deg = BSC2d->Degree();
623 for(i = 2;i <= nbInter;i++) {
624 iinter = Inter.Value(i);
625 ip1inter = Inter.Value(i+1);
627 GTC->SetTrim(iinter, ip1inter);
628 AHC = new GeomAdaptor_HCurve(GTC);
632 AHC2d = BuildInitialCurve2d(AHC, S);
635 gp_Pnt2d fp2d = G2dC->Value(iinter), lp2d = G2dC->Value(ip1inter);
636 gp_Pnt fps, lps, fpc, lpc;
637 S->D0(fp2d.X(), fp2d.Y(), fps);
638 S->D0(lp2d.X(), lp2d.Y(), lps);
639 Curve->D0(iinter, fpc);
640 Curve->D0(ip1inter, lpc);
642 if((fps.IsEqual(fpc, Tol3d)) &&
643 (lps.IsEqual(lpc, Tol3d))) {
644 //if((fps.IsEqual(fpc, myTolerance)) &&
645 // (lps.IsEqual(lpc, myTolerance))) {
646 G2dTC->SetTrim(iinter, ip1inter);
647 Geom2dAdaptor_Curve G2dAC(G2dTC);
648 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
649 myProjIsDone = Standard_True;
652 AHC2d = BuildInitialCurve2d(AHC, S);
656 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
658 return Handle(Geom2d_BSplineCurve)();
660 LOfBSpline2d.Append(BSC2d);
661 nbK2d += BSC2d->NbKnots() - 1;
662 deg = Max(deg, BSC2d->Degree());
665 return Handle(Geom2d_BSplineCurve)();
669 Standard_Integer NbC = LOfBSpline2d.Extent();
670 Handle(Geom2d_BSplineCurve) CurBS;
671 CurBS = Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
672 LOfBSpline2d.RemoveFirst();
673 for (Standard_Integer ii = 2; ii <= NbC; ii++) {
674 Handle(Geom2d_BSplineCurve) BS =
675 Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
676 CurBS = Concat(CurBS,BS);
677 LOfBSpline2d.RemoveFirst();
683 if(InitialCurve2d.IsNull()) {
684 AHC2d = BuildInitialCurve2d(Curve, S);
686 return Handle(Geom2d_BSplineCurve)();
688 return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
691 //=======================================================================
692 //function : ProjLib_BuildInitialCurve2d
694 //=======================================================================
696 Handle(Adaptor2d_HCurve2d)
697 ProjLib_ComputeApproxOnPolarSurface::
698 BuildInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
699 const Handle(Adaptor3d_HSurface)& Surf)
701 // discretize the Curve with quasiuniform deflection
702 // density at least NbOfPnts points
703 myProjIsDone = Standard_False;
706 Standard_Real Tol3d = myTolerance;
707 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
708 Standard_Real DistTol3d = 100.0*Tol3d;
710 Standard_Real uperiod = 0., vperiod = 0.;
711 if(Surf->IsUPeriodic() || Surf->IsUClosed())
712 uperiod = Surf->LastUParameter() - Surf->FirstUParameter();
714 if(Surf->IsVPeriodic() || Surf->IsVClosed())
715 vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
718 // NO myTol is Tol2d !!!!
719 //Standard_Real TolU = myTolerance, TolV = myTolerance;
720 //Standard_Real Tol3d = 100*myTolerance; // At random Balthazar.
722 Standard_Integer NbOfPnts = 61;
723 GCPnts_QuasiUniformAbscissa QUA(Curve->GetCurve(),NbOfPnts);
724 TColgp_Array1OfPnt Pts(1,NbOfPnts);
725 TColStd_Array1OfReal Param(1,NbOfPnts);
726 Standard_Integer i, j;
727 for( i = 1; i <= NbOfPnts ; i++ ) {
728 Param(i) = QUA.Parameter(i);
729 Pts(i) = Curve->Value(Param(i));
732 TColgp_Array1OfPnt2d Pts2d(1,NbOfPnts);
733 TColStd_Array1OfInteger Mult(1,NbOfPnts);
735 Mult(1) = Mult(NbOfPnts) = 2;
737 Standard_Real Uinf, Usup, Vinf, Vsup;
738 Uinf = Surf->Surface().FirstUParameter();
739 Usup = Surf->Surface().LastUParameter();
740 Vinf = Surf->Surface().FirstVParameter();
741 Vsup = Surf->Surface().LastVParameter();
742 GeomAbs_SurfaceType Type = Surf->GetType();
743 if((Type != GeomAbs_BSplineSurface) && (Type != GeomAbs_BezierSurface) &&
744 (Type != GeomAbs_OffsetSurface)) {
746 // Standard_Integer usens = 0, vsens = 0;
747 // to know the position relatively to the period
749 // case GeomAbs_Plane:
751 // gp_Pln Plane = Surf->Plane();
752 // for ( i = 1 ; i <= NbOfPnts ; i++) {
753 // ElSLib::Parameters( Plane, Pts(i), S, T);
754 // Pts2d(i).SetCoord(S,T);
756 // myProjIsDone = Standard_True;
759 case GeomAbs_Cylinder:
761 // Standard_Real Sloc, Tloc;
763 Standard_Integer usens = 0;
764 gp_Cylinder Cylinder = Surf->Cylinder();
765 ElSLib::Parameters( Cylinder, Pts(1), S, T);
766 Pts2d(1).SetCoord(S,T);
767 for ( i = 2 ; i <= NbOfPnts ; i++) {
769 ElSLib::Parameters( Cylinder, Pts(i), S, T);
770 if(Abs(Sloc - S) > M_PI) {
776 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
778 myProjIsDone = Standard_True;
783 // Standard_Real Sloc, Tloc;
785 Standard_Integer usens = 0;
786 gp_Cone Cone = Surf->Cone();
787 ElSLib::Parameters( Cone, Pts(1), S, T);
788 Pts2d(1).SetCoord(S,T);
789 for ( i = 2 ; i <= NbOfPnts ; i++) {
791 ElSLib::Parameters( Cone, Pts(i), S, T);
792 if(Abs(Sloc - S) > M_PI) {
798 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
800 myProjIsDone = Standard_True;
805 Standard_Real Sloc, Tloc;
806 Standard_Integer usens = 0, vsens = 0; //usens steps by half-period
807 Standard_Boolean vparit = Standard_False;
808 gp_Sphere Sphere = Surf->Sphere();
809 ElSLib::Parameters( Sphere, Pts(1), S, T);
810 Pts2d(1).SetCoord(S,T);
811 for ( i = 2 ; i <= NbOfPnts ; i++) {
813 ElSLib::Parameters( Sphere, Pts(i), S, T);
814 if(1.6*M_PI < Abs(Sloc - S)) {
820 if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
826 if(Abs(Tloc - Vsup) < (Vsup - Vinf)/5)
832 Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
835 Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
839 myProjIsDone = Standard_True;
844 Standard_Real Sloc, Tloc;
845 Standard_Integer usens = 0, vsens = 0;
846 gp_Torus Torus = Surf->Torus();
847 ElSLib::Parameters( Torus, Pts(1), S, T);
848 Pts2d(1).SetCoord(S,T);
849 for ( i = 2 ; i <= NbOfPnts ; i++) {
851 ElSLib::Parameters( Torus, Pts(i), S, T);
852 if(Abs(Sloc - S) > M_PI) {
858 if(Abs(Tloc - T) > M_PI) {
864 Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
866 myProjIsDone = Standard_True;
870 Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
874 myProjIsDone = Standard_False;
875 Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
878 TColgp_SequenceOfPnt2d Sols;
879 Standard_Boolean areManyZeros = Standard_False;
881 Curve->D0(Param.Value(1), pntproj) ;
882 Extrema_ExtPS aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
883 Standard_Real aMinSqDist = RealLast();
886 for (i = 1; i <= aExtPS.NbExt(); i++)
888 Standard_Real aSqDist = aExtPS.SquareDistance(i);
889 if (aSqDist < aMinSqDist)
890 aMinSqDist = aSqDist;
893 if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
895 TolU = Min(TolU, Precision::PConfusion());
896 TolV = Min(TolV, Precision::PConfusion());
897 aExtPS.Initialize(Surf->Surface(),
898 Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(),
899 Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
901 aExtPS.Perform(pntproj);
904 if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
906 Standard_Integer GoodValue = 1;
908 for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
909 if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) {
910 if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
911 aExtPS.Point(i).Parameter(u,v);
913 Standard_Boolean isSame = Standard_False;
914 for( j = 1; j <= Sols.Length(); j++ ) {
915 if( p2d.SquareDistance( Sols.Value(j) ) <= 1.e-18 ) {
916 isSame = Standard_True;
920 if( !isSame ) Sols.Append( p2d );
922 if( Dist2Min > aExtPS.SquareDistance(i) ) {
923 Dist2Min = aExtPS.SquareDistance(i);
929 if( Sols.Length() > 1 ) areManyZeros = Standard_True;
931 if( Dist2Min <= DistTol3d * DistTol3d) {
932 if( !areManyZeros ) {
933 aExtPS.Point(GoodValue).Parameter(u,v);
934 Pts2d(1).SetCoord(u,v);
935 myProjIsDone = Standard_True;
938 Standard_Integer nbSols = Sols.Length();
939 Standard_Real Dist2Max = -1.e+200;
940 for( i = 1; i <= nbSols; i++ ) {
941 const gp_Pnt2d& aP1 = Sols.Value(i);
942 for( j = i+1; j <= nbSols; j++ ) {
943 const gp_Pnt2d& aP2 = Sols.Value(j);
944 Standard_Real aDist2 = aP1.SquareDistance(aP2);
945 if( aDist2 > Dist2Max ) Dist2Max = aDist2;
948 Standard_Real aMaxT2 = Max(TolU,TolV);
950 if( Dist2Max > aMaxT2 ) {
951 Standard_Integer tPp = 0;
952 for( i = 1; i <= 5; i++ ) {
953 Standard_Integer nbExtOk = 0;
954 Standard_Integer indExt = 0;
955 Standard_Integer iT = 1 + (NbOfPnts - 1)/5*i;
956 Curve->D0( Param.Value(iT), pntproj );
957 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
959 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
960 for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
961 if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) {
963 if( aTPS.SquareDistance(j) < Dist2Min ) {
964 Dist2Min = aTPS.SquareDistance(j);
972 aTPS.Point(indExt).Parameter(u,v);
978 gp_Pnt2d aPp = gp_Pnt2d(u,v);
981 Standard_Boolean isFound = Standard_False;
983 Curve->D0( Param.Value(tPp+j), pntproj );
984 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
986 Standard_Integer indExt = 0;
987 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
988 for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
989 if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) {
990 Dist2Min = aTPS.SquareDistance(i);
992 isFound = Standard_True;
997 aTPS.Point(indExt).Parameter(u,v);
1002 if( (tPp+j) > NbOfPnts ) break;
1006 gp_Vec2d atV(aPp,aPn);
1007 Standard_Boolean isChosen = Standard_False;
1008 for( i = 1; i <= nbSols; i++ ) {
1009 const gp_Pnt2d& aP1 = Sols.Value(i);
1010 gp_Vec2d asV(aP1,aPp);
1011 if( asV.Dot(atV) > 0. ) {
1012 isChosen = Standard_True;
1013 Pts2d(1).SetCoord(aP1.X(),aP1.Y());
1014 myProjIsDone = Standard_True;
1019 aExtPS.Point(GoodValue).Parameter(u,v);
1020 Pts2d(1).SetCoord(u,v);
1021 myProjIsDone = Standard_True;
1025 aExtPS.Point(GoodValue).Parameter(u,v);
1026 Pts2d(1).SetCoord(u,v);
1027 myProjIsDone = Standard_True;
1031 aExtPS.Point(GoodValue).Parameter(u,v);
1032 Pts2d(1).SetCoord(u,v);
1033 myProjIsDone = Standard_True;
1037 aExtPS.Point(GoodValue).Parameter(u,v);
1038 Pts2d(1).SetCoord(u,v);
1039 myProjIsDone = Standard_True;
1044 // calculate the following points with GenLocate_ExtPS
1045 // (and store the result and each parameter in a sequence)
1046 Standard_Integer usens = 0, vsens = 0;
1047 // to know the position relatively to the period
1048 Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
1049 // U0 and V0 are the points in the initialized period
1050 // (period with u and v),
1051 // U1 and V1 are the points for construction of poles
1053 for ( i = 2 ; i <= NbOfPnts ; i++)
1055 myProjIsDone = Standard_False;
1056 Dist2Min = RealLast();
1057 Curve->D0(Param.Value(i), pntproj);
1058 Extrema_GenLocateExtPS aLocateExtPS
1059 (pntproj, Surf->Surface(), U0, V0, TolU, TolV) ;
1061 if (aLocateExtPS.IsDone())
1062 if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
1063 //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
1064 (aLocateExtPS.Point()).Parameter(U0,V0);
1065 U1 = U0 + usens*uperiod;
1066 V1 = V0 + vsens*vperiod;
1067 Pts2d(i).SetCoord(U1,V1);
1068 myProjIsDone = Standard_True;
1070 if(!myProjIsDone && uperiod) {
1071 Standard_Real Uinf, Usup, Uaux;
1072 Uinf = Surf->Surface().FirstUParameter();
1073 Usup = Surf->Surface().LastUParameter();
1074 if((Usup - U0) > (U0 - Uinf))
1075 Uaux = 2*Uinf - U0 + uperiod;
1077 Uaux = 2*Usup - U0 - uperiod;
1078 Extrema_GenLocateExtPS locext(pntproj,
1080 Uaux, V0, TolU, TolV);
1081 if (locext.IsDone())
1082 if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
1083 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1084 (locext.Point()).Parameter(u,v);
1085 if((Usup - U0) > (U0 - Uinf))
1090 U1 = U0 + usens*uperiod;
1091 V1 = V0 + vsens*vperiod;
1092 Pts2d(i).SetCoord(U1,V1);
1093 myProjIsDone = Standard_True;
1096 if(!myProjIsDone && vperiod) {
1097 Standard_Real Vinf, Vsup, Vaux;
1098 Vinf = Surf->Surface().FirstVParameter();
1099 Vsup = Surf->Surface().LastVParameter();
1100 if((Vsup - V0) > (V0 - Vinf))
1101 Vaux = 2*Vinf - V0 + vperiod;
1103 Vaux = 2*Vsup - V0 - vperiod;
1104 Extrema_GenLocateExtPS locext(pntproj,
1106 U0, Vaux, TolU, TolV) ;
1107 if (locext.IsDone())
1108 if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
1109 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1110 (locext.Point()).Parameter(u,v);
1111 if((Vsup - V0) > (V0 - Vinf))
1116 U1 = U0 + usens*uperiod;
1117 V1 = V0 + vsens*vperiod;
1118 Pts2d(i).SetCoord(U1,V1);
1119 myProjIsDone = Standard_True;
1122 if(!myProjIsDone && uperiod && vperiod) {
1123 Standard_Real Uaux, Vaux;
1124 if((Usup - U0) > (U0 - Uinf))
1125 Uaux = 2*Uinf - U0 + uperiod;
1127 Uaux = 2*Usup - U0 - uperiod;
1128 if((Vsup - V0) > (V0 - Vinf))
1129 Vaux = 2*Vinf - V0 + vperiod;
1131 Vaux = 2*Vsup - V0 - vperiod;
1132 Extrema_GenLocateExtPS locext(pntproj,
1134 Uaux, Vaux, TolU, TolV);
1135 if (locext.IsDone())
1136 if (locext.SquareDistance() < DistTol3d * DistTol3d) {
1137 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1138 (locext.Point()).Parameter(u,v);
1139 if((Usup - U0) > (U0 - Uinf))
1143 if((Vsup - V0) > (V0 - Vinf))
1148 U1 = U0 + usens*uperiod;
1149 V1 = V0 + vsens*vperiod;
1150 Pts2d(i).SetCoord(U1,V1);
1151 myProjIsDone = Standard_True;
1155 Extrema_ExtPS ext(pntproj, Surf->Surface(), TolU, TolV) ;
1157 Dist2Min = ext.SquareDistance(1);
1158 Standard_Integer GoodValue = 1;
1159 for ( j = 2 ; j <= ext.NbExt() ; j++ )
1160 if( Dist2Min > ext.SquareDistance(j)) {
1161 Dist2Min = ext.SquareDistance(j);
1164 if (Dist2Min < DistTol3d * DistTol3d) {
1165 //if (Dist2Min < Tol3d * Tol3d) {
1166 (ext.Point(GoodValue)).Parameter(u,v);
1168 if((U0 - u) > (2*uperiod/3)) {
1172 if((u - U0) > (2*uperiod/3)) {
1177 if((V0 - v) > (vperiod/2)) {
1181 if((v - V0) > (vperiod/2)) {
1186 U1 = U0 + usens*uperiod;
1187 V1 = V0 + vsens*vperiod;
1188 Pts2d(i).SetCoord(U1,V1);
1189 myProjIsDone = Standard_True;
1197 // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
1199 myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
1200 //jgv: put the curve into parametric range
1201 gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
1202 Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
1203 Standard_Real sense = 0.;
1206 if (TestU < Uinf - TolU)
1208 else if (TestU > Usup + TolU)
1210 while (TestU < Uinf - TolU || TestU > Usup + TolU)
1211 TestU += sense * uperiod;
1216 if (TestV < Vinf - TolV)
1218 else if (TestV > Vsup + TolV)
1220 while (TestV < Vinf - TolV || TestV > Vsup + TolV)
1221 TestV += sense * vperiod;
1223 gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
1224 if (Abs(Offset.X()) > gp::Resolution() ||
1225 Abs(Offset.Y()) > gp::Resolution())
1226 myBSpline->Translate(Offset);
1227 //////////////////////////////////////////
1228 Geom2dAdaptor_Curve GAC(myBSpline);
1229 Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
1232 // sprintf(name,"%s_%d","build",compteur++);
1233 // DrawTrSurf::Set(name,myBSpline);
1238 // Modified by Sergey KHROMOV - Thu Apr 18 10:57:50 2002 Begin
1239 // Standard_NoSuchObject_Raise_if(1,"ProjLib_Compu: build echec");
1240 // Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
1241 return Handle(Adaptor2d_HCurve2d)();
1243 // myProjIsDone = Standard_False;
1244 // Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
1245 // Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
1246 // Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
1252 //=======================================================================
1253 //function : ProjLib_ProjectUsingInitialCurve2d
1255 //=======================================================================
1256 Handle(Geom2d_BSplineCurve)
1257 ProjLib_ComputeApproxOnPolarSurface::
1258 ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
1259 const Handle(Adaptor3d_HSurface)& Surf,
1260 const Handle(Adaptor2d_HCurve2d)& InitCurve2d)
1263 Standard_Real Tol3d = myTolerance;
1264 Standard_Real DistTol3d = 1.0*Tol3d;
1265 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
1266 Standard_Real Tol2d = Sqrt(TolU*TolU + TolV*TolV);
1269 GeomAbs_SurfaceType TheTypeS = Surf->GetType();
1270 GeomAbs_CurveType TheTypeC = Curve->GetType();
1271 // Handle(Standard_Type) TheTypeS = Surf->DynamicType();
1272 // Handle(Standard_Type) TheTypeC = Curve->DynamicType(); // si on a :
1273 // if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
1274 if(TheTypeS == GeomAbs_Plane) {
1276 gp_Pln Plane = Surf->Plane();
1277 if(TheTypeC == GeomAbs_BSplineCurve) {
1278 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1279 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1280 for(i = 1;i <= Curve->NbPoles();i++) {
1281 ElSLib::Parameters( Plane, BSC->Pole(i), S, T);
1282 Poles2d(i).SetCoord(S,T);
1284 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1286 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1287 BSC->Multiplicities(Mults);
1288 if(BSC->IsRational()) {
1289 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1290 BSC->Weights(Weights);
1291 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1292 BSC->Degree(), BSC->IsPeriodic()) ;
1294 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1295 BSC->Degree(), BSC->IsPeriodic()) ;
1298 if(TheTypeC == GeomAbs_BezierCurve) {
1299 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1300 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1301 for(i = 1;i <= Curve->NbPoles();i++) {
1302 ElSLib::Parameters( Plane, BC->Pole(i), S, T);
1303 Poles2d(i).SetCoord(S,T);
1305 TColStd_Array1OfReal Knots(1, 2);
1306 Knots.SetValue(1,0.0);
1307 Knots.SetValue(2,1.0);
1308 TColStd_Array1OfInteger Mults(1, 2);
1309 Mults.Init(BC->NbPoles());
1310 if(BC->IsRational()) {
1311 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1312 BC->Weights(Weights);
1313 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1314 BC->Degree(), BC->IsPeriodic()) ;
1316 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1317 BC->Degree(), BC->IsPeriodic()) ;
1320 if(TheTypeS == GeomAbs_BSplineSurface) {
1321 Handle(Geom_BSplineSurface) BSS = Surf->BSpline();
1322 if((BSS->MaxDegree() == 1) &&
1323 (BSS->NbUPoles() == 2) &&
1324 (BSS->NbVPoles() == 2)) {
1325 gp_Pnt p11 = BSS->Pole(1,1);
1326 gp_Pnt p12 = BSS->Pole(1,2);
1327 gp_Pnt p21 = BSS->Pole(2,1);
1328 gp_Pnt p22 = BSS->Pole(2,2);
1331 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1332 //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
1333 // so the polar surface is plane
1334 // and if it is enough to projet the poles of Curve
1335 Standard_Integer Dist2Min = IntegerLast();
1338 //Standard_Real TolU = Surf->UResolution(myTolerance)
1339 // , TolV = Surf->VResolution(myTolerance);
1341 if(TheTypeC == GeomAbs_BSplineCurve) {
1342 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1343 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1344 for(i = 1;i <= Curve->NbPoles();i++) {
1345 myProjIsDone = Standard_False;
1346 Dist2Min = IntegerLast();
1347 Extrema_GenLocateExtPS extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1348 (p11.Y()+p22.Y())/2,TolU,TolV) ;
1349 if (extrloc.IsDone()) {
1350 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1351 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1352 //if (Dist2Min < myTolerance * myTolerance) {
1353 (extrloc.Point()).Parameter(u,v);
1354 Poles2d(i).SetCoord(u,v);
1355 myProjIsDone = Standard_True;
1364 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1366 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1367 BSC->Multiplicities(Mults);
1368 if(BSC->IsRational()) {
1369 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1370 BSC->Weights(Weights);
1371 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1372 BSC->Degree(), BSC->IsPeriodic()) ;
1374 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1375 BSC->Degree(), BSC->IsPeriodic()) ;
1380 if(TheTypeC == GeomAbs_BezierCurve) {
1381 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1382 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1383 for(i = 1;i <= Curve->NbPoles();i++) {
1384 Dist2Min = IntegerLast();
1385 Extrema_GenLocateExtPS extrloc(BC->Pole(i),Surf->Surface(),0.5,
1387 if (extrloc.IsDone()) {
1388 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1389 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1390 //if (Dist2Min < myTolerance * myTolerance) {
1391 (extrloc.Point()).Parameter(u,v);
1392 Poles2d(i).SetCoord(u,v);
1393 myProjIsDone = Standard_True;
1399 myProjIsDone = Standard_False;
1403 TColStd_Array1OfReal Knots(1, 2);
1404 Knots.SetValue(1,0.0);
1405 Knots.SetValue(2,1.0);
1406 TColStd_Array1OfInteger Mults(1, 2);
1407 Mults.Init(BC->NbPoles());
1408 if(BC->IsRational()) {
1409 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1410 BC->Weights(Weights);
1411 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1412 BC->Degree(), BC->IsPeriodic()) ;
1414 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1415 BC->Degree(), BC->IsPeriodic()) ;
1421 else if(TheTypeS == GeomAbs_BezierSurface) {
1422 Handle(Geom_BezierSurface) BS = Surf->Bezier();
1423 if((BS->MaxDegree() == 1) &&
1424 (BS->NbUPoles() == 2) &&
1425 (BS->NbVPoles() == 2)) {
1426 gp_Pnt p11 = BS->Pole(1,1);
1427 gp_Pnt p12 = BS->Pole(1,2);
1428 gp_Pnt p21 = BS->Pole(2,1);
1429 gp_Pnt p22 = BS->Pole(2,2);
1432 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1433 //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
1434 // and if it is enough to project the poles of Curve
1435 Standard_Integer Dist2Min = IntegerLast();
1438 //Standard_Real TolU = Surf->UResolution(myTolerance)
1439 // , TolV = Surf->VResolution(myTolerance);
1442 if(TheTypeC == GeomAbs_BSplineCurve) {
1443 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1444 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1445 for(i = 1;i <= Curve->NbPoles();i++) {
1446 myProjIsDone = Standard_False;
1447 Dist2Min = IntegerLast();
1448 Extrema_GenLocateExtPS extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1449 (p11.Y()+p22.Y())/2,TolU,TolV) ;
1450 if (extrloc.IsDone()) {
1451 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1452 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1453 //if (Dist2Min < myTolerance * myTolerance) {
1454 (extrloc.Point()).Parameter(u,v);
1455 Poles2d(i).SetCoord(u,v);
1456 myProjIsDone = Standard_True;
1465 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1467 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1468 BSC->Multiplicities(Mults);
1469 if(BSC->IsRational()) {
1470 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1471 BSC->Weights(Weights);
1472 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1473 BSC->Degree(), BSC->IsPeriodic()) ;
1475 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1476 BSC->Degree(), BSC->IsPeriodic()) ;
1481 if(TheTypeC == GeomAbs_BezierCurve) {
1482 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1483 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1484 for(i = 1;i <= Curve->NbPoles();i++) {
1485 Dist2Min = IntegerLast();
1486 Extrema_GenLocateExtPS extrloc(BC->Pole(i),Surf->Surface(),0.5,
1488 if (extrloc.IsDone()) {
1489 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1490 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1491 //if (Dist2Min < myTolerance * myTolerance) {
1492 (extrloc.Point()).Parameter(u,v);
1493 Poles2d(i).SetCoord(u,v);
1494 myProjIsDone = Standard_True;
1500 myProjIsDone = Standard_False;
1504 TColStd_Array1OfReal Knots(1, 2);
1505 Knots.SetValue(1,0.0);
1506 Knots.SetValue(2,1.0);
1507 TColStd_Array1OfInteger Mults(1, 2);
1508 Mults.Init(BC->NbPoles());
1509 if(BC->IsRational()) {
1510 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1511 BC->Weights(Weights);
1512 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1513 BC->Degree(), BC->IsPeriodic()) ;
1515 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1516 BC->Degree(), BC->IsPeriodic()) ;
1523 ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ; //OCC217
1524 //ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ;
1527 Standard_Integer Nb = 50;
1529 Standard_Real U, U1, U2;
1530 U1 = F.FirstParameter();
1531 U2 = F.LastParameter();
1533 TColgp_Array1OfPnt2d DummyPoles(1,Nb+1);
1534 TColStd_Array1OfReal DummyKnots(1,Nb+1);
1535 TColStd_Array1OfInteger DummyMults(1,Nb+1);
1538 DummyMults(Nb+1) = 2;
1539 for (Standard_Integer ij = 0; ij <= Nb; ij++) {
1540 U = (Nb-ij)*U1 + ij*U2;
1542 DummyPoles(ij+1) = F.Value(U);
1543 DummyKnots(ij+1) = ij;
1545 Handle(Geom2d_BSplineCurve) DummyC2d =
1546 new Geom2d_BSplineCurve(DummyPoles, DummyKnots, DummyMults, 1);
1547 Standard_CString Temp = "bs2d";
1549 DrawTrSurf::Set(Temp,DummyC2d);
1551 // DrawTrSurf::Set((Standard_CString ) "bs2d",DummyC2d);
1552 Handle(Geom2dAdaptor_HCurve) DDD =
1553 Handle(Geom2dAdaptor_HCurve)::DownCast(InitCurve2d);
1557 DrawTrSurf::Set(Temp,DDD->ChangeCurve2d().Curve());
1559 // DrawTrSurf::Set((Standard_CString ) "initc2d",DDD->ChangeCurve2d().Curve());
1562 Standard_Integer Deg1,Deg2;
1568 Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217
1569 //Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
1572 if(Fit.IsAllApproximated()) {
1574 Standard_Integer NbCurves = Fit.NbMultiCurves();
1575 Standard_Integer MaxDeg = 0;
1576 // To transform the MultiCurve into BSpline, it is required that all
1577 // Bezier constituing it have the same degree -> Calculation of MaxDeg
1578 Standard_Integer NbPoles = 1;
1579 for (i = 1; i <= NbCurves; i++) {
1580 Standard_Integer Deg = Fit.Value(i).Degree();
1581 MaxDeg = Max ( MaxDeg, Deg);
1584 NbPoles = MaxDeg * NbCurves + 1; //Tops on the BSpline
1585 TColgp_Array1OfPnt2d Poles( 1, NbPoles);
1587 TColgp_Array1OfPnt2d TempPoles( 1, MaxDeg + 1);//to augment the degree
1589 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Nodes of the BSpline
1591 Standard_Integer Compt = 1;
1592 for (i = 1; i <= NbCurves; i++) {
1593 Fit.Parameters(i, Knots(i), Knots(i+1));
1594 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
1595 TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Retrieve the tops
1596 MC.Curve(1, Poles2d);
1598 //Eventual augmentation of the degree
1599 Standard_Integer Inc = MaxDeg - MC.Degree();
1601 // BSplCLib::IncreaseDegree( Inc, Poles2d, PLib::NoWeights(),
1602 BSplCLib::IncreaseDegree( MaxDeg, Poles2d, PLib::NoWeights(),
1603 TempPoles, PLib::NoWeights());
1604 //update of tops of the PCurve
1605 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1606 Poles.SetValue( Compt, TempPoles( j));
1611 //update of tops of the PCurve
1612 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1613 Poles.SetValue( Compt, Poles2d( j));
1621 //update of fields of ProjLib_Approx
1622 Standard_Integer NbKnots = NbCurves + 1;
1624 // The start and end nodes are not correct : Cf: opening of the interval
1625 //Knots( 1) -= 1.e-9;
1626 //Knots(NbKnots) += 1.e-9;
1629 TColStd_Array1OfInteger Mults( 1, NbKnots);
1631 Mults.SetValue( 1, MaxDeg + 1);
1632 Mults.SetValue(NbKnots, MaxDeg + 1);
1633 myProjIsDone = Standard_True;
1634 Handle(Geom2d_BSplineCurve) Dummy =
1635 new Geom2d_BSplineCurve(Poles,Knots,Mults,MaxDeg);
1637 // try to smoother the Curve GeomAbs_C1.
1639 Standard_Boolean OK = Standard_True;
1641 for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
1642 OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d); //OCC217
1643 //OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance);
1647 cout << "ProjLib_ComputeApproxOnPolarSurface : Smoothing echoue"<<endl;
1652 return Handle(Geom2d_BSplineCurve)();
1655 //=======================================================================
1656 //function : BSpline
1658 //=======================================================================
1660 Handle(Geom2d_BSplineCurve)
1661 ProjLib_ComputeApproxOnPolarSurface::BSpline() const
1664 // Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End
1665 // Standard_NoSuchObject_Raise_if
1667 // "ProjLib_ComputeApproxOnPolarSurface:BSpline");
1668 // Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End
1672 //=======================================================================
1673 //function : Curve2d
1675 //=======================================================================
1677 Handle(Geom2d_Curve)
1678 ProjLib_ComputeApproxOnPolarSurface::Curve2d() const
1681 Standard_NoSuchObject_Raise_if
1683 "ProjLib_ComputeApproxOnPolarSurface:2ndCurve2d");
1688 //=======================================================================
1691 //=======================================================================
1693 Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const
1696 return myProjIsDone;