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