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