0025285: Wrong result of General Fuse operation for an edge and a face.
[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
4e57c75e 15#include <BOPTools_AlgoTools2D.ixx>
7fd59977 16
17#include <Standard_NotImplemented.hxx>
18#include <Precision.hxx>
19#include <gp.hxx>
20
21#include <gp_Pnt.hxx>
22#include <gp_Pnt2d.hxx>
23#include <gp_Vec.hxx>
24#include <gp_Vec2d.hxx>
25
26#include <Geom2d_Curve.hxx>
27#include <Geom2d_Line.hxx>
28#include <Geom2d_Circle.hxx>
29#include <Geom2d_Ellipse.hxx>
30#include <Geom2d_Parabola.hxx>
31#include <Geom2d_Hyperbola.hxx>
f1baf495 32#include <Geom2d_TrimmedCurve.hxx>
33
34#include <Geom2dAdaptor.hxx>
7fd59977 35
36#include <Geom_Curve.hxx>
7fd59977 37#include <Geom_TrimmedCurve.hxx>
38#include <Geom_Surface.hxx>
f1baf495 39#include <Geom_Plane.hxx>
40
41#include <GeomAdaptor_Surface.hxx>
42#include <GeomAdaptor_Curve.hxx>
43#include <GeomAdaptor_HCurve.hxx>
44#include <GeomAdaptor_HSurface.hxx>
45#include <Geom_Plane.hxx>
46#include <Geom_RectangularTrimmedSurface.hxx>
47
48#include <GeomProjLib.hxx>
7fd59977 49
50#include <TopLoc_Location.hxx>
7fd59977 51#include <TopExp.hxx>
52
53#include <ProjLib_ProjectedCurve.hxx>
54
55#include <BRep_Tool.hxx>
f1baf495 56#include <BRep_Builder.hxx>
57#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
58#include <BRep_TEdge.hxx>
59#include <BRep_CurveRepresentation.hxx>
60#include <BRep_GCurve.hxx>
61
7fd59977 62#include <BRepAdaptor_HSurface.hxx>
f1baf495 63
7fd59977 64#include <BRepAdaptor_Curve.hxx>
7fd59977 65#include <BRepAdaptor_Surface.hxx>
d8a24e83 66#include <BRepClass_FaceClassifier.hxx>
7fd59977 67
f1baf495 68#include <BRepTools.hxx>
69
70#include <BOPCol_IndexedMapOfShape.hxx>
71
72#include <BOPTools.hxx>
655fddc8 73#include <IntTools_Tools.hxx>
fc88faf1 74#include <gp_Cylinder.hxx>
75#include <TopExp_Explorer.hxx>
2a78ec6a 76#include <GeomInt.hxx>
7fd59977 77
78static
f1baf495 79 Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
80
81static
82 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
83 const TopoDS_Face& ,
84 Standard_Real& ,
85 Standard_Real& ,
86 Standard_Boolean& );
87static
88 Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
89 const Handle(Geom_Surface)& ,
90 const TopLoc_Location& ,
91 Standard_Real& ,
92 Standard_Real& ,
93 Standard_Boolean& );
fc88faf1 94static
95 Standard_Real MaxToleranceEdge (const TopoDS_Face& );
7fd59977 96
4e57c75e 97//=======================================================================
98//function : BuildPCurveForEdgeOnFace
99//purpose :
100//=======================================================================
f1baf495 101void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
102 const TopoDS_Face& aF)
4e57c75e 103{
104 BRep_Builder aBB;
105 Handle(Geom2d_Curve) aC2D;
106 Standard_Real aTolPC, aTolFact, aTolEdge, aFirst, aLast;
107
108 Standard_Boolean aHasOld;
f1baf495 109 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, aC2D,
110 aFirst, aLast,
111 aTolEdge);
4e57c75e 112 if (aHasOld) {
113 return;
114 }
115
116
117 BOPTools_AlgoTools2D::CurveOnSurface(aE, aF, aC2D, aTolPC);
118
119 aTolEdge=BRep_Tool::Tolerance(aE);
120
121 aTolFact=Max(aTolEdge, aTolPC);
122
123 aBB.UpdateEdge(aE, aC2D, aF, aTolFact);
124 return;
125}
126
7fd59977 127//=======================================================================
128//function : EdgeTangent
129//purpose :
130//=======================================================================
f1baf495 131Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
132 (const TopoDS_Edge& anEdge,
133 const Standard_Real aT,
134 gp_Vec& aTau)
7fd59977 135{
136 Standard_Boolean isdgE;
137 Standard_Real first, last;
138
139 isdgE = BRep_Tool::Degenerated(anEdge);
140 if (isdgE) {
141 return Standard_False;
142 }
143 if (!CheckEdgeLength(anEdge)) {
144 return Standard_False;
145 }
146
147 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
148 gp_Pnt aP;
149 aC->D1(aT, aP, aTau);
150 Standard_Real mod = aTau.Magnitude();
151 if(mod > gp::Resolution()) {
152 aTau /= mod;
153 }
154 else {
155 return Standard_False;
156 }
157 //aTau.Normalize();
158 if (anEdge.Orientation() == TopAbs_REVERSED){
159 aTau.Reverse();
160 }
161 return Standard_True;
162}
163
7fd59977 164//=======================================================================
165//function : PointOnOnSurface
166//purpose :
167//=======================================================================
f1baf495 168void BOPTools_AlgoTools2D::PointOnSurface (const TopoDS_Edge& aE,
169 const TopoDS_Face& aF,
170 const Standard_Real aParameter,
171 Standard_Real& U,
172 Standard_Real& V)
7fd59977 173{
174 gp_Pnt2d aP2D;
175 Handle(Geom2d_Curve) aC2D;
176 Standard_Real aToler, aFirst, aLast;
177
f1baf495 178 BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D,
179 aFirst, aLast, aToler);
7fd59977 180 aC2D->D0(aParameter, aP2D);
181 U=aP2D.X();
182 V=aP2D.Y();
183 return;
184}
185
186//=======================================================================
187//function : CurveOnSurface
188//purpose :
189//=======================================================================
f1baf495 190void BOPTools_AlgoTools2D::CurveOnSurface (const TopoDS_Edge& aE,
191 const TopoDS_Face& aF,
192 Handle(Geom2d_Curve)& aC2D,
193 Standard_Real& aToler)
7fd59977 194{
195 Standard_Real aFirst, aLast;
f1baf495 196 //
197 BOPTools_AlgoTools2D::CurveOnSurface (aE, aF, aC2D,
198 aFirst, aLast, aToler);
199 //
7fd59977 200 return;
201}
202//=======================================================================
203//function : CurveOnSurface
204//purpose :
205//=======================================================================
f1baf495 206void BOPTools_AlgoTools2D::CurveOnSurface (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 Handle(Geom2d_Curve) C2D;
215
f1baf495 216 aHasOld=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF, C2D,
217 aFirst, aLast,
218 aToler);
7fd59977 219 if (aHasOld) {
220 aC2D=C2D;
221 return;
222 }
223
4e57c75e 224 BOPTools_AlgoTools2D::Make2D(aE, aF, C2D, aFirst, aLast, aToler);
7fd59977 225 aC2D=C2D;
226 return;
227}
7fd59977 228//=======================================================================
229//function : HasCurveOnSurface
230//purpose :
231//=======================================================================
f1baf495 232Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
233 (const TopoDS_Edge& aE,
234 const TopoDS_Face& aF,
235 Handle(Geom2d_Curve)& aC2D,
236 Standard_Real& aFirst,
237 Standard_Real& aLast,
238 Standard_Real& aToler)
7fd59977 239{
240 Standard_Boolean aHasOld;
241
242 aToler=BRep_Tool::Tolerance(aE);
243 BRep_Tool::Range(aE, aFirst, aLast);
244
245 if((aLast - aFirst) < Precision::PConfusion()) {
246 return Standard_False;
247 }
248
f1baf495 249 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
7fd59977 250 aHasOld=!aC2D.IsNull();
251 return aHasOld;
252}
253//=======================================================================
254//function : HasCurveOnSurface
255//purpose :
256//=======================================================================
f1baf495 257Standard_Boolean BOPTools_AlgoTools2D::HasCurveOnSurface
258 (const TopoDS_Edge& aE,
259 const TopoDS_Face& aF)
4e57c75e 260
7fd59977 261{
f1baf495 262 Standard_Boolean bHasOld;
7fd59977 263 Handle(Geom2d_Curve) aC2D;
264 Standard_Real aFirst, aLast;
f1baf495 265 //
7fd59977 266 BRep_Tool::Range(aE, aFirst, aLast);
f1baf495 267 //
7fd59977 268 if((aLast - aFirst) < Precision::PConfusion()) {
269 return Standard_False;
270 }
f1baf495 271 //
272 aC2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
273 bHasOld=!aC2D.IsNull();
274 //
275 return bHasOld;
7fd59977 276}
7fd59977 277//=======================================================================
278//function : AdjustPCurveOnFace
279//purpose :
280//=======================================================================
f1baf495 281void BOPTools_AlgoTools2D::AdjustPCurveOnFace
282 (const TopoDS_Face& aF,
283 const Handle(Geom_Curve)& aC3D,
284 const Handle(Geom2d_Curve)& aC2D,
285 Handle(Geom2d_Curve)& aC2DA)
7fd59977 286{
287 Standard_Real first, last;
288
289 first = aC3D -> FirstParameter();
290 last = aC3D -> LastParameter();
291
4e57c75e 292 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, first, last, aC2D, aC2DA);
7fd59977 293}
294//=======================================================================
295//function : AdjustPCurveOnFace
296//purpose :
297//=======================================================================
f1baf495 298void BOPTools_AlgoTools2D::AdjustPCurveOnFace
299 (const TopoDS_Face& aF,
300 const Standard_Real aFirst,
301 const Standard_Real aLast,
302 const Handle(Geom2d_Curve)& aC2D,
303 Handle(Geom2d_Curve)& aC2DA)
7fd59977 304{
655fddc8 305 Standard_Boolean mincond, maxcond;
7fd59977 306 Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
655fddc8 307 Standard_Real aUPeriod;
7fd59977 308 //
309 aDelta=Precision::PConfusion();
310
311 BRepAdaptor_Surface aBAS(aF, Standard_False);
312
313 BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
314
315 aT =.5*(aFirst+aLast);
316
317 gp_Pnt2d pC2D;
318 aC2D->D0(aT, pC2D);
319
320 u2 = pC2D.X();
321 v2 = pC2D.Y();
fc88faf1 322 //
323 // du
7fd59977 324 du = 0.;
325 if (aBAS.IsUPeriodic()) {
9c0b61f3 326 Standard_Real u2x;
655fddc8 327 aUPeriod = aBAS.UPeriod();
7fd59977 328 //
9c0b61f3 329 // A. drive u2 into the stall [Umin, Umin+aUPeriod] -> u2x
330 GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2x, du, 0.);
331 //
332 // b. try to clarify u2 using the precision (aDelta)
333 if (fabs(u2x-UMin) < aDelta) {
334 u2=UMin;
335 }
336 else if (fabs(u2x-UMin-aUPeriod) < aDelta) {
337 u2=UMin+aUPeriod;
338 }
339 // C. compute du again using clarified value of u2
340 GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2x, du, 0.);
fc88faf1 341 //
342 if (du==0.) {
343 if (aBAS.GetType()==GeomAbs_Cylinder) {
344 Standard_Real aR, dFi, aTol;
345 //
346 gp_Cylinder aCylinder=aBAS.Cylinder();
347 aR=aCylinder.Radius();
348 aTol=MaxToleranceEdge(aF);
349 dFi=aTol/aR;
350 if (dFi<aDelta) {
351 dFi=aDelta;
352 }
353 //
354 mincond = (UMin - u2 > dFi);
355 maxcond = (u2 - UMax > dFi);
356 if (mincond || maxcond) {
357 du = ( mincond ) ? aUPeriod : -aUPeriod;
358 }
359 }
360 }
655fddc8 361 }
fc88faf1 362
7fd59977 363 // dv
364 dv = 0.;
365 if (aBAS.IsVPeriodic()) {
366 Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
367 //
655fddc8 368 aVPeriod = aBAS.VPeriod();
7fd59977 369 mincond = (VMin - v2 > aDelta);
370 maxcond = (v2 - VMax > aDelta);
655fddc8 371 //
372 if (mincond || maxcond) {
7fd59977 373 dv = ( mincond ) ? aVPeriod : -aVPeriod;
374 }
375 //
7fd59977 376 if ((VMax-VMin<aVPeriod) && dv) {
377 aVm=v2;
378 aVr=v2+dv;
379 aVmid=0.5*(VMin+VMax);
380 dVm=fabs(aVm-aVmid);
381 dVr=fabs(aVr-aVmid);
382 if (dVm<dVr) {
4e57c75e 383 dv=0.;
7fd59977 384 }
385 }
7fd59977 386 }
387 //
d8a24e83 388 {
389 //check the point with classifier
390 Standard_Real u,v;
391 u = u2 + du;
392 v = v2 + dv;
393 if (aBAS.IsUPeriodic()) {
394 aUPeriod = aBAS.UPeriod();
395 if ((UMax - UMin - 2*aDelta) > aUPeriod) {
396 if ((u > (UMin + aDelta + aUPeriod)) ||
397 (u < (UMax - aDelta - aUPeriod))) {
398 BRepClass_FaceClassifier aClassifier;
399 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
400 TopAbs_State Status = aClassifier.State();
401 if (Status == TopAbs_OUT) {
402 du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
403 }
404 }
405 }
406 }
407 //
408 u = u2 + du;
409 if (aBAS.IsVPeriodic()) {
410 Standard_Real aVPeriod = aBAS.VPeriod();
411 if ((VMax - VMin - 2*aDelta) > aVPeriod) {
412 if ((v > (VMin + aDelta + aVPeriod)) ||
413 (v < (VMax - aDelta - aVPeriod))) {
414 BRepClass_FaceClassifier aClassifier;
415 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
416 TopAbs_State Status = aClassifier.State();
417 if (Status == TopAbs_OUT) {
418 dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
419 }
420 }
421 }
422 }
423 }
7fd59977 424 // Translation if necessary
425 Handle(Geom2d_Curve) aC2Dx=aC2D;
426
427 if ( du != 0. || dv != 0.) {
428 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
429 gp_Vec2d aV2D(du,dv);
430 PCT->Translate(aV2D);
431 aC2Dx = PCT;
432 }
433
434 aC2DA=aC2Dx;
435}
436
4e57c75e 437//=======================================================================
438//function : IntermediatePoint
439//purpose :
440//=======================================================================
f1baf495 441Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
442 (const Standard_Real aFirst,
443 const Standard_Real aLast)
4e57c75e 444{
445 //define parameter division number as 10*e^(-PI) = 0.43213918
446 const Standard_Real PAR_T = 0.43213918;
447 Standard_Real aParm;
448 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
449 return aParm;
450}
451//=======================================================================
452//function : IntermediatePoint
453//purpose :
454//=======================================================================
f1baf495 455Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
456 (const TopoDS_Edge& aE)
4e57c75e 457
458{
459 Standard_Real aT, aT1, aT2;
460
461 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
462 if (aC1.IsNull())
463 BRep_Tool::Range(aE, aT1, aT2);
464
465 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
466 return aT;
467}
468
469//=======================================================================
470//function : BuildPCurveForEdgeOnPlane
471//purpose :
472//=======================================================================
f1baf495 473void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane
474 (const TopoDS_Edge& aE,
475 const TopoDS_Face& aF)
476{
477 Standard_Boolean bToUpdate;
478 Standard_Real aTolE, aT1, aT2;
4e57c75e 479 Handle(Geom2d_Curve) aC2D;
4e57c75e 480 BRep_Builder aBB;
481 //
f1baf495 482 aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
483 if (bToUpdate) {
484 aTolE=BRep_Tool::Tolerance(aE);
485 aBB.UpdateEdge(aE, aC2D, aF, aTolE);
4e57c75e 486 }
4e57c75e 487}
acccace3 488//=======================================================================
489// function: BuildPCurveForEdgesOnPlane
490// purpose:
491//=======================================================================
492void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane
f1baf495 493 (const BOPCol_ListOfShape& aLE,
494 const TopoDS_Face& aF)
acccace3 495{
acccace3 496 BOPCol_ListIteratorOfListOfShape aIt;
acccace3 497 //
f1baf495 498 aIt.Initialize(aLE);
acccace3 499 for(; aIt.More(); aIt.Next()) {
500 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
f1baf495 501 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
acccace3 502 }
503}
4e57c75e 504//=======================================================================
505//function : Make2D
506//purpose :
507//=======================================================================
acccace3 508void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
f1baf495 509 const TopoDS_Face& aF,
510 Handle(Geom2d_Curve)& aC2D,
511 Standard_Real& aFirst,
512 Standard_Real& aLast,
513 Standard_Real& aToler)
4e57c75e 514{
515 Standard_Boolean aLocIdentity;
516 Standard_Real f3d, l3d;
517 TopLoc_Location aLoc;
518
519 Handle(Geom2d_Curve) C2D;
520
521
522 C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
523
524 if (!C2D.IsNull()) {
525 aC2D=C2D;
526 return;
527 }
528
529 Handle(Geom_Curve) C3D2, C3D;
530 C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
531 //
532 if (C3D.IsNull()) {
533 // aE has no 3D curve, so nothing is done
534 }
535 //
536 aLocIdentity=aLoc.IsIdentity();
537
538 if (aLocIdentity) {
539 C3D2 = C3D;
540 }
541 else {
542 C3D2 = Handle(Geom_Curve)::
543 DownCast(C3D->Transformed(aLoc.Transformation()));
544 }
545
546 //
547 aToler=.5*BRep_Tool::Tolerance(aE);
548 BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
549 //
550 aFirst = f3d;
551 aLast = l3d;
552}
553
554//=======================================================================
555//function : MakePCurveOnFace
556//purpose :
557//=======================================================================
f1baf495 558void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
559 const Handle(Geom_Curve)& aC3D,
560 Handle(Geom2d_Curve)& aC2D, //->
561 Standard_Real& TolReached2d)
4e57c75e 562{
563 Standard_Real aFirst, aLast;
564
565 aFirst = aC3D -> FirstParameter();
566 aLast = aC3D -> LastParameter();
567 //
568 TolReached2d=0.;
569 //
f1baf495 570 BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst,
571 aLast, aC2D, TolReached2d);
4e57c75e 572}
573
574//=======================================================================
575//function : MakePCurveOnFace
576//purpose :
577//=======================================================================
f1baf495 578void BOPTools_AlgoTools2D::MakePCurveOnFace
579 (const TopoDS_Face& aF,
580 const Handle(Geom_Curve)& aC3D,
581 const Standard_Real aFirst,
582 const Standard_Real aLast,
583 Handle(Geom2d_Curve)& aC2D,
584 Standard_Real& TolReached2d)
4e57c75e 585{
586 Standard_Real aTolR;
587 Handle(Geom2d_Curve) aC2DA;
f2843558 588 //
589 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
590 GeomAdaptor_Surface aGAS(aS);
591 Handle(GeomAdaptor_HSurface) aBAHS=
592 new GeomAdaptor_HSurface(aGAS);
593 Handle(GeomAdaptor_HCurve) aBAHC =
594 new GeomAdaptor_HCurve(aC3D, aFirst, aLast);
4e57c75e 595
596 //when the type of surface is GeomAbs_SurfaceOfRevolution
f2843558 597 if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
4e57c75e 598 Standard_Real aTR = 1.e-7;
599 ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
600 BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
601 aTolR = aProj1.GetTolerance();
602 } else {
603 ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
604 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
605 aTolR=aProjCurv.GetTolerance();
606 }
607 //
608 if (aC2D.IsNull()) {
609 ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
610 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
611 aTolR = aProjCurvAgain.GetTolerance();
612 //
613 if (aC2D.IsNull()) {
614 Standard_Real aTR=0.0001;
615 ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
616 BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
617 aTolR = aProj3.GetTolerance();
618 }
619 }
620 TolReached2d=aTolR;
621
f1baf495 622 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aFirst, aLast,
623 aC2D, aC2DA);
4e57c75e 624 aC2D=aC2DA;
625}
7fd59977 626
627//=======================================================================
628//function : MakePCurveOfType
629//purpose :
630//=======================================================================
f1baf495 631void BOPTools_AlgoTools2D::MakePCurveOfType
632 (const ProjLib_ProjectedCurve& PC,
633 Handle(Geom2d_Curve)& C2D)
7fd59977 634{
635
636 switch (PC.GetType()) {
637
638 case GeomAbs_Line :
639 C2D = new Geom2d_Line(PC.Line());
640 break;
641 case GeomAbs_Circle :
642 C2D = new Geom2d_Circle(PC.Circle());
643 break;
644 case GeomAbs_Ellipse :
645 C2D = new Geom2d_Ellipse(PC.Ellipse());
646 break;
647 case GeomAbs_Parabola :
648 C2D = new Geom2d_Parabola(PC.Parabola());
649 break;
650 case GeomAbs_Hyperbola :
651 C2D = new Geom2d_Hyperbola(PC.Hyperbola());
652 break;
653 case GeomAbs_BSplineCurve :
654 C2D = PC.BSpline();
655 break;
656 case GeomAbs_BezierCurve :
657 case GeomAbs_OtherCurve :
658 default :
f1baf495 659 Standard_NotImplemented::Raise
660 ("BOPTools_AlgoTools2D::MakePCurveOfType");
7fd59977 661 break;
662 }
663}
4e57c75e 664//=======================================================================
665//function : CheckEdgeLength
666//purpose :
667//=======================================================================
668Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
669{
670 BRepAdaptor_Curve BC(E);
671
672 BOPCol_IndexedMapOfShape aM;
673 BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
674 Standard_Integer i, anExtent, aN=10;
675 Standard_Real ln=0., d, t, f, l, dt;
676 anExtent=aM.Extent();
677
678 if (anExtent!=1)
679 return Standard_True;
680
681 gp_Pnt p1, p2;
682 f = BC.FirstParameter();
683 l = BC.LastParameter();
684 dt=(l-f)/aN;
685
686 BC.D0(f, p1);
687 for (i=1; i<=aN; i++) {
688 t=f+i*dt;
689
690 if (i==aN)
691 BC.D0(l, p2);
692 else
693 BC.D0(t, p2);
694
695 d=p1.Distance(p2);
696 ln+=d;
697 p1=p2;
698 }
f1baf495 699 //
4e57c75e 700 return (ln > Precision::Confusion());
701}
4e57c75e 702//=======================================================================
f1baf495 703//function : BRep_Tool_CurveOnSurface
4e57c75e 704//purpose :
705//=======================================================================
f1baf495 706Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E,
707 const TopoDS_Face& F,
708 Standard_Real& First,
709 Standard_Real& Last,
710 Standard_Boolean& bToUpdate)
4e57c75e 711{
f1baf495 712 TopLoc_Location l;
713 const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
714 TopoDS_Edge aLocalEdge = E;
715 if (F.Orientation() == TopAbs_REVERSED) {
716 aLocalEdge.Reverse();
4e57c75e 717 }
f1baf495 718 //
719 return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
4e57c75e 720}
7fd59977 721//=======================================================================
f1baf495 722//function : BRep_Tool_CurveOnSurface
7fd59977 723//purpose :
724//=======================================================================
f1baf495 725Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
726 (const TopoDS_Edge& E,
727 const Handle(Geom_Surface)& S,
728 const TopLoc_Location& L,
729 Standard_Real& First,
730 Standard_Real& Last,
731 Standard_Boolean& bToUpdate)
7fd59977 732{
f1baf495 733 static const Handle(Geom2d_Curve) nullPCurve;
734 bToUpdate=Standard_False;
735 TopLoc_Location loc = L.Predivided(E.Location());
736 Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
737
738 // find the representation
739 BRep_ListIteratorOfListOfCurveRepresentation itcr
740 ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
741
742 while (itcr.More()) {
743 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
744 if (cr->IsCurveOnSurface(S,loc)) {
745 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
746 GC->Range(First,Last);
747 if (GC->IsCurveOnClosedSurface() && Eisreversed)
748 return GC->PCurve2();
749 else
750 return GC->PCurve();
751 }
752 itcr.Next();
7fd59977 753 }
754
f1baf495 755 // for planar surface and 3d curve try a projection
756 // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
757 Handle(Geom_Plane) GP;
758 Handle(Geom_RectangularTrimmedSurface) GRTS;
759 GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
760 if(!GRTS.IsNull())
761 GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
762 else
763 GP = Handle(Geom_Plane)::DownCast(S);
764 //fin modif du 21-05-97
7fd59977 765
f1baf495 766 if (!GP.IsNull()) {
7fd59977 767
f1baf495 768 Handle(GeomAdaptor_HCurve) HC;
769 Handle(GeomAdaptor_HSurface) HS;
7fd59977 770
f1baf495 771 HC = new GeomAdaptor_HCurve();
772 HS = new GeomAdaptor_HSurface();
7fd59977 773
f1baf495 774 TopLoc_Location LC;
7fd59977 775
f1baf495 776 Standard_Real f, l;// for those who call with (u,u).
777 Handle(Geom_Curve) C3d =
778 BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
779 // we can loose scale factor of Curve transformation (eap 13 May 2002)
7fd59977 780
f1baf495 781 LC = L/*.Predivided(LC)*/;
7fd59977 782
f1baf495 783 if (C3d.IsNull()) return nullPCurve;
7fd59977 784
f1baf495 785 Handle(Geom_Plane) Plane = GP;
786 if (!LC.IsIdentity()) {
787 const gp_Trsf& T = LC.Transformation();
788 Handle(Geom_Geometry) GPT = GP->Transformed(T);
789 Plane = *((Handle(Geom_Plane)*)&GPT);
790 }
791 GeomAdaptor_Surface& GAS = HS->ChangeSurface();
792 GAS.Load(Plane);
793
794 Handle(Geom_Curve) ProjOnPlane =
795 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
796 Plane,
797 Plane->Position().Direction(),
798 Standard_True);
799
800 GeomAdaptor_Curve& GAC = HC->ChangeCurve();
801 GAC.Load(ProjOnPlane);
802
803 ProjLib_ProjectedCurve Proj(HS,HC);
804 Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
7fd59977 805
f1baf495 806 if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
807 Handle(Geom2d_TrimmedCurve) TC =
808 (*((Handle(Geom2d_TrimmedCurve)*)&pc));
809 pc = TC->BasisCurve();
810 }
811 First = f; Last = l;
812 //
813 bToUpdate=Standard_True;
814 //
815 return pc;
816 }
817
818 return nullPCurve;
819}
fc88faf1 820//=======================================================================
821//function : MaxToleranceEdge
822//purpose :
823//=======================================================================
824Standard_Real MaxToleranceEdge (const TopoDS_Face& aF)
825{
826 Standard_Real aTol, aTolMax;
827 TopExp_Explorer aExp;
828 //
829 aTolMax=0.;
830 aExp.Init(aF, TopAbs_EDGE);
831 for (; aExp.More(); aExp.Next()) {
832 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
833 aTol=BRep_Tool::Tolerance(aE);
834 if (aTol>aTolMax) {
835 aTolMax=aTol;
836 }
837 }
838 return aTolMax;
839}