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