Commit | Line | Data |
---|---|---|
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 | 61 | IMPLEMENT_STANDARD_RTTIEXT(ShapeAnalysis_Surface,Standard_Transient) |
92efcf78 | 62 | |
42cf5bc1 | 63 | //S4135 |
64 | //S4135 | |
7fd59977 | 65 | //======================================================================= |
66 | //function : ShapeAnalysis_Surface | |
67 | //purpose : | |
68 | //======================================================================= | |
7fd59977 | 69 | ShapeAnalysis_Surface::ShapeAnalysis_Surface(const Handle(Geom_Surface)& S) : |
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) | |
76 | { | |
84eca96b | 77 | mySurf->Bounds(myUF,myUL,myVF,myVL); |
78 | myAdSur = new GeomAdaptor_HSurface (mySurf); | |
7fd59977 | 79 | } |
80 | ||
81 | //======================================================================= | |
82 | //function : Init | |
83 | //purpose : | |
84 | //======================================================================= | |
85 | ||
86 | void 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.; | |
93 | mySurf->Bounds (myUF,myUL,myVF,myVL); | |
84eca96b | 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 | ||
105 | void ShapeAnalysis_Surface::Init(const Handle(ShapeAnalysis_Surface)& other) | |
106 | { | |
107 | Init (other->Surface()); | |
108 | myAdSur = other->TrueAdaptor3d(); | |
109 | myNbDeg = other->myNbDeg; //rln S4135 direct transmission (to avoid computation in <other>) | |
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]); | |
112 | } | |
113 | } | |
114 | ||
115 | //======================================================================= | |
116 | //function : Adaptor3d | |
117 | //purpose : | |
118 | //======================================================================= | |
119 | ||
120 | const Handle(GeomAdaptor_HSurface)& ShapeAnalysis_Surface::Adaptor3d() | |
121 | { | |
7fd59977 | 122 | return myAdSur; |
123 | } | |
124 | ||
125 | //======================================================================= | |
126 | //function : ComputeSingularities | |
127 | //purpose : | |
128 | //======================================================================= | |
129 | ||
130 | void ShapeAnalysis_Surface::ComputeSingularities() | |
131 | { | |
132 | //rln S4135 | |
133 | if (myNbDeg >= 0) return; | |
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 | |
136 | if (mySurf.IsNull()) return; | |
137 | ||
138 | Standard_Real su1, sv1, su2, sv2; | |
139 | // mySurf->Bounds(su1, su2, sv1, sv2); | |
140 | Bounds(su1, su2, sv1, sv2);//modified by rln on 12/11/97 mySurf-> is deleted | |
141 | ||
142 | myNbDeg = 0; //:r3 | |
143 | ||
144 | if (mySurf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) { | |
145 | Handle(Geom_ConicalSurface) conicS = | |
146 | Handle(Geom_ConicalSurface)::DownCast(mySurf); | |
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); | |
152 | myFirstPar[0] = su1; | |
153 | myLastPar [0] = su2; | |
154 | myUIsoDeg [0] = Standard_False; | |
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 | |
163 | Standard_Real Ang = ACos (Min (1., majorR / minorR)); | |
164 | myPreci [0] = myPreci[1] = Max (0., majorR - minorR); | |
c6541a0c D |
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; |
172 | myLastPar [0] = myLastPar [1] = su2; | |
173 | myUIsoDeg [0] = myUIsoDeg [1] = Standard_False; | |
174 | myNbDeg = ( majorR > minorR ? 1 : 2 ); | |
175 | } | |
176 | else if (mySurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) { | |
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); | |
184 | myFirstPar[0] = myFirstPar[1] = su1; | |
185 | myLastPar [0] = myLastPar [1] = su2; | |
186 | myUIsoDeg [0] = myUIsoDeg [1] = Standard_False; | |
187 | myNbDeg = 2; | |
188 | } | |
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 | |
84eca96b | 194 | myP3d [0] = myAdSur->Value (su1, 0.5 * (sv1 + sv2)); |
7fd59977 | 195 | myFirstP2d[0].SetCoord (su1, sv2); |
196 | myLastP2d [0].SetCoord (su1, sv1); | |
197 | ||
84eca96b | 198 | myP3d [1] = myAdSur->Value (su2, 0.5 * (sv1 + sv2)); |
7fd59977 | 199 | myFirstP2d[1].SetCoord (su2, sv1); |
200 | myLastP2d [1].SetCoord (su2, sv2); | |
201 | ||
84eca96b | 202 | myP3d [2] = myAdSur->Value (0.5 * (su1 + su2), sv1); |
7fd59977 | 203 | myFirstP2d[2].SetCoord (su1, sv1); |
204 | myLastP2d [2].SetCoord (su2, sv1); | |
205 | ||
84eca96b | 206 | myP3d [3] = myAdSur->Value (0.5 * (su1 + su2), sv2); |
7fd59977 | 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 | ||
84eca96b | 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); | |
7fd59977 | 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))); | |
227 | ||
228 | myNbDeg = 4; | |
229 | } | |
230 | SortSingularities(); | |
231 | } | |
232 | ||
233 | //======================================================================= | |
234 | //function : HasSingularities | |
235 | //purpose : | |
236 | //======================================================================= | |
237 | ||
238 | Standard_Boolean ShapeAnalysis_Surface::HasSingularities (const Standard_Real preci) | |
239 | { | |
240 | return NbSingularities(preci) > 0; | |
241 | } | |
242 | ||
243 | //======================================================================= | |
244 | //function : NbSingularities | |
245 | //purpose : | |
246 | //======================================================================= | |
247 | ||
248 | Standard_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++) | |
253 | if (myPreci[i-1] <= preci) | |
254 | Nb++; | |
255 | return Nb; | |
256 | } | |
257 | ||
258 | //======================================================================= | |
259 | //function : Singularity | |
260 | //purpose : | |
261 | //======================================================================= | |
262 | ||
263 | Standard_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) | |
271 | { | |
272 | // ATTENTION, les champs sont des tableaux C, n0s partent de 0. num part de 1 | |
273 | if (myNbDeg < 0) ComputeSingularities(); | |
274 | if (num < 1 || num > myNbDeg) return Standard_False; | |
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]; | |
282 | return Standard_True; | |
283 | } | |
284 | ||
285 | //======================================================================= | |
286 | //function : IsDegenerated | |
287 | //purpose : | |
288 | //======================================================================= | |
289 | ||
290 | Standard_Boolean ShapeAnalysis_Surface::IsDegenerated(const gp_Pnt& P3d,const Standard_Real preci) | |
291 | { | |
292 | if (myNbDeg < 0) ComputeSingularities (); | |
293 | for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i ++) { | |
294 | myGap = myP3d[i].Distance (P3d); | |
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 | ||
307 | Standard_Boolean ShapeAnalysis_Surface::DegeneratedValues(const gp_Pnt& P3d, | |
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*/) | |
314 | { | |
315 | if (myNbDeg < 0) ComputeSingularities (); | |
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(); | |
319 | for (Standard_Integer i = 0; i < myNbDeg && myPreci[i] <= preci; i ++) { | |
320 | myGap = myP3d[i].Distance (P3d); | |
321 | //rln S4135 | |
322 | if (myGap <= preci) | |
323 | if (gapMin > myGap) { | |
324 | gapMin = myGap; | |
325 | indMin = i; | |
326 | } | |
327 | } | |
328 | if (indMin >= 0) { | |
329 | myGap = gapMin; | |
330 | firstP2d = myFirstP2d[indMin]; | |
331 | lastP2d = myLastP2d[indMin]; | |
332 | firstPar = myFirstPar[indMin]; | |
333 | lastPar = myLastPar[indMin]; | |
334 | return Standard_True; | |
335 | } | |
336 | return Standard_False; | |
337 | } | |
338 | ||
339 | //======================================================================= | |
340 | //function : ProjectDegenerated | |
341 | //purpose : | |
342 | //======================================================================= | |
343 | ||
344 | Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const gp_Pnt& P3d, | |
345 | const Standard_Real preci, | |
346 | const gp_Pnt2d& neighbour, | |
347 | gp_Pnt2d& result) | |
348 | { | |
349 | if (myNbDeg < 0) ComputeSingularities (); | |
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(); | |
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) ) ); | |
359 | //rln S4135 | |
360 | if ( gap2 <= preci*preci && gapMin > gap2 ) { | |
361 | gapMin = gap2; | |
362 | indMin = i; | |
363 | } | |
364 | } | |
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()); | |
369 | return Standard_True; | |
370 | } | |
371 | ||
372 | //pdn %12 11.02.99 PRO9234 entity 15402 | |
373 | //======================================================================= | |
374 | //function : ProjectDegenerated | |
375 | //purpose : | |
376 | //======================================================================= | |
377 | ||
378 | Standard_Boolean ShapeAnalysis_Surface::ProjectDegenerated(const Standard_Integer nbrPnt, | |
2c26a53d | 379 | const TColgp_SequenceOfPnt& points, |
380 | TColgp_SequenceOfPnt2d& pnt2d, | |
7fd59977 | 381 | const Standard_Real preci, |
382 | const Standard_Boolean direct) | |
383 | { | |
384 | if (myNbDeg < 0) ComputeSingularities (); | |
385 | ||
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); | |
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 ) { | |
396 | gapMin = gap2; | |
397 | indMin = i; | |
398 | } | |
399 | } | |
400 | if ( indMin <0 ) return Standard_False; | |
401 | ||
402 | myGap = Sqrt ( gapMin ); | |
403 | gp_Pnt2d pk; | |
404 | ||
405 | Standard_Integer k; // svv Jan11 2000 : porting on DEC | |
406 | for ( k=j+step; k <= nbrPnt && k >= 1; k += step ) { | |
407 | pk = pnt2d(k); | |
408 | gp_Pnt P1 = points(k); | |
409 | if ( myP3d[indMin].SquareDistance(P1) > prec2 && | |
410 | myP3d[indMin].SquareDistance(Value(pk)) > prec2 ) | |
411 | break; | |
412 | } | |
413 | ||
414 | //:p8 abv 11 Mar 99: PRO7226 #489490: if whole pcurve is degenerate, distribute evenly | |
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++ ) { | |
419 | //szv#4:S4163:12Mar99 warning - possible div by zero | |
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 ); | |
423 | } | |
424 | return Standard_True; | |
425 | } | |
426 | ||
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()); | |
430 | } | |
431 | return Standard_True; | |
432 | } | |
433 | ||
434 | //======================================================================= | |
435 | //method : IsDegenerated | |
436 | //purpose: | |
437 | //======================================================================= | |
438 | ||
439 | Standard_Boolean ShapeAnalysis_Surface::IsDegenerated (const gp_Pnt2d &p2d1, | |
440 | const gp_Pnt2d &p2d2, | |
441 | const Standard_Real tol, | |
442 | const Standard_Real ratio) | |
443 | { | |
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; | |
450 | ||
451 | GeomAdaptor_Surface& SA = Adaptor3d()->ChangeSurface(); | |
452 | Standard_Real RU = SA.UResolution ( 1. ); | |
453 | Standard_Real RV = SA.VResolution ( 1. ); | |
454 | ||
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; | |
458 | max3d *= ratio; | |
459 | return du * du + dv * dv > max3d * max3d; | |
460 | } | |
461 | ||
462 | //======================================================================= | |
463 | //static : ComputeIso | |
464 | //purpose : | |
465 | //======================================================================= | |
466 | ||
467 | static Handle(Geom_Curve) ComputeIso | |
468 | (const Handle(Geom_Surface)& surf, | |
469 | const Standard_Boolean utype, const Standard_Real par) | |
470 | { | |
471 | Handle(Geom_Curve) iso; | |
472 | try { | |
473 | OCC_CATCH_SIGNALS | |
474 | if (utype) iso = surf->UIso (par); | |
475 | else iso = surf->VIso (par); | |
476 | } | |
9775fa61 | 477 | catch(Standard_Failure const& anException) { |
478 | #ifdef OCCT_DEBUG | |
479 | //:s5 | |
7fd59977 | 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 | ||
494 | void ShapeAnalysis_Surface::ComputeBoundIsos() | |
495 | { | |
496 | if (myIsos) return; | |
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); | |
502 | } | |
503 | ||
504 | //======================================================================= | |
505 | //function : UIso | |
506 | //purpose : | |
507 | //======================================================================= | |
508 | ||
509 | Handle(Geom_Curve) ShapeAnalysis_Surface::UIso(const Standard_Real U) | |
510 | { | |
511 | if (U == myUF) { ComputeBoundIsos(); return myIsoUF; } | |
512 | if (U == myUL) { ComputeBoundIsos(); return myIsoUL; } | |
513 | return ComputeIso (mySurf,Standard_True, U); | |
514 | } | |
515 | ||
516 | //======================================================================= | |
517 | //function : VIso | |
518 | //purpose : | |
519 | //======================================================================= | |
520 | ||
521 | Handle(Geom_Curve) ShapeAnalysis_Surface::VIso(const Standard_Real V) | |
522 | { | |
523 | if (V == myVF) { ComputeBoundIsos(); return myIsoVF; } | |
524 | if (V == myVL) { ComputeBoundIsos(); return myIsoVL; } | |
525 | return ComputeIso (mySurf,Standard_False,V); | |
526 | } | |
527 | ||
528 | //======================================================================= | |
529 | //function : IsUClosed | |
530 | //purpose : | |
531 | //======================================================================= | |
532 | ||
533 | Standard_Boolean ShapeAnalysis_Surface::IsUClosed(const Standard_Real preci) | |
534 | { | |
535 | Standard_Real prec = Max (preci, Precision::Confusion()); | |
536 | if (myUCloseVal < 0) { | |
537 | // Faut calculer : calculs minimaux | |
538 | Standard_Real uf,ul,vf,vl; | |
539 | Bounds (uf,ul,vf,vl);//modified by rln on 12/11/97 mySurf-> is deleted | |
540 | // mySurf->Bounds (uf,ul,vf,vl); | |
541 | if (Precision::IsInfinite (uf) || Precision::IsInfinite (ul)) myUDelt = 0.; | |
542 | else myUDelt = Abs (ul-uf) / 20;//modified by rln 11/11/97 instead of 10 | |
543 | //because of the example when 10 was not enough | |
544 | if (mySurf->IsUClosed()) { myUCloseVal = 0.; myUDelt = 0.; myGap = 0.; return Standard_True; } | |
545 | ||
546 | // Calculs adaptes | |
547 | //#67 rln S4135 | |
548 | GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); | |
549 | GeomAbs_SurfaceType surftype = SurfAdapt.GetType(); | |
550 | if (mySurf->IsKind (STANDARD_TYPE (Geom_RectangularTrimmedSurface))) | |
551 | surftype = GeomAbs_OtherSurface; | |
552 | ||
553 | switch (surftype) { | |
554 | case GeomAbs_Plane: { | |
555 | myUCloseVal = RealLast(); | |
556 | break; | |
557 | } | |
558 | case GeomAbs_SurfaceOfExtrusion: { //:c8 abv 03 Mar 98: UKI60094 #753: process Geom_SurfaceOfLinearExtrusion | |
559 | Handle(Geom_SurfaceOfLinearExtrusion) extr = | |
560 | Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(mySurf); | |
561 | Handle(Geom_Curve) crv = extr->BasisCurve(); | |
562 | Standard_Real f = crv->FirstParameter(); | |
563 | Standard_Real l = crv->LastParameter(); | |
564 | //:r3 abv (smh) 30 Mar 99: protect against unexpected signals | |
565 | if ( ! Precision::IsInfinite ( f ) && ! Precision::IsInfinite ( l ) ) { | |
566 | gp_Pnt p1 = crv->Value ( f ); | |
567 | gp_Pnt p2 = crv->Value ( l ); | |
568 | myUCloseVal = p1.Distance ( p2 ); | |
569 | } | |
570 | else myUCloseVal = RealLast(); | |
571 | break; | |
572 | } | |
573 | case GeomAbs_BSplineSurface: { | |
574 | Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf); | |
575 | Standard_Integer nbup = bs->NbUPoles(); | |
576 | Standard_Real distmin = RealLast(); | |
577 | if (bs->IsUPeriodic()) { | |
578 | myUCloseVal = 0; | |
579 | myUDelt = 0; | |
580 | } | |
581 | else if (nbup < 3) {//modified by rln on 12/11/97 | |
582 | myUCloseVal = RealLast(); | |
583 | } | |
584 | else if (bs->IsURational() || | |
585 | //#6 rln 20/02/98 ProSTEP ug_exhaust-A.stp entity #18360 (Uclosed BSpline, | |
586 | //but multiplicity of boundary knots != degree + 1) | |
587 | bs->UMultiplicity(1) != bs->UDegree()+1 || //#6 //:h4: #6 moved | |
588 | bs->UMultiplicity(bs->NbUKnots()) != bs->UDegree()+1 ) { //#6 //:h4 | |
589 | Standard_Integer nbvk = bs->NbVKnots(); | |
590 | for (Standard_Integer i = 1; i <= nbvk; i ++) { | |
591 | Standard_Real v = bs->VKnot(i); | |
84eca96b | 592 | gp_Pnt p1 = SurfAdapt.Value (uf, v); |
593 | gp_Pnt p2 = SurfAdapt.Value (ul, v); | |
7fd59977 | 594 | myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2)); |
595 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
596 | if (i > 1) { | |
597 | v = 0.5 * (bs->VKnot(i-1) + bs->VKnot(i)); | |
598 | p1 = bs->Value (uf, v); | |
599 | p2 = bs->Value (ul, v); | |
600 | myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2)); | |
601 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
602 | } | |
603 | } | |
604 | myUCloseVal = Sqrt (myUCloseVal); | |
605 | distmin = Sqrt (distmin); | |
606 | myUDelt = Min (myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh | |
607 | } | |
608 | else { | |
609 | Standard_Integer nbvp = bs->NbVPoles(); | |
610 | for (Standard_Integer i = 1; i <= nbvp; i ++) { | |
611 | myUCloseVal = Max (myUCloseVal, bs->Pole(1,i).SquareDistance(bs->Pole(nbup,i))); | |
612 | distmin = Min (distmin, bs->Pole(1,i).SquareDistance(bs->Pole(nbup,i))); | |
613 | } | |
614 | myUCloseVal = Sqrt (myUCloseVal); | |
615 | distmin = Sqrt (distmin); | |
616 | myUDelt = Min (myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh | |
617 | } | |
618 | break; | |
619 | } | |
620 | case GeomAbs_BezierSurface: { | |
621 | Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf); | |
622 | Standard_Integer nbup = bz->NbUPoles(); | |
623 | Standard_Real distmin = RealLast(); | |
624 | if (nbup < 3) | |
625 | myUCloseVal = RealLast(); | |
626 | else { | |
627 | Standard_Integer nbvp = bz->NbVPoles(); | |
628 | for (Standard_Integer i = 1; i <= nbvp; i ++) { | |
629 | myUCloseVal = Max (myUCloseVal, bz->Pole(1,i).SquareDistance(bz->Pole(nbup,i))); | |
630 | distmin = Min (distmin, bz->Pole(1,i).SquareDistance(bz->Pole(nbup,i))); | |
631 | } | |
632 | myUCloseVal = Sqrt (myUCloseVal); | |
633 | distmin = Sqrt (distmin); | |
634 | myUDelt = Min (myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh | |
635 | } | |
636 | break; | |
637 | } | |
638 | default: { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface | |
639 | Standard_Real distmin = RealLast(); | |
640 | Standard_Integer nbpoints = 101; //can be revised | |
641 | for (Standard_Integer i = 0; i < nbpoints; i++) { | |
84eca96b | 642 | gp_Pnt p1 = SurfAdapt.Value (uf, vf + (vl - vf ) * i / (nbpoints - 1)); |
643 | gp_Pnt p2 = SurfAdapt.Value (ul, vf + (vl - vf ) * i / (nbpoints - 1)); | |
7fd59977 | 644 | myUCloseVal = Max (myUCloseVal, p1.SquareDistance (p2)); |
645 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
646 | } | |
647 | myUCloseVal = Sqrt (myUCloseVal); | |
648 | distmin = Sqrt (distmin); | |
649 | myUDelt = Min (myUDelt, 0.5 * SurfAdapt.UResolution(distmin)); //#4 smh | |
650 | break; | |
651 | } | |
652 | } //switch | |
653 | myGap = myUCloseVal; | |
654 | } | |
655 | return (myUCloseVal <= prec); | |
656 | } | |
657 | ||
658 | //======================================================================= | |
659 | //function : IsVClosed | |
660 | //purpose : | |
661 | //======================================================================= | |
662 | ||
663 | Standard_Boolean ShapeAnalysis_Surface::IsVClosed(const Standard_Real preci) | |
664 | { | |
665 | Standard_Real prec = Max (preci, Precision::Confusion()); | |
666 | if (myVCloseVal < 0) { | |
667 | // Faut calculer : calculs minimaux | |
668 | Standard_Real uf,ul,vf,vl; | |
669 | Bounds (uf,ul,vf,vl);//modified by rln on 12/11/97 mySurf-> is deleted | |
670 | // mySurf->Bounds (uf,ul,vf,vl); | |
671 | if (Precision::IsInfinite (vf) || Precision::IsInfinite (vl)) myVDelt = 0.; | |
672 | else myVDelt = Abs (vl-vf) / 20;// 2; rln S4135 | |
673 | //because of the example when 10 was not enough | |
674 | if (mySurf->IsVClosed()) { myVCloseVal = 0.; myVDelt = 0.; myGap = 0.; return Standard_True; } | |
675 | ||
676 | // Calculs adaptes | |
677 | //#67 rln S4135 | |
678 | GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); | |
679 | GeomAbs_SurfaceType surftype = SurfAdapt.GetType(); | |
680 | if (mySurf->IsKind (STANDARD_TYPE (Geom_RectangularTrimmedSurface))) | |
681 | surftype = GeomAbs_OtherSurface; | |
682 | ||
683 | switch (surftype) { | |
684 | case GeomAbs_Plane: | |
685 | case GeomAbs_Cone: | |
686 | case GeomAbs_Cylinder: | |
687 | case GeomAbs_Sphere: | |
688 | case GeomAbs_SurfaceOfExtrusion: { | |
689 | myVCloseVal = RealLast(); | |
690 | break; | |
691 | } | |
692 | case GeomAbs_SurfaceOfRevolution: { | |
693 | Handle(Geom_SurfaceOfRevolution) revol = | |
694 | Handle(Geom_SurfaceOfRevolution)::DownCast(mySurf); | |
695 | Handle(Geom_Curve) crv = revol->BasisCurve(); | |
696 | gp_Pnt p1 = crv->Value ( crv->FirstParameter() ); | |
697 | gp_Pnt p2 = crv->Value ( crv->LastParameter() ); | |
698 | myVCloseVal = p1.Distance ( p2 ); | |
699 | break; | |
700 | } | |
701 | case GeomAbs_BSplineSurface: { | |
702 | Handle(Geom_BSplineSurface) bs = Handle(Geom_BSplineSurface)::DownCast(mySurf); | |
703 | Standard_Integer nbvp = bs->NbVPoles(); | |
704 | Standard_Real distmin = RealLast(); | |
705 | if (bs->IsVPeriodic()) { | |
706 | myVCloseVal = 0; | |
707 | myVDelt = 0; | |
708 | } | |
709 | else if (nbvp < 3) {//modified by rln on 12/11/97 | |
710 | myVCloseVal = RealLast(); | |
711 | } | |
712 | else if (bs->IsVRational() || | |
713 | bs->VMultiplicity(1) != bs->VDegree()+1 || //#6 //:h4 | |
714 | bs->VMultiplicity(bs->NbVKnots()) != bs->VDegree()+1 ) { //#6 //:h4 | |
715 | Standard_Integer nbuk = bs->NbUKnots(); | |
716 | for (Standard_Integer i = 1; i <= nbuk; i ++) { | |
717 | Standard_Real u = bs->UKnot(i); | |
84eca96b | 718 | gp_Pnt p1 = SurfAdapt.Value (u, vf); |
719 | gp_Pnt p2 = SurfAdapt.Value (u, vl); | |
7fd59977 | 720 | myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2)); |
721 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
722 | if (i > 1) { | |
723 | u = 0.5 * (bs->UKnot(i-1) + bs->UKnot(i)); | |
84eca96b | 724 | p1 = SurfAdapt.Value (u, vf); |
725 | p2 = SurfAdapt.Value (u, vl); | |
7fd59977 | 726 | myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2)); |
727 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
728 | } | |
729 | } | |
730 | myVCloseVal = Sqrt (myVCloseVal); | |
731 | distmin = Sqrt (distmin); | |
732 | myVDelt = Min (myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh | |
733 | } | |
734 | else { | |
735 | Standard_Integer nbup = bs->NbUPoles(); | |
736 | for (Standard_Integer i = 1; i <= nbup; i ++) { | |
737 | myVCloseVal = Max (myVCloseVal, bs->Pole(i,1).SquareDistance(bs->Pole(i,nbvp))); | |
738 | distmin = Min (distmin, bs->Pole(i,1).SquareDistance(bs->Pole(i,nbvp))); | |
739 | } | |
740 | myVCloseVal = Sqrt (myVCloseVal); | |
741 | distmin = Sqrt (distmin); | |
742 | myVDelt = Min (myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh | |
743 | } | |
744 | break; | |
745 | } | |
746 | case GeomAbs_BezierSurface: { | |
747 | Handle(Geom_BezierSurface) bz = Handle(Geom_BezierSurface)::DownCast(mySurf); | |
748 | Standard_Integer nbvp = bz->NbVPoles(); | |
749 | Standard_Real distmin = RealLast(); | |
750 | if (nbvp < 3) | |
751 | myVCloseVal = RealLast(); | |
752 | else { | |
753 | Standard_Integer nbup = bz->NbUPoles(); | |
754 | for (Standard_Integer i = 1; i <= nbup; i ++) { | |
755 | myVCloseVal = Max (myVCloseVal, bz->Pole(i,1).SquareDistance(bz->Pole(i,nbvp))); | |
756 | distmin = Min (distmin, bz->Pole(i,1).SquareDistance(bz->Pole(i,nbvp))); | |
757 | } | |
758 | myVCloseVal = Sqrt (myVCloseVal); | |
759 | distmin = Sqrt (distmin); | |
760 | myVDelt = Min (myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh | |
761 | } | |
762 | break; | |
763 | } | |
764 | default: { //Geom_RectangularTrimmedSurface and Geom_OffsetSurface | |
765 | Standard_Real distmin = RealLast(); | |
766 | Standard_Integer nbpoints = 101; //can be revised | |
767 | for (Standard_Integer i = 0; i < nbpoints; i++) { | |
84eca96b | 768 | gp_Pnt p1 = SurfAdapt.Value (uf + (ul - uf ) * i / (nbpoints - 1), vf); |
769 | gp_Pnt p2 = SurfAdapt.Value (uf + (ul - uf ) * i / (nbpoints - 1), vl); | |
7fd59977 | 770 | myVCloseVal = Max (myVCloseVal, p1.SquareDistance (p2)); |
771 | distmin = Min (distmin, p1.SquareDistance (p2)); | |
772 | } | |
773 | myVCloseVal = Sqrt (myVCloseVal); | |
774 | distmin = Sqrt (distmin); | |
775 | myVDelt = Min (myVDelt, 0.5 * SurfAdapt.VResolution(distmin)); //#4 smh | |
776 | break; | |
777 | } | |
778 | } //switch | |
779 | myGap = myVCloseVal; | |
780 | } | |
781 | return (myVCloseVal <= prec); | |
782 | } | |
783 | ||
784 | //======================================================================= | |
785 | //function : SurfaceNewton | |
786 | //purpose : Newton algo (S4030) | |
787 | //======================================================================= | |
dde68833 | 788 | Standard_Integer ShapeAnalysis_Surface::SurfaceNewton(const gp_Pnt2d &p2dPrev, |
7fd59977 | 789 | const gp_Pnt& P3D, |
790 | const Standard_Real preci, | |
791 | gp_Pnt2d &sol) | |
792 | { | |
793 | GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); | |
794 | Standard_Real uf, ul, vf, vl; | |
795 | Bounds(uf, ul, vf, vl); | |
796 | Standard_Real du = SurfAdapt.UResolution (preci); | |
797 | Standard_Real dv = SurfAdapt.VResolution (preci); | |
798 | Standard_Real UF = uf - du, UL = ul + du; | |
799 | Standard_Real VF = vf - dv, VL = vl + dv; | |
800 | ||
801 | //Standard_Integer fail = 0; | |
802 | Standard_Real Tol = Precision::Confusion(); | |
803 | Standard_Real Tol2 = Tol * Tol;//, rs2p=1e10; | |
804 | Standard_Real U = p2dPrev.X(), V = p2dPrev.Y(); | |
805 | gp_Vec rsfirst = P3D.XYZ() - Value ( U, V ).XYZ(); //pdn | |
806 | for ( Standard_Integer i=0; i < 25; i++ ) { | |
807 | gp_Vec ru, rv, ruu, rvv, ruv; | |
808 | gp_Pnt pnt; | |
84eca96b | 809 | SurfAdapt.D2 ( U, V, pnt, ru, rv, ruu, rvv, ruv ); |
7fd59977 | 810 | |
811 | // normal | |
812 | Standard_Real ru2 = ru * ru, rv2 = rv * rv; | |
813 | gp_Vec n = ru ^ rv; | |
814 | Standard_Real nrm2 = n.SquareMagnitude(); | |
f4dee9bb | 815 | if ( nrm2 < 1e-10 || Precision::IsPositiveInfinite(nrm2)) break; // n == 0, use standard |
7fd59977 | 816 | |
817 | // descriminant | |
818 | gp_Vec rs = P3D.XYZ() - Value ( U, V ).XYZ(); | |
819 | Standard_Real rSuu = ( rs * ruu ); | |
820 | Standard_Real rSvv = ( rs * rvv ); | |
821 | Standard_Real rSuv = ( rs * ruv ); | |
822 | Standard_Real D = -nrm2 + rv2 * rSuu + ru2 * rSvv - | |
823 | 2 * rSuv * (ru*rv) + rSuv*rSuv - rSuu*rSvv; | |
824 | if ( fabs ( D ) < 1e-10 ) break; // bad case; use standard | |
825 | ||
826 | // compute step | |
827 | Standard_Real fract = 1. / D; | |
828 | du = ( rs * ( ( n ^ rv ) + ru * rSvv - rv * rSuv ) ) * fract; | |
829 | dv = ( rs * ( ( ru ^ n ) + rv * rSuu - ru * rSuv ) ) * fract; | |
830 | U += du; | |
831 | V += dv; | |
2e9fd4bc | 832 | if ( U < UF || U > UL || V < VF || V > VL ) break; |
7fd59977 | 833 | // check that iterations do not diverge |
834 | //pdn Standard_Real rs2 = rs.SquareMagnitude(); | |
835 | // if ( rs2 > 4.*rs2p ) break; | |
836 | // rs2p = rs2; | |
837 | ||
838 | // test the step by uv and deviation from the solution | |
839 | Standard_Real aResolution = Max(1e-12,(U+V)*10e-16); | |
840 | if ( fabs ( du ) + fabs ( dv ) > aResolution ) continue; //Precision::PConfusion() continue; | |
841 | ||
2e9fd4bc | 842 | //if ( U < UF || U > UL || V < VF || V > VL ) break; |
7fd59977 | 843 | |
844 | //pdn PRO10109 4517: protect against wrong result | |
845 | Standard_Real rs2 = rs.SquareMagnitude(); | |
846 | if ( rs2 > rsfirst.SquareMagnitude() ) break; | |
847 | ||
848 | Standard_Real rsn = rs * n; | |
849 | if ( rs2 - rsn * rsn / nrm2 > Tol2 ) break; | |
850 | ||
851 | // if ( rs2 > 100 * preci * preci ) { fail = 6; break; } | |
852 | ||
853 | // OK, return the result | |
854 | // cout << "Newton: solution found in " << i+1 << " iterations" << endl; | |
855 | sol.SetCoord( U, V ); | |
856 | ||
dde68833 | 857 | return ( nrm2 < 0.01 * ru2 * rv2 ? 2 : 1 ); //:q6 |
7fd59977 | 858 | } |
859 | // cout << "Newton: failed after " << i+1 << " iterations (fail " << fail << " )" << endl; | |
860 | return Standard_False; | |
861 | } | |
862 | ||
863 | //======================================================================= | |
864 | //function : NextValueOfUV | |
865 | //purpose : optimizing projection by Newton algo (S4030) | |
866 | //======================================================================= | |
867 | ||
868 | gp_Pnt2d ShapeAnalysis_Surface::NextValueOfUV(const gp_Pnt2d &p2dPrev, | |
869 | const gp_Pnt& P3D, | |
870 | const Standard_Real preci, | |
871 | const Standard_Real maxpreci) | |
872 | { | |
873 | GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); | |
874 | GeomAbs_SurfaceType surftype = SurfAdapt.GetType(); | |
875 | ||
876 | switch (surftype){ | |
877 | case GeomAbs_BezierSurface : | |
878 | case GeomAbs_BSplineSurface : | |
879 | case GeomAbs_SurfaceOfExtrusion : | |
880 | case GeomAbs_SurfaceOfRevolution : | |
881 | case GeomAbs_OffsetSurface : | |
882 | ||
7fd59977 | 883 | { |
15b54261 | 884 | if (surftype == GeomAbs_BSplineSurface) |
885 | { | |
886 | Handle(Geom_BSplineSurface) aBSpline = SurfAdapt.BSpline(); | |
887 | ||
888 | //Check near to knot position ~ near to C0 points on U isoline. | |
889 | if ( SurfAdapt.UContinuity() == GeomAbs_C0 ) | |
890 | { | |
891 | Standard_Integer aMinIndex = aBSpline->FirstUKnotIndex(); | |
892 | Standard_Integer aMaxIndex = aBSpline->LastUKnotIndex(); | |
893 | for (Standard_Integer anIdx = aMinIndex; anIdx <= aMaxIndex; ++anIdx) | |
894 | { | |
895 | Standard_Real aKnot = aBSpline->UKnot(anIdx); | |
896 | if (Abs (aKnot - p2dPrev.X()) < Precision::Confusion()) | |
897 | return ValueOfUV ( P3D, preci ); | |
898 | } | |
899 | } | |
900 | ||
901 | //Check near to knot position ~ near to C0 points on U isoline. | |
902 | if ( SurfAdapt.VContinuity() == GeomAbs_C0 ) | |
903 | { | |
904 | Standard_Integer aMinIndex = aBSpline->FirstVKnotIndex(); | |
905 | Standard_Integer aMaxIndex = aBSpline->LastVKnotIndex(); | |
906 | for (Standard_Integer anIdx = aMinIndex; anIdx <= aMaxIndex; ++anIdx) | |
907 | { | |
908 | Standard_Real aKnot = aBSpline->VKnot(anIdx); | |
909 | if (Abs (aKnot - p2dPrev.Y()) < Precision::Confusion()) | |
910 | return ValueOfUV ( P3D, preci ); | |
911 | } | |
912 | } | |
913 | } | |
914 | ||
7fd59977 | 915 | gp_Pnt2d sol; |
dde68833 | 916 | Standard_Integer res = SurfaceNewton(p2dPrev,P3D,preci,sol); |
917 | if (res != 0) | |
15b54261 | 918 | { |
919 | Standard_Real gap = P3D.Distance ( Value(sol) ); | |
920 | if ( res == 2 || //:q6 abv 19 Mar 99: protect against strange attractors | |
921 | ( maxpreci > 0. && gap - maxpreci > Precision::Confusion()) ) | |
922 | { //:q1: check with maxpreci | |
923 | Standard_Real U = sol.X(), V = sol.Y(); | |
924 | myGap = UVFromIso ( P3D, preci, U, V ); | |
925 | // gp_Pnt2d p = ValueOfUV ( P3D, preci ); | |
926 | if ( gap >= myGap ) return gp_Pnt2d ( U, V ); | |
927 | } | |
928 | myGap = gap; | |
929 | return sol; | |
7fd59977 | 930 | } |
931 | } | |
932 | break; | |
933 | default: | |
934 | break; | |
935 | } | |
936 | return ValueOfUV ( P3D, preci ); | |
937 | } | |
938 | ||
939 | //======================================================================= | |
940 | //function : ValueOfUV | |
941 | //purpose : | |
942 | //======================================================================= | |
943 | ||
944 | gp_Pnt2d ShapeAnalysis_Surface::ValueOfUV(const gp_Pnt& P3D,const Standard_Real preci) | |
945 | { | |
946 | GeomAdaptor_Surface& SurfAdapt = Adaptor3d()->ChangeSurface(); | |
1d47d8d0 | 947 | Standard_Real S = 0., T = 0.; |
7fd59977 | 948 | myGap = -1.; // devra etre calcule |
949 | Standard_Boolean computed = Standard_True; // a priori | |
950 | ||
951 | Standard_Real uf, ul, vf, vl; | |
952 | Bounds(uf, ul, vf, vl);//modified by rln on 12/11/97 mySurf-> is deleted | |
953 | ||
954 | { //:c9 abv 3 Mar 98: UKI60107-1 #350: to prevent 'catch' from catching exception raising below it | |
955 | try { // ajout CKY 30-DEC-1997 (cf ProStep TR6 r_89-ug) | |
956 | OCC_CATCH_SIGNALS | |
957 | GeomAbs_SurfaceType surftype = SurfAdapt.GetType(); | |
958 | switch (surftype){ | |
959 | ||
960 | case GeomAbs_Plane : | |
961 | { | |
962 | gp_Pln Plane = SurfAdapt.Plane(); | |
963 | ElSLib::Parameters( Plane, P3D, S, T); | |
964 | break; | |
965 | } | |
966 | case GeomAbs_Cylinder : | |
967 | { | |
968 | gp_Cylinder Cylinder = SurfAdapt.Cylinder(); | |
969 | ElSLib::Parameters( Cylinder, P3D, S, T); | |
c6541a0c | 970 | S += ShapeAnalysis::AdjustByPeriod(S,0.5*(uf+ul),2*M_PI); |
7fd59977 | 971 | break; |
972 | } | |
973 | case GeomAbs_Cone : | |
974 | { | |
975 | gp_Cone Cone = SurfAdapt.Cone(); | |
976 | ElSLib::Parameters( Cone, P3D, S, T); | |
c6541a0c | 977 | S += ShapeAnalysis::AdjustByPeriod(S,0.5*(uf+ul),2*M_PI); |
7fd59977 | 978 | break; |
979 | } | |
980 | case GeomAbs_Sphere : | |
981 | { | |
982 | gp_Sphere Sphere = SurfAdapt.Sphere(); | |
983 | ElSLib::Parameters( Sphere, P3D, S, T); | |
c6541a0c | 984 | S += ShapeAnalysis::AdjustByPeriod(S,0.5*(uf+ul),2*M_PI); |
7fd59977 | 985 | break; |
986 | } | |
987 | case GeomAbs_Torus : | |
988 | { | |
989 | gp_Torus Torus = SurfAdapt.Torus(); | |
990 | ElSLib::Parameters( Torus, P3D, S, T); | |
c6541a0c D |
991 | S += ShapeAnalysis::AdjustByPeriod(S,0.5*(uf+ul),2*M_PI); |
992 | T += ShapeAnalysis::AdjustByPeriod(T,0.5*(vf+vl),2*M_PI); | |
7fd59977 | 993 | break; |
994 | } | |
995 | case GeomAbs_BezierSurface : | |
996 | case GeomAbs_BSplineSurface : | |
997 | case GeomAbs_SurfaceOfExtrusion : | |
998 | case GeomAbs_SurfaceOfRevolution : | |
999 | case GeomAbs_OffsetSurface : //:d0 abv 3 Mar 98: UKI60107-1 #350 | |
1000 | { | |
1001 | S = (uf+ul)/2; T = (vf+vl)/2; // yaura aumoins qqchose | |
1002 | //pdn to fix hangs PRO17015 | |
1003 | if ((surftype==GeomAbs_SurfaceOfExtrusion)&&Precision::IsInfinite(uf)&&Precision::IsInfinite(ul)) { | |
1004 | //conic case | |
1005 | gp_Pnt2d prev(S,T); | |
1006 | gp_Pnt2d solution; | |
dde68833 | 1007 | if (SurfaceNewton(prev,P3D,preci,solution) != 0) |
1008 | { | |
0797d9d3 | 1009 | #ifdef OCCT_DEBUG |
7fd59977 | 1010 | cout <<"Newton found point on conic extrusion"<<endl; |
1011 | #endif | |
1012 | return solution; | |
1013 | } | |
0797d9d3 | 1014 | #ifdef OCCT_DEBUG |
7fd59977 | 1015 | cout <<"Newton failed point on conic extrusion"<<endl; |
1016 | #endif | |
1017 | uf = -500; | |
1018 | ul = 500; | |
1019 | } | |
1020 | ||
1021 | if (Precision::IsInfinite(uf)) uf = -1000; | |
1022 | if (Precision::IsInfinite(ul)) ul = 1000; | |
1023 | if (Precision::IsInfinite(vf)) vf = -1000; | |
1024 | if (Precision::IsInfinite(vl)) vl = 1000; | |
1025 | ||
1026 | //:30 by abv 2.12.97: speed optimization | |
1027 | // code is taken from GeomAPI_ProjectPointOnSurf | |
1028 | if ( ! myExtOK ) { | |
1029 | // Standard_Real du = Abs(ul-uf)/100; Standard_Real dv = Abs(vl-vf)/100; | |
1030 | // if (IsUClosed()) du = 0; if (IsVClosed()) dv = 0; | |
1031 | // Forcer appel a IsU-VClosed | |
1032 | if (myUCloseVal < 0) IsUClosed(); | |
1033 | if (myVCloseVal < 0) IsVClosed(); | |
c15398ab RL |
1034 | Standard_Real du = 0., dv = 0.; |
1035 | //extension of the surface range is limited to non-offset surfaces as the latter | |
1036 | //can throw exception (e.g. Geom_UndefinedValue) when computing value - see id23943 | |
1037 | if (!mySurf->IsKind (STANDARD_TYPE (Geom_OffsetSurface))) { | |
1038 | //modified by rln during fixing CSR # BUC60035 entity #D231 | |
1039 | du = Min (myUDelt, SurfAdapt.UResolution (preci)); | |
1040 | dv = Min (myVDelt, SurfAdapt.VResolution (preci)); | |
1041 | } | |
7fd59977 | 1042 | Standard_Real Tol = Precision::PConfusion(); |
6062bf3e | 1043 | myExtPS.SetFlag (Extrema_ExtFlag_MIN); |
84eca96b | 1044 | myExtPS.Initialize (SurfAdapt, uf-du, ul+du, vf-dv, vl+dv, Tol, Tol ); |
7fd59977 | 1045 | myExtOK = Standard_True; |
1046 | } | |
1047 | myExtPS.Perform ( P3D ); | |
1048 | Standard_Integer nPSurf = ( myExtPS.IsDone() ? myExtPS.NbExt() : 0 ); | |
1049 | ||
1050 | if ( nPSurf > 0 ) { | |
1051 | Standard_Real dist2Min = myExtPS.SquareDistance( 1 ); | |
1052 | Standard_Integer indMin=1; | |
1053 | for (Standard_Integer sol = 2; sol <= nPSurf ; sol++) { | |
1054 | Standard_Real dist2 = myExtPS.SquareDistance(sol); | |
1055 | if ( dist2Min > dist2 ) { | |
1056 | dist2Min = dist2; | |
1057 | indMin = sol; | |
1058 | } | |
1059 | } | |
1060 | myExtPS.Point(indMin).Parameter ( S, T ); | |
1061 | // PTV 26.06.2002 WORKAROUND protect OCC486. Remove after fix bug. | |
1062 | // file CEA_cuve-V5.igs Entityes 244, 259, 847, 925 | |
1063 | // if project point3D on SurfaceOfRevolution Extreme recompute 2d point, but | |
1064 | // returns an old distance from 3d to solution :-( | |
84eca96b | 1065 | gp_Pnt aCheckPnt = SurfAdapt.Value( S, T ); |
7fd59977 | 1066 | dist2Min = P3D.SquareDistance(aCheckPnt); |
1067 | // end of WORKAROUND | |
1068 | Standard_Real disSurf = sqrt (dist2Min);//, disCurv =1.e10; | |
1069 | ||
1070 | // Test de projection merdeuse sur les bords : | |
1071 | Standard_Real UU = S, VV = T, DistMinOnIso = RealLast(); // myGap; | |
1072 | // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); | |
1073 | ||
1074 | //test added by rln on 08/12/97 | |
1075 | // DistMinOnIso = UVFromIso (P3D, preci, UU, VV); | |
1076 | Standard_Boolean possLockal = Standard_False; //:study S4030 (optimizing) | |
1077 | if (disSurf > preci) { | |
1078 | gp_Pnt2d pp(UU,VV); | |
dde68833 | 1079 | if (SurfaceNewton (pp, P3D, preci, pp) != 0) |
1080 | { //:q2 abv 16 Mar 99: PRO7226 #412920 | |
7fd59977 | 1081 | Standard_Real dist = P3D.Distance ( Value(pp) ); |
1082 | if ( dist < disSurf ) { | |
1083 | disSurf = dist; | |
1084 | S = UU = pp.X(); | |
1085 | T = VV = pp.Y(); | |
1086 | } | |
1087 | } | |
1088 | if ( disSurf < 10*preci) | |
1089 | if (mySurf->Continuity() != GeomAbs_C0){ | |
1090 | Standard_Real Tol = Precision::Confusion(); | |
1091 | gp_Vec D1U, D1V; | |
1092 | gp_Pnt pnt; | |
84eca96b | 1093 | SurfAdapt.D1(UU, VV, pnt, D1U, D1V); |
7fd59977 | 1094 | gp_Vec b = D1U.Crossed(D1V); |
1095 | gp_Vec a (pnt, P3D); | |
1096 | Standard_Real ab = a.Dot(b); | |
1097 | Standard_Real nrm2 = b.SquareMagnitude(); | |
1098 | if ( nrm2 > 1e-10 ) { | |
1099 | Standard_Real dist = a.SquareMagnitude() - (ab*ab)/nrm2; | |
1100 | possLockal = ( dist < Tol*Tol ); | |
1101 | } | |
1102 | } | |
1103 | if (!possLockal) { | |
1104 | DistMinOnIso = UVFromIso (P3D, preci, UU, VV); | |
1105 | } | |
1106 | } | |
1107 | ||
1108 | if (disSurf > DistMinOnIso) { | |
1109 | // On prend les parametres UU et VV; | |
1110 | S = UU; | |
1111 | T = VV; | |
1112 | myGap = DistMinOnIso; | |
1113 | } | |
1114 | else { | |
1115 | myGap = disSurf; | |
1116 | } | |
1117 | ||
1118 | // On essaie Intersection Droite Passant par P3D / Surface | |
1119 | // if ((myGap > preci)&&(!possLockal) ) { | |
1120 | // Standard_Real SS, TT; | |
1121 | // disCurv = FindUV(P3D, mySurf, S, T, SS, TT); | |
1122 | // if (disCurv < preci || disCurv < myGap) { | |
1123 | // S = SS; | |
1124 | // T = TT; | |
1125 | // } | |
1126 | // } | |
1127 | ||
1128 | } | |
1129 | else { | |
0797d9d3 | 1130 | #ifdef OCCT_DEBUG |
7fd59977 | 1131 | cout << "Warning: ShapeAnalysis_Surface::ValueOfUV(): Extrema failed, doing Newton" << endl; |
1132 | #endif | |
1133 | // on essai sur les bords | |
1134 | Standard_Real UU = S, VV = T;//, DistMinOnIso; | |
1135 | // ForgetNewton(P3D, mySurf, preci, UU, VV, DistMinOnIso); | |
1136 | myGap = UVFromIso (P3D, preci, UU, VV); | |
1137 | // if (DistMinOnIso > preci) { | |
1138 | // Standard_Real SS, TT; | |
1139 | // Standard_Real disCurv = FindUV(P3D, mySurf, UU, VV, SS, TT); | |
1140 | // if (disCurv < preci) { | |
1141 | // S = SS; | |
1142 | // T = TT; | |
1143 | // } | |
1144 | // } | |
1145 | // else { | |
1146 | S = UU; | |
1147 | T = VV; | |
1148 | // } | |
1149 | } | |
1150 | } | |
1151 | break; | |
1152 | ||
1153 | default : | |
1154 | computed = Standard_False; | |
1155 | break; | |
1156 | } | |
1157 | ||
1158 | } // end Try ValueOfUV (CKY 30-DEC-1997) | |
1159 | ||
9775fa61 | 1160 | catch(Standard_Failure const& anException) { |
1161 | #ifdef OCCT_DEBUG | |
7fd59977 | 1162 | // Pas de raison mais qui sait. Mieux vaut retourner un truc faux que stopper |
1163 | // L ideal serait d avoir un status ... mais qui va l interroger ? | |
1164 | // Avec ce status, on saurait que ce point est a sauter et voila tout | |
1165 | // En attendant, on met une valeur "pas idiote" mais surement fausse ... | |
9775fa61 | 1166 | //szv#4:S4163:12Mar99 optimized |
1167 | //:s5 | |
7fd59977 | 1168 | cout << "\nWarning: ShapeAnalysis_Surface::ValueOfUV(): Exception: "; |
9775fa61 | 1169 | anException.Print(cout); cout << endl; |
7fd59977 | 1170 | #endif |
9775fa61 | 1171 | (void)anException; |
1172 | S = (Precision::IsInfinite(uf))? 0 : (uf+ul) / 2.; | |
1173 | T = (Precision::IsInfinite(vf))? 0 : (vf+vl) / 2.; | |
7fd59977 | 1174 | } |
1175 | } //:c9 | |
1176 | //szv#4:S4163:12Mar99 waste raise | |
9775fa61 | 1177 | //if (!computed) throw Standard_NoSuchObject("PCurveLib_ProjectPointOnSurf::ValueOfUV untreated surface type"); |
84eca96b | 1178 | if (computed) { if (myGap <= 0) myGap = P3D.Distance (SurfAdapt.Value (S,T)); } |
7fd59977 | 1179 | else { myGap = -1.; S = 0.; T = 0.; } |
1180 | return gp_Pnt2d( S, T); | |
1181 | } | |
1182 | ||
1183 | //======================================================================= | |
1184 | //function : UVFromIso | |
1185 | //purpose : | |
1186 | //======================================================================= | |
1187 | ||
1188 | Standard_Real ShapeAnalysis_Surface::UVFromIso(const gp_Pnt& P3d,const Standard_Real preci,Standard_Real& U,Standard_Real& V) | |
1189 | { | |
1190 | // Projection qui considere les isos ... comme suit : | |
1191 | // Les 4 bords, plus les isos en U et en V | |
1192 | // En effet, souvent, un des deux est bon ... | |
1193 | Standard_Real theMin = RealLast(); | |
1194 | ||
1195 | gp_Pnt pntres; | |
1196 | Standard_Real Cf, Cl, UU,VV; | |
1197 | ||
1198 | // Initialisation des recherches : point deja trouve (?) | |
1199 | UU = U; VV = V; | |
84eca96b | 1200 | gp_Pnt depart = myAdSur->Value (U,V); |
7fd59977 | 1201 | theMin = depart.Distance(P3d); |
1202 | ||
1203 | if (theMin < preci/10) return theMin; // c etait deja OK | |
1204 | ComputeBoxes(); | |
1205 | if(myIsoUF.IsNull() || myIsoUL.IsNull() || myIsoVF.IsNull() || myIsoVL.IsNull()) { | |
1206 | // no isolines | |
1207 | // no more precise computation | |
1208 | return theMin; | |
1209 | } | |
1210 | try { // RAJOUT | |
1211 | OCC_CATCH_SIGNALS | |
1212 | //pdn Create BndBox containing point; | |
1213 | Bnd_Box aPBox; | |
1214 | aPBox.Set(P3d); | |
1215 | ||
1216 | //cout<<"Adaptor3d()->Surface().GetType() = "<<Adaptor3d()->Surface().GetType()<<endl; | |
1217 | ||
1218 | //modified by rln on 04/12/97 in order to use theese variables later | |
1219 | Standard_Boolean UV = Standard_True; | |
1220 | Standard_Real par=0., other=0., dist=0.; | |
1221 | Handle(Geom_Curve) iso; | |
1222 | Adaptor3d_IsoCurve anIsoCurve(Adaptor3d()); | |
1223 | for (Standard_Integer num = 0; num < 6; num ++) { | |
1224 | ||
1225 | UV = (num < 3); // 0-1-2 : iso-U 3-4-5 : iso-V | |
1226 | if( !(Adaptor3d()->Surface().GetType()==GeomAbs_OffsetSurface) ) { | |
1227 | const Bnd_Box *anIsoBox = 0; | |
1228 | switch (num) { | |
1229 | case 0 : par = myUF; iso = myIsoUF; anIsoBox = &myBndUF; break; | |
1230 | case 1 : par = myUL; iso = myIsoUL; anIsoBox = &myBndUL; break; | |
1231 | case 2 : par = U; iso = UIso (U); break; | |
1232 | case 3 : par = myVF; iso = myIsoVF; anIsoBox = &myBndVF; break; | |
1233 | case 4 : par = myVL; iso = myIsoVL; anIsoBox = &myBndVL; break; | |
1234 | case 5 : par = V; iso = VIso (V); break; | |
1235 | default: break; | |
1236 | } | |
1237 | ||
1238 | // On y va la-dessus | |
1239 | if (!Precision::IsInfinite(par) && !iso.IsNull()) { | |
1240 | if( anIsoBox && anIsoBox->Distance(aPBox) > theMin) | |
1241 | continue; | |
1242 | ||
1243 | Cf = iso->FirstParameter(); | |
1244 | Cl = iso->LastParameter(); | |
1245 | ||
1246 | if (Precision::IsInfinite(Cf)) Cf = -1000; | |
1247 | if (Precision::IsInfinite(Cl)) Cl = +1000; | |
1248 | dist = ShapeAnalysis_Curve().Project (iso,P3d,preci,pntres,other,Cf,Cl, Standard_False); | |
1249 | if (dist < theMin) { | |
1250 | theMin = dist; | |
1251 | //:q6 if (UV) VV = other; else UU = other; | |
1252 | // Selon une isoU, on calcule le meilleur V; et lycee de Versailles | |
1253 | UU = (UV ? par : other); VV = (UV ? other : par); //:q6: uncommented | |
1254 | } | |
1255 | } | |
1256 | } | |
1257 | ||
1258 | else { | |
1259 | Adaptor3d_Curve *anAdaptor = NULL; | |
1260 | GeomAdaptor_Curve aGeomCurve; | |
1261 | ||
1262 | const Bnd_Box *anIsoBox = 0; | |
1263 | switch (num) { | |
1264 | case 0 : par = myUF; aGeomCurve.Load(myIsoUF); anAdaptor=&aGeomCurve; anIsoBox = &myBndUF; break; | |
1265 | case 1 : par = myUL; aGeomCurve.Load(myIsoUL); anAdaptor=&aGeomCurve; anIsoBox = &myBndUL;break; | |
1266 | case 2 : par = U; anIsoCurve.Load(GeomAbs_IsoU,U); anAdaptor=&anIsoCurve; break; | |
1267 | case 3 : par = myVF; aGeomCurve.Load(myIsoVF); anAdaptor=&aGeomCurve; anIsoBox = &myBndVF; break; | |
1268 | case 4 : par = myVL; aGeomCurve.Load(myIsoVL); anAdaptor=&aGeomCurve; anIsoBox = &myBndVL;break; | |
1269 | case 5 : par = V; anIsoCurve.Load(GeomAbs_IsoV,V); anAdaptor=&anIsoCurve; break; | |
1270 | default : break; | |
1271 | } | |
1272 | if( anIsoBox && anIsoBox->Distance(aPBox) > theMin) | |
1273 | continue; | |
1274 | dist = ShapeAnalysis_Curve().Project(*anAdaptor,P3d,preci,pntres,other); | |
1275 | if (dist < theMin) { | |
1276 | theMin = dist; | |
1277 | UU = (UV ? par : other); VV = (UV ? other : par); //:q6: uncommented | |
1278 | } | |
1279 | } | |
1280 | } | |
1281 | ||
1282 | //added by rln on 04/12/97 iterational process | |
1283 | Standard_Real PrevU = U, PrevV = V; | |
1284 | Standard_Integer MaxIters = 5, Iters = 0; | |
1285 | if( !(Adaptor3d()->Surface().GetType()==GeomAbs_OffsetSurface) ) { | |
1286 | while (((PrevU != UU) || (PrevV != VV)) && (Iters < MaxIters) && (theMin > preci)) { | |
1287 | PrevU = UU; PrevV = VV; | |
1288 | if (UV) {par = UU; iso = UIso(UU);} | |
1289 | else {par = VV; iso = VIso(VV);} | |
1290 | if(!iso.IsNull()) { | |
1291 | Cf = iso->FirstParameter(); | |
1292 | Cl = iso->LastParameter(); | |
1293 | if (Precision::IsInfinite(Cf)) Cf = -1000; | |
1294 | if (Precision::IsInfinite(Cl)) Cl = +1000; | |
1295 | dist = ShapeAnalysis_Curve().Project (iso, P3d, preci, pntres, other, Cf, Cl, Standard_False); | |
1296 | if (dist < theMin) { | |
1297 | theMin = dist; | |
1298 | if (UV) VV = other; else UU = other; | |
1299 | } | |
1300 | } | |
1301 | UV = !UV; | |
1302 | if (UV) {par = UU; iso = UIso(UU);} | |
1303 | else {par = VV; iso = VIso(VV);} | |
1304 | if(!iso.IsNull()) { | |
1305 | Cf = iso->FirstParameter(); | |
1306 | Cl = iso->LastParameter(); | |
1307 | if (Precision::IsInfinite(Cf)) Cf = -1000; | |
1308 | if (Precision::IsInfinite(Cl)) Cl = +1000; | |
1309 | dist = ShapeAnalysis_Curve().Project (iso, P3d, preci, pntres, other, Cf, Cl, Standard_False); | |
1310 | if (dist < theMin) { | |
1311 | theMin = dist; | |
1312 | if (UV) VV = other; else UU = other; | |
1313 | } | |
1314 | } | |
1315 | UV = !UV; | |
1316 | Iters++; | |
1317 | } | |
1318 | } | |
1319 | ||
1320 | else { | |
1321 | while (((PrevU != UU) || (PrevV != VV)) && (Iters < MaxIters) && (theMin > preci)) { | |
1322 | PrevU = UU; PrevV = VV; | |
1323 | if (UV) { | |
1324 | par = UU; | |
1325 | anIsoCurve.Load(GeomAbs_IsoU,UU); | |
1326 | } | |
1327 | else { | |
1328 | par = VV; | |
1329 | anIsoCurve.Load(GeomAbs_IsoV,VV); | |
1330 | } | |
1331 | Cf = anIsoCurve.FirstParameter(); | |
1332 | Cl = anIsoCurve.LastParameter(); | |
1333 | if (Precision::IsInfinite(Cf)) Cf = -1000; | |
1334 | if (Precision::IsInfinite(Cl)) Cl = +1000; | |
1335 | dist = ShapeAnalysis_Curve().Project(anIsoCurve, P3d, preci, pntres, other); | |
1336 | if (dist < theMin) { | |
1337 | theMin = dist; | |
1338 | if (UV) VV = other; else UU = other; | |
1339 | } | |
1340 | UV = !UV; | |
1341 | if (UV) { | |
1342 | par = UU; | |
1343 | anIsoCurve.Load(GeomAbs_IsoU,UU); | |
1344 | } | |
1345 | else { | |
1346 | par = VV; | |
1347 | anIsoCurve.Load(GeomAbs_IsoV,VV); | |
1348 | } | |
1349 | Cf = anIsoCurve.FirstParameter(); | |
1350 | Cl = anIsoCurve.LastParameter(); | |
1351 | if (Precision::IsInfinite(Cf)) Cf = -1000; | |
1352 | if (Precision::IsInfinite(Cl)) Cl = +1000; | |
1353 | dist = ShapeAnalysis_Curve().ProjectAct (anIsoCurve, P3d, preci, pntres, other); | |
1354 | if (dist < theMin) { | |
1355 | theMin = dist; | |
1356 | if (UV) VV = other; else UU = other; | |
1357 | } | |
1358 | UV = !UV; | |
1359 | Iters++; | |
1360 | } | |
1361 | } | |
1362 | ||
1363 | U = UU; V = VV; | |
1364 | ||
1365 | } // fin try RAJOUT | |
9775fa61 | 1366 | catch(Standard_Failure const& anException) { |
1367 | #ifdef OCCT_DEBUG | |
1368 | //:s5 | |
7fd59977 | 1369 | cout << "\nWarning: ShapeAnalysis_Curve::UVFromIso(): Exception: "; |
9775fa61 | 1370 | anException.Print(cout); cout << endl; |
7fd59977 | 1371 | #endif |
9775fa61 | 1372 | (void)anException; |
1373 | theMin = RealLast(); // theMin de depart | |
7fd59977 | 1374 | } |
1375 | return theMin; | |
1376 | } | |
1377 | ||
1378 | ||
1379 | //======================================================================= | |
1380 | //function : SortSingularities | |
1381 | //purpose : | |
1382 | //======================================================================= | |
1383 | ||
1384 | void ShapeAnalysis_Surface::SortSingularities() | |
1385 | { | |
1386 | for (Standard_Integer i = 0; i < myNbDeg - 1; i++) { | |
1387 | Standard_Real minPreci = myPreci[i]; | |
1388 | Standard_Integer minIndex = i; | |
1389 | for (Standard_Integer j = i + 1; j < myNbDeg; j++) | |
1390 | if (minPreci > myPreci[j]) { minPreci = myPreci[j]; minIndex = j; } | |
1391 | if (minIndex != i) { | |
1392 | myPreci[minIndex] = myPreci[i]; myPreci[i] = minPreci; | |
1393 | gp_Pnt tmpP3d = myP3d[minIndex]; | |
1394 | myP3d[minIndex] = myP3d[i]; myP3d[i] = tmpP3d; | |
1395 | gp_Pnt2d tmpP2d = myFirstP2d[minIndex]; | |
1396 | myFirstP2d[minIndex] = myFirstP2d[i]; myFirstP2d[i] = tmpP2d; | |
1397 | tmpP2d = myLastP2d[minIndex]; myLastP2d[minIndex] = myLastP2d[i]; myLastP2d[i] = tmpP2d; | |
1398 | Standard_Real tmpPar = myFirstPar[minIndex]; | |
1399 | myFirstPar[minIndex] = myFirstPar[i]; myFirstPar[i] = tmpPar; | |
1400 | tmpPar = myLastPar[minIndex]; myLastPar[minIndex] = myLastPar[i]; myLastPar[i] = tmpPar; | |
1401 | Standard_Boolean tmpUIsoDeg = myUIsoDeg[minIndex]; | |
1402 | myUIsoDeg[minIndex] = myUIsoDeg[i]; myUIsoDeg[i] = tmpUIsoDeg; | |
1403 | } | |
1404 | } | |
1405 | } | |
1406 | ||
1407 | ||
1408 | //======================================================================= | |
1409 | //function : SetDomain | |
1410 | //purpose : | |
1411 | //======================================================================= | |
1412 | ||
1413 | void ShapeAnalysis_Surface::SetDomain(const Standard_Real U1, | |
1414 | const Standard_Real U2, | |
1415 | const Standard_Real V1, | |
1416 | const Standard_Real V2) | |
1417 | { | |
1418 | myUF = U1; | |
1419 | myUL = U2; | |
1420 | myVF = V1; | |
1421 | myVL = V2; | |
1422 | } | |
1423 | ||
1424 | ||
1425 | void ShapeAnalysis_Surface::ComputeBoxes() | |
1426 | { | |
1427 | if(myIsoBoxes) return; | |
1428 | myIsoBoxes = Standard_True; | |
1429 | ComputeBoundIsos(); | |
1430 | if(!myIsoUF.IsNull()) | |
1431 | BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoUF),Precision::Confusion(),myBndUF); | |
1432 | if(!myIsoUL.IsNull()) | |
1433 | BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoUL),Precision::Confusion(),myBndUL); | |
1434 | if(!myIsoVF.IsNull()) | |
1435 | BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoVF),Precision::Confusion(),myBndVF); | |
1436 | if(!myIsoVL.IsNull()) | |
1437 | BndLib_Add3dCurve::Add(GeomAdaptor_Curve(myIsoVL),Precision::Confusion(),myBndVL); | |
1438 | } | |
1439 | ||
1440 | const Bnd_Box& ShapeAnalysis_Surface::GetBoxUF() | |
1441 | { | |
1442 | ComputeBoxes(); | |
1443 | return myBndUF; | |
1444 | } | |
1445 | ||
1446 | const Bnd_Box& ShapeAnalysis_Surface::GetBoxUL() | |
1447 | { | |
1448 | ComputeBoxes(); | |
1449 | return myBndUL; | |
1450 | } | |
1451 | ||
1452 | const Bnd_Box& ShapeAnalysis_Surface::GetBoxVF() | |
1453 | { | |
1454 | ComputeBoxes(); | |
1455 | return myBndVF; | |
1456 | } | |
1457 | ||
1458 | const Bnd_Box& ShapeAnalysis_Surface::GetBoxVL() | |
1459 | { | |
1460 | ComputeBoxes(); | |
1461 | return myBndVL; | |
1462 | } |