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