0024023: Revamp the OCCT Handle -- downcast (automatic)
[occt.git] / src / IntTools / IntTools_FaceFace.cxx
CommitLineData
b311480e 1// Created on: 2000-11-23
2// Created by: Michael KLOKOV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <IntTools_FaceFace.ixx>
17
18#include <Precision.hxx>
19
20#include <TColStd_HArray1OfReal.hxx>
21#include <TColStd_Array1OfReal.hxx>
22#include <TColStd_Array1OfInteger.hxx>
23#include <TColStd_SequenceOfReal.hxx>
24#include <TColStd_ListOfInteger.hxx>
25#include <TColStd_ListIteratorOfListOfInteger.hxx>
26#include <TColStd_Array1OfListOfInteger.hxx>
27
28#include <gp_Lin2d.hxx>
29#include <gp_Ax22d.hxx>
30#include <gp_Circ2d.hxx>
31#include <gp_Torus.hxx>
32#include <gp_Cylinder.hxx>
33
34#include <Bnd_Box.hxx>
35
36#include <TColgp_HArray1OfPnt2d.hxx>
37#include <TColgp_SequenceOfPnt2d.hxx>
38#include <TColgp_Array1OfPnt.hxx>
39#include <TColgp_Array1OfPnt2d.hxx>
40
41#include <IntAna_QuadQuadGeo.hxx>
42
43#include <IntSurf_PntOn2S.hxx>
44#include <IntSurf_LineOn2S.hxx>
45#include <IntSurf_PntOn2S.hxx>
46#include <IntSurf_ListOfPntOn2S.hxx>
47#include <IntRes2d_Domain.hxx>
48#include <ProjLib_Plane.hxx>
49
50#include <IntPatch_GLine.hxx>
51#include <IntPatch_RLine.hxx>
52#include <IntPatch_WLine.hxx>
53#include <IntPatch_ALine.hxx>
54#include <IntPatch_ALineToWLine.hxx>
55
56#include <ElSLib.hxx>
57#include <ElCLib.hxx>
58
59#include <Extrema_ExtCC.hxx>
60#include <Extrema_POnCurv.hxx>
61#include <BndLib_AddSurface.hxx>
62
63#include <Adaptor3d_SurfacePtr.hxx>
64#include <Adaptor2d_HLine2d.hxx>
65
66#include <GeomAbs_SurfaceType.hxx>
67#include <GeomAbs_CurveType.hxx>
68
69#include <Geom_Surface.hxx>
70#include <Geom_Line.hxx>
71#include <Geom_Circle.hxx>
72#include <Geom_Ellipse.hxx>
73#include <Geom_Parabola.hxx>
74#include <Geom_Hyperbola.hxx>
75#include <Geom_TrimmedCurve.hxx>
76#include <Geom_BSplineCurve.hxx>
77#include <Geom_RectangularTrimmedSurface.hxx>
78#include <Geom_OffsetSurface.hxx>
79#include <Geom_Curve.hxx>
80#include <Geom_Conic.hxx>
81
82#include <Geom2d_TrimmedCurve.hxx>
83#include <Geom2d_BSplineCurve.hxx>
84#include <Geom2d_Line.hxx>
85#include <Geom2d_Curve.hxx>
86#include <Geom2d_Circle.hxx>
87
88#include <Geom2dAPI_InterCurveCurve.hxx>
89#include <Geom2dInt_GInter.hxx>
d4b867e6 90#include <Geom2dAdaptor.hxx>
7fd59977 91#include <GeomAdaptor_Curve.hxx>
92#include <GeomAdaptor_HSurface.hxx>
93#include <GeomAdaptor_Surface.hxx>
94#include <GeomLib_CheckBSplineCurve.hxx>
95#include <GeomLib_Check2dBSplineCurve.hxx>
96
97#include <GeomInt_WLApprox.hxx>
98#include <GeomProjLib.hxx>
99#include <GeomAPI_ProjectPointOnSurf.hxx>
100#include <Geom2dAdaptor_Curve.hxx>
7fd59977 101#include <TopoDS.hxx>
102#include <TopoDS_Edge.hxx>
103#include <TopExp_Explorer.hxx>
104
105#include <BRep_Tool.hxx>
106#include <BRepTools.hxx>
107#include <BRepAdaptor_Surface.hxx>
108
7fd59977 109#include <IntTools_Curve.hxx>
110#include <IntTools_Tools.hxx>
111#include <IntTools_Tools.hxx>
112#include <IntTools_TopolTool.hxx>
113#include <IntTools_PntOnFace.hxx>
114#include <IntTools_PntOn2Faces.hxx>
1e143abb 115#include <IntTools_Context.hxx>
0fc4f2e2 116#include <IntSurf_ListIteratorOfListOfPntOn2S.hxx>
2a78ec6a 117#include <GeomInt.hxx>
a2eede02 118
d4b867e6 119#include <Approx_CurveOnSurface.hxx>
120#include <GeomAdaptor.hxx>
121#include <GeomInt_IntSS.hxx>
122
fa9681ca
P
123static
124 void RefineVector(gp_Vec2d& aV2D);
0797d9d3 125#ifdef OCCT_DEBUG_DUMPWLINE
a2eede02
P
126static
127 void DumpWLine(const Handle(IntPatch_WLine)& aWLine);
4e18e72a 128#endif
7fd59977 129//
130static
131 void TolR3d(const TopoDS_Face& ,
655fddc8 132 const TopoDS_Face& ,
133 Standard_Real& );
7fd59977 134static
135 Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)&,
655fddc8 136 const Standard_Integer,
137 const Standard_Integer);
7fd59977 138
139static
140 void Parameters(const Handle(GeomAdaptor_HSurface)&,
655fddc8 141 const Handle(GeomAdaptor_HSurface)&,
142 const gp_Pnt&,
143 Standard_Real&,
144 Standard_Real&,
145 Standard_Real&,
146 Standard_Real&);
7fd59977 147
148static
7fd59977 149 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
655fddc8 150 const Standard_Real theTolerance,
151 Standard_Real& theumin,
152 Standard_Real& theumax,
153 Standard_Real& thevmin,
154 Standard_Real& thevmax);
d4b867e6 155
7fd59977 156static
157 Standard_Boolean NotUseSurfacesForApprox
158 (const TopoDS_Face& aF1,
655fddc8 159 const TopoDS_Face& aF2,
160 const Handle(IntPatch_WLine)& WL,
161 const Standard_Integer ifprm,
162 const Standard_Integer ilprm);
7fd59977 163
164static
165 Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine);
166
167static
7fd59977 168 Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
655fddc8 169 const Standard_Integer ideb,
170 const Standard_Integer ifin,
171 const Standard_Boolean onFirst);
7fd59977 172
173static
174 Standard_Boolean DecompositionOfWLine(const Handle(IntPatch_WLine)& theWLine,
655fddc8 175 const Handle(GeomAdaptor_HSurface)& theSurface1,
176 const Handle(GeomAdaptor_HSurface)& theSurface2,
177 const TopoDS_Face& theFace1,
178 const TopoDS_Face& theFace2,
2a78ec6a 179 const GeomInt_LineConstructor& theLConstructor,
655fddc8 180 const Standard_Boolean theAvoidLConstructor,
181 IntPatch_SequenceOfLine& theNewLines,
182 Standard_Real& theReachedTol3d,
1e143abb 183 const Handle(IntTools_Context)& );
7fd59977 184
185static
186 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
655fddc8 187 const Handle(Geom_Curve)& theCurve,
188 const TopoDS_Face& theFace1,
189 const TopoDS_Face& theFace2,
190 const Standard_Real theOtherParameter,
191 const Standard_Boolean bIncreasePar,
192 Standard_Real& theNewParameter,
1e143abb 193 const Handle(IntTools_Context)& );
7fd59977 194
195static
196 Standard_Boolean IsCurveValid(Handle(Geom2d_Curve)& thePCurve);
197
198static
199 Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
655fddc8 200 const Standard_Real theFirstBoundary,
201 const Standard_Real theSecondBoundary,
202 const Standard_Real theResolution,
203 Standard_Boolean& IsOnFirstBoundary);
7fd59977 204static
205 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 206 const gp_Pnt2d& theLastPoint,
207 const Standard_Real theUmin,
208 const Standard_Real theUmax,
209 const Standard_Real theVmin,
210 const Standard_Real theVmax,
211 gp_Pnt2d& theNewPoint);
7fd59977 212
213
214static
215 Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
655fddc8 216 const Handle(GeomAdaptor_HSurface)& theSurface2,
217 const TopoDS_Face& theFace1,
218 const TopoDS_Face& theFace2,
219 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
220 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
221 Handle(TColStd_HArray1OfReal)& theResultRadius,
1e143abb 222 const Handle(IntTools_Context)& );
7fd59977 223
224static
225 Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 226 const gp_Pnt2d& theLastPoint,
227 const Standard_Real theUmin,
228 const Standard_Real theUmax,
229 const Standard_Real theVmin,
230 const Standard_Real theVmax,
231 const gp_Pnt2d& theTanZoneCenter,
232 const Standard_Real theZoneRadius,
233 Handle(GeomAdaptor_HSurface) theGASurface,
234 gp_Pnt2d& theNewPoint);
7fd59977 235
236static
237 Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
655fddc8 238 const gp_Pnt2d& theTanZoneCenter,
239 const Standard_Real theZoneRadius,
240 Handle(GeomAdaptor_HSurface) theGASurface);
7fd59977 241
242static
4f189102 243 gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
655fddc8 244 const gp_Pnt2d& theOriginalPoint,
245 Handle(GeomAdaptor_HSurface) theGASurface);
7fd59977 246static
4f189102 247 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
655fddc8 248 const gp_Sphere& theSph);
7fd59977 249
250static void PerformPlanes(const Handle(GeomAdaptor_HSurface)& theS1,
655fddc8 251 const Handle(GeomAdaptor_HSurface)& theS2,
252 const Standard_Real TolAng,
253 const Standard_Real TolTang,
254 const Standard_Boolean theApprox1,
255 const Standard_Boolean theApprox2,
7fd59977 256 IntTools_SequenceOfCurves& theSeqOfCurve,
655fddc8 257 Standard_Boolean& theTangentFaces);
7fd59977 258
259static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_HSurface)& theS,
655fddc8 260 const gp_Lin2d& theLin2d,
261 const Standard_Real theTol,
262 Standard_Real& theP1,
263 Standard_Real& theP2);
0fc4f2e2 264//
7fd59977 265static
266 void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
655fddc8 267 const Handle(GeomAdaptor_HSurface)& aHS2,
268 Standard_Integer& iDegMin,
269 Standard_Integer& iNbIter,
270 Standard_Integer& iDegMax);
7fd59977 271
0fc4f2e2
P
272static
273 void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
655fddc8 274 const Handle(GeomAdaptor_HSurface)& aHS2,
788cbaf4 275 Standard_Real& aTolTang);
0fc4f2e2 276
0fc4f2e2
P
277static
278 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
655fddc8 279 const GeomAbs_SurfaceType aType2);
0fc4f2e2
P
280static
281 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
d10203e8 282
7fd59977 283//
4f189102 284static
989341c5 285 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
286 const TopoDS_Face& aFace);
287
9a5a19e9 288static
289 void CorrectPlaneBoundaries(Standard_Real& aUmin,
290 Standard_Real& aUmax,
291 Standard_Real& aVmin,
292 Standard_Real& aVmax);
293
7fd59977 294//=======================================================================
295//function :
296//purpose :
297//=======================================================================
4f189102 298IntTools_FaceFace::IntTools_FaceFace()
7fd59977 299{
3f16d970 300 myIsDone=Standard_False;
7fd59977 301 myTangentFaces=Standard_False;
302 //
303 myHS1 = new GeomAdaptor_HSurface ();
304 myHS2 = new GeomAdaptor_HSurface ();
305 myTolReached2d=0.;
306 myTolReached3d=0.;
307 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
4f189102
P
308
309}
310//=======================================================================
311//function : SetContext
312//purpose :
313//=======================================================================
1e143abb 314void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
4f189102
P
315{
316 myContext=aContext;
317}
318//=======================================================================
319//function : Context
320//purpose :
321//=======================================================================
1e143abb 322const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
4f189102
P
323{
324 return myContext;
7fd59977 325}
326//=======================================================================
327//function : Face1
328//purpose :
329//=======================================================================
4f189102 330const TopoDS_Face& IntTools_FaceFace::Face1() const
7fd59977 331{
332 return myFace1;
333}
7fd59977 334//=======================================================================
335//function : Face2
336//purpose :
337//=======================================================================
4f189102 338const TopoDS_Face& IntTools_FaceFace::Face2() const
7fd59977 339{
340 return myFace2;
341}
7fd59977 342//=======================================================================
343//function : TangentFaces
344//purpose :
345//=======================================================================
4f189102 346Standard_Boolean IntTools_FaceFace::TangentFaces() const
7fd59977 347{
348 return myTangentFaces;
349}
350//=======================================================================
351//function : Points
352//purpose :
353//=======================================================================
4f189102 354const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
7fd59977 355{
356 return myPnts;
357}
358//=======================================================================
359//function : IsDone
360//purpose :
361//=======================================================================
4f189102 362Standard_Boolean IntTools_FaceFace::IsDone() const
7fd59977 363{
364 return myIsDone;
365}
366//=======================================================================
367//function : TolReached3d
368//purpose :
369//=======================================================================
4f189102 370Standard_Real IntTools_FaceFace::TolReached3d() const
7fd59977 371{
372 return myTolReached3d;
373}
374//=======================================================================
375//function : Lines
376//purpose : return lines of intersection
377//=======================================================================
4f189102 378const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
7fd59977 379{
4f189102
P
380 StdFail_NotDone_Raise_if
381 (!myIsDone,
788cbaf4 382 "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
7fd59977 383 return mySeqOfCurve;
384}
7fd59977 385//=======================================================================
386//function : TolReached2d
387//purpose :
388//=======================================================================
4f189102 389Standard_Real IntTools_FaceFace::TolReached2d() const
7fd59977 390{
391 return myTolReached2d;
392}
393// =======================================================================
394// function: SetParameters
395//
396// =======================================================================
4f189102 397void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
655fddc8 398 const Standard_Boolean ToApproxC2dOnS1,
399 const Standard_Boolean ToApproxC2dOnS2,
400 const Standard_Real ApproximationTolerance)
7fd59977 401{
402 myApprox = ToApproxC3d;
403 myApprox1 = ToApproxC2dOnS1;
404 myApprox2 = ToApproxC2dOnS2;
405 myTolApprox = ApproximationTolerance;
406}
407//=======================================================================
408//function : SetList
409//purpose :
410//=======================================================================
7fd59977 411void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
412{
413 myListOfPnts = aListOfPnts;
414}
788cbaf4 415
416
417static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
418 const TopoDS_Face& theF2)
419{
420 const Standard_Real Tolang = 1.e-8;
421 const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
422 const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
423 const Standard_Real aTolSum = aTolF1 + aTolF2;
424 Standard_Real aHigh = 0.0;
425
426 const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
427 const GeomAbs_SurfaceType aType1=aBAS1.GetType();
428 const GeomAbs_SurfaceType aType2=aBAS2.GetType();
429
430 gp_Pln aS1;
431 gp_Cylinder aS2;
432 if(aType1 == GeomAbs_Plane)
433 {
434 aS1=aBAS1.Plane();
435 }
436 else if(aType2 == GeomAbs_Plane)
437 {
438 aS1=aBAS2.Plane();
439 }
440 else
441 {
442 return Standard_True;
443 }
444
445 if(aType1 == GeomAbs_Cylinder)
446 {
447 aS2=aBAS1.Cylinder();
448 const Standard_Real VMin = aBAS1.FirstVParameter();
449 const Standard_Real VMax = aBAS1.LastVParameter();
450
451 if( Precision::IsNegativeInfinite(VMin) ||
452 Precision::IsPositiveInfinite(VMax))
453 return Standard_True;
454 else
455 aHigh = VMax - VMin;
456 }
457 else if(aType2 == GeomAbs_Cylinder)
458 {
459 aS2=aBAS2.Cylinder();
460
461 const Standard_Real VMin = aBAS2.FirstVParameter();
462 const Standard_Real VMax = aBAS2.LastVParameter();
463
464 if( Precision::IsNegativeInfinite(VMin) ||
465 Precision::IsPositiveInfinite(VMax))
466 return Standard_True;
467 else
468 aHigh = VMax - VMin;
469 }
470 else
471 {
472 return Standard_True;
473 }
474
475 IntAna_QuadQuadGeo inter;
476 inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh);
477 if(inter.TypeInter() == IntAna_Ellipse)
478 {
479 const gp_Elips anEl = inter.Ellipse(1);
480 const Standard_Real aMajorR = anEl.MajorRadius();
481 const Standard_Real aMinorR = anEl.MinorRadius();
482
483 return (aMajorR < 100000.0 * aMinorR);
484 }
485 else
486 {
487 return inter.IsDone();
488 }
489}
7fd59977 490//=======================================================================
491//function : Perform
492//purpose : intersect surfaces of the faces
493//=======================================================================
9a5a19e9 494void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
c002793b 495 const TopoDS_Face& aF2)
7fd59977 496{
788cbaf4 497 Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False;
498
4f189102 499 if (myContext.IsNull()) {
1e143abb 500 myContext=new IntTools_Context;
4f189102 501 }
788cbaf4 502
7fd59977 503 mySeqOfCurve.Clear();
7fd59977 504 myTolReached2d=0.;
505 myTolReached3d=0.;
7fd59977 506 myIsDone = Standard_False;
0fc4f2e2 507 myNbrestr=0;//?
788cbaf4 508
0fc4f2e2
P
509 myFace1=aF1;
510 myFace2=aF2;
788cbaf4 511
512 const BRepAdaptor_Surface aBAS1(myFace1, Standard_False);
513 const BRepAdaptor_Surface aBAS2(myFace2, Standard_False);
514 GeomAbs_SurfaceType aType1=aBAS1.GetType();
515 GeomAbs_SurfaceType aType2=aBAS2.GetType();
516
517 const Standard_Boolean bReverse=SortTypes(aType1, aType2);
518 if (bReverse)
519 {
0fc4f2e2
P
520 myFace1=aF2;
521 myFace2=aF1;
522 aType1=aBAS2.GetType();
523 aType2=aBAS1.GetType();
788cbaf4 524
525 if (myListOfPnts.Extent())
526 {
0fc4f2e2
P
527 Standard_Real aU1,aV1,aU2,aV2;
528 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
529 //
530 aItP2S.Initialize(myListOfPnts);
788cbaf4 531 for (; aItP2S.More(); aItP2S.Next())
532 {
655fddc8 533 IntSurf_PntOn2S& aP2S=aItP2S.Value();
534 aP2S.Parameters(aU1,aV1,aU2,aV2);
535 aP2S.SetValue(aU2,aV2,aU1,aV1);
0fc4f2e2
P
536 }
537 }
2d2aa6f1 538 //
539 Standard_Boolean anAproxTmp = myApprox1;
540 myApprox1 = myApprox2;
541 myApprox2 = anAproxTmp;
0fc4f2e2 542 }
7fd59977 543
788cbaf4 544
545 const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
546 const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
547
548 const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
549 const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
550
551 Standard_Real TolArc = aTolF1 + aTolF2;
552 Standard_Real TolTang = TolArc;
553
554 const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
555 aType1 == GeomAbs_Cone ||
556 aType1 == GeomAbs_Torus);
557
558 const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
559 aType2 == GeomAbs_Cone ||
560 aType2 == GeomAbs_Torus);
561
a34f083b 562 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
788cbaf4 563 Standard_Real umin, umax, vmin, vmax;
a34f083b 564 //
0fc4f2e2 565 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
9a5a19e9 566 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
7fd59977 567 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
568 //
0fc4f2e2 569 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
9a5a19e9 570 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
7fd59977 571 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
a34f083b 572 //
7fd59977 573 Standard_Real TolAng = 1.e-8;
a34f083b 574 //
59495dbe 575 PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
a34f083b 576 mySeqOfCurve, myTangentFaces);
577 //
7fd59977 578 myIsDone = Standard_True;
4f189102 579
a34f083b 580 if(!myTangentFaces) {
788cbaf4 581 const Standard_Integer NbLinPP = mySeqOfCurve.Length();
a34f083b 582 if(NbLinPP) {
655fddc8 583 Standard_Real aTolFMax;
584 myTolReached3d = 1.e-7;
585 aTolFMax=Max(aTolF1, aTolF2);
a34f083b 586 if (aTolFMax>myTolReached3d) {
655fddc8 587 myTolReached3d=aTolFMax;
588 }
a34f083b 589 //
655fddc8 590 myTolReached2d = myTolReached3d;
788cbaf4 591
a34f083b 592 if (bReverse) {
655fddc8 593 Handle(Geom2d_Curve) aC2D1, aC2D2;
788cbaf4 594 const Standard_Integer aNbLin = mySeqOfCurve.Length();
a34f083b 595 for (Standard_Integer i = 1; i <= aNbLin; ++i) {
655fddc8 596 IntTools_Curve& aIC=mySeqOfCurve(i);
597 aC2D1=aIC.FirstCurve2d();
598 aC2D2=aIC.SecondCurve2d();
599 aIC.SetFirstCurve2d(aC2D2);
600 aIC.SetSecondCurve2d(aC2D1);
601 }
602 }
0fc4f2e2
P
603 }
604 }
7fd59977 605 return;
0fc4f2e2 606 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
788cbaf4 607
608 if ((aType1==GeomAbs_Plane) && isFace2Quad)
609 {
788cbaf4 610 Standard_Real umin, umax, vmin, vmax;
9a5a19e9 611 // F1
612 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
613 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
7fd59977 614 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
615 // F2
0fc4f2e2
P
616 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
617 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 618 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
619 //
620 if( aType2==GeomAbs_Cone ) {
621 TolArc = 0.0001;
7fd59977 622 hasCone = Standard_True;
623 }
624 }
788cbaf4 625 else if ((aType2==GeomAbs_Plane) && isFace1Quad)
626 {
788cbaf4 627 Standard_Real umin, umax, vmin, vmax;
9a5a19e9 628 //F1
0fc4f2e2
P
629 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
630 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 631 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
632 // F2
0fc4f2e2 633 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
9a5a19e9 634 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
7fd59977 635 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
636 //
637 if( aType1==GeomAbs_Cone ) {
638 TolArc = 0.0001;
7fd59977 639 hasCone = Standard_True;
640 }
641 }
788cbaf4 642 else
643 {
644 Standard_Real umin, umax, vmin, vmax;
0fc4f2e2 645 BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
0fc4f2e2 646 CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 647 myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
0fc4f2e2 648 BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
0fc4f2e2 649 CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
7fd59977 650 myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
651 }
788cbaf4 652
653 const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
654 const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
655
7fd59977 656 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
788cbaf4 657
658
659 Tolerances(myHS1, myHS2, TolTang);
660
661 {
662 const Standard_Real UVMaxStep = 0.001;
663 const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1;
59495dbe 664 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
788cbaf4 665 }
666
7fd59977 667 if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
668 (myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
669 (myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
788cbaf4 670 (myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
671 {
7fd59977 672 RestrictLine = Standard_True;
673 }
674 //
788cbaf4 675 if((aType1 != GeomAbs_BSplineSurface) &&
59495dbe 676 (aType1 != GeomAbs_BezierSurface) &&
788cbaf4 677 (aType1 != GeomAbs_OtherSurface) &&
678 (aType2 != GeomAbs_BSplineSurface) &&
59495dbe 679 (aType2 != GeomAbs_BezierSurface) &&
788cbaf4 680 (aType2 != GeomAbs_OtherSurface))
681 {
7fd59977 682 RestrictLine = Standard_True;
788cbaf4 683
7fd59977 684 if ((aType1 == GeomAbs_Torus) ||
788cbaf4 685 (aType2 == GeomAbs_Torus))
686 {
7fd59977 687 myListOfPnts.Clear();
688 }
689 }
788cbaf4 690
7fd59977 691 //
788cbaf4 692 if(!RestrictLine)
693 {
7fd59977 694 TopExp_Explorer aExp;
788cbaf4 695 for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
696 {
7fd59977 697 const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
698 aExp.Init(aF, TopAbs_EDGE);
788cbaf4 699 for(; aExp.More(); aExp.Next())
700 {
655fddc8 701 const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
788cbaf4 702
703 if(BRep_Tool::Degenerated(aE))
704 {
655fddc8 705 RestrictLine = Standard_True;
706 break;
707 }
7fd59977 708 }
709 }
710 }
788cbaf4 711
712 const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2);
713 myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
714 myListOfPnts, RestrictLine, isGeomInt);
715
7fd59977 716 myIsDone = myIntersector.IsDone();
788cbaf4 717
718 if (myIsDone)
719 {
7fd59977 720 myTangentFaces=myIntersector.TangentFaces();
721 if (myTangentFaces) {
722 return;
723 }
724 //
725 if(RestrictLine) {
726 myListOfPnts.Clear(); // to use LineConstructor
727 }
728 //
788cbaf4 729 const Standard_Integer aNbLin = myIntersector.NbLines();
730 for (Standard_Integer i=1; i <= aNbLin; ++i) {
7fd59977 731 MakeCurve(i, dom1, dom2);
732 }
733 //
734 ComputeTolReached3d();
735 //
0fc4f2e2
P
736 if (bReverse) {
737 Handle(Geom2d_Curve) aC2D1, aC2D2;
738 //
788cbaf4 739 const Standard_Integer aNbLin=mySeqOfCurve.Length();
740 for (Standard_Integer i=1; i<=aNbLin; ++i)
741 {
655fddc8 742 IntTools_Curve& aIC=mySeqOfCurve(i);
743 aC2D1=aIC.FirstCurve2d();
744 aC2D2=aIC.SecondCurve2d();
745 aIC.SetFirstCurve2d(aC2D2);
746 aIC.SetSecondCurve2d(aC2D1);
0fc4f2e2
P
747 }
748 }
788cbaf4 749
0fc4f2e2 750 // Points
e9e644ed 751 Standard_Boolean bValid2D1, bValid2D2;
7fd59977 752 Standard_Real U1,V1,U2,V2;
753 IntTools_PntOnFace aPntOnF1, aPntOnF2;
0fc4f2e2 754 IntTools_PntOn2Faces aPntOn2Faces;
7fd59977 755 //
788cbaf4 756 const Standard_Integer aNbPnts = myIntersector.NbPnts();
757 for (Standard_Integer i=1; i <= aNbPnts; ++i)
758 {
7fd59977 759 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
760 const gp_Pnt& aPnt=aISPnt.Value();
761 aISPnt.Parameters(U1,V1,U2,V2);
e9e644ed 762 //
763 // check the validity of the intersection point for the faces
764 bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
765 if (!bValid2D1) {
766 continue;
767 }
768 //
769 bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
770 if (!bValid2D2) {
771 continue;
772 }
773 //
774 // add the intersection point
0fc4f2e2
P
775 aPntOnF1.Init(myFace1, aPnt, U1, V1);
776 aPntOnF2.Init(myFace2, aPnt, U2, V2);
d10203e8 777 //
788cbaf4 778 if (!bReverse)
779 {
655fddc8 780 aPntOn2Faces.SetP1(aPntOnF1);
781 aPntOn2Faces.SetP2(aPntOnF2);
0fc4f2e2 782 }
788cbaf4 783 else
784 {
655fddc8 785 aPntOn2Faces.SetP2(aPntOnF1);
786 aPntOn2Faces.SetP1(aPntOnF2);
0fc4f2e2 787 }
788cbaf4 788
7fd59977 789 myPnts.Append(aPntOn2Faces);
790 }
7fd59977 791 }
792}
788cbaf4 793
7fd59977 794//=======================================================================
1b7ae951 795//function : ComputeTolerance
796//purpose :
797//=======================================================================
798Standard_Real IntTools_FaceFace::ComputeTolerance()
799{
800 Standard_Integer i, j, aNbLin;
bcf50875 801 Standard_Real aFirst, aLast, aD, aDMax, aT;
1b7ae951 802 Handle(Geom_Surface) aS1, aS2;
803 //
804 aDMax = 0;
1b7ae951 805 aNbLin = mySeqOfCurve.Length();
806 //
807 aS1 = myHS1->ChangeSurface().Surface();
808 aS2 = myHS2->ChangeSurface().Surface();
809 //
260f924f 810 for (i = 1; i <= aNbLin; ++i)
811 {
1b7ae951 812 const IntTools_Curve& aIC = mySeqOfCurve(i);
813 const Handle(Geom_Curve)& aC3D = aIC.Curve();
260f924f 814 if (aC3D.IsNull())
815 {
1b7ae951 816 continue;
817 }
818 //
819 aFirst = aC3D->FirstParameter();
820 aLast = aC3D->LastParameter();
821 //
822 const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
823 const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
824 //
260f924f 825 for (j = 0; j < 2; ++j)
826 {
1b7ae951 827 const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
828 const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
829 //
260f924f 830 if (!aC2D.IsNull())
831 {
1b7ae951 832 if (IntTools_Tools::ComputeTolerance
260f924f 833 (aC3D, aC2D, aS, aFirst, aLast, aD, aT))
834 {
835 if (aD > aDMax)
836 {
1b7ae951 837 aDMax = aD;
838 }
839 }
840 }
1b7ae951 841 }
842 }
843 //
844 return aDMax;
845}
846
847//=======================================================================
7fd59977 848//function :ComputeTolReached3d
849//purpose :
850//=======================================================================
851 void IntTools_FaceFace::ComputeTolReached3d()
852{
128dba6f 853 Standard_Integer aNbLin, i;
7fd59977 854 GeomAbs_SurfaceType aType1, aType2;
855 //
856 aNbLin=myIntersector.NbLines();
37b6f439 857 if (!aNbLin) {
858 return;
859 }
860 //
7fd59977 861 aType1=myHS1->Surface().GetType();
862 aType2=myHS2->Surface().GetType();
863 //
4f189102
P
864 if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
865 if (aNbLin==2){
866 Handle(IntPatch_Line) aIL1, aIL2;
867 IntPatch_IType aTL1, aTL2;
7fd59977 868 //
4f189102
P
869 aIL1=myIntersector.Line(1);
870 aIL2=myIntersector.Line(2);
871 aTL1=aIL1->ArcType();
872 aTL2=aIL2->ArcType();
873 if (aTL1==IntPatch_Lin && aTL2==IntPatch_Lin) {
655fddc8 874 Standard_Real aD, aDTresh, dTol;
875 gp_Lin aL1, aL2;
876 //
877 dTol=1.e-8;
878 aDTresh=1.5e-6;
879 //
880 aL1=Handle(IntPatch_GLine)::DownCast(aIL1)->Line();
881 aL2=Handle(IntPatch_GLine)::DownCast(aIL2)->Line();
882 aD=aL1.Distance(aL2);
883 aD=0.5*aD;
884 if (aD<aDTresh) {
885 myTolReached3d=aD+dTol;
886 }
887 return;
7fd59977 888 }
889 }
4f189102 890 //ZZ
37b6f439 891 if (aNbLin) {// Check the distances
1b7ae951 892 Standard_Real aDMax;
4f189102 893 //
1b7ae951 894 aDMax = ComputeTolerance();
895 if (aDMax > 0.) {
896 myTolReached3d = aDMax;
897 }
37b6f439 898 }// if (aNbLin)
4f189102
P
899 }// if (aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder) {
900 //
0fc4f2e2 901 //904/G3 f
4f189102 902 else if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
7fd59977 903 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
904 //
905 aTolTresh=1.e-7;
906 //
907 aTolF1 = BRep_Tool::Tolerance(myFace1);
908 aTolF2 = BRep_Tool::Tolerance(myFace2);
909 aTolFMax=Max(aTolF1, aTolF2);
910 //
911 if (aTolFMax>aTolTresh) {
912 myTolReached3d=aTolFMax;
913 }
4f189102 914 }//if (aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
0fc4f2e2 915 //t
7fd59977 916 //IFV Bug OCC20297
4f189102 917 else if((aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane) ||
655fddc8 918 (aType2 == GeomAbs_Cylinder && aType1 == GeomAbs_Plane)) {
7fd59977 919 if(aNbLin == 1) {
920 const Handle(IntPatch_Line)& aIL1 = myIntersector.Line(1);
921 if(aIL1->ArcType() == IntPatch_Circle) {
655fddc8 922 gp_Circ aCir = Handle(IntPatch_GLine)::DownCast(aIL1)->Circle();
923 gp_XYZ aCirDir = aCir.Axis().Direction().XYZ();
924 gp_XYZ aPlDir;
925 gp_Pln aPln;
926 if(aType1 == GeomAbs_Plane) {
927 aPln = myHS1->Surface().Plane();
928 }
929 else {
930 aPln = myHS2->Surface().Plane();
931 }
932 aPlDir = aPln.Axis().Direction().XYZ();
933 Standard_Real cs = aCirDir*aPlDir;
934 if(cs < 0.) aPlDir.Reverse();
935 Standard_Real eps = 1.e-14;
936 if(!aPlDir.IsEqual(aCirDir, eps)) {
937 Standard_Integer aNbP = 11;
938 Standard_Real dt = 2.*M_PI / (aNbP - 1), t;
939 for(t = 0.; t < 2.*M_PI; t += dt) {
940 Standard_Real d = aPln.Distance(ElCLib::Value(t, aCir));
941 if(myTolReached3d < d) myTolReached3d = d;
942 }
943 myTolReached3d *= 1.1;
944 }
7fd59977 945 } //aIL1->ArcType() == IntPatch_Circle
946 } //aNbLin == 1
4f189102 947 } // aType1 == GeomAbs_Cylinder && aType2 == GeomAbs_Plane)
7fd59977 948 //End IFV Bug OCC20297
0fc4f2e2 949 //
4f189102 950 else if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
655fddc8 951 (aType2==GeomAbs_Plane && aType1==GeomAbs_Torus)) {
0fc4f2e2
P
952 aNbLin=mySeqOfCurve.Length();
953 if (aNbLin!=1) {
954 return;
955 }
956 //
128dba6f 957 Standard_Integer aNbP;
0fc4f2e2
P
958 Standard_Real aT, aT1, aT2, dT, aUT, aVT, aUP, aVP;
959 Standard_Real aDP, aDT, aDmax;
960 gp_Pln aPln;
961 gp_Torus aTorus;
962 gp_Pnt aP, aPP, aPT;
963 //
964 const IntTools_Curve& aIC=mySeqOfCurve(1);
965 const Handle(Geom_Curve)& aC3D=aIC.Curve();
c5f3a425 966 Handle(Geom_BSplineCurve) aBS (Handle(Geom_BSplineCurve)::DownCast(aC3D));
0fc4f2e2
P
967 if (aBS.IsNull()) {
968 return;
969 }
970 //
971 aT1=aBS->FirstParameter();
972 aT2=aBS->LastParameter();
973 //
974 aPln =(aType1==GeomAbs_Plane) ? myHS1->Plane() : myHS2->Plane();
975 aTorus=(aType1==GeomAbs_Plane) ? myHS2->Torus() : myHS1->Torus();
976 //
977 aDmax=-1.;
978 aNbP=11;
979 dT=(aT2-aT1)/(aNbP-1);
980 for (i=0; i<aNbP; ++i) {
981 aT=aT1+i*dT;
982 if (i==aNbP-1) {
655fddc8 983 aT=aT2;
0fc4f2e2
P
984 }
985 //
986 aC3D->D0(aT, aP);
987 //
988 ElSLib::Parameters(aPln, aP, aUP, aVP);
989 aPP=ElSLib::Value(aUP, aVP, aPln);
990 aDP=aP.SquareDistance(aPP);
991 if (aDP>aDmax) {
655fddc8 992 aDmax=aDP;
0fc4f2e2
P
993 }
994 //
995 ElSLib::Parameters(aTorus, aP, aUT, aVT);
996 aPT=ElSLib::Value(aUT, aVT, aTorus);
997 aDT=aP.SquareDistance(aPT);
998 if (aDT>aDmax) {
655fddc8 999 aDmax=aDT;
0fc4f2e2
P
1000 }
1001 }
1002 //
1003 if (aDmax > myTolReached3d*myTolReached3d) {
1004 myTolReached3d=sqrt(aDmax);
1005 myTolReached3d=1.1*myTolReached3d;
1006 }
1007 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
a9f7b6b5 1008 //
4f189102 1009 else if ((aType1==GeomAbs_SurfaceOfRevolution && aType2==GeomAbs_Cylinder) ||
1b7ae951 1010 (aType2==GeomAbs_SurfaceOfRevolution && aType1==GeomAbs_Cylinder) ||
1011 (aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ||
1012 (aType2==GeomAbs_Plane && aType1==GeomAbs_Sphere) ||
1013 (aType1==GeomAbs_Plane && aType2==GeomAbs_SurfaceOfExtrusion) ||
1014 (aType2==GeomAbs_Plane && aType1==GeomAbs_SurfaceOfExtrusion) ||
1015 (aType1==GeomAbs_Plane && aType2==GeomAbs_BSplineSurface) ||
1016 (aType2==GeomAbs_Plane && aType1==GeomAbs_BSplineSurface) ||
1017 !myApprox) {
0c5acd27 1018 //
1b7ae951 1019 Standard_Real aDMax;
0c5acd27 1020 //
1b7ae951 1021 aDMax = ComputeTolerance();
1022 if (aDMax > myTolReached3d) {
1023 myTolReached3d = aDMax;
0c5acd27 1024 }
4e57c75e 1025 }
7fd59977 1026}
1b7ae951 1027
7fd59977 1028//=======================================================================
1029//function : MakeCurve
1030//purpose :
1031//=======================================================================
1032 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
655fddc8 1033 const Handle(Adaptor3d_TopolTool)& dom1,
1034 const Handle(Adaptor3d_TopolTool)& dom2)
7fd59977 1035{
4abae870 1036 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
1037 Standard_Boolean ok, bPCurvesOk;
7fd59977 1038 Standard_Integer i, j, aNbParts;
1039 Standard_Real fprm, lprm;
1040 Standard_Real Tolpc;
1041 Handle(IntPatch_Line) L;
1042 IntPatch_IType typl;
1043 Handle(Geom_Curve) newc;
1044 //
1045 const Standard_Real TOLCHECK =0.0000001;
1046 const Standard_Real TOLANGCHECK=0.1;
1047 //
1048 rejectSurface = Standard_False;
1049 reApprox = Standard_False;
989341c5 1050 //
1051 bPCurvesOk = Standard_True;
59495dbe 1052
1053 reapprox:;
1054
7fd59977 1055 Tolpc = myTolApprox;
1056 bAvoidLineConstructor = Standard_False;
1057 L = myIntersector.Line(Index);
1058 typl = L->ArcType();
1059 //
1060 if(typl==IntPatch_Walking) {
1061 Handle(IntPatch_Line) anewL;
1062 //
c5f3a425 1063 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
4abae870 1064 //DumpWLine(aWLine);
1065
7fd59977 1066 anewL = ComputePurgedWLine(aWLine);
1067 if(anewL.IsNull()) {
1068 return;
1069 }
1070 L = anewL;
4abae870 1071
c5f3a425 1072 //Handle(IntPatch_WLine) aWLineX (Handle(IntPatch_WLine)::DownCast(L));
4abae870 1073 //DumpWLine(aWLineX);
1074
7fd59977 1075 //
1076 if(!myListOfPnts.IsEmpty()) {
1077 bAvoidLineConstructor = Standard_True;
1078 }
1079
1080 Standard_Integer nbp = aWLine->NbPnts();
1081 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
1082 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
1083
1084 const gp_Pnt& P1 = p1.Value();
1085 const gp_Pnt& P2 = p2.Value();
1086
1087 if(P1.SquareDistance(P2) < 1.e-14) {
1088 bAvoidLineConstructor = Standard_False;
1089 }
7fd59977 1090 }
d4b867e6 1091
1092 typl=L->ArcType();
1093
7fd59977 1094 //
1095 // Line Constructor
1096 if(!bAvoidLineConstructor) {
1097 myLConstruct.Perform(L);
1098 //
1099 bDone=myLConstruct.IsDone();
d4b867e6 1100 if(!bDone)
1101 {
7fd59977 1102 return;
1103 }
d4b867e6 1104
1105 if(typl != IntPatch_Restriction)
1106 {
1107 aNbParts=myLConstruct.NbParts();
1108 if (aNbParts <= 0)
1109 {
1110 return;
1111 }
1112 }
7fd59977 1113 }
1114 // Do the Curve
d4b867e6 1115
1116
7fd59977 1117 switch (typl) {
59495dbe 1118 //########################################
1119 // Line, Parabola, Hyperbola
1120 //########################################
7fd59977 1121 case IntPatch_Lin:
1122 case IntPatch_Parabola:
1123 case IntPatch_Hyperbola: {
1124 if (typl == IntPatch_Lin) {
1125 newc =
655fddc8 1126 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
7fd59977 1127 }
1128
1129 else if (typl == IntPatch_Parabola) {
1130 newc =
655fddc8 1131 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
7fd59977 1132 }
59495dbe 1133
7fd59977 1134 else if (typl == IntPatch_Hyperbola) {
1135 newc =
655fddc8 1136 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
7fd59977 1137 }
1138 //
1139 // myTolReached3d
1140 if (typl == IntPatch_Lin) {
1141 TolR3d (myFace1, myFace2, myTolReached3d);
1142 }
1143 //
1144 aNbParts=myLConstruct.NbParts();
1145 for (i=1; i<=aNbParts; i++) {
0da45792 1146 Standard_Boolean bFNIt, bLPIt;
1147 //
7fd59977 1148 myLConstruct.Part(i, fprm, lprm);
d4b867e6 1149 //
0da45792 1150 bFNIt=Precision::IsNegativeInfinite(fprm);
1151 bLPIt=Precision::IsPositiveInfinite(lprm);
1152 //
1153 if (!bFNIt && !bLPIt) {
655fddc8 1154 //
1155 IntTools_Curve aCurve;
1156 //
1157 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
1158 aCurve.SetCurve(aCT3D);
1159 if (typl == IntPatch_Parabola) {
1160 Standard_Real aTolF1, aTolF2, aTolBase;
1161
1162 aTolF1 = BRep_Tool::Tolerance(myFace1);
1163 aTolF2 = BRep_Tool::Tolerance(myFace2);
1164 aTolBase=aTolF1+aTolF2;
1165 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
1166 }
1167 //
1168 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
1169 if(myApprox1) {
1170 Handle (Geom2d_Curve) C2d;
d4b867e6 1171 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1172 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1173 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1174 myTolReached2d=Tolpc;
1175 }
1176 //
1177 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1178 }
1179 else {
1180 Handle(Geom2d_BSplineCurve) H1;
1181 //
1182 aCurve.SetFirstCurve2d(H1);
1183 }
0da45792 1184 //
655fddc8 1185 if(myApprox2) {
1186 Handle (Geom2d_Curve) C2d;
d4b867e6 1187 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1188 myHS2->ChangeSurface().Surface(), newc, C2d);
655fddc8 1189 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1190 myTolReached2d=Tolpc;
1191 }
1192 //
1193 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1194 }
1195 else {
1196 Handle(Geom2d_BSplineCurve) H1;
1197 //
1198 aCurve.SetSecondCurve2d(H1);
1199 }
1200 mySeqOfCurve.Append(aCurve);
0da45792 1201 } //if (!bFNIt && !bLPIt) {
7fd59977 1202 else {
655fddc8 1203 // on regarde si on garde
1204 //
655fddc8 1205 Standard_Real aTestPrm, dT=100.;
0da45792 1206 //
655fddc8 1207 aTestPrm=0.;
655fddc8 1208 if (bFNIt && !bLPIt) {
1209 aTestPrm=lprm-dT;
1210 }
1211 else if (!bFNIt && bLPIt) {
1212 aTestPrm=fprm+dT;
1213 }
0da45792 1214 else {
1215 // i.e, if (bFNIt && bLPIt)
1216 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
1217 }
1218 //
655fddc8 1219 gp_Pnt ptref(newc->Value(aTestPrm));
1220 //
94218044 1221 GeomAbs_SurfaceType typS1 = myHS1->GetType();
1222 GeomAbs_SurfaceType typS2 = myHS2->GetType();
1223 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
1224 typS1 == GeomAbs_OffsetSurface ||
1225 typS1 == GeomAbs_SurfaceOfRevolution ||
1226 typS2 == GeomAbs_SurfaceOfExtrusion ||
1227 typS2 == GeomAbs_OffsetSurface ||
0da45792 1228 typS2 == GeomAbs_SurfaceOfRevolution) {
94218044 1229 Handle(Geom2d_BSplineCurve) H1;
1230 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1231 continue;
1232 }
1233
655fddc8 1234 Standard_Real u1, v1, u2, v2, Tol;
1235
1236 Tol = Precision::Confusion();
1237 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1238 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1239 if(ok) {
1240 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1241 }
1242 if (ok) {
1243 Handle(Geom2d_BSplineCurve) H1;
1244 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1245 }
7fd59977 1246 }
0da45792 1247 }// for (i=1; i<=aNbParts; i++) {
7fd59977 1248 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
59495dbe 1249 break;
7fd59977 1250
59495dbe 1251 //########################################
1252 // Circle and Ellipse
1253 //########################################
7fd59977 1254 case IntPatch_Circle:
1255 case IntPatch_Ellipse: {
1256
1257 if (typl == IntPatch_Circle) {
1258 newc = new Geom_Circle
655fddc8 1259 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
7fd59977 1260 }
1261 else { //IntPatch_Ellipse
1262 newc = new Geom_Ellipse
655fddc8 1263 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
7fd59977 1264 }
1265 //
1266 // myTolReached3d
1267 TolR3d (myFace1, myFace2, myTolReached3d);
1268 //
1269 aNbParts=myLConstruct.NbParts();
1270 //
1271 Standard_Real aPeriod, aNul;
1272 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
59495dbe 1273
7fd59977 1274 aNul=0.;
c6541a0c 1275 aPeriod=M_PI+M_PI;
7fd59977 1276
1277 for (i=1; i<=aNbParts; i++) {
1278 myLConstruct.Part(i, fprm, lprm);
1279
1280 if (fprm < aNul && lprm > aNul) {
655fddc8 1281 // interval that goes through 0. is divided on two intervals;
1282 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1283 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1284 //
1285 if((aPeriod - fprm) > Tolpc) {
1286 aSeqFprm.Append(fprm);
1287 aSeqLprm.Append(aPeriod);
1288 }
1289 else {
1290 gp_Pnt P1 = newc->Value(fprm);
1291 gp_Pnt P2 = newc->Value(aPeriod);
1292 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1293 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1294
1295 if(P1.Distance(P2) > aTolDist) {
1296 Standard_Real anewpar = fprm;
94218044 1297
4abae870 1298 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
1299 lprm, Standard_False, anewpar, myContext)) {
655fddc8 1300 fprm = anewpar;
1301 }
1302 aSeqFprm.Append(fprm);
1303 aSeqLprm.Append(aPeriod);
1304 }
1305 }
1306
1307 //
1308 if((lprm - aNul) > Tolpc) {
1309 aSeqFprm.Append(aNul);
1310 aSeqLprm.Append(lprm);
1311 }
1312 else {
1313 gp_Pnt P1 = newc->Value(aNul);
1314 gp_Pnt P2 = newc->Value(lprm);
1315 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1316 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1317
1318 if(P1.Distance(P2) > aTolDist) {
1319 Standard_Real anewpar = lprm;
94218044 1320
4abae870 1321 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
1322 fprm, Standard_True, anewpar, myContext)) {
655fddc8 1323 lprm = anewpar;
1324 }
1325 aSeqFprm.Append(aNul);
1326 aSeqLprm.Append(lprm);
1327 }
1328 }
7fd59977 1329 }
1330 else {
655fddc8 1331 // usual interval
1332 aSeqFprm.Append(fprm);
1333 aSeqLprm.Append(lprm);
7fd59977 1334 }
1335 }
59495dbe 1336
7fd59977 1337 //
1338 aNbParts=aSeqFprm.Length();
1339 for (i=1; i<=aNbParts; i++) {
1340 fprm=aSeqFprm(i);
1341 lprm=aSeqLprm(i);
1342 //
1343 Standard_Real aRealEpsilon=RealEpsilon();
c6541a0c 1344 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
655fddc8 1345 //==============================================
1346 ////
1347 IntTools_Curve aCurve;
1348 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1349 aCurve.SetCurve(aTC3D);
1350 fprm=aTC3D->FirstParameter();
1351 lprm=aTC3D->LastParameter ();
1352 ////
1353 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1354 if(myApprox1) {
1355 Handle (Geom2d_Curve) C2d;
d4b867e6 1356 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1357 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1358 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1359 myTolReached2d=Tolpc;
1360 }
1361 //
1362 aCurve.SetFirstCurve2d(C2d);
1363 }
1364 else { ////
1365 Handle(Geom2d_BSplineCurve) H1;
1366 aCurve.SetFirstCurve2d(H1);
1367 }
1368
1369
1370 if(myApprox2) {
1371 Handle (Geom2d_Curve) C2d;
d4b867e6 1372 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1373 myHS2->ChangeSurface().Surface(),newc,C2d);
655fddc8 1374 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1375 myTolReached2d=Tolpc;
1376 }
1377 //
1378 aCurve.SetSecondCurve2d(C2d);
1379 }
1380 else {
1381 Handle(Geom2d_BSplineCurve) H1;
1382 aCurve.SetSecondCurve2d(H1);
1383 }
1384 }
1385
1386 else {
1387 Handle(Geom2d_BSplineCurve) H1;
1388 aCurve.SetFirstCurve2d(H1);
1389 aCurve.SetSecondCurve2d(H1);
1390 }
1391 mySeqOfCurve.Append(aCurve);
1392 //==============================================
c6541a0c 1393 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
7fd59977 1394
1395 else {
655fddc8 1396 // on regarde si on garde
1397 //
1398 if (aNbParts==1) {
1399// if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1400 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1401 IntTools_Curve aCurve;
1402 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1403 aCurve.SetCurve(aTC3D);
1404 fprm=aTC3D->FirstParameter();
1405 lprm=aTC3D->LastParameter ();
1406
1407 if(myApprox1) {
1408 Handle (Geom2d_Curve) C2d;
d4b867e6 1409 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1410 myHS1->ChangeSurface().Surface(),newc,C2d);
655fddc8 1411 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1412 myTolReached2d=Tolpc;
1413 }
1414 //
1415 aCurve.SetFirstCurve2d(C2d);
1416 }
1417 else { ////
1418 Handle(Geom2d_BSplineCurve) H1;
1419 aCurve.SetFirstCurve2d(H1);
1420 }
1421
1422 if(myApprox2) {
1423 Handle (Geom2d_Curve) C2d;
d4b867e6 1424 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1425 myHS2->ChangeSurface().Surface(),newc,C2d);
655fddc8 1426 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1427 myTolReached2d=Tolpc;
1428 }
1429 //
1430 aCurve.SetSecondCurve2d(C2d);
1431 }
1432 else {
1433 Handle(Geom2d_BSplineCurve) H1;
1434 aCurve.SetSecondCurve2d(H1);
1435 }
1436 mySeqOfCurve.Append(aCurve);
1437 break;
1438 }
1439 }
1440 //
1441 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1442
1443 aTwoPIdiv17=2.*M_PI/17.;
1444
1445 for (j=0; j<=17; j++) {
1446 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1447 Tol = Precision::Confusion();
1448
1449 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1450 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1451 if(ok) {
1452 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1453 }
1454 if (ok) {
1455 IntTools_Curve aCurve;
1456 aCurve.SetCurve(newc);
1457 //==============================================
1458 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1459
1460 if(myApprox1) {
1461 Handle (Geom2d_Curve) C2d;
d4b867e6 1462 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1463 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1464 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1465 myTolReached2d=Tolpc;
1466 }
1467 //
1468 aCurve.SetFirstCurve2d(C2d);
1469 }
1470 else {
1471 Handle(Geom2d_BSplineCurve) H1;
1472 aCurve.SetFirstCurve2d(H1);
1473 }
1474
1475 if(myApprox2) {
1476 Handle (Geom2d_Curve) C2d;
d4b867e6 1477 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1478 myHS2->ChangeSurface().Surface(), newc, C2d);
655fddc8 1479 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1480 myTolReached2d=Tolpc;
1481 }
1482 //
1483 aCurve.SetSecondCurve2d(C2d);
1484 }
1485
1486 else {
1487 Handle(Geom2d_BSplineCurve) H1;
1488 aCurve.SetSecondCurve2d(H1);
1489 }
1490 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1491
1492 else {
1493 Handle(Geom2d_BSplineCurve) H1;
1494 //
1495 aCurve.SetFirstCurve2d(H1);
1496 aCurve.SetSecondCurve2d(H1);
1497 }
1498 //==============================================
1499 //
1500 mySeqOfCurve.Append(aCurve);
1501 break;
1502
1503 }// end of if (ok) {
1504 }// end of for (Standard_Integer j=0; j<=17; j++)
1505 }// end of else { on regarde si on garde
59495dbe 1506 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1507 }// IntPatch_Circle: IntPatch_Ellipse:
1508 break;
1509
7fd59977 1510 case IntPatch_Analytic: {
1511 IntSurf_Quadric quad1,quad2;
1512 GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
59495dbe 1513
7fd59977 1514 switch (typs) {
59495dbe 1515 case GeomAbs_Plane:
1516 quad1.SetValue(myHS1->Surface().Plane());
655fddc8 1517 break;
59495dbe 1518 case GeomAbs_Cylinder:
655fddc8 1519 quad1.SetValue(myHS1->Surface().Cylinder());
1520 break;
59495dbe 1521 case GeomAbs_Cone:
655fddc8 1522 quad1.SetValue(myHS1->Surface().Cone());
1523 break;
59495dbe 1524 case GeomAbs_Sphere:
655fddc8 1525 quad1.SetValue(myHS1->Surface().Sphere());
1526 break;
7eed5d29 1527 case GeomAbs_Torus:
1528 quad1.SetValue(myHS1->Surface().Torus());
1529 break;
59495dbe 1530 default:
655fddc8 1531 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
59495dbe 1532 }
1533
7fd59977 1534 typs = myHS2->Surface().GetType();
59495dbe 1535
7fd59977 1536 switch (typs) {
59495dbe 1537 case GeomAbs_Plane:
1538 quad2.SetValue(myHS2->Surface().Plane());
655fddc8 1539 break;
59495dbe 1540 case GeomAbs_Cylinder:
655fddc8 1541 quad2.SetValue(myHS2->Surface().Cylinder());
1542 break;
59495dbe 1543 case GeomAbs_Cone:
655fddc8 1544 quad2.SetValue(myHS2->Surface().Cone());
1545 break;
59495dbe 1546 case GeomAbs_Sphere:
655fddc8 1547 quad2.SetValue(myHS2->Surface().Sphere());
1548 break;
7eed5d29 1549 case GeomAbs_Torus:
1550 quad2.SetValue(myHS2->Surface().Torus());
1551 break;
59495dbe 1552 default:
655fddc8 1553 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
59495dbe 1554 }
7fd59977 1555 //
1556 //=========
1557 IntPatch_ALineToWLine convert (quad1, quad2);
59495dbe 1558
7fd59977 1559 if (!myApprox) {
1560 aNbParts=myLConstruct.NbParts();
1561 for (i=1; i<=aNbParts; i++) {
655fddc8 1562 myLConstruct.Part(i, fprm, lprm);
1563 Handle(IntPatch_WLine) WL =
1564 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1565 //
1566 Handle(Geom2d_BSplineCurve) H1;
1567 Handle(Geom2d_BSplineCurve) H2;
1568
1569 if(myApprox1) {
1570 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1571 }
1572
1573 if(myApprox2) {
1574 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1575 }
1576 //
1577 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
7fd59977 1578 }
1579 } // if (!myApprox)
1580
1581 else { // myApprox=TRUE
1582 GeomInt_WLApprox theapp3d;
1583 //
1584 Standard_Real tol2d = myTolApprox;
655fddc8 1585 //
7fd59977 1586 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
59495dbe 1587
7fd59977 1588 aNbParts=myLConstruct.NbParts();
1589 for (i=1; i<=aNbParts; i++) {
655fddc8 1590 myLConstruct.Part(i, fprm, lprm);
1591 Handle(IntPatch_WLine) WL =
1592 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
1593
1594 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
1595
1596 if (!theapp3d.IsDone()) {
1597 //
1598 Handle(Geom2d_BSplineCurve) H1;
1599 Handle(Geom2d_BSplineCurve) H2;
1600
1601 if(myApprox1) {
1602 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1603 }
1604
1605 if(myApprox2) {
1606 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1607 }
1608 //
1609 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1610 }
1611
1612 else {
1613 if(myApprox1 || myApprox2) {
1614 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1615 myTolReached2d = theapp3d.TolReached2d();
1616 }
1617 }
1618
1619 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1620 myTolReached3d = theapp3d.TolReached3d();
1621 }
1622
1623 Standard_Integer aNbMultiCurves, nbpoles;
1624 aNbMultiCurves=theapp3d.NbMultiCurves();
1625 for (j=1; j<=aNbMultiCurves; j++) {
1626 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1627 nbpoles = mbspc.NbPoles();
1628
1629 TColgp_Array1OfPnt tpoles(1, nbpoles);
1630 mbspc.Curve(1, tpoles);
1631 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1632 mbspc.Knots(),
1633 mbspc.Multiplicities(),
1634 mbspc.Degree());
1635
1636 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1637 Check.FixTangent(Standard_True,Standard_True);
1638 //
1639 IntTools_Curve aCurve;
1640 aCurve.SetCurve(BS);
1641
1642 if(myApprox1) {
1643 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1644 mbspc.Curve(2,tpoles2d);
1645 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1646 mbspc.Knots(),
1647 mbspc.Multiplicities(),
1648 mbspc.Degree());
1649
1650 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1651 newCheck.FixTangent(Standard_True,Standard_True);
1652 //
1653 aCurve.SetFirstCurve2d(BS2);
1654 }
1655 else {
1656 Handle(Geom2d_BSplineCurve) H1;
1657 aCurve.SetFirstCurve2d(H1);
1658 }
1659
1660 if(myApprox2) {
1661 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1662 Standard_Integer TwoOrThree;
1663 TwoOrThree=myApprox1 ? 3 : 2;
1664 mbspc.Curve(TwoOrThree, tpoles2d);
1665 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1666 mbspc.Knots(),
1667 mbspc.Multiplicities(),
1668 mbspc.Degree());
1669
1670 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1671 newCheck.FixTangent(Standard_True,Standard_True);
1672 //
1673 aCurve.SetSecondCurve2d(BS2);
1674 }
1675 else {
1676 Handle(Geom2d_BSplineCurve) H2;
1677 aCurve.SetSecondCurve2d(H2);
1678 }
1679 //
1680 mySeqOfCurve.Append(aCurve);
1681
1682 }// for (j=1; j<=aNbMultiCurves; j++) {
1683 }// else from if (!theapp3d.IsDone())
7fd59977 1684 }// for (i=1; i<=aNbParts; i++) {
1685 }// else { // myApprox=TRUE
1686 }// case IntPatch_Analytic:
59495dbe 1687 break;
7fd59977 1688
59495dbe 1689 case IntPatch_Walking:{
7fd59977 1690 Handle(IntPatch_WLine) WL =
1691 Handle(IntPatch_WLine)::DownCast(L);
1692 //
1693 Standard_Integer ifprm, ilprm;
1694 //
1695 if (!myApprox) {
1696 aNbParts = 1;
1697 if(!bAvoidLineConstructor){
655fddc8 1698 aNbParts=myLConstruct.NbParts();
7fd59977 1699 }
1700 for (i=1; i<=aNbParts; ++i) {
655fddc8 1701 Handle(Geom2d_BSplineCurve) H1, H2;
1702 Handle(Geom_Curve) aBSp;
1703 //
1704 if(bAvoidLineConstructor) {
1705 ifprm = 1;
1706 ilprm = WL->NbPnts();
1707 }
1708 else {
1709 myLConstruct.Part(i, fprm, lprm);
1710 ifprm=(Standard_Integer)fprm;
1711 ilprm=(Standard_Integer)lprm;
1712 }
1713 //
1714 if(myApprox1) {
1715 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1716 }
1717 //
1718 if(myApprox2) {
1719 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1720 }
1721 //
1722 aBSp=MakeBSpline(WL, ifprm, ilprm);
1723 IntTools_Curve aIC(aBSp, H1, H2);
1724 mySeqOfCurve.Append(aIC);
7fd59977 1725 }// for (i=1; i<=aNbParts; ++i) {
1726 }// if (!myApprox) {
1727 //
1728 else { // X
1729 Standard_Boolean bIsDecomposited;
1730 Standard_Integer nbiter, aNbSeqOfL;
4abae870 1731 Standard_Real tol2d, aTolApproxImp;
7fd59977 1732 IntPatch_SequenceOfLine aSeqOfL;
1733 GeomInt_WLApprox theapp3d;
1734 Approx_ParametrizationType aParType = Approx_ChordLength;
1735 //
1736 Standard_Boolean anApprox1 = myApprox1;
1737 Standard_Boolean anApprox2 = myApprox2;
4abae870 1738 //
1739 aTolApproxImp=1.e-5;
7fd59977 1740 tol2d = myTolApprox;
1741
1742 GeomAbs_SurfaceType typs1, typs2;
1743 typs1 = myHS1->Surface().GetType();
1744 typs2 = myHS2->Surface().GetType();
1745 Standard_Boolean anWithPC = Standard_True;
1746
1747 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
655fddc8 1748 anWithPC =
1749 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
7fd59977 1750 }
1751 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
655fddc8 1752 anWithPC =
1753 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
7fd59977 1754 }
4abae870 1755 //
7fd59977 1756 if(!anWithPC) {
4abae870 1757 myTolApprox = aTolApproxImp;//1.e-5;
655fddc8 1758 anApprox1 = Standard_False;
1759 anApprox2 = Standard_False;
1760 //
1761 tol2d = myTolApprox;
7fd59977 1762 }
655fddc8 1763
7fd59977 1764 if(myHS1 == myHS2) {
655fddc8 1765 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1766 rejectSurface = Standard_True;
7fd59977 1767 }
1768 else {
655fddc8 1769 if(reApprox && !rejectSurface)
1770 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1771 else {
1772 Standard_Integer iDegMax, iDegMin, iNbIter;
1773 //
1774 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1775 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType);
1776 }
7fd59977 1777 }
1778 //
1779 Standard_Real aReachedTol = Precision::Confusion();
1780 bIsDecomposited=DecompositionOfWLine(WL,
655fddc8 1781 myHS1,
1782 myHS2,
1783 myFace1,
1784 myFace2,
1785 myLConstruct,
1786 bAvoidLineConstructor,
1787 aSeqOfL,
1788 aReachedTol,
1789 myContext);
4abae870 1790 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
655fddc8 1791 myTolReached3d = aReachedTol;
4abae870 1792 }
7fd59977 1793 //
1794 aNbSeqOfL=aSeqOfL.Length();
1795 //
1796 if (bIsDecomposited) {
655fddc8 1797 nbiter=aNbSeqOfL;
7fd59977 1798 }
1799 else {
655fddc8 1800 nbiter=1;
1801 aNbParts=1;
1802 if (!bAvoidLineConstructor) {
1803 aNbParts=myLConstruct.NbParts();
1804 nbiter=aNbParts;
1805 }
7fd59977 1806 }
1807 //
7fd59977 1808 for(i = 1; i <= nbiter; ++i) {
655fddc8 1809 if(bIsDecomposited) {
1810 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1811 ifprm = 1;
1812 ilprm = WL->NbPnts();
1813 }
1814 else {
1815 if(bAvoidLineConstructor) {
1816 ifprm = 1;
1817 ilprm = WL->NbPnts();
1818 }
1819 else {
1820 myLConstruct.Part(i, fprm, lprm);
1821 ifprm = (Standard_Integer)fprm;
1822 ilprm = (Standard_Integer)lprm;
1823 }
1824 }
1825 //-- lbr :
1826 //-- Si une des surfaces est un plan , on approxime en 2d
1827 //-- sur cette surface et on remonte les points 2d en 3d.
1828 if(typs1 == GeomAbs_Plane) {
1829 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1830 }
1831 else if(typs2 == GeomAbs_Plane) {
1832 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1833 }
1834 else {
1835 //
1836 if (myHS1 != myHS2){
1837 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1838 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1839
1840 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType);
1841
1842 Standard_Boolean bUseSurfaces;
1843 bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1844 if (bUseSurfaces) {
1845 // ######
1846 rejectSurface = Standard_True;
1847 // ######
1848 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1849 }
1850 }
1851 }
1852 //
1853 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1854 }
1855 //
94218044 1856 if (!theapp3d.IsDone()) {
655fddc8 1857 Handle(Geom2d_BSplineCurve) H1;
94218044 1858 Handle(Geom2d_BSplineCurve) H2;
655fddc8 1859 //
1860 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
4abae870 1861 //
655fddc8 1862 if(myApprox1) {
1863 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1864 }
4abae870 1865 //
655fddc8 1866 if(myApprox2) {
1867 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1868 }
1869 //
1870 IntTools_Curve aIC(aBSp, H1, H2);
1871 mySeqOfCurve.Append(aIC);
1872 }
1873
1874 else {
1875 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1876 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1877 myTolReached2d = theapp3d.TolReached2d();
1878 }
1879 }
1880 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1881 myTolReached3d = myTolReached2d;
1882 //
1883 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1884 if (myTolReached3d<1.e-6) {
1885 myTolReached3d = theapp3d.TolReached3d();
1886 myTolReached3d=1.e-6;
1887 }
1888 }
1889 }
1890 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1891 myTolReached3d = theapp3d.TolReached3d();
1892 }
1893
1894 Standard_Integer aNbMultiCurves, nbpoles;
1895 aNbMultiCurves=theapp3d.NbMultiCurves();
1896 for (j=1; j<=aNbMultiCurves; j++) {
1897 if(typs1 == GeomAbs_Plane) {
1898 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1899 nbpoles = mbspc.NbPoles();
1900
1901 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1902 TColgp_Array1OfPnt tpoles(1,nbpoles);
1903
1904 mbspc.Curve(1,tpoles2d);
1905 const gp_Pln& Pln = myHS1->Surface().Plane();
1906 //
1907 Standard_Integer ik;
1908 for(ik = 1; ik<= nbpoles; ik++) {
1909 tpoles.SetValue(ik,
1910 ElSLib::Value(tpoles2d.Value(ik).X(),
1911 tpoles2d.Value(ik).Y(),
1912 Pln));
1913 }
1914 //
1915 Handle(Geom_BSplineCurve) BS =
1916 new Geom_BSplineCurve(tpoles,
1917 mbspc.Knots(),
1918 mbspc.Multiplicities(),
1919 mbspc.Degree());
1920 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1921 Check.FixTangent(Standard_True, Standard_True);
1922 //
1923 IntTools_Curve aCurve;
1924 aCurve.SetCurve(BS);
1925
1926 if(myApprox1) {
1927 Handle(Geom2d_BSplineCurve) BS1 =
1928 new Geom2d_BSplineCurve(tpoles2d,
1929 mbspc.Knots(),
1930 mbspc.Multiplicities(),
1931 mbspc.Degree());
1932 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1933 Check1.FixTangent(Standard_True,Standard_True);
1934 //
1935 // ############################################
1936 if(!rejectSurface && !reApprox) {
1937 Standard_Boolean isValid = IsCurveValid(BS1);
1938 if(!isValid) {
1939 reApprox = Standard_True;
1940 goto reapprox;
1941 }
1942 }
1943 // ############################################
1944 aCurve.SetFirstCurve2d(BS1);
1945 }
1946 else {
1947 Handle(Geom2d_BSplineCurve) H1;
1948 aCurve.SetFirstCurve2d(H1);
1949 }
1950
1951 if(myApprox2) {
1952 mbspc.Curve(2, tpoles2d);
1953
1954 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1955 mbspc.Knots(),
1956 mbspc.Multiplicities(),
1957 mbspc.Degree());
1958 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1959 newCheck.FixTangent(Standard_True,Standard_True);
1960
1961 // ###########################################
1962 if(!rejectSurface && !reApprox) {
1963 Standard_Boolean isValid = IsCurveValid(BS2);
1964 if(!isValid) {
1965 reApprox = Standard_True;
1966 goto reapprox;
1967 }
1968 }
1969 // ###########################################
1970 //
1971 aCurve.SetSecondCurve2d(BS2);
1972 }
1973 else {
1974 Handle(Geom2d_BSplineCurve) H2;
1975 //
1976 aCurve.SetSecondCurve2d(H2);
1977 }
1978 //
1979 mySeqOfCurve.Append(aCurve);
4abae870 1980 }//if(typs1 == GeomAbs_Plane) {
655fddc8 1981
1982 else if(typs2 == GeomAbs_Plane) {
1983 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1984 nbpoles = mbspc.NbPoles();
1985
1986 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1987 TColgp_Array1OfPnt tpoles(1,nbpoles);
1988 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1989 const gp_Pln& Pln = myHS2->Surface().Plane();
1990 //
1991 Standard_Integer ik;
1992 for(ik = 1; ik<= nbpoles; ik++) {
1993 tpoles.SetValue(ik,
1994 ElSLib::Value(tpoles2d.Value(ik).X(),
1995 tpoles2d.Value(ik).Y(),
1996 Pln));
1997
1998 }
1999 //
2000 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
2001 mbspc.Knots(),
2002 mbspc.Multiplicities(),
2003 mbspc.Degree());
2004 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2005 Check.FixTangent(Standard_True,Standard_True);
2006 //
2007 IntTools_Curve aCurve;
2008 aCurve.SetCurve(BS);
2009
2010 if(myApprox2) {
2011 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
2012 mbspc.Knots(),
2013 mbspc.Multiplicities(),
2014 mbspc.Degree());
2015 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
2016 Check1.FixTangent(Standard_True,Standard_True);
2017 //
2018 // ###########################################
2019 if(!rejectSurface && !reApprox) {
2020 Standard_Boolean isValid = IsCurveValid(BS1);
2021 if(!isValid) {
2022 reApprox = Standard_True;
2023 goto reapprox;
2024 }
2025 }
989341c5 2026 // ###########################################
2027 bPCurvesOk = CheckPCurve(BS1, myFace2);
655fddc8 2028 aCurve.SetSecondCurve2d(BS1);
2029 }
2030 else {
2031 Handle(Geom2d_BSplineCurve) H2;
2032 aCurve.SetSecondCurve2d(H2);
2033 }
2034
2035 if(myApprox1) {
2036 mbspc.Curve(1,tpoles2d);
2037 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2038 mbspc.Knots(),
2039 mbspc.Multiplicities(),
2040 mbspc.Degree());
2041 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
2042 Check2.FixTangent(Standard_True,Standard_True);
2043 //
2044 // ###########################################
2045 if(!rejectSurface && !reApprox) {
2046 Standard_Boolean isValid = IsCurveValid(BS2);
2047 if(!isValid) {
2048 reApprox = Standard_True;
2049 goto reapprox;
2050 }
2051 }
989341c5 2052 // ###########################################
2053 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1);
655fddc8 2054 aCurve.SetFirstCurve2d(BS2);
2055 }
2056 else {
2057 Handle(Geom2d_BSplineCurve) H1;
2058 //
2059 aCurve.SetFirstCurve2d(H1);
2060 }
2061 //
989341c5 2062 //if points of the pcurves are out of the faces bounds
2063 //create 3d and 2d curves without approximation
2064 if (!bPCurvesOk) {
2065 Handle(Geom2d_BSplineCurve) H1, H2;
655fddc8 2066 bPCurvesOk = Standard_True;
2067 //
989341c5 2068 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
59495dbe 2069
989341c5 2070 if(myApprox1) {
2071 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
655fddc8 2072 bPCurvesOk = CheckPCurve(H1, myFace1);
989341c5 2073 }
59495dbe 2074
989341c5 2075 if(myApprox2) {
2076 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
655fddc8 2077 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2);
989341c5 2078 }
2079 //
655fddc8 2080 //if pcurves created without approximation are out of the
2081 //faces bounds, use approximated 3d and 2d curves
2082 if (bPCurvesOk) {
2083 IntTools_Curve aIC(aBSp, H1, H2);
2084 mySeqOfCurve.Append(aIC);
2085 } else {
2086 mySeqOfCurve.Append(aCurve);
2087 }
989341c5 2088 } else {
2089 mySeqOfCurve.Append(aCurve);
2090 }
4abae870 2091 }// else if(typs2 == GeomAbs_Plane)
2092 //
2093 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
2094 Standard_Boolean bIsValid1, bIsValid2;
2095 Handle(Geom_BSplineCurve) BS;
2096 Handle(Geom2d_BSplineCurve) aH2D;
2097 IntTools_Curve aCurve;
2098 //
2099 bIsValid1=Standard_True;
2100 bIsValid2=Standard_True;
2101 //
655fddc8 2102 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2103 nbpoles = mbspc.NbPoles();
2104 TColgp_Array1OfPnt tpoles(1,nbpoles);
2105 mbspc.Curve(1,tpoles);
4abae870 2106 BS=new Geom_BSplineCurve(tpoles,
655fddc8 2107 mbspc.Knots(),
2108 mbspc.Multiplicities(),
2109 mbspc.Degree());
2110 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2111 Check.FixTangent(Standard_True,Standard_True);
2112 //
2113 aCurve.SetCurve(BS);
4abae870 2114 aCurve.SetFirstCurve2d(aH2D);
2115 aCurve.SetSecondCurve2d(aH2D);
2116 //
655fddc8 2117 if(myApprox1) {
2118 if(anApprox1) {
4abae870 2119 Handle(Geom2d_BSplineCurve) BS1;
655fddc8 2120 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2121 mbspc.Curve(2,tpoles2d);
4abae870 2122 //
2123 BS1=new Geom2d_BSplineCurve(tpoles2d,
655fddc8 2124 mbspc.Knots(),
2125 mbspc.Multiplicities(),
2126 mbspc.Degree());
2127 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
2128 newCheck.FixTangent(Standard_True,Standard_True);
2129 //
4abae870 2130 if (!reApprox) {
2131 bIsValid1=CheckPCurve(BS1, myFace1);
2132 }
2133 //
655fddc8 2134 aCurve.SetFirstCurve2d(BS1);
2135 }
2136 else {
2137 Handle(Geom2d_BSplineCurve) BS1;
2138 fprm = BS->FirstParameter();
2139 lprm = BS->LastParameter();
2140
2141 Handle(Geom2d_Curve) C2d;
2142 Standard_Real aTol = myTolApprox;
d4b867e6 2143 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
2144 myHS1->ChangeSurface().Surface(), BS, C2d);
655fddc8 2145 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2146 aCurve.SetFirstCurve2d(BS1);
2147 }
4abae870 2148 } // if(myApprox1) {
655fddc8 2149 //
2150 if(myApprox2) {
2151 if(anApprox2) {
4abae870 2152 Handle(Geom2d_BSplineCurve) BS2;
655fddc8 2153 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2154 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
4abae870 2155 BS2=new Geom2d_BSplineCurve(tpoles2d,
655fddc8 2156 mbspc.Knots(),
2157 mbspc.Multiplicities(),
2158 mbspc.Degree());
2159 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
2160 newCheck.FixTangent(Standard_True,Standard_True);
2161 //
4abae870 2162 if (!reApprox) {
2163 bIsValid2=CheckPCurve(BS2, myFace2);
2164 }
655fddc8 2165 aCurve.SetSecondCurve2d(BS2);
2166 }
2167 else {
2168 Handle(Geom2d_BSplineCurve) BS2;
2169 fprm = BS->FirstParameter();
2170 lprm = BS->LastParameter();
2171
2172 Handle(Geom2d_Curve) C2d;
2173 Standard_Real aTol = myTolApprox;
d4b867e6 2174 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
2175 myHS2->ChangeSurface().Surface(), BS, C2d);
655fddc8 2176 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2177 aCurve.SetSecondCurve2d(BS2);
2178 }
4abae870 2179 } //if(myApprox2) {
2180 if (!bIsValid1 || !bIsValid2) {
2181 myTolApprox=aTolApproxImp;//1.e-5;
2182 tol2d = myTolApprox;
2183 reApprox = Standard_True;
2184 goto reapprox;
655fddc8 2185 }
2186 //
2187 mySeqOfCurve.Append(aCurve);
2188 }
2189 }
2190 }
7fd59977 2191 }
2192 }// else { // X
2193 }// case IntPatch_Walking:{
59495dbe 2194 break;
2195
7fd59977 2196 case IntPatch_Restriction:
d4b867e6 2197 {
2198 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
2199 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
2200 Standard_Boolean isAnalS1 = Standard_False;
2201 switch (typS1)
2202 {
2203 case GeomAbs_Plane:
2204 case GeomAbs_Cylinder:
2205 case GeomAbs_Sphere:
2206 case GeomAbs_Cone:
2207 case GeomAbs_Torus: isAnalS1 = Standard_True; break;
2208 default: break;
2209 }
7fd59977 2210
d4b867e6 2211 Standard_Integer isAnalS2 = Standard_False;
2212 switch (typS2)
2213 {
2214 case GeomAbs_Plane:
2215 case GeomAbs_Cylinder:
2216 case GeomAbs_Sphere:
2217 case GeomAbs_Cone:
2218 case GeomAbs_Torus: isAnalS2 = Standard_True; break;
2219 default: break;
2220 }
7fd59977 2221
d4b867e6 2222 Handle(IntPatch_RLine) RL =
2223 Handle(IntPatch_RLine)::DownCast(L);
2224 Handle(Geom_Curve) aC3d;
2225 Handle(Geom2d_Curve) aC2d1, aC2d2;
2226 Standard_Real aTolReached;
2227 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
2228 aC2d1, aC2d2, aTolReached);
2229
2230 if(aC3d.IsNull())
2231 break;
2232
2233 Bnd_Box2d aBox1, aBox2;
2234
2235 const Standard_Real aU1f = myHS1->FirstUParameter(),
2236 aV1f = myHS1->FirstVParameter(),
2237 aU1l = myHS1->LastUParameter(),
2238 aV1l = myHS1->LastVParameter();
2239 const Standard_Real aU2f = myHS2->FirstUParameter(),
2240 aV2f = myHS2->FirstVParameter(),
2241 aU2l = myHS2->LastUParameter(),
2242 aV2l = myHS2->LastVParameter();
2243
2244 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
2245 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
2246 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
2247 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
2248
2249 GeomInt_VectorOfReal anArrayOfParameters;
655fddc8 2250
d4b867e6 2251 //We consider here that the intersection line is same-parameter-line
2252 anArrayOfParameters.Append(aC3d->FirstParameter());
2253 anArrayOfParameters.Append(aC3d->LastParameter());
2254
2255 GeomInt_IntSS::
2256 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
2257
2258 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
2259
2260 //Trim RLine found.
2261 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
2262 {
2263 const Standard_Real aParF = anArrayOfParameters(anInd),
2264 aParL = anArrayOfParameters(anInd+1);
2265
2266 if((aParL - aParF) <= Precision::PConfusion())
2267 continue;
2268
2269 const Standard_Real aPar = 0.5*(aParF + aParL);
2270 gp_Pnt2d aPt;
2271
2272 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
2273 if(!aC2d1.IsNull())
2274 {
2275 aC2d1->D0(aPar, aPt);
2276
2277 if(aBox1.IsOut(aPt))
2278 continue;
2279
2280 if(myApprox1)
2281 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
4abae870 2282 }
d4b867e6 2283
2284 if(!aC2d2.IsNull())
2285 {
2286 aC2d2->D0(aPar, aPt);
2287
2288 if(aBox2.IsOut(aPt))
2289 continue;
2290
2291 if(myApprox2)
2292 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
2293 }
2294
2295 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
2296
2297 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
2298 mySeqOfCurve.Append(aIC);
7fd59977 2299 }
2300 }
d4b867e6 2301 break;
2302 default:
2303 break;
2304
7fd59977 2305 }
7fd59977 2306}
2307
2308//=======================================================================
2309//function : Parameters
2310//purpose :
2311//=======================================================================
2312 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
655fddc8 2313 const Handle(GeomAdaptor_HSurface)& HS2,
2314 const gp_Pnt& Ptref,
2315 Standard_Real& U1,
2316 Standard_Real& V1,
2317 Standard_Real& U2,
2318 Standard_Real& V2)
7fd59977 2319{
2320
2321 IntSurf_Quadric quad1,quad2;
2322 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2323
2324 switch (typs) {
2325 case GeomAbs_Plane:
2326 quad1.SetValue(HS1->Surface().Plane());
2327 break;
2328 case GeomAbs_Cylinder:
2329 quad1.SetValue(HS1->Surface().Cylinder());
2330 break;
2331 case GeomAbs_Cone:
2332 quad1.SetValue(HS1->Surface().Cone());
2333 break;
2334 case GeomAbs_Sphere:
2335 quad1.SetValue(HS1->Surface().Sphere());
2336 break;
7eed5d29 2337 case GeomAbs_Torus:
2338 quad1.SetValue(HS1->Surface().Torus());
2339 break;
7fd59977 2340 default:
2341 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2342 }
2343
2344 typs = HS2->Surface().GetType();
2345 switch (typs) {
2346 case GeomAbs_Plane:
2347 quad2.SetValue(HS2->Surface().Plane());
2348 break;
2349 case GeomAbs_Cylinder:
2350 quad2.SetValue(HS2->Surface().Cylinder());
2351 break;
2352 case GeomAbs_Cone:
2353 quad2.SetValue(HS2->Surface().Cone());
2354 break;
2355 case GeomAbs_Sphere:
2356 quad2.SetValue(HS2->Surface().Sphere());
2357 break;
7eed5d29 2358 case GeomAbs_Torus:
2359 quad2.SetValue(HS2->Surface().Torus());
2360 break;
7fd59977 2361 default:
2362 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2363 }
2364
2365 quad1.Parameters(Ptref,U1,V1);
2366 quad2.Parameters(Ptref,U2,V2);
2367}
2368
2369//=======================================================================
2370//function : MakeBSpline
2371//purpose :
2372//=======================================================================
2373Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
655fddc8 2374 const Standard_Integer ideb,
2375 const Standard_Integer ifin)
7fd59977 2376{
2377 Standard_Integer i,nbpnt = ifin-ideb+1;
2378 TColgp_Array1OfPnt poles(1,nbpnt);
2379 TColStd_Array1OfReal knots(1,nbpnt);
2380 TColStd_Array1OfInteger mults(1,nbpnt);
2381 Standard_Integer ipidebm1;
2382 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2383 poles(i) = WL->Point(ipidebm1).Value();
2384 mults(i) = 1;
2385 knots(i) = i-1;
2386 }
2387 mults(1) = mults(nbpnt) = 2;
2388 return
2389 new Geom_BSplineCurve(poles,knots,mults,1);
2390}
2391//
2392
2393//=======================================================================
2394//function : MakeBSpline2d
2395//purpose :
2396//=======================================================================
2397Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
655fddc8 2398 const Standard_Integer ideb,
2399 const Standard_Integer ifin,
2400 const Standard_Boolean onFirst)
7fd59977 2401{
2402 Standard_Integer i, nbpnt = ifin-ideb+1;
2403 TColgp_Array1OfPnt2d poles(1,nbpnt);
2404 TColStd_Array1OfReal knots(1,nbpnt);
2405 TColStd_Array1OfInteger mults(1,nbpnt);
2406 Standard_Integer ipidebm1;
2407
2408 for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) {
2409 Standard_Real U, V;
2410 if(onFirst)
655fddc8 2411 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
7fd59977 2412 else
655fddc8 2413 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
7fd59977 2414 poles(i).SetCoord(U, V);
2415 mults(i) = 1;
2416 knots(i) = i-1;
2417 }
2418 mults(1) = mults(nbpnt) = 2;
2419
2420 return new Geom2d_BSplineCurve(poles,knots,mults,1);
2421}
2422//=======================================================================
2423//function : PrepareLines3D
2424//purpose :
2425//=======================================================================
a9f7b6b5 2426 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
7fd59977 2427{
a9f7b6b5
P
2428 Standard_Integer i, aNbCurves;
2429 GeomAbs_SurfaceType aType1, aType2;
7fd59977 2430 IntTools_SequenceOfCurves aNewCvs;
7fd59977 2431 //
a9f7b6b5 2432 // 1. Treatment closed curves
7fd59977 2433 aNbCurves=mySeqOfCurve.Length();
a9f7b6b5 2434 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2435 const IntTools_Curve& aIC=mySeqOfCurve(i);
7fd59977 2436 //
a9f7b6b5
P
2437 if (bToSplit) {
2438 Standard_Integer j, aNbC;
2439 IntTools_SequenceOfCurves aSeqCvs;
2440 //
2441 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2442 if (aNbC) {
655fddc8 2443 for (j=1; j<=aNbC; ++j) {
2444 const IntTools_Curve& aICNew=aSeqCvs(j);
2445 aNewCvs.Append(aICNew);
2446 }
a9f7b6b5
P
2447 }
2448 else {
655fddc8 2449 aNewCvs.Append(aIC);
7fd59977 2450 }
2451 }
7fd59977 2452 else {
2453 aNewCvs.Append(aIC);
2454 }
2455 }
2456 //
2457 // 2. Plane\Cone intersection when we had 4 curves
a9f7b6b5
P
2458 aType1=myHS1->GetType();
2459 aType2=myHS2->GetType();
2460 aNbCurves=aNewCvs.Length();
2461 //
7fd59977 2462 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2463 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
7fd59977 2464 if (aNbCurves==4) {
a9f7b6b5
P
2465 GeomAbs_CurveType aCType1;
2466 //
2467 aCType1=aNewCvs(1).Type();
7fd59977 2468 if (aCType1==GeomAbs_Line) {
655fddc8 2469 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2470 //
2471 for (i=1; i<=aNbCurves; ++i) {
2472 const IntTools_Curve& aIC=aNewCvs(i);
2473 aSeqIn.Append(aIC);
2474 }
2475 //
2476 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2477 //
2478 aNewCvs.Clear();
2479 aNbCurves=aSeqOut.Length();
2480 for (i=1; i<=aNbCurves; ++i) {
2481 const IntTools_Curve& aIC=aSeqOut(i);
2482 aNewCvs.Append(aIC);
2483 }
7fd59977 2484 }
2485 }
a9f7b6b5 2486 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
7fd59977 2487 //
2488 // 3. Fill mySeqOfCurve
2489 mySeqOfCurve.Clear();
2490 aNbCurves=aNewCvs.Length();
a9f7b6b5 2491 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2492 const IntTools_Curve& aIC=aNewCvs(i);
2493 mySeqOfCurve.Append(aIC);
2494 }
7fd59977 2495}
7fd59977 2496//=======================================================================
2497//function : CorrectSurfaceBoundaries
2498//purpose :
2499//=======================================================================
59495dbe 2500 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
c002793b 2501 const Standard_Real theTolerance,
2502 Standard_Real& theumin,
2503 Standard_Real& theumax,
2504 Standard_Real& thevmin,
2505 Standard_Real& thevmax)
7fd59977 2506{
2507 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2508 Standard_Real uinf, usup, vinf, vsup, delta;
2509 GeomAbs_SurfaceType aType;
2510 Handle(Geom_Surface) aSurface;
2511 //
2512 aSurface = BRep_Tool::Surface(theFace);
2513 aSurface->Bounds(uinf, usup, vinf, vsup);
2514 delta = theTolerance;
2515 enlarge = Standard_False;
2516 //
2517 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2518 //
2519 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2520 Handle(Geom_Surface) aBasisSurface =
2521 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2522
2523 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2524 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2525 return;
2526 }
2527 }
2528 //
2529 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2530 Handle(Geom_Surface) aBasisSurface =
2531 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2532
2533 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2534 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2535 return;
2536 }
2537 }
2538 //
2539 isuperiodic = anAdaptorSurface.IsUPeriodic();
2540 isvperiodic = anAdaptorSurface.IsVPeriodic();
2541 //
2542 aType=anAdaptorSurface.GetType();
2543 if((aType==GeomAbs_BezierSurface) ||
2544 (aType==GeomAbs_BSplineSurface) ||
2545 (aType==GeomAbs_SurfaceOfExtrusion) ||
c002793b 2546 (aType==GeomAbs_SurfaceOfRevolution) ||
2547 (aType==GeomAbs_Cylinder)) {
7fd59977 2548 enlarge=Standard_True;
2549 }
2550 //
2551 if(!isuperiodic && enlarge) {
2552
d4b867e6 2553 if(!Precision::IsInfinite(theumin) &&
2554 ((theumin - uinf) > delta))
7fd59977 2555 theumin -= delta;
2556 else {
2557 theumin = uinf;
2558 }
2559
d4b867e6 2560 if(!Precision::IsInfinite(theumax) &&
2561 ((usup - theumax) > delta))
7fd59977 2562 theumax += delta;
2563 else
2564 theumax = usup;
2565 }
2566 //
2567 if(!isvperiodic && enlarge) {
d4b867e6 2568 if(!Precision::IsInfinite(thevmin) &&
2569 ((thevmin - vinf) > delta)) {
7fd59977 2570 thevmin -= delta;
2571 }
2572 else {
2573 thevmin = vinf;
2574 }
d4b867e6 2575 if(!Precision::IsInfinite(thevmax) &&
2576 ((vsup - thevmax) > delta)) {
7fd59977 2577 thevmax += delta;
2578 }
2579 else {
2580 thevmax = vsup;
2581 }
2582 }
2583 //
2584 {
2585 Standard_Integer aNbP;
2586 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2587 //
2588 aTolPA=Precision::Angular();
2589 // U
2590 if (isuperiodic) {
2591 aXP=anAdaptorSurface.UPeriod();
2592 dXfact=theumax-theumin;
2593 if (dXfact-aTolPA>aXP) {
655fddc8 2594 aXmid=0.5*(theumax+theumin);
2595 aNbP=RealToInt(aXmid/aXP);
2596 if (aXmid<0.) {
2597 aNbP=aNbP-1;
2598 }
2599 aX1=aNbP*aXP;
2600 if (theumin>aTolPA) {
2601 aX1=theumin+aNbP*aXP;
2602 }
2603 aX2=aX1+aXP;
2604 if (theumin<aX1) {
2605 theumin=aX1;
2606 }
2607 if (theumax>aX2) {
2608 theumax=aX2;
2609 }
7fd59977 2610 }
2611 }
2612 // V
2613 if (isvperiodic) {
2614 aXP=anAdaptorSurface.VPeriod();
2615 dXfact=thevmax-thevmin;
2616 if (dXfact-aTolPA>aXP) {
655fddc8 2617 aXmid=0.5*(thevmax+thevmin);
2618 aNbP=RealToInt(aXmid/aXP);
2619 if (aXmid<0.) {
2620 aNbP=aNbP-1;
2621 }
2622 aX1=aNbP*aXP;
2623 if (thevmin>aTolPA) {
2624 aX1=thevmin+aNbP*aXP;
2625 }
2626 aX2=aX1+aXP;
2627 if (thevmin<aX1) {
2628 thevmin=aX1;
2629 }
2630 if (thevmax>aX2) {
2631 thevmax=aX2;
2632 }
7fd59977 2633 }
2634 }
2635 }
2636 //
2637 if(isuperiodic || isvperiodic) {
2638 Standard_Boolean correct = Standard_False;
2639 Standard_Boolean correctU = Standard_False;
2640 Standard_Boolean correctV = Standard_False;
2641 Bnd_Box2d aBox;
2642 TopExp_Explorer anExp;
2643
2644 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2645 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
655fddc8 2646 correct = Standard_True;
2647 Standard_Real f, l;
2648 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2649
2650 for(Standard_Integer i = 0; i < 2; i++) {
2651 if(i==0) {
2652 anEdge.Orientation(TopAbs_FORWARD);
2653 }
2654 else {
2655 anEdge.Orientation(TopAbs_REVERSED);
2656 }
2657 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2658
2659 if(aCurve.IsNull()) {
2660 correct = Standard_False;
2661 break;
2662 }
2663 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2664
2665 if(aLine.IsNull()) {
2666 correct = Standard_False;
2667 break;
2668 }
2669 gp_Dir2d anUDir(1., 0.);
2670 gp_Dir2d aVDir(0., 1.);
2671 Standard_Real anAngularTolerance = Precision::Angular();
2672
2673 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2674 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2675
2676 gp_Pnt2d pp1 = aCurve->Value(f);
2677 aBox.Add(pp1);
2678 gp_Pnt2d pp2 = aCurve->Value(l);
2679 aBox.Add(pp2);
2680 }
2681 if(!correct)
2682 break;
7fd59977 2683 }
2684 }
2685
2686 if(correct) {
2687 Standard_Real umin, vmin, umax, vmax;
2688 aBox.Get(umin, vmin, umax, vmax);
2689
2690 if(isuperiodic && correctU) {
655fddc8 2691
2692 if(theumin < umin)
2693 theumin = umin;
2694
2695 if(theumax > umax) {
2696 theumax = umax;
2697 }
7fd59977 2698 }
2699 if(isvperiodic && correctV) {
655fddc8 2700
2701 if(thevmin < vmin)
2702 thevmin = vmin;
2703 if(thevmax > vmax)
2704 thevmax = vmax;
7fd59977 2705 }
2706 }
2707 }
2708}
2709//
2710//
2711// The block is dedicated to determine whether WLine [ifprm, ilprm]
2712// crosses the degenerated zone on each given surface or not.
2713// If Yes -> We will not use info about surfaces during approximation
8e0115e4 2714// because inside degenerated zone of the surface the approx. algo.
7fd59977 2715// uses wrong values of normal, etc., and resulting curve will have
2716// oscillations that we would not like to have.
7fd59977 2717
2718
4e57c75e 2719
7fd59977 2720static
2721 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
655fddc8 2722 const Handle(Geom_Surface)& aS,
2723 const Standard_Integer iDir);
7fd59977 2724static
2725 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
655fddc8 2726 const TopoDS_Face& aF1,
2727 const TopoDS_Face& aF2);
7fd59977 2728//=======================================================================
2729//function : NotUseSurfacesForApprox
2730//purpose :
2731//=======================================================================
2732Standard_Boolean NotUseSurfacesForApprox(const TopoDS_Face& aF1,
655fddc8 2733 const TopoDS_Face& aF2,
2734 const Handle(IntPatch_WLine)& WL,
2735 const Standard_Integer ifprm,
2736 const Standard_Integer ilprm)
7fd59977 2737{
2738 Standard_Boolean bPInDZ;
2739
2740 Handle(IntSurf_LineOn2S) aLineOn2S=WL->Curve();
2741
2742 const IntSurf_PntOn2S& aP2Sfprm=aLineOn2S->Value(ifprm);
2743 bPInDZ=IsPointInDegeneratedZone(aP2Sfprm, aF1, aF2);
2744 if (bPInDZ) {
2745 return bPInDZ;
2746 }
2747
2748 const IntSurf_PntOn2S& aP2Slprm=aLineOn2S->Value(ilprm);
2749 bPInDZ=IsPointInDegeneratedZone(aP2Slprm, aF1, aF2);
2750
2751 return bPInDZ;
2752}
2753//=======================================================================
2754//function : IsPointInDegeneratedZone
2755//purpose :
2756//=======================================================================
2757Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
655fddc8 2758 const TopoDS_Face& aF1,
2759 const TopoDS_Face& aF2)
2760
7fd59977 2761{
2762 Standard_Boolean bFlag=Standard_True;
2763 Standard_Real US11, US12, VS11, VS12, US21, US22, VS21, VS22;
2764 Standard_Real U1, V1, U2, V2, aDelta, aD;
2765 gp_Pnt2d aP2d;
2766
2767 Handle(Geom_Surface)aS1 = BRep_Tool::Surface(aF1);
2768 aS1->Bounds(US11, US12, VS11, VS12);
2769 GeomAdaptor_Surface aGAS1(aS1);
2770
2771 Handle(Geom_Surface)aS2 = BRep_Tool::Surface(aF2);
2772 aS1->Bounds(US21, US22, VS21, VS22);
2773 GeomAdaptor_Surface aGAS2(aS2);
2774 //
2775 //const gp_Pnt& aP=aP2S.Value();
2776 aP2S.Parameters(U1, V1, U2, V2);
2777 //
2778 aDelta=1.e-7;
2779 // Check on Surf 1
2780 aD=aGAS1.UResolution(aDelta);
2781 aP2d.SetCoord(U1, V1);
2782 if (fabs(U1-US11) < aD) {
2783 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2784 if (bFlag) {
2785 return bFlag;
2786 }
2787 }
2788 if (fabs(U1-US12) < aD) {
2789 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2790 if (bFlag) {
2791 return bFlag;
2792 }
2793 }
2794 aD=aGAS1.VResolution(aDelta);
2795 if (fabs(V1-VS11) < aDelta) {
2796 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2797 if (bFlag) {
2798 return bFlag;
2799 }
2800 }
2801 if (fabs(V1-VS12) < aDelta) {
2802 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2803 if (bFlag) {
2804 return bFlag;
2805 }
2806 }
2807 // Check on Surf 2
2808 aD=aGAS2.UResolution(aDelta);
2809 aP2d.SetCoord(U2, V2);
2810 if (fabs(U2-US21) < aDelta) {
2811 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2812 if (bFlag) {
2813 return bFlag;
2814 }
2815 }
2816 if (fabs(U2-US22) < aDelta) {
2817 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2818 if (bFlag) {
2819 return bFlag;
2820 }
2821 }
2822 aD=aGAS2.VResolution(aDelta);
2823 if (fabs(V2-VS21) < aDelta) {
2824 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2825 if (bFlag) {
2826 return bFlag;
2827 }
2828 }
2829 if (fabs(V2-VS22) < aDelta) {
2830 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2831 if (bFlag) {
2832 return bFlag;
2833 }
2834 }
2835 return !bFlag;
2836}
2837
2838//=======================================================================
2839//function : IsDegeneratedZone
2840//purpose :
2841//=======================================================================
2842Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
655fddc8 2843 const Handle(Geom_Surface)& aS,
2844 const Standard_Integer iDir)
7fd59977 2845{
2846 Standard_Boolean bFlag=Standard_True;
2847 Standard_Real US1, US2, VS1, VS2, dY, dX, d1, d2, dD;
2848 Standard_Real aXm, aYm, aXb, aYb, aXe, aYe;
2849 aS->Bounds(US1, US2, VS1, VS2);
2850
2851 gp_Pnt aPm, aPb, aPe;
2852
2853 aXm=aP2d.X();
2854 aYm=aP2d.Y();
2855
2856 aS->D0(aXm, aYm, aPm);
2857
2858 dX=1.e-5;
2859 dY=1.e-5;
2860 dD=1.e-12;
2861
2862 if (iDir==1) {
2863 aXb=aXm;
2864 aXe=aXm;
2865 aYb=aYm-dY;
2866 if (aYb < VS1) {
2867 aYb=VS1;
2868 }
2869 aYe=aYm+dY;
2870 if (aYe > VS2) {
2871 aYe=VS2;
2872 }
2873 aS->D0(aXb, aYb, aPb);
2874 aS->D0(aXe, aYe, aPe);
2875
2876 d1=aPm.Distance(aPb);
2877 d2=aPm.Distance(aPe);
2878 if (d1 < dD && d2 < dD) {
2879 return bFlag;
2880 }
2881 return !bFlag;
2882 }
2883 //
2884 else if (iDir==2) {
2885 aYb=aYm;
2886 aYe=aYm;
2887 aXb=aXm-dX;
2888 if (aXb < US1) {
2889 aXb=US1;
2890 }
2891 aXe=aXm+dX;
2892 if (aXe > US2) {
2893 aXe=US2;
2894 }
2895 aS->D0(aXb, aYb, aPb);
2896 aS->D0(aXe, aYe, aPe);
2897
2898 d1=aPm.Distance(aPb);
2899 d2=aPm.Distance(aPe);
2900 if (d1 < dD && d2 < dD) {
2901 return bFlag;
2902 }
2903 return !bFlag;
2904 }
2905 return !bFlag;
2906}
2907
2908//=========================================================================
2909// static function : ComputePurgedWLine
2910// purpose : Removes equal points (leave one of equal points) from theWLine
2911// and recompute vertex parameters.
2912// Returns new WLine or null WLine if the number
2913// of the points is less than 2.
2914//=========================================================================
2915Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
3928aec6 2916
3928aec6 2917 Standard_Integer i, k, v, nb, nbvtx;
7fd59977 2918 Handle(IntPatch_WLine) aResult;
3928aec6
P
2919 nbvtx = theWLine->NbVertex();
2920 nb = theWLine->NbPnts();
2921 if (nb==2) {
2922 const IntSurf_PntOn2S& p1 = theWLine->Point(1);
2923 const IntSurf_PntOn2S& p2 = theWLine->Point(2);
2924 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2925 return aResult;
2926 }
2927 }
2928 //
7fd59977 2929 Handle(IntPatch_WLine) aLocalWLine;
2930 Handle(IntPatch_WLine) aTmpWLine = theWLine;
7fd59977 2931 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
2932 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
7fd59977 2933 for(i = 1; i <= nb; i++) {
2934 aLineOn2S->Add(theWLine->Point(i));
2935 }
2936
2937 for(v = 1; v <= nbvtx; v++) {
2938 aLocalWLine->AddVertex(theWLine->Vertex(v));
2939 }
2940
2941 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
2942 Standard_Integer aStartIndex = i + 1;
2943 Standard_Integer anEndIndex = i + 5;
2944 nb = aLineOn2S->NbPoints();
2945 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
2946
a2eede02 2947 if((aStartIndex > nb) || (anEndIndex <= 1)) {
7fd59977 2948 continue;
2949 }
2950 k = aStartIndex;
2951
2952 while(k <= anEndIndex) {
2953
2954 if(i != k) {
655fddc8 2955 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
2956 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
2957
2958 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2959 aTmpWLine = aLocalWLine;
2960 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2961
2962 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
2963 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
2964 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
2965
2966 if(avertexindex >= k) {
2967 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
2968 }
2969 aLocalWLine->AddVertex(aVertex);
2970 }
2971 aLineOn2S->RemovePoint(k);
2972 anEndIndex--;
2973 continue;
2974 }
7fd59977 2975 }
2976 k++;
2977 }
2978 }
2979
2980 if(aLineOn2S->NbPoints() > 1) {
2981 aResult = aLocalWLine;
2982 }
2983 return aResult;
2984}
2985
2986//=======================================================================
2987//function : TolR3d
2988//purpose :
2989//=======================================================================
2990void TolR3d(const TopoDS_Face& aF1,
655fddc8 2991 const TopoDS_Face& aF2,
2992 Standard_Real& myTolReached3d)
7fd59977 2993{
2994 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
2995
2996 aTolTresh=2.999999e-3;
2997 aTolF1 = BRep_Tool::Tolerance(aF1);
2998 aTolF2 = BRep_Tool::Tolerance(aF2);
2999 aTolFMax=Max(aTolF1, aTolF2);
3000
3001 if (aTolFMax>aTolTresh) {
3002 myTolReached3d=aTolFMax;
3003 }
3004}
3005//=======================================================================
7fd59977 3006//function : IsPointOnBoundary
3007//purpose :
3008//=======================================================================
3009Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
655fddc8 3010 const Standard_Real theFirstBoundary,
3011 const Standard_Real theSecondBoundary,
3012 const Standard_Real theResolution,
3013 Standard_Boolean& IsOnFirstBoundary)
7fd59977 3014{
3015 Standard_Boolean bRet;
3016 Standard_Integer i;
3017 Standard_Real adist;
3018 //
3019 bRet=Standard_False;
3020 for(i = 0; i < 2; ++i) {
3021 IsOnFirstBoundary = (i == 0);
3022 if (IsOnFirstBoundary) {
3023 adist = fabs(theParameter - theFirstBoundary);
3024 }
3025 else {
3026 adist = fabs(theParameter - theSecondBoundary);
3027 }
3028 if(adist < theResolution) {
3029 return !bRet;
3030 }
3031 }
3032 return bRet;
3033}
3034// ------------------------------------------------------------------------------------------------
3035// static function: FindPoint
3036// purpose:
3037// ------------------------------------------------------------------------------------------------
3038Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 3039 const gp_Pnt2d& theLastPoint,
3040 const Standard_Real theUmin,
3041 const Standard_Real theUmax,
3042 const Standard_Real theVmin,
3043 const Standard_Real theVmax,
3044 gp_Pnt2d& theNewPoint) {
7fd59977 3045
3046 gp_Vec2d aVec(theFirstPoint, theLastPoint);
3047 Standard_Integer i = 0, j = 0;
3048
3049 for(i = 0; i < 4; i++) {
3050 gp_Vec2d anOtherVec;
3051 gp_Vec2d anOtherVecNormal;
3052 gp_Pnt2d aprojpoint = theLastPoint;
3053
3054 if((i % 2) == 0) {
3055 anOtherVec.SetX(0.);
3056 anOtherVec.SetY(1.);
3057 anOtherVecNormal.SetX(1.);
3058 anOtherVecNormal.SetY(0.);
3059
3060 if(i < 2)
655fddc8 3061 aprojpoint.SetX(theUmin);
7fd59977 3062 else
655fddc8 3063 aprojpoint.SetX(theUmax);
7fd59977 3064 }
3065 else {
3066 anOtherVec.SetX(1.);
3067 anOtherVec.SetY(0.);
3068 anOtherVecNormal.SetX(0.);
3069 anOtherVecNormal.SetY(1.);
3070
3071 if(i < 2)
655fddc8 3072 aprojpoint.SetY(theVmin);
7fd59977 3073 else
655fddc8 3074 aprojpoint.SetY(theVmax);
7fd59977 3075 }
3076 gp_Vec2d anormvec = aVec;
3077 anormvec.Normalize();
fa9681ca 3078 RefineVector(anormvec);
7fd59977 3079 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
3080
3081 if(fabs(adot1) < Precision::Angular())
3082 continue;
3083 Standard_Real adist = 0.;
3084 Standard_Boolean bIsOut = Standard_False;
3085
3086 if((i % 2) == 0) {
3087 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
3088 bIsOut = (i < 2) ? (theLastPoint.X() < theUmin) : (theLastPoint.X() > theUmax);
3089 }
3090 else {
3091 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
3092 bIsOut = (i < 2) ? (theLastPoint.Y() < theVmin) : (theLastPoint.Y() > theVmax);
3093 }
3094 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
3095
3096 for(j = 0; j < 2; j++) {
3097 anoffset = (j == 0) ? anoffset : -anoffset;
3098 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
3099 gp_Vec2d acurvec(theLastPoint, acurpoint);
3100 if ( bIsOut )
655fddc8 3101 acurvec.Reverse();
7fd59977 3102
9e9df9d9
P
3103 Standard_Real aDotX, anAngleX;
3104 //
3105 aDotX = aVec.Dot(acurvec);
3106 anAngleX = aVec.Angle(acurvec);
3107 //
3108 if(aDotX > 0. && fabs(anAngleX) < Precision::PConfusion()) {
655fddc8 3109 if((i % 2) == 0) {
3110 if((acurpoint.Y() >= theVmin) &&
3111 (acurpoint.Y() <= theVmax)) {
3112 theNewPoint = acurpoint;
3113 return Standard_True;
3114 }
3115 }
3116 else {
3117 if((acurpoint.X() >= theUmin) &&
3118 (acurpoint.X() <= theUmax)) {
3119 theNewPoint = acurpoint;
3120 return Standard_True;
3121 }
3122 }
7fd59977 3123 }
3124 }
3125 }
3126 return Standard_False;
3127}
3128
3129
3130// ------------------------------------------------------------------------------------------------
3131// static function: FindPoint
3132// purpose: Find point on the boundary of radial tangent zone
3133// ------------------------------------------------------------------------------------------------
3134Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 3135 const gp_Pnt2d& theLastPoint,
3136 const Standard_Real theUmin,
3137 const Standard_Real theUmax,
3138 const Standard_Real theVmin,
3139 const Standard_Real theVmax,
3140 const gp_Pnt2d& theTanZoneCenter,
3141 const Standard_Real theZoneRadius,
3142 Handle(GeomAdaptor_HSurface) theGASurface,
3143 gp_Pnt2d& theNewPoint) {
7fd59977 3144 theNewPoint = theLastPoint;
3145
3146 if ( !IsInsideTanZone( theLastPoint, theTanZoneCenter, theZoneRadius, theGASurface) )
3147 return Standard_False;
3148
3149 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3150 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3151
3152 Standard_Real aRadius = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3153 gp_Ax22d anAxis( theTanZoneCenter, gp_Dir2d(1, 0), gp_Dir2d(0, 1) );
3154 gp_Circ2d aCircle( anAxis, aRadius );
3155
3156 //
3157 gp_Vec2d aDir( theLastPoint.XY() - theFirstPoint.XY() );
3158 Standard_Real aLength = aDir.Magnitude();
3159 if ( aLength <= gp::Resolution() )
3160 return Standard_False;
3161 gp_Lin2d aLine( theFirstPoint, aDir );
3162
3163 //
3164 Handle(Geom2d_Line) aCLine = new Geom2d_Line( aLine );
3165 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve( aCLine, 0, aLength );
3166 Handle(Geom2d_Circle) aC2 = new Geom2d_Circle( aCircle );
3167
3168 Standard_Real aTol = aRadius * 0.001;
3169 aTol = ( aTol < Precision::PConfusion() ) ? Precision::PConfusion() : aTol;
3170
3171 Geom2dAPI_InterCurveCurve anIntersector;
3172 anIntersector.Init( aC1, aC2, aTol );
3173
3174 if ( anIntersector.NbPoints() == 0 )
3175 return Standard_False;
3176
3177 Standard_Boolean aFound = Standard_False;
3178 Standard_Real aMinDist = aLength * aLength;
3179 Standard_Integer i = 0;
3180 for ( i = 1; i <= anIntersector.NbPoints(); i++ ) {
3181 gp_Pnt2d aPInt = anIntersector.Point( i );
3182 if ( aPInt.SquareDistance( theFirstPoint ) < aMinDist ) {
3183 if ( ( aPInt.X() >= theUmin ) && ( aPInt.X() <= theUmax ) &&
655fddc8 3184 ( aPInt.Y() >= theVmin ) && ( aPInt.Y() <= theVmax ) ) {
3185 theNewPoint = aPInt;
3186 aFound = Standard_True;
7fd59977 3187 }
3188 }
3189 }
3190
3191 return aFound;
3192}
3193
3194// ------------------------------------------------------------------------------------------------
3195// static function: IsInsideTanZone
3196// purpose: Check if point is inside a radial tangent zone
3197// ------------------------------------------------------------------------------------------------
3198Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
655fddc8 3199 const gp_Pnt2d& theTanZoneCenter,
3200 const Standard_Real theZoneRadius,
3201 Handle(GeomAdaptor_HSurface) theGASurface) {
7fd59977 3202
3203 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3204 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3205 Standard_Real aRadiusSQR = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3206 aRadiusSQR *= aRadiusSQR;
3207 if ( thePoint.SquareDistance( theTanZoneCenter ) <= aRadiusSQR )
3208 return Standard_True;
3209 return Standard_False;
3210}
3211
3212// ------------------------------------------------------------------------------------------------
3213// static function: CheckTangentZonesExist
3214// purpose: Check if tangent zone exists
3215// ------------------------------------------------------------------------------------------------
3216Standard_Boolean CheckTangentZonesExist( const Handle(GeomAdaptor_HSurface)& theSurface1,
655fddc8 3217 const Handle(GeomAdaptor_HSurface)& theSurface2 )
7fd59977 3218{
3219 if ( ( theSurface1->GetType() != GeomAbs_Torus ) ||
3220 ( theSurface2->GetType() != GeomAbs_Torus ) )
3221 return Standard_False;
3222
7fd59977 3223 gp_Torus aTor1 = theSurface1->Torus();
3224 gp_Torus aTor2 = theSurface2->Torus();
3225
3226 if ( aTor1.Location().Distance( aTor2.Location() ) > Precision::Confusion() )
3227 return Standard_False;
3228
3229 if ( ( fabs( aTor1.MajorRadius() - aTor2.MajorRadius() ) > Precision::Confusion() ) ||
3230 ( fabs( aTor1.MinorRadius() - aTor2.MinorRadius() ) > Precision::Confusion() ) )
3231 return Standard_False;
3232
3233 if ( ( aTor1.MajorRadius() < aTor1.MinorRadius() ) ||
3234 ( aTor2.MajorRadius() < aTor2.MinorRadius() ) )
3235 return Standard_False;
3236 return Standard_True;
3237}
3238
3239// ------------------------------------------------------------------------------------------------
3240// static function: ComputeTangentZones
3241// purpose:
3242// ------------------------------------------------------------------------------------------------
3243Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
655fddc8 3244 const Handle(GeomAdaptor_HSurface)& theSurface2,
3245 const TopoDS_Face& theFace1,
3246 const TopoDS_Face& theFace2,
3247 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
3248 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
3249 Handle(TColStd_HArray1OfReal)& theResultRadius,
1e143abb 3250 const Handle(IntTools_Context)& aContext)
4f189102 3251{
7fd59977 3252 Standard_Integer aResult = 0;
3253 if ( !CheckTangentZonesExist( theSurface1, theSurface2 ) )
3254 return aResult;
3255
7fd59977 3256
3257 TColgp_SequenceOfPnt2d aSeqResultS1, aSeqResultS2;
3258 TColStd_SequenceOfReal aSeqResultRad;
3259
3260 gp_Torus aTor1 = theSurface1->Torus();
3261 gp_Torus aTor2 = theSurface2->Torus();
3262
3263 gp_Ax2 anax1( aTor1.Location(), aTor1.Axis().Direction() );
3264 gp_Ax2 anax2( aTor2.Location(), aTor2.Axis().Direction() );
3265 Standard_Integer j = 0;
3266
3267 for ( j = 0; j < 2; j++ ) {
3268 Standard_Real aCoef = ( j == 0 ) ? -1 : 1;
3269 Standard_Real aRadius1 = fabs(aTor1.MajorRadius() + aCoef * aTor1.MinorRadius());
3270 Standard_Real aRadius2 = fabs(aTor2.MajorRadius() + aCoef * aTor2.MinorRadius());
3271
3272 gp_Circ aCircle1( anax1, aRadius1 );
3273 gp_Circ aCircle2( anax2, aRadius2 );
3274
3275 // roughly compute radius of tangent zone for perpendicular case
3276 Standard_Real aCriteria = Precision::Confusion() * 0.5;
3277
3278 Standard_Real aT1 = aCriteria;
3279 Standard_Real aT2 = aCriteria;
3280 if ( j == 0 ) {
3281 // internal tangency
3282 Standard_Real aR = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3283 //aT1 = aCriteria * aCriteria + aR * aR - ( aR - aCriteria ) * ( aR - aCriteria );
3284 aT1 = 2. * aR * aCriteria;
3285 aT2 = aT1;
3286 }
3287 else {
3288 // external tangency
3289 Standard_Real aRb = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3290 Standard_Real aRm = ( aRadius1 < aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3291 Standard_Real aDelta = aRb - aCriteria;
3292 aDelta *= aDelta;
3293 aDelta -= aRm * aRm;
3294 aDelta /= 2. * (aRb - aRm);
3295 aDelta -= 0.5 * (aRb - aRm);
3296
3297 aT1 = 2. * aRm * (aRm - aDelta);
3298 aT2 = aT1;
3299 }
3300 aCriteria = ( aT1 > aT2) ? aT1 : aT2;
3301 if ( aCriteria > 0 )
3302 aCriteria = sqrt( aCriteria );
3303
3304 if ( aCriteria > 0.5 * aTor1.MinorRadius() ) {
3305 // too big zone -> drop to minimum
3306 aCriteria = Precision::Confusion();
3307 }
3308
3309 GeomAdaptor_Curve aC1( new Geom_Circle(aCircle1) );
3310 GeomAdaptor_Curve aC2( new Geom_Circle(aCircle2) );
c6541a0c 3311 Extrema_ExtCC anExtrema(aC1, aC2, 0, 2. * M_PI, 0, 2. * M_PI,
655fddc8 3312 Precision::PConfusion(), Precision::PConfusion());
3313
7fd59977 3314 if ( anExtrema.IsDone() ) {
3315
3316 Standard_Integer i = 0;
3317 for ( i = 1; i <= anExtrema.NbExt(); i++ ) {
655fddc8 3318 if ( anExtrema.SquareDistance(i) > aCriteria * aCriteria )
3319 continue;
3320
3321 Extrema_POnCurv P1, P2;
3322 anExtrema.Points( i, P1, P2 );
3323
3324 Standard_Boolean bFoundResult = Standard_True;
3325 gp_Pnt2d pr1, pr2;
3326
3327 Standard_Integer surfit = 0;
3328 for ( surfit = 0; surfit < 2; surfit++ ) {
3329 GeomAPI_ProjectPointOnSurf& aProjector =
3330 (surfit == 0) ? aContext->ProjPS(theFace1) : aContext->ProjPS(theFace2);
3331
3332 gp_Pnt aP3d = (surfit == 0) ? P1.Value() : P2.Value();
3333 aProjector.Perform(aP3d);
3334
3335 if(!aProjector.IsDone())
3336 bFoundResult = Standard_False;
3337 else {
3338 if(aProjector.LowerDistance() > aCriteria) {
3339 bFoundResult = Standard_False;
3340 }
3341 else {
3342 Standard_Real foundU = 0, foundV = 0;
3343 aProjector.LowerDistanceParameters(foundU, foundV);
3344 if ( surfit == 0 )
3345 pr1 = gp_Pnt2d( foundU, foundV );
3346 else
3347 pr2 = gp_Pnt2d( foundU, foundV );
3348 }
3349 }
3350 }
3351 if ( bFoundResult ) {
3352 aSeqResultS1.Append( pr1 );
3353 aSeqResultS2.Append( pr2 );
3354 aSeqResultRad.Append( aCriteria );
3355
3356 // torus is u and v periodic
3357 const Standard_Real twoPI = M_PI + M_PI;
3358 Standard_Real arr1tmp[2] = {pr1.X(), pr1.Y()};
3359 Standard_Real arr2tmp[2] = {pr2.X(), pr2.Y()};
3360
3361 // iteration on period bounds
3362 for ( Standard_Integer k1 = 0; k1 < 2; k1++ ) {
3363 Standard_Real aBound = ( k1 == 0 ) ? 0 : twoPI;
3364 Standard_Real aShift = ( k1 == 0 ) ? twoPI : -twoPI;
3365
3366 // iteration on surfaces
3367 for ( Standard_Integer k2 = 0; k2 < 2;