0025418: Debug output to be limited to OCC development environment
[occt.git] / src / ProjLib / ProjLib_ComputeApproxOnPolarSurface.cxx
CommitLineData
b311480e 1// Created by: Bruno DUMORTIER
2// Copyright (c) 1995-1999 Matra Datavision
973c2be1 3// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16#include <ProjLib_ComputeApproxOnPolarSurface.hxx>
17#include <AppCont_Function2d.hxx>
18#include <ElSLib.hxx>
19#include <ElCLib.hxx>
20#include <BSplCLib.hxx>
21#include <PLib.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>
27#include <math.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>
43
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>
52
53#include <GeomAbs_SurfaceType.hxx>
54#include <GeomAbs_CurveType.hxx>
7fd59977 55#include <Adaptor3d_Surface.hxx>
56#include <Adaptor3d_Curve.hxx>
57#include <Adaptor3d_HSurface.hxx>
58#include <Adaptor3d_HCurve.hxx>
59#include <Adaptor2d_HCurve2d.hxx>
60#include <Geom2dAdaptor_Curve.hxx>
61#include <Geom2dAdaptor_HCurve.hxx>
62#include <GeomAdaptor_HCurve.hxx>
63#include <GeomAdaptor.hxx>
64#include <GeomAdaptor_Surface.hxx>
65#include <TColgp_SequenceOfPnt.hxx>
66
67#include <gp_Pnt.hxx>
68#include <gp_Pnt2d.hxx>
69#include <gp_Vec2d.hxx>
70#include <Extrema_GenLocateExtPS.hxx>
71#include <Extrema_ExtPS.hxx>
72#include <GCPnts_QuasiUniformAbscissa.hxx>
73#include <Standard_DomainError.hxx>
74//#include <GeomLib_IsIso.hxx>
75//#include <GeomLib_CheckSameParameter.hxx>
76
0797d9d3 77#ifdef OCCT_DEBUG
7fd59977 78#ifdef DRAW
79#include <DrawTrSurf.hxx>
80#endif
81//static Standard_Integer compteur = 0;
82#endif
83
84//=======================================================================
85//function : Value
86//purpose : (OCC217 - apo)- Compute Point2d that project on polar surface(<Surf>) 3D<Curve>
87// <InitCurve2d> use for calculate start 2D point.
88//=======================================================================
89
90static gp_Pnt2d Function_Value(const Standard_Real U,
91 const Handle(Adaptor3d_HSurface)& Surf,
92 const Handle(Adaptor3d_HCurve)& Curve,
93 const Handle(Adaptor2d_HCurve2d)& InitCurve2d,
94 //OCC217
95 const Standard_Real DistTol3d, const Standard_Real tolU, const Standard_Real tolV)
96 //const Standard_Real Tolerance)
97{
98 //OCC217
99 //Standard_Real Tol3d = 100*Tolerance;
100
101 gp_Pnt2d p2d = InitCurve2d->Value(U) ;
102 gp_Pnt p = Curve->Value(U);
103// Curve->D0(U,p) ;
104 Standard_Real Uinf, Usup, Vinf, Vsup;
105 Uinf = Surf->Surface().FirstUParameter();
106 Usup = Surf->Surface().LastUParameter();
107 Vinf = Surf->Surface().FirstVParameter();
108 Vsup = Surf->Surface().LastVParameter();
109 Standard_Integer decalU = 0, decalV = 0;
110 Standard_Real U0 = p2d.X(), V0 = p2d.Y();
111
112 GeomAbs_SurfaceType Type = Surf->GetType();
113 if((Type != GeomAbs_BSplineSurface) &&
114 (Type != GeomAbs_BezierSurface) &&
115 (Type != GeomAbs_OffsetSurface) ) {
1d47d8d0 116 Standard_Real S = 0., T = 0.;
7fd59977 117 switch (Type) {
118// case GeomAbs_Plane:
119// {
120// gp_Pln Plane = Surf->Plane();
121// ElSLib::Parameters( Plane, p, S, T);
122// break;
123// }
124 case GeomAbs_Cylinder:
125 {
126 gp_Cylinder Cylinder = Surf->Cylinder();
127 ElSLib::Parameters( Cylinder, p, S, T);
c6541a0c
D
128 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
129 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
130 S += decalU*2*M_PI;
7fd59977 131 break;
132 }
133 case GeomAbs_Cone:
134 {
135 gp_Cone Cone = Surf->Cone();
136 ElSLib::Parameters( Cone, p, S, T);
c6541a0c
D
137 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
138 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
139 S += decalU*2*M_PI;
7fd59977 140 break;
141 }
142 case GeomAbs_Sphere:
143 {
144 gp_Sphere Sphere = Surf->Sphere();
145 ElSLib::Parameters( Sphere, p, S, T);
c6541a0c
D
146 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
147 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
148 S += decalU*2*M_PI;
149 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
150 if(V0 > (Vsup+(Vsup-Vinf))) decalV = int((V0 - Vsup+(Vsup-Vinf))/(2*M_PI))+1;
151 T += decalV*2*M_PI;
152 if(0.4*M_PI < Abs(U0 - S) && Abs(U0 - S) < 1.6*M_PI) {
153 T = M_PI - T;
7fd59977 154 if(U0 < S)
c6541a0c 155 S -= M_PI;
7fd59977 156 else
c6541a0c 157 S += M_PI;
7fd59977 158 }
159 break;
160 }
161 case GeomAbs_Torus:
162 {
163 gp_Torus Torus = Surf->Torus();
164 ElSLib::Parameters( Torus, p, S, T);
c6541a0c
D
165 if(U0 < Uinf) decalU = -int((Uinf - U0)/(2*M_PI))-1;
166 if(U0 > Usup) decalU = int((U0 - Usup)/(2*M_PI))+1;
167 if(V0 < Vinf) decalV = -int((Vinf - V0)/(2*M_PI))-1;
168 if(V0 > Vsup) decalV = int((V0 - Vsup)/(2*M_PI))+1;
169 S += decalU*2*M_PI; T += decalV*2*M_PI;
7fd59977 170 break;
171 }
172 default:
173 Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::Value");
174 }
175 return gp_Pnt2d(S, T);
176 }
177
178 //////////////////
179 Standard_Real Dist2Min = RealLast();
180 //OCC217
181 //Standard_Real tolU,tolV ;
182 //tolU = Tolerance;
183 //tolV = Tolerance;
184
185 Standard_Real uperiod =0, vperiod = 0, u, v;
186 // U0 and V0 are the points within the initialized period
187 // (periode with u and v),
188 // U1 and V1 are the points for construction of tops
189
190 if(Surf->IsUPeriodic() || Surf->IsUClosed()) {
191 uperiod = Surf->LastUParameter() - Surf->FirstUParameter();
192 }
193 if(Surf->IsVPeriodic() || Surf->IsVClosed()) {
194 vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
195 }
eafb234b 196 if(U0 < Uinf) {
7fd59977 197 if(!uperiod)
198 U0 = Uinf;
199 else {
200 decalU = int((Uinf - U0)/uperiod)+1;
201 U0 += decalU*uperiod;
202 }
eafb234b 203 }
204 if(U0 > Usup) {
7fd59977 205 if(!uperiod)
206 U0 = Usup;
207 else {
208 decalU = -(int((U0 - Usup)/uperiod)+1);
209 U0 += decalU*uperiod;
210 }
eafb234b 211 }
212 if(V0 < Vinf) {
7fd59977 213 if(!vperiod)
214 V0 = Vinf;
215 else {
216 decalV = int((Vinf - V0)/vperiod)+1;
217 V0 += decalV*vperiod;
218 }
eafb234b 219 }
220 if(V0 > Vsup) {
7fd59977 221 if(!vperiod)
222 V0 = Vsup;
223 else {
224 decalV = -int((V0 - Vsup)/vperiod)-1;
225 V0 += decalV*vperiod;
226 }
eafb234b 227 }
7fd59977 228
229 // The surface around U0 is reduced
230 Standard_Real uLittle = (Usup - Uinf)/10, vLittle = (Vsup - Vinf)/10;
231 Standard_Real uInfLi = 0, vInfLi = 0,uSupLi = 0, vSupLi = 0;
232 if((U0 - Uinf) > uLittle) uInfLi = U0 - uLittle; else uInfLi = Uinf;
233 if((V0 - Vinf) > vLittle) vInfLi = V0 - vLittle; else vInfLi = Vinf;
234 if((Usup - U0) > uLittle) uSupLi = U0 + uLittle; else uSupLi = Usup;
235 if((Vsup - V0) > vLittle) vSupLi = V0 + vLittle; else vSupLi = Vsup;
236
237 // const Adaptor3d_Surface GAS = Surf->Surface();
238
239 GeomAdaptor_Surface SurfLittle;
240 if (Type == GeomAbs_BSplineSurface) {
241 Handle(Geom_Surface) GBSS(Surf->Surface().BSpline());
242 SurfLittle.Load(GBSS, uInfLi, uSupLi, vInfLi, vSupLi);
243 }
244 else if (Type == GeomAbs_BezierSurface) {
245 Handle(Geom_Surface) GS(Surf->Surface().Bezier());
246 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
247 }
248 else if (Type == GeomAbs_OffsetSurface) {
249 Handle(Geom_Surface) GS = GeomAdaptor::MakeSurface(Surf->Surface());
250 SurfLittle.Load(GS, uInfLi, uSupLi, vInfLi, vSupLi);
251 }
252 else {
253 Standard_NoSuchObject::Raise("");
254 }
255
256 Extrema_GenLocateExtPS locext(p, SurfLittle, U0, V0, tolU, tolV);
257 if (locext.IsDone()) {
258 Dist2Min = locext.SquareDistance();
259 if (Dist2Min < DistTol3d * DistTol3d) {
260 (locext.Point()).Parameter(u, v);
261 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
262 return pnt;
263 }
264 }
265
266 Extrema_ExtPS ext(p, SurfLittle, tolU, tolV) ;
267 if (ext.IsDone() && ext.NbExt()>=1 ) {
268 Dist2Min = ext.SquareDistance(1);
269 Standard_Integer GoodValue = 1;
270 for ( Standard_Integer i = 2 ; i <= ext.NbExt() ; i++ )
271 if( Dist2Min > ext.SquareDistance(i)) {
272 Dist2Min = ext.SquareDistance(i);
273 GoodValue = i;
274 }
275 if (Dist2Min < DistTol3d * DistTol3d) {
276 (ext.Point(GoodValue)).Parameter(u,v);
277 gp_Pnt2d pnt(u - decalU*uperiod,v - decalV*vperiod);
278 return pnt;
279 }
280 }
281
282 return p2d;
283}
284
285
286//=======================================================================
287//function : ProjLib_PolarFunction
288//purpose : (OCC217 - apo)- This class produce interface to call "gp_Pnt2d Function_Value(...)"
289//=======================================================================
290
291class ProjLib_PolarFunction : public AppCont_Function2d
292{
293 Handle(Adaptor3d_HCurve) myCurve;
294 Handle(Adaptor2d_HCurve2d) myInitialCurve2d ;
295 Handle(Adaptor3d_HSurface) mySurface ;
296 //OCC217
297 Standard_Real myTolU, myTolV;
298 Standard_Real myDistTol3d;
299 //Standard_Real myTolerance ;
300
301 public :
302
303 ProjLib_PolarFunction(const Handle(Adaptor3d_HCurve) & C,
304 const Handle(Adaptor3d_HSurface)& Surf,
305 const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
306 //OCC217
307 const Standard_Real Tol3d) :
308 //const Standard_Real Tolerance) :
309 myCurve(C),
310 myInitialCurve2d(InitialCurve2d),
311 mySurface(Surf),
312 //OCC217
313 myTolU(Surf->UResolution(Tol3d)),
314 myTolV(Surf->VResolution(Tol3d)),
315 myDistTol3d(100.0*Tol3d){} ;
316 //myTolerance(Tolerance){} ;
317
318 ~ProjLib_PolarFunction() {}
319
320 Standard_Real FirstParameter() const
86eff19e 321 {return (myCurve->FirstParameter()/*+1.e-9*/);}
7fd59977 322
323 Standard_Real LastParameter() const
86eff19e 324 {return (myCurve->LastParameter()/*-1.e-9*/);}
7fd59977 325
326 gp_Pnt2d Value(const Standard_Real t) const {
327 return Function_Value
328 (t,mySurface,myCurve,myInitialCurve2d,myDistTol3d,myTolU,myTolV) ; //OCC217
329 //(t,mySurface,myCurve,myInitialCurve2d,myTolerance) ;
330 }
331
332// Standard_Boolean D1(const Standard_Real t, gp_Pnt2d& P, gp_Vec2d& V) const
333 Standard_Boolean D1(const Standard_Real , gp_Pnt2d& , gp_Vec2d& ) const
334 {return Standard_False;}
335};
336
337//=======================================================================
338//function : ProjLib_ComputeApproxOnPolarSurface
339//purpose :
340//=======================================================================
341
342ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface(){}
343
344
345//=======================================================================
346//function : ProjLib_ComputeApproxOnPolarSurface
347//purpose :
348//=======================================================================
349
350ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
351(const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
352 const Handle(Adaptor3d_HCurve)& Curve,
353 const Handle(Adaptor3d_HSurface)& S,
354 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
355 //const Standard_Real tolerance):myProjIsDone(Standard_False)
356{
357 myTolerance = tol3d; //OCC217
358 //myTolerance = Max(Tolerance,Precision::PApproximation());
359 myBSpline = Perform(InitialCurve2d,Curve,S);
360}
361//=======================================================================
362//function : ProjLib_ComputeApproxOnPolarSurface
363//purpose : Process the case of sewing
364//=======================================================================
365
366ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
367(const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
368 const Handle(Adaptor2d_HCurve2d)& InitialCurve2dBis,
369 const Handle(Adaptor3d_HCurve)& Curve,
370 const Handle(Adaptor3d_HSurface)& S,
371 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
372 //const Standard_Real tolerance):myProjIsDone(Standard_False)
373{// InitialCurve2d and InitialCurve2dBis are two pcurves of the sewing
374 myTolerance = tol3d; //OCC217
375 //myTolerance = Max(tolerance,Precision::PApproximation());
376 Handle(Geom2d_BSplineCurve) bsc = Perform(InitialCurve2d,Curve,S);
377 if(myProjIsDone) {
378 gp_Pnt2d P2dproj, P2d, P2dBis;
379 P2dproj = bsc->StartPoint();
380 P2d = InitialCurve2d->Value(InitialCurve2d->FirstParameter());
381 P2dBis = InitialCurve2dBis->Value(InitialCurve2dBis->FirstParameter());
382
383 Standard_Real Dist, DistBis;
384 Dist = P2dproj.Distance(P2d);
385 DistBis = P2dproj.Distance(P2dBis);
386 if( Dist < DistBis) {
387 // myBSpline2d is the pcurve that is found. It is translated to obtain myCurve2d
388 myBSpline = bsc;
389 Handle(Geom2d_Geometry) GG = myBSpline->Translated(P2d, P2dBis);
390 my2ndCurve = Handle(Geom2d_Curve)::DownCast(GG);
391 }
392 else {
393 my2ndCurve = bsc;
394 Handle(Geom2d_Geometry) GG = my2ndCurve->Translated(P2dBis, P2d);
395 myBSpline = Handle(Geom2d_BSplineCurve)::DownCast(GG);
396 }
397 }
398}
399
400//=======================================================================
401//function : ProjLib_ComputeApproxOnPolarSurface
402//purpose : case without curve of initialization
403//=======================================================================
404
405ProjLib_ComputeApproxOnPolarSurface::ProjLib_ComputeApproxOnPolarSurface
406(const Handle(Adaptor3d_HCurve)& Curve,
407 const Handle(Adaptor3d_HSurface)& S,
408 const Standard_Real tol3d):myProjIsDone(Standard_False) //OCC217
409 //const Standard_Real tolerance):myProjIsDone(Standard_False)
410{
411 myTolerance = tol3d; //OCC217
412 //myTolerance = Max(tolerance,Precision::PApproximation());
857ffd5e 413 const Handle(Adaptor2d_HCurve2d) InitCurve2d ;
7fd59977 414 myBSpline = Perform(InitCurve2d,Curve,S);
415}
416
417static Handle(Geom2d_BSplineCurve) Concat(Handle(Geom2d_BSplineCurve) C1,
418 Handle(Geom2d_BSplineCurve) C2)
419{
420 Standard_Integer deg, deg1, deg2;
421 deg1 = C1->Degree();
422 deg2 = C2->Degree();
423
424 if ( deg1 < deg2) {
425 C1->IncreaseDegree(deg2);
426 deg = deg2;
427 }
428 else if ( deg2 < deg1) {
429 C2->IncreaseDegree(deg1);
430 deg = deg1;
431 }
432 else deg = deg1;
433
434 Standard_Integer np1,np2,nk1,nk2,np,nk;
435 np1 = C1->NbPoles();
436 nk1 = C1->NbKnots();
437 np2 = C2->NbPoles();
438 nk2 = C2->NbKnots();
439 nk = nk1 + nk2 -1;
440 np = np1 + np2 -1;
441
442 TColStd_Array1OfReal K1(1,nk1); C1->Knots(K1);
443 TColStd_Array1OfInteger M1(1,nk1); C1->Multiplicities(M1);
444 TColgp_Array1OfPnt2d P1(1,np1); C1->Poles(P1);
445 TColStd_Array1OfReal K2(1,nk2); C2->Knots(K2);
446 TColStd_Array1OfInteger M2(1,nk2); C2->Multiplicities(M2);
447 TColgp_Array1OfPnt2d P2(1,np2); C2->Poles(P2);
448
449 // Compute the new BSplineCurve
450 TColStd_Array1OfReal K(1,nk);
451 TColStd_Array1OfInteger M(1,nk);
452 TColgp_Array1OfPnt2d P(1,np);
453
454 Standard_Integer i, count = 0;
455 // Set Knots and Mults
456 for ( i = 1; i <= nk1; i++) {
457 count++;
458 K(count) = K1(i);
459 M(count) = M1(i);
460 }
461 M(count) = deg;
462 for ( i = 2; i <= nk2; i++) {
463 count++;
464 K(count) = K2(i);
465 M(count) = M2(i);
466 }
467 // Set the Poles
468 count = 0;
469 for (i = 1; i <= np1; i++) {
470 count++;
471 P(count) = P1(i);
472 }
473 for (i = 2; i <= np2; i++) {
474 count++;
475 P(count) = P2(i);
476 }
477
478 Handle(Geom2d_BSplineCurve) BS =
479 new Geom2d_BSplineCurve(P,K,M,deg);
480 return BS;
481}
482
483
484//=======================================================================
485//function : Perform
486//purpose :
487//=======================================================================
488Handle(Geom2d_BSplineCurve) ProjLib_ComputeApproxOnPolarSurface::Perform
489(const Handle(Adaptor2d_HCurve2d)& InitialCurve2d,
490 const Handle(Adaptor3d_HCurve)& Curve,
491 const Handle(Adaptor3d_HSurface)& S)
492{
493 //OCC217
494 Standard_Real Tol3d = myTolerance;
495 Standard_Real ParamTol = Precision::PApproximation();
496
497 Handle(Adaptor2d_HCurve2d) AHC2d = InitialCurve2d;
498 Handle(Adaptor3d_HCurve) AHC = Curve;
499
500// if the curve 3d is a BSpline with degree C0, it is cut into sections with degree C1
501// -> bug cts18237
502 GeomAbs_CurveType typeCurve = Curve->GetType();
503 if(typeCurve == GeomAbs_BSplineCurve) {
504 TColStd_ListOfTransient LOfBSpline2d;
505 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
506 Standard_Integer nbInter = Curve->NbIntervals(GeomAbs_C1);
507 if(nbInter > 1) {
508 Standard_Integer i, j;
509 Handle(Geom_TrimmedCurve) GTC;
510 Handle(Geom2d_TrimmedCurve) G2dTC;
511 TColStd_Array1OfReal Inter(1,nbInter+1);
512 Curve->Intervals(Inter,GeomAbs_C1);
513 Standard_Real firstinter = Inter.Value(1), secondinter = Inter.Value(2);
514 // initialization 3d
515 GTC = new Geom_TrimmedCurve(BSC, firstinter, secondinter);
516 AHC = new GeomAdaptor_HCurve(GTC);
517
518 // if there is an initialization curve:
519 // - either this is a BSpline C0, with discontinuity at the same parameters of nodes
520 // and the sections C1 are taken
521 // - or this is a curve C1 and the sections of intrest are taken otherwise the curve is created.
522
523 // initialization 2d
524 Standard_Integer nbInter2d;
525 Standard_Boolean C2dIsToCompute;
526 C2dIsToCompute = InitialCurve2d.IsNull();
527 Handle(Geom2d_BSplineCurve) BSC2d;
528 Handle(Geom2d_Curve) G2dC;
529
530 if(!C2dIsToCompute) {
531 nbInter2d = InitialCurve2d->NbIntervals(GeomAbs_C1);
532 TColStd_Array1OfReal Inter2d(1,nbInter2d+1);
533 InitialCurve2d->Intervals(Inter2d,GeomAbs_C1);
534 j = 1;
535 for(i = 1,j = 1;i <= nbInter;i++)
536 if(Abs(Inter.Value(i) - Inter2d.Value(j)) < ParamTol) { //OCC217
537 //if(Abs(Inter.Value(i) - Inter2d.Value(j)) < myTolerance) {
538 if (j > nbInter2d) break;
539 j++;
540 }
541 if(j != (nbInter2d+1)) {
542 C2dIsToCompute = Standard_True;
543 }
544 }
545
546 if(C2dIsToCompute) {
547 AHC2d = BuildInitialCurve2d(AHC, S);
548 }
549 else {
550 typeCurve = InitialCurve2d->GetType();
551 switch (typeCurve) {
552 case GeomAbs_Line: {
553 G2dC = new Geom2d_Line(InitialCurve2d->Line());
554 break;
555 }
556 case GeomAbs_Circle: {
557 G2dC = new Geom2d_Circle(InitialCurve2d->Circle());
558 break;
559 }
560 case GeomAbs_Ellipse: {
561 G2dC = new Geom2d_Ellipse(InitialCurve2d->Ellipse());
562 break;
563 }
564 case GeomAbs_Hyperbola: {
565 G2dC = new Geom2d_Hyperbola(InitialCurve2d->Hyperbola());
566 break;
567 }
568 case GeomAbs_Parabola: {
569 G2dC = new Geom2d_Parabola(InitialCurve2d->Parabola());
570 break;
571 }
572 case GeomAbs_BezierCurve: {
573 G2dC = InitialCurve2d->Bezier();
574 break;
575 }
576 case GeomAbs_BSplineCurve: {
577 G2dC = InitialCurve2d->BSpline();
578 break;
579 }
580 case GeomAbs_OtherCurve:
581 default:
582 break;
583 }
584 gp_Pnt2d fp2d = G2dC->Value(firstinter), lp2d = G2dC->Value(secondinter);
585 gp_Pnt fps, lps, fpc, lpc;
586 S->D0(fp2d.X(), fp2d.Y(), fps);
587 S->D0(lp2d.X(), lp2d.Y(), lps);
588 Curve->D0(firstinter, fpc);
589 Curve->D0(secondinter, lpc);
590 //OCC217
591 if((fps.IsEqual(fpc, Tol3d)) &&
592 (lps.IsEqual(lpc, Tol3d))) {
593 //if((fps.IsEqual(fpc, myTolerance)) &&
594 // (lps.IsEqual(lpc, myTolerance))) {
595 G2dTC = new Geom2d_TrimmedCurve(G2dC, firstinter, secondinter);
596 Geom2dAdaptor_Curve G2dAC(G2dTC);
597 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
598 myProjIsDone = Standard_True;
599 }
600 else {
601 AHC2d = BuildInitialCurve2d(AHC, S);
602 C2dIsToCompute = Standard_True;
603 }
604 }
605
606 if(myProjIsDone) {
607 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
608 if(BSC2d.IsNull()) return Handle(Geom2d_BSplineCurve)(); //IFV
609 LOfBSpline2d.Append(BSC2d);
610 }
611 else {
612 return Handle(Geom2d_BSplineCurve)();
613 }
614
615
616
617 Standard_Real iinter, ip1inter;
618 Standard_Integer nbK2d, deg;
619 nbK2d = BSC2d->NbKnots(); deg = BSC2d->Degree();
620
621 for(i = 2;i <= nbInter;i++) {
622 iinter = Inter.Value(i);
623 ip1inter = Inter.Value(i+1);
624 // general case 3d
625 GTC->SetTrim(iinter, ip1inter);
626 AHC = new GeomAdaptor_HCurve(GTC);
627
628 // general case 2d
629 if(C2dIsToCompute) {
630 AHC2d = BuildInitialCurve2d(AHC, S);
631 }
632 else {
633 gp_Pnt2d fp2d = G2dC->Value(iinter), lp2d = G2dC->Value(ip1inter);
634 gp_Pnt fps, lps, fpc, lpc;
635 S->D0(fp2d.X(), fp2d.Y(), fps);
636 S->D0(lp2d.X(), lp2d.Y(), lps);
637 Curve->D0(iinter, fpc);
638 Curve->D0(ip1inter, lpc);
639 //OCC217
640 if((fps.IsEqual(fpc, Tol3d)) &&
641 (lps.IsEqual(lpc, Tol3d))) {
642 //if((fps.IsEqual(fpc, myTolerance)) &&
643 // (lps.IsEqual(lpc, myTolerance))) {
644 G2dTC->SetTrim(iinter, ip1inter);
645 Geom2dAdaptor_Curve G2dAC(G2dTC);
646 AHC2d = new Geom2dAdaptor_HCurve(G2dAC);
647 myProjIsDone = Standard_True;
648 }
649 else {
650 AHC2d = BuildInitialCurve2d(AHC, S);
651 }
652 }
653 if(myProjIsDone) {
654 BSC2d = ProjectUsingInitialCurve2d(AHC, S, AHC2d);
655 if(BSC2d.IsNull()) {
656 return Handle(Geom2d_BSplineCurve)();
657 }
658 LOfBSpline2d.Append(BSC2d);
659 nbK2d += BSC2d->NbKnots() - 1;
660 deg = Max(deg, BSC2d->Degree());
661 }
662 else {
663 return Handle(Geom2d_BSplineCurve)();
664 }
665 }
666
667 Standard_Integer NbC = LOfBSpline2d.Extent();
668 Handle(Geom2d_BSplineCurve) CurBS;
669 CurBS = Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
670 LOfBSpline2d.RemoveFirst();
671 for (Standard_Integer ii = 2; ii <= NbC; ii++) {
672 Handle(Geom2d_BSplineCurve) BS =
673 Handle(Geom2d_BSplineCurve)::DownCast(LOfBSpline2d.First());
674 CurBS = Concat(CurBS,BS);
675 LOfBSpline2d.RemoveFirst();
676 }
677 return CurBS;
678 }
679 }
680
681 if(InitialCurve2d.IsNull()) {
682 AHC2d = BuildInitialCurve2d(Curve, S);
683 if(!myProjIsDone)
684 return Handle(Geom2d_BSplineCurve)();
685 }
686 return ProjectUsingInitialCurve2d(AHC, S, AHC2d);
687}
688
689//=======================================================================
690//function : ProjLib_BuildInitialCurve2d
691//purpose :
692//=======================================================================
693
694Handle(Adaptor2d_HCurve2d)
695 ProjLib_ComputeApproxOnPolarSurface::
696 BuildInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
697 const Handle(Adaptor3d_HSurface)& Surf)
698{
699 // discretize the Curve with quasiuniform deflection
700 // density at least NbOfPnts points
701 myProjIsDone = Standard_False;
702
703 //OCC217
704 Standard_Real Tol3d = myTolerance;
705 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
706 Standard_Real DistTol3d = 100.0*Tol3d;
707
ee9451ab 708 Standard_Real uperiod = 0., vperiod = 0.;
709 if(Surf->IsUPeriodic() || Surf->IsUClosed())
710 uperiod = Surf->LastUParameter() - Surf->FirstUParameter();
711
712 if(Surf->IsVPeriodic() || Surf->IsVClosed())
713 vperiod = Surf->LastVParameter() - Surf->FirstVParameter();
714
715
7fd59977 716 // NO myTol is Tol2d !!!!
717 //Standard_Real TolU = myTolerance, TolV = myTolerance;
718 //Standard_Real Tol3d = 100*myTolerance; // At random Balthazar.
719
720 Standard_Integer NbOfPnts = 61;
721 GCPnts_QuasiUniformAbscissa QUA(Curve->GetCurve(),NbOfPnts);
722 TColgp_Array1OfPnt Pts(1,NbOfPnts);
723 TColStd_Array1OfReal Param(1,NbOfPnts);
724 Standard_Integer i, j;
725 for( i = 1; i <= NbOfPnts ; i++ ) {
726 Param(i) = QUA.Parameter(i);
727 Pts(i) = Curve->Value(Param(i));
728 }
729
730 TColgp_Array1OfPnt2d Pts2d(1,NbOfPnts);
731 TColStd_Array1OfInteger Mult(1,NbOfPnts);
732 Mult.Init(1);
733 Mult(1) = Mult(NbOfPnts) = 2;
734
ee9451ab 735 Standard_Real Uinf, Usup, Vinf, Vsup;
736 Uinf = Surf->Surface().FirstUParameter();
737 Usup = Surf->Surface().LastUParameter();
7fd59977 738 Vinf = Surf->Surface().FirstVParameter();
739 Vsup = Surf->Surface().LastVParameter();
740 GeomAbs_SurfaceType Type = Surf->GetType();
741 if((Type != GeomAbs_BSplineSurface) && (Type != GeomAbs_BezierSurface) &&
742 (Type != GeomAbs_OffsetSurface)) {
743 Standard_Real S, T;
744// Standard_Integer usens = 0, vsens = 0;
745 // to know the position relatively to the period
746 switch (Type) {
747// case GeomAbs_Plane:
748// {
749// gp_Pln Plane = Surf->Plane();
750// for ( i = 1 ; i <= NbOfPnts ; i++) {
751// ElSLib::Parameters( Plane, Pts(i), S, T);
752// Pts2d(i).SetCoord(S,T);
753// }
754// myProjIsDone = Standard_True;
755// break;
756// }
757 case GeomAbs_Cylinder:
758 {
759// Standard_Real Sloc, Tloc;
eafb234b 760 Standard_Real Sloc;
761 Standard_Integer usens = 0;
762 gp_Cylinder Cylinder = Surf->Cylinder();
763 ElSLib::Parameters( Cylinder, Pts(1), S, T);
764 Pts2d(1).SetCoord(S,T);
765 for ( i = 2 ; i <= NbOfPnts ; i++) {
766 Sloc = S;
767 ElSLib::Parameters( Cylinder, Pts(i), S, T);
768 if(Abs(Sloc - S) > M_PI) {
769 if(Sloc > S)
770 usens++;
771 else
772 usens--;
773 }
774 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
775 }
776 myProjIsDone = Standard_True;
777 break;
7fd59977 778 }
779 case GeomAbs_Cone:
780 {
781// Standard_Real Sloc, Tloc;
eafb234b 782 Standard_Real Sloc;
783 Standard_Integer usens = 0;
784 gp_Cone Cone = Surf->Cone();
785 ElSLib::Parameters( Cone, Pts(1), S, T);
786 Pts2d(1).SetCoord(S,T);
787 for ( i = 2 ; i <= NbOfPnts ; i++) {
788 Sloc = S;
789 ElSLib::Parameters( Cone, Pts(i), S, T);
790 if(Abs(Sloc - S) > M_PI) {
791 if(Sloc > S)
792 usens++;
793 else
794 usens--;
795 }
796 Pts2d(i).SetCoord(S+usens*2*M_PI,T);
797 }
798 myProjIsDone = Standard_True;
799 break;
7fd59977 800 }
801 case GeomAbs_Sphere:
802 {
803 Standard_Real Sloc, Tloc;
804 Standard_Integer usens = 0, vsens = 0; //usens steps by half-period
805 Standard_Boolean vparit = Standard_False;
806 gp_Sphere Sphere = Surf->Sphere();
807 ElSLib::Parameters( Sphere, Pts(1), S, T);
808 Pts2d(1).SetCoord(S,T);
809 for ( i = 2 ; i <= NbOfPnts ; i++) {
810 Sloc = S;Tloc = T;
811 ElSLib::Parameters( Sphere, Pts(i), S, T);
eafb234b 812 if(1.6*M_PI < Abs(Sloc - S)) {
7fd59977 813 if(Sloc > S)
814 usens += 2;
815 else
816 usens -= 2;
eafb234b 817 }
c6541a0c 818 if(1.6*M_PI > Abs(Sloc - S) && Abs(Sloc - S) > 0.4*M_PI) {
7fd59977 819 vparit = !vparit;
820 if(Sloc > S)
821 usens++;
822 else
823 usens--;
824 if(Abs(Tloc - Vsup) < (Vsup - Vinf)/5)
825 vsens++;
826 else
827 vsens--;
828 }
829 if(vparit) {
c6541a0c 830 Pts2d(i).SetCoord(S+usens*M_PI,(M_PI - T)*(vsens-1));
7fd59977 831 }
832 else {
c6541a0c 833 Pts2d(i).SetCoord(S+usens*M_PI,T+vsens*M_PI);
7fd59977 834
835 }
836 }
837 myProjIsDone = Standard_True;
838 break;
839 }
840 case GeomAbs_Torus:
841 {
842 Standard_Real Sloc, Tloc;
843 Standard_Integer usens = 0, vsens = 0;
844 gp_Torus Torus = Surf->Torus();
845 ElSLib::Parameters( Torus, Pts(1), S, T);
846 Pts2d(1).SetCoord(S,T);
847 for ( i = 2 ; i <= NbOfPnts ; i++) {
848 Sloc = S; Tloc = T;
849 ElSLib::Parameters( Torus, Pts(i), S, T);
eafb234b 850 if(Abs(Sloc - S) > M_PI) {
7fd59977 851 if(Sloc > S)
852 usens++;
853 else
854 usens--;
eafb234b 855 }
856 if(Abs(Tloc - T) > M_PI) {
7fd59977 857 if(Tloc > T)
858 vsens++;
859 else
860 vsens--;
eafb234b 861 }
c6541a0c 862 Pts2d(i).SetCoord(S+usens*2*M_PI,T+vsens*2*M_PI);
7fd59977 863 }
864 myProjIsDone = Standard_True;
865 break;
866 }
867 default:
868 Standard_NoSuchObject::Raise("ProjLib_ComputeApproxOnPolarSurface::BuildInitialCurve2d");
869 }
870 }
871 else {
7fd59977 872 myProjIsDone = Standard_False;
873 Standard_Real Dist2Min = 1.e+200, u = 0., v = 0.;
874 gp_Pnt pntproj;
875
876 TColgp_SequenceOfPnt2d Sols;
877 Standard_Boolean areManyZeros = Standard_False;
878
879 Curve->D0(Param.Value(1), pntproj) ;
880 Extrema_ExtPS aExtPS(pntproj, Surf->Surface(), TolU, TolV) ;
f7e3c52f 881 Standard_Real aMinSqDist = RealLast();
882 if (aExtPS.IsDone())
883 {
884 for (i = 1; i <= aExtPS.NbExt(); i++)
885 {
886 Standard_Real aSqDist = aExtPS.SquareDistance(i);
887 if (aSqDist < aMinSqDist)
888 aMinSqDist = aSqDist;
889 }
890 }
891 if (aMinSqDist > DistTol3d * DistTol3d) //try to project with less tolerance
892 {
893 TolU = Min(TolU, Precision::PConfusion());
894 TolV = Min(TolV, Precision::PConfusion());
895 aExtPS.Initialize(Surf->Surface(),
896 Surf->Surface().FirstUParameter(), Surf->Surface().LastUParameter(),
897 Surf->Surface().FirstVParameter(), Surf->Surface().LastVParameter(),
898 TolU, TolV);
899 aExtPS.Perform(pntproj);
900 }
7fd59977 901
902 if( aExtPS.IsDone() && aExtPS.NbExt() >= 1 ) {
903
904 Standard_Integer GoodValue = 1;
905
906 for ( i = 1 ; i <= aExtPS.NbExt() ; i++ ) {
907 if( aExtPS.SquareDistance(i) < DistTol3d * DistTol3d ) {
908 if( aExtPS.SquareDistance(i) <= 1.e-18 ) {
909 aExtPS.Point(i).Parameter(u,v);
910 gp_Pnt2d p2d(u,v);
911 Standard_Boolean isSame = Standard_False;
912 for( j = 1; j <= Sols.Length(); j++ ) {
913 if( p2d.SquareDistance( Sols.Value(j) ) <= 1.e-18 ) {
914 isSame = Standard_True;
915 break;
916 }
917 }
918 if( !isSame ) Sols.Append( p2d );
919 }
920 if( Dist2Min > aExtPS.SquareDistance(i) ) {
921 Dist2Min = aExtPS.SquareDistance(i);
922 GoodValue = i;
923 }
924 }
925 }
926
927 if( Sols.Length() > 1 ) areManyZeros = Standard_True;
928
929 if( Dist2Min <= DistTol3d * DistTol3d) {
930 if( !areManyZeros ) {
931 aExtPS.Point(GoodValue).Parameter(u,v);
932 Pts2d(1).SetCoord(u,v);
933 myProjIsDone = Standard_True;
934 }
935 else {
936 Standard_Integer nbSols = Sols.Length();
937 Standard_Real Dist2Max = -1.e+200;
938 for( i = 1; i <= nbSols; i++ ) {
939 const gp_Pnt2d& aP1 = Sols.Value(i);
940 for( j = i+1; j <= nbSols; j++ ) {
941 const gp_Pnt2d& aP2 = Sols.Value(j);
942 Standard_Real aDist2 = aP1.SquareDistance(aP2);
943 if( aDist2 > Dist2Max ) Dist2Max = aDist2;
944 }
945 }
946 Standard_Real aMaxT2 = Max(TolU,TolV);
947 aMaxT2 *= aMaxT2;
948 if( Dist2Max > aMaxT2 ) {
949 Standard_Integer tPp = 0;
950 for( i = 1; i <= 5; i++ ) {
951 Standard_Integer nbExtOk = 0;
952 Standard_Integer indExt = 0;
953 Standard_Integer iT = 1 + (NbOfPnts - 1)/5*i;
954 Curve->D0( Param.Value(iT), pntproj );
955 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
956 Dist2Min = 1.e+200;
957 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
958 for( j = 1 ; j <= aTPS.NbExt() ; j++ ) {
959 if( aTPS.SquareDistance(j) < DistTol3d * DistTol3d ) {
960 nbExtOk++;
961 if( aTPS.SquareDistance(j) < Dist2Min ) {
962 Dist2Min = aTPS.SquareDistance(j);
963 indExt = j;
964 }
965 }
966 }
967 }
968 if( nbExtOk == 1 ) {
969 tPp = iT;
970 aTPS.Point(indExt).Parameter(u,v);
971 break;
972 }
973 }
974
975 if( tPp != 0 ) {
976 gp_Pnt2d aPp = gp_Pnt2d(u,v);
977 gp_Pnt2d aPn;
978 j = 1;
979 Standard_Boolean isFound = Standard_False;
980 while( !isFound ) {
981 Curve->D0( Param.Value(tPp+j), pntproj );
982 Extrema_ExtPS aTPS( pntproj, Surf->Surface(), TolU, TolV );
983 Dist2Min = 1.e+200;
984 Standard_Integer indExt = 0;
985 if( aTPS.IsDone() && aTPS.NbExt() >= 1 ) {
986 for( i = 1 ; i <= aTPS.NbExt() ; i++ ) {
987 if( aTPS.SquareDistance(i) < DistTol3d * DistTol3d && aTPS.SquareDistance(i) < Dist2Min ) {
988 Dist2Min = aTPS.SquareDistance(i);
989 indExt = i;
990 isFound = Standard_True;
991 }
992 }
993 }
994 if( isFound ) {
995 aTPS.Point(indExt).Parameter(u,v);
996 aPn = gp_Pnt2d(u,v);
997 break;
998 }
999 j++;
1000 if( (tPp+j) > NbOfPnts ) break;
1001 }
1002
1003 if( isFound ) {
1004 gp_Vec2d atV(aPp,aPn);
1005 Standard_Boolean isChosen = Standard_False;
1006 for( i = 1; i <= nbSols; i++ ) {
1007 const gp_Pnt2d& aP1 = Sols.Value(i);
1008 gp_Vec2d asV(aP1,aPp);
1009 if( asV.Dot(atV) > 0. ) {
1010 isChosen = Standard_True;
1011 Pts2d(1).SetCoord(aP1.X(),aP1.Y());
1012 myProjIsDone = Standard_True;
1013 break;
1014 }
1015 }
1016 if( !isChosen ) {
1017 aExtPS.Point(GoodValue).Parameter(u,v);
1018 Pts2d(1).SetCoord(u,v);
1019 myProjIsDone = Standard_True;
1020 }
1021 }
1022 else {
1023 aExtPS.Point(GoodValue).Parameter(u,v);
1024 Pts2d(1).SetCoord(u,v);
1025 myProjIsDone = Standard_True;
1026 }
1027 }
1028 else {
1029 aExtPS.Point(GoodValue).Parameter(u,v);
1030 Pts2d(1).SetCoord(u,v);
1031 myProjIsDone = Standard_True;
1032 }
1033 }
1034 else {
1035 aExtPS.Point(GoodValue).Parameter(u,v);
1036 Pts2d(1).SetCoord(u,v);
1037 myProjIsDone = Standard_True;
1038 }
1039 }
1040 }
1041
1042 // calculate the following points with GenLocate_ExtPS
1043 // (and store the result and each parameter in a sequence)
1044 Standard_Integer usens = 0, vsens = 0;
1045 // to know the position relatively to the period
ee9451ab 1046 Standard_Real U0 = u, V0 = v, U1 = u, V1 = v;
7fd59977 1047 // U0 and V0 are the points in the initialized period
1048 // (period with u and v),
1049 // U1 and V1 are the points for construction of poles
1050
7fd59977 1051 for ( i = 2 ; i <= NbOfPnts ; i++)
1052 if(myProjIsDone) {
1053 myProjIsDone = Standard_False;
1054 Dist2Min = RealLast();
1055 Curve->D0(Param.Value(i), pntproj);
1056 Extrema_GenLocateExtPS aLocateExtPS
1057 (pntproj, Surf->Surface(), U0, V0, TolU, TolV) ;
1058
1059 if (aLocateExtPS.IsDone())
15173a08 1060 {
1061 if (aLocateExtPS.SquareDistance() < DistTol3d * DistTol3d)
1062 { //OCC217
1063 //if (aLocateExtPS.SquareDistance() < Tol3d * Tol3d) {
7fd59977 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;
1069 }
15173a08 1070 else
1071 {
1072 Extrema_ExtPS aGlobalExtr(pntproj, Surf->Surface(), TolU, TolV);
1073 if (aGlobalExtr.IsDone())
1074 {
1075 Standard_Real LocalMinSqDist = RealLast();
1076 Standard_Integer imin = 0;
1077 for (Standard_Integer isol = 1; isol <= aGlobalExtr.NbExt(); isol++)
1078 {
1079 Standard_Real aSqDist = aGlobalExtr.SquareDistance(isol);
1080 if (aSqDist < LocalMinSqDist)
1081 {
1082 LocalMinSqDist = aSqDist;
1083 imin = isol;
1084 }
1085 }
1086 if (LocalMinSqDist < DistTol3d * DistTol3d)
1087 {
1088 Standard_Real LocalU, LocalV;
1089 aGlobalExtr.Point(imin).Parameter(LocalU, LocalV);
1090 if (uperiod > 0. && Abs(U0 - LocalU) >= uperiod/2.)
1091 {
1092 if (LocalU > U0)
1093 usens = -1;
1094 else
1095 usens = 1;
1096 }
1097 if (vperiod > 0. && Abs(V0 - LocalV) >= vperiod/2.)
1098 {
1099 if (LocalV > V0)
1100 vsens = -1;
1101 else
1102 vsens = 1;
1103 }
1104 U0 = LocalU; V0 = LocalV;
1105 U1 = U0 + usens*uperiod;
1106 V1 = V0 + vsens*vperiod;
1107 Pts2d(i).SetCoord(U1,V1);
1108 myProjIsDone = Standard_True;
7a8c6a36 1109
1110 if((i == 2) && (!IsEqual(uperiod, 0.0) || !IsEqual(vperiod, 0.0)))
1111 {//Make 1st point more precise for periodic surfaces
1112 const Standard_Integer aSize = 3;
1113 const gp_Pnt2d aP(Pts2d(2));
1114 Standard_Real aUpar[aSize], aVpar[aSize];
1115 Pts2d(1).Coord(aUpar[1], aVpar[1]);
1116 aUpar[0] = aUpar[1] - uperiod;
1117 aUpar[2] = aUpar[1] + uperiod;
1118 aVpar[0] = aVpar[1] - vperiod;
1119 aVpar[2] = aVpar[1] + vperiod;
1120
1121 Standard_Real aSQdistMin = RealLast();
1122 Standard_Integer aBestUInd = 1, aBestVInd = 1;
1123 const Standard_Integer aSizeU = IsEqual(uperiod, 0.0) ? 1 : aSize,
1124 aSizeV = IsEqual(vperiod, 0.0) ? 1 : aSize;
1125 for(Standard_Integer uInd = 0; uInd < aSizeU; uInd++)
1126 {
1127 for(Standard_Integer vInd = 0; vInd < aSizeV; vInd++)
1128 {
1129 Standard_Real aSQdist = aP.SquareDistance(gp_Pnt2d(aUpar[uInd], aVpar[vInd]));
1130 if(aSQdist < aSQdistMin)
1131 {
1132 aSQdistMin = aSQdist;
1133 aBestUInd = uInd;
1134 aBestVInd = vInd;
1135 }
1136 }
1137 }
1138
1139 Pts2d(1).SetCoord(aUpar[aBestUInd], aVpar[aBestVInd]);
1140 }//if(i == 2) condition
15173a08 1141 }
1142 }
1143 }
1144 }
7fd59977 1145 if(!myProjIsDone && uperiod) {
1146 Standard_Real Uinf, Usup, Uaux;
1147 Uinf = Surf->Surface().FirstUParameter();
1148 Usup = Surf->Surface().LastUParameter();
1149 if((Usup - U0) > (U0 - Uinf))
1150 Uaux = 2*Uinf - U0 + uperiod;
1151 else
1152 Uaux = 2*Usup - U0 - uperiod;
1153 Extrema_GenLocateExtPS locext(pntproj,
1154 Surf->Surface(),
1155 Uaux, V0, TolU, TolV);
1156 if (locext.IsDone())
1157 if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
1158 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1159 (locext.Point()).Parameter(u,v);
1160 if((Usup - U0) > (U0 - Uinf))
1161 usens--;
1162 else
1163 usens++;
1164 U0 = u; V0 = v;
1165 U1 = U0 + usens*uperiod;
1166 V1 = V0 + vsens*vperiod;
1167 Pts2d(i).SetCoord(U1,V1);
1168 myProjIsDone = Standard_True;
1169 }
1170 }
1171 if(!myProjIsDone && vperiod) {
1172 Standard_Real Vinf, Vsup, Vaux;
1173 Vinf = Surf->Surface().FirstVParameter();
1174 Vsup = Surf->Surface().LastVParameter();
1175 if((Vsup - V0) > (V0 - Vinf))
1176 Vaux = 2*Vinf - V0 + vperiod;
1177 else
1178 Vaux = 2*Vsup - V0 - vperiod;
1179 Extrema_GenLocateExtPS locext(pntproj,
1180 Surf->Surface(),
1181 U0, Vaux, TolU, TolV) ;
1182 if (locext.IsDone())
1183 if (locext.SquareDistance() < DistTol3d * DistTol3d) { //OCC217
1184 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1185 (locext.Point()).Parameter(u,v);
1186 if((Vsup - V0) > (V0 - Vinf))
1187 vsens--;
1188 else
1189 vsens++;
1190 U0 = u; V0 = v;
1191 U1 = U0 + usens*uperiod;
1192 V1 = V0 + vsens*vperiod;
1193 Pts2d(i).SetCoord(U1,V1);
1194 myProjIsDone = Standard_True;
1195 }
1196 }
1197 if(!myProjIsDone && uperiod && vperiod) {
1198 Standard_Real Uaux, Vaux;
1199 if((Usup - U0) > (U0 - Uinf))
1200 Uaux = 2*Uinf - U0 + uperiod;
1201 else
1202 Uaux = 2*Usup - U0 - uperiod;
1203 if((Vsup - V0) > (V0 - Vinf))
1204 Vaux = 2*Vinf - V0 + vperiod;
1205 else
1206 Vaux = 2*Vsup - V0 - vperiod;
1207 Extrema_GenLocateExtPS locext(pntproj,
1208 Surf->Surface(),
1209 Uaux, Vaux, TolU, TolV);
1210 if (locext.IsDone())
1211 if (locext.SquareDistance() < DistTol3d * DistTol3d) {
1212 //if (locext.SquareDistance() < Tol3d * Tol3d) {
1213 (locext.Point()).Parameter(u,v);
1214 if((Usup - U0) > (U0 - Uinf))
1215 usens--;
1216 else
1217 usens++;
1218 if((Vsup - V0) > (V0 - Vinf))
1219 vsens--;
1220 else
1221 vsens++;
1222 U0 = u; V0 = v;
1223 U1 = U0 + usens*uperiod;
1224 V1 = V0 + vsens*vperiod;
1225 Pts2d(i).SetCoord(U1,V1);
1226 myProjIsDone = Standard_True;
1227 }
1228 }
1229 if(!myProjIsDone) {
1230 Extrema_ExtPS ext(pntproj, Surf->Surface(), TolU, TolV) ;
1231 if (ext.IsDone()) {
1232 Dist2Min = ext.SquareDistance(1);
1233 Standard_Integer GoodValue = 1;
1234 for ( j = 2 ; j <= ext.NbExt() ; j++ )
1235 if( Dist2Min > ext.SquareDistance(j)) {
1236 Dist2Min = ext.SquareDistance(j);
1237 GoodValue = j;
1238 }
1239 if (Dist2Min < DistTol3d * DistTol3d) {
1240 //if (Dist2Min < Tol3d * Tol3d) {
1241 (ext.Point(GoodValue)).Parameter(u,v);
eafb234b 1242 if(uperiod) {
7fd59977 1243 if((U0 - u) > (2*uperiod/3)) {
1244 usens++;
1245 }
1246 else
1247 if((u - U0) > (2*uperiod/3)) {
1248 usens--;
1249 }
eafb234b 1250 }
1251 if(vperiod) {
7fd59977 1252 if((V0 - v) > (vperiod/2)) {
1253 vsens++;
1254 }
1255 else
1256 if((v - V0) > (vperiod/2)) {
1257 vsens--;
1258 }
eafb234b 1259 }
7fd59977 1260 U0 = u; V0 = v;
1261 U1 = U0 + usens*uperiod;
1262 V1 = V0 + vsens*vperiod;
1263 Pts2d(i).SetCoord(U1,V1);
1264 myProjIsDone = Standard_True;
1265 }
1266 }
1267 }
1268 }
1269 else break;
1270 }
1271 }
1272 // -- Pnts2d is transformed into Geom2d_BSplineCurve, with the help of Param and Mult
1273 if(myProjIsDone) {
1274 myBSpline = new Geom2d_BSplineCurve(Pts2d,Param,Mult,1);
ee9451ab 1275 //jgv: put the curve into parametric range
1276 gp_Pnt2d MidPoint = myBSpline->Value(0.5*(myBSpline->FirstParameter() + myBSpline->LastParameter()));
1277 Standard_Real TestU = MidPoint.X(), TestV = MidPoint.Y();
1278 Standard_Real sense = 0.;
1279 if (uperiod)
1280 {
1281 if (TestU < Uinf - TolU)
1282 sense = 1.;
1283 else if (TestU > Usup + TolU)
1284 sense = -1;
1285 while (TestU < Uinf - TolU || TestU > Usup + TolU)
1286 TestU += sense * uperiod;
1287 }
1288 if (vperiod)
1289 {
1290 sense = 0.;
1291 if (TestV < Vinf - TolV)
1292 sense = 1.;
1293 else if (TestV > Vsup + TolV)
1294 sense = -1.;
1295 while (TestV < Vinf - TolV || TestV > Vsup + TolV)
1296 TestV += sense * vperiod;
1297 }
1298 gp_Vec2d Offset(TestU - MidPoint.X(), TestV - MidPoint.Y());
1299 if (Abs(Offset.X()) > gp::Resolution() ||
1300 Abs(Offset.Y()) > gp::Resolution())
1301 myBSpline->Translate(Offset);
1302 //////////////////////////////////////////
7fd59977 1303 Geom2dAdaptor_Curve GAC(myBSpline);
1304 Handle(Adaptor2d_HCurve2d) IC2d = new Geom2dAdaptor_HCurve(GAC);
0797d9d3 1305#ifdef OCCT_DEBUG
7fd59977 1306// char name [100];
1307// sprintf(name,"%s_%d","build",compteur++);
1308// DrawTrSurf::Set(name,myBSpline);
1309#endif
1310 return IC2d;
1311 }
1312 else {
1313// Modified by Sergey KHROMOV - Thu Apr 18 10:57:50 2002 Begin
1314// Standard_NoSuchObject_Raise_if(1,"ProjLib_Compu: build echec");
1315// Modified by Sergey KHROMOV - Thu Apr 18 10:57:51 2002 End
1316 return Handle(Adaptor2d_HCurve2d)();
1317 }
d3f26155 1318// myProjIsDone = Standard_False;
7fd59977 1319// Modified by Sergey KHROMOV - Thu Apr 18 10:58:01 2002 Begin
1320// Standard_NoSuchObject_Raise_if(1,"ProjLib_ComputeOnPS: build echec");
1321// Modified by Sergey KHROMOV - Thu Apr 18 10:58:02 2002 End
7fd59977 1322}
1323
1324
1325
1326
1327//=======================================================================
1328//function : ProjLib_ProjectUsingInitialCurve2d
1329//purpose :
1330//=======================================================================
1331Handle(Geom2d_BSplineCurve)
1332 ProjLib_ComputeApproxOnPolarSurface::
1333 ProjectUsingInitialCurve2d(const Handle(Adaptor3d_HCurve)& Curve,
1334 const Handle(Adaptor3d_HSurface)& Surf,
1335 const Handle(Adaptor2d_HCurve2d)& InitCurve2d)
1336{
1337 //OCC217
1338 Standard_Real Tol3d = myTolerance;
1339 Standard_Real DistTol3d = 1.0*Tol3d;
1340 Standard_Real TolU = Surf->UResolution(Tol3d), TolV = Surf->VResolution(Tol3d);
1341 Standard_Real Tol2d = Sqrt(TolU*TolU + TolV*TolV);
1342
1343 Standard_Integer i;
1344 GeomAbs_SurfaceType TheTypeS = Surf->GetType();
1345 GeomAbs_CurveType TheTypeC = Curve->GetType();
1346// Handle(Standard_Type) TheTypeS = Surf->DynamicType();
1347// Handle(Standard_Type) TheTypeC = Curve->DynamicType(); // si on a :
1348// if(TheTypeS == STANDARD_TYPE(Geom_BSplineSurface)) {
1349 if(TheTypeS == GeomAbs_Plane) {
1350 Standard_Real S, T;
1351 gp_Pln Plane = Surf->Plane();
1352 if(TheTypeC == GeomAbs_BSplineCurve) {
1353 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1354 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1355 for(i = 1;i <= Curve->NbPoles();i++) {
1356 ElSLib::Parameters( Plane, BSC->Pole(i), S, T);
1357 Poles2d(i).SetCoord(S,T);
1358 }
1359 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1360 BSC->Knots(Knots);
1361 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1362 BSC->Multiplicities(Mults);
1363 if(BSC->IsRational()) {
1364 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1365 BSC->Weights(Weights);
1366 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1367 BSC->Degree(), BSC->IsPeriodic()) ;
1368 }
1369 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1370 BSC->Degree(), BSC->IsPeriodic()) ;
1371
1372 }
1373 if(TheTypeC == GeomAbs_BezierCurve) {
1374 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1375 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1376 for(i = 1;i <= Curve->NbPoles();i++) {
1377 ElSLib::Parameters( Plane, BC->Pole(i), S, T);
1378 Poles2d(i).SetCoord(S,T);
1379 }
1380 TColStd_Array1OfReal Knots(1, 2);
1381 Knots.SetValue(1,0.0);
1382 Knots.SetValue(2,1.0);
1383 TColStd_Array1OfInteger Mults(1, 2);
1384 Mults.Init(BC->NbPoles());
1385 if(BC->IsRational()) {
1386 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1387 BC->Weights(Weights);
1388 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1389 BC->Degree(), BC->IsPeriodic()) ;
1390 }
1391 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1392 BC->Degree(), BC->IsPeriodic()) ;
1393 }
1394 }
1395 if(TheTypeS == GeomAbs_BSplineSurface) {
1396 Handle(Geom_BSplineSurface) BSS = Surf->BSpline();
1397 if((BSS->MaxDegree() == 1) &&
1398 (BSS->NbUPoles() == 2) &&
1399 (BSS->NbVPoles() == 2)) {
1400 gp_Pnt p11 = BSS->Pole(1,1);
1401 gp_Pnt p12 = BSS->Pole(1,2);
1402 gp_Pnt p21 = BSS->Pole(2,1);
1403 gp_Pnt p22 = BSS->Pole(2,2);
1404 gp_Vec V1(p11,p12);
1405 gp_Vec V2(p21,p22);
c6541a0c
D
1406 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1407 //if(V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
7fd59977 1408 // so the polar surface is plane
1409 // and if it is enough to projet the poles of Curve
1410 Standard_Integer Dist2Min = IntegerLast();
1411 Standard_Real u,v;
1412 //OCC217
1413 //Standard_Real TolU = Surf->UResolution(myTolerance)
1414 // , TolV = Surf->VResolution(myTolerance);
1415// gp_Pnt pntproj;
1416 if(TheTypeC == GeomAbs_BSplineCurve) {
1417 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1418 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1419 for(i = 1;i <= Curve->NbPoles();i++) {
1420 myProjIsDone = Standard_False;
1421 Dist2Min = IntegerLast();
1422 Extrema_GenLocateExtPS extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1423 (p11.Y()+p22.Y())/2,TolU,TolV) ;
1424 if (extrloc.IsDone()) {
1425 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1426 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1427 //if (Dist2Min < myTolerance * myTolerance) {
1428 (extrloc.Point()).Parameter(u,v);
1429 Poles2d(i).SetCoord(u,v);
1430 myProjIsDone = Standard_True;
1431 }
1432 else break;
1433 }
1434 else break;
1435 if(!myProjIsDone)
1436 break;
1437 }
1438 if(myProjIsDone) {
1439 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1440 BSC->Knots(Knots);
1441 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1442 BSC->Multiplicities(Mults);
1443 if(BSC->IsRational()) {
1444 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1445 BSC->Weights(Weights);
1446 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1447 BSC->Degree(), BSC->IsPeriodic()) ;
1448 }
1449 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1450 BSC->Degree(), BSC->IsPeriodic()) ;
1451
1452
1453 }
1454 }
1455 if(TheTypeC == GeomAbs_BezierCurve) {
1456 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1457 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1458 for(i = 1;i <= Curve->NbPoles();i++) {
1459 Dist2Min = IntegerLast();
1460 Extrema_GenLocateExtPS extrloc(BC->Pole(i),Surf->Surface(),0.5,
1461 0.5,TolU,TolV) ;
1462 if (extrloc.IsDone()) {
1463 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1464 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1465 //if (Dist2Min < myTolerance * myTolerance) {
1466 (extrloc.Point()).Parameter(u,v);
1467 Poles2d(i).SetCoord(u,v);
1468 myProjIsDone = Standard_True;
1469 }
1470 else break;
1471 }
1472 else break;
1473 if(myProjIsDone)
1474 myProjIsDone = Standard_False;
1475 else break;
1476 }
1477 if(myProjIsDone) {
1478 TColStd_Array1OfReal Knots(1, 2);
1479 Knots.SetValue(1,0.0);
1480 Knots.SetValue(2,1.0);
1481 TColStd_Array1OfInteger Mults(1, 2);
1482 Mults.Init(BC->NbPoles());
1483 if(BC->IsRational()) {
1484 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1485 BC->Weights(Weights);
1486 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1487 BC->Degree(), BC->IsPeriodic()) ;
1488 }
1489 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1490 BC->Degree(), BC->IsPeriodic()) ;
1491 }
1492 }
1493 }
1494 }
1495 }
1496 else if(TheTypeS == GeomAbs_BezierSurface) {
1497 Handle(Geom_BezierSurface) BS = Surf->Bezier();
1498 if((BS->MaxDegree() == 1) &&
1499 (BS->NbUPoles() == 2) &&
1500 (BS->NbVPoles() == 2)) {
1501 gp_Pnt p11 = BS->Pole(1,1);
1502 gp_Pnt p12 = BS->Pole(1,2);
1503 gp_Pnt p21 = BS->Pole(2,1);
1504 gp_Pnt p22 = BS->Pole(2,2);
1505 gp_Vec V1(p11,p12);
1506 gp_Vec V2(p21,p22);
c6541a0c
D
1507 if(V1.IsEqual(V2,Tol3d,Tol3d/(p11.Distance(p12)*180/M_PI))){ //OCC217
1508 //if (V1.IsEqual(V2,myTolerance,myTolerance/(p11.Distance(p12)*180/M_PI))){
7fd59977 1509 // and if it is enough to project the poles of Curve
1510 Standard_Integer Dist2Min = IntegerLast();
1511 Standard_Real u,v;
1512 //OCC217
1513 //Standard_Real TolU = Surf->UResolution(myTolerance)
1514 // , TolV = Surf->VResolution(myTolerance);
1515
1516// gp_Pnt pntproj;
1517 if(TheTypeC == GeomAbs_BSplineCurve) {
1518 Handle(Geom_BSplineCurve) BSC = Curve->BSpline();
1519 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1520 for(i = 1;i <= Curve->NbPoles();i++) {
1521 myProjIsDone = Standard_False;
1522 Dist2Min = IntegerLast();
1523 Extrema_GenLocateExtPS extrloc(BSC->Pole(i),Surf->Surface(),(p11.X()+p22.X())/2,
1524 (p11.Y()+p22.Y())/2,TolU,TolV) ;
1525 if (extrloc.IsDone()) {
1526 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1527 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1528 //if (Dist2Min < myTolerance * myTolerance) {
1529 (extrloc.Point()).Parameter(u,v);
1530 Poles2d(i).SetCoord(u,v);
1531 myProjIsDone = Standard_True;
1532 }
1533 else break;
1534 }
1535 else break;
1536 if(!myProjIsDone)
1537 break;
1538 }
1539 if(myProjIsDone) {
1540 TColStd_Array1OfReal Knots(1, BSC->NbKnots());
1541 BSC->Knots(Knots);
1542 TColStd_Array1OfInteger Mults(1, BSC->NbKnots());
1543 BSC->Multiplicities(Mults);
1544 if(BSC->IsRational()) {
1545 TColStd_Array1OfReal Weights(1, BSC->NbPoles());
1546 BSC->Weights(Weights);
1547 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1548 BSC->Degree(), BSC->IsPeriodic()) ;
1549 }
1550 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1551 BSC->Degree(), BSC->IsPeriodic()) ;
1552
1553
1554 }
1555 }
1556 if(TheTypeC == GeomAbs_BezierCurve) {
1557 Handle(Geom_BezierCurve) BC = Curve->Bezier();
1558 TColgp_Array1OfPnt2d Poles2d(1,Curve->NbPoles());
1559 for(i = 1;i <= Curve->NbPoles();i++) {
1560 Dist2Min = IntegerLast();
1561 Extrema_GenLocateExtPS extrloc(BC->Pole(i),Surf->Surface(),0.5,
1562 0.5,TolU,TolV) ;
1563 if (extrloc.IsDone()) {
1564 Dist2Min = (Standard_Integer ) extrloc.SquareDistance();
1565 if (Dist2Min < DistTol3d * DistTol3d) { //OCC217
1566 //if (Dist2Min < myTolerance * myTolerance) {
1567 (extrloc.Point()).Parameter(u,v);
1568 Poles2d(i).SetCoord(u,v);
1569 myProjIsDone = Standard_True;
1570 }
1571 else break;
1572 }
1573 else break;
1574 if(myProjIsDone)
1575 myProjIsDone = Standard_False;
1576 else break;
1577 }
1578 if(myProjIsDone) {
1579 TColStd_Array1OfReal Knots(1, 2);
1580 Knots.SetValue(1,0.0);
1581 Knots.SetValue(2,1.0);
1582 TColStd_Array1OfInteger Mults(1, 2);
1583 Mults.Init(BC->NbPoles());
1584 if(BC->IsRational()) {
1585 TColStd_Array1OfReal Weights(1, BC->NbPoles());
1586 BC->Weights(Weights);
1587 return new Geom2d_BSplineCurve(Poles2d, Weights, Knots, Mults,
1588 BC->Degree(), BC->IsPeriodic()) ;
1589 }
1590 return new Geom2d_BSplineCurve(Poles2d, Knots, Mults,
1591 BC->Degree(), BC->IsPeriodic()) ;
1592 }
1593 }
1594 }
1595 }
1596 }
1597
1598 ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, Tol3d) ; //OCC217
1599 //ProjLib_PolarFunction F(Curve, Surf, InitCurve2d, myTolerance) ;
1600
0797d9d3 1601#ifdef OCCT_DEBUG
7fd59977 1602 Standard_Integer Nb = 50;
1603
1604 Standard_Real U, U1, U2;
1605 U1 = F.FirstParameter();
1606 U2 = F.LastParameter();
1607
1608 TColgp_Array1OfPnt2d DummyPoles(1,Nb+1);
1609 TColStd_Array1OfReal DummyKnots(1,Nb+1);
1610 TColStd_Array1OfInteger DummyMults(1,Nb+1);
1611 DummyMults.Init(1);
1612 DummyMults(1) = 2;
1613 DummyMults(Nb+1) = 2;
1614 for (Standard_Integer ij = 0; ij <= Nb; ij++) {
1615 U = (Nb-ij)*U1 + ij*U2;
1616 U /= Nb;
1617 DummyPoles(ij+1) = F.Value(U);
1618 DummyKnots(ij+1) = ij;
1619 }
1620 Handle(Geom2d_BSplineCurve) DummyC2d =
1621 new Geom2d_BSplineCurve(DummyPoles, DummyKnots, DummyMults, 1);
7fd59977 1622#ifdef DRAW
96a95605 1623 Standard_CString Temp = "bs2d";
7fd59977 1624 DrawTrSurf::Set(Temp,DummyC2d);
1625#endif
1626// DrawTrSurf::Set((Standard_CString ) "bs2d",DummyC2d);
1627 Handle(Geom2dAdaptor_HCurve) DDD =
1628 Handle(Geom2dAdaptor_HCurve)::DownCast(InitCurve2d);
1629
7fd59977 1630#ifdef DRAW
96a95605 1631 Temp = "initc2d";
7fd59977 1632 DrawTrSurf::Set(Temp,DDD->ChangeCurve2d().Curve());
1633#endif
1634// DrawTrSurf::Set((Standard_CString ) "initc2d",DDD->ChangeCurve2d().Curve());
1635#endif
1636
1637 Standard_Integer Deg1,Deg2;
1638// Deg1 = 8;
1639// Deg2 = 8;
1640 Deg1 = 2; //IFV
1641 Deg2 = 8; //IFV
1642
1643 Approx_FitAndDivide2d Fit(F,Deg1,Deg2,Tol3d,Tol2d, //OCC217
1644 //Approx_FitAndDivide2d Fit(F,Deg1,Deg2,myTolerance,myTolerance,
1645 Standard_True);
1646
1647 if(Fit.IsAllApproximated()) {
1648 Standard_Integer i;
1649 Standard_Integer NbCurves = Fit.NbMultiCurves();
1650 Standard_Integer MaxDeg = 0;
1651 // To transform the MultiCurve into BSpline, it is required that all
1652 // Bezier constituing it have the same degree -> Calculation of MaxDeg
1653 Standard_Integer NbPoles = 1;
1654 for (i = 1; i <= NbCurves; i++) {
1655 Standard_Integer Deg = Fit.Value(i).Degree();
1656 MaxDeg = Max ( MaxDeg, Deg);
1657 }
1658
1659 NbPoles = MaxDeg * NbCurves + 1; //Tops on the BSpline
1660 TColgp_Array1OfPnt2d Poles( 1, NbPoles);
1661
1662 TColgp_Array1OfPnt2d TempPoles( 1, MaxDeg + 1);//to augment the degree
1663
1664 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Nodes of the BSpline
1665
1666 Standard_Integer Compt = 1;
1667 for (i = 1; i <= NbCurves; i++) {
1668 Fit.Parameters(i, Knots(i), Knots(i+1));
1669 AppParCurves_MultiCurve MC = Fit.Value( i); //Load the Ith Curve
1670 TColgp_Array1OfPnt2d Poles2d( 1, MC.Degree() + 1);//Retrieve the tops
1671 MC.Curve(1, Poles2d);
1672
1673 //Eventual augmentation of the degree
1674 Standard_Integer Inc = MaxDeg - MC.Degree();
1675 if ( Inc > 0) {
1676// BSplCLib::IncreaseDegree( Inc, Poles2d, PLib::NoWeights(),
1677 BSplCLib::IncreaseDegree( MaxDeg, Poles2d, PLib::NoWeights(),
1678 TempPoles, PLib::NoWeights());
1679 //update of tops of the PCurve
1680 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1681 Poles.SetValue( Compt, TempPoles( j));
1682 Compt++;
1683 }
1684 }
1685 else {
1686 //update of tops of the PCurve
1687 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
1688 Poles.SetValue( Compt, Poles2d( j));
1689 Compt++;
1690 }
1691 }
1692
1693 Compt--;
1694 }
1695
1696 //update of fields of ProjLib_Approx
1697 Standard_Integer NbKnots = NbCurves + 1;
1698
1699 // The start and end nodes are not correct : Cf: opening of the interval
86eff19e
J
1700 //Knots( 1) -= 1.e-9;
1701 //Knots(NbKnots) += 1.e-9;
7fd59977 1702
1703
1704 TColStd_Array1OfInteger Mults( 1, NbKnots);
1705 Mults.Init(MaxDeg);
1706 Mults.SetValue( 1, MaxDeg + 1);
1707 Mults.SetValue(NbKnots, MaxDeg + 1);
1708 myProjIsDone = Standard_True;
1709 Handle(Geom2d_BSplineCurve) Dummy =
1710 new Geom2d_BSplineCurve(Poles,Knots,Mults,MaxDeg);
1711
1712 // try to smoother the Curve GeomAbs_C1.
1713
1714 Standard_Boolean OK = Standard_True;
1715
1716 for (Standard_Integer ij = 2; ij < NbKnots; ij++) {
1717 OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,Tol3d); //OCC217
1718 //OK = OK && Dummy->RemoveKnot(ij,MaxDeg-1,myTolerance);
1719 }
0797d9d3 1720#ifdef OCCT_DEBUG
7fd59977 1721 if (!OK) {
1722 cout << "ProjLib_ComputeApproxOnPolarSurface : Smoothing echoue"<<endl;
1723 }
1724#endif
1725 return Dummy;
1726 }
1727 return Handle(Geom2d_BSplineCurve)();
1728}
1729
1730//=======================================================================
1731//function : BSpline
1732//purpose :
1733//=======================================================================
1734
1735Handle(Geom2d_BSplineCurve)
1736 ProjLib_ComputeApproxOnPolarSurface::BSpline() const
1737
1738{
1739// Modified by Sergey KHROMOV - Thu Apr 18 11:16:46 2002 End
1740// Standard_NoSuchObject_Raise_if
1741// (!myProjIsDone,
1742// "ProjLib_ComputeApproxOnPolarSurface:BSpline");
1743// Modified by Sergey KHROMOV - Thu Apr 18 11:16:47 2002 End
1744 return myBSpline ;
1745}
1746
1747//=======================================================================
1748//function : Curve2d
1749//purpose :
1750//=======================================================================
1751
1752Handle(Geom2d_Curve)
1753 ProjLib_ComputeApproxOnPolarSurface::Curve2d() const
1754
1755{
1756 Standard_NoSuchObject_Raise_if
1757 (!myProjIsDone,
1758 "ProjLib_ComputeApproxOnPolarSurface:2ndCurve2d");
1759 return my2ndCurve ;
1760}
1761
1762
1763//=======================================================================
1764//function : IsDone
1765//purpose :
1766//=======================================================================
1767
1768Standard_Boolean ProjLib_ComputeApproxOnPolarSurface::IsDone() const
1769
1770{
1771 return myProjIsDone;
1772}