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