0024639: Parallelization FillDS part of BO
[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//=======================================================================
505abfb8 45//function : ~
46//purpose :
47//=======================================================================
48BOPInt_ShrunkRange::~BOPInt_ShrunkRange ()
49{
50}
51//=======================================================================
4e57c75e 52//function : SetData
7fd59977 53//purpose :
54//=======================================================================
505abfb8 55void BOPInt_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//=======================================================================
72void BOPInt_ShrunkRange::SetContext(const Handle(BOPInt_Context)& aCtx)
73{
74 myCtx=aCtx;
75}
76//=======================================================================
77//function : Context
78//purpose :
79//=======================================================================
80const Handle(BOPInt_Context)& BOPInt_ShrunkRange::Context()const
81{
82 return myCtx;
83}
84//=======================================================================
7fd59977 85//function : Edge
86//purpose :
87//=======================================================================
505abfb8 88const TopoDS_Edge& BOPInt_ShrunkRange::Edge() const
7fd59977 89{
90 return myEdge;
91}
92//=======================================================================
93//function : ShrunkRange
94//purpose :
95//=======================================================================
505abfb8 96void BOPInt_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//=======================================================================
505abfb8 106const Bnd_Box& BOPInt_ShrunkRange::BndBox() const
7fd59977 107{
108 return myBndBox;
109}
110//=======================================================================
4e57c75e 111//function : ErrorStatus
7fd59977 112//purpose :
113//=======================================================================
505abfb8 114Standard_Integer BOPInt_ShrunkRange::ErrorStatus() const
7fd59977 115{
4e57c75e 116 return myErrorStatus;
7fd59977 117}
4e57c75e 118
7fd59977 119//=======================================================================
4e57c75e 120//function : SetShrunkRange
7fd59977 121//purpose :
122//=======================================================================
505abfb8 123void BOPInt_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//=======================================================================
505abfb8 137void BOPInt_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);
319 }
320 }
7fd59977 321 }
322 //
4e57c75e 323 if (!bAppr) {
324 dt1 *= 10;
325 }
7fd59977 326 t11=t1+dt1;
327 aC->D0 (t11, aP11);
328
329 gp_Vec aV11(aP1, aP11);
330 // avoid exception if aP1 == aP11
331 if (aV11.SquareMagnitude() < gp::Resolution())
332 t1C = t1;
333 else {
334 gp_Dir aD11(aV11);
335
336 gp_Pnt aP1L;
337 //
338 aP1L.SetCoord (aP1.X()+d1*aD11.X(),
339 aP1.Y()+d1*aD11.Y(),
340 aP1.Z()+d1*aD11.Z());
341
342 BRepBuilderAPI_MakeVertex aMV1(aP1L);
343 const TopoDS_Vertex& aV1L=aMV1.Vertex();
344 //
4e57c75e 345 pri=myCtx->ComputeVE (aV1L, myEdge, t1C);
7fd59977 346 //
347 if (pri==-3) {
4e57c75e 348 myErrorStatus=4;
349 return;
7fd59977 350 }
351 }
352 }
353 //
354 // Vertex2 => t2C
355 gp_Pnt aP2, aP12;
356 aC->D0 (t2, aP2);
357 //
358 bInf2=Precision::IsPositiveInfinite(t2);
359 if (bInf2) {
360 t2C=t2;
361 }
362 //
363 else {
df32346f 364 Standard_Real d2 = aCoeff2*aTol2;
7fd59977 365 // dt2 = aBAC.Resolution(d2);
366
367 //
368 gp_Vec aD1vec2;
369 gp_Pnt aPoint;
370 aBAC.D1(t2, aPoint, aD1vec2);
371 Standard_Real ad1length2 = aD1vec2.Magnitude();
372 Standard_Boolean bTryOtherPoints = Standard_False;
373 dt2 = (t2 - t1) * 0.5;
374
375 if(ad1length2 > 1.e-12) {
4e57c75e 376 dt2 = d2 / ad1length2;
377
378 if(dt2 > (t2 - t1)) {
379 bTryOtherPoints = Standard_True;
380 }
7fd59977 381 }
382 else {
4e57c75e 383 bTryOtherPoints = Standard_True;
7fd59977 384 }
385
386 if(bTryOtherPoints) {
4e57c75e 387 Standard_Integer nbsamples = 5;
388 Standard_Integer ii = 0;
389 Standard_Real adelta = (t2 - t1) / (nbsamples + 1);
390 Standard_Boolean bFound = Standard_False;
391
392 for(ii = 1; ii <= nbsamples; ii++) {
393 Standard_Real aparameter = t2 - (adelta * ii);
394 gp_Pnt aPoint2;
395 aBAC.D1(aparameter, aPoint2, aD1vec2);
396
397 if(aPoint.Distance(aPoint2) < d2)
398 dt2 = adelta * ii;
399 ad1length2 = aD1vec2.Magnitude();
400
401 if(ad1length2 > 1.e-12) {
402 dt2 = d2 / ad1length2;
403
404 if(dt2 < (t2 - t1)) {
405 bFound = Standard_True;
406 break;
407 }
408 }
409 }
410
411 if(!bFound) {
412 if(dt2 > (t2 - t1)) {
413 dt2 = aBAC.Resolution(d2);
414 }
415 }
7fd59977 416 }
417 //
4e57c75e 418 if (!bAppr) {
419 dt2 *= 10;
420 }
421
7fd59977 422 t12=t2-dt2;
423 aC->D0 (t12, aP12);
424
425 gp_Vec aV12(aP2, aP12);
426 // avoid exception if aP1 == aP11
427 if (aV12.SquareMagnitude() < gp::Resolution())
428 t2C = t2;
429 else {
430 gp_Dir aD12(aV12);
431
432 gp_Pnt aP2L;
433 //
434 aP2L.SetCoord (aP2.X()+d2*aD12.X(),
435 aP2.Y()+d2*aD12.Y(),
436 aP2.Z()+d2*aD12.Z());
437
438 BRepBuilderAPI_MakeVertex aMV2(aP2L);
439 const TopoDS_Vertex& aV2L=aMV2.Vertex();
440 //
4e57c75e 441 pri=myCtx->ComputeVE (aV2L, myEdge, t2C);
7fd59977 442 //
443 if (pri==-3) {
4e57c75e 444 myErrorStatus=5;
445 return;
7fd59977 446 }
447 }
448 }
449 } // else {
505abfb8 450 //
7fd59977 451 if (t1C>t2){
452 t1C=0.5*(t2+t1);
453 t2C=t1C+0.1*(t2-t1C);
454 }
455
456 if (t1C>t2C) {
457 t2C=t1C+0.1*(t2-t1C);
458 }
4e57c75e 459 //
5f05c0a3 460 if (t2C-t1C < anEps) {
4e57c75e 461 myErrorStatus = 7;
462 return;
463 }
464 //
465 myTS1=t1C;
466 myTS2=t2C;
7fd59977 467 //
468 // BndBox
469 Standard_Real ddx=aTolE;//1.e-12;
470 BndLib_Add3dCurve::Add (aBAC, t1C, t2C, ddx, myBndBox);
7fd59977 471}
7fd59977 472/////////////////////////////////////////////////////////////////////////
473//
474// myErrorStatus :
475//
476// 1- Nothing has been done
477// 2- The source range is out of the edge's range
478// 3- t1 < t2 for source range
479// 4- Can not project V1L to the Edge;
480// 5- Can not project V2L to the Edge;
481// 6- for obtained shrunk range [t11, t12] -> t11>t2 || t12<t1;
4e57c75e 482// 7- too small range.