0025791: Impossibility to generate projects for Foundation Classes without TclTk...
[occt.git] / src / ShapeConstruct / ShapeConstruct_ProjectCurveOnSurface.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14//:k1 abv 16.12.98 K4L PRO10107, PRO10108, PRO10109
15//:j8 abv 10.12.98 TR10 r0501_db.stp #9423
16//:S4030 abv, pdn: new methods - interface to standard ProjLib_CompProjectedCurve
17//%12 pdn 15.02.99 PRO9234 optimizing
18//%12 pdn 15.02.99 PRO9234 using improved ProjectDegenerated method
19// rln 03.03.99 S4135: bm2_sd_t4-A.stp treatment of Geom_SphericalSurface together with V-closed surfaces
20//:p9 abv 11.03.99 PRO7226 #489490: make IsAnIsoparametric to find nearest case
21//:q1 abv 15.03.99 (pdn) PRO7226 #525030: limit NextValueOfUV() by tolerance
22//:q5 abv 19.03.99 code improvement
23//:q9 abv 23.03.99 PRO7226.stp #489490: cashe for projecting end points
24//#78 rln 12.03.99 S4135: checking spatial closure with myPreci
25// pdn 12.03.99 S4135: creating pcurve with minimal length in the case of densed points
26// abv 29.03.99 IsAnIsoparametric with Precision::Confusion
27// pdn 09.04.99 IsAnisoparametric uses already computed parameters (S4030, fix PRO14323)
28//szv#4 S4163
29//:s5 abv 22.04.99 Adding debug printouts in catch {} blocks
30//#1 svv 11.01.00 Porting on DEC
31#include <ShapeConstruct_ProjectCurveOnSurface.ixx>
32
33#include <Standard_ErrorHandler.hxx>
34#include <Standard_Failure.hxx>
35
36#include <Precision.hxx>
37#include <TColStd_Array1OfInteger.hxx>
38#include <TColgp_Array1OfPnt.hxx>
39
40#include <GeomAPI_PointsToBSpline.hxx>
41#include <Geom2dAPI_Interpolate.hxx>
42#include <GeomAPI_Interpolate.hxx>
43#include <Geom2dAdaptor.hxx>
44#include <Geom2d_Line.hxx>
45#include <Geom2d_TrimmedCurve.hxx>
46#include <Geom2d_BSplineCurve.hxx>
47#include <Geom_BSplineCurve.hxx>
48#include <Geom_TrimmedCurve.hxx>
49#include <Geom_RectangularTrimmedSurface.hxx>
50#include <Geom_SurfaceOfLinearExtrusion.hxx>
51#include <Geom_SphericalSurface.hxx>
52#include <Geom_OffsetSurface.hxx>
53#include <Geom_Plane.hxx>
54#include <GeomProjLib.hxx>
55#include <GeomAdaptor_HSurface.hxx>
56#include <GeomAdaptor_HCurve.hxx>
57
58#include <ShapeAnalysis_Curve.hxx>
59#include <ShapeAnalysis_Surface.hxx>
60#include <ShapeExtend.hxx>
61
62#include <ProjLib_ProjectedCurve.hxx>
63#include <ProjLib_CompProjectedCurve.hxx>
64#include <ProjLib_HCompProjectedCurve.hxx>
65#include <Approx_CurveOnSurface.hxx>
66
67#define NCONTROL 23
b311480e 68
7fd59977 69//=======================================================================
70//function : ShapeConstruct_ProjectCurveOnSurface
71//purpose :
72//=======================================================================
73
74ShapeConstruct_ProjectCurveOnSurface::ShapeConstruct_ProjectCurveOnSurface()
75{
76 myPreci = Precision::Confusion();
77 myBuild = Standard_False;
78 myAdjustOverDegen = 1; //:c0 //szv#4:S4163:12Mar99 was boolean
79 myNbCashe = 0; //:q9
80}
81
82//=======================================================================
83//function : Init
84//purpose :
85//=======================================================================
86
87 void ShapeConstruct_ProjectCurveOnSurface::Init(const Handle(Geom_Surface)& surf,const Standard_Real preci)
88{
89 Init (new ShapeAnalysis_Surface (surf), preci);
90}
91
92//=======================================================================
93//function : Init
94//purpose :
95//=======================================================================
96
97 void ShapeConstruct_ProjectCurveOnSurface::Init(const Handle(ShapeAnalysis_Surface)& surf,const Standard_Real preci)
98{
99 SetSurface (surf);
100 SetPrecision (preci);
101}
102
103//=======================================================================
104//function : SetSurface
105//purpose :
106//=======================================================================
107
108 void ShapeConstruct_ProjectCurveOnSurface::SetSurface(const Handle(Geom_Surface)& surf)
109{
110 SetSurface (new ShapeAnalysis_Surface (surf));
111}
112
113//=======================================================================
114//function : SetSurface
115//purpose :
116//=======================================================================
117
118 void ShapeConstruct_ProjectCurveOnSurface::SetSurface(const Handle(ShapeAnalysis_Surface)& surf)
119{
120 if ( mySurf == surf ) return;
121 mySurf = surf;
122 myNbCashe = 0; //:q9
123}
124
125//=======================================================================
126//function : SetPrecision
127//purpose :
128//=======================================================================
129
130 void ShapeConstruct_ProjectCurveOnSurface::SetPrecision(const Standard_Real preci)
131{
132 myPreci = preci;
133}
134
135//=======================================================================
136//function : BuildCurveMode
137//purpose :
138//=======================================================================
139
140 Standard_Boolean& ShapeConstruct_ProjectCurveOnSurface::BuildCurveMode()
141{
142 return myBuild;
143}
144
145//=======================================================================
146//function : AdjustOverDegenMode
147//purpose :
148//=======================================================================
149//:c0
150
151//szv#4:S4163:12Mar99 was Boolean
152 Standard_Integer& ShapeConstruct_ProjectCurveOnSurface::AdjustOverDegenMode()
153 {
154 return myAdjustOverDegen;
155 }
156
157
158//=======================================================================
159//function : NbSurfIntervals
160//purpose : work-around of bug in standard method
161// GeomAdaptor_Surface->NbIntervals() (PRO16346)
162//=======================================================================
163
164static Standard_Integer NbSurfIntervals(const Handle(GeomAdaptor_HSurface)& GAS, const GeomAbs_Shape cont)
165{
166 Standard_Integer NbU = 0;
167 if (GAS->GetType() == GeomAbs_SurfaceOfExtrusion) {
168 // extract the surface
169 Handle(Geom_SurfaceOfLinearExtrusion) surf = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(GAS->ChangeSurface().Surface());
170 // build a 3d adaptor curve
171 GeomAdaptor_Curve Adaptor3dCurve(surf->BasisCurve(), GAS->FirstUParameter(), GAS->LastUParameter());
172 if (Adaptor3dCurve.GetType() == GeomAbs_BSplineCurve)
173 NbU = Adaptor3dCurve.NbIntervals(cont);
174 }
175 if (NbU == 0)
176 NbU = GAS->NbUIntervals(cont);
177 return NbU * (GAS->NbVIntervals(cont));
178}
179
180//=======================================================================
181//function : Status
182//purpose :
183//=======================================================================
184
185 Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Status (const ShapeExtend_Status Status) const
186{
187 return ShapeExtend::DecodeStatus (myStatus, Status);
188}
189
190//=======================================================================
191//function : Perform
192//purpose :
193//=======================================================================
194
195Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::Perform (Handle(Geom_Curve)& c3d,
196 const Standard_Real First,
197 const Standard_Real Last,
198 Handle(Geom2d_Curve)& c2d,
199 const GeomAbs_Shape,
200 const Standard_Integer,
201 const Standard_Integer)
202{
203 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
204 //Standard_Boolean OK = Standard_True; //szv#4:S4163:12Mar99 not needed
205
206 if (mySurf.IsNull()) {
207 c2d.Nullify();
208 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
209 return Standard_False;
210 }
211
212// Projection Analytique
213 Handle(Geom_Curve) crv3dtrim = c3d;
214 if ( ! c3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) )
215 crv3dtrim = new Geom_TrimmedCurve ( c3d, First, Last );
216 c2d = ProjectAnalytic ( crv3dtrim );
217 if (!c2d.IsNull()) {
218 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
219 return Standard_True;
220 }
221
222// Projection par approximation
223
224 // discretize the 3d curve
225
226 Standard_Integer nbrPnt;
227
228// $$$$ :92 abv 28 Jan 98 see PRO10107, big BSplineCurve C0
229 Standard_Integer nbPini = NCONTROL; // as in BRepCheck_Edge (RLN/Nijni)
230 // 20; // number of points for interpolation, should be "parametric dependent"
231
232 //:92 abv 28 Jan 98: if curve is BSpline with many intervals,
233 // increase number of points to provide at least Degree()+1 points per interval
234 Handle(Geom_BSplineCurve) bspl;
235 if ( c3d->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)) ) {
236 Handle(Geom_TrimmedCurve) ctrim = Handle(Geom_TrimmedCurve)::DownCast(c3d);
237 bspl = Handle(Geom_BSplineCurve)::DownCast ( ctrim->BasisCurve() );
238 }
239 else bspl = Handle(Geom_BSplineCurve)::DownCast ( c3d );
240 if ( ! bspl.IsNull() ) {
241 Standard_Integer nint = 0;
242 for ( Standard_Integer i=1; i < bspl->NbKnots(); i++ )
243 if ( bspl->Knot(i+1) > First && bspl->Knot(i) < Last ) nint++;
244 Standard_Integer minPnt = nint * ( bspl->Degree() + 1 );
245 while ( nbPini < minPnt ) nbPini += NCONTROL - 1;
0797d9d3 246#ifdef OCCT_DEBUG
7fd59977 247 if ( nbPini > NCONTROL )
248 cout << "Warning: number of points for projecting is " << nbPini << endl;
249#endif
250 }
251
252// $$$$ end :92 (big BSplineCurve C0)
253
254 // this number should be "parametric dependent"
255 TColgp_Array1OfPnt points(1, nbPini);
256 TColStd_Array1OfReal params(1, nbPini);
257
258 Standard_Integer iPnt;
259 gp_Pnt p3d;
260 Standard_Real deltaT, t;
261 deltaT = (Last - First) / (nbPini-1);
262 nbrPnt = nbPini;
263 for (iPnt = 1; iPnt <= nbPini; iPnt ++) {
264 if (iPnt == 1) t = First;
265 else if (iPnt == nbPini) t = Last;
266 else t = First + (iPnt - 1) * deltaT;
267
268 c3d->D0 (t, p3d);
269 points(iPnt) = p3d;
270 params(iPnt) = t;
271 }
272
273// CALCUL par approximation
274
275 TColgp_Array1OfPnt2d pnt2d(1, nbrPnt);
276 ApproxPCurve (nbrPnt,points,params,pnt2d,c2d); //szv#4:S4163:12Mar99 OK not needed
277 if (!c2d.IsNull()) {
278 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
279 return Standard_True;
280 }// cas particulier d iso
281
282// INTERPOLATION du resultat
283
284 if ( myBuild ) {
285 Handle(TColgp_HArray1OfPnt) thePnts = new TColgp_HArray1OfPnt (1, nbPini);
286 Handle(TColStd_HArray1OfReal) theParams = new TColStd_HArray1OfReal(1, nbPini);
287 for (iPnt = 1; iPnt <= nbPini ; iPnt ++) {
288 thePnts->SetValue(iPnt, points(iPnt));
289 theParams->SetValue(iPnt, params(iPnt));
290 }
291
292 Handle(Geom_Curve) newc3d = InterpolateCurve3d (nbPini,thePnts,theParams, c3d);
293 if ( newc3d.IsNull() ) myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
294 else {
295 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE3);
296 c3d = newc3d;
297 }
298 }
299
300 Handle(TColgp_HArray1OfPnt2d) thePnts2d = new TColgp_HArray1OfPnt2d(1, nbPini);
301 Handle(TColStd_HArray1OfReal) theParams2d = new TColStd_HArray1OfReal(1, nbPini);
302 for (iPnt = 1; iPnt <= nbPini ; iPnt ++) {
303 theParams2d->SetValue(iPnt, params(iPnt));
304 thePnts2d->SetValue(iPnt, pnt2d(iPnt));
305 }
306
307 c2d = InterpolatePCurve (nbPini, thePnts2d, theParams2d, c3d);
308// c2d = ApproximatePCurve (nbPini, thePnts2d, theParams2d, c3d);
309// Faut-il aussi reprendre la C3D ?
310
311 myStatus |= ShapeExtend::EncodeStatus (c2d.IsNull() ? ShapeExtend_FAIL1 : ShapeExtend_DONE2);
312 return Status (ShapeExtend_DONE);
313}
314
315//=======================================================================
316//function : PerformByProjLib
317//purpose :
318//=======================================================================
319
320Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(Handle(Geom_Curve)& c3d,
321 const Standard_Real First,
322 const Standard_Real Last,
323 Handle(Geom2d_Curve)& c2d,
324 const GeomAbs_Shape continuity,
325 const Standard_Integer maxdeg,
326 const Standard_Integer nbinterval)
327{
328 //Standard_Boolean OK = Standard_True; //szv#4:S4163:12Mar99 unused
329 c2d.Nullify();
330 if (mySurf.IsNull()) {
331 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
332 return Standard_False;
333 }
334
335 try {
336 OCC_CATCH_SIGNALS
337 Handle(GeomAdaptor_HSurface) GAS = mySurf->Adaptor3d();
338 Standard_Real URes = GAS->ChangeSurface().UResolution ( myPreci );
339 Standard_Real VRes = GAS->ChangeSurface().VResolution ( myPreci );
340 Handle(GeomAdaptor_HCurve) GAC = new GeomAdaptor_HCurve (c3d,First,Last);
341 ProjLib_CompProjectedCurve Projector ( GAS, GAC, URes, VRes );
342
343 Standard_Real ubeg, ufin;
344 Standard_Integer nbSol = Projector.NbCurves();
345 if (nbSol==1) {
346 Projector.Bounds(1, ubeg, ufin);
347 if((ubeg<=First)&&(ufin>=Last)) {
348 Standard_Integer nbintervals = ( nbinterval < 1 ?
349 NbSurfIntervals(GAS, GeomAbs_C3)+GAC->NbIntervals(GeomAbs_C3)+2:
350 nbinterval);
351 Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
352 HProjector->Set(Projector);
353 Handle(Adaptor2d_HCurve2d) HPCur = HProjector;
354 Approx_CurveOnSurface appr(HPCur, GAS, First, Last, myPreci,
355 continuity, maxdeg,
356 nbintervals,
357 Standard_False, Standard_True);
358 if ( appr.IsDone() )
359 c2d = appr.Curve2d();
360 }
0797d9d3 361#ifdef OCCT_DEBUG
7fd59977 362 else
363 cout<<"Warning: ProjLib cutting pcurve "<< First << " -> " << ubeg <<" ; "<< Last << " -> " << ufin << endl;
364#endif
365 }
0797d9d3 366#ifdef OCCT_DEBUG
7fd59977 367 else cout<<"Warning: ProjLib "<< nbSol << " curves in ProjLib"<<endl;
368#endif
369 if(c2d.IsNull()) {
370 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
371 return Standard_False;
372 }
373 else {
374 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
375 return Standard_True;
376 }
377
378 }
379 catch(Standard_Failure) {
0797d9d3 380#ifdef OCCT_DEBUG
7fd59977 381 cout << "Warning: ShapeConstruct_ProjectCurveOnSurface::PerformByProjLib(): Exception: ";
382 Standard_Failure::Caught()->Print(cout); cout << endl;
383#endif
384 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
385 c2d.Nullify();
386 }
387 return Standard_False;
388}
389
390//=======================================================================
391//function : PerformAdvanced
392//purpose :
393//=======================================================================
394
395Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::PerformAdvanced (Handle(Geom_Curve)& c3d,
396 const Standard_Real First,
397 const Standard_Real Last,
398 Handle(Geom2d_Curve)& c2d)
399{
400 Standard_Boolean hasResult = Standard_False;
401 Standard_Integer nbintervals;
402
403 Standard_Boolean isStandard = (mySurf->Adaptor3d()->GetType() != GeomAbs_Cylinder);
404// && (mySurf->Adaptor3d()->GetType() != GeomAbs_SurfaceOfRevolution);
405
406 if (isStandard) isStandard = !mySurf->HasSingularities(myPreci);
407 if (isStandard) {
408 Handle(GeomAdaptor_HSurface) GAS = mySurf->Adaptor3d();
409 Handle(GeomAdaptor_HCurve) GAC = new GeomAdaptor_HCurve (c3d,First,Last);
410 nbintervals = NbSurfIntervals(GAS, GeomAbs_C1);//+GAC->NbIntervals(GeomAbs_C3);
411 isStandard = (nbintervals < 2);
412 }
413 if (isStandard) {
414 hasResult = PerformByProjLib(c3d, First, Last, c2d);
415 }
416 if (!hasResult) hasResult = Perform (c3d, First, Last, c2d);
417 return hasResult;
418}
419
420//=======================================================================
421//function : ProjectAnalytic
422//purpose :
423//=======================================================================
424
425 Handle(Geom2d_Curve) ShapeConstruct_ProjectCurveOnSurface::ProjectAnalytic(const Handle(Geom_Curve)& c3d) const
426{
427 Handle(Geom2d_Curve) result;
428
429 //:k1 abv 16 Dec 98: limit analytic cases by Plane surfaces only
430 // This is necessary for K4L since it fails on other surfaces
431 // when general method GeomProjLib::Curve2d() is used
432 // Projection is done as in BRep_Tool and BRepCheck_Edge
433 Handle(Geom_Surface) surf = mySurf->Surface();
434 Handle(Geom_Plane) Plane = Handle(Geom_Plane)::DownCast ( surf );
435 if ( Plane.IsNull() ) {
436 Handle(Geom_RectangularTrimmedSurface) RTS =
437 Handle(Geom_RectangularTrimmedSurface)::DownCast ( surf );
438 if ( ! RTS.IsNull() ) Plane = Handle(Geom_Plane)::DownCast ( RTS->BasisSurface() );
439 else {
440 Handle(Geom_OffsetSurface) OS =
441 Handle(Geom_OffsetSurface)::DownCast ( surf );
442 if ( ! OS.IsNull() )
443 Plane = Handle(Geom_Plane)::DownCast ( OS->BasisSurface() );
444 }
445 }
446 if ( ! Plane.IsNull() ) {
447 Handle(Geom_Curve) ProjOnPlane =
448 GeomProjLib::ProjectOnPlane (c3d, Plane,
449 Plane->Position().Direction(), Standard_True);
450 Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve ( ProjOnPlane );
451 ProjLib_ProjectedCurve Proj ( mySurf->Adaptor3d(), HC );
452
453 result = Geom2dAdaptor::MakeCurve(Proj);
454 if ( result.IsNull() ) return result;
455 if ( result->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ) {
456 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast ( result );
457 result = TC->BasisCurve();
458 }
63c629aa 459
7fd59977 460 return result;
461 }
462
463 return result;
464}
465
466//=======================================================================
467//function : ApproxPCurve
468//purpose :
469//=======================================================================
470
471 Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::ApproxPCurve(const Standard_Integer nbrPnt,
472 const TColgp_Array1OfPnt& points,
473 const TColStd_Array1OfReal& params,
474 TColgp_Array1OfPnt2d& pnt2d,
475 Handle(Geom2d_Curve)& c2d)
476{
477 Standard_Boolean isDone = Standard_True;
478
479 // test if the curve 3d is a boundary of the surface
480 // (only for Bezier or BSpline surface)
481
482 Standard_Boolean isoParam, isoPar2d3d, isoTypeU, p1OnIso, p2OnIso, isoclosed;
483 gp_Pnt2d valueP1, valueP2;
484 Handle(Geom_Curve) cIso;
485 Standard_Real t1, t2;
486
487 Handle(Standard_Type) sType = mySurf->Surface()->DynamicType();
488 Standard_Boolean isAnalytic = Standard_True;
489 if (sType == STANDARD_TYPE(Geom_BezierSurface) || sType == STANDARD_TYPE(Geom_BSplineSurface)) isAnalytic = Standard_False;
490 Standard_Real uf, ul, vf, vl;
491 mySurf->Surface()->Bounds(uf, ul, vf, vl);
492 isoclosed = Standard_False;
493 TColStd_Array1OfReal pout(1, nbrPnt);
494
495 isoParam = IsAnIsoparametric(nbrPnt, points, params,
496 isoTypeU, p1OnIso, valueP1, p2OnIso, valueP2,
497 isoPar2d3d, cIso, t1, t2, pout);
498
499 // projection of the points on surfaces
500
501 gp_Pnt p3d;
502 gp_Pnt2d p2d;
503 Standard_Integer i;
504 Standard_Real isoValue=0., isoPar1=0., isoPar2=0., tPar=0., tdeb,tfin;
505 Standard_Real Cf, Cl, parf, parl; //szv#4:S4163:12Mar99 dist not needed
506
507 // Le calcul part-il dans le bon sens, c-a-d deb et fin dans le bon ordre ?
508 // Si uclosed et iso en V, attention isoPar1 ET/OU 2 peut toucher la fermeture
509 if(isoParam){
510 if(isoTypeU){
511 isoValue = valueP1.X();
512 isoPar1 = valueP1.Y();
513 isoPar2 = valueP2.Y();
514 isoclosed = mySurf->IsVClosed(myPreci);//#78 rln 12.03.99 S4135
515 parf = vf; parl = vl;
516 }
517 else {
518 isoValue = valueP1.Y();
519 isoPar1 = valueP1.X();
520 isoPar2 = valueP2.X();
521 isoclosed = mySurf->IsUClosed(myPreci);//#78 rln 12.03.99 S4135
522 parf = uf; parl = ul;
523 }
524 if (!isoPar2d3d && !isAnalytic) {
525 Cf = cIso->FirstParameter();
526 Cl = cIso->LastParameter();
527 if (Precision::IsInfinite(Cf)) Cf = -1000;
528 if (Precision::IsInfinite(Cl)) Cl = +1000;
529 //pdn S4030 optimizing and fix isopar case on PRO41323
530 tdeb = pout(2);
531 // dist = ShapeAnalysis_Curve().Project (cIso,points(2),myPreci,pt,tdeb,Cf,Cl);
532 // Chacun des par1 ou par2 est-il sur un bord. Attention first/last : recaler
533 if (isoclosed && (isoPar1 == parf || isoPar1 == parl)) {
534 if (Abs(tdeb-parf) < Abs(tdeb-parl)) isoPar1 = parf;
535 else isoPar1 = parl;
536 if (isoTypeU) valueP1.SetY (isoPar1);
537 else valueP1.SetX (isoPar1);
538 }
539 if (isoclosed && (isoPar2 == parf || isoPar2 == parl)) {
540 //pdn S4030 optimizing and fix isopar case on PRO41323
541 tfin = pout(nbrPnt-1);
542 //dist = ShapeAnalysis_Curve().Project (cIso,points(nbrPnt-1),myPreci,pt,tfin,Cf,Cl);
543 if (Abs(tfin-parf) < Abs(tfin-parl)) isoPar2 = parf;
544 else isoPar2 = parl;
545 if (isoTypeU) valueP2.SetY (isoPar2);
546 else valueP2.SetX (isoPar2);
547 }
548
549 // Interversion Par1/Par2 (ne veut que si les 2 sont sur les bords ...)
550 // Est-ce encore necessaire apres ce qui vient d etre fait ?
551
552 // PTV 05.02.02 fix for translation face from 12_hp_mouse (PARASOLID) face 24008
553 // if curve is periodic do not change the points
554 // skl change "if" for pout(nbrPnt-1) 19.11.2003
555 if (!isoclosed) {
556 if( (Abs(tdeb-isoPar1)>Abs(tdeb-isoPar2)) &&
557 (Abs(pout(nbrPnt-1)-isoPar2)>Abs(pout(nbrPnt-1)-isoPar1)) ) {
558 gp_Pnt2d valueTmp = valueP1;
559 valueP1 = valueP2; valueP2 = valueTmp;
560 if (isoTypeU) {
561 isoValue = valueP1.X();
562 isoPar1 = valueP1.Y();
563 isoPar2 = valueP2.Y();
564 }
565 else {
566 isoValue = valueP1.Y();
567 isoPar1 = valueP1.X();
568 isoPar2 = valueP2.X();
569 }
570 // Fin calcul sens de courbe iso
571 }
572 } // end of fix check 05.02.02
573 }
574 }
575
576 // Si pas isoParam, on a quand meme du p1OnIso/p2OnIso possible ... !!!
577 // (utile pour detromper bug de projection). Mais detromper aussi circularite
578 //else {
579 //if (p1OnIso) valueP1 =
580 //BestExtremum (valueP1,points(1),points(2));
581 //if (p2OnIso) valueP2 =
582 //BestExtremum (valueP2,points(nbrPnt),points(nbrPnt-1));
583 //}
584
585 Standard_Real gap = myPreci; //:q1
586 Standard_Boolean ChangeCycle = Standard_False; //skl for OCC3430
587 if( myNbCashe>0 && myCashe3d[0].Distance(points(1))>myCashe3d[0].Distance(points(nbrPnt)) )
588 //if(myCashe3d[0].Distance(points(nbrPnt))<myPreci)
589 if(myCashe3d[0].Distance(points(nbrPnt))<Precision::Confusion())
590 ChangeCycle = Standard_True;
591 //for( i = 1; i <= nbrPnt; i ++) {
592 for(Standard_Integer ii=1; ii<=nbrPnt; ii++) {
593 if(ChangeCycle) //skl for OCC3430
594 i=nbrPnt-ii+1;
595 else
596 i=ii;
597 p3d = points(i);
598 if (isoParam) {
599
600 if (isoPar2d3d) {
601 if (isoPar2 > isoPar1) tPar = params(i);
602 else tPar = t1 + t2 - params(i);
603 } else if (!isAnalytic) {
604 // projection to iso
605 if (i==1) tPar = isoPar1;
606 else if (i==nbrPnt) tPar = isoPar2;
607 else {
608 tPar = pout(i);
609 //:S4030 ShapeAnalysis_Curve().Project (cIso,p3d,myPreci,pt,tPar,Cf,Cl); //szv#4:S4163:12Mar99 `dist=` not needed
610 }
611 }
612
613 if (!isoPar2d3d && isAnalytic) {
614 if (i == 1) p2d = valueP1;
615 else if (i == nbrPnt) p2d = valueP2;
616 else {
617 p2d = mySurf->NextValueOfUV(p2d,p3d, myPreci, //%12 pdn 15.02.99 optimizing
618 Precision::Confusion()+1000*gap); //:q1
619 gap = mySurf->Gap();
620 }
621 } else {
622 if(isoTypeU) { p2d.SetX(isoValue); p2d.SetY(tPar); }
623 else { p2d.SetX(tPar); p2d.SetY(isoValue); }
624 }
625 }
626
627 else {
628 if ( (i == 1) && p1OnIso) p2d = valueP1;
629 else if( (i == nbrPnt) && p2OnIso) p2d = valueP2;
630 else {// general case (not an iso) mais attention aux singularites !
631 if ( ii==1 ) {
632 //:q9 abv 23 Mar 99: use cashe as 1st approach
633 Standard_Integer j; // svv #1
634 for ( j=0; j < myNbCashe; j++ )
635 if ( myCashe3d[j].SquareDistance ( p3d ) < myPreci*myPreci ) {
636 p2d = mySurf->NextValueOfUV (myCashe2d[j], p3d, myPreci,
637 Precision::Confusion()+gap);
638 break;
639 }
640 if ( j >= myNbCashe ) p2d = mySurf->ValueOfUV(p3d, myPreci);
641 }
642 else {
643 p2d = mySurf->NextValueOfUV (p2d, p3d, myPreci, //:S4030: optimizing
644 Precision::Confusion()+1000*gap); //:q1
645 }
646 gap = mySurf->Gap();
647 }
648 }
649 pnt2d (i) = p2d;
650 if ( ii > 1 ) {
651 if(ChangeCycle)
652 p2d.SetXY ( 2. * p2d.XY() - pnt2d(i+1).XY() );
653 else
654 p2d.SetXY ( 2. * p2d.XY() - pnt2d(i-1).XY() );
655 }
656 }
657
658 //pdn %12 11.02.99 PRO9234 entity 15402
659 if (!isoPar2d3d) {
660 mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_True);
661 mySurf->ProjectDegenerated(nbrPnt,points,pnt2d,myPreci,Standard_False);
662 }
663
664 // attention aux singularites ... (hors cas iso qui les traite deja)
665 // if (!isoParam) {
666 // p2d = pnt2d (1);
667 // if (mySurf->ProjectDegenerated (points(1),myPreci,pnt2d (2),p2d))
668 // pnt2d (1) = p2d;
669 // p2d = pnt2d (nbrPnt);
670 // if (mySurf->ProjectDegenerated (points(nbrPnt),myPreci,pnt2d (nbrPnt-1),p2d))
671 // pnt2d (nbrPnt) = p2d;
672 // }
673
674 // Si la surface est UCLosed et VClosed, on recadre les points
675 // algo un peu complique, on retarde l implementation
676 Standard_Real Up = ul - uf;
677 Standard_Real Vp = vl - vf;
678 Standard_Real dist2d;
0797d9d3 679#ifdef OCCT_DEBUG
7fd59977 680 if (mySurf->IsUClosed(myPreci) && mySurf->IsVClosed(myPreci)) {//#78 rln 12.03.99 S4135
681 cout << "WARNING : Recadrage incertain sur U & VClosed" << endl;
682 }
683#endif
684 // Si la surface est UCLosed, on recadre les points
685 if (mySurf->IsUClosed(myPreci)) {//#78 rln 12.03.99 S4135
686 // Premier point dans le domain [uf, ul]
687 Standard_Real prevX, firstX = pnt2d (1).X();
688 while (firstX < uf) { firstX += Up; pnt2d (1).SetX(firstX); }
689 while (firstX > ul) { firstX -= Up; pnt2d (1).SetX(firstX); }
690 prevX = firstX;
691
692 //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds
693 Standard_Real minX = firstX, maxX = firstX;
694
695 // On decalle toujours le suivant
696 for (i = 2; i <= nbrPnt; i++) {
697 // dist2d = pnt2d (i-1).Distance(pnt2d (i));
698 Standard_Real CurX = pnt2d (i).X();
699 dist2d = Abs (CurX - prevX);
700 if (dist2d > ( Up / 2) ) {
701 if (CurX > prevX + Up/2) {
702 while (CurX > prevX + Up/2) { CurX -= Up; pnt2d (i).SetX (CurX); }
703 } else if (CurX < prevX - Up/2) {
704 while (CurX < prevX - Up/2) { CurX += Up; pnt2d (i).SetX (CurX); }
705 }
706
707 }
708 prevX = CurX;
709 if ( minX > CurX ) minX = CurX; //:97
710 else if ( maxX < CurX ) maxX = CurX; //:97
711 }
712
713 //:97
714 Standard_Real midX = 0.5 * ( minX + maxX );
715 Standard_Real shiftX=0.;
716 if ( midX > ul ) shiftX = -Up;
717 else if ( midX < uf ) shiftX = Up;
718 if ( shiftX != 0. )
719 for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetX ( pnt2d(i).X() + shiftX );
720 }
721 // Si la surface est VCLosed, on recadre les points
722 // Same code as UClosed : optimisation souhaitable !!
723 // CKY : d abord un code IDENTIQUE A UClosed; PUIS le special Seam ...
724 // Si la surface est UCLosed, on recadre les points
725 //
726 //#69 rln 01.03.99 S4135 bm2_sd_t4-A.stp entity 30
727 //#78 rln 12.03.99 S4135
728 if (mySurf->IsVClosed(myPreci) || mySurf->Surface()->IsKind (STANDARD_TYPE (Geom_SphericalSurface))) {
729 // Premier point dans le domain [vf, vl]
730 Standard_Real prevY, firstY = pnt2d (1).Y();
731 while (firstY < vf) { firstY += Vp; pnt2d (1).SetY(firstY); }
732 while (firstY > vl) { firstY -= Vp; pnt2d (1).SetY(firstY); }
733 prevY = firstY;
734
735 //:97 abv 1 Feb 98: treat case when curve is whole out of surface bounds
736 Standard_Real minY = firstY, maxY = firstY;
737
738 // On decalle toujours le suivant
739 for (i = 2; i <= nbrPnt; i ++) {
740 // dist2d = pnt2d (i-1).Distance(pnt2d (i));
741 Standard_Real CurY = pnt2d (i).Y();
742 dist2d = Abs (CurY - prevY);
743 if (dist2d > ( Vp / 2) ) {
744 if (CurY > prevY + Vp/2) {
745 while (CurY > prevY + Vp/2) { CurY -= Vp; pnt2d (i).SetY (CurY); }
746 } else if (CurY < prevY - Vp/2) {
747 while (CurY < prevY - Vp/2) { CurY += Vp; pnt2d (i).SetY (CurY); }
748 }
749 }
750 prevY = CurY;
751 if ( minY > CurY ) minY = CurY; //:97
752 else if ( maxY < CurY ) maxY = CurY; //:97
753 }
754
755 //:97
756 Standard_Real midY = 0.5 * ( minY + maxY );
757 Standard_Real shiftY=0.;
758 if ( midY > vl ) shiftY = -Vp;
759 else if ( midY < vf ) shiftY = Vp;
760 if ( shiftY != 0. )
761 for ( i=1; i <= nbrPnt; i++ ) pnt2d(i).SetY ( pnt2d(i).Y() + shiftY );
762 }
763
764 //#69 rln 01.03.99 S4135 bm2_sd_t4-A.stp entity 30
765 //#78 rln 12.03.99 S4135
766 if (mySurf->IsVClosed(myPreci) || mySurf->Surface()->IsKind (STANDARD_TYPE (Geom_SphericalSurface))) {
767 for (i = 2; i <= nbrPnt; i++) {
768 //#1 rln 11/02/98 ca_exhaust.stp entity #9869 dist2d = pnt2d (i-1).Distance(pnt2d (i));
769 dist2d = Abs (pnt2d(i).Y() - pnt2d(i - 1).Y());
770 if (dist2d > ( Vp / 2) ) {
771 // ATTENTION : il faut regarder ou le decalage se fait.
772 // si plusieurs points sont decalles, il faut plusieurs passes
773 // pour obtenir un resultat correct.
774 // NOT YET IMPLEMENTED
775
776 // one of those point is incorrectly placed
777 // i.e on the wrong side of the "seam"
778 // on prend le point le plus pres des bords vf ou vl
779 Standard_Boolean prevOnFirst = Standard_False;
780 Standard_Boolean prevOnLast = Standard_False;
781 Standard_Boolean currOnFirst = Standard_False;
782 Standard_Boolean currOnLast = Standard_False;
783
784 // .X ? plutot .Y , non ?
785 Standard_Real distPrevVF = Abs(pnt2d (i-1).Y() - vf);
786 Standard_Real distPrevVL = Abs(pnt2d (i-1).Y() - vl);
787 Standard_Real distCurrVF = Abs(pnt2d (i).Y() - vf);
788 Standard_Real distCurrVL = Abs(pnt2d (i).Y() - vl);
789
790 Standard_Real theMin = distPrevVF;
791 prevOnFirst = Standard_True;
792 if (distPrevVL < theMin) {
793 theMin = distPrevVL;
794 prevOnFirst = Standard_False;
795 prevOnLast = Standard_True;
796 }
797 if (distCurrVF < theMin) {
798 theMin = distCurrVF;
799 prevOnFirst = Standard_False;
800 prevOnLast = Standard_False;
801 currOnFirst = Standard_True;
802 }
803 if (distCurrVL < theMin) {
804 theMin = distCurrVL;
805 prevOnFirst = Standard_False;
806 prevOnLast = Standard_False;
807 currOnFirst = Standard_False;
808 currOnLast = Standard_True;
809 }
810 // Modifs RLN/Nijni 3-DEC-1997
811 if (prevOnFirst) {
812 // on decalle le point (i-1) en V Last
813 gp_Pnt2d newPrev(pnt2d (i-1).X(), vf); // instead of vl RLN/Nijni
814 pnt2d (i-1) = newPrev;
815 }
816 else if (prevOnLast) {
817 // on decalle le point (i-1) en V first
818 gp_Pnt2d newPrev(pnt2d (i-1).X(), vl); // instead of vf RLN/Nijni
819 pnt2d (i-1) = newPrev;
820 }
821 else if (currOnFirst) {
822 // on decalle le point (i) en V Last
823 gp_Pnt2d newCurr(pnt2d (i).X(),vf); // instead of vl RLN/Nijni
824 pnt2d (i) = newCurr;
825 }
826 else if (currOnLast) {
827 // on decalle le point (i) en V First
828 gp_Pnt2d newCurr(pnt2d (i).X(), vl); // instead of vf RLN/Nijni
829 pnt2d (i) = newCurr;
830 }
831 // on verifie
0797d9d3 832#ifdef OCCT_DEBUG
7fd59977 833 dist2d = pnt2d (i-1).Distance(pnt2d (i));
834 if (dist2d > ( Vp / 2) ) {
835 cout << "Echec dans le recadrage" << endl;
836 }
837#endif
838 }
839 }
840 }
841
842 //:c0 abv 20 Feb 98: treat very special case when 3d curve
843 // go over the pole of, e.g., sphere, and partly lies along seam.
844 // 2d representation of such a curve should consist of 3 parts - one on
845 // regular part of surface (interior), one part along degenerated boundary
846 // and one along seam.
847 // Since it cannot be adjusted later by arranging pcurves (curve is single),
848 // to fix it it is nesessary to have a possibility of adjusting seam
849 // part of such curve either to left or right boundary of surface.
850 // Test is performed only if flag AdjustOverDegen is not -1.
851 // If AdjustOverDegen is True, seam part of curve is adjusted to
852 // the left, and if False - to the right parametric boundary
853 // If treated case is detected, flag DONE4 is set to status
854 // NOTE: currently, precision is Precision::PConfusion() since it
855 // is enough on encountered example
856 // (ug_turbine-A.stp from ProSTEP Benchmark #3, entities ##2470 & 5680)
857 // (r1001_ac.stp from Test Rally #10, face #35027 and others)
858 if ( myAdjustOverDegen != -1 ) {
859 if ( mySurf->IsUClosed(myPreci) ) {//#78 rln 12.03.99 S4135
860 mySurf->IsDegenerated ( gp_Pnt(0,0,0), myPreci ); // pour calculer les dgnr
861 if ( mySurf->NbSingularities(myPreci) > 0 ) { //rln S4135
862 // 1st, find gap point (degenerated pole)
863 Standard_Real PrevX=0.;
864 Standard_Integer OnBound=0, PrevOnBound=0;
865 Standard_Integer ind; // svv #1
866 Standard_Boolean start = Standard_True;
867 for ( ind=1; ind <= nbrPnt; ind++ ) {
868 Standard_Real CurX = pnt2d(ind).X();
869 // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity
870 if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) )
871 continue;
872 OnBound = ( Abs ( Abs ( CurX - 0.5 * ( ul + uf ) ) - Up/2 ) <=
873 Precision::PConfusion() );
874 if ( ! start && Abs ( Abs ( CurX - PrevX ) - Up/2 ) <= 0.01*Up )
875 break;
876 start = Standard_False;
877 PrevX = CurX;
878 PrevOnBound = OnBound;
879 }
880 // if found, adjust seam part
881 if ( ind <= nbrPnt ) {
882 PrevX = ( myAdjustOverDegen ? uf : ul );
883 Standard_Real dU = Up/2 + Precision::PConfusion();
884 if ( PrevOnBound ) {
885 pnt2d(ind-1).SetX ( PrevX );
886 for ( Standard_Integer j=ind-2; j >0; j-- ) {
887 Standard_Real CurX = pnt2d(j).X();
888 while ( CurX < PrevX - dU ) pnt2d(j).SetX ( CurX += Up );
889 while ( CurX > PrevX + dU ) pnt2d(j).SetX ( CurX -= Up );
890 }
891 }
892 else if ( OnBound ) {
893 pnt2d(ind).SetX ( PrevX );
894 for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) {
895 Standard_Real CurX = pnt2d(j).X();
896 while ( CurX < PrevX - dU ) pnt2d(j).SetX ( CurX += Up );
897 while ( CurX > PrevX + dU ) pnt2d(j).SetX ( CurX -= Up );
898 }
899 }
900 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE4);
901 }
902 }
903 }
904 else if ( mySurf->IsVClosed(myPreci) ) {//#78 rln 12.03.99 S4135
905 mySurf->IsDegenerated ( gp_Pnt(0,0,0), myPreci ); // pour calculer les dgnr
906 if ( mySurf->NbSingularities(myPreci) > 0 ) { //rln S4135
907 // 1st, find gap point (degenerated pole)
908 Standard_Real PrevY=0.;
909 Standard_Integer OnBound=0, PrevOnBound=0;
910 Standard_Integer ind; // svv #1
911 Standard_Boolean start = Standard_True;
912 for ( ind=1; ind <= nbrPnt; ind++ ) {
913 Standard_Real CurY = pnt2d(ind).Y();
914 // abv 16 Mar 00: trj3_s1-ug.stp #697: ignore points in singularity
915 if ( mySurf->IsDegenerated ( points(ind), Precision::Confusion() ) )
916 continue;
917 OnBound = ( Abs ( Abs ( CurY - 0.5 * ( vl + vf ) ) - Vp/2 ) <=
918 Precision::PConfusion() );
919 if ( ! start && Abs ( Abs ( CurY - PrevY ) - Vp/2 ) <= 0.01*Vp )
920 break;
921 start = Standard_False;
922 PrevY = CurY;
923 PrevOnBound = OnBound;
924 }
925 // if found, adjust seam part
926 if ( ind <= nbrPnt ) {
927 PrevY = ( myAdjustOverDegen ? vf : vl );
928 Standard_Real dV = Vp/2 + Precision::PConfusion();
929 if ( PrevOnBound ) {
930 pnt2d(ind-1).SetY ( PrevY );
931 for ( Standard_Integer j=ind-2; j >0; j-- ) {
932 Standard_Real CurY = pnt2d(j).Y();
933 while ( CurY < PrevY - dV ) pnt2d(j).SetY ( CurY += Vp );
934 while ( CurY > PrevY + dV ) pnt2d(j).SetY ( CurY -= Vp );
935 }
936 }
937 else if ( OnBound ) {
938 pnt2d(ind).SetY ( PrevY );
939 for ( Standard_Integer j=ind+1; j <= nbrPnt; j++ ) {
940 Standard_Real CurY = pnt2d(j).Y();
941 while ( CurY < PrevY - dV ) pnt2d(j).SetY ( CurY += Vp );
942 while ( CurY > PrevY + dV ) pnt2d(j).SetY ( CurY -= Vp );
943 }
944 }
945 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE4);
946 }
947 }
948 }
949 }
950
951 //:q9: fill cashe
952 myNbCashe = 2;
953 if(ChangeCycle) { // msv 10.08.04: avoid using of uninitialised field
954 //if(myCashe3d[0].Distance(points(1))>Precision::Confusion() &&
955 // myCashe3d[1].Distance(points(1))>Precision::Confusion()) {
956 myCashe3d[0] = points(1);
957 myCashe3d[1] = points(nbrPnt);
958 myCashe2d[0] = pnt2d(1);
959 myCashe2d[1] = pnt2d(nbrPnt);
960 }
961 else {
962 myCashe3d[1] = points(1);
963 myCashe3d[0] = points(nbrPnt);
964 myCashe2d[1] = pnt2d(1);
965 myCashe2d[0] = pnt2d(nbrPnt);
966 }
967
968 if (isoParam && isoPar2d3d) {
969
970 // create directly isoparametrics (PCurve)
971
972 gp_Vec2d aVec2d(valueP1, valueP2);
973 gp_Dir2d aDir2d(aVec2d);
974 gp_Pnt2d P0;
975
976 if (isoTypeU) P0.SetCoord(valueP1.X(), valueP1.Y() - params(1)*aDir2d.Y());
977 else P0.SetCoord(valueP1.X() - params(1)*aDir2d.X(), valueP1.Y());
978
979 c2d = new Geom2d_Line(P0, aDir2d);
980 }
981
7fd59977 982 return isDone;
983}
984
985//=======================================================================
986//function : ApproximatePCurve
987//purpose :
988//=======================================================================
989
990Handle(Geom2d_Curve) ShapeConstruct_ProjectCurveOnSurface::ApproximatePCurve(const Standard_Integer /*nbrPnt*/,
991 Handle(TColgp_HArray1OfPnt2d)& points2d,
992 Handle(TColStd_HArray1OfReal)& params,
993 const Handle(Geom_Curve)& /*orig*/) const
994{
995// Standard_Real resol = Min(mySurf->Adaptor3d()->VResolution(myPreci), mySurf->Adaptor3d()->UResolution(myPreci));
996 Standard_Real theTolerance2d = myPreci; // (100*nbrPnt);//resol;
997 Handle(Geom2d_Curve) C2d;
998 try {
999 OCC_CATCH_SIGNALS
1000 CheckPoints2d (points2d, params, theTolerance2d);
1001 Standard_Integer numberPnt = points2d->Length();
1002
1003 TColgp_Array1OfPnt points3d(1,numberPnt);
1004 gp_Pnt2d pnt2d;
1005 gp_Pnt pnt;
1006 Standard_Integer i; // svv #1
1007 for( i = 1; i <= numberPnt; i++) {
1008 pnt2d = points2d->Value(i);
1009 pnt.SetCoord(pnt2d.X(),pnt2d.Y(),0);
1010 points3d(i) = pnt;
1011 }
1012
1013 GeomAPI_PointsToBSpline appr(points3d, params->Array1(), 1, 10, GeomAbs_C1, theTolerance2d);
1014 Handle(Geom_BSplineCurve) crv3d = appr.Curve();
1015 Standard_Integer NbPoles = crv3d->NbPoles();
1016 TColgp_Array1OfPnt poles3d (1, NbPoles);
1017 TColgp_Array1OfPnt2d poles2d (1, NbPoles);
1018 crv3d->Poles(poles3d);
1019 for( i = 1; i <= NbPoles; i++) {
1020 pnt2d.SetCoord(poles3d(i).X(),poles3d(i).Y());
1021 poles2d(i) = pnt2d;
1022 }
1023 TColStd_Array1OfReal weights (1,NbPoles);
1024 TColStd_Array1OfInteger multiplicities (1,crv3d->NbKnots());
1025 TColStd_Array1OfReal knots(1,crv3d->NbKnots());
1026 crv3d->Knots(knots);
1027 crv3d->Weights(weights);
1028 crv3d->Multiplicities(multiplicities);
1029 C2d = new Geom2d_BSplineCurve ( poles2d, weights, knots, multiplicities, crv3d->Degree(), crv3d->IsPeriodic());
1030 return C2d;
1031 }
1032 catch(Standard_Failure) {
0797d9d3 1033#ifdef OCCT_DEBUG //:s5
7fd59977 1034 // debug ...
1035 Standard_Integer nbp = params->Length();
1036 Standard_Integer nb2 = points2d->Length();
1037 cout << "Warning: ShapeConstruct_ProjectCurveOnSurface::ApproximatePCurve(): Exception: ";
1038 Standard_Failure::Caught()->Print(cout);
1039 cout<<"Pb Geom2dAPI_Approximate, tol2d="<<theTolerance2d<<" NbParams="<<nbp<<" NbPnts="<<nb2<<endl;
1040// if (nb2 > nbp) nb2 = nbp;
1041// Standard_Real rbp,rb2; rbp = nbp; rb2 = nb2;
1042// // dbl.AddString ("NbP2d/NbParams puis X Y Param -> mini");
1043// dbl.AddReals (rb2,rbp);
1044// for (Standard_Integer i = 1; i <= nb2; i ++) {
1045// gp_XYZ quoi (points2d->Value(i).X(),points2d->Value(i).Y(),params->Value(i) );
1046// dbl.AddXYZ (quoi);
1047// }
1048#endif
1049 C2d.Nullify();
1050 }
1051 return C2d;
1052}
1053
1054//=======================================================================
1055//function : InterpolatePCurve
1056//purpose :
1057//=======================================================================
1058
1059 Handle(Geom2d_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolatePCurve(const Standard_Integer nbrPnt,
1060 Handle(TColgp_HArray1OfPnt2d)& points2d,
1061 Handle(TColStd_HArray1OfReal)& params,
1062 const Handle(Geom_Curve)& /*orig*/) const
1063{
1064 Handle(Geom2d_Curve) C2d; // NULL si echec
1065 Standard_Real theTolerance2d = myPreci / (100 * nbrPnt);
1066 try {
1067 OCC_CATCH_SIGNALS
1068 // on verifie d abord s il n y a pas de points confondus
1069 // si besoin on retouche les valeurs ...
1070 CheckPoints2d (points2d, params, theTolerance2d);
1071 Geom2dAPI_Interpolate myInterPol2d (points2d, params,
1072 Standard_False, theTolerance2d);
1073 myInterPol2d.Perform();
1074 if (myInterPol2d.IsDone()) C2d = myInterPol2d.Curve();
1075 }
1076 catch(Standard_Failure) {
0797d9d3 1077#ifdef OCCT_DEBUG //:s5
7fd59977 1078// // debug ...
1079 Standard_Integer nbp = params->Length();
1080 Standard_Integer nb2 = points2d->Length();
1081 cout << "Warning: ShapeConstruct_ProjectCurveOnSurface::InterpolatePCurve(): Exception: ";
1082 Standard_Failure::Caught()->Print(cout);
1083 cout<<"Pb Geom2dAPI_Interpolate, tol2d="<<theTolerance2d<<" NbParams="<<nbp<<" NbPnts="<<nb2<<endl;
1084// if (nb2 > nbp) nb2 = nbp;
1085// Standard_Real rbp,rb2; rbp = nbp; rb2 = nb2;
1086// // dbl.AddString ("NbP2d/NbParams puis X Y Param -> mini");
1087// dbl.AddReals (rb2,rbp);
1088// for (Standard_Integer i = 1; i <= nb2; i ++) {
1089// gp_XYZ quoi (points2d->Value(i).X(),points2d->Value(i).Y(),params->Value(i) );
1090// dbl.AddXYZ (quoi);
1091// }
1092#endif
1093 C2d.Nullify();
1094 }
1095 return C2d;
1096}
1097
1098//=======================================================================
1099//function : InterpolateCurve3d
1100//purpose :
1101//=======================================================================
1102
1103Handle(Geom_Curve) ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(const Standard_Integer,
1104 Handle(TColgp_HArray1OfPnt)& points,
1105 Handle(TColStd_HArray1OfReal)& params,
1106 const Handle(Geom_Curve)& /*orig*/) const
1107{
1108 Handle(Geom_Curve) C3d; // NULL si echec
1109 try {
1110 OCC_CATCH_SIGNALS
1111 Standard_Real Tol = myPreci;
1112 CheckPoints(points, params, Tol);
1113 GeomAPI_Interpolate myInterPol(points, params, Standard_False, Tol);
1114 myInterPol.Perform();
1115 if (myInterPol.IsDone()) C3d = myInterPol.Curve();
1116 }
1117 catch(Standard_Failure) {
1118 C3d.Nullify();
0797d9d3 1119#ifdef OCCT_DEBUG //:s5
7fd59977 1120 cout << "Warning: ShapeConstruct_ProjectCurveOnSurface::InterpolateCurve3d(): Exception: ";
1121 Standard_Failure::Caught()->Print(cout); cout << endl;
1122#endif
1123 }
1124 return C3d;
1125}
1126
1127//=======================================================================
1128//function : CheckPoints
1129//purpose :
1130//=======================================================================
1131
1132 void ShapeConstruct_ProjectCurveOnSurface::CheckPoints(Handle(TColgp_HArray1OfPnt)& points,Handle(TColStd_HArray1OfReal)& params,Standard_Real& preci) const
1133{
1134 Standard_Integer firstElem = points->Lower();
1135 Standard_Integer lastElem = points->Upper();
1136 Standard_Integer i;
1137 Standard_Integer nbPntDropped = 0;
1138 Standard_Integer lastValid = firstElem; // indice of last undropped point
1139
1140 // will store 0 when the point is to be removed, 1 otherwise
1141 TColStd_Array1OfInteger tmpParam(firstElem, lastElem);
1142 for (i = firstElem; i<=lastElem ; i++) tmpParam.SetValue(i,1);
7ae65f0d 1143 Standard_Real DistMin2 = RealLast();
7fd59977 1144 gp_Pnt Prev = points->Value (lastValid);
1145 gp_Pnt Curr;
1146 for (i = firstElem + 1; i <= lastElem ; i ++) {
1147 Curr = points->Value(i);
7ae65f0d 1148 Standard_Real CurDist2 = Prev.SquareDistance(Curr);
1149 if (CurDist2 < gp::Resolution()) { // test 0
7fd59977 1150 nbPntDropped ++;
1151 if ( i == lastElem ) tmpParam.SetValue(lastValid, 0); // last point kept
1152 else tmpParam.SetValue(i, 0); // current dropped, lastValid unchanged
1153 } else {
7ae65f0d 1154 if (CurDist2 < DistMin2)
1155 DistMin2 = CurDist2;
7fd59977 1156 // lastValid becomes the current (i.e. i)
1157 lastValid = i;
1158 Prev = Curr;
1159 }
1160 }
7ae65f0d 1161 if (DistMin2 < RealLast())
1162 preci = 0.9 * Sqrt (DistMin2); // preci est la distance min entre les points on la reduit un peu
1163 if (nbPntDropped == 0)
7fd59977 1164 return;
7ae65f0d 1165
0797d9d3 1166#ifdef OCCT_DEBUG
7fd59977 1167 cout << "Warning : removing 3d points for interpolation" << endl;
1168#endif
1169 // Build new HArrays
1170 Standard_Integer newLast = lastElem - nbPntDropped;
1171 if ((newLast - firstElem + 1) < 2) {
0797d9d3 1172#ifdef OCCT_DEBUG
7fd59977 1173 cout << "Too many degenerated points for 3D interpolation" << endl;
1174#endif
1175 return;
1176 }
1177 Handle(TColgp_HArray1OfPnt) newPnts =
1178 new TColgp_HArray1OfPnt(firstElem, newLast);
1179 Handle(TColStd_HArray1OfReal) newParams =
1180 new TColStd_HArray1OfReal(firstElem, newLast);
1181 Standard_Integer newCurr = 1;
1182 for (i = firstElem; i<= lastElem ; i++) {
1183 if (tmpParam.Value(i) == 1) {
1184 newPnts->SetValue(newCurr, points->Value(i));
1185 newParams->SetValue(newCurr, params->Value(i));
1186 newCurr ++;
1187 }
1188 }
1189 points = newPnts;
1190 params = newParams;
7fd59977 1191 // on la reduit un peu
1192}
1193
1194//=======================================================================
1195//function : CheckPoints2d
1196//purpose :
1197//=======================================================================
1198
1199 void ShapeConstruct_ProjectCurveOnSurface::CheckPoints2d(Handle(TColgp_HArray1OfPnt2d)& points,
1200 Handle(TColStd_HArray1OfReal)& params,
1201 Standard_Real& preci) const
1202{
1203 Standard_Integer firstElem = points->Lower();
1204 Standard_Integer lastElem = points->Upper();
1205 Standard_Integer i;
1206 Standard_Integer nbPntDropped = 0;
1207 Standard_Integer lastValid = firstElem; // indice of last undropped point
1208
1209 // will store 0 when the point is to be removed, 1 otherwise
1210 TColStd_Array1OfInteger tmpParam(firstElem, lastElem);
1211 for (i = firstElem; i<=lastElem ; i++) {
1212 tmpParam.SetValue(i,1);
1213 }
7ae65f0d 1214 Standard_Real DistMin2 = RealLast();
7fd59977 1215 gp_Pnt2d Prev = points->Value(lastValid);
1216 gp_Pnt2d Curr;
1217 for (i = firstElem + 1; i<=lastElem ; i++) {
1218 Curr = points->Value(i);
7ae65f0d 1219 Standard_Real CurDist2 = Prev.SquareDistance(Curr);
1220 if (CurDist2 < gp::Resolution()) { // test 0
7fd59977 1221 nbPntDropped ++;
1222 if ( i == lastElem ) tmpParam.SetValue(lastValid, 0); // last point kept
1223 else tmpParam.SetValue(i, 0); // current dropped, lastValid unchanged
1224 } else {
7ae65f0d 1225 if (CurDist2 < DistMin2)
1226 DistMin2 = CurDist2;
7fd59977 1227 // lastValid becomes the current (i.e. i)
1228 lastValid = i;
1229 Prev = Curr;
1230 }
1231 }
7ae65f0d 1232 if (DistMin2 < RealLast())
1233 preci = 0.9 * Sqrt (DistMin2);
1234 if (nbPntDropped == 0)
7fd59977 1235 return;
7ae65f0d 1236
0797d9d3 1237#ifdef OCCT_DEBUG
7fd59977 1238 cout << "Warning : removing 2d points for interpolation" << endl;
1239#endif
1240 // Build new HArrays
1241 Standard_Integer newLast = lastElem - nbPntDropped;
1242 if ((newLast - firstElem + 1) < 2) {
0797d9d3 1243#ifdef OCCT_DEBUG
7fd59977 1244 cout << "Too many degenerated points for 2D interpolation" << endl;
1245#endif
1246 //pdn 12.02.99 S4135 Creating pcurve with minimal length.
1247 tmpParam.SetValue(firstElem,1);
1248 tmpParam.SetValue(lastElem,1);
1249 gp_XY lastPnt = points->Value(lastElem).XY();
1250 lastPnt.Add(gp_XY(preci,preci));
1251 points->SetValue(lastElem,lastPnt);
1252 newLast = firstElem+1;
1253 //return;
1254 }
1255 Handle(TColgp_HArray1OfPnt2d) newPnts =
1256 new TColgp_HArray1OfPnt2d(firstElem, newLast);
1257 Handle(TColStd_HArray1OfReal) newParams =
1258 new TColStd_HArray1OfReal(firstElem, newLast);
1259 Standard_Integer newCurr = 1;
1260 for (i = firstElem; i <= lastElem ; i++) {
1261 if (tmpParam.Value(i) == 1) {
0797d9d3 1262#ifdef OCCT_DEBUG
7fd59977 1263 cout << "Point " << i << " : " << points->Value(i).X() << " " << points->Value(i).Y() << " at param " << params->Value(i) << endl;
1264#endif
1265 newPnts->SetValue(newCurr, points->Value(i));
1266 newParams->SetValue(newCurr, params->Value(i));
1267 newCurr ++;
1268 }
1269 else {
0797d9d3 1270#ifdef OCCT_DEBUG
7fd59977 1271 cout << "Removed " << i << " : " << points->Value(i).X() << " " << points->Value(i).Y() << " at param " << params->Value(i) << endl;
1272#endif
1273 }
1274 }
1275 points = newPnts;
1276 params = newParams;
7fd59977 1277}
1278
1279//=======================================================================
1280//function : IsAnIsoparametric
1281//purpose :
1282//=======================================================================
1283//:S4030: modified for optimization
1284//:p9 abv 11 Mar 99: PRO7226 #489490: find nearest boundary instead of first one
1285
1286 Standard_Boolean ShapeConstruct_ProjectCurveOnSurface::IsAnIsoparametric(const Standard_Integer nbrPnt,
1287 const TColgp_Array1OfPnt& points,
1288 const TColStd_Array1OfReal& params,
1289 Standard_Boolean& isoTypeU,
1290 Standard_Boolean& p1OnIso,
1291 gp_Pnt2d& valueP1,
1292 Standard_Boolean& p2OnIso,
1293 gp_Pnt2d& valueP2,
1294 Standard_Boolean& isoPar2d3d,
1295 Handle(Geom_Curve)& cIso,
1296 Standard_Real& t1,
1297 Standard_Real& t2,
1298 TColStd_Array1OfReal& pout) const
1299{
1300 try { // RAJOUT
1301 OCC_CATCH_SIGNALS
1302
1303 Standard_Real prec = Precision::Confusion();//myPreci;
1304
1305 Standard_Boolean isoParam = Standard_False;
1306 isoPar2d3d = Standard_False;
1307
1308 Standard_Real U1, U2, V1, V2;
1309 mySurf->Bounds(U1, U2, V1, V2);
1310
1311 if ( mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1312 Handle(Geom_RectangularTrimmedSurface) sTrim =
1313 Handle(Geom_RectangularTrimmedSurface)::DownCast(mySurf->Surface());
1314 sTrim->Bounds(U1, U2, V1, V2);
1315 }
1316
1317 gp_Pnt pt;
1318 Standard_Integer mpt[2]; mpt[0] = mpt[1] = 0;
d20d815b 1319 Standard_Real t, tpar[2] = { 0.0, 0.0 }, isoValue=0.;
7fd59977 1320 Standard_Real mindist2;
1321 Standard_Real mind2[2];
1322 mindist2 = mind2[0] = mind2[1] = 4*prec*prec;
1323
1324 p1OnIso = Standard_False;
1325 p2OnIso = Standard_False;
1326 const Bnd_Box* aBox = 0;
1327
1328 for (Standard_Integer j=1; (j<=4) /*&& !isoParam*/; j++) {
1329 Standard_Real isoVal=0.;
1330 Standard_Boolean isoU=Standard_False; //szv#4:S4163:12Mar99 `isoU` must be Standard_Boolean
1331 Handle(Geom_Curve) cI;
1332 Standard_Real tt1, tt2;
1333
1334 if (j == 1 ) {
1335 if (Precision::IsInfinite(U1)) continue;
1336 cI = mySurf->UIso(U1);
1337 isoU = Standard_True;
1338 isoVal = U1;
1339 aBox = & mySurf->GetBoxUF();
1340 }
1341 else if (j == 2) {
1342 if (Precision::IsInfinite(U2)) continue;
1343 cI = mySurf->UIso(U2);
1344 isoU = Standard_True;
1345 isoVal = U2;
1346 aBox = & mySurf->GetBoxUL();
1347 }
1348 else if (j == 3) {
1349 if (Precision::IsInfinite(V1)) continue;
1350 cI = mySurf->VIso(V1);
1351 isoU = Standard_False;
1352 isoVal = V1;
1353 aBox = & mySurf->GetBoxVF();
1354 }
1355 else if (j == 4) {
1356 if (Precision::IsInfinite(V2)) continue;
1357 cI = mySurf->VIso(V2);
1358 isoU = Standard_False;
1359 isoVal = V2;
1360 aBox = & mySurf->GetBoxVL();
1361 }
1362 if(cI.IsNull())
1363 continue;
1364
1365 if (isoU) { tt1 = V1; tt2 = V2; }
1366 else { tt1 = U1; tt2 = U2; }
1367
1368 gp_Pnt ext1, ext2;
1369 cI->D0(tt1, ext1);
1370 cI->D0(tt2, ext2);
1371
1372// PATCH CKY 9-JUL-1998 : protection contre singularite
1373 gp_Pnt extmi;
1374 cI->D0( (tt1+tt2)/2,extmi);
1375 if (ext1.IsEqual(ext2,prec) && ext1.IsEqual(extmi,prec)) continue;
1376
1377 Standard_Boolean PtEQext1 = Standard_False;
1378 Standard_Boolean PtEQext2 = Standard_False;
1379
eb1ebea4 1380 Standard_Real currd2[2], tp[2] = {0, 0};
7fd59977 1381 Standard_Integer mp[2];
1382
1383 for (Standard_Integer i=0; i<2; i++) {
1384 mp[i] = 0;
1385 Standard_Integer k = (i == 0 ? 1 : nbrPnt);
1386
1387 // si ext1 == ext2 => valueP1 == valueP2 => vect null plus tard
1388 currd2[i] = points(k).SquareDistance ( ext1 );
1389 if ( currd2[i] <= prec*prec && !PtEQext1) {
1390 mp[i] = 1;
1391 tp[i] = tt1;
1392 PtEQext1 = Standard_True;
1393 continue;
1394 }
1395
1396 currd2[i] = points(k).SquareDistance ( ext2 );
1397 if ( currd2[i] <= prec*prec && !PtEQext2) {
1398 mp[i] = 2;
1399 tp[i] = tt2;
1400 PtEQext2 = Standard_True;
1401 continue;
1402 }
1403
1404 // On evite de projecter sur un iso degenere
1405 // on doit egalement le faire pour l apex du cone
1406 if (mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) && !isoU) {
1407 continue;
1408 }
1409
1410 if(aBox->IsOut(points(k))) continue;
1411
1412 Standard_Real Cf = cI->FirstParameter();
1413 Standard_Real Cl = cI->LastParameter();
1414 if (Precision::IsInfinite(Cf)) Cf = -1000;
1415 if (Precision::IsInfinite(Cl)) Cl = +1000;
1416
1417 ShapeAnalysis_Curve sac;
1418 Standard_Real dist = sac.Project (cI,points(k),prec,pt,t,Cf,Cl);
1419 currd2[i] = dist * dist;
1420 if ((dist <= prec) && (t>= Cf) && (t<=Cl)) {
1421 mp[i] = 3;
1422 tp[i] = t;
1423 }
1424 }
1425
1426 //:e7 abv 21 Apr 98: ProSTEP TR8, r0501_pe #56679:
1427 // avoid possible null-length curves
1428 if ( mp[0] >0 && mp[1] >0 &&
1429 Abs ( tp[0] - tp[1] ) < Precision::PConfusion() ) continue;
1430
1431
1432 if (mp[0] > 0 &&
1433 ( ! p1OnIso || currd2[0] < mind2[0] ) ) {
1434 p1OnIso = Standard_True;
1435 mind2[0] = currd2[0];
1436 if (isoU) valueP1.SetCoord(isoVal, tp[0]);
1437 else valueP1.SetCoord(tp[0], isoVal);
1438 }
1439
1440 if (mp[1] > 0 &&
1441 ( ! p2OnIso || currd2[1] < mind2[1] ) ) {
1442 p2OnIso = Standard_True;
1443 mind2[1] = currd2[1];
1444 if (isoU) valueP2.SetCoord(isoVal, tp[1]);
1445 else valueP2.SetCoord(tp[1], isoVal);
1446 }
1447
1448 if ( mp[0] <=0 || mp[1] <=0 ) continue;
1449
1450 Standard_Real md2 = currd2[0] + currd2[1];
1451 if ( mindist2 <= md2 ) continue;
1452
1453 mindist2 = md2;
1454 mpt[0] = mp[0];
1455 mpt[1] = mp[1];
1456 tpar[0] = tp[0];
1457 tpar[1] = tp[1];
1458 isoTypeU = isoU;
1459 isoValue = isoVal;
1460 cIso = cI;
1461 t1 = tt1;
1462 t2 = tt2;
1463 }
1464
1465 // probablely it concerns an isoparametrics
1466 if ( mpt[0] >0 && mpt[1] >0 ) {
1467
1468 p1OnIso = p2OnIso = Standard_True;
1469 if (isoTypeU) {
1470 valueP1.SetCoord(isoValue, tpar[0]);
1471 valueP2.SetCoord(isoValue, tpar[1]);
1472 }
1473 else {
1474 valueP1.SetCoord(tpar[0], isoValue);
1475 valueP2.SetCoord(tpar[1], isoValue);
1476 }
1477
1478 if ( mpt[0] != 3 && mpt[1] != 3 ) {
1479 isoPar2d3d = Standard_True;
1480 for (Standard_Integer i=2; i < nbrPnt && isoPar2d3d; i++){
1481 if (tpar[1] > tpar[0]) t = params(i);
1482 else t = t1+t2-params(i);
1483 cIso->D0(t, pt);
1484 if (!points(i).IsEqual(pt, prec)) isoPar2d3d = Standard_False;
1485 }
1486 }
1487
1488 if (isoPar2d3d) isoParam = Standard_True;
1489 else {
1490 Standard_Real prevParam = tpar[0];
1491 Standard_Real Cf, Cl;
1492 Standard_Boolean isoByDistance = Standard_True;
1493 Cf = cIso->FirstParameter();
1494 Cl = cIso->LastParameter();
1495 if (Precision::IsInfinite(Cf)) Cf = -1000;
1496 if (Precision::IsInfinite(Cl)) Cl = +1000;
1497
1498 ShapeAnalysis_Curve sac;
1499 for (Standard_Integer i=2; i < nbrPnt && isoByDistance; i++) {
1500 Standard_Real dist = sac.NextProject (prevParam,cIso,points(i),
1501 prec,pt,t,Cf,Cl,
1502 Standard_False); //:j8 abv 10.12.98: TR10 r0501_db.stp #9423: avoid adjusting to ends
1503 prevParam = t;
1504 pout(i)=t;
1505 if( (dist > prec) || (t < Cf) || (t > Cl) )
1506 isoByDistance = Standard_False;
1507 }
1508 if (isoByDistance) isoParam = Standard_True;
1509 }
1510 }
1511/* if (!isoParam) { CKY 29-mai-1997 : garder tout ce qu on peut ?
1512 p1OnIso = Standard_False;
1513 p2OnIso = Standard_False;
1514 } */
1515 return isoParam;
1516 } // RAJOUT
1517 catch(Standard_Failure) {
1518// pb : on affiche ce qu on peut
0797d9d3 1519#ifdef OCCT_DEBUG
7fd59977 1520 for (Standard_Integer numpnt = 1; numpnt <= nbrPnt; numpnt ++) {
1521 cout<<"["<<numpnt<<"]param="<<params(numpnt)<<" point=("<<
1522 points(numpnt).X()<<" "<<points(numpnt).Y()<<" "<<points(numpnt).Z()<<")"<<endl;
1523 }
1524#endif
0797d9d3 1525#ifdef OCCT_DEBUG //:s5
7fd59977 1526 cout << "Warning: ShapeConstruct_ProjectCurveOnSurface::IsAnIsoparametric(): Exception: ";
1527 Standard_Failure::Caught()->Print(cout); cout << endl;
1528#endif
1529 return Standard_False;
1530 }
7fd59977 1531}
1532
1533/* S4135 : BestExtremum is commented after IsAnIsoparametric works with Precision::Confusion()
1534//=======================================================================
1535//function : BestExtremum
1536//purpose : auxiliaire prenant le meilleur extremum si ISO car doute possible
1537//=======================================================================
1538
1539 gp_Pnt2d ShapeConstruct_ProjectCurveOnSurface::BestExtremum(const gp_Pnt2d& P2iso,const gp_Pnt& P3ext,const gp_Pnt& P3next) const
1540{
1541// P2iso a ete calcule depuis P3ext sur une iso externe de la surface
1542// En principe bon mais circularite possible ... et IsU/VClosed faillible
1543// (si baillement 1e-4 ou 1e-5, on est dedans !). DONC
1544// 1/ on privilegie l iso mais a tout hasard on verifie si Surf meilleur
1545// 2/ si iso, attention a la circularite (cas limite)
1546
1547// NB : si isoParam, on suppose que P2iso est bon (car il y en a 2). A voir...
1548
1549// D abord, calcul p2ext depuis la surface. choix surface/iso
1550 return P2iso;
1551 Standard_Real prec = Precision::Confusion();//myPreci;
1552 gp_Pnt2d P2cal = mySurf->ValueOfUV(P3ext, prec);
1553 gp_Pnt P3cal = mySurf->Value (P2cal);
1554 Standard_Real dcal = P3ext.Distance (P3cal);
1555 Standard_Real dnxt = P3ext.Distance (P3next);
1556 if (dcal > dnxt) return P2iso; // en fait protection sur BUG (PRO8468)
1557
1558// On choisit entre P2iso et P2cal, le plus proche de P2next ... !!!
1559 gp_Pnt2d P2next = mySurf->ValueOfUV(P3next, prec);
1560 if (P2next.Distance(P2cal) < P2next.Distance(P2iso)) return P2cal;
1561 return P2iso;
1562}
1563*/