0029351: Boolean Operations create invalid pcurves
[occt.git] / src / BOPTools / BOPTools_AlgoTools2D.cxx
CommitLineData
b311480e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 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.
7fd59977 14
7fd59977 15
42cf5bc1 16#include <BOPTools_AlgoTools2D.hxx>
17#include <BRep_Builder.hxx>
18#include <BRep_CurveRepresentation.hxx>
19#include <BRep_GCurve.hxx>
20#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21#include <BRep_TEdge.hxx>
22#include <BRep_Tool.hxx>
23#include <BRepAdaptor_Curve.hxx>
24#include <BRepAdaptor_HSurface.hxx>
25#include <BRepAdaptor_Surface.hxx>
26#include <BRepClass_FaceClassifier.hxx>
27#include <BRepTools.hxx>
28#include <Geom2d_BSplineCurve.hxx>
7fd59977 29#include <Geom2d_Circle.hxx>
42cf5bc1 30#include <Geom2d_Curve.hxx>
7fd59977 31#include <Geom2d_Ellipse.hxx>
7fd59977 32#include <Geom2d_Hyperbola.hxx>
42cf5bc1 33#include <Geom2d_Line.hxx>
34#include <Geom2d_Parabola.hxx>
f1baf495 35#include <Geom2d_TrimmedCurve.hxx>
f1baf495 36#include <Geom2dAdaptor.hxx>
7fd59977 37#include <Geom_Curve.hxx>
f1baf495 38#include <Geom_Plane.hxx>
42cf5bc1 39#include <Geom_RectangularTrimmedSurface.hxx>
40#include <Geom_Surface.hxx>
41#include <Geom_TrimmedCurve.hxx>
f1baf495 42#include <GeomAdaptor_Curve.hxx>
43#include <GeomAdaptor_HCurve.hxx>
44#include <GeomAdaptor_HSurface.hxx>
42cf5bc1 45#include <GeomAdaptor_Surface.hxx>
46#include <GeomInt.hxx>
0a807dd9 47#include <GeomLib.hxx>
f1baf495 48#include <GeomProjLib.hxx>
42cf5bc1 49#include <gp.hxx>
fc88faf1 50#include <gp_Cylinder.hxx>
42cf5bc1 51#include <gp_Pnt.hxx>
52#include <gp_Pnt2d.hxx>
53#include <gp_Vec.hxx>
54#include <gp_Vec2d.hxx>
55#include <IntTools_Context.hxx>
56#include <IntTools_Tools.hxx>
57#include <Precision.hxx>
58#include <ProjLib_ProjectedCurve.hxx>
f48cb55d 59#include <ProjLib.hxx>
42cf5bc1 60#include <Standard_ConstructionError.hxx>
61#include <Standard_NotImplemented.hxx>
62#include <TopExp.hxx>
fc88faf1 63#include <TopExp_Explorer.hxx>
42cf5bc1 64#include <TopLoc_Location.hxx>
65#include <TopoDS_Edge.hxx>
66#include <TopoDS_Face.hxx>
7fd59977 67
fc88faf1 68static
69 Standard_Real MaxToleranceEdge (const TopoDS_Face& );
7fd59977 70
4e57c75e 71//=======================================================================
72//function : BuildPCurveForEdgeOnFace
73//purpose :
74//=======================================================================
f1baf495 75void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
51db0179 76 const TopoDS_Face& aF,
77 const Handle(IntTools_Context)& theContext)
4e57c75e 78{
79 BRep_Builder aBB;
80 Handle(Geom2d_Curve) aC2D;
81 Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast;
82
83 Standard_Boolean aHasOld;
f1baf495 84 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D,
85 aFirst, aLast,
86 aTolEdge);
4e57c75e 87 if (aHasOld) {
88 return;
89 }
90
91
51db0179 92 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC, theContext);
4e57c75e 93
94 aTolEdge=BRep_Tool::Tolerance(aE);
95
96 aTolFact=Max(aTolEdge, aTolPC);
97
98 aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
99 return;
100}
101
7fd59977 102//=======================================================================
103//function : EdgeTangent
104//purpose :
105//=======================================================================
f1baf495 106Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
107 (const TopoDS_Edge& anEdge,
108 const Standard_Real aT,
109 gp_Vec& aTau)
7fd59977 110{
111 Standard_Boolean isdgE;
112 Standard_Real first, last;
113
114 isdgE = BRep_Tool::Degenerated(anEdge);
115 if (isdgE) {
116 return Standard_False;
117 }
7fd59977 118
119 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
120 gp_Pnt aP;
121 aC->D1(aT, aP, aTau);
122 Standard_Real mod = aTau.Magnitude();
123 if(mod > gp::Resolution()) {
124 aTau /= mod;
125 }
126 else {
127 return Standard_False;
128 }
129 //aTau.Normalize();
130 if (anEdge.Orientation() == TopAbs_REVERSED){
131 aTau.Reverse();
132 }
133 return Standard_True;
134}
135
7fd59977 136//=======================================================================
137//function : PointOnOnSurface
138//purpose :
139//=======================================================================
f1baf495 140void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
141 const TopoDS_Face& aF,
142 const Standard_Real aParameter,
143 Standard_Real& U,
51db0179 144 Standard_Real& V,
145 const Handle(IntTools_Context)& theContext)
7fd59977 146{
147 gp_Pnt2d aP2D;
148 Handle(Geom2d_Curve) aC2D;
149 Standard_Real aToler, aFirst, aLast;
150
51db0179 151 BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D, aFirst, aLast, aToler, theContext);
7fd59977 152 aC2D->D0(aParameter, aP2D);
153 U=aP2D.X();
154 V=aP2D.Y();
155 return;
156}
157
158//=======================================================================
159//function : CurveOnSurface
160//purpose :
161//=======================================================================
f1baf495 162void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
163 const TopoDS_Face& aF,
164 Handle(Geom2d_Curve)& aC2D,
51db0179 165 Standard_Real& aToler,
166 const Handle(IntTools_Context)& theContext)
7fd59977 167{
168 Standard_Real aFirst, aLast;
f1baf495 169 //
51db0179 170 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aFirst, aLast, aToler, theContext);
f1baf495 171 //
7fd59977 172 return;
173}
174//=======================================================================
175//function : CurveOnSurface
176//purpose :
177//=======================================================================
f1baf495 178void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
179 const TopoDS_Face& aF,
180 Handle(Geom2d_Curve)& aC2D,
181 Standard_Real& aFirst,
182 Standard_Real& aLast,
51db0179 183 Standard_Real& aToler,
184 const Handle(IntTools_Context)& theContext)
7fd59977 185{
186 Standard_Boolean aHasOld;
187 Handle(Geom2d_Curve) C2D;
188
f1baf495 189 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D,
190 aFirst, aLast,
191 aToler);
7fd59977 192 if (aHasOld) {
193 aC2D=C2D;
194 return;
195 }
196
51db0179 197 BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler, theContext);
7fd59977 198 aC2D=C2D;
199 return;
200}
7fd59977 201//=======================================================================
202//function : HasCurveOnSurface
203//purpose :
204//=======================================================================
f1baf495 205Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
206 (const TopoDS_Edge& aE,
207 const TopoDS_Face& aF,
208 Handle(Geom2d_Curve)& aC2D,
209 Standard_Real& aFirst,
210 Standard_Real& aLast,
211 Standard_Real& aToler)
7fd59977 212{
213 Standard_Boolean aHasOld;
214
215 aToler=BRep_Tool::Tolerance(aE);
216 BRep_Tool::Range(aE, aFirst, aLast);
217
218 if((aLast - aFirst) < Precision::PConfusion()) {
219 return Standard_False;
220 }
221
f1baf495 222 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
7fd59977 223 aHasOld=!aC2D.IsNull();
224 return aHasOld;
225}
226//=======================================================================
227//function : HasCurveOnSurface
228//purpose :
229//=======================================================================
f1baf495 230Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
231 (const TopoDS_Edge& aE,
232 const TopoDS_Face& aF)
7fd59977 233{
f1baf495 234 Standard_Boolean bHasOld;
7fd59977 235 Handle(Geom2d_Curve) aC2D;
236 Standard_Real aFirst, aLast;
f1baf495 237 //
7fd59977 238 BRep_Tool::Range(aE, aFirst, aLast);
f1baf495 239 //
7fd59977 240 if((aLast - aFirst) < Precision::PConfusion()) {
241 return Standard_False;
242 }
f1baf495 243 //
244 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
245 bHasOld=!aC2D.IsNull();
246 //
247 return bHasOld;
7fd59977 248}
7fd59977 249//=======================================================================
250//function : AdjustPCurveOnFace
251//purpose :
252//=======================================================================
51db0179 253void BOPTools_AlgoTools2D::AdjustPCurveOnFace
254 (const TopoDS_Face& theF,
255 const Handle(Geom_Curve)& theC3D,
256 const Handle(Geom2d_Curve)& theC2D,
257 Handle(Geom2d_Curve)& theC2DA,
258 const Handle(IntTools_Context)& theContext)
7fd59977 259{
51db0179 260 Standard_Real aT1 = theC3D->FirstParameter();
261 Standard_Real aT2 = theC3D->LastParameter();
fd372378 262 //
51db0179 263 BOPTools_AlgoTools2D::AdjustPCurveOnFace (theF, aT1, aT2, theC2D, theC2DA, theContext);
fd372378 264}
7fd59977 265//=======================================================================
266//function : AdjustPCurveOnFace
267//purpose :
268//=======================================================================
f1baf495 269void BOPTools_AlgoTools2D::AdjustPCurveOnFace
51db0179 270 (const TopoDS_Face& theF,
271 const Standard_Real theFirst,
272 const Standard_Real theLast,
273 const Handle(Geom2d_Curve)& theC2D,
274 Handle(Geom2d_Curve)& theC2DA,
275 const Handle(IntTools_Context)& theContext)
fd372378 276{
51db0179 277 BRepAdaptor_Surface aBASTmp;
278 const BRepAdaptor_Surface* pBAS;
279 if (!theContext.IsNull()) {
280 pBAS = &theContext->SurfaceAdaptor(theF);
281 }
282 else {
283 aBASTmp.Initialize(theF, Standard_True);
284 pBAS = &aBASTmp;
285 }
fd372378 286 //
51db0179 287 BOPTools_AlgoTools2D::AdjustPCurveOnSurf(*pBAS, theFirst, theLast, theC2D, theC2DA);
fd372378 288}
fd372378 289//=======================================================================
290//function : AdjustPCurveOnFace
291//purpose :
292//=======================================================================
51db0179 293void BOPTools_AlgoTools2D::AdjustPCurveOnSurf
fd372378 294 (const BRepAdaptor_Surface& aBAS,
f1baf495 295 const Standard_Real aFirst,
296 const Standard_Real aLast,
51db0179 297 const Handle(Geom2d_Curve)& aC2D,
f1baf495 298 Handle(Geom2d_Curve)& aC2DA)
7fd59977 299{
655fddc8 300 Standard_Boolean mincond, maxcond;
7fd59977 301 Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
655fddc8 302 Standard_Real aUPeriod;
7fd59977 303 //
fd372378 304 const TopoDS_Face& aF=aBAS.Face();
305 UMin=aBAS.FirstUParameter();
306 UMax=aBAS.LastUParameter();
307 VMin=aBAS.FirstVParameter();
308 VMax=aBAS.LastVParameter();
309 //
fd372378 310 aDelta=Precision::PConfusion();
7fd59977 311
312 aT =.5*(aFirst+aLast);
313
314 gp_Pnt2d pC2D;
315 aC2D->D0(aT, pC2D);
316
317 u2 = pC2D.X();
318 v2 = pC2D.Y();
fc88faf1 319 //
320 // du
7fd59977 321 du = 0.;
322 if (aBAS.IsUPeriodic()) {
655fddc8 323 aUPeriod = aBAS.UPeriod();
fd372378 324
7fd59977 325 //
67e36f0c 326 // a. try to clarify u2 using the precision (aDelta)
327 if (fabs(u2-UMin) < aDelta) {
328 u2=UMin;
329 }
330 else if (fabs(u2-UMin-aUPeriod) < aDelta) {
9c0b61f3 331 u2=UMin+aUPeriod;
332 }
67e36f0c 333 // b. compute du again using clarified value of u2
334 GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
fc88faf1 335 //
336 if (du==0.) {
337 if (aBAS.GetType()==GeomAbs_Cylinder) {
338 Standard_Real aR, dFi, aTol;
339 //
340 gp_Cylinder aCylinder=aBAS.Cylinder();
341 aR=aCylinder.Radius();
342 aTol=MaxToleranceEdge(aF);
343 dFi=aTol/aR;
344 if (dFi<aDelta) {
345 dFi=aDelta;
346 }
347 //
348 mincond = (UMin - u2 > dFi);
349 maxcond = (u2 - UMax > dFi);
350 if (mincond || maxcond) {
351 du = ( mincond ) ? aUPeriod : -aUPeriod;
352 }
353 }
354 }
655fddc8 355 }
fc88faf1 356
7fd59977 357 // dv
358 dv = 0.;
359 if (aBAS.IsVPeriodic()) {
360 Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
361 //
655fddc8 362 aVPeriod = aBAS.VPeriod();
7fd59977 363 mincond = (VMin - v2 > aDelta);
364 maxcond = (v2 - VMax > aDelta);
655fddc8 365 //
366 if (mincond || maxcond) {
7fd59977 367 dv = ( mincond ) ? aVPeriod : -aVPeriod;
368 }
369 //
7fd59977 370 if ((VMax-VMin<aVPeriod) && dv) {
371 aVm=v2;
372 aVr=v2+dv;
373 aVmid=0.5*(VMin+VMax);
374 dVm=fabs(aVm-aVmid);
375 dVr=fabs(aVr-aVmid);
376 if (dVm<dVr) {
4e57c75e 377 dv=0.;
7fd59977 378 }
379 }
7fd59977 380 }
381 //
d8a24e83 382 {
383 //check the point with classifier
384 Standard_Real u,v;
385 u = u2 + du;
386 v = v2 + dv;
387 if (aBAS.IsUPeriodic()) {
388 aUPeriod = aBAS.UPeriod();
389 if ((UMax - UMin - 2*aDelta) > aUPeriod) {
390 if ((u > (UMin + aDelta + aUPeriod)) ||
391 (u < (UMax - aDelta - aUPeriod))) {
392 BRepClass_FaceClassifier aClassifier;
393 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
394 TopAbs_State Status = aClassifier.State();
395 if (Status == TopAbs_OUT) {
396 du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
397 }
398 }
399 }
400 }
401 //
402 u = u2 + du;
403 if (aBAS.IsVPeriodic()) {
404 Standard_Real aVPeriod = aBAS.VPeriod();
405 if ((VMax - VMin - 2*aDelta) > aVPeriod) {
406 if ((v > (VMin + aDelta + aVPeriod)) ||
407 (v < (VMax - aDelta - aVPeriod))) {
408 BRepClass_FaceClassifier aClassifier;
409 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
410 TopAbs_State Status = aClassifier.State();
411 if (Status == TopAbs_OUT) {
412 dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
413 }
414 }
415 }
416 }
417 }
7fd59977 418 // Translation if necessary
419 Handle(Geom2d_Curve) aC2Dx=aC2D;
420
421 if ( du != 0. || dv != 0.) {
422 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
423 gp_Vec2d aV2D(du,dv);
424 PCT->Translate(aV2D);
425 aC2Dx = PCT;
426 }
427
428 aC2DA=aC2Dx;
429}
430
4e57c75e 431//=======================================================================
432//function : IntermediatePoint
433//purpose :
434//=======================================================================
f1baf495 435Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
436 (const Standard_Real aFirst,
437 const Standard_Real aLast)
4e57c75e 438{
439 //define parameter division number as 10*e^(-PI) = 0.43213918
440 const Standard_Real PAR_T = 0.43213918;
441 Standard_Real aParm;
442 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
443 return aParm;
444}
445//=======================================================================
446//function : IntermediatePoint
447//purpose :
448//=======================================================================
f1baf495 449Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
450 (const TopoDS_Edge& aE)
4e57c75e 451
452{
453 Standard_Real aT, aT1, aT2;
454
455 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
456 if (aC1.IsNull())
457 BRep_Tool::Range(aE, aT1, aT2);
458
459 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
460 return aT;
461}
4e57c75e 462//=======================================================================
463//function : Make2D
464//purpose :
465//=======================================================================
acccace3 466void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
f1baf495 467 const TopoDS_Face& aF,
468 Handle(Geom2d_Curve)& aC2D,
469 Standard_Real& aFirst,
470 Standard_Real& aLast,
51db0179 471 Standard_Real& aToler,
472 const Handle(IntTools_Context)& theContext)
4e57c75e 473{
474 Standard_Boolean aLocIdentity;
475 Standard_Real f3d, l3d;
476 TopLoc_Location aLoc;
477
478 Handle(Geom2d_Curve) C2D;
479
480
481 C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
482
483 if (!C2D.IsNull()) {
484 aC2D=C2D;
485 return;
486 }
487
488 Handle(Geom_Curve) C3D2, C3D;
489 C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
490 //
491 if (C3D.IsNull()) {
492 // aE has no 3D curve, so nothing is done
493 }
494 //
495 aLocIdentity=aLoc.IsIdentity();
496
497 if (aLocIdentity) {
498 C3D2 = C3D;
499 }
500 else {
501 C3D2 = Handle(Geom_Curve)::
502 DownCast(C3D->Transformed(aLoc.Transformation()));
503 }
504
505 //
ee5ee7db 506 aToler = BRep_Tool::Tolerance(aE);
51db0179 507 BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler, theContext);
4e57c75e 508 //
509 aFirst = f3d;
510 aLast = l3d;
511}
512
513//=======================================================================
514//function : MakePCurveOnFace
515//purpose :
516//=======================================================================
f1baf495 517void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
518 const Handle(Geom_Curve)& aC3D,
519 Handle(Geom2d_Curve)& aC2D, //->
51db0179 520 Standard_Real& TolReached2d,
521 const Handle(IntTools_Context)& theContext)
4e57c75e 522{
523 Standard_Real aFirst, aLast;
524
525 aFirst = aC3D -> FirstParameter();
526 aLast = aC3D -> LastParameter();
527 //
528 TolReached2d=0.;
529 //
51db0179 530 BOPTools_AlgoTools2D::MakePCurveOnFace
531 (aF, aC3D, aFirst, aLast, aC2D, TolReached2d, theContext);
4e57c75e 532}
533
534//=======================================================================
535//function : MakePCurveOnFace
536//purpose :
537//=======================================================================
51db0179 538void BOPTools_AlgoTools2D::MakePCurveOnFace
f1baf495 539 (const TopoDS_Face& aF,
540 const Handle(Geom_Curve)& aC3D,
fd372378 541 const Standard_Real aT1,
542 const Standard_Real aT2,
51db0179 543 Handle(Geom2d_Curve)& aC2D,
544 Standard_Real& TolReached2d,
545 const Handle(IntTools_Context)& theContext)
4e57c75e 546{
51db0179 547 BRepAdaptor_Surface aBASTmp;
548 const BRepAdaptor_Surface* pBAS;
549 if (!theContext.IsNull()) {
550 pBAS = &theContext->SurfaceAdaptor(aF);
551 }
552 else {
553 aBASTmp.Initialize(aF, Standard_True);
554 pBAS = &aBASTmp;
555 }
fd372378 556 //
51db0179 557 Handle(BRepAdaptor_HSurface) aBAHS = new BRepAdaptor_HSurface(*pBAS);
558 Handle(GeomAdaptor_HCurve) aBAHC = new GeomAdaptor_HCurve(aC3D, aT1, aT2);
f2843558 559 //
51db0179 560 Standard_Real aTolR;
f998596a 561 Standard_Real aTR = Precision::Confusion();//1.e-7;
562 Standard_Real aMaxTol = 1.e3 * aTR; //0.0001
563 Standard_Boolean isAnaSurf = ProjLib::IsAnaSurf(aBAHS);
564
4e57c75e 565 //when the type of surface is GeomAbs_SurfaceOfRevolution
f998596a 566 if (pBAS->GetType() == GeomAbs_SurfaceOfRevolution)
567 {
fd372378 568 if (TolReached2d > aTR) {
569 aTR=TolReached2d;
570 }
571 //
4e57c75e 572 ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
f48cb55d 573 ProjLib::MakePCurveOfType(aProj1, aC2D);
4e57c75e 574 aTolR = aProj1.GetTolerance();
fd372378 575 }
f998596a 576 else
577 {
578 ProjLib_ProjectedCurve aProjCurv(aBAHS);
579 Standard_Integer aDegMin = -1, aDegMax = -1, aMaxSegments = -1;
580 Standard_Real aMaxDist = -1;
581 AppParCurves_Constraint aBndPnt = AppParCurves_TangencyPoint;
582 if ((TolReached2d >= 10. * aTR) && (TolReached2d <= aMaxTol || isAnaSurf))
583 {
584 aTR = Min(aMaxTol, 0.1*TolReached2d);
585 aMaxSegments = 100;
586 aMaxDist = 1.e3*TolReached2d;
47a27171 587 if(!isAnaSurf || TolReached2d > 1.)
f998596a 588 {
589 aBndPnt = AppParCurves_PassPoint;
590 }
591 }
592 else if(TolReached2d > aMaxTol)
593 {
594 aTR = Min(TolReached2d, 1.e3 * aMaxTol);
595 aMaxDist = 1.e2 * aTR;
596 aMaxSegments = 100;
597 }
598 aProjCurv.Load(aTR);
599 aProjCurv.SetDegree(aDegMin, aDegMax);
600 aProjCurv.SetMaxSegments(aMaxSegments);
601 aProjCurv.SetBndPnt(aBndPnt);
602 aProjCurv.SetMaxDist(aMaxDist);
603 aProjCurv.Perform(aBAHC);
f48cb55d 604 ProjLib::MakePCurveOfType(aProjCurv, aC2D);
4e57c75e 605 aTolR=aProjCurv.GetTolerance();
606 }
607 //
f998596a 608 if (aC2D.IsNull() && (aTR < aMaxTol || aTR < TolReached2d))
609 {
610 aTR = Max(TolReached2d, aMaxTol);
611 ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, aTR);// 2
f48cb55d 612 ProjLib::MakePCurveOfType(aProjCurvAgain, aC2D);
4e57c75e 613 aTolR = aProjCurvAgain.GetTolerance();
4e57c75e 614 }
b9a7d225 615 //
616 if(aC2D.IsNull())
617 {
9775fa61 618 throw Standard_ConstructionError("BOPTools_AlgoTools2D::MakePCurveOnFace : PCurve is Null");
b9a7d225 619 }
620 //
4e57c75e 621 TolReached2d=aTolR;
0a807dd9 622
623 // Adjust curve for periodic surface
51db0179 624 Handle(Geom2d_Curve) aC2DA;
625 BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA);
0a807dd9 626 aC2D = aC2DA;
627
628 // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve.
629 Standard_Real aTCFirst = aC2D->FirstParameter();
630 Standard_Real aTCLast = aC2D->LastParameter();
631 if ((aTCFirst - aT1) > Precision::PConfusion() ||
632 (aT2 - aTCLast ) > Precision::PConfusion())
633 {
634 if (aTCFirst < aT1) aTCFirst = aT1;
635 if (aTCLast > aT2) aTCLast = aT2;
636
637 GeomLib::SameRange(Precision::PConfusion(), aC2D,
638 aTCFirst, aTCLast, aT1, aT2, aC2D);
639 }
640
1b7ae951 641 // compute the appropriate tolerance for the edge
51db0179 642 Handle(Geom_Surface) aS = pBAS->Surface().Surface();
643 aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf()));
644 //
645 Standard_Real aT;
1b7ae951 646 if (IntTools_Tools::ComputeTolerance
fd372378 647 (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
1b7ae951 648 if (aTolR > TolReached2d) {
649 TolReached2d = aTolR;
650 }
651 }
4e57c75e 652}
7fd59977 653
fc88faf1 654//=======================================================================
655//function : MaxToleranceEdge
656//purpose :
657//=======================================================================
658Standard_Real MaxToleranceEdge (const TopoDS_Face& aF)
659{
660 Standard_Real aTol, aTolMax;
661 TopExp_Explorer aExp;
662 //
663 aTolMax=0.;
664 aExp.Init(aF, TopAbs_EDGE);
665 for (; aExp.More(); aExp.Next()) {
666 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
667 aTol=BRep_Tool::Tolerance(aE);
668 if (aTol>aTolMax) {
669 aTolMax=aTol;
670 }
671 }
672 return aTolMax;
673}
39067947 674
675//=======================================================================
676//function : IsEdgeIsoline
677//purpose :
678//=======================================================================
679void BOPTools_AlgoTools2D::IsEdgeIsoline( const TopoDS_Edge& theE,
680 const TopoDS_Face& theF,
681 Standard_Boolean& isTheUIso,
682 Standard_Boolean& isTheVIso)
683{
684 isTheUIso = isTheVIso = Standard_False;
685
686 gp_Vec2d aT;
687 gp_Pnt2d aP;
688 Standard_Real aFirst = 0.0, aLast = 0.0;
689 const Handle(Geom2d_Curve) aPC = BRep_Tool::CurveOnSurface(theE, theF, aFirst, aLast);
690
691 aPC->D1(0.5*(aFirst+aLast), aP, aT);
692
693 const Standard_Real aSqMagn = aT.SquareMagnitude();
694 if(aSqMagn <= gp::Resolution())
695 return;
696
697 //Normalyze aT
698 aT /= sqrt(aSqMagn);
699
700 //sin(da) ~ da, when da->0.
701 const Standard_Real aTol = Precision::Angular();
702 const gp_Vec2d aRefVDir(0.0, 1.0), aRefUDir(1.0, 0.0);
703
704 const Standard_Real aDPv = aT.CrossMagnitude(aRefVDir),
705 aDPu = aT.CrossMagnitude(aRefUDir);
706
707 isTheUIso = (aDPv <= aTol);
708 isTheVIso = (aDPu <= aTol);
f48cb55d 709}