0025982: Wrong result obtained by General Fuse operator.
[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{
fd372378 287 Standard_Real aT1, aT2;
288 //
289 aT1=aC3D->FirstParameter();
290 aT2=aC3D->LastParameter();
291 //
292 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aF, aT1, aT2, aC2D, aC2DA);
293}
7fd59977 294//=======================================================================
295//function : AdjustPCurveOnFace
296//purpose :
297//=======================================================================
f1baf495 298void BOPTools_AlgoTools2D::AdjustPCurveOnFace
299 (const TopoDS_Face& aF,
fd372378 300 const Standard_Real aT1,
301 const Standard_Real aT2,
302 const Handle(Geom2d_Curve)& aC2D,
303 Handle(Geom2d_Curve)& aC2DA)
304{
305 BRepAdaptor_Surface aBAS(aF, Standard_True);
306 //
307 BOPTools_AlgoTools2D::AdjustPCurveOnFace(aBAS, aT1, aT2,
308 aC2D, aC2DA);
309}
310
311//=======================================================================
312//function : AdjustPCurveOnFace
313//purpose :
314//=======================================================================
315void BOPTools_AlgoTools2D::AdjustPCurveOnFace
316 (const BRepAdaptor_Surface& aBAS,
f1baf495 317 const Standard_Real aFirst,
318 const Standard_Real aLast,
319 const Handle(Geom2d_Curve)& aC2D,
320 Handle(Geom2d_Curve)& aC2DA)
7fd59977 321{
655fddc8 322 Standard_Boolean mincond, maxcond;
7fd59977 323 Standard_Real UMin, UMax, VMin, VMax, aT, u2, v2, du, dv, aDelta;
655fddc8 324 Standard_Real aUPeriod;
7fd59977 325 //
fd372378 326 const TopoDS_Face& aF=aBAS.Face();
327 UMin=aBAS.FirstUParameter();
328 UMax=aBAS.LastUParameter();
329 VMin=aBAS.FirstVParameter();
330 VMax=aBAS.LastVParameter();
331 //
332 //BRepAdaptor_Surface aBAS(aF, Standard_False);
333 //BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
334 //
335 aDelta=Precision::PConfusion();
7fd59977 336
337 aT =.5*(aFirst+aLast);
338
339 gp_Pnt2d pC2D;
340 aC2D->D0(aT, pC2D);
341
342 u2 = pC2D.X();
343 v2 = pC2D.Y();
fc88faf1 344 //
345 // du
7fd59977 346 du = 0.;
347 if (aBAS.IsUPeriodic()) {
655fddc8 348 aUPeriod = aBAS.UPeriod();
fd372378 349
7fd59977 350 //
67e36f0c 351 // a. try to clarify u2 using the precision (aDelta)
352 if (fabs(u2-UMin) < aDelta) {
353 u2=UMin;
354 }
355 else if (fabs(u2-UMin-aUPeriod) < aDelta) {
9c0b61f3 356 u2=UMin+aUPeriod;
357 }
67e36f0c 358 // b. compute du again using clarified value of u2
359 GeomInt::AdjustPeriodic(u2, UMin, UMax, aUPeriod, u2, du, 0.);
fc88faf1 360 //
361 if (du==0.) {
362 if (aBAS.GetType()==GeomAbs_Cylinder) {
363 Standard_Real aR, dFi, aTol;
364 //
365 gp_Cylinder aCylinder=aBAS.Cylinder();
366 aR=aCylinder.Radius();
367 aTol=MaxToleranceEdge(aF);
368 dFi=aTol/aR;
369 if (dFi<aDelta) {
370 dFi=aDelta;
371 }
372 //
373 mincond = (UMin - u2 > dFi);
374 maxcond = (u2 - UMax > dFi);
375 if (mincond || maxcond) {
376 du = ( mincond ) ? aUPeriod : -aUPeriod;
377 }
378 }
379 }
655fddc8 380 }
fc88faf1 381
7fd59977 382 // dv
383 dv = 0.;
384 if (aBAS.IsVPeriodic()) {
385 Standard_Real aVPeriod, aVm, aVr, aVmid, dVm, dVr;
386 //
655fddc8 387 aVPeriod = aBAS.VPeriod();
7fd59977 388 mincond = (VMin - v2 > aDelta);
389 maxcond = (v2 - VMax > aDelta);
655fddc8 390 //
391 if (mincond || maxcond) {
7fd59977 392 dv = ( mincond ) ? aVPeriod : -aVPeriod;
393 }
394 //
7fd59977 395 if ((VMax-VMin<aVPeriod) && dv) {
396 aVm=v2;
397 aVr=v2+dv;
398 aVmid=0.5*(VMin+VMax);
399 dVm=fabs(aVm-aVmid);
400 dVr=fabs(aVr-aVmid);
401 if (dVm<dVr) {
4e57c75e 402 dv=0.;
7fd59977 403 }
404 }
7fd59977 405 }
406 //
d8a24e83 407 {
408 //check the point with classifier
409 Standard_Real u,v;
410 u = u2 + du;
411 v = v2 + dv;
412 if (aBAS.IsUPeriodic()) {
413 aUPeriod = aBAS.UPeriod();
414 if ((UMax - UMin - 2*aDelta) > aUPeriod) {
415 if ((u > (UMin + aDelta + aUPeriod)) ||
416 (u < (UMax - aDelta - aUPeriod))) {
417 BRepClass_FaceClassifier aClassifier;
418 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
419 TopAbs_State Status = aClassifier.State();
420 if (Status == TopAbs_OUT) {
421 du += (u > (UMin + aDelta + aUPeriod)) ? -aUPeriod : aUPeriod;
422 }
423 }
424 }
425 }
426 //
427 u = u2 + du;
428 if (aBAS.IsVPeriodic()) {
429 Standard_Real aVPeriod = aBAS.VPeriod();
430 if ((VMax - VMin - 2*aDelta) > aVPeriod) {
431 if ((v > (VMin + aDelta + aVPeriod)) ||
432 (v < (VMax - aDelta - aVPeriod))) {
433 BRepClass_FaceClassifier aClassifier;
434 aClassifier.Perform(aF, gp_Pnt2d(u, v), aDelta);
435 TopAbs_State Status = aClassifier.State();
436 if (Status == TopAbs_OUT) {
437 dv += (v > (VMin + aDelta + aVPeriod)) ? -aVPeriod : aVPeriod;
438 }
439 }
440 }
441 }
442 }
7fd59977 443 // Translation if necessary
444 Handle(Geom2d_Curve) aC2Dx=aC2D;
445
446 if ( du != 0. || dv != 0.) {
447 Handle(Geom2d_Curve) PCT = Handle(Geom2d_Curve)::DownCast(aC2Dx->Copy());
448 gp_Vec2d aV2D(du,dv);
449 PCT->Translate(aV2D);
450 aC2Dx = PCT;
451 }
452
453 aC2DA=aC2Dx;
454}
455
4e57c75e 456//=======================================================================
457//function : IntermediatePoint
458//purpose :
459//=======================================================================
f1baf495 460Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
461 (const Standard_Real aFirst,
462 const Standard_Real aLast)
4e57c75e 463{
464 //define parameter division number as 10*e^(-PI) = 0.43213918
465 const Standard_Real PAR_T = 0.43213918;
466 Standard_Real aParm;
467 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
468 return aParm;
469}
470//=======================================================================
471//function : IntermediatePoint
472//purpose :
473//=======================================================================
f1baf495 474Standard_Real BOPTools_AlgoTools2D::IntermediatePoint
475 (const TopoDS_Edge& aE)
4e57c75e 476
477{
478 Standard_Real aT, aT1, aT2;
479
480 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aE, aT1, aT2);
481 if (aC1.IsNull())
482 BRep_Tool::Range(aE, aT1, aT2);
483
484 aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
485 return aT;
486}
487
488//=======================================================================
489//function : BuildPCurveForEdgeOnPlane
490//purpose :
491//=======================================================================
f1baf495 492void BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane
493 (const TopoDS_Edge& aE,
494 const TopoDS_Face& aF)
495{
496 Standard_Boolean bToUpdate;
497 Standard_Real aTolE, aT1, aT2;
4e57c75e 498 Handle(Geom2d_Curve) aC2D;
4e57c75e 499 BRep_Builder aBB;
500 //
f1baf495 501 aC2D=BRep_Tool_CurveOnSurface(aE, aF, aT1, aT2, bToUpdate);
502 if (bToUpdate) {
503 aTolE=BRep_Tool::Tolerance(aE);
504 aBB.UpdateEdge(aE, aC2D, aF, aTolE);
4e57c75e 505 }
4e57c75e 506}
acccace3 507//=======================================================================
508// function: BuildPCurveForEdgesOnPlane
509// purpose:
510//=======================================================================
511void BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane
f1baf495 512 (const BOPCol_ListOfShape& aLE,
513 const TopoDS_Face& aF)
acccace3 514{
acccace3 515 BOPCol_ListIteratorOfListOfShape aIt;
acccace3 516 //
f1baf495 517 aIt.Initialize(aLE);
acccace3 518 for(; aIt.More(); aIt.Next()) {
519 const TopoDS_Edge& aE=(*(TopoDS_Edge *)&aIt.Value());
f1baf495 520 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (aE, aF);
acccace3 521 }
522}
4e57c75e 523//=======================================================================
524//function : Make2D
525//purpose :
526//=======================================================================
acccace3 527void BOPTools_AlgoTools2D::Make2D (const TopoDS_Edge& aE,
f1baf495 528 const TopoDS_Face& aF,
529 Handle(Geom2d_Curve)& aC2D,
530 Standard_Real& aFirst,
531 Standard_Real& aLast,
532 Standard_Real& aToler)
4e57c75e 533{
534 Standard_Boolean aLocIdentity;
535 Standard_Real f3d, l3d;
536 TopLoc_Location aLoc;
537
538 Handle(Geom2d_Curve) C2D;
539
540
541 C2D=BRep_Tool::CurveOnSurface(aE, aF, aFirst, aLast);
542
543 if (!C2D.IsNull()) {
544 aC2D=C2D;
545 return;
546 }
547
548 Handle(Geom_Curve) C3D2, C3D;
549 C3D = BRep_Tool::Curve(aE, aLoc, f3d, l3d);
550 //
551 if (C3D.IsNull()) {
552 // aE has no 3D curve, so nothing is done
553 }
554 //
555 aLocIdentity=aLoc.IsIdentity();
556
557 if (aLocIdentity) {
558 C3D2 = C3D;
559 }
560 else {
561 C3D2 = Handle(Geom_Curve)::
562 DownCast(C3D->Transformed(aLoc.Transformation()));
563 }
564
565 //
ee5ee7db 566 aToler = BRep_Tool::Tolerance(aE);
4e57c75e 567 BOPTools_AlgoTools2D::MakePCurveOnFace(aF, C3D2, f3d, l3d, aC2D, aToler);
568 //
569 aFirst = f3d;
570 aLast = l3d;
571}
572
573//=======================================================================
574//function : MakePCurveOnFace
575//purpose :
576//=======================================================================
f1baf495 577void BOPTools_AlgoTools2D::MakePCurveOnFace (const TopoDS_Face& aF,
578 const Handle(Geom_Curve)& aC3D,
579 Handle(Geom2d_Curve)& aC2D, //->
580 Standard_Real& TolReached2d)
4e57c75e 581{
582 Standard_Real aFirst, aLast;
583
584 aFirst = aC3D -> FirstParameter();
585 aLast = aC3D -> LastParameter();
586 //
587 TolReached2d=0.;
588 //
f1baf495 589 BOPTools_AlgoTools2D::MakePCurveOnFace (aF, aC3D, aFirst,
590 aLast, aC2D, TolReached2d);
4e57c75e 591}
592
593//=======================================================================
594//function : MakePCurveOnFace
595//purpose :
596//=======================================================================
f1baf495 597void BOPTools_AlgoTools2D::MakePCurveOnFace
598 (const TopoDS_Face& aF,
599 const Handle(Geom_Curve)& aC3D,
fd372378 600 const Standard_Real aT1,
601 const Standard_Real aT2,
f1baf495 602 Handle(Geom2d_Curve)& aC2D,
603 Standard_Real& TolReached2d)
4e57c75e 604{
1b7ae951 605 Standard_Real aTolR, aT;
fd372378 606 Standard_Real aUMin, aUMax, aVMin, aVMax;
4e57c75e 607 Handle(Geom2d_Curve) aC2DA;
fd372378 608 Handle(GeomAdaptor_HSurface) aBAHS;
609 Handle(GeomAdaptor_HCurve) aBAHC;
610 Handle(Geom_Surface) aS;
611 //
612 BRepAdaptor_Surface aBAS(aF, Standard_True);
613 aUMin=aBAS.FirstUParameter();
614 aUMax=aBAS.LastUParameter();
615 aVMin=aBAS.FirstVParameter();
616 aVMax=aBAS.LastVParameter();
617 aS=aBAS.Surface().Surface();
618 aS=Handle(Geom_Surface)::DownCast(aS->Transformed(aBAS.Trsf()));
619 GeomAdaptor_Surface aGAS(aS, aUMin, aUMax, aVMin, aVMax);
620 //
621 aBAHS=new GeomAdaptor_HSurface(aGAS);
622 aBAHC=new GeomAdaptor_HCurve(aC3D, aT1, aT2);
f2843558 623 //
4e57c75e 624 //when the type of surface is GeomAbs_SurfaceOfRevolution
f2843558 625 if (aGAS.GetType() == GeomAbs_SurfaceOfRevolution) {
fd372378 626 Standard_Real aTR;
627 //
628 aTR=Precision::Confusion();//1.e-7;
629 if (TolReached2d > aTR) {
630 aTR=TolReached2d;
631 }
632 //
4e57c75e 633 ProjLib_ProjectedCurve aProj1(aBAHS, aBAHC, aTR);
634 BOPTools_AlgoTools2D::MakePCurveOfType(aProj1, aC2D);
635 aTolR = aProj1.GetTolerance();
fd372378 636 }
637 else {
4e57c75e 638 ProjLib_ProjectedCurve aProjCurv(aBAHS, aBAHC);// 1
639 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurv, aC2D);
640 aTolR=aProjCurv.GetTolerance();
641 }
642 //
643 if (aC2D.IsNull()) {
644 ProjLib_ProjectedCurve aProjCurvAgain(aBAHS, aBAHC, TolReached2d);// 2
645 BOPTools_AlgoTools2D::MakePCurveOfType(aProjCurvAgain, aC2D);
646 aTolR = aProjCurvAgain.GetTolerance();
647 //
648 if (aC2D.IsNull()) {
649 Standard_Real aTR=0.0001;
650 ProjLib_ProjectedCurve aProj3(aBAHS, aBAHC, aTR);// 3
651 BOPTools_AlgoTools2D::MakePCurveOfType(aProj3, aC2D);
652 aTolR = aProj3.GetTolerance();
653 }
654 }
655 TolReached2d=aTolR;
fd372378 656 BOPTools_AlgoTools2D::AdjustPCurveOnFace (aBAS, aT1, aT2,
f1baf495 657 aC2D, aC2DA);
fd372378 658 //
4e57c75e 659 aC2D=aC2DA;
1b7ae951 660 //
661 // compute the appropriate tolerance for the edge
662 if (IntTools_Tools::ComputeTolerance
fd372378 663 (aC3D, aC2D, aS, aT1, aT2, aTolR, aT)) {
1b7ae951 664 if (aTolR > TolReached2d) {
665 TolReached2d = aTolR;
666 }
667 }
4e57c75e 668}
7fd59977 669
670//=======================================================================
671//function : MakePCurveOfType
672//purpose :
673//=======================================================================
f1baf495 674void BOPTools_AlgoTools2D::MakePCurveOfType
675 (const ProjLib_ProjectedCurve& PC,
676 Handle(Geom2d_Curve)& C2D)
7fd59977 677{
678
679 switch (PC.GetType()) {
680
681 case GeomAbs_Line :
682 C2D = new Geom2d_Line(PC.Line());
683 break;
684 case GeomAbs_Circle :
685 C2D = new Geom2d_Circle(PC.Circle());
686 break;
687 case GeomAbs_Ellipse :
688 C2D = new Geom2d_Ellipse(PC.Ellipse());
689 break;
690 case GeomAbs_Parabola :
691 C2D = new Geom2d_Parabola(PC.Parabola());
692 break;
693 case GeomAbs_Hyperbola :
694 C2D = new Geom2d_Hyperbola(PC.Hyperbola());
695 break;
696 case GeomAbs_BSplineCurve :
697 C2D = PC.BSpline();
698 break;
699 case GeomAbs_BezierCurve :
700 case GeomAbs_OtherCurve :
701 default :
f1baf495 702 Standard_NotImplemented::Raise
703 ("BOPTools_AlgoTools2D::MakePCurveOfType");
7fd59977 704 break;
705 }
706}
4e57c75e 707//=======================================================================
708//function : CheckEdgeLength
709//purpose :
710//=======================================================================
711Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
712{
713 BRepAdaptor_Curve BC(E);
714
715 BOPCol_IndexedMapOfShape aM;
716 BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
717 Standard_Integer i, anExtent, aN=10;
718 Standard_Real ln=0., d, t, f, l, dt;
719 anExtent=aM.Extent();
720
721 if (anExtent!=1)
722 return Standard_True;
723
724 gp_Pnt p1, p2;
725 f = BC.FirstParameter();
726 l = BC.LastParameter();
727 dt=(l-f)/aN;
728
729 BC.D0(f, p1);
730 for (i=1; i<=aN; i++) {
731 t=f+i*dt;
732
733 if (i==aN)
734 BC.D0(l, p2);
735 else
736 BC.D0(t, p2);
737
738 d=p1.Distance(p2);
739 ln+=d;
740 p1=p2;
741 }
f1baf495 742 //
4e57c75e 743 return (ln > Precision::Confusion());
744}
4e57c75e 745//=======================================================================
f1baf495 746//function : BRep_Tool_CurveOnSurface
4e57c75e 747//purpose :
748//=======================================================================
f1baf495 749Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& E,
750 const TopoDS_Face& F,
751 Standard_Real& First,
752 Standard_Real& Last,
753 Standard_Boolean& bToUpdate)
4e57c75e 754{
f1baf495 755 TopLoc_Location l;
756 const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,l);
757 TopoDS_Edge aLocalEdge = E;
758 if (F.Orientation() == TopAbs_REVERSED) {
759 aLocalEdge.Reverse();
4e57c75e 760 }
f1baf495 761 //
762 return BRep_Tool_CurveOnSurface(aLocalEdge,S,l,First,Last,bToUpdate);
4e57c75e 763}
7fd59977 764//=======================================================================
f1baf495 765//function : BRep_Tool_CurveOnSurface
7fd59977 766//purpose :
767//=======================================================================
f1baf495 768Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface
769 (const TopoDS_Edge& E,
770 const Handle(Geom_Surface)& S,
771 const TopLoc_Location& L,
772 Standard_Real& First,
773 Standard_Real& Last,
774 Standard_Boolean& bToUpdate)
7fd59977 775{
f1baf495 776 static const Handle(Geom2d_Curve) nullPCurve;
777 bToUpdate=Standard_False;
778 TopLoc_Location loc = L.Predivided(E.Location());
779 Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
780
781 // find the representation
782 BRep_ListIteratorOfListOfCurveRepresentation itcr
783 ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
784
785 while (itcr.More()) {
786 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
787 if (cr->IsCurveOnSurface(S,loc)) {
788 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
789 GC->Range(First,Last);
790 if (GC->IsCurveOnClosedSurface() && Eisreversed)
791 return GC->PCurve2();
792 else
793 return GC->PCurve();
794 }
795 itcr.Next();
7fd59977 796 }
797
f1baf495 798 // for planar surface and 3d curve try a projection
799 // modif 21-05-97 : for RectangularTrimmedSurface, try a projection
800 Handle(Geom_Plane) GP;
801 Handle(Geom_RectangularTrimmedSurface) GRTS;
802 GRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
803 if(!GRTS.IsNull())
804 GP = Handle(Geom_Plane)::DownCast(GRTS->BasisSurface());
805 else
806 GP = Handle(Geom_Plane)::DownCast(S);
807 //fin modif du 21-05-97
7fd59977 808
f1baf495 809 if (!GP.IsNull()) {
7fd59977 810
f1baf495 811 Handle(GeomAdaptor_HCurve) HC;
812 Handle(GeomAdaptor_HSurface) HS;
7fd59977 813
f1baf495 814 HC = new GeomAdaptor_HCurve();
815 HS = new GeomAdaptor_HSurface();
7fd59977 816
f1baf495 817 TopLoc_Location LC;
7fd59977 818
f1baf495 819 Standard_Real f, l;// for those who call with (u,u).
820 Handle(Geom_Curve) C3d =
821 BRep_Tool::Curve(E,/*LC,*/f,l); // transforming plane instead of curve
822 // we can loose scale factor of Curve transformation (eap 13 May 2002)
7fd59977 823
f1baf495 824 LC = L/*.Predivided(LC)*/;
7fd59977 825
f1baf495 826 if (C3d.IsNull()) return nullPCurve;
7fd59977 827
f1baf495 828 Handle(Geom_Plane) Plane = GP;
829 if (!LC.IsIdentity()) {
830 const gp_Trsf& T = LC.Transformation();
831 Handle(Geom_Geometry) GPT = GP->Transformed(T);
832 Plane = *((Handle(Geom_Plane)*)&GPT);
833 }
834 GeomAdaptor_Surface& GAS = HS->ChangeSurface();
835 GAS.Load(Plane);
836
837 Handle(Geom_Curve) ProjOnPlane =
838 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,f,l),
839 Plane,
840 Plane->Position().Direction(),
841 Standard_True);
842
843 GeomAdaptor_Curve& GAC = HC->ChangeCurve();
844 GAC.Load(ProjOnPlane);
845
846 ProjLib_ProjectedCurve Proj(HS,HC);
847 Handle(Geom2d_Curve) pc = Geom2dAdaptor::MakeCurve(Proj);
7fd59977 848
f1baf495 849 if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
850 Handle(Geom2d_TrimmedCurve) TC =
851 (*((Handle(Geom2d_TrimmedCurve)*)&pc));
852 pc = TC->BasisCurve();
853 }
854 First = f; Last = l;
855 //
856 bToUpdate=Standard_True;
857 //
858 return pc;
859 }
860
861 return nullPCurve;
862}
fc88faf1 863//=======================================================================
864//function : MaxToleranceEdge
865//purpose :
866//=======================================================================
867Standard_Real MaxToleranceEdge (const TopoDS_Face& aF)
868{
869 Standard_Real aTol, aTolMax;
870 TopExp_Explorer aExp;
871 //
872 aTolMax=0.;
873 aExp.Init(aF, TopAbs_EDGE);
874 for (; aExp.More(); aExp.Next()) {
875 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
876 aTol=BRep_Tool::Tolerance(aE);
877 if (aTol>aTolMax) {
878 aTolMax=aTol;
879 }
880 }
881 return aTolMax;
882}