0025937: Failed Cut Edge or Face by HalfSpace.
[occt.git] / src / IntTools / IntTools_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
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 48IntTools_ShrunkRange::~IntTools_ShrunkRange ()
505abfb8 49{
50}
51//=======================================================================
4e57c75e 52//function : SetData
7fd59977 53//purpose :
54//=======================================================================
1e143abb 55void 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 72void IntTools_ShrunkRange::SetContext(const Handle(IntTools_Context)& aCtx)
505abfb8 73{
74 myCtx=aCtx;
75}
76//=======================================================================
77//function : Context
78//purpose :
79//=======================================================================
1e143abb 80const Handle(IntTools_Context)& IntTools_ShrunkRange::Context()const
505abfb8 81{
82 return myCtx;
83}
84//=======================================================================
7fd59977 85//function : Edge
86//purpose :
87//=======================================================================
1e143abb 88const TopoDS_Edge& IntTools_ShrunkRange::Edge() const
7fd59977 89{
90 return myEdge;
91}
92//=======================================================================
93//function : ShrunkRange
94//purpose :
95//=======================================================================
1e143abb 96void 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 106const Bnd_Box& IntTools_ShrunkRange::BndBox() const
7fd59977 107{
108 return myBndBox;
109}
110//=======================================================================
4e57c75e 111//function : ErrorStatus
7fd59977 112//purpose :
113//=======================================================================
1e143abb 114Standard_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 123void 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 137void 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.