Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created by: Peter KURNEV |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
7fd59977 | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
b311480e | 14 | |
1e143abb | 15 | #include <IntTools_ShrunkRange.ixx> |
7fd59977 | 16 | |
17 | #include <Precision.hxx> | |
18 | ||
7fd59977 | 19 | #include <gp.hxx> |
20 | #include <gp_Circ.hxx> | |
21 | ||
7fd59977 | 22 | #include <Geom_Curve.hxx> |
23 | ||
24 | #include <BRep_Tool.hxx> | |
25 | #include <BRepBuilderAPI_MakeVertex.hxx> | |
26 | #include <BRepAdaptor_Curve.hxx> | |
27 | #include <BndLib_Add3dCurve.hxx> | |
1e143abb | 28 | #include <IntTools_Context.hxx> |
4e57c75e | 29 | #include <gp_Lin.hxx> |
30 | #include <ElCLib.hxx> | |
7fd59977 | 31 | |
32 | //======================================================================= | |
4e57c75e | 33 | //function : |
7fd59977 | 34 | //purpose : |
35 | //======================================================================= | |
1e143abb | 36 | IntTools_ShrunkRange::IntTools_ShrunkRange () |
7fd59977 | 37 | { |
4e57c75e | 38 | myT1=-99; |
39 | myT2=myT1; | |
40 | myTS1=myT1; | |
41 | myTS2=myT1; | |
42 | myErrorStatus=1; | |
7fd59977 | 43 | } |
7fd59977 | 44 | //======================================================================= |
505abfb8 | 45 | //function : ~ |
46 | //purpose : | |
47 | //======================================================================= | |
1e143abb | 48 | IntTools_ShrunkRange::~IntTools_ShrunkRange () |
505abfb8 | 49 | { |
50 | } | |
51 | //======================================================================= | |
4e57c75e | 52 | //function : SetData |
7fd59977 | 53 | //purpose : |
54 | //======================================================================= | |
1e143abb | 55 | void IntTools_ShrunkRange::SetData(const TopoDS_Edge& aE, |
56 | const Standard_Real aT1, | |
57 | const Standard_Real aT2, | |
58 | const TopoDS_Vertex& aV1, | |
59 | const TopoDS_Vertex& aV2) | |
7fd59977 | 60 | { |
61 | myEdge=aE; | |
62 | myV1=aV1; | |
63 | myV2=aV2; | |
4e57c75e | 64 | myT1=aT1; |
65 | myT2=aT2; | |
7fd59977 | 66 | myErrorStatus=1; |
4f189102 P |
67 | } |
68 | //======================================================================= | |
505abfb8 | 69 | //function : SetContext |
70 | //purpose : | |
71 | //======================================================================= | |
1e143abb | 72 | void IntTools_ShrunkRange::SetContext(const Handle(IntTools_Context)& aCtx) |
505abfb8 | 73 | { |
74 | myCtx=aCtx; | |
75 | } | |
76 | //======================================================================= | |
77 | //function : Context | |
78 | //purpose : | |
79 | //======================================================================= | |
1e143abb | 80 | const Handle(IntTools_Context)& IntTools_ShrunkRange::Context()const |
505abfb8 | 81 | { |
82 | return myCtx; | |
83 | } | |
84 | //======================================================================= | |
7fd59977 | 85 | //function : Edge |
86 | //purpose : | |
87 | //======================================================================= | |
1e143abb | 88 | const TopoDS_Edge& IntTools_ShrunkRange::Edge() const |
7fd59977 | 89 | { |
90 | return myEdge; | |
91 | } | |
92 | //======================================================================= | |
93 | //function : ShrunkRange | |
94 | //purpose : | |
95 | //======================================================================= | |
1e143abb | 96 | void IntTools_ShrunkRange::ShrunkRange(Standard_Real& aT1, |
97 | Standard_Real& aT2) const | |
7fd59977 | 98 | { |
4e57c75e | 99 | aT1=myTS1; |
100 | aT2=myTS2; | |
7fd59977 | 101 | } |
102 | //======================================================================= | |
103 | //function : BndBox | |
104 | //purpose : | |
105 | //======================================================================= | |
1e143abb | 106 | const Bnd_Box& IntTools_ShrunkRange::BndBox() const |
7fd59977 | 107 | { |
108 | return myBndBox; | |
109 | } | |
110 | //======================================================================= | |
4e57c75e | 111 | //function : ErrorStatus |
7fd59977 | 112 | //purpose : |
113 | //======================================================================= | |
1e143abb | 114 | Standard_Integer IntTools_ShrunkRange::ErrorStatus() const |
7fd59977 | 115 | { |
4e57c75e | 116 | return myErrorStatus; |
7fd59977 | 117 | } |
4e57c75e | 118 | |
7fd59977 | 119 | //======================================================================= |
4e57c75e | 120 | //function : SetShrunkRange |
7fd59977 | 121 | //purpose : |
122 | //======================================================================= | |
1e143abb | 123 | void IntTools_ShrunkRange::SetShrunkRange(const Standard_Real aT1, |
124 | const Standard_Real aT2) | |
7fd59977 | 125 | { |
4e57c75e | 126 | myTS1=aT1; |
127 | myTS2=aT2; | |
128 | // | |
129 | BRepAdaptor_Curve aBAC(myEdge); | |
130 | BndLib_Add3dCurve::Add (aBAC, aT1, aT2, 0., myBndBox); | |
7fd59977 | 131 | } |
4e57c75e | 132 | |
7fd59977 | 133 | //======================================================================= |
134 | //function : Perform | |
135 | //purpose : | |
136 | //======================================================================= | |
1e143abb | 137 | void IntTools_ShrunkRange::Perform() |
7fd59977 | 138 | { |
505abfb8 | 139 | Standard_Real aCF, aCL, aTolE, aTolV1; |
140 | Standard_Real aTolV2, t1, t11, t1C, t2, t12, t2C; | |
df32346f | 141 | Standard_Real aCoeff1, aCoeff2, aTol1, aTol2, dt1, dt2, aR, anEps; |
7fd59977 | 142 | Standard_Integer pri; |
4e57c75e | 143 | Standard_Boolean bInf1, bInf2, bAppr; |
7fd59977 | 144 | GeomAbs_CurveType aCurveType; |
145 | Handle(Geom_Curve) aC; | |
146 | // | |
4e57c75e | 147 | myErrorStatus=0; |
148 | myTS1=-99; | |
149 | myTS2=myTS1; | |
5f05c0a3 | 150 | anEps = 1.e-8; |
4f189102 | 151 | // |
7fd59977 | 152 | aTolE =BRep_Tool::Tolerance(myEdge); |
153 | aTolV1=BRep_Tool::Tolerance(myV1); | |
154 | aTolV2=BRep_Tool::Tolerance(myV2); | |
4e57c75e | 155 | //for edges with the tolerance value |
156 | //more than the tolerance value of vertices | |
157 | if (aTolV1 < aTolE) { | |
158 | aTolV1 = aTolE; | |
159 | } | |
4f189102 | 160 | // |
4e57c75e | 161 | if (aTolV2 < aTolE) { |
162 | aTolV2 = aTolE; | |
163 | } | |
164 | // | |
165 | t1=myT1; | |
166 | t2=myT2; | |
7fd59977 | 167 | // |
168 | BRepAdaptor_Curve aBAC(myEdge); | |
169 | aCurveType=aBAC.GetType(); | |
170 | // | |
171 | aC=BRep_Tool::Curve(myEdge, aCF, aCL); | |
172 | BRep_Tool::Range(myEdge, aCF, aCL); | |
173 | // | |
174 | if (t1 < aCF || t2 > aCL) { | |
175 | myErrorStatus=2; | |
176 | return; | |
177 | } | |
178 | // | |
505abfb8 | 179 | bAppr = !(fabs(t2 - t1) > 100); |
5f05c0a3 | 180 | if (fabs(t2 - t1) < anEps) { |
4e57c75e | 181 | myErrorStatus=7; |
182 | return; | |
183 | } | |
184 | // | |
185 | if (t1 > t2) { | |
7fd59977 | 186 | myErrorStatus=3; |
187 | return; | |
188 | } | |
189 | // | |
df32346f | 190 | aTol1 = aTolV1+aTolE; |
191 | aTol2 = aTolV2+aTolE; | |
192 | // | |
193 | aCoeff1 = (aTolE>0.05) ? 1. : 2.; | |
194 | aCoeff2 = aCoeff1; | |
195 | if (aCoeff1 == 2.) { | |
196 | aCoeff1=(aTol1>0.05) ? 1.5 : 2.; | |
197 | aCoeff2=(aTol2>0.05) ? 1.5 : 2.; | |
198 | } | |
7fd59977 | 199 | // xf |
df32346f | 200 | if (aCurveType==GeomAbs_Line && (aCoeff1 != 1 || aCoeff2 != 1)) { |
7fd59977 | 201 | Standard_Real aTV1, aTV2, aEps; |
202 | gp_Pnt aPV1, aPV2, aPC1, aPC2; | |
203 | gp_Lin aL; | |
204 | // | |
205 | aEps=Precision::Confusion(); | |
206 | aEps=aEps*aEps;//1.e-14; | |
207 | aL=aBAC.Line(); | |
208 | // | |
209 | aPV1=BRep_Tool::Pnt(myV1); | |
210 | aTV1=ElCLib::Parameter(aL, aPV1); | |
211 | // | |
212 | aPV2=BRep_Tool::Pnt(myV2); | |
213 | aTV2=ElCLib::Parameter(aL, aPV2); | |
214 | // | |
df32346f | 215 | if (fabs(aTV1-aCF)<aEps) { |
216 | aCoeff1=1.; | |
217 | } | |
218 | if (fabs(aTV2-aCL)<aEps) { | |
219 | aCoeff2=1.; | |
7fd59977 | 220 | } |
221 | } | |
222 | // | |
df32346f | 223 | dt1=aCoeff1*aTol1; |
224 | dt2=aCoeff2*aTol2; | |
7fd59977 | 225 | // xt |
226 | // | |
227 | if (aCurveType==GeomAbs_Line) { | |
228 | Standard_Real dt1x, dt2x; | |
229 | ||
230 | dt1x = aBAC.Resolution(dt1); | |
231 | t11=t1+dt1x; | |
232 | ||
233 | dt2x = aBAC.Resolution(dt2); | |
234 | t12=t2-dt2x; | |
235 | ||
236 | if (t11>t2 || t12<t1) { | |
237 | t1C=t1; | |
238 | t2C=t2; | |
4e57c75e | 239 | myTS1=t1C; |
240 | myTS2=t2C; | |
7fd59977 | 241 | // |
242 | // BndBox | |
243 | Standard_Real ddx=aTolE;//1.e-12; | |
244 | BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox); | |
245 | ||
4e57c75e | 246 | myErrorStatus=6;//0 |
7fd59977 | 247 | return; |
248 | } | |
249 | } | |
250 | // | |
251 | if (aCurveType==GeomAbs_Circle) { | |
252 | gp_Circ aCrc=aBAC.Circle(); | |
253 | aR=aCrc.Radius(); | |
254 | t1C=t1+dt1/aR; | |
255 | t2C=t2-dt2/aR; | |
256 | } | |
7fd59977 | 257 | else { |
258 | // | |
259 | // Vertex1 => t1C | |
260 | gp_Pnt aP1,aP11; | |
261 | aC->D0 (t1, aP1); | |
262 | // | |
263 | bInf1=Precision::IsNegativeInfinite(t1); | |
264 | if (bInf1) { | |
265 | t1C=t1; | |
266 | } | |
267 | // | |
268 | else { | |
df32346f | 269 | Standard_Real d1 = aCoeff1*aTol1; |
7fd59977 | 270 | // dt1 = aBAC.Resolution(d1); |
271 | // | |
272 | gp_Vec aD1vec1; | |
273 | gp_Pnt aPoint; | |
274 | aBAC.D1(t1, aPoint, aD1vec1); | |
275 | Standard_Real ad1length1 = aD1vec1.Magnitude(); | |
276 | Standard_Boolean bTryOtherPoints = Standard_False; | |
277 | dt1 = (t2 - t1) * 0.5; | |
278 | ||
279 | if(ad1length1 > 1.e-12) { | |
4e57c75e | 280 | dt1 = d1 / ad1length1; |
281 | ||
282 | if(dt1 > (t2 - t1)) { | |
283 | // bad parametrization, big tolerance or too small range | |
284 | bTryOtherPoints = Standard_True; | |
285 | } | |
7fd59977 | 286 | } |
287 | else { | |
4e57c75e | 288 | bTryOtherPoints = Standard_True; |
7fd59977 | 289 | } |
4e57c75e | 290 | |
7fd59977 | 291 | if(bTryOtherPoints) { |
4e57c75e | 292 | Standard_Integer nbsamples = 5; |
293 | Standard_Integer ii = 0; | |
294 | Standard_Real adelta = (t2 - t1) / (nbsamples + 1); | |
295 | Standard_Boolean bFound = Standard_False; | |
296 | ||
297 | for(ii = 1; ii <= nbsamples; ii++) { | |
298 | Standard_Real aparameter = t1 + (adelta * ii); | |
299 | gp_Pnt aPoint2; | |
300 | aBAC.D1(aparameter, aPoint2, aD1vec1); | |
301 | ||
302 | if(aPoint.Distance(aPoint2) < d1) | |
303 | dt1 = adelta * ii; | |
304 | ad1length1 = aD1vec1.Magnitude(); | |
305 | ||
306 | if(ad1length1 > 1.e-12) { | |
307 | dt1 = d1 / ad1length1; | |
308 | ||
309 | if(dt1 < (t2 - t1)) { | |
310 | bFound = Standard_True; | |
311 | break; | |
312 | } | |
313 | } | |
314 | } | |
315 | ||
316 | if(!bFound) { | |
317 | if(dt1 > (t2 - t1)) { | |
318 | dt1 = aBAC.Resolution(d1); | |
d46546cd | 319 | if (dt1 > (t2 - t1)) { |
320 | myErrorStatus = 7; | |
321 | return; | |
322 | } | |
4e57c75e | 323 | } |
324 | } | |
7fd59977 | 325 | } |
326 | // | |
4e57c75e | 327 | if (!bAppr) { |
328 | dt1 *= 10; | |
329 | } | |
7fd59977 | 330 | t11=t1+dt1; |
331 | aC->D0 (t11, aP11); | |
332 | ||
333 | gp_Vec aV11(aP1, aP11); | |
334 | // avoid exception if aP1 == aP11 | |
335 | if (aV11.SquareMagnitude() < gp::Resolution()) | |
336 | t1C = t1; | |
337 | else { | |
338 | gp_Dir aD11(aV11); | |
339 | ||
340 | gp_Pnt aP1L; | |
341 | // | |
342 | aP1L.SetCoord (aP1.X()+d1*aD11.X(), | |
343 | aP1.Y()+d1*aD11.Y(), | |
344 | aP1.Z()+d1*aD11.Z()); | |
345 | ||
346 | BRepBuilderAPI_MakeVertex aMV1(aP1L); | |
347 | const TopoDS_Vertex& aV1L=aMV1.Vertex(); | |
348 | // | |
4e57c75e | 349 | pri=myCtx->ComputeVE (aV1L, myEdge, t1C); |
7fd59977 | 350 | // |
351 | if (pri==-3) { | |
4e57c75e | 352 | myErrorStatus=4; |
353 | return; | |
7fd59977 | 354 | } |
355 | } | |
356 | } | |
357 | // | |
358 | // Vertex2 => t2C | |
359 | gp_Pnt aP2, aP12; | |
360 | aC->D0 (t2, aP2); | |
361 | // | |
362 | bInf2=Precision::IsPositiveInfinite(t2); | |
363 | if (bInf2) { | |
364 | t2C=t2; | |
365 | } | |
366 | // | |
367 | else { | |
df32346f | 368 | Standard_Real d2 = aCoeff2*aTol2; |
7fd59977 | 369 | // dt2 = aBAC.Resolution(d2); |
370 | ||
371 | // | |
372 | gp_Vec aD1vec2; | |
373 | gp_Pnt aPoint; | |
374 | aBAC.D1(t2, aPoint, aD1vec2); | |
375 | Standard_Real ad1length2 = aD1vec2.Magnitude(); | |
376 | Standard_Boolean bTryOtherPoints = Standard_False; | |
377 | dt2 = (t2 - t1) * 0.5; | |
378 | ||
379 | if(ad1length2 > 1.e-12) { | |
4e57c75e | 380 | dt2 = d2 / ad1length2; |
381 | ||
382 | if(dt2 > (t2 - t1)) { | |
383 | bTryOtherPoints = Standard_True; | |
384 | } | |
7fd59977 | 385 | } |
386 | else { | |
4e57c75e | 387 | bTryOtherPoints = Standard_True; |
7fd59977 | 388 | } |
389 | ||
390 | if(bTryOtherPoints) { | |
4e57c75e | 391 | Standard_Integer nbsamples = 5; |
392 | Standard_Integer ii = 0; | |
393 | Standard_Real adelta = (t2 - t1) / (nbsamples + 1); | |
394 | Standard_Boolean bFound = Standard_False; | |
395 | ||
396 | for(ii = 1; ii <= nbsamples; ii++) { | |
397 | Standard_Real aparameter = t2 - (adelta * ii); | |
398 | gp_Pnt aPoint2; | |
399 | aBAC.D1(aparameter, aPoint2, aD1vec2); | |
400 | ||
401 | if(aPoint.Distance(aPoint2) < d2) | |
402 | dt2 = adelta * ii; | |
403 | ad1length2 = aD1vec2.Magnitude(); | |
404 | ||
405 | if(ad1length2 > 1.e-12) { | |
406 | dt2 = d2 / ad1length2; | |
407 | ||
408 | if(dt2 < (t2 - t1)) { | |
409 | bFound = Standard_True; | |
410 | break; | |
411 | } | |
412 | } | |
413 | } | |
414 | ||
415 | if(!bFound) { | |
416 | if(dt2 > (t2 - t1)) { | |
417 | dt2 = aBAC.Resolution(d2); | |
d46546cd | 418 | if(dt2 > (t2 - t1)) { |
419 | myErrorStatus = 7; | |
420 | return; | |
421 | } | |
4e57c75e | 422 | } |
423 | } | |
7fd59977 | 424 | } |
425 | // | |
4e57c75e | 426 | if (!bAppr) { |
427 | dt2 *= 10; | |
428 | } | |
429 | ||
7fd59977 | 430 | t12=t2-dt2; |
431 | aC->D0 (t12, aP12); | |
432 | ||
433 | gp_Vec aV12(aP2, aP12); | |
434 | // avoid exception if aP1 == aP11 | |
435 | if (aV12.SquareMagnitude() < gp::Resolution()) | |
436 | t2C = t2; | |
437 | else { | |
438 | gp_Dir aD12(aV12); | |
439 | ||
440 | gp_Pnt aP2L; | |
441 | // | |
442 | aP2L.SetCoord (aP2.X()+d2*aD12.X(), | |
443 | aP2.Y()+d2*aD12.Y(), | |
444 | aP2.Z()+d2*aD12.Z()); | |
445 | ||
446 | BRepBuilderAPI_MakeVertex aMV2(aP2L); | |
447 | const TopoDS_Vertex& aV2L=aMV2.Vertex(); | |
448 | // | |
4e57c75e | 449 | pri=myCtx->ComputeVE (aV2L, myEdge, t2C); |
7fd59977 | 450 | // |
451 | if (pri==-3) { | |
4e57c75e | 452 | myErrorStatus=5; |
453 | return; | |
7fd59977 | 454 | } |
455 | } | |
456 | } | |
457 | } // else { | |
505abfb8 | 458 | // |
7fd59977 | 459 | if (t1C>t2){ |
460 | t1C=0.5*(t2+t1); | |
461 | t2C=t1C+0.1*(t2-t1C); | |
462 | } | |
463 | ||
464 | if (t1C>t2C) { | |
465 | t2C=t1C+0.1*(t2-t1C); | |
466 | } | |
4e57c75e | 467 | // |
5f05c0a3 | 468 | if (t2C-t1C < anEps) { |
4e57c75e | 469 | myErrorStatus = 7; |
470 | return; | |
471 | } | |
472 | // | |
473 | myTS1=t1C; | |
474 | myTS2=t2C; | |
7fd59977 | 475 | // |
476 | // BndBox | |
477 | Standard_Real ddx=aTolE;//1.e-12; | |
478 | BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox); | |
7fd59977 | 479 | } |
7fd59977 | 480 | ///////////////////////////////////////////////////////////////////////// |
481 | // | |
482 | // myErrorStatus : | |
483 | // | |
484 | // 1- Nothing has been done | |
485 | // 2- The source range is out of the edge's range | |
486 | // 3- t1 < t2 for source range | |
487 | // 4- Can not project V1L to the Edge; | |
488 | // 5- Can not project V2L to the Edge; | |
489 | // 6- for obtained shrunk range [t11, t12] -> t11>t2 || t12<t1; | |
4e57c75e | 490 | // 7- too small range. |