0023749: Tests cases boolean bsection M9 N4 work incorrect with new Boolean Operation...
[occt.git] / src / BOPInt / BOPInt_ShrunkRange.cxx
CommitLineData
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.