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