7fd59977 |
1 | // File: IntTools_ShrunkRange.cxx |
2 | // Created: Sun Mar 11 10:38:43 2001 |
3 | // Author: Peter KURNEV |
4 | // <pkv@irinox> |
5 | // |
6 | |
7 | #include <IntTools_ShrunkRange.ixx> |
8 | |
9 | #include <Precision.hxx> |
10 | |
11 | #include <gp_Lin.hxx> |
12 | #include <gp.hxx> |
13 | #include <gp_Circ.hxx> |
14 | |
15 | #include <ElCLib.hxx> |
16 | |
17 | #include <Geom_Curve.hxx> |
18 | |
19 | #include <BRep_Tool.hxx> |
20 | #include <BRepBuilderAPI_MakeVertex.hxx> |
21 | #include <BRepAdaptor_Curve.hxx> |
22 | #include <BndLib_Add3dCurve.hxx> |
23 | |
24 | #include <IntTools_Tools.hxx> |
25 | |
26 | //======================================================================= |
27 | //function : IntTools_ShrunkRange |
28 | //purpose : |
29 | //======================================================================= |
30 | IntTools_ShrunkRange::IntTools_ShrunkRange () |
31 | { |
32 | } |
33 | |
34 | //======================================================================= |
35 | //function : IntTools_ShrunkRange |
36 | //purpose : |
37 | //======================================================================= |
38 | IntTools_ShrunkRange::IntTools_ShrunkRange (const TopoDS_Edge& aE, |
39 | const TopoDS_Vertex& aV1, |
40 | const TopoDS_Vertex& aV2, |
41 | const IntTools_Range& aR, |
42 | const IntTools_Context& aCtx) |
43 | { |
44 | myEdge=aE; |
45 | myV1=aV1; |
46 | myV2=aV2; |
47 | myRange=aR; |
48 | myCtx=(IntTools_PContext)&aCtx; |
49 | myIsDone=Standard_False; |
50 | myErrorStatus=1; |
51 | Perform(); |
52 | } |
53 | //======================================================================= |
54 | //function : Edge |
55 | //purpose : |
56 | //======================================================================= |
57 | const TopoDS_Edge& IntTools_ShrunkRange::Edge() const |
58 | { |
59 | return myEdge; |
60 | } |
61 | //======================================================================= |
62 | //function : ShrunkRange |
63 | //purpose : |
64 | //======================================================================= |
65 | const IntTools_Range& IntTools_ShrunkRange::ShrunkRange() const |
66 | { |
67 | return myShrunkRange; |
68 | } |
69 | //======================================================================= |
70 | //function : BndBox |
71 | //purpose : |
72 | //======================================================================= |
73 | const Bnd_Box& IntTools_ShrunkRange::BndBox() const |
74 | { |
75 | return myBndBox; |
76 | } |
77 | //======================================================================= |
78 | //function : IsDone |
79 | //purpose : |
80 | //======================================================================= |
81 | Standard_Boolean IntTools_ShrunkRange::IsDone() const |
82 | { |
83 | return myIsDone; |
84 | } |
85 | //======================================================================= |
86 | //function : ErrorStatus |
87 | //purpose : |
88 | //======================================================================= |
89 | Standard_Integer IntTools_ShrunkRange::ErrorStatus() const |
90 | { |
91 | return myErrorStatus; |
92 | } |
93 | //======================================================================= |
94 | //function : Perform |
95 | //purpose : |
96 | //======================================================================= |
97 | void IntTools_ShrunkRange::Perform() |
98 | { |
99 | Standard_Real aCF, aCL, aTolE, aTolV1, aTolV2, t1, t11, t1C, t2, t12, t2C; |
100 | Standard_Real aCoeff, dt1, dt2, aR; |
101 | Standard_Integer pri; |
102 | Standard_Boolean bInf1, bInf2; |
103 | GeomAbs_CurveType aCurveType; |
104 | Handle(Geom_Curve) aC; |
105 | // |
106 | aTolE =BRep_Tool::Tolerance(myEdge); |
107 | aTolV1=BRep_Tool::Tolerance(myV1); |
108 | aTolV2=BRep_Tool::Tolerance(myV2); |
109 | //xf |
110 | //dt1=aCoeff*(aTolV1+aTolE); |
111 | //dt2=aCoeff*(aTolV2+aTolE); |
112 | //xt |
113 | myRange.Range (t1, t2); |
114 | // |
115 | BRepAdaptor_Curve aBAC(myEdge); |
116 | aCurveType=aBAC.GetType(); |
117 | // |
118 | aC=BRep_Tool::Curve(myEdge, aCF, aCL); |
119 | BRep_Tool::Range(myEdge, aCF, aCL); |
120 | // |
121 | if (t1 < aCF || t2 > aCL) { |
122 | myErrorStatus=2; |
123 | return; |
124 | } |
125 | // |
126 | if (t1 > t2 ) { |
127 | myErrorStatus=3; |
128 | return; |
129 | } |
130 | // |
131 | aCoeff=2.; |
132 | // xf |
133 | if (aCurveType==GeomAbs_Line) { |
134 | Standard_Real aTV1, aTV2, aEps; |
135 | gp_Pnt aPV1, aPV2, aPC1, aPC2; |
136 | gp_Lin aL; |
137 | // |
138 | aEps=Precision::Confusion(); |
139 | aEps=aEps*aEps;//1.e-14; |
140 | aL=aBAC.Line(); |
141 | // |
142 | aPV1=BRep_Tool::Pnt(myV1); |
143 | aTV1=ElCLib::Parameter(aL, aPV1); |
144 | // |
145 | aPV2=BRep_Tool::Pnt(myV2); |
146 | aTV2=ElCLib::Parameter(aL, aPV2); |
147 | // |
148 | if (fabs(aTV1-aCF)<aEps && fabs(aTV2-aCL)<aEps) { |
149 | aCoeff=1.; |
150 | } |
151 | } |
152 | // |
153 | dt1=aCoeff*(aTolV1+aTolE); |
154 | dt2=aCoeff*(aTolV2+aTolE); |
155 | // xt |
156 | // |
157 | if (aCurveType==GeomAbs_Line) { |
158 | Standard_Real dt1x, dt2x; |
159 | |
160 | dt1x = aBAC.Resolution(dt1); |
161 | t11=t1+dt1x; |
162 | |
163 | dt2x = aBAC.Resolution(dt2); |
164 | t12=t2-dt2x; |
165 | |
166 | if (t11>t2 || t12<t1) { |
167 | t1C=t1; |
168 | t2C=t2; |
169 | myShrunkRange.SetFirst(t1C); |
170 | myShrunkRange.SetLast (t2C); |
171 | // |
172 | // BndBox |
173 | Standard_Real ddx=aTolE;//1.e-12; |
174 | BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox); |
175 | |
176 | myErrorStatus=6; |
177 | myIsDone=Standard_True; |
178 | return; |
179 | } |
180 | } |
181 | // |
182 | if (aCurveType==GeomAbs_Circle) { |
183 | gp_Circ aCrc=aBAC.Circle(); |
184 | aR=aCrc.Radius(); |
185 | t1C=t1+dt1/aR; |
186 | t2C=t2-dt2/aR; |
187 | } |
188 | |
189 | else { |
190 | // |
191 | // Vertex1 => t1C |
192 | gp_Pnt aP1,aP11; |
193 | aC->D0 (t1, aP1); |
194 | // |
195 | bInf1=Precision::IsNegativeInfinite(t1); |
196 | if (bInf1) { |
197 | t1C=t1; |
198 | } |
199 | // |
200 | else { |
201 | Standard_Real d1 = aCoeff*(aTolV1+aTolE); |
202 | // dt1 = aBAC.Resolution(d1); |
203 | // |
204 | gp_Vec aD1vec1; |
205 | gp_Pnt aPoint; |
206 | aBAC.D1(t1, aPoint, aD1vec1); |
207 | Standard_Real ad1length1 = aD1vec1.Magnitude(); |
208 | Standard_Boolean bTryOtherPoints = Standard_False; |
209 | dt1 = (t2 - t1) * 0.5; |
210 | |
211 | if(ad1length1 > 1.e-12) { |
212 | dt1 = d1 / ad1length1; |
213 | |
214 | if(dt1 > (t2 - t1)) { |
215 | // bad parametrization, big tolerance or too small range |
216 | bTryOtherPoints = Standard_True; |
217 | } |
218 | } |
219 | else { |
220 | bTryOtherPoints = Standard_True; |
221 | } |
222 | |
223 | if(bTryOtherPoints) { |
224 | Standard_Integer nbsamples = 5; |
225 | Standard_Integer ii = 0; |
226 | Standard_Real adelta = (t2 - t1) / (nbsamples + 1); |
227 | Standard_Boolean bFound = Standard_False; |
228 | |
229 | for(ii = 1; ii <= nbsamples; ii++) { |
230 | Standard_Real aparameter = t1 + (adelta * ii); |
231 | gp_Pnt aPoint2; |
232 | aBAC.D1(aparameter, aPoint2, aD1vec1); |
233 | |
234 | if(aPoint.Distance(aPoint2) < d1) |
235 | dt1 = adelta * ii; |
236 | ad1length1 = aD1vec1.Magnitude(); |
237 | |
238 | if(ad1length1 > 1.e-12) { |
239 | dt1 = d1 / ad1length1; |
240 | |
241 | if(dt1 < (t2 - t1)) { |
242 | bFound = Standard_True; |
243 | break; |
244 | } |
245 | } |
246 | } |
247 | |
248 | if(!bFound) { |
249 | if(dt1 > (t2 - t1)) { |
250 | dt1 = aBAC.Resolution(d1); |
251 | } |
252 | } |
253 | } |
254 | // |
255 | |
256 | t11=t1+dt1; |
257 | aC->D0 (t11, aP11); |
258 | |
259 | gp_Vec aV11(aP1, aP11); |
260 | // avoid exception if aP1 == aP11 |
261 | if (aV11.SquareMagnitude() < gp::Resolution()) |
262 | t1C = t1; |
263 | else { |
264 | gp_Dir aD11(aV11); |
265 | |
266 | gp_Pnt aP1L; |
267 | // |
268 | aP1L.SetCoord (aP1.X()+d1*aD11.X(), |
269 | aP1.Y()+d1*aD11.Y(), |
270 | aP1.Z()+d1*aD11.Z()); |
271 | |
272 | BRepBuilderAPI_MakeVertex aMV1(aP1L); |
273 | const TopoDS_Vertex& aV1L=aMV1.Vertex(); |
274 | // |
275 | pri=myCtx->ComputeVE (aV1L, myEdge, t1C); |
276 | // |
277 | if (pri==-3) { |
278 | //modified by NIZNHY-PKV Tue Apr 6 14:06:29 2010 |
279 | t1C = t1; |
280 | //myErrorStatus=4; |
281 | //return; |
282 | //modified by NIZNHY-PKV Tue Apr 6 14:06:31 2010 |
283 | |
284 | } |
285 | } |
286 | } |
287 | // |
288 | // Vertex2 => t2C |
289 | gp_Pnt aP2, aP12; |
290 | aC->D0 (t2, aP2); |
291 | // |
292 | bInf2=Precision::IsPositiveInfinite(t2); |
293 | if (bInf2) { |
294 | t2C=t2; |
295 | } |
296 | // |
297 | else { |
298 | Standard_Real d2 = aCoeff*(aTolV2+aTolE); |
299 | // dt2 = aBAC.Resolution(d2); |
300 | |
301 | // |
302 | gp_Vec aD1vec2; |
303 | gp_Pnt aPoint; |
304 | aBAC.D1(t2, aPoint, aD1vec2); |
305 | Standard_Real ad1length2 = aD1vec2.Magnitude(); |
306 | Standard_Boolean bTryOtherPoints = Standard_False; |
307 | dt2 = (t2 - t1) * 0.5; |
308 | |
309 | if(ad1length2 > 1.e-12) { |
310 | dt2 = d2 / ad1length2; |
311 | |
312 | if(dt2 > (t2 - t1)) { |
313 | bTryOtherPoints = Standard_True; |
314 | } |
315 | } |
316 | else { |
317 | bTryOtherPoints = Standard_True; |
318 | } |
319 | |
320 | if(bTryOtherPoints) { |
321 | Standard_Integer nbsamples = 5; |
322 | Standard_Integer ii = 0; |
323 | Standard_Real adelta = (t2 - t1) / (nbsamples + 1); |
324 | Standard_Boolean bFound = Standard_False; |
325 | |
326 | for(ii = 1; ii <= nbsamples; ii++) { |
327 | Standard_Real aparameter = t2 - (adelta * ii); |
328 | gp_Pnt aPoint2; |
329 | aBAC.D1(aparameter, aPoint2, aD1vec2); |
330 | |
331 | if(aPoint.Distance(aPoint2) < d2) |
332 | dt2 = adelta * ii; |
333 | ad1length2 = aD1vec2.Magnitude(); |
334 | |
335 | if(ad1length2 > 1.e-12) { |
336 | dt2 = d2 / ad1length2; |
337 | |
338 | if(dt2 < (t2 - t1)) { |
339 | bFound = Standard_True; |
340 | break; |
341 | } |
342 | } |
343 | } |
344 | |
345 | if(!bFound) { |
346 | if(dt2 > (t2 - t1)) { |
347 | dt2 = aBAC.Resolution(d2); |
348 | } |
349 | } |
350 | } |
351 | // |
352 | |
353 | t12=t2-dt2; |
354 | aC->D0 (t12, aP12); |
355 | |
356 | gp_Vec aV12(aP2, aP12); |
357 | // avoid exception if aP1 == aP11 |
358 | if (aV12.SquareMagnitude() < gp::Resolution()) |
359 | t2C = t2; |
360 | else { |
361 | gp_Dir aD12(aV12); |
362 | |
363 | gp_Pnt aP2L; |
364 | // |
365 | aP2L.SetCoord (aP2.X()+d2*aD12.X(), |
366 | aP2.Y()+d2*aD12.Y(), |
367 | aP2.Z()+d2*aD12.Z()); |
368 | |
369 | BRepBuilderAPI_MakeVertex aMV2(aP2L); |
370 | const TopoDS_Vertex& aV2L=aMV2.Vertex(); |
371 | // |
372 | pri=myCtx->ComputeVE (aV2L, myEdge, t2C); |
373 | // |
374 | if (pri==-3) { |
375 | //modified by NIZNHY-PKV Tue Apr 6 14:07:34 2010f |
376 | t2C = t2; |
377 | //myErrorStatus=5; |
378 | //return; |
379 | //modified by NIZNHY-PKV Tue Apr 6 14:07:39 2010t |
380 | } |
381 | } |
382 | } |
383 | } // else { |
384 | |
385 | |
386 | if (t1C>t2){ |
387 | t1C=0.5*(t2+t1); |
388 | t2C=t1C+0.1*(t2-t1C); |
389 | } |
390 | |
391 | if (t1C>t2C) { |
392 | t2C=t1C+0.1*(t2-t1C); |
393 | } |
394 | |
395 | myShrunkRange.SetFirst(t1C); |
396 | myShrunkRange.SetLast (t2C); |
397 | // |
398 | // BndBox |
399 | Standard_Real ddx=aTolE;//1.e-12; |
400 | BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox); |
401 | // |
402 | // Ok |
403 | myErrorStatus=0; |
404 | myIsDone=Standard_True; |
405 | } |
406 | |
407 | //======================================================================= |
408 | //function : SetShrunkRange |
409 | //purpose : |
410 | //======================================================================= |
411 | void IntTools_ShrunkRange::SetShrunkRange(const IntTools_Range& aR) |
412 | { |
413 | Standard_Real f, l; |
414 | aR.Range(f, l); |
415 | |
416 | myShrunkRange.SetFirst(f); |
417 | myShrunkRange.SetLast (l); |
418 | |
419 | BRepAdaptor_Curve aBAC(myEdge); |
420 | BndLib_Add3dCurve::Add (aBAC, f, l, 0., myBndBox); |
421 | } |
422 | |
423 | ///////////////////////////////////////////////////////////////////////// |
424 | // |
425 | // myErrorStatus : |
426 | // |
427 | // 1- Nothing has been done |
428 | // 2- The source range is out of the edge's range |
429 | // 3- t1 < t2 for source range |
430 | // 4- Can not project V1L to the Edge; |
431 | // 5- Can not project V2L to the Edge; |
432 | // 6- for obtained shrunk range [t11, t12] -> t11>t2 || t12<t1; |