0028694: IGES reader produces too small edge covered by its vertices
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_Surface.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// 06.01.99 pdn private method SurfaceNewton PRO17015: fix against hang in Extrema
15// 11.01.99 pdn PRO10109 4517: protect against wrong result
16//%12 pdn 11.02.99 PRO9234 project degenerated
17// 03.03.99 rln S4135: new algorithms for IsClosed (accepts precision), Degenerated (stores precision)
18//:p7 abv 10.03.99 PRO18206: adding new method IsDegenerated()
19//:p8 abv 11.03.99 PRO7226 #489490: improving ProjectDegenerated() for degenerated edges
20//:q1 pdn, abv 15.03.99 PRO7226 #525030: adding maxpreci in NextValueOfUV()
21//:q2 abv 16.03.99: PRO7226 #412920: applying Newton algorithm before UVFromIso()
22//:q6 abv 19.03.99: ie_soapbox-B.stp #390760: improving projecting point on surface
23//#77 rln 15.03.99: S4135: returning singularity which has minimum gap between singular point and input 3D point
24//:r3 abv 30.03.99: (by smh) S4163: protect against unexpected signals
25//:#4 smh 07.04.99: S4163 Zero divide.
26//#4 szv S4163: optimizations
27//:r9 abv 09.04.99: id_turbine-C.stp #3865: check degenerated 2d point by recomputing to 3d instead of Resolution
28//:s5 abv 22.04.99 Adding debug printouts in catch {} blocks
7fd59977 29
42cf5bc1 30#include <Adaptor3d_Curve.hxx>
31#include <Adaptor3d_IsoCurve.hxx>
32#include <Bnd_Box.hxx>
33#include <BndLib_Add3dCurve.hxx>
34#include <ElSLib.hxx>
35#include <Geom_BezierSurface.hxx>
7fd59977 36#include <Geom_BoundedSurface.hxx>
37#include <Geom_BSplineSurface.hxx>
7fd59977 38#include <Geom_ConicalSurface.hxx>
42cf5bc1 39#include <Geom_Curve.hxx>
40#include <Geom_OffsetSurface.hxx>
7fd59977 41#include <Geom_RectangularTrimmedSurface.hxx>
42#include <Geom_SphericalSurface.hxx>
42cf5bc1 43#include <Geom_Surface.hxx>
7fd59977 44#include <Geom_SurfaceOfLinearExtrusion.hxx>
45#include <Geom_SurfaceOfRevolution.hxx>
46#include <Geom_ToroidalSurface.hxx>
42cf5bc1 47#include <GeomAbs_SurfaceForm.hxx>
48#include <GeomAdaptor_Curve.hxx>
49#include <GeomAdaptor_HSurface.hxx>
50#include <gp_Pnt.hxx>
51#include <gp_Pnt2d.hxx>
7fd59977 52#include <Precision.hxx>
42cf5bc1 53#include <ShapeAnalysis.hxx>
7fd59977 54#include <ShapeAnalysis_Curve.hxx>
42cf5bc1 55#include <ShapeAnalysis_Surface.hxx>
7fd59977 56#include <Standard_ErrorHandler.hxx>
57#include <Standard_Failure.hxx>
58#include <Standard_NoSuchObject.hxx>
42cf5bc1 59#include <Standard_Type.hxx>
7fd59977 60
25e59720 61IMPLEMENT_STANDARD_RTTIEXT(ShapeAnalysis_Surface,Standard_Transient)
92efcf78 62
42cf5bc1 63//S4135
64//S4135
7fd59977 65//=======================================================================
66//function : ShapeAnalysis_Surface
67//purpose :
68//=======================================================================
7fd59977 69ShapeAnalysis_Surface::ShapeAnalysis_Surface(const Handle(Geom_Surface)& S) :
65bb82f2 70 mySurf(S),
71 myExtOK(Standard_False), //:30
72 myNbDeg(-1),
73 myIsos(Standard_False),
74 myIsoBoxes(Standard_False),
75 myGap(0.), myUDelt(0.01), myVDelt(0.01), myUCloseVal(-1), myVCloseVal(-1)
7fd59977 76{
65bb82f2 77 mySurf->Bounds(myUF, myUL, myVF, myVL);
78 myAdSur = new GeomAdaptor_HSurface(mySurf);
7fd59977 79}
80
81//=======================================================================
82//function : Init
83//purpose :
84//=======================================================================
85
86void ShapeAnalysis_Surface::Init(const Handle(Geom_Surface)& S)
87{
88 if (mySurf == S) return;
89 myExtOK = Standard_False; //:30
84eca96b 90 mySurf = S;
7fd59977 91 myNbDeg = -1;
92 myUCloseVal = myVCloseVal = -1; myGap = 0.;
65bb82f2 93 mySurf->Bounds(myUF, myUL, myVF, myVL);
94 myAdSur = new GeomAdaptor_HSurface(mySurf);
7fd59977 95 myIsos = Standard_False;
96 myIsoBoxes = Standard_False;
97 myIsoUF.Nullify(); myIsoUL.Nullify(); myIsoVF.Nullify(); myIsoVL.Nullify();
98}
99
100//=======================================================================
101//function : Init
102//purpose :
103//=======================================================================
104
105void ShapeAnalysis_Surface::Init(const Handle(ShapeAnalysis_Surface)& other)
106{
65bb82f2 107 Init(other->Surface());
7fd59977 108 myAdSur = other->TrueAdaptor3d();
109 myNbDeg = other->myNbDeg; //rln S4135 direct transmission (to avoid computation in <other>)
65bb82f2 110 for (Standard_Integer i = 0; i < myNbDeg; i++) {
111 other->Singularity(i + 1, myPreci[i], myP3d[i], myFirstP2d[i], myLastP2d[i], myFirstPar[i], myLastPar[i], myUIsoDeg[i]);
7fd59977 112 }
113}
114
115//=======================================================================
116//function : Adaptor3d
117//purpose :
118//=======================================================================
119
120const Handle(GeomAdaptor_HSurface)& ShapeAnalysis_Surface::Adaptor3d()
121{
7fd59977 122 return myAdSur;
123}
124
125//=======================================================================
126//function : ComputeSingularities
127//purpose :
128//=======================================================================
129
130void ShapeAnalysis_Surface::ComputeSingularities()
131{
132 //rln S4135
133 if (myNbDeg >= 0) return;
65bb82f2 134 //:51 abv 22 Dec 97: allow forcing: if (myNbDeg >= 0) return;
135 //CKY 27-FEV-98 : en appel direct on peut forcer. En appel interne on optimise
7fd59977 136 if (mySurf.IsNull()) return;
65bb82f2 137
7fd59977 138 Standard_Real su1, sv1, su2, sv2;
65bb82f2 139 // mySurf->Bounds(su1, su2, sv1, sv2);
7fd59977 140 Bounds(su1, su2, sv1, sv2);//modified by rln on 12/11/97 mySurf-> is deleted
141
142 myNbDeg = 0; //:r3
65bb82f2 143
7fd59977 144 if (mySurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
145 Handle(Geom_ConicalSurface) conicS =
146 Handle(Geom_ConicalSurface)::DownCast(mySurf);
65bb82f2 147 Standard_Real vApex = -conicS->RefRadius() / Sin(conicS->SemiAngle());
148 myPreci[0] = 0;
149 myP3d[0] = conicS->Apex();
150 myFirstP2d[0].SetCoord(su1, vApex);
151 myLastP2d[0].SetCoord(su2, vApex);
7fd59977 152 myFirstPar[0] = su1;
65bb82f2 153 myLastPar[0] = su2;
154 myUIsoDeg[0] = Standard_False;
7fd59977 155 myNbDeg = 1;
156 }
157 else if (mySurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
158 Handle(Geom_ToroidalSurface) toroidS =
159 Handle(Geom_ToroidalSurface)::DownCast(mySurf);
160 Standard_Real minorR = toroidS->MinorRadius();
161 Standard_Real majorR = toroidS->MajorRadius();
162 //szv#4:S4163:12Mar99 warning - possible div by zero
65bb82f2 163 Standard_Real Ang = ACos(Min(1., majorR / minorR));
164 myPreci[0] = myPreci[1] = Max(0., majorR - minorR);
165 myP3d[0] = mySurf->Value(0., M_PI - Ang);
166 myFirstP2d[0].SetCoord(su1, M_PI - Ang);
167 myLastP2d[0].SetCoord(su2, M_PI - Ang);
168 myP3d[1] = mySurf->Value(0., M_PI + Ang);
169 myFirstP2d[1].SetCoord(su2, M_PI + Ang);
170 myLastP2d[1].SetCoord(su1, M_PI + Ang);
7fd59977 171 myFirstPar[0] = myFirstPar[1] = su1;
65bb82f2 172 myLastPar[0] = myLastPar[1] = su2;
173 myUIsoDeg[0] = myUIsoDeg[1] = Standard_False;
174 myNbDeg = (majorR > minorR ? 1 : 2);
7fd59977 175 }
176 else if (mySurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
65bb82f2 177 myPreci[0] = myPreci[1] = 0;
178 myP3d[0] = mySurf->Value(su1, sv2); // Northern pole is first
179 myP3d[1] = mySurf->Value(su1, sv1);
180 myFirstP2d[0].SetCoord(su2, sv2);
181 myLastP2d[0].SetCoord(su1, sv2);
182 myFirstP2d[1].SetCoord(su1, sv1);
183 myLastP2d[1].SetCoord(su2, sv1);
7fd59977 184 myFirstPar[0] = myFirstPar[1] = su1;
65bb82f2 185 myLastPar[0] = myLastPar[1] = su2;
186 myUIsoDeg[0] = myUIsoDeg[1] = Standard_False;
7fd59977 187 myNbDeg = 2;
188 }
65bb82f2 189 else if ((mySurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface))) ||
190 (mySurf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) || //:b2 abv 18 Feb 98
191 (mySurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface)))) { //rln S4135
192
193 //rln S4135 //:r3
194 myP3d[0] = myAdSur->Value(su1, 0.5 * (sv1 + sv2));
195 myFirstP2d[0].SetCoord(su1, sv2);
196 myLastP2d[0].SetCoord(su1, sv1);
197
198 myP3d[1] = myAdSur->Value(su2, 0.5 * (sv1 + sv2));
199 myFirstP2d[1].SetCoord(su2, sv1);
200 myLastP2d[1].SetCoord(su2, sv2);
201
202 myP3d[2] = myAdSur->Value(0.5 * (su1 + su2), sv1);
203 myFirstP2d[2].SetCoord(su1, sv1);
204 myLastP2d[2].SetCoord(su2, sv1);
205
206 myP3d[3] = myAdSur->Value(0.5 * (su1 + su2), sv2);
207 myFirstP2d[3].SetCoord(su2, sv2);
208 myLastP2d[3].SetCoord(su1, sv2);
209
210 myFirstPar[0] = myFirstPar[1] = sv1;
211 myLastPar[0] = myLastPar[1] = sv2;
212 myUIsoDeg[0] = myUIsoDeg[1] = Standard_True;
213
214 myFirstPar[2] = myFirstPar[3] = su1;
215 myLastPar[2] = myLastPar[3] = su2;
216 myUIsoDeg[2] = myUIsoDeg[3] = Standard_False;
217
218 gp_Pnt Corner1 = myAdSur->Value(su1, sv1);
219 gp_Pnt Corner2 = myAdSur->Value(su1, sv2);
220 gp_Pnt Corner3 = myAdSur->Value(su2, sv1);
221 gp_Pnt Corner4 = myAdSur->Value(su2, sv2);
222
223 myPreci[0] = Max(Corner1.Distance(Corner2), Max(myP3d[0].Distance(Corner1), myP3d[0].Distance(Corner2)));
224 myPreci[1] = Max(Corner3.Distance(Corner4), Max(myP3d[1].Distance(Corner3), myP3d[1].Distance(Corner4)));
225 myPreci[2] = Max(Corner1.Distance(Corner3), Max(myP3d[2].Distance(Corner1), myP3d[2].Distance(Corner3)));
226 myPreci[3] = Max(Corner2.Distance(Corner4), Max(myP3d[3].Distance(Corner2), myP3d[3].Distance(Corner4)));
7fd59977 227
228 myNbDeg = 4;
229 }
230 SortSingularities();
231}
232
233//=======================================================================
234//function : HasSingularities
235//purpose :
236//=======================================================================
237
65bb82f2 238Standard_Boolean ShapeAnalysis_Surface::HasSingularities(const Standard_Real preci)
7fd59977 239{
240 return NbSingularities(preci) > 0;
241}
242
243//=======================================================================
244//function : NbSingularities
245//purpose :
246//=======================================================================
247
248Standard_Integer ShapeAnalysis_Surface::NbSingularities(const Standard_Real preci)
249{
250 if (myNbDeg < 0) ComputeSingularities();
251 Standard_Integer Nb = 0;
252 for (Standard_Integer i = 1; i <= myNbDeg; i++)
65bb82f2 253 if (myPreci[i - 1] <= preci)
7fd59977 254 Nb++;
255 return Nb;
256}
257
258//=======================================================================
259//function : Singularity
260//purpose :
261//=======================================================================
262
65bb82f2 263Standard_Boolean ShapeAnalysis_Surface::Singularity(const Standard_Integer num,
264 Standard_Real& preci,
265 gp_Pnt& P3d,
266 gp_Pnt2d& firstP2d,
267 gp_Pnt2d& lastP2d,
268 Standard_Real& firstpar,
269 Standard_Real& lastpar,
270 Standard_Boolean& uisodeg)
7fd59977 271{
65bb82f2 272 // ATTENTION, les champs sont des tableaux C, n0s partent de 0. num part de 1
7fd59977 273 if (myNbDeg < 0) ComputeSingularities();
274 if (num < 1 || num > myNbDeg) return Standard_False;
65bb82f2 275 P3d = myP3d[num - 1];
276 preci = myPreci[num - 1];
277 firstP2d = myFirstP2d[num - 1];
278 lastP2d = myLastP2d[num - 1];
279 firstpar = myFirstPar[num - 1];
280 lastpar = myLastPar[num - 1];
281 uisodeg = myUIsoDeg[num - 1];
7fd59977 282 return Standard_True;
283}
284
285//=======================================================================
286//function : IsDegenerated
287//purpose :
288//=======================================================================
289
65bb82f2 290Standard_Boolean ShapeAnalysis_Surface::IsDegenerated(const gp_Pnt& P3d, const Standard_Real preci)
7fd59977 291{
65bb82f2 292 if (myNbDeg < 0) ComputeSingularities();
293 for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i++) {
294 myGap = myP3d[i].Distance(P3d);
7fd59977 295 //rln S4135
296 if (myGap <= preci)
297 return Standard_True;
298 }
299 return Standard_False;
300}
301
302//=======================================================================
303//function : DegeneratedValues
304//purpose :
305//=======================================================================
306
307Standard_Boolean ShapeAnalysis_Surface::DegeneratedValues(const gp_Pnt& P3d,
65bb82f2 308 const Standard_Real preci,
309 gp_Pnt2d& firstP2d,
310 gp_Pnt2d& lastP2d,
311 Standard_Real& firstPar,
312 Standard_Real& lastPar,
313 const Standard_Boolean /*forward*/)
7fd59977 314{
65bb82f2 315 if (myNbDeg < 0) ComputeSingularities();
7fd59977 316 //#77 rln S4135: returning singularity which has minimum gap between singular point and input 3D point
317 Standard_Integer indMin = -1;
318 Standard_Real gapMin = RealLast();
65bb82f2 319 for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i++) {
320 myGap = myP3d[i].Distance(P3d);
7fd59977 321 //rln S4135
322 if (myGap <= preci)
323 if (gapMin > myGap) {
65bb82f2 324 gapMin = myGap;
325 indMin = i;
7fd59977 326 }
327 }
328 if (indMin >= 0) {
329 myGap = gapMin;
330 firstP2d = myFirstP2d[indMin];
65bb82f2 331 lastP2d = myLastP2d[indMin];
7fd59977 332 firstPar = myFirstPar[indMin];
65bb82f2 333 lastPar = myLastPar[indMin];
7fd59977 334 return Standard_True;
335 }
336 return Standard_False;
337}
338
339//=======================================================================
340//function : ProjectDegenerated
341//purpose :
342//=======================================================================
343
344Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const gp_Pnt& P3d,
65bb82f2 345 const Standard_Real preci,
346 const gp_Pnt2d& neighbour,
347 gp_Pnt2d& result)
7fd59977 348{
65bb82f2 349 if (myNbDeg < 0) ComputeSingularities();
7fd59977 350 //added by rln on 03/12/97
351 //:c1 abv 23 Feb 98: preci (3d) -> Resolution (2d)
352 //#77 rln S4135
353 Standard_Integer indMin = -1;
354 Standard_Real gapMin = RealLast();
65bb82f2 355 for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i++) {
356 Standard_Real gap2 = myP3d[i].SquareDistance(P3d);
357 if (gap2 > preci*preci)
358 gap2 = Min(gap2, myP3d[i].SquareDistance(Value(result)));
7fd59977 359 //rln S4135
65bb82f2 360 if (gap2 <= preci*preci && gapMin > gap2) {
7fd59977 361 gapMin = gap2;
362 indMin = i;
363 }
364 }
65bb82f2 365 if (indMin < 0) return Standard_False;
366 myGap = Sqrt(gapMin);
367 if (!myUIsoDeg[indMin]) result.SetX(neighbour.X());
368 else result.SetY(neighbour.Y());
7fd59977 369 return Standard_True;
370}
371
372//pdn %12 11.02.99 PRO9234 entity 15402
373//=======================================================================
374//function : ProjectDegenerated
375//purpose :
376//=======================================================================
377
378Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const Standard_Integer nbrPnt,
65bb82f2 379 const TColgp_SequenceOfPnt& points,
380 TColgp_SequenceOfPnt2d& pnt2d,
381 const Standard_Real preci,
382 const Standard_Boolean direct)
7fd59977 383{
65bb82f2 384 if (myNbDeg < 0) ComputeSingularities();
385
7fd59977 386 Standard_Integer step = (direct ? 1 : -1);
387 //#77 rln S4135
388 Standard_Integer indMin = -1;
389 Standard_Real gapMin = RealLast(), prec2 = preci*preci;
390 Standard_Integer j = (direct ? 1 : nbrPnt);
65bb82f2 391 for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i++) {
392 Standard_Real gap2 = myP3d[i].SquareDistance(points(j));
393 if (gap2 > prec2)
394 gap2 = Min(gap2, myP3d[i].SquareDistance(Value(pnt2d(j))));
395 if (gap2 <= prec2 && gapMin > gap2) {
7fd59977 396 gapMin = gap2;
397 indMin = i;
398 }
399 }
65bb82f2 400 if (indMin <0) return Standard_False;
7fd59977 401
65bb82f2 402 myGap = Sqrt(gapMin);
7fd59977 403 gp_Pnt2d pk;
65bb82f2 404
7fd59977 405 Standard_Integer k; // svv Jan11 2000 : porting on DEC
65bb82f2 406 for (k = j + step; k <= nbrPnt && k >= 1; k += step) {
407 pk = pnt2d(k);
7fd59977 408 gp_Pnt P1 = points(k);
65bb82f2 409 if (myP3d[indMin].SquareDistance(P1) > prec2 &&
410 myP3d[indMin].SquareDistance(Value(pk)) > prec2)
7fd59977 411 break;
412 }
65bb82f2 413
7fd59977 414 //:p8 abv 11 Mar 99: PRO7226 #489490: if whole pcurve is degenerate, distribute evenly
65bb82f2 415 if (k <1 || k > nbrPnt) {
416 Standard_Real x1 = (myUIsoDeg[indMin] ? pnt2d(1).Y() : pnt2d(1).X());
417 Standard_Real x2 = (myUIsoDeg[indMin] ? pnt2d(nbrPnt).Y() : pnt2d(nbrPnt).X());
418 for (j = 1; j <= nbrPnt; j++) {
7fd59977 419 //szv#4:S4163:12Mar99 warning - possible div by zero
65bb82f2 420 Standard_Real x = (x1 * (nbrPnt - j) + x2 * (j - 1)) / (nbrPnt - 1);
421 if (!myUIsoDeg[indMin]) pnt2d(j).SetX(x);
422 else pnt2d(j).SetY(x);
7fd59977 423 }
424 return Standard_True;
425 }
426
65bb82f2 427 for (j = k - step; j <= nbrPnt && j >= 1; j -= step) {
428 if (!myUIsoDeg[indMin]) pnt2d(j).SetX(pk.X());
429 else pnt2d(j).SetY(pk.Y());
7fd59977 430 }
431 return Standard_True;
432}
433
434//=======================================================================
435//method : IsDegenerated
436//purpose:
437//=======================================================================
438
65bb82f2 439Standard_Boolean ShapeAnalysis_Surface::IsDegenerated(const gp_Pnt2d &p2d1,
440 const gp_Pnt2d &p2d2,
441 const Standard_Real tol,
442 const Standard_Real ratio)
7fd59977 443{
65bb82f2 444 gp_Pnt p1 = Value(p2d1);
445 gp_Pnt p2 = Value(p2d2);
446 gp_Pnt pm = Value(0.5 * (p2d1.XY() + p2d2.XY()));
447 Standard_Real max3d = Max(p1.Distance(p2),
448 Max(pm.Distance(p1), pm.Distance(p2)));
449 if (max3d > tol) return Standard_False;
7fd59977 450
451 GeomAdaptor_Surface& SA = Adaptor3d()->ChangeSurface();
65bb82f2 452 Standard_Real RU = SA.UResolution(1.);
453 Standard_Real RV = SA.VResolution(1.);
7fd59977 454
65bb82f2 455 if (RU < Precision::PConfusion() || RV < Precision::PConfusion()) return 0;
456 Standard_Real du = Abs(p2d1.X() - p2d2.X()) / RU;
457 Standard_Real dv = Abs(p2d1.Y() - p2d2.Y()) / RV;
7fd59977 458 max3d *= ratio;
459 return du * du + dv * dv > max3d * max3d;
460}
461
462//=======================================================================
463//static : ComputeIso
464//purpose :
465//=======================================================================
466
467static Handle(Geom_Curve) ComputeIso
65bb82f2 468(const Handle(Geom_Surface)& surf,
469 const Standard_Boolean utype, const Standard_Real par)
7fd59977 470{
471 Handle(Geom_Curve) iso;
472 try {
473 OCC_CATCH_SIGNALS
65bb82f2 474 if (utype) iso = surf->UIso(par);
475 else iso = surf->VIso(par);
7fd59977 476 }
65bb82f2 477 catch (Standard_Failure const& anException) {
9775fa61 478#ifdef OCCT_DEBUG
65bb82f2 479 //:s5
480 cout << "\nWarning: ShapeAnalysis_Surface, ComputeIso(): Exception in UVIso(): ";
9775fa61 481 anException.Print(cout); cout << endl;
7fd59977 482#endif
9775fa61 483 (void)anException;
484 iso.Nullify();
7fd59977 485 }
486 return iso;
487}
488
489//=======================================================================
490//function : ComputeBoundIsos
491//purpose :
492//=======================================================================
493
494void ShapeAnalysis_Surface::ComputeBoundIsos()
495{
496 if (myIsos) return;
65bb82f2 497 myIsos = Standard_True;
498 myIsoUF = ComputeIso(mySurf, Standard_True, myUF);
499 myIsoUL = ComputeIso(mySurf, Standard_True, myUL);
500 myIsoVF = ComputeIso(mySurf, Standard_False, myVF);
501 myIsoVL = ComputeIso(mySurf, Standard_False, myVL);
7fd59977 502}
503
504//=======================================================================
505//function : UIso
506//purpose :
507//=======================================================================
508
509Handle(Geom_Curve) ShapeAnalysis_Surface::UIso(const Standard_Real U)
510{
65bb82f2 511 if (U == myUF) { ComputeBoundIsos(); return myIsoUF; }
512 if (U == myUL) { ComputeBoundIsos(); return myIsoUL; }
513 return ComputeIso(mySurf, Standard_True, U);
7fd59977 514}
515
516//=======================================================================
517//function : VIso
518//purpose :
519//=======================================================================
520
521Handle(Geom_Curve) ShapeAnalysis_Surface::VIso(const Standard_Real V)
522{
65bb82f2 523 if (V == myVF) { ComputeBoundIsos(); return myIsoVF; }
524 if (V == myVL) { ComputeBoundIsos(); return myIsoVL; }
525 return ComputeIso(mySurf, Standard_False, V);
7fd59977 526}
527
528//=======================================================================
529//function : IsUClosed
530//purpose :
531//=======================================================================
532
533Standard_Boolean ShapeAnalysis_Surface::IsUClosed(const Standard_Real preci)
534{
65bb82f2 535 Standard_Real prec = Max(preci, Precision::Confusion());
536 Standard_Real anUmidVal = -1.;
537 if (myUCloseVal < 0)
538 {
539 // Faut calculer : calculs minimaux
540 Standard_Real uf, ul, vf, vl;
541 Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
542 //mySurf->Bounds (uf,ul,vf,vl);
543 if (Precision::IsInfinite(uf) || Precision::IsInfinite(ul))
544 {
545 myUDelt = 0.;
546 }
547 else
548 {
549 myUDelt = Abs(ul - uf) / 20;//modified by rln 11/11/97 instead of 10
550 //because of the example when 10 was not enough
551 }
552 if (mySurf->IsUClosed())
553 {
554 myUCloseVal = 0.;
555 myUDelt = 0.;
556 myGap = 0.;
557 return Standard_True;
558 }
559
560 //Calculs adaptes
7fd59977 561 //#67 rln S4135
562 GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
563 GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
65bb82f2 564 if (mySurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
565 {
7fd59977 566 surftype = GeomAbs_OtherSurface;
65bb82f2 567 }
7fd59977 568
65bb82f2 569 switch (surftype)
570 {
571 case GeomAbs_Plane:
572 {
7fd59977 573 myUCloseVal = RealLast();
574 break;
575 }
65bb82f2 576 case GeomAbs_SurfaceOfExtrusion:
577 { //:c8 abv 03 Mar 98: UKI60094 #753: process Geom_SurfaceOfLinearExtrusion
7fd59977 578 Handle(Geom_SurfaceOfLinearExtrusion) extr =
65bb82f2 579 Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurf);
7fd59977 580 Handle(Geom_Curve) crv = extr->BasisCurve();
581 Standard_Real f = crv->FirstParameter();
582 Standard_Real l = crv->LastParameter();
583 //:r3 abv (smh) 30 Mar 99: protect against unexpected signals
65bb82f2 584 if (!Precision::IsInfinite(f) && !Precision::IsInfinite(l))
585 {
586 gp_Pnt p1 = crv->Value(f);
587 gp_Pnt p2 = crv->Value(l);
588 myUCloseVal = p1.SquareDistance(p2);
589 gp_Pnt pm = crv->Value((f + l) / 2.);
590 anUmidVal = p1.SquareDistance(pm);
591 }
592 else
593 {
594 myUCloseVal = RealLast();
7fd59977 595 }
7fd59977 596 break;
597 }
65bb82f2 598 case GeomAbs_BSplineSurface:
599 {
7fd59977 600 Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf);
601 Standard_Integer nbup = bs->NbUPoles();
602 Standard_Real distmin = RealLast();
65bb82f2 603 if (bs->IsUPeriodic())
604 {
605 myUCloseVal = 0;
606 myUDelt = 0;
7fd59977 607 }
65bb82f2 608 else if (nbup < 3)
609 {//modified by rln on 12/11/97
610 myUCloseVal = RealLast();
7fd59977 611 }
612 else if (bs->IsURational() ||
65bb82f2 613 //#6 rln 20/02/98 ProSTEP ug_exhaust-A.stp entity #18360 (Uclosed BSpline,
614 //but multiplicity of boundary knots != degree + 1)
615 bs->UMultiplicity(1) != bs->UDegree() + 1 || //#6 //:h4: #6 moved
616 bs->UMultiplicity(bs->NbUKnots()) != bs->UDegree() + 1)
617 { //#6 //:h4
618 Standard_Integer nbvk = bs->NbVKnots();
619 Standard_Real v = bs->VKnot(1);
620 gp_Pnt p1 = SurfAdapt.Value(uf, v);
621 gp_Pnt p2 = SurfAdapt.Value(ul, v);
622 myUCloseVal = p1.SquareDistance(p2);
623 gp_Pnt pm = SurfAdapt.Value((uf + ul) / 2., v);
624 anUmidVal = p1.SquareDistance(pm);
625 distmin = myUCloseVal;
626 for (Standard_Integer i = 2; i <= nbvk; i++)
627 {
628 v = 0.5 * (bs->VKnot(i - 1) + bs->VKnot(i));
629 p1 = bs->Value(uf, v);
630 p2 = bs->Value(ul, v);
631 Standard_Real aDist = p1.SquareDistance(p2);
632 if (aDist > myUCloseVal)
633 {
634 myUCloseVal = aDist;
635 pm = bs->Value((uf + ul) / 2., v);
636 anUmidVal = p1.SquareDistance(pm);
637 }
638 else
639 {
640 distmin = Min(distmin, aDist);
641 }
642 }
643 distmin = Sqrt(distmin);
644 myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
7fd59977 645 }
65bb82f2 646 else
647 {
648 Standard_Integer nbvp = bs->NbVPoles();
649 myUCloseVal = bs->Pole(1, 1).SquareDistance(bs->Pole(nbup, 1));
650 anUmidVal = bs->Pole(1, 1).SquareDistance(bs->Pole(nbup / 2 + 1, 1));
651 distmin = myUCloseVal;
652 for (Standard_Integer i = 2; i <= nbvp; i++)
653 {
654 Standard_Real aDist = bs->Pole(1, i).SquareDistance(bs->Pole(nbup, i));
655 if (aDist > myUCloseVal)
656 {
657 myUCloseVal = aDist;
658 anUmidVal = bs->Pole(1, i).SquareDistance(bs->Pole(nbup / 2 + 1, i));
659 }
660 else
661 {
662 distmin = Min(distmin, aDist);
663 }
664 }
665 distmin = Sqrt(distmin);
666 myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
7fd59977 667 }
668 break;
669 }
65bb82f2 670 case GeomAbs_BezierSurface:
671 {
7fd59977 672 Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf);
673 Standard_Integer nbup = bz->NbUPoles();
674 Standard_Real distmin = RealLast();
675 if (nbup < 3)
65bb82f2 676 {
677 myUCloseVal = RealLast();
678 }
679 else
680 {
681 Standard_Integer nbvp = bz->NbVPoles();
682 myUCloseVal = bz->Pole(1, 1).SquareDistance(bz->Pole(nbup, 1));
683 anUmidVal = bz->Pole(1, 1).SquareDistance(bz->Pole(nbup / 2 + 1, 1));
684 distmin = myUCloseVal;
685 for (Standard_Integer i = 1; i <= nbvp; i++)
686 {
687 Standard_Real aDist = bz->Pole(1, i).SquareDistance(bz->Pole(nbup, i));
688 if (aDist > myUCloseVal) {
689 myUCloseVal = aDist;
690 anUmidVal = bz->Pole(1, i).SquareDistance(bz->Pole(nbup / 2 + 1, i));
691 }
692 else
693 {
694 distmin = Min(distmin, aDist);
695 }
696 }
697 distmin = Sqrt(distmin);
698 myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
7fd59977 699 }
700 break;
701 }
65bb82f2 702 default:
703 { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
7fd59977 704 Standard_Real distmin = RealLast();
705 Standard_Integer nbpoints = 101; //can be revised
65bb82f2 706 gp_Pnt p1 = SurfAdapt.Value(uf, vf);
707 gp_Pnt p2 = SurfAdapt.Value(ul, vf);
708 myUCloseVal = p1.SquareDistance(p2);
709 gp_Pnt pm = SurfAdapt.Value((uf + ul) / 2, vf);
710 anUmidVal = p1.SquareDistance(pm);
711 distmin = myUCloseVal;
712 for (Standard_Integer i = 1; i < nbpoints; i++)
713 {
714 Standard_Real vparam = vf + (vl - vf) * i / (nbpoints - 1);
715 p1 = SurfAdapt.Value(uf, vparam);
716 p2 = SurfAdapt.Value(ul, vparam);
717 Standard_Real aDist = p1.SquareDistance(p2);
718 if (aDist > myUCloseVal)
719 {
720 myUCloseVal = aDist;
721 pm = SurfAdapt.Value((uf + ul) / 2, vparam);
722 anUmidVal = p1.SquareDistance(pm);
723 }
724 else
725 {
726 distmin = Min(distmin, aDist);
727 }
7fd59977 728 }
65bb82f2 729 distmin = Sqrt(distmin);
730 myUDelt = Min(myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh
7fd59977 731 break;
732 }
733 } //switch
65bb82f2 734 myGap = sqrt(myUCloseVal);
735 myUCloseVal = myGap;
736 }
737
738 if (anUmidVal > 0. && myUCloseVal > sqrt(anUmidVal))
739 {
740 myUCloseVal = RealLast();
741 return Standard_False;
7fd59977 742 }
65bb82f2 743
7fd59977 744 return (myUCloseVal <= prec);
745}
746
747//=======================================================================
748//function : IsVClosed
749//purpose :
750//=======================================================================
751
752Standard_Boolean ShapeAnalysis_Surface::IsVClosed(const Standard_Real preci)
753{
65bb82f2 754 Standard_Real prec = Max(preci, Precision::Confusion());
755 Standard_Real aVmidVal = -1.;
756 if (myVCloseVal < 0)
757 {
758 // Faut calculer : calculs minimaux
759 Standard_Real uf, ul, vf, vl;
760 Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
761 // mySurf->Bounds (uf,ul,vf,vl);
762 if (Precision::IsInfinite(vf) || Precision::IsInfinite(vl))
763 {
764 myVDelt = 0.;
765 }
766 else
767 {
768 myVDelt = Abs(vl - vf) / 20;// 2; rln S4135
769 //because of the example when 10 was not enough
770 }
771 if (mySurf->IsVClosed())
772 {
773 myVCloseVal = 0.;
774 myVDelt = 0.;
775 myGap = 0.;
776 return Standard_True;
777 }
778
779 // Calculs adaptes
7fd59977 780 //#67 rln S4135
781 GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
782 GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
65bb82f2 783 if (mySurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
784 {
7fd59977 785 surftype = GeomAbs_OtherSurface;
65bb82f2 786 }
7fd59977 787
65bb82f2 788 switch (surftype)
789 {
7fd59977 790 case GeomAbs_Plane:
791 case GeomAbs_Cone:
792 case GeomAbs_Cylinder:
793 case GeomAbs_Sphere:
65bb82f2 794 case GeomAbs_SurfaceOfExtrusion:
795 {
7fd59977 796 myVCloseVal = RealLast();
797 break;
798 }
65bb82f2 799 case GeomAbs_SurfaceOfRevolution:
800 {
7fd59977 801 Handle(Geom_SurfaceOfRevolution) revol =
65bb82f2 802 Handle(Geom_SurfaceOfRevolution)::DownCast(mySurf);
7fd59977 803 Handle(Geom_Curve) crv = revol->BasisCurve();
65bb82f2 804 gp_Pnt p1 = crv->Value(crv->FirstParameter());
805 gp_Pnt p2 = crv->Value(crv->LastParameter());
806 myVCloseVal = p1.SquareDistance(p2);
7fd59977 807 break;
808 }
65bb82f2 809 case GeomAbs_BSplineSurface:
810 {
7fd59977 811 Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf);
812 Standard_Integer nbvp = bs->NbVPoles();
813 Standard_Real distmin = RealLast();
65bb82f2 814 if (bs->IsVPeriodic())
815 {
816 myVCloseVal = 0;
817 myVDelt = 0;
7fd59977 818 }
65bb82f2 819 else if (nbvp < 3)
820 {//modified by rln on 12/11/97
821 myVCloseVal = RealLast();
7fd59977 822 }
823 else if (bs->IsVRational() ||
65bb82f2 824 bs->VMultiplicity(1) != bs->VDegree() + 1 || //#6 //:h4
825 bs->VMultiplicity(bs->NbVKnots()) != bs->VDegree() + 1)
826 { //#6 //:h4
827 Standard_Integer nbuk = bs->NbUKnots();
828 Standard_Real u = bs->UKnot(1);
829 gp_Pnt p1 = SurfAdapt.Value(u, vf);
830 gp_Pnt p2 = SurfAdapt.Value(u, vl);
831 myVCloseVal = p1.SquareDistance(p2);
832 gp_Pnt pm = SurfAdapt.Value(u, (vf + vl) / 2.);
833 aVmidVal = p1.SquareDistance(pm);
834 distmin = myVCloseVal;
835 for (Standard_Integer i = 2; i <= nbuk; i++)
836 {
837 u = 0.5 * (bs->UKnot(i - 1) + bs->UKnot(i));
838 p1 = SurfAdapt.Value(u, vf);
839 p2 = SurfAdapt.Value(u, vl);
840 Standard_Real aDist = p1.SquareDistance(p2);
841 if (aDist > myVCloseVal)
842 {
843 myVCloseVal = aDist;
844 pm = SurfAdapt.Value(u, (vf + vl) / 2);
845 aVmidVal = p1.SquareDistance(pm);
846 }
847 else
848 {
849 distmin = Min(distmin, aDist);
850 }
851 }
852 distmin = Sqrt(distmin);
853 myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
7fd59977 854 }
65bb82f2 855 else
856 {
857 Standard_Integer nbup = bs->NbUPoles();
858 myVCloseVal = bs->Pole(1, 1).SquareDistance(bs->Pole(1, nbvp));
859 aVmidVal = bs->Pole(1, 1).SquareDistance(bs->Pole(1, nbvp / 2 + 1));
860 distmin = myVCloseVal;
861 for (Standard_Integer i = 2; i <= nbup; i++)
862 {
863 Standard_Real aDist = bs->Pole(i, 1).SquareDistance(bs->Pole(i, nbvp));
864 if (aDist > myVCloseVal)
865 {
866 myVCloseVal = aDist;
867 aVmidVal = bs->Pole(i, 1).SquareDistance(bs->Pole(i, nbvp / 2 + 1));
868 }
869 else
870 {
871 distmin = Min(distmin, aDist);
872 }
873 }
874 distmin = Sqrt(distmin);
875 myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
7fd59977 876 }
877 break;
878 }
65bb82f2 879 case GeomAbs_BezierSurface:
880 {
7fd59977 881 Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf);
882 Standard_Integer nbvp = bz->NbVPoles();
883 Standard_Real distmin = RealLast();
884 if (nbvp < 3)
65bb82f2 885 {
886 myVCloseVal = RealLast();
887 }
888 else
889 {
890 Standard_Integer nbup = bz->NbUPoles();
891 myVCloseVal = bz->Pole(1, 1).SquareDistance(bz->Pole(1, nbvp));
892 aVmidVal = bz->Pole(1, 1).SquareDistance(bz->Pole(1, nbvp / 2 + 1));
893 distmin = myVCloseVal;
894 for (Standard_Integer i = 2; i <= nbup; i++)
895 {
896 Standard_Real aDist = bz->Pole(i, 1).SquareDistance(bz->Pole(i, nbvp));
897 if (aDist > myVCloseVal)
898 {
899 myVCloseVal = aDist;
900 aVmidVal = bz->Pole(i, 1).SquareDistance(bz->Pole(i, nbvp / 2 + 1));
901 }
902 else
903 {
904 distmin = Min(distmin, aDist);
905 }
906 }
907 distmin = Sqrt(distmin);
908 myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
7fd59977 909 }
910 break;
911 }
65bb82f2 912 default:
913 { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface
7fd59977 914 Standard_Real distmin = RealLast();
915 Standard_Integer nbpoints = 101; //can be revised
65bb82f2 916 gp_Pnt p1 = SurfAdapt.Value(uf, vf);
917 gp_Pnt p2 = SurfAdapt.Value(uf, vl);
918 gp_Pnt pm = SurfAdapt.Value(uf, (vf + vl) / 2);
919 myVCloseVal = p1.SquareDistance(p2);
920 aVmidVal = p1.SquareDistance(pm);
921 distmin = myVCloseVal;
922 for (Standard_Integer i = 1; i < nbpoints; i++)
923 {
924 Standard_Real uparam = uf + (ul - uf) * i / (nbpoints - 1);
925 p1 = SurfAdapt.Value(uparam, vf);
926 p2 = SurfAdapt.Value(uparam, vl);
927 Standard_Real aDist = p1.SquareDistance(p2);
928 if (aDist > myVCloseVal)
929 {
930 myVCloseVal = aDist;
931 pm = SurfAdapt.Value(uparam, (vf + vl) / 2);
932 aVmidVal = p1.SquareDistance(pm);
933 }
934 else
935 {
936 distmin = Min(distmin, aDist);
937 }
7fd59977 938 }
65bb82f2 939 distmin = Sqrt(distmin);
940 myVDelt = Min(myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh
7fd59977 941 break;
942 }
943 } //switch
65bb82f2 944 myGap = Sqrt(myVCloseVal);
945 myVCloseVal = myGap;
946 }
947
948 if (aVmidVal > 0. && myVCloseVal > sqrt(aVmidVal))
949 {
950 myVCloseVal = RealLast();
951 return Standard_False;
7fd59977 952 }
65bb82f2 953
7fd59977 954 return (myVCloseVal <= prec);
955}
956
65bb82f2 957
7fd59977 958//=======================================================================
959//function : SurfaceNewton
960//purpose : Newton algo (S4030)
961//=======================================================================
dde68833 962Standard_Integer ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev,
65bb82f2 963 const gp_Pnt& P3D,
964 const Standard_Real preci,
965 gp_Pnt2d &sol)
7fd59977 966{
967 GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
968 Standard_Real uf, ul, vf, vl;
969 Bounds(uf, ul, vf, vl);
65bb82f2 970 Standard_Real du = SurfAdapt.UResolution(preci);
971 Standard_Real dv = SurfAdapt.VResolution(preci);
7fd59977 972 Standard_Real UF = uf - du, UL = ul + du;
973 Standard_Real VF = vf - dv, VL = vl + dv;
974
65bb82f2 975 //Standard_Integer fail = 0;
7fd59977 976 Standard_Real Tol = Precision::Confusion();
977 Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10;
978 Standard_Real U = p2dPrev.X(), V = p2dPrev.Y();
65bb82f2 979 gp_Vec rsfirst = P3D.XYZ() - Value(U, V).XYZ(); //pdn
980 for (Standard_Integer i = 0; i < 25; i++) {
7fd59977 981 gp_Vec ru, rv, ruu, rvv, ruv;
982 gp_Pnt pnt;
65bb82f2 983 SurfAdapt.D2(U, V, pnt, ru, rv, ruu, rvv, ruv);
7fd59977 984
985 // normal
986 Standard_Real ru2 = ru * ru, rv2 = rv * rv;
987 gp_Vec n = ru ^ rv;
988 Standard_Real nrm2 = n.SquareMagnitude();
65bb82f2 989 if (nrm2 < 1e-10 || Precision::IsPositiveInfinite(nrm2)) break; // n == 0, use standard
990
991 // descriminant
992 gp_Vec rs = P3D.XYZ() - Value(U, V).XYZ();
993 Standard_Real rSuu = (rs * ruu);
994 Standard_Real rSvv = (rs * rvv);
995 Standard_Real rSuv = (rs * ruv);
996 Standard_Real D = -nrm2 + rv2 * rSuu + ru2 * rSvv -
997 2 * rSuv * (ru*rv) + rSuv*rSuv - rSuu*rSvv;
998 if (fabs(D) < 1e-10) break; // bad case; use standard
999
1000 // compute step
7fd59977 1001 Standard_Real fract = 1. / D;
65bb82f2 1002 du = (rs * ((n ^ rv) + ru * rSvv - rv * rSuv)) * fract;
1003 dv = (rs * ((ru ^ n) + rv * rSuu - ru * rSuv)) * fract;
7fd59977 1004 U += du;
1005 V += dv;
65bb82f2 1006 if (U < UF || U > UL || V < VF || V > VL) break;
7fd59977 1007 // check that iterations do not diverge
65bb82f2 1008 //pdn Standard_Real rs2 = rs.SquareMagnitude();
1009 // if ( rs2 > 4.*rs2p ) break;
1010 // rs2p = rs2;
7fd59977 1011
1012 // test the step by uv and deviation from the solution
65bb82f2 1013 Standard_Real aResolution = Max(1e-12, (U + V)*10e-16);
1014 if (fabs(du) + fabs(dv) > aResolution) continue; //Precision::PConfusion() continue;
7fd59977 1015
65bb82f2 1016 //if ( U < UF || U > UL || V < VF || V > VL ) break;
7fd59977 1017
65bb82f2 1018 //pdn PRO10109 4517: protect against wrong result
7fd59977 1019 Standard_Real rs2 = rs.SquareMagnitude();
65bb82f2 1020 if (rs2 > rsfirst.SquareMagnitude()) break;
7fd59977 1021
1022 Standard_Real rsn = rs * n;
65bb82f2 1023 if (rs2 - rsn * rsn / nrm2 > Tol2) break;
7fd59977 1024
65bb82f2 1025 // if ( rs2 > 100 * preci * preci ) { fail = 6; break; }
7fd59977 1026
1027 // OK, return the result
65bb82f2 1028 // cout << "Newton: solution found in " << i+1 << " iterations" << endl;
1029 sol.SetCoord(U, V);
1030
1031 return (nrm2 < 0.01 * ru2 * rv2 ? 2 : 1); //:q6
7fd59977 1032 }
65bb82f2 1033 // cout << "Newton: failed after " << i+1 << " iterations (fail " << fail << " )" << endl;
7fd59977 1034 return Standard_False;
1035}
1036
1037//=======================================================================
1038//function : NextValueOfUV
1039//purpose : optimizing projection by Newton algo (S4030)
1040//=======================================================================
1041
1042gp_Pnt2d ShapeAnalysis_Surface::NextValueOfUV(const gp_Pnt2d &p2dPrev,
65bb82f2 1043 const gp_Pnt& P3D,
1044 const Standard_Real preci,
1045 const Standard_Real maxpreci)
7fd59977 1046{
1047 GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
1048 GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
1049
65bb82f2 1050 switch (surftype) {
1051 case GeomAbs_BezierSurface:
1052 case GeomAbs_BSplineSurface:
1053 case GeomAbs_SurfaceOfExtrusion:
1054 case GeomAbs_SurfaceOfRevolution:
1055 case GeomAbs_OffsetSurface:
7fd59977 1056
65bb82f2 1057 {
1058 if (surftype == GeomAbs_BSplineSurface)
7fd59977 1059 {
65bb82f2 1060 Handle(Geom_BSplineSurface) aBSpline = SurfAdapt.BSpline();
15b54261 1061
65bb82f2 1062 //Check near to knot position ~ near to C0 points on U isoline.
1063 if (SurfAdapt.UContinuity() == GeomAbs_C0)
1064 {
1065 Standard_Integer aMinIndex = aBSpline->FirstUKnotIndex();
1066 Standard_Integer aMaxIndex = aBSpline->LastUKnotIndex();
1067 for (Standard_Integer anIdx = aMinIndex; anIdx <= aMaxIndex; ++anIdx)
15b54261 1068 {
65bb82f2 1069 Standard_Real aKnot = aBSpline->UKnot(anIdx);
1070 if (Abs(aKnot - p2dPrev.X()) < Precision::Confusion())
1071 return ValueOfUV(P3D, preci);
15b54261 1072 }
65bb82f2 1073 }
15b54261 1074
65bb82f2 1075 //Check near to knot position ~ near to C0 points on U isoline.
1076 if (SurfAdapt.VContinuity() == GeomAbs_C0)
1077 {
1078 Standard_Integer aMinIndex = aBSpline->FirstVKnotIndex();
1079 Standard_Integer aMaxIndex = aBSpline->LastVKnotIndex();
1080 for (Standard_Integer anIdx = aMinIndex; anIdx <= aMaxIndex; ++anIdx)
15b54261 1081 {
65bb82f2 1082 Standard_Real aKnot = aBSpline->VKnot(anIdx);
1083 if (Abs(aKnot - p2dPrev.Y()) < Precision::Confusion())
1084 return ValueOfUV(P3D, preci);
15b54261 1085 }
1086 }
65bb82f2 1087 }
15b54261 1088
65bb82f2 1089 gp_Pnt2d sol;
1090 Standard_Integer res = SurfaceNewton(p2dPrev, P3D, preci, sol);
1091 if (res != 0)
1092 {
1093 Standard_Real gap = P3D.Distance(Value(sol));
1094 if (res == 2 || //:q6 abv 19 Mar 99: protect against strange attractors
1095 (maxpreci > 0. && gap - maxpreci > Precision::Confusion()))
1096 { //:q1: check with maxpreci
1097 Standard_Real U = sol.X(), V = sol.Y();
1098 myGap = UVFromIso(P3D, preci, U, V);
1099 // gp_Pnt2d p = ValueOfUV ( P3D, preci );
1100 if (gap >= myGap) return gp_Pnt2d(U, V);
7fd59977 1101 }
65bb82f2 1102 myGap = gap;
1103 return sol;
7fd59977 1104 }
65bb82f2 1105 }
1106 break;
7fd59977 1107 default:
1108 break;
1109 }
65bb82f2 1110 return ValueOfUV(P3D, preci);
7fd59977 1111}
1112
1113//=======================================================================
1114//function : ValueOfUV
1115//purpose :
1116//=======================================================================
1117
65bb82f2 1118gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D, const Standard_Real preci)
7fd59977 1119{
1120 GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface();
1d47d8d0 1121 Standard_Real S = 0., T = 0.;
7fd59977 1122 myGap = -1.; // devra etre calcule
1123 Standard_Boolean computed = Standard_True; // a priori
65bb82f2 1124
7fd59977 1125 Standard_Real uf, ul, vf, vl;
1126 Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted
65bb82f2 1127
7fd59977 1128 { //:c9 abv 3 Mar 98: UKI60107-1 #350: to prevent 'catch' from catching exception raising below it
65bb82f2 1129 try { // ajout CKY 30-DEC-1997 (cf ProStep TR6 r_89-ug)
1130 OCC_CATCH_SIGNALS
1131 GeomAbs_SurfaceType surftype = SurfAdapt.GetType();
1132 switch (surftype) {
7fd59977 1133
65bb82f2 1134 case GeomAbs_Plane:
1135 {
1136 gp_Pln Plane = SurfAdapt.Plane();
1137 ElSLib::Parameters(Plane, P3D, S, T);
1138 break;
1139 }
1140 case GeomAbs_Cylinder:
1141 {
1142 gp_Cylinder Cylinder = SurfAdapt.Cylinder();
1143 ElSLib::Parameters(Cylinder, P3D, S, T);
1144 S += ShapeAnalysis::AdjustByPeriod(S, 0.5*(uf + ul), 2 * M_PI);
1145 break;
1146 }
1147 case GeomAbs_Cone:
1148 {
1149 gp_Cone Cone = SurfAdapt.Cone();
1150 ElSLib::Parameters(Cone, P3D, S, T);
1151 S += ShapeAnalysis::AdjustByPeriod(S, 0.5*(uf + ul), 2 * M_PI);
1152 break;
1153 }
1154 case GeomAbs_Sphere:
1155 {
1156 gp_Sphere Sphere = SurfAdapt.Sphere();
1157 ElSLib::Parameters(Sphere, P3D, S, T);
1158 S += ShapeAnalysis::AdjustByPeriod(S, 0.5*(uf + ul), 2 * M_PI);
1159 break;
1160 }
1161 case GeomAbs_Torus:
1162 {
1163 gp_Torus Torus = SurfAdapt.Torus();
1164 ElSLib::Parameters(Torus, P3D, S, T);
1165 S += ShapeAnalysis::AdjustByPeriod(S, 0.5*(uf + ul), 2 * M_PI);
1166 T += ShapeAnalysis::AdjustByPeriod(T, 0.5*(vf + vl), 2 * M_PI);
1167 break;
1168 }
1169 case GeomAbs_BezierSurface:
1170 case GeomAbs_BSplineSurface:
1171 case GeomAbs_SurfaceOfExtrusion:
1172 case GeomAbs_SurfaceOfRevolution:
1173 case GeomAbs_OffsetSurface: //:d0 abv 3 Mar 98: UKI60107-1 #350
1174 {
1175 S = (uf + ul) / 2; T = (vf + vl) / 2; // yaura aumoins qqchose
1176 //pdn to fix hangs PRO17015
1177 if ((surftype == GeomAbs_SurfaceOfExtrusion) && Precision::IsInfinite(uf) && Precision::IsInfinite(ul)) {
1178 //conic case
1179 gp_Pnt2d prev(S, T);
1180 gp_Pnt2d solution;
1181 if (SurfaceNewton(prev, P3D, preci, solution) != 0)
1182 {
0797d9d3 1183#ifdef OCCT_DEBUG
65bb82f2 1184 cout << "Newton found point on conic extrusion" << endl;
7fd59977 1185#endif
65bb82f2 1186 return solution;
1187 }
0797d9d3 1188#ifdef OCCT_DEBUG
65bb82f2 1189 cout << "Newton failed point on conic extrusion" << endl;
7fd59977 1190#endif
65bb82f2 1191 uf = -500;
1192 ul = 500;
1193 }
7fd59977 1194
65bb82f2 1195 if (Precision::IsInfinite(uf)) uf = -1000;
1196 if (Precision::IsInfinite(ul)) ul = 1000;
1197 if (Precision::IsInfinite(vf)) vf = -1000;
1198 if (Precision::IsInfinite(vl)) vl = 1000;
1199
1200 //:30 by abv 2.12.97: speed optimization
1201 // code is taken from GeomAPI_ProjectPointOnSurf
1202 if (!myExtOK) {
1203 // Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100;
1204 // if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0;
1205 // Forcer appel a IsU-VClosed
1206 if (myUCloseVal < 0) IsUClosed();
1207 if (myVCloseVal < 0) IsVClosed();
1208 Standard_Real du = 0., dv = 0.;
1209 //extension of the surface range is limited to non-offset surfaces as the latter
1210 //can throw exception (e.g. Geom_UndefinedValue) when computing value - see id23943
1211 if (!mySurf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1212 //modified by rln during fixing CSR # BUC60035 entity #D231
1213 du = Min(myUDelt, SurfAdapt.UResolution(preci));
1214 dv = Min(myVDelt, SurfAdapt.VResolution(preci));
1215 }
1216 Standard_Real Tol = Precision::PConfusion();
1217 myExtPS.SetFlag(Extrema_ExtFlag_MIN);
1218 myExtPS.Initialize(SurfAdapt, uf - du, ul + du, vf - dv, vl + dv, Tol, Tol);
1219 myExtOK = Standard_True;
1220 }
1221 myExtPS.Perform(P3D);
1222 Standard_Integer nPSurf = (myExtPS.IsDone() ? myExtPS.NbExt() : 0);
1223
1224 if (nPSurf > 0) {
1225 Standard_Real dist2Min = myExtPS.SquareDistance(1);
1226 Standard_Integer indMin = 1;
1227 for (Standard_Integer sol = 2; sol <= nPSurf; sol++) {
1228 Standard_Real dist2 = myExtPS.SquareDistance(sol);
1229 if (dist2Min > dist2) {
1230 dist2Min = dist2;
1231 indMin = sol;
1232 }
1233 }
1234 myExtPS.Point(indMin).Parameter(S, T);
1235 // PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug.
1236 // file CEA_cuve-V5.igs Entityes 244, 259, 847, 925
1237 // if project point3D on SurfaceOfRevolution Extreme recompute 2d point, but
1238 // returns an old distance from 3d to solution :-(
1239 gp_Pnt aCheckPnt = SurfAdapt.Value(S, T);
1240 dist2Min = P3D.SquareDistance(aCheckPnt);
1241 // end of WORKAROUND
1242 Standard_Real disSurf = sqrt(dist2Min);//, disCurv =1.e10;
1243
1244 // Test de projection merdeuse sur les bords :
1245 Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap;
1246 // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
1247
1248 //test added by rln on 08/12/97
1249 // DistMinOnIso = UVFromIso (P3D, preci, UU, VV);
1250 Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing)
1251 if (disSurf > preci) {
1252 gp_Pnt2d pp(UU, VV);
1253 if (SurfaceNewton(pp, P3D, preci, pp) != 0)
1254 { //:q2 abv 16 Mar 99: PRO7226 #412920
1255 Standard_Real dist = P3D.Distance(Value(pp));
1256 if (dist < disSurf) {
1257 disSurf = dist;
1258 S = UU = pp.X();
1259 T = VV = pp.Y();
1260 }
1261 }
1262 if (disSurf < 10 * preci)
1263 if (mySurf->Continuity() != GeomAbs_C0) {
1264 Standard_Real Tol = Precision::Confusion();
1265 gp_Vec D1U, D1V;
1266 gp_Pnt pnt;
1267 SurfAdapt.D1(UU, VV, pnt, D1U, D1V);
1268 gp_Vec b = D1U.Crossed(D1V);
1269 gp_Vec a(pnt, P3D);
1270 Standard_Real ab = a.Dot(b);
1271 Standard_Real nrm2 = b.SquareMagnitude();
1272 if (nrm2 > 1e-10) {
1273 Standard_Real dist = a.SquareMagnitude() - (ab*ab) / nrm2;
1274 possLockal = (dist < Tol*Tol);
1275 }
1276 }
1277 if (!possLockal) {
1278 DistMinOnIso = UVFromIso(P3D, preci, UU, VV);
1279 }
1280 }
7fd59977 1281
65bb82f2 1282 if (disSurf > DistMinOnIso) {
1283 // On prend les parametres UU et VV;
1284 S = UU;
1285 T = VV;
1286 myGap = DistMinOnIso;
1287 }
1288 else {
1289 myGap = disSurf;
1290 }
1291
1292 // On essaie Intersection Droite Passant par P3D / Surface
1293 // if ((myGap > preci)&&(!possLockal) ) {
1294 // Standard_Real SS, TT;
1295 // disCurv = FindUV(P3D, mySurf, S, T, SS, TT);
1296 // if (disCurv < preci || disCurv < myGap) {
1297 // S = SS;
1298 // T = TT;
1299 // }
1300 // }
1301
1302 }
1303 else {
0797d9d3 1304#ifdef OCCT_DEBUG
65bb82f2 1305 cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl;
7fd59977 1306#endif
65bb82f2 1307 // on essai sur les bords
1308 Standard_Real UU = S, VV = T;//, DistMinOnIso;
1309 // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso);
1310 myGap = UVFromIso(P3D, preci, UU, VV);
1311 // if (DistMinOnIso > preci) {
1312 // Standard_Real SS, TT;
1313 // Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT);
1314 // if (disCurv < preci) {
1315 // S = SS;
1316 // T = TT;
1317 // }
1318 // }
1319 // else {
1320 S = UU;
1321 T = VV;
1322 // }
1323 }
7fd59977 1324 }
65bb82f2 1325 break;
7fd59977 1326
65bb82f2 1327 default:
1328 computed = Standard_False;
1329 break;
1330 }
7fd59977 1331
65bb82f2 1332 } // end Try ValueOfUV (CKY 30-DEC-1997)
7fd59977 1333
65bb82f2 1334 catch (Standard_Failure const& anException) {
9775fa61 1335#ifdef OCCT_DEBUG
65bb82f2 1336 // Pas de raison mais qui sait. Mieux vaut retourner un truc faux que stopper
1337 // L ideal serait d avoir un status ... mais qui va l interroger ?
1338 // Avec ce status, on saurait que ce point est a sauter et voila tout
1339 // En attendant, on met une valeur "pas idiote" mais surement fausse ...
1340 //szv#4:S4163:12Mar99 optimized
1341 //:s5
1342 cout << "\nWarning: ShapeAnalysis_Surface::ValueOfUV(): Exception: ";
1343 anException.Print(cout); cout << endl;
7fd59977 1344#endif
65bb82f2 1345 (void)anException;
1346 S = (Precision::IsInfinite(uf)) ? 0 : (uf + ul) / 2.;
1347 T = (Precision::IsInfinite(vf)) ? 0 : (vf + vl) / 2.;
1348 }
7fd59977 1349 } //:c9
65bb82f2 1350 //szv#4:S4163:12Mar99 waste raise
1351 //if (!computed) throw Standard_NoSuchObject("PCurveLib_ProjectPointOnSurf::ValueOfUV untreated surface type");
1352 if (computed) { if (myGap <= 0) myGap = P3D.Distance(SurfAdapt.Value(S, T)); }
7fd59977 1353 else { myGap = -1.; S = 0.; T = 0.; }
65bb82f2 1354 return gp_Pnt2d(S, T);
7fd59977 1355}
1356
1357//=======================================================================
1358//function : UVFromIso
1359//purpose :
1360//=======================================================================
1361
65bb82f2 1362Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d, const Standard_Real preci, Standard_Real& U, Standard_Real& V)
7fd59977 1363{
65bb82f2 1364 // Projection qui considere les isos ... comme suit :
1365 // Les 4 bords, plus les isos en U et en V
1366 // En effet, souvent, un des deux est bon ...
7fd59977 1367 Standard_Real theMin = RealLast();
65bb82f2 1368
7fd59977 1369 gp_Pnt pntres;
65bb82f2 1370 Standard_Real Cf, Cl, UU, VV;
7fd59977 1371
1372 // Initialisation des recherches : point deja trouve (?)
1373 UU = U; VV = V;
65bb82f2 1374 gp_Pnt depart = myAdSur->Value(U, V);
7fd59977 1375 theMin = depart.Distance(P3d);
65bb82f2 1376
1377 if (theMin < preci / 10) return theMin; // c etait deja OK
7fd59977 1378 ComputeBoxes();
65bb82f2 1379 if (myIsoUF.IsNull() || myIsoUL.IsNull() || myIsoVF.IsNull() || myIsoVL.IsNull()) {
7fd59977 1380 // no isolines
1381 // no more precise computation
1382 return theMin;
1383 }
1384 try { // RAJOUT
1385 OCC_CATCH_SIGNALS
65bb82f2 1386 //pdn Create BndBox containing point;
1387 Bnd_Box aPBox;
7fd59977 1388 aPBox.Set(P3d);
1389
1390 //cout<<"Adaptor3d()->Surface().GetType() = "<<Adaptor3d()->Surface().GetType()<<endl;
1391
1392 //modified by rln on 04/12/97 in order to use theese variables later
1393 Standard_Boolean UV = Standard_True;
65bb82f2 1394 Standard_Real par = 0., other = 0., dist = 0.;
7fd59977 1395 Handle(Geom_Curve) iso;
1396 Adaptor3d_IsoCurve anIsoCurve(Adaptor3d());
65bb82f2 1397 for (Standard_Integer num = 0; num < 6; num++) {
7fd59977 1398
1399 UV = (num < 3); // 0-1-2 : iso-U 3-4-5 : iso-V
65bb82f2 1400 if (!(Adaptor3d()->Surface().GetType() == GeomAbs_OffsetSurface)) {
1401 const Bnd_Box *anIsoBox = 0;
7fd59977 1402 switch (num) {
65bb82f2 1403 case 0: par = myUF; iso = myIsoUF; anIsoBox = &myBndUF; break;
1404 case 1: par = myUL; iso = myIsoUL; anIsoBox = &myBndUL; break;
1405 case 2: par = U; iso = UIso(U); break;
1406 case 3: par = myVF; iso = myIsoVF; anIsoBox = &myBndVF; break;
1407 case 4: par = myVL; iso = myIsoVL; anIsoBox = &myBndVL; break;
1408 case 5: par = V; iso = VIso(V); break;
7fd59977 1409 default: break;
1410 }
65bb82f2 1411
7fd59977 1412 // On y va la-dessus
1413 if (!Precision::IsInfinite(par) && !iso.IsNull()) {
65bb82f2 1414 if (anIsoBox && anIsoBox->Distance(aPBox) > theMin)
7fd59977 1415 continue;
65bb82f2 1416
7fd59977 1417 Cf = iso->FirstParameter();
1418 Cl = iso->LastParameter();
65bb82f2 1419
7fd59977 1420 if (Precision::IsInfinite(Cf)) Cf = -1000;
1421 if (Precision::IsInfinite(Cl)) Cl = +1000;
65bb82f2 1422 dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
7fd59977 1423 if (dist < theMin) {
1424 theMin = dist;
1425 //:q6 if (UV) VV = other; else UU = other;
1426 // Selon une isoU, on calcule le meilleur V; et lycee de Versailles
1427 UU = (UV ? par : other); VV = (UV ? other : par); //:q6: uncommented
1428 }
1429 }
1430 }
1431
1432 else {
1433 Adaptor3d_Curve *anAdaptor = NULL;
1434 GeomAdaptor_Curve aGeomCurve;
65bb82f2 1435
1436 const Bnd_Box *anIsoBox = 0;
7fd59977 1437 switch (num) {
65bb82f2 1438 case 0: par = myUF; aGeomCurve.Load(myIsoUF); anAdaptor = &aGeomCurve; anIsoBox = &myBndUF; break;
1439 case 1: par = myUL; aGeomCurve.Load(myIsoUL); anAdaptor = &aGeomCurve; anIsoBox = &myBndUL; break;
1440 case 2: par = U; anIsoCurve.Load(GeomAbs_IsoU, U); anAdaptor = &anIsoCurve; break;
1441 case 3: par = myVF; aGeomCurve.Load(myIsoVF); anAdaptor = &aGeomCurve; anIsoBox = &myBndVF; break;
1442 case 4: par = myVL; aGeomCurve.Load(myIsoVL); anAdaptor = &aGeomCurve; anIsoBox = &myBndVL; break;
1443 case 5: par = V; anIsoCurve.Load(GeomAbs_IsoV, V); anAdaptor = &anIsoCurve; break;
1444 default: break;
7fd59977 1445 }
65bb82f2 1446 if (anIsoBox && anIsoBox->Distance(aPBox) > theMin)
7fd59977 1447 continue;
65bb82f2 1448 dist = ShapeAnalysis_Curve().Project(*anAdaptor, P3d, preci, pntres, other);
7fd59977 1449 if (dist < theMin) {
1450 theMin = dist;
1451 UU = (UV ? par : other); VV = (UV ? other : par); //:q6: uncommented
1452 }
1453 }
1454 }
65bb82f2 1455
7fd59977 1456 //added by rln on 04/12/97 iterational process
1457 Standard_Real PrevU = U, PrevV = V;
1458 Standard_Integer MaxIters = 5, Iters = 0;
65bb82f2 1459 if (!(Adaptor3d()->Surface().GetType() == GeomAbs_OffsetSurface)) {
7fd59977 1460 while (((PrevU != UU) || (PrevV != VV)) && (Iters < MaxIters) && (theMin > preci)) {
1461 PrevU = UU; PrevV = VV;
65bb82f2 1462 if (UV) { par = UU; iso = UIso(UU); }
1463 else { par = VV; iso = VIso(VV); }
1464 if (!iso.IsNull()) {
7fd59977 1465 Cf = iso->FirstParameter();
1466 Cl = iso->LastParameter();
1467 if (Precision::IsInfinite(Cf)) Cf = -1000;
1468 if (Precision::IsInfinite(Cl)) Cl = +1000;
65bb82f2 1469 dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
7fd59977 1470 if (dist < theMin) {
1471 theMin = dist;
1472 if (UV) VV = other; else UU = other;
1473 }
1474 }
1475 UV = !UV;
65bb82f2 1476 if (UV) { par = UU; iso = UIso(UU); }
1477 else { par = VV; iso = VIso(VV); }
1478 if (!iso.IsNull()) {
7fd59977 1479 Cf = iso->FirstParameter();
1480 Cl = iso->LastParameter();
1481 if (Precision::IsInfinite(Cf)) Cf = -1000;
1482 if (Precision::IsInfinite(Cl)) Cl = +1000;
65bb82f2 1483 dist = ShapeAnalysis_Curve().Project(iso, P3d, preci, pntres, other, Cf, Cl, Standard_False);
7fd59977 1484 if (dist < theMin) {
1485 theMin = dist;
1486 if (UV) VV = other; else UU = other;
1487 }
1488 }
1489 UV = !UV;
1490 Iters++;
1491 }
1492 }
1493
1494 else {
1495 while (((PrevU != UU) || (PrevV != VV)) && (Iters < MaxIters) && (theMin > preci)) {
1496 PrevU = UU; PrevV = VV;
1497 if (UV) {
1498 par = UU;
65bb82f2 1499 anIsoCurve.Load(GeomAbs_IsoU, UU);
7fd59977 1500 }
1501 else {
1502 par = VV;
65bb82f2 1503 anIsoCurve.Load(GeomAbs_IsoV, VV);
7fd59977 1504 }
1505 Cf = anIsoCurve.FirstParameter();
1506 Cl = anIsoCurve.LastParameter();
1507 if (Precision::IsInfinite(Cf)) Cf = -1000;
1508 if (Precision::IsInfinite(Cl)) Cl = +1000;
1509 dist = ShapeAnalysis_Curve().Project(anIsoCurve, P3d, preci, pntres, other);
1510 if (dist < theMin) {
1511 theMin = dist;
1512 if (UV) VV = other; else UU = other;
1513 }
1514 UV = !UV;
65bb82f2 1515 if (UV) {
1516 par = UU;
1517 anIsoCurve.Load(GeomAbs_IsoU, UU);
1518 }
1519 else {
1520 par = VV;
1521 anIsoCurve.Load(GeomAbs_IsoV, VV);
1522 }
7fd59977 1523 Cf = anIsoCurve.FirstParameter();
1524 Cl = anIsoCurve.LastParameter();
1525 if (Precision::IsInfinite(Cf)) Cf = -1000;
1526 if (Precision::IsInfinite(Cl)) Cl = +1000;
65bb82f2 1527 dist = ShapeAnalysis_Curve().ProjectAct(anIsoCurve, P3d, preci, pntres, other);
7fd59977 1528 if (dist < theMin) {
1529 theMin = dist;
1530 if (UV) VV = other; else UU = other;
1531 }
1532 UV = !UV;
1533 Iters++;
1534 }
1535 }
1536
1537 U = UU; V = VV;
1538
1539 } // fin try RAJOUT
65bb82f2 1540 catch (Standard_Failure const& anException) {
9775fa61 1541#ifdef OCCT_DEBUG
65bb82f2 1542 //:s5
1543 cout << "\nWarning: ShapeAnalysis_Curve::UVFromIso(): Exception: ";
9775fa61 1544 anException.Print(cout); cout << endl;
7fd59977 1545#endif
9775fa61 1546 (void)anException;
1547 theMin = RealLast(); // theMin de depart
7fd59977 1548 }
1549 return theMin;
1550}
1551
1552
1553//=======================================================================
1554//function : SortSingularities
1555//purpose :
1556//=======================================================================
1557
1558void ShapeAnalysis_Surface::SortSingularities()
1559{
1560 for (Standard_Integer i = 0; i < myNbDeg - 1; i++) {
1561 Standard_Real minPreci = myPreci[i];
1562 Standard_Integer minIndex = i;
1563 for (Standard_Integer j = i + 1; j < myNbDeg; j++)
1564 if (minPreci > myPreci[j]) { minPreci = myPreci[j]; minIndex = j; }
1565 if (minIndex != i) {
1566 myPreci[minIndex] = myPreci[i]; myPreci[i] = minPreci;
1567 gp_Pnt tmpP3d = myP3d[minIndex];
1568 myP3d[minIndex] = myP3d[i]; myP3d[i] = tmpP3d;
1569 gp_Pnt2d tmpP2d = myFirstP2d[minIndex];
1570 myFirstP2d[minIndex] = myFirstP2d[i]; myFirstP2d[i] = tmpP2d;
1571 tmpP2d = myLastP2d[minIndex]; myLastP2d[minIndex] = myLastP2d[i]; myLastP2d[i] = tmpP2d;
1572 Standard_Real tmpPar = myFirstPar[minIndex];
1573 myFirstPar[minIndex] = myFirstPar[i]; myFirstPar[i] = tmpPar;
1574 tmpPar = myLastPar[minIndex]; myLastPar[minIndex] = myLastPar[i]; myLastPar[i] = tmpPar;
1575 Standard_Boolean tmpUIsoDeg = myUIsoDeg[minIndex];
65bb82f2 1576 myUIsoDeg[minIndex] = myUIsoDeg[i]; myUIsoDeg[i] = tmpUIsoDeg;
7fd59977 1577 }
65bb82f2 1578 }
7fd59977 1579}
1580
1581
1582//=======================================================================
1583//function : SetDomain
1584//purpose :
1585//=======================================================================
1586
1587void ShapeAnalysis_Surface::SetDomain(const Standard_Real U1,
65bb82f2 1588 const Standard_Real U2,
1589 const Standard_Real V1,
1590 const Standard_Real V2)
7fd59977 1591{
1592 myUF = U1;
1593 myUL = U2;
1594 myVF = V1;
1595 myVL = V2;
1596}
1597
1598
1599void ShapeAnalysis_Surface::ComputeBoxes()
1600{
65bb82f2 1601 if (myIsoBoxes) return;
7fd59977 1602 myIsoBoxes = Standard_True;
1603 ComputeBoundIsos();
65bb82f2 1604 if (!myIsoUF.IsNull())
1605 BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoUF), Precision::Confusion(), myBndUF);
1606 if (!myIsoUL.IsNull())
1607 BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoUL), Precision::Confusion(), myBndUL);
1608 if (!myIsoVF.IsNull())
1609 BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoVF), Precision::Confusion(), myBndVF);
1610 if (!myIsoVL.IsNull())
1611 BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoVL), Precision::Confusion(), myBndVL);
7fd59977 1612}
1613
65bb82f2 1614const Bnd_Box& ShapeAnalysis_Surface::GetBoxUF()
7fd59977 1615{
1616 ComputeBoxes();
1617 return myBndUF;
1618}
1619
65bb82f2 1620const Bnd_Box& ShapeAnalysis_Surface::GetBoxUL()
7fd59977 1621{
1622 ComputeBoxes();
1623 return myBndUL;
1624}
1625
65bb82f2 1626const Bnd_Box& ShapeAnalysis_Surface::GetBoxVF()
7fd59977 1627{
1628 ComputeBoxes();
1629 return myBndVF;
1630}
1631
65bb82f2 1632const Bnd_Box& ShapeAnalysis_Surface::GetBoxVL()
7fd59977 1633{
1634 ComputeBoxes();
1635 return myBndVL;
1636}