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