0024023: Revamp the OCCT Handle -- plugin
[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();
4f189102
P
966 const Handle(Geom_BSplineCurve)& aBS=
967 Handle(Geom_BSplineCurve)::DownCast(aC3D);
0fc4f2e2
P
968 if (aBS.IsNull()) {
969 return;
970 }
971 //
972 aT1=aBS->FirstParameter();
973 aT2=aBS->LastParameter();
974 //
975 aPln =(aType1==GeomAbs_Plane) ? myHS1->Plane() : myHS2->Plane();
976 aTorus=(aType1==GeomAbs_Plane) ? myHS2->Torus() : myHS1->Torus();
977 //
978 aDmax=-1.;
979 aNbP=11;
980 dT=(aT2-aT1)/(aNbP-1);
981 for (i=0; i<aNbP; ++i) {
982 aT=aT1+i*dT;
983 if (i==aNbP-1) {
655fddc8 984 aT=aT2;
0fc4f2e2
P
985 }
986 //
987 aC3D->D0(aT, aP);
988 //
989 ElSLib::Parameters(aPln, aP, aUP, aVP);
990 aPP=ElSLib::Value(aUP, aVP, aPln);
991 aDP=aP.SquareDistance(aPP);
992 if (aDP>aDmax) {
655fddc8 993 aDmax=aDP;
0fc4f2e2
P
994 }
995 //
996 ElSLib::Parameters(aTorus, aP, aUT, aVT);
997 aPT=ElSLib::Value(aUT, aVT, aTorus);
998 aDT=aP.SquareDistance(aPT);
999 if (aDT>aDmax) {
655fddc8 1000 aDmax=aDT;
0fc4f2e2
P
1001 }
1002 }
1003 //
1004 if (aDmax > myTolReached3d*myTolReached3d) {
1005 myTolReached3d=sqrt(aDmax);
1006 myTolReached3d=1.1*myTolReached3d;
1007 }
1008 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Torus) ||
a9f7b6b5 1009 //
4f189102 1010 else if ((aType1==GeomAbs_SurfaceOfRevolution && aType2==GeomAbs_Cylinder) ||
1b7ae951 1011 (aType2==GeomAbs_SurfaceOfRevolution && aType1==GeomAbs_Cylinder) ||
1012 (aType1==GeomAbs_Plane && aType2==GeomAbs_Sphere) ||
1013 (aType2==GeomAbs_Plane && aType1==GeomAbs_Sphere) ||
1014 (aType1==GeomAbs_Plane && aType2==GeomAbs_SurfaceOfExtrusion) ||
1015 (aType2==GeomAbs_Plane && aType1==GeomAbs_SurfaceOfExtrusion) ||
1016 (aType1==GeomAbs_Plane && aType2==GeomAbs_BSplineSurface) ||
1017 (aType2==GeomAbs_Plane && aType1==GeomAbs_BSplineSurface) ||
1018 !myApprox) {
0c5acd27 1019 //
1b7ae951 1020 Standard_Real aDMax;
0c5acd27 1021 //
1b7ae951 1022 aDMax = ComputeTolerance();
1023 if (aDMax > myTolReached3d) {
1024 myTolReached3d = aDMax;
0c5acd27 1025 }
4e57c75e 1026 }
7fd59977 1027}
1b7ae951 1028
7fd59977 1029//=======================================================================
1030//function : MakeCurve
1031//purpose :
1032//=======================================================================
1033 void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
655fddc8 1034 const Handle(Adaptor3d_TopolTool)& dom1,
1035 const Handle(Adaptor3d_TopolTool)& dom2)
7fd59977 1036{
4abae870 1037 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
1038 Standard_Boolean ok, bPCurvesOk;
7fd59977 1039 Standard_Integer i, j, aNbParts;
1040 Standard_Real fprm, lprm;
1041 Standard_Real Tolpc;
1042 Handle(IntPatch_Line) L;
1043 IntPatch_IType typl;
1044 Handle(Geom_Curve) newc;
1045 //
1046 const Standard_Real TOLCHECK =0.0000001;
1047 const Standard_Real TOLANGCHECK=0.1;
1048 //
1049 rejectSurface = Standard_False;
1050 reApprox = Standard_False;
989341c5 1051 //
1052 bPCurvesOk = Standard_True;
59495dbe 1053
1054 reapprox:;
1055
7fd59977 1056 Tolpc = myTolApprox;
1057 bAvoidLineConstructor = Standard_False;
1058 L = myIntersector.Line(Index);
1059 typl = L->ArcType();
1060 //
1061 if(typl==IntPatch_Walking) {
1062 Handle(IntPatch_Line) anewL;
1063 //
1064 const Handle(IntPatch_WLine)& aWLine=
1065 Handle(IntPatch_WLine)::DownCast(L);
4abae870 1066 //DumpWLine(aWLine);
1067
7fd59977 1068 anewL = ComputePurgedWLine(aWLine);
1069 if(anewL.IsNull()) {
1070 return;
1071 }
1072 L = anewL;
4abae870 1073
1074 //const Handle(IntPatch_WLine)& aWLineX = Handle(IntPatch_WLine)::DownCast(L);
1075 //DumpWLine(aWLineX);
1076
7fd59977 1077 //
1078 if(!myListOfPnts.IsEmpty()) {
1079 bAvoidLineConstructor = Standard_True;
1080 }
1081
1082 Standard_Integer nbp = aWLine->NbPnts();
1083 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
1084 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
1085
1086 const gp_Pnt& P1 = p1.Value();
1087 const gp_Pnt& P2 = p2.Value();
1088
1089 if(P1.SquareDistance(P2) < 1.e-14) {
1090 bAvoidLineConstructor = Standard_False;
1091 }
7fd59977 1092 }
d4b867e6 1093
1094 typl=L->ArcType();
1095
7fd59977 1096 //
1097 // Line Constructor
1098 if(!bAvoidLineConstructor) {
1099 myLConstruct.Perform(L);
1100 //
1101 bDone=myLConstruct.IsDone();
d4b867e6 1102 if(!bDone)
1103 {
7fd59977 1104 return;
1105 }
d4b867e6 1106
1107 if(typl != IntPatch_Restriction)
1108 {
1109 aNbParts=myLConstruct.NbParts();
1110 if (aNbParts <= 0)
1111 {
1112 return;
1113 }
1114 }
7fd59977 1115 }
1116 // Do the Curve
d4b867e6 1117
1118
7fd59977 1119 switch (typl) {
59495dbe 1120 //########################################
1121 // Line, Parabola, Hyperbola
1122 //########################################
7fd59977 1123 case IntPatch_Lin:
1124 case IntPatch_Parabola:
1125 case IntPatch_Hyperbola: {
1126 if (typl == IntPatch_Lin) {
1127 newc =
655fddc8 1128 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
7fd59977 1129 }
1130
1131 else if (typl == IntPatch_Parabola) {
1132 newc =
655fddc8 1133 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
7fd59977 1134 }
59495dbe 1135
7fd59977 1136 else if (typl == IntPatch_Hyperbola) {
1137 newc =
655fddc8 1138 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
7fd59977 1139 }
1140 //
1141 // myTolReached3d
1142 if (typl == IntPatch_Lin) {
1143 TolR3d (myFace1, myFace2, myTolReached3d);
1144 }
1145 //
1146 aNbParts=myLConstruct.NbParts();
1147 for (i=1; i<=aNbParts; i++) {
0da45792 1148 Standard_Boolean bFNIt, bLPIt;
1149 //
7fd59977 1150 myLConstruct.Part(i, fprm, lprm);
d4b867e6 1151 //
0da45792 1152 bFNIt=Precision::IsNegativeInfinite(fprm);
1153 bLPIt=Precision::IsPositiveInfinite(lprm);
1154 //
1155 if (!bFNIt && !bLPIt) {
655fddc8 1156 //
1157 IntTools_Curve aCurve;
1158 //
1159 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
1160 aCurve.SetCurve(aCT3D);
1161 if (typl == IntPatch_Parabola) {
1162 Standard_Real aTolF1, aTolF2, aTolBase;
1163
1164 aTolF1 = BRep_Tool::Tolerance(myFace1);
1165 aTolF2 = BRep_Tool::Tolerance(myFace2);
1166 aTolBase=aTolF1+aTolF2;
1167 myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
1168 }
1169 //
1170 aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
1171 if(myApprox1) {
1172 Handle (Geom2d_Curve) C2d;
d4b867e6 1173 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1174 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1175 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1176 myTolReached2d=Tolpc;
1177 }
1178 //
1179 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1180 }
1181 else {
1182 Handle(Geom2d_BSplineCurve) H1;
1183 //
1184 aCurve.SetFirstCurve2d(H1);
1185 }
0da45792 1186 //
655fddc8 1187 if(myApprox2) {
1188 Handle (Geom2d_Curve) C2d;
d4b867e6 1189 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1190 myHS2->ChangeSurface().Surface(), newc, C2d);
655fddc8 1191 if(Tolpc>myTolReached2d || myTolReached2d==0.) {
1192 myTolReached2d=Tolpc;
1193 }
1194 //
1195 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d,fprm,lprm));
1196 }
1197 else {
1198 Handle(Geom2d_BSplineCurve) H1;
1199 //
1200 aCurve.SetSecondCurve2d(H1);
1201 }
1202 mySeqOfCurve.Append(aCurve);
0da45792 1203 } //if (!bFNIt && !bLPIt) {
7fd59977 1204 else {
655fddc8 1205 // on regarde si on garde
1206 //
655fddc8 1207 Standard_Real aTestPrm, dT=100.;
0da45792 1208 //
655fddc8 1209 aTestPrm=0.;
655fddc8 1210 if (bFNIt && !bLPIt) {
1211 aTestPrm=lprm-dT;
1212 }
1213 else if (!bFNIt && bLPIt) {
1214 aTestPrm=fprm+dT;
1215 }
0da45792 1216 else {
1217 // i.e, if (bFNIt && bLPIt)
1218 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
1219 }
1220 //
655fddc8 1221 gp_Pnt ptref(newc->Value(aTestPrm));
1222 //
94218044 1223 GeomAbs_SurfaceType typS1 = myHS1->GetType();
1224 GeomAbs_SurfaceType typS2 = myHS2->GetType();
1225 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
1226 typS1 == GeomAbs_OffsetSurface ||
1227 typS1 == GeomAbs_SurfaceOfRevolution ||
1228 typS2 == GeomAbs_SurfaceOfExtrusion ||
1229 typS2 == GeomAbs_OffsetSurface ||
0da45792 1230 typS2 == GeomAbs_SurfaceOfRevolution) {
94218044 1231 Handle(Geom2d_BSplineCurve) H1;
1232 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1233 continue;
1234 }
1235
655fddc8 1236 Standard_Real u1, v1, u2, v2, Tol;
1237
1238 Tol = Precision::Confusion();
1239 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1240 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
1241 if(ok) {
1242 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1243 }
1244 if (ok) {
1245 Handle(Geom2d_BSplineCurve) H1;
1246 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
1247 }
7fd59977 1248 }
0da45792 1249 }// for (i=1; i<=aNbParts; i++) {
7fd59977 1250 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
59495dbe 1251 break;
7fd59977 1252
59495dbe 1253 //########################################
1254 // Circle and Ellipse
1255 //########################################
7fd59977 1256 case IntPatch_Circle:
1257 case IntPatch_Ellipse: {
1258
1259 if (typl == IntPatch_Circle) {
1260 newc = new Geom_Circle
655fddc8 1261 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
7fd59977 1262 }
1263 else { //IntPatch_Ellipse
1264 newc = new Geom_Ellipse
655fddc8 1265 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
7fd59977 1266 }
1267 //
1268 // myTolReached3d
1269 TolR3d (myFace1, myFace2, myTolReached3d);
1270 //
1271 aNbParts=myLConstruct.NbParts();
1272 //
1273 Standard_Real aPeriod, aNul;
1274 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
59495dbe 1275
7fd59977 1276 aNul=0.;
c6541a0c 1277 aPeriod=M_PI+M_PI;
7fd59977 1278
1279 for (i=1; i<=aNbParts; i++) {
1280 myLConstruct.Part(i, fprm, lprm);
1281
1282 if (fprm < aNul && lprm > aNul) {
655fddc8 1283 // interval that goes through 0. is divided on two intervals;
1284 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
1285 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
1286 //
1287 if((aPeriod - fprm) > Tolpc) {
1288 aSeqFprm.Append(fprm);
1289 aSeqLprm.Append(aPeriod);
1290 }
1291 else {
1292 gp_Pnt P1 = newc->Value(fprm);
1293 gp_Pnt P2 = newc->Value(aPeriod);
1294 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1295 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1296
1297 if(P1.Distance(P2) > aTolDist) {
1298 Standard_Real anewpar = fprm;
94218044 1299
4abae870 1300 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
1301 lprm, Standard_False, anewpar, myContext)) {
655fddc8 1302 fprm = anewpar;
1303 }
1304 aSeqFprm.Append(fprm);
1305 aSeqLprm.Append(aPeriod);
1306 }
1307 }
1308
1309 //
1310 if((lprm - aNul) > Tolpc) {
1311 aSeqFprm.Append(aNul);
1312 aSeqLprm.Append(lprm);
1313 }
1314 else {
1315 gp_Pnt P1 = newc->Value(aNul);
1316 gp_Pnt P2 = newc->Value(lprm);
1317 Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
1318 aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
1319
1320 if(P1.Distance(P2) > aTolDist) {
1321 Standard_Real anewpar = lprm;
94218044 1322
4abae870 1323 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
1324 fprm, Standard_True, anewpar, myContext)) {
655fddc8 1325 lprm = anewpar;
1326 }
1327 aSeqFprm.Append(aNul);
1328 aSeqLprm.Append(lprm);
1329 }
1330 }
7fd59977 1331 }
1332 else {
655fddc8 1333 // usual interval
1334 aSeqFprm.Append(fprm);
1335 aSeqLprm.Append(lprm);
7fd59977 1336 }
1337 }
59495dbe 1338
7fd59977 1339 //
1340 aNbParts=aSeqFprm.Length();
1341 for (i=1; i<=aNbParts; i++) {
1342 fprm=aSeqFprm(i);
1343 lprm=aSeqLprm(i);
1344 //
1345 Standard_Real aRealEpsilon=RealEpsilon();
c6541a0c 1346 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
655fddc8 1347 //==============================================
1348 ////
1349 IntTools_Curve aCurve;
1350 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1351 aCurve.SetCurve(aTC3D);
1352 fprm=aTC3D->FirstParameter();
1353 lprm=aTC3D->LastParameter ();
1354 ////
1355 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
1356 if(myApprox1) {
1357 Handle (Geom2d_Curve) C2d;
d4b867e6 1358 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1359 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1360 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1361 myTolReached2d=Tolpc;
1362 }
1363 //
1364 aCurve.SetFirstCurve2d(C2d);
1365 }
1366 else { ////
1367 Handle(Geom2d_BSplineCurve) H1;
1368 aCurve.SetFirstCurve2d(H1);
1369 }
1370
1371
1372 if(myApprox2) {
1373 Handle (Geom2d_Curve) C2d;
d4b867e6 1374 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1375 myHS2->ChangeSurface().Surface(),newc,C2d);
655fddc8 1376 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1377 myTolReached2d=Tolpc;
1378 }
1379 //
1380 aCurve.SetSecondCurve2d(C2d);
1381 }
1382 else {
1383 Handle(Geom2d_BSplineCurve) H1;
1384 aCurve.SetSecondCurve2d(H1);
1385 }
1386 }
1387
1388 else {
1389 Handle(Geom2d_BSplineCurve) H1;
1390 aCurve.SetFirstCurve2d(H1);
1391 aCurve.SetSecondCurve2d(H1);
1392 }
1393 mySeqOfCurve.Append(aCurve);
1394 //==============================================
c6541a0c 1395 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
7fd59977 1396
1397 else {
655fddc8 1398 // on regarde si on garde
1399 //
1400 if (aNbParts==1) {
1401// if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1402 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1403 IntTools_Curve aCurve;
1404 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1405 aCurve.SetCurve(aTC3D);
1406 fprm=aTC3D->FirstParameter();
1407 lprm=aTC3D->LastParameter ();
1408
1409 if(myApprox1) {
1410 Handle (Geom2d_Curve) C2d;
d4b867e6 1411 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1412 myHS1->ChangeSurface().Surface(),newc,C2d);
655fddc8 1413 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1414 myTolReached2d=Tolpc;
1415 }
1416 //
1417 aCurve.SetFirstCurve2d(C2d);
1418 }
1419 else { ////
1420 Handle(Geom2d_BSplineCurve) H1;
1421 aCurve.SetFirstCurve2d(H1);
1422 }
1423
1424 if(myApprox2) {
1425 Handle (Geom2d_Curve) C2d;
d4b867e6 1426 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
1427 myHS2->ChangeSurface().Surface(),newc,C2d);
655fddc8 1428 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1429 myTolReached2d=Tolpc;
1430 }
1431 //
1432 aCurve.SetSecondCurve2d(C2d);
1433 }
1434 else {
1435 Handle(Geom2d_BSplineCurve) H1;
1436 aCurve.SetSecondCurve2d(H1);
1437 }
1438 mySeqOfCurve.Append(aCurve);
1439 break;
1440 }
1441 }
1442 //
1443 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1444
1445 aTwoPIdiv17=2.*M_PI/17.;
1446
1447 for (j=0; j<=17; j++) {
1448 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1449 Tol = Precision::Confusion();
1450
1451 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1452 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1453 if(ok) {
1454 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1455 }
1456 if (ok) {
1457 IntTools_Curve aCurve;
1458 aCurve.SetCurve(newc);
1459 //==============================================
1460 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1461
1462 if(myApprox1) {
1463 Handle (Geom2d_Curve) C2d;
d4b867e6 1464 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1465 myHS1->ChangeSurface().Surface(), newc, C2d);
655fddc8 1466 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1467 myTolReached2d=Tolpc;
1468 }
1469 //
1470 aCurve.SetFirstCurve2d(C2d);
1471 }
1472 else {
1473 Handle(Geom2d_BSplineCurve) H1;
1474 aCurve.SetFirstCurve2d(H1);
1475 }
1476
1477 if(myApprox2) {
1478 Handle (Geom2d_Curve) C2d;
d4b867e6 1479 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
1480 myHS2->ChangeSurface().Surface(), newc, C2d);
655fddc8 1481 if(Tolpc>myTolReached2d || myTolReached2d==0) {
1482 myTolReached2d=Tolpc;
1483 }
1484 //
1485 aCurve.SetSecondCurve2d(C2d);
1486 }
1487
1488 else {
1489 Handle(Geom2d_BSplineCurve) H1;
1490 aCurve.SetSecondCurve2d(H1);
1491 }
1492 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
1493
1494 else {
1495 Handle(Geom2d_BSplineCurve) H1;
1496 //
1497 aCurve.SetFirstCurve2d(H1);
1498 aCurve.SetSecondCurve2d(H1);
1499 }
1500 //==============================================
1501 //
1502 mySeqOfCurve.Append(aCurve);
1503 break;
1504
1505 }// end of if (ok) {
1506 }// end of for (Standard_Integer j=0; j<=17; j++)
1507 }// end of else { on regarde si on garde
59495dbe 1508 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1509 }// IntPatch_Circle: IntPatch_Ellipse:
1510 break;
1511
7fd59977 1512 case IntPatch_Analytic: {
1513 IntSurf_Quadric quad1,quad2;
1514 GeomAbs_SurfaceType typs = myHS1->Surface().GetType();
59495dbe 1515
7fd59977 1516 switch (typs) {
59495dbe 1517 case GeomAbs_Plane:
1518 quad1.SetValue(myHS1->Surface().Plane());
655fddc8 1519 break;
59495dbe 1520 case GeomAbs_Cylinder:
655fddc8 1521 quad1.SetValue(myHS1->Surface().Cylinder());
1522 break;
59495dbe 1523 case GeomAbs_Cone:
655fddc8 1524 quad1.SetValue(myHS1->Surface().Cone());
1525 break;
59495dbe 1526 case GeomAbs_Sphere:
655fddc8 1527 quad1.SetValue(myHS1->Surface().Sphere());
1528 break;
7eed5d29 1529 case GeomAbs_Torus:
1530 quad1.SetValue(myHS1->Surface().Torus());
1531 break;
59495dbe 1532 default:
655fddc8 1533 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
59495dbe 1534 }
1535
7fd59977 1536 typs = myHS2->Surface().GetType();
59495dbe 1537
7fd59977 1538 switch (typs) {
59495dbe 1539 case GeomAbs_Plane:
1540 quad2.SetValue(myHS2->Surface().Plane());
655fddc8 1541 break;
59495dbe 1542 case GeomAbs_Cylinder:
655fddc8 1543 quad2.SetValue(myHS2->Surface().Cylinder());
1544 break;
59495dbe 1545 case GeomAbs_Cone:
655fddc8 1546 quad2.SetValue(myHS2->Surface().Cone());
1547 break;
59495dbe 1548 case GeomAbs_Sphere:
655fddc8 1549 quad2.SetValue(myHS2->Surface().Sphere());
1550 break;
7eed5d29 1551 case GeomAbs_Torus:
1552 quad2.SetValue(myHS2->Surface().Torus());
1553 break;
59495dbe 1554 default:
655fddc8 1555 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
59495dbe 1556 }
7fd59977 1557 //
1558 //=========
1559 IntPatch_ALineToWLine convert (quad1, quad2);
59495dbe 1560
7fd59977 1561 if (!myApprox) {
1562 aNbParts=myLConstruct.NbParts();
1563 for (i=1; i<=aNbParts; i++) {
655fddc8 1564 myLConstruct.Part(i, fprm, lprm);
1565 Handle(IntPatch_WLine) WL =
1566 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1567 //
1568 Handle(Geom2d_BSplineCurve) H1;
1569 Handle(Geom2d_BSplineCurve) H2;
1570
1571 if(myApprox1) {
1572 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1573 }
1574
1575 if(myApprox2) {
1576 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1577 }
1578 //
1579 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
7fd59977 1580 }
1581 } // if (!myApprox)
1582
1583 else { // myApprox=TRUE
1584 GeomInt_WLApprox theapp3d;
1585 //
1586 Standard_Real tol2d = myTolApprox;
655fddc8 1587 //
7fd59977 1588 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
59495dbe 1589
7fd59977 1590 aNbParts=myLConstruct.NbParts();
1591 for (i=1; i<=aNbParts; i++) {
655fddc8 1592 myLConstruct.Part(i, fprm, lprm);
1593 Handle(IntPatch_WLine) WL =
1594 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
1595
1596 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
1597
1598 if (!theapp3d.IsDone()) {
1599 //
1600 Handle(Geom2d_BSplineCurve) H1;
1601 Handle(Geom2d_BSplineCurve) H2;
1602
1603 if(myApprox1) {
1604 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1605 }
1606
1607 if(myApprox2) {
1608 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1609 }
1610 //
1611 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1612 }
1613
1614 else {
1615 if(myApprox1 || myApprox2) {
1616 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1617 myTolReached2d = theapp3d.TolReached2d();
1618 }
1619 }
1620
1621 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1622 myTolReached3d = theapp3d.TolReached3d();
1623 }
1624
1625 Standard_Integer aNbMultiCurves, nbpoles;
1626 aNbMultiCurves=theapp3d.NbMultiCurves();
1627 for (j=1; j<=aNbMultiCurves; j++) {
1628 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1629 nbpoles = mbspc.NbPoles();
1630
1631 TColgp_Array1OfPnt tpoles(1, nbpoles);
1632 mbspc.Curve(1, tpoles);
1633 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1634 mbspc.Knots(),
1635 mbspc.Multiplicities(),
1636 mbspc.Degree());
1637
1638 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1639 Check.FixTangent(Standard_True,Standard_True);
1640 //
1641 IntTools_Curve aCurve;
1642 aCurve.SetCurve(BS);
1643
1644 if(myApprox1) {
1645 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1646 mbspc.Curve(2,tpoles2d);
1647 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1648 mbspc.Knots(),
1649 mbspc.Multiplicities(),
1650 mbspc.Degree());
1651
1652 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1653 newCheck.FixTangent(Standard_True,Standard_True);
1654 //
1655 aCurve.SetFirstCurve2d(BS2);
1656 }
1657 else {
1658 Handle(Geom2d_BSplineCurve) H1;
1659 aCurve.SetFirstCurve2d(H1);
1660 }
1661
1662 if(myApprox2) {
1663 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1664 Standard_Integer TwoOrThree;
1665 TwoOrThree=myApprox1 ? 3 : 2;
1666 mbspc.Curve(TwoOrThree, tpoles2d);
1667 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1668 mbspc.Knots(),
1669 mbspc.Multiplicities(),
1670 mbspc.Degree());
1671
1672 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1673 newCheck.FixTangent(Standard_True,Standard_True);
1674 //
1675 aCurve.SetSecondCurve2d(BS2);
1676 }
1677 else {
1678 Handle(Geom2d_BSplineCurve) H2;
1679 aCurve.SetSecondCurve2d(H2);
1680 }
1681 //
1682 mySeqOfCurve.Append(aCurve);
1683
1684 }// for (j=1; j<=aNbMultiCurves; j++) {
1685 }// else from if (!theapp3d.IsDone())
7fd59977 1686 }// for (i=1; i<=aNbParts; i++) {
1687 }// else { // myApprox=TRUE
1688 }// case IntPatch_Analytic:
59495dbe 1689 break;
7fd59977 1690
59495dbe 1691 case IntPatch_Walking:{
7fd59977 1692 Handle(IntPatch_WLine) WL =
1693 Handle(IntPatch_WLine)::DownCast(L);
1694 //
1695 Standard_Integer ifprm, ilprm;
1696 //
1697 if (!myApprox) {
1698 aNbParts = 1;
1699 if(!bAvoidLineConstructor){
655fddc8 1700 aNbParts=myLConstruct.NbParts();
7fd59977 1701 }
1702 for (i=1; i<=aNbParts; ++i) {
655fddc8 1703 Handle(Geom2d_BSplineCurve) H1, H2;
1704 Handle(Geom_Curve) aBSp;
1705 //
1706 if(bAvoidLineConstructor) {
1707 ifprm = 1;
1708 ilprm = WL->NbPnts();
1709 }
1710 else {
1711 myLConstruct.Part(i, fprm, lprm);
1712 ifprm=(Standard_Integer)fprm;
1713 ilprm=(Standard_Integer)lprm;
1714 }
1715 //
1716 if(myApprox1) {
1717 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1718 }
1719 //
1720 if(myApprox2) {
1721 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1722 }
1723 //
1724 aBSp=MakeBSpline(WL, ifprm, ilprm);
1725 IntTools_Curve aIC(aBSp, H1, H2);
1726 mySeqOfCurve.Append(aIC);
7fd59977 1727 }// for (i=1; i<=aNbParts; ++i) {
1728 }// if (!myApprox) {
1729 //
1730 else { // X
1731 Standard_Boolean bIsDecomposited;
1732 Standard_Integer nbiter, aNbSeqOfL;
4abae870 1733 Standard_Real tol2d, aTolApproxImp;
7fd59977 1734 IntPatch_SequenceOfLine aSeqOfL;
1735 GeomInt_WLApprox theapp3d;
1736 Approx_ParametrizationType aParType = Approx_ChordLength;
1737 //
1738 Standard_Boolean anApprox1 = myApprox1;
1739 Standard_Boolean anApprox2 = myApprox2;
4abae870 1740 //
1741 aTolApproxImp=1.e-5;
7fd59977 1742 tol2d = myTolApprox;
1743
1744 GeomAbs_SurfaceType typs1, typs2;
1745 typs1 = myHS1->Surface().GetType();
1746 typs2 = myHS2->Surface().GetType();
1747 Standard_Boolean anWithPC = Standard_True;
1748
1749 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
655fddc8 1750 anWithPC =
1751 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
7fd59977 1752 }
1753 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
655fddc8 1754 anWithPC =
1755 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
7fd59977 1756 }
4abae870 1757 //
7fd59977 1758 if(!anWithPC) {
4abae870 1759 myTolApprox = aTolApproxImp;//1.e-5;
655fddc8 1760 anApprox1 = Standard_False;
1761 anApprox2 = Standard_False;
1762 //
1763 tol2d = myTolApprox;
7fd59977 1764 }
655fddc8 1765
7fd59977 1766 if(myHS1 == myHS2) {
655fddc8 1767 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1768 rejectSurface = Standard_True;
7fd59977 1769 }
1770 else {
655fddc8 1771 if(reApprox && !rejectSurface)
1772 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1773 else {
1774 Standard_Integer iDegMax, iDegMin, iNbIter;
1775 //
1776 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1777 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType);
1778 }
7fd59977 1779 }
1780 //
1781 Standard_Real aReachedTol = Precision::Confusion();
1782 bIsDecomposited=DecompositionOfWLine(WL,
655fddc8 1783 myHS1,
1784 myHS2,
1785 myFace1,
1786 myFace2,
1787 myLConstruct,
1788 bAvoidLineConstructor,
1789 aSeqOfL,
1790 aReachedTol,
1791 myContext);
4abae870 1792 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) ) {
655fddc8 1793 myTolReached3d = aReachedTol;
4abae870 1794 }
7fd59977 1795 //
1796 aNbSeqOfL=aSeqOfL.Length();
1797 //
1798 if (bIsDecomposited) {
655fddc8 1799 nbiter=aNbSeqOfL;
7fd59977 1800 }
1801 else {
655fddc8 1802 nbiter=1;
1803 aNbParts=1;
1804 if (!bAvoidLineConstructor) {
1805 aNbParts=myLConstruct.NbParts();
1806 nbiter=aNbParts;
1807 }
7fd59977 1808 }
1809 //
7fd59977 1810 for(i = 1; i <= nbiter; ++i) {
655fddc8 1811 if(bIsDecomposited) {
1812 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1813 ifprm = 1;
1814 ilprm = WL->NbPnts();
1815 }
1816 else {
1817 if(bAvoidLineConstructor) {
1818 ifprm = 1;
1819 ilprm = WL->NbPnts();
1820 }
1821 else {
1822 myLConstruct.Part(i, fprm, lprm);
1823 ifprm = (Standard_Integer)fprm;
1824 ilprm = (Standard_Integer)lprm;
1825 }
1826 }
1827 //-- lbr :
1828 //-- Si une des surfaces est un plan , on approxime en 2d
1829 //-- sur cette surface et on remonte les points 2d en 3d.
1830 if(typs1 == GeomAbs_Plane) {
1831 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1832 }
1833 else if(typs2 == GeomAbs_Plane) {
1834 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1835 }
1836 else {
1837 //
1838 if (myHS1 != myHS2){
1839 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1840 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1841
1842 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType);
1843
1844 Standard_Boolean bUseSurfaces;
1845 bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1846 if (bUseSurfaces) {
1847 // ######
1848 rejectSurface = Standard_True;
1849 // ######
1850 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1851 }
1852 }
1853 }
1854 //
1855 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1856 }
1857 //
94218044 1858 if (!theapp3d.IsDone()) {
655fddc8 1859 Handle(Geom2d_BSplineCurve) H1;
94218044 1860 Handle(Geom2d_BSplineCurve) H2;
655fddc8 1861 //
1862 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
4abae870 1863 //
655fddc8 1864 if(myApprox1) {
1865 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1866 }
4abae870 1867 //
655fddc8 1868 if(myApprox2) {
1869 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1870 }
1871 //
1872 IntTools_Curve aIC(aBSp, H1, H2);
1873 mySeqOfCurve.Append(aIC);
1874 }
1875
1876 else {
1877 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1878 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1879 myTolReached2d = theapp3d.TolReached2d();
1880 }
1881 }
1882 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
1883 myTolReached3d = myTolReached2d;
1884 //
1885 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
1886 if (myTolReached3d<1.e-6) {
1887 myTolReached3d = theapp3d.TolReached3d();
1888 myTolReached3d=1.e-6;
1889 }
1890 }
1891 }
1892 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
1893 myTolReached3d = theapp3d.TolReached3d();
1894 }
1895
1896 Standard_Integer aNbMultiCurves, nbpoles;
1897 aNbMultiCurves=theapp3d.NbMultiCurves();
1898 for (j=1; j<=aNbMultiCurves; j++) {
1899 if(typs1 == GeomAbs_Plane) {
1900 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1901 nbpoles = mbspc.NbPoles();
1902
1903 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1904 TColgp_Array1OfPnt tpoles(1,nbpoles);
1905
1906 mbspc.Curve(1,tpoles2d);
1907 const gp_Pln& Pln = myHS1->Surface().Plane();
1908 //
1909 Standard_Integer ik;
1910 for(ik = 1; ik<= nbpoles; ik++) {
1911 tpoles.SetValue(ik,
1912 ElSLib::Value(tpoles2d.Value(ik).X(),
1913 tpoles2d.Value(ik).Y(),
1914 Pln));
1915 }
1916 //
1917 Handle(Geom_BSplineCurve) BS =
1918 new Geom_BSplineCurve(tpoles,
1919 mbspc.Knots(),
1920 mbspc.Multiplicities(),
1921 mbspc.Degree());
1922 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1923 Check.FixTangent(Standard_True, Standard_True);
1924 //
1925 IntTools_Curve aCurve;
1926 aCurve.SetCurve(BS);
1927
1928 if(myApprox1) {
1929 Handle(Geom2d_BSplineCurve) BS1 =
1930 new Geom2d_BSplineCurve(tpoles2d,
1931 mbspc.Knots(),
1932 mbspc.Multiplicities(),
1933 mbspc.Degree());
1934 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1935 Check1.FixTangent(Standard_True,Standard_True);
1936 //
1937 // ############################################
1938 if(!rejectSurface && !reApprox) {
1939 Standard_Boolean isValid = IsCurveValid(BS1);
1940 if(!isValid) {
1941 reApprox = Standard_True;
1942 goto reapprox;
1943 }
1944 }
1945 // ############################################
1946 aCurve.SetFirstCurve2d(BS1);
1947 }
1948 else {
1949 Handle(Geom2d_BSplineCurve) H1;
1950 aCurve.SetFirstCurve2d(H1);
1951 }
1952
1953 if(myApprox2) {
1954 mbspc.Curve(2, tpoles2d);
1955
1956 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1957 mbspc.Knots(),
1958 mbspc.Multiplicities(),
1959 mbspc.Degree());
1960 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1961 newCheck.FixTangent(Standard_True,Standard_True);
1962
1963 // ###########################################
1964 if(!rejectSurface && !reApprox) {
1965 Standard_Boolean isValid = IsCurveValid(BS2);
1966 if(!isValid) {
1967 reApprox = Standard_True;
1968 goto reapprox;
1969 }
1970 }
1971 // ###########################################
1972 //
1973 aCurve.SetSecondCurve2d(BS2);
1974 }
1975 else {
1976 Handle(Geom2d_BSplineCurve) H2;
1977 //
1978 aCurve.SetSecondCurve2d(H2);
1979 }
1980 //
1981 mySeqOfCurve.Append(aCurve);
4abae870 1982 }//if(typs1 == GeomAbs_Plane) {
655fddc8 1983
1984 else if(typs2 == GeomAbs_Plane) {
1985 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1986 nbpoles = mbspc.NbPoles();
1987
1988 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1989 TColgp_Array1OfPnt tpoles(1,nbpoles);
1990 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
1991 const gp_Pln& Pln = myHS2->Surface().Plane();
1992 //
1993 Standard_Integer ik;
1994 for(ik = 1; ik<= nbpoles; ik++) {
1995 tpoles.SetValue(ik,
1996 ElSLib::Value(tpoles2d.Value(ik).X(),
1997 tpoles2d.Value(ik).Y(),
1998 Pln));
1999
2000 }
2001 //
2002 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
2003 mbspc.Knots(),
2004 mbspc.Multiplicities(),
2005 mbspc.Degree());
2006 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2007 Check.FixTangent(Standard_True,Standard_True);
2008 //
2009 IntTools_Curve aCurve;
2010 aCurve.SetCurve(BS);
2011
2012 if(myApprox2) {
2013 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
2014 mbspc.Knots(),
2015 mbspc.Multiplicities(),
2016 mbspc.Degree());
2017 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
2018 Check1.FixTangent(Standard_True,Standard_True);
2019 //
2020 // ###########################################
2021 if(!rejectSurface && !reApprox) {
2022 Standard_Boolean isValid = IsCurveValid(BS1);
2023 if(!isValid) {
2024 reApprox = Standard_True;
2025 goto reapprox;
2026 }
2027 }
989341c5 2028 // ###########################################
2029 bPCurvesOk = CheckPCurve(BS1, myFace2);
655fddc8 2030 aCurve.SetSecondCurve2d(BS1);
2031 }
2032 else {
2033 Handle(Geom2d_BSplineCurve) H2;
2034 aCurve.SetSecondCurve2d(H2);
2035 }
2036
2037 if(myApprox1) {
2038 mbspc.Curve(1,tpoles2d);
2039 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2040 mbspc.Knots(),
2041 mbspc.Multiplicities(),
2042 mbspc.Degree());
2043 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
2044 Check2.FixTangent(Standard_True,Standard_True);
2045 //
2046 // ###########################################
2047 if(!rejectSurface && !reApprox) {
2048 Standard_Boolean isValid = IsCurveValid(BS2);
2049 if(!isValid) {
2050 reApprox = Standard_True;
2051 goto reapprox;
2052 }
2053 }
989341c5 2054 // ###########################################
2055 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1);
655fddc8 2056 aCurve.SetFirstCurve2d(BS2);
2057 }
2058 else {
2059 Handle(Geom2d_BSplineCurve) H1;
2060 //
2061 aCurve.SetFirstCurve2d(H1);
2062 }
2063 //
989341c5 2064 //if points of the pcurves are out of the faces bounds
2065 //create 3d and 2d curves without approximation
2066 if (!bPCurvesOk) {
2067 Handle(Geom2d_BSplineCurve) H1, H2;
655fddc8 2068 bPCurvesOk = Standard_True;
2069 //
989341c5 2070 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
59495dbe 2071
989341c5 2072 if(myApprox1) {
2073 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
655fddc8 2074 bPCurvesOk = CheckPCurve(H1, myFace1);
989341c5 2075 }
59495dbe 2076
989341c5 2077 if(myApprox2) {
2078 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
655fddc8 2079 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2);
989341c5 2080 }
2081 //
655fddc8 2082 //if pcurves created without approximation are out of the
2083 //faces bounds, use approximated 3d and 2d curves
2084 if (bPCurvesOk) {
2085 IntTools_Curve aIC(aBSp, H1, H2);
2086 mySeqOfCurve.Append(aIC);
2087 } else {
2088 mySeqOfCurve.Append(aCurve);
2089 }
989341c5 2090 } else {
2091 mySeqOfCurve.Append(aCurve);
2092 }
4abae870 2093 }// else if(typs2 == GeomAbs_Plane)
2094 //
2095 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
2096 Standard_Boolean bIsValid1, bIsValid2;
2097 Handle(Geom_BSplineCurve) BS;
2098 Handle(Geom2d_BSplineCurve) aH2D;
2099 IntTools_Curve aCurve;
2100 //
2101 bIsValid1=Standard_True;
2102 bIsValid2=Standard_True;
2103 //
655fddc8 2104 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2105 nbpoles = mbspc.NbPoles();
2106 TColgp_Array1OfPnt tpoles(1,nbpoles);
2107 mbspc.Curve(1,tpoles);
4abae870 2108 BS=new Geom_BSplineCurve(tpoles,
655fddc8 2109 mbspc.Knots(),
2110 mbspc.Multiplicities(),
2111 mbspc.Degree());
2112 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2113 Check.FixTangent(Standard_True,Standard_True);
2114 //
2115 aCurve.SetCurve(BS);
4abae870 2116 aCurve.SetFirstCurve2d(aH2D);
2117 aCurve.SetSecondCurve2d(aH2D);
2118 //
655fddc8 2119 if(myApprox1) {
2120 if(anApprox1) {
4abae870 2121 Handle(Geom2d_BSplineCurve) BS1;
655fddc8 2122 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2123 mbspc.Curve(2,tpoles2d);
4abae870 2124 //
2125 BS1=new Geom2d_BSplineCurve(tpoles2d,
655fddc8 2126 mbspc.Knots(),
2127 mbspc.Multiplicities(),
2128 mbspc.Degree());
2129 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
2130 newCheck.FixTangent(Standard_True,Standard_True);
2131 //
4abae870 2132 if (!reApprox) {
2133 bIsValid1=CheckPCurve(BS1, myFace1);
2134 }
2135 //
655fddc8 2136 aCurve.SetFirstCurve2d(BS1);
2137 }
2138 else {
2139 Handle(Geom2d_BSplineCurve) BS1;
2140 fprm = BS->FirstParameter();
2141 lprm = BS->LastParameter();
2142
2143 Handle(Geom2d_Curve) C2d;
2144 Standard_Real aTol = myTolApprox;
d4b867e6 2145 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
2146 myHS1->ChangeSurface().Surface(), BS, C2d);
655fddc8 2147 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2148 aCurve.SetFirstCurve2d(BS1);
2149 }
4abae870 2150 } // if(myApprox1) {
655fddc8 2151 //
2152 if(myApprox2) {
2153 if(anApprox2) {
4abae870 2154 Handle(Geom2d_BSplineCurve) BS2;
655fddc8 2155 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2156 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
4abae870 2157 BS2=new Geom2d_BSplineCurve(tpoles2d,
655fddc8 2158 mbspc.Knots(),
2159 mbspc.Multiplicities(),
2160 mbspc.Degree());
2161 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
2162 newCheck.FixTangent(Standard_True,Standard_True);
2163 //
4abae870 2164 if (!reApprox) {
2165 bIsValid2=CheckPCurve(BS2, myFace2);
2166 }
655fddc8 2167 aCurve.SetSecondCurve2d(BS2);
2168 }
2169 else {
2170 Handle(Geom2d_BSplineCurve) BS2;
2171 fprm = BS->FirstParameter();
2172 lprm = BS->LastParameter();
2173
2174 Handle(Geom2d_Curve) C2d;
2175 Standard_Real aTol = myTolApprox;
d4b867e6 2176 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
2177 myHS2->ChangeSurface().Surface(), BS, C2d);
655fddc8 2178 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2179 aCurve.SetSecondCurve2d(BS2);
2180 }
4abae870 2181 } //if(myApprox2) {
2182 if (!bIsValid1 || !bIsValid2) {
2183 myTolApprox=aTolApproxImp;//1.e-5;
2184 tol2d = myTolApprox;
2185 reApprox = Standard_True;
2186 goto reapprox;
655fddc8 2187 }
2188 //
2189 mySeqOfCurve.Append(aCurve);
2190 }
2191 }
2192 }
7fd59977 2193 }
2194 }// else { // X
2195 }// case IntPatch_Walking:{
59495dbe 2196 break;
2197
7fd59977 2198 case IntPatch_Restriction:
d4b867e6 2199 {
2200 GeomAbs_SurfaceType typS1 = myHS1->Surface().GetType();
2201 GeomAbs_SurfaceType typS2 = myHS2->Surface().GetType();
2202 Standard_Boolean isAnalS1 = Standard_False;
2203 switch (typS1)
2204 {
2205 case GeomAbs_Plane:
2206 case GeomAbs_Cylinder:
2207 case GeomAbs_Sphere:
2208 case GeomAbs_Cone:
2209 case GeomAbs_Torus: isAnalS1 = Standard_True; break;
2210 default: break;
2211 }
7fd59977 2212
d4b867e6 2213 Standard_Integer isAnalS2 = Standard_False;
2214 switch (typS2)
2215 {
2216 case GeomAbs_Plane:
2217 case GeomAbs_Cylinder:
2218 case GeomAbs_Sphere:
2219 case GeomAbs_Cone:
2220 case GeomAbs_Torus: isAnalS2 = Standard_True; break;
2221 default: break;
2222 }
7fd59977 2223
d4b867e6 2224 Handle(IntPatch_RLine) RL =
2225 Handle(IntPatch_RLine)::DownCast(L);
2226 Handle(Geom_Curve) aC3d;
2227 Handle(Geom2d_Curve) aC2d1, aC2d2;
2228 Standard_Real aTolReached;
2229 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
2230 aC2d1, aC2d2, aTolReached);
2231
2232 if(aC3d.IsNull())
2233 break;
2234
2235 Bnd_Box2d aBox1, aBox2;
2236
2237 const Standard_Real aU1f = myHS1->FirstUParameter(),
2238 aV1f = myHS1->FirstVParameter(),
2239 aU1l = myHS1->LastUParameter(),
2240 aV1l = myHS1->LastVParameter();
2241 const Standard_Real aU2f = myHS2->FirstUParameter(),
2242 aV2f = myHS2->FirstVParameter(),
2243 aU2l = myHS2->LastUParameter(),
2244 aV2l = myHS2->LastVParameter();
2245
2246 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
2247 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
2248 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
2249 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
2250
2251 GeomInt_VectorOfReal anArrayOfParameters;
655fddc8 2252
d4b867e6 2253 //We consider here that the intersection line is same-parameter-line
2254 anArrayOfParameters.Append(aC3d->FirstParameter());
2255 anArrayOfParameters.Append(aC3d->LastParameter());
2256
2257 GeomInt_IntSS::
2258 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
2259
2260 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
2261
2262 //Trim RLine found.
2263 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
2264 {
2265 const Standard_Real aParF = anArrayOfParameters(anInd),
2266 aParL = anArrayOfParameters(anInd+1);
2267
2268 if((aParL - aParF) <= Precision::PConfusion())
2269 continue;
2270
2271 const Standard_Real aPar = 0.5*(aParF + aParL);
2272 gp_Pnt2d aPt;
2273
2274 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
2275 if(!aC2d1.IsNull())
2276 {
2277 aC2d1->D0(aPar, aPt);
2278
2279 if(aBox1.IsOut(aPt))
2280 continue;
2281
2282 if(myApprox1)
2283 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
4abae870 2284 }
d4b867e6 2285
2286 if(!aC2d2.IsNull())
2287 {
2288 aC2d2->D0(aPar, aPt);
2289
2290 if(aBox2.IsOut(aPt))
2291 continue;
2292
2293 if(myApprox2)
2294 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
2295 }
2296
2297 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
2298
2299 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
2300 mySeqOfCurve.Append(aIC);
7fd59977 2301 }
2302 }
d4b867e6 2303 break;
2304 default:
2305 break;
2306
7fd59977 2307 }
7fd59977 2308}
2309
2310//=======================================================================
2311//function : Parameters
2312//purpose :
2313//=======================================================================
2314 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
655fddc8 2315 const Handle(GeomAdaptor_HSurface)& HS2,
2316 const gp_Pnt& Ptref,
2317 Standard_Real& U1,
2318 Standard_Real& V1,
2319 Standard_Real& U2,
2320 Standard_Real& V2)
7fd59977 2321{
2322
2323 IntSurf_Quadric quad1,quad2;
2324 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2325
2326 switch (typs) {
2327 case GeomAbs_Plane:
2328 quad1.SetValue(HS1->Surface().Plane());
2329 break;
2330 case GeomAbs_Cylinder:
2331 quad1.SetValue(HS1->Surface().Cylinder());
2332 break;
2333 case GeomAbs_Cone:
2334 quad1.SetValue(HS1->Surface().Cone());
2335 break;
2336 case GeomAbs_Sphere:
2337 quad1.SetValue(HS1->Surface().Sphere());
2338 break;
7eed5d29 2339 case GeomAbs_Torus:
2340 quad1.SetValue(HS1->Surface().Torus());
2341 break;
7fd59977 2342 default:
2343 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2344 }
2345
2346 typs = HS2->Surface().GetType();
2347 switch (typs) {
2348 case GeomAbs_Plane:
2349 quad2.SetValue(HS2->Surface().Plane());
2350 break;
2351 case GeomAbs_Cylinder:
2352 quad2.SetValue(HS2->Surface().Cylinder());
2353 break;
2354 case GeomAbs_Cone:
2355 quad2.SetValue(HS2->Surface().Cone());
2356 break;
2357 case GeomAbs_Sphere:
2358 quad2.SetValue(HS2->Surface().Sphere());
2359 break;
7eed5d29 2360 case GeomAbs_Torus:
2361 quad2.SetValue(HS2->Surface().Torus());
2362 break;
7fd59977 2363 default:
2364 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2365 }
2366
2367 quad1.Parameters(Ptref,U1,V1);
2368 quad2.Parameters(Ptref,U2,V2);
2369}
2370
2371//=======================================================================
2372//function : MakeBSpline
2373//purpose :
2374//=======================================================================
2375Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
655fddc8 2376 const Standard_Integer ideb,
2377 const Standard_Integer ifin)
7fd59977 2378{
2379 Standard_Integer i,nbpnt = ifin-ideb+1;
2380 TColgp_Array1OfPnt poles(1,nbpnt);
2381 TColStd_Array1OfReal knots(1,nbpnt);
2382 TColStd_Array1OfInteger mults(1,nbpnt);
2383 Standard_Integer ipidebm1;
2384 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2385 poles(i) = WL->Point(ipidebm1).Value();
2386 mults(i) = 1;
2387 knots(i) = i-1;
2388 }
2389 mults(1) = mults(nbpnt) = 2;
2390 return
2391 new Geom_BSplineCurve(poles,knots,mults,1);
2392}
2393//
2394
2395//=======================================================================
2396//function : MakeBSpline2d
2397//purpose :
2398//=======================================================================
2399Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
655fddc8 2400 const Standard_Integer ideb,
2401 const Standard_Integer ifin,
2402 const Standard_Boolean onFirst)
7fd59977 2403{
2404 Standard_Integer i, nbpnt = ifin-ideb+1;
2405 TColgp_Array1OfPnt2d poles(1,nbpnt);
2406 TColStd_Array1OfReal knots(1,nbpnt);
2407 TColStd_Array1OfInteger mults(1,nbpnt);
2408 Standard_Integer ipidebm1;
2409
2410 for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) {
2411 Standard_Real U, V;
2412 if(onFirst)
655fddc8 2413 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
7fd59977 2414 else
655fddc8 2415 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
7fd59977 2416 poles(i).SetCoord(U, V);
2417 mults(i) = 1;
2418 knots(i) = i-1;
2419 }
2420 mults(1) = mults(nbpnt) = 2;
2421
2422 return new Geom2d_BSplineCurve(poles,knots,mults,1);
2423}
2424//=======================================================================
2425//function : PrepareLines3D
2426//purpose :
2427//=======================================================================
a9f7b6b5 2428 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
7fd59977 2429{
a9f7b6b5
P
2430 Standard_Integer i, aNbCurves;
2431 GeomAbs_SurfaceType aType1, aType2;
7fd59977 2432 IntTools_SequenceOfCurves aNewCvs;
7fd59977 2433 //
a9f7b6b5 2434 // 1. Treatment closed curves
7fd59977 2435 aNbCurves=mySeqOfCurve.Length();
a9f7b6b5 2436 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2437 const IntTools_Curve& aIC=mySeqOfCurve(i);
7fd59977 2438 //
a9f7b6b5
P
2439 if (bToSplit) {
2440 Standard_Integer j, aNbC;
2441 IntTools_SequenceOfCurves aSeqCvs;
2442 //
2443 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2444 if (aNbC) {
655fddc8 2445 for (j=1; j<=aNbC; ++j) {
2446 const IntTools_Curve& aICNew=aSeqCvs(j);
2447 aNewCvs.Append(aICNew);
2448 }
a9f7b6b5
P
2449 }
2450 else {
655fddc8 2451 aNewCvs.Append(aIC);
7fd59977 2452 }
2453 }
7fd59977 2454 else {
2455 aNewCvs.Append(aIC);
2456 }
2457 }
2458 //
2459 // 2. Plane\Cone intersection when we had 4 curves
a9f7b6b5
P
2460 aType1=myHS1->GetType();
2461 aType2=myHS2->GetType();
2462 aNbCurves=aNewCvs.Length();
2463 //
7fd59977 2464 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2465 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
7fd59977 2466 if (aNbCurves==4) {
a9f7b6b5
P
2467 GeomAbs_CurveType aCType1;
2468 //
2469 aCType1=aNewCvs(1).Type();
7fd59977 2470 if (aCType1==GeomAbs_Line) {
655fddc8 2471 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2472 //
2473 for (i=1; i<=aNbCurves; ++i) {
2474 const IntTools_Curve& aIC=aNewCvs(i);
2475 aSeqIn.Append(aIC);
2476 }
2477 //
2478 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2479 //
2480 aNewCvs.Clear();
2481 aNbCurves=aSeqOut.Length();
2482 for (i=1; i<=aNbCurves; ++i) {
2483 const IntTools_Curve& aIC=aSeqOut(i);
2484 aNewCvs.Append(aIC);
2485 }
7fd59977 2486 }
2487 }
a9f7b6b5 2488 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
7fd59977 2489 //
2490 // 3. Fill mySeqOfCurve
2491 mySeqOfCurve.Clear();
2492 aNbCurves=aNewCvs.Length();
a9f7b6b5 2493 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2494 const IntTools_Curve& aIC=aNewCvs(i);
2495 mySeqOfCurve.Append(aIC);
2496 }
7fd59977 2497}
7fd59977 2498//=======================================================================
2499//function : CorrectSurfaceBoundaries
2500//purpose :
2501//=======================================================================
59495dbe 2502 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
c002793b 2503 const Standard_Real theTolerance,
2504 Standard_Real& theumin,
2505 Standard_Real& theumax,
2506 Standard_Real& thevmin,
2507 Standard_Real& thevmax)
7fd59977 2508{
2509 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2510 Standard_Real uinf, usup, vinf, vsup, delta;
2511 GeomAbs_SurfaceType aType;
2512 Handle(Geom_Surface) aSurface;
2513 //
2514 aSurface = BRep_Tool::Surface(theFace);
2515 aSurface->Bounds(uinf, usup, vinf, vsup);
2516 delta = theTolerance;
2517 enlarge = Standard_False;
2518 //
2519 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2520 //
2521 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2522 Handle(Geom_Surface) aBasisSurface =
2523 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2524
2525 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2526 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2527 return;
2528 }
2529 }
2530 //
2531 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2532 Handle(Geom_Surface) aBasisSurface =
2533 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2534
2535 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2536 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2537 return;
2538 }
2539 }
2540 //
2541 isuperiodic = anAdaptorSurface.IsUPeriodic();
2542 isvperiodic = anAdaptorSurface.IsVPeriodic();
2543 //
2544 aType=anAdaptorSurface.GetType();
2545 if((aType==GeomAbs_BezierSurface) ||
2546 (aType==GeomAbs_BSplineSurface) ||
2547 (aType==GeomAbs_SurfaceOfExtrusion) ||
c002793b 2548 (aType==GeomAbs_SurfaceOfRevolution) ||
2549 (aType==GeomAbs_Cylinder)) {
7fd59977 2550 enlarge=Standard_True;
2551 }
2552 //
2553 if(!isuperiodic && enlarge) {
2554
d4b867e6 2555 if(!Precision::IsInfinite(theumin) &&
2556 ((theumin - uinf) > delta))
7fd59977 2557 theumin -= delta;
2558 else {
2559 theumin = uinf;
2560 }
2561
d4b867e6 2562 if(!Precision::IsInfinite(theumax) &&
2563 ((usup - theumax) > delta))
7fd59977 2564 theumax += delta;
2565 else
2566 theumax = usup;
2567 }
2568 //
2569 if(!isvperiodic && enlarge) {
d4b867e6 2570 if(!Precision::IsInfinite(thevmin) &&
2571 ((thevmin - vinf) > delta)) {
7fd59977 2572 thevmin -= delta;
2573 }
2574 else {
2575 thevmin = vinf;
2576 }
d4b867e6 2577 if(!Precision::IsInfinite(thevmax) &&
2578 ((vsup - thevmax) > delta)) {
7fd59977 2579 thevmax += delta;
2580 }
2581 else {
2582 thevmax = vsup;
2583 }
2584 }
2585 //
2586 {
2587 Standard_Integer aNbP;
2588 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2589 //
2590 aTolPA=Precision::Angular();
2591 // U
2592 if (isuperiodic) {
2593 aXP=anAdaptorSurface.UPeriod();
2594 dXfact=theumax-theumin;
2595 if (dXfact-aTolPA>aXP) {
655fddc8 2596 aXmid=0.5*(theumax+theumin);
2597 aNbP=RealToInt(aXmid/aXP);
2598 if (aXmid<0.) {
2599 aNbP=aNbP-1;
2600 }
2601 aX1=aNbP*aXP;
2602 if (theumin>aTolPA) {
2603 aX1=theumin+aNbP*aXP;
2604 }
2605 aX2=aX1+aXP;
2606 if (theumin<aX1) {
2607 theumin=aX1;
2608 }
2609 if (theumax>aX2) {
2610 theumax=aX2;
2611 }
7fd59977 2612 }
2613 }
2614 // V
2615 if (isvperiodic) {
2616 aXP=anAdaptorSurface.VPeriod();
2617 dXfact=thevmax-thevmin;
2618 if (dXfact-aTolPA>aXP) {
655fddc8 2619 aXmid=0.5*(thevmax+thevmin);
2620 aNbP=RealToInt(aXmid/aXP);
2621 if (aXmid<0.) {
2622 aNbP=aNbP-1;
2623 }
2624 aX1=aNbP*aXP;
2625 if (thevmin>aTolPA) {
2626 aX1=thevmin+aNbP*aXP;
2627 }
2628 aX2=aX1+aXP;
2629 if (thevmin<aX1) {
2630 thevmin=aX1;
2631 }
2632 if (thevmax>aX2) {
2633 thevmax=aX2;
2634 }
7fd59977 2635 }
2636 }
2637 }
2638 //
2639 if(isuperiodic || isvperiodic) {
2640 Standard_Boolean correct = Standard_False;
2641 Standard_Boolean correctU = Standard_False;
2642 Standard_Boolean correctV = Standard_False;
2643 Bnd_Box2d aBox;
2644 TopExp_Explorer anExp;
2645
2646 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2647 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
655fddc8 2648 correct = Standard_True;
2649 Standard_Real f, l;
2650 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2651
2652 for(Standard_Integer i = 0; i < 2; i++) {
2653 if(i==0) {
2654 anEdge.Orientation(TopAbs_FORWARD);
2655 }
2656 else {
2657 anEdge.Orientation(TopAbs_REVERSED);
2658 }
2659 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2660
2661 if(aCurve.IsNull()) {
2662 correct = Standard_False;
2663 break;
2664 }
2665 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2666
2667 if(aLine.IsNull()) {
2668 correct = Standard_False;
2669 break;
2670 }
2671 gp_Dir2d anUDir(1., 0.);
2672 gp_Dir2d aVDir(0., 1.);
2673 Standard_Real anAngularTolerance = Precision::Angular();
2674
2675 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2676 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2677
2678 gp_Pnt2d pp1 = aCurve->Value(f);
2679 aBox.Add(pp1);
2680 gp_Pnt2d pp2 = aCurve->Value(l);
2681 aBox.Add(pp2);
2682 }
2683 if(!correct)
2684 break;
7fd59977 2685 }
2686 }
2687
2688 if(correct) {
2689 Standard_Real umin, vmin, umax, vmax;
2690 aBox.Get(umin, vmin, umax, vmax);
2691
2692 if(isuperiodic && correctU) {
655fddc8 2693
2694 if(theumin < umin)
2695 theumin = umin;
2696
2697 if(theumax > umax) {
2698 theumax = umax;
2699 }
7fd59977 2700 }
2701 if(isvperiodic && correctV) {
655fddc8 2702
2703 if(thevmin < vmin)
2704 thevmin = vmin;
2705 if(thevmax > vmax)
2706 thevmax = vmax;
7fd59977 2707 }
2708 }
2709 }
2710}
2711//
2712//
2713// The block is dedicated to determine whether WLine [ifprm, ilprm]
2714// crosses the degenerated zone on each given surface or not.
2715// If Yes -> We will not use info about surfaces during approximation
8e0115e4 2716// because inside degenerated zone of the surface the approx. algo.
7fd59977 2717// uses wrong values of normal, etc., and resulting curve will have
2718// oscillations that we would not like to have.
7fd59977 2719
2720
4e57c75e 2721
7fd59977 2722static
2723 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
655fddc8 2724 const Handle(Geom_Surface)& aS,
2725 const Standard_Integer iDir);
7fd59977 2726static
2727 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
655fddc8 2728 const TopoDS_Face& aF1,
2729 const TopoDS_Face& aF2);
7fd59977 2730//=======================================================================
2731//function : NotUseSurfacesForApprox
2732//purpose :
2733//=======================================================================
2734Standard_Boolean NotUseSurfacesForApprox(const TopoDS_Face& aF1,
655fddc8 2735 const TopoDS_Face& aF2,
2736 const Handle(IntPatch_WLine)& WL,
2737 const Standard_Integer ifprm,
2738 const Standard_Integer ilprm)
7fd59977 2739{
2740 Standard_Boolean bPInDZ;
2741
2742 Handle(IntSurf_LineOn2S) aLineOn2S=WL->Curve();
2743
2744 const IntSurf_PntOn2S& aP2Sfprm=aLineOn2S->Value(ifprm);
2745 bPInDZ=IsPointInDegeneratedZone(aP2Sfprm, aF1, aF2);
2746 if (bPInDZ) {
2747 return bPInDZ;
2748 }
2749
2750 const IntSurf_PntOn2S& aP2Slprm=aLineOn2S->Value(ilprm);
2751 bPInDZ=IsPointInDegeneratedZone(aP2Slprm, aF1, aF2);
2752
2753 return bPInDZ;
2754}
2755//=======================================================================
2756//function : IsPointInDegeneratedZone
2757//purpose :
2758//=======================================================================
2759Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
655fddc8 2760 const TopoDS_Face& aF1,
2761 const TopoDS_Face& aF2)
2762
7fd59977 2763{
2764 Standard_Boolean bFlag=Standard_True;
2765 Standard_Real US11, US12, VS11, VS12, US21, US22, VS21, VS22;
2766 Standard_Real U1, V1, U2, V2, aDelta, aD;
2767 gp_Pnt2d aP2d;
2768
2769 Handle(Geom_Surface)aS1 = BRep_Tool::Surface(aF1);
2770 aS1->Bounds(US11, US12, VS11, VS12);
2771 GeomAdaptor_Surface aGAS1(aS1);
2772
2773 Handle(Geom_Surface)aS2 = BRep_Tool::Surface(aF2);
2774 aS1->Bounds(US21, US22, VS21, VS22);
2775 GeomAdaptor_Surface aGAS2(aS2);
2776 //
2777 //const gp_Pnt& aP=aP2S.Value();
2778 aP2S.Parameters(U1, V1, U2, V2);
2779 //
2780 aDelta=1.e-7;
2781 // Check on Surf 1
2782 aD=aGAS1.UResolution(aDelta);
2783 aP2d.SetCoord(U1, V1);
2784 if (fabs(U1-US11) < aD) {
2785 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2786 if (bFlag) {
2787 return bFlag;
2788 }
2789 }
2790 if (fabs(U1-US12) < aD) {
2791 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2792 if (bFlag) {
2793 return bFlag;
2794 }
2795 }
2796 aD=aGAS1.VResolution(aDelta);
2797 if (fabs(V1-VS11) < aDelta) {
2798 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2799 if (bFlag) {
2800 return bFlag;
2801 }
2802 }
2803 if (fabs(V1-VS12) < aDelta) {
2804 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2805 if (bFlag) {
2806 return bFlag;
2807 }
2808 }
2809 // Check on Surf 2
2810 aD=aGAS2.UResolution(aDelta);
2811 aP2d.SetCoord(U2, V2);
2812 if (fabs(U2-US21) < aDelta) {
2813 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2814 if (bFlag) {
2815 return bFlag;
2816 }
2817 }
2818 if (fabs(U2-US22) < aDelta) {
2819 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2820 if (bFlag) {
2821 return bFlag;
2822 }
2823 }
2824 aD=aGAS2.VResolution(aDelta);
2825 if (fabs(V2-VS21) < aDelta) {
2826 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2827 if (bFlag) {
2828 return bFlag;
2829 }
2830 }
2831 if (fabs(V2-VS22) < aDelta) {
2832 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2833 if (bFlag) {
2834 return bFlag;
2835 }
2836 }
2837 return !bFlag;
2838}
2839
2840//=======================================================================
2841//function : IsDegeneratedZone
2842//purpose :
2843//=======================================================================
2844Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
655fddc8 2845 const Handle(Geom_Surface)& aS,
2846 const Standard_Integer iDir)
7fd59977 2847{
2848 Standard_Boolean bFlag=Standard_True;
2849 Standard_Real US1, US2, VS1, VS2, dY, dX, d1, d2, dD;
2850 Standard_Real aXm, aYm, aXb, aYb, aXe, aYe;
2851 aS->Bounds(US1, US2, VS1, VS2);
2852
2853 gp_Pnt aPm, aPb, aPe;
2854
2855 aXm=aP2d.X();
2856 aYm=aP2d.Y();
2857
2858 aS->D0(aXm, aYm, aPm);
2859
2860 dX=1.e-5;
2861 dY=1.e-5;
2862 dD=1.e-12;
2863
2864 if (iDir==1) {
2865 aXb=aXm;
2866 aXe=aXm;
2867 aYb=aYm-dY;
2868 if (aYb < VS1) {
2869 aYb=VS1;
2870 }
2871 aYe=aYm+dY;
2872 if (aYe > VS2) {
2873 aYe=VS2;
2874 }
2875 aS->D0(aXb, aYb, aPb);
2876 aS->D0(aXe, aYe, aPe);
2877
2878 d1=aPm.Distance(aPb);
2879 d2=aPm.Distance(aPe);
2880 if (d1 < dD && d2 < dD) {
2881 return bFlag;
2882 }
2883 return !bFlag;
2884 }
2885 //
2886 else if (iDir==2) {
2887 aYb=aYm;
2888 aYe=aYm;
2889 aXb=aXm-dX;
2890 if (aXb < US1) {
2891 aXb=US1;
2892 }
2893 aXe=aXm+dX;
2894 if (aXe > US2) {
2895 aXe=US2;
2896 }
2897 aS->D0(aXb, aYb, aPb);
2898 aS->D0(aXe, aYe, aPe);
2899
2900 d1=aPm.Distance(aPb);
2901 d2=aPm.Distance(aPe);
2902 if (d1 < dD && d2 < dD) {
2903 return bFlag;
2904 }
2905 return !bFlag;
2906 }
2907 return !bFlag;
2908}
2909
2910//=========================================================================
2911// static function : ComputePurgedWLine
2912// purpose : Removes equal points (leave one of equal points) from theWLine
2913// and recompute vertex parameters.
2914// Returns new WLine or null WLine if the number
2915// of the points is less than 2.
2916//=========================================================================
2917Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
3928aec6 2918
3928aec6 2919 Standard_Integer i, k, v, nb, nbvtx;
7fd59977 2920 Handle(IntPatch_WLine) aResult;
3928aec6
P
2921 nbvtx = theWLine->NbVertex();
2922 nb = theWLine->NbPnts();
2923 if (nb==2) {
2924 const IntSurf_PntOn2S& p1 = theWLine->Point(1);
2925 const IntSurf_PntOn2S& p2 = theWLine->Point(2);
2926 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2927 return aResult;
2928 }
2929 }
2930 //
7fd59977 2931 Handle(IntPatch_WLine) aLocalWLine;
2932 Handle(IntPatch_WLine) aTmpWLine = theWLine;
7fd59977 2933 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
2934 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
7fd59977 2935 for(i = 1; i <= nb; i++) {
2936 aLineOn2S->Add(theWLine->Point(i));
2937 }
2938
2939 for(v = 1; v <= nbvtx; v++) {
2940 aLocalWLine->AddVertex(theWLine->Vertex(v));
2941 }
2942
2943 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
2944 Standard_Integer aStartIndex = i + 1;
2945 Standard_Integer anEndIndex = i + 5;
2946 nb = aLineOn2S->NbPoints();
2947 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
2948
a2eede02 2949 if((aStartIndex > nb) || (anEndIndex <= 1)) {
7fd59977 2950 continue;
2951 }
2952 k = aStartIndex;
2953
2954 while(k <= anEndIndex) {
2955
2956 if(i != k) {
655fddc8 2957 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
2958 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
2959
2960 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
2961 aTmpWLine = aLocalWLine;
2962 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
2963
2964 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
2965 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
2966 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
2967
2968 if(avertexindex >= k) {
2969 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
2970 }
2971 aLocalWLine->AddVertex(aVertex);
2972 }
2973 aLineOn2S->RemovePoint(k);
2974 anEndIndex--;
2975 continue;
2976 }
7fd59977 2977 }
2978 k++;
2979 }
2980 }
2981
2982 if(aLineOn2S->NbPoints() > 1) {
2983 aResult = aLocalWLine;
2984 }
2985 return aResult;
2986}
2987
2988//=======================================================================
2989//function : TolR3d
2990//purpose :
2991//=======================================================================
2992void TolR3d(const TopoDS_Face& aF1,
655fddc8 2993 const TopoDS_Face& aF2,
2994 Standard_Real& myTolReached3d)
7fd59977 2995{
2996 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
2997
2998 aTolTresh=2.999999e-3;
2999 aTolF1 = BRep_Tool::Tolerance(aF1);
3000 aTolF2 = BRep_Tool::Tolerance(aF2);
3001 aTolFMax=Max(aTolF1, aTolF2);
3002
3003 if (aTolFMax>aTolTresh) {
3004 myTolReached3d=aTolFMax;
3005 }
3006}
3007//=======================================================================
7fd59977 3008//function : IsPointOnBoundary
3009//purpose :
3010//=======================================================================
3011Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
655fddc8 3012 const Standard_Real theFirstBoundary,
3013 const Standard_Real theSecondBoundary,
3014 const Standard_Real theResolution,
3015 Standard_Boolean& IsOnFirstBoundary)
7fd59977 3016{
3017 Standard_Boolean bRet;
3018 Standard_Integer i;
3019 Standard_Real adist;
3020 //
3021 bRet=Standard_False;
3022 for(i = 0; i < 2; ++i) {
3023 IsOnFirstBoundary = (i == 0);
3024 if (IsOnFirstBoundary) {
3025 adist = fabs(theParameter - theFirstBoundary);
3026 }
3027 else {
3028 adist = fabs(theParameter - theSecondBoundary);
3029 }
3030 if(adist < theResolution) {
3031 return !bRet;
3032 }
3033 }
3034 return bRet;
3035}
3036// ------------------------------------------------------------------------------------------------
3037// static function: FindPoint
3038// purpose:
3039// ------------------------------------------------------------------------------------------------
3040Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 3041 const gp_Pnt2d& theLastPoint,
3042 const Standard_Real theUmin,
3043 const Standard_Real theUmax,
3044 const Standard_Real theVmin,
3045 const Standard_Real theVmax,
3046 gp_Pnt2d& theNewPoint) {
7fd59977 3047
3048 gp_Vec2d aVec(theFirstPoint, theLastPoint);
3049 Standard_Integer i = 0, j = 0;
3050
3051 for(i = 0; i < 4; i++) {
3052 gp_Vec2d anOtherVec;
3053 gp_Vec2d anOtherVecNormal;
3054 gp_Pnt2d aprojpoint = theLastPoint;
3055
3056 if((i % 2) == 0) {
3057 anOtherVec.SetX(0.);
3058 anOtherVec.SetY(1.);
3059 anOtherVecNormal.SetX(1.);
3060 anOtherVecNormal.SetY(0.);
3061
3062 if(i < 2)
655fddc8 3063 aprojpoint.SetX(theUmin);
7fd59977 3064 else
655fddc8 3065 aprojpoint.SetX(theUmax);
7fd59977 3066 }
3067 else {
3068 anOtherVec.SetX(1.);
3069 anOtherVec.SetY(0.);
3070 anOtherVecNormal.SetX(0.);
3071 anOtherVecNormal.SetY(1.);
3072
3073 if(i < 2)
655fddc8 3074 aprojpoint.SetY(theVmin);
7fd59977 3075 else
655fddc8 3076 aprojpoint.SetY(theVmax);
7fd59977 3077 }
3078 gp_Vec2d anormvec = aVec;
3079 anormvec.Normalize();
fa9681ca 3080 RefineVector(anormvec);
7fd59977 3081 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
3082
3083 if(fabs(adot1) < Precision::Angular())
3084 continue;
3085 Standard_Real adist = 0.;
3086 Standard_Boolean bIsOut = Standard_False;
3087
3088 if((i % 2) == 0) {
3089 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
3090 bIsOut = (i < 2) ? (theLastPoint.X() < theUmin) : (theLastPoint.X() > theUmax);
3091 }
3092 else {
3093 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
3094 bIsOut = (i < 2) ? (theLastPoint.Y() < theVmin) : (theLastPoint.Y() > theVmax);
3095 }
3096 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
3097
3098 for(j = 0; j < 2; j++) {
3099 anoffset = (j == 0) ? anoffset : -anoffset;
3100 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
3101 gp_Vec2d acurvec(theLastPoint, acurpoint);
3102 if ( bIsOut )
655fddc8 3103 acurvec.Reverse();
7fd59977 3104
9e9df9d9
P
3105 Standard_Real aDotX, anAngleX;
3106 //
3107 aDotX = aVec.Dot(acurvec);
3108 anAngleX = aVec.Angle(acurvec);
3109 //
3110 if(aDotX > 0. && fabs(anAngleX) < Precision::PConfusion()) {
655fddc8 3111 if((i % 2) == 0) {
3112 if((acurpoint.Y() >= theVmin) &&
3113 (acurpoint.Y() <= theVmax)) {
3114 theNewPoint = acurpoint;
3115 return Standard_True;
3116 }
3117 }
3118 else {
3119 if((acurpoint.X() >= theUmin) &&
3120 (acurpoint.X() <= theUmax)) {
3121 theNewPoint = acurpoint;
3122 return Standard_True;
3123 }
3124 }
7fd59977 3125 }
3126 }
3127 }
3128 return Standard_False;
3129}
3130
3131
3132// ------------------------------------------------------------------------------------------------
3133// static function: FindPoint
3134// purpose: Find point on the boundary of radial tangent zone
3135// ------------------------------------------------------------------------------------------------
3136Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
655fddc8 3137 const gp_Pnt2d& theLastPoint,
3138 const Standard_Real theUmin,
3139 const Standard_Real theUmax,
3140 const Standard_Real theVmin,
3141 const Standard_Real theVmax,
3142 const gp_Pnt2d& theTanZoneCenter,
3143 const Standard_Real theZoneRadius,
3144 Handle(GeomAdaptor_HSurface) theGASurface,
3145 gp_Pnt2d& theNewPoint) {
7fd59977 3146 theNewPoint = theLastPoint;
3147
3148 if ( !IsInsideTanZone( theLastPoint, theTanZoneCenter, theZoneRadius, theGASurface) )
3149 return Standard_False;
3150
3151 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3152 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3153
3154 Standard_Real aRadius = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3155 gp_Ax22d anAxis( theTanZoneCenter, gp_Dir2d(1, 0), gp_Dir2d(0, 1) );
3156 gp_Circ2d aCircle( anAxis, aRadius );
3157
3158 //
3159 gp_Vec2d aDir( theLastPoint.XY() - theFirstPoint.XY() );
3160 Standard_Real aLength = aDir.Magnitude();
3161 if ( aLength <= gp::Resolution() )
3162 return Standard_False;
3163 gp_Lin2d aLine( theFirstPoint, aDir );
3164
3165 //
3166 Handle(Geom2d_Line) aCLine = new Geom2d_Line( aLine );
3167 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve( aCLine, 0, aLength );
3168 Handle(Geom2d_Circle) aC2 = new Geom2d_Circle( aCircle );
3169
3170 Standard_Real aTol = aRadius * 0.001;
3171 aTol = ( aTol < Precision::PConfusion() ) ? Precision::PConfusion() : aTol;
3172
3173 Geom2dAPI_InterCurveCurve anIntersector;
3174 anIntersector.Init( aC1, aC2, aTol );
3175
3176 if ( anIntersector.NbPoints() == 0 )
3177 return Standard_False;
3178
3179 Standard_Boolean aFound = Standard_False;
3180 Standard_Real aMinDist = aLength * aLength;
3181 Standard_Integer i = 0;
3182 for ( i = 1; i <= anIntersector.NbPoints(); i++ ) {
3183 gp_Pnt2d aPInt = anIntersector.Point( i );
3184 if ( aPInt.SquareDistance( theFirstPoint ) < aMinDist ) {
3185 if ( ( aPInt.X() >= theUmin ) && ( aPInt.X() <= theUmax ) &&
655fddc8 3186 ( aPInt.Y() >= theVmin ) && ( aPInt.Y() <= theVmax ) ) {
3187 theNewPoint = aPInt;
3188 aFound = Standard_True;
7fd59977 3189 }
3190 }
3191 }
3192
3193 return aFound;
3194}
3195
3196// ------------------------------------------------------------------------------------------------
3197// static function: IsInsideTanZone
3198// purpose: Check if point is inside a radial tangent zone
3199// ------------------------------------------------------------------------------------------------
3200Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
655fddc8 3201 const gp_Pnt2d& theTanZoneCenter,
3202 const Standard_Real theZoneRadius,
3203 Handle(GeomAdaptor_HSurface) theGASurface) {
7fd59977 3204
3205 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3206 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3207 Standard_Real aRadiusSQR = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3208 aRadiusSQR *= aRadiusSQR;
3209 if ( thePoint.SquareDistance( theTanZoneCenter ) <= aRadiusSQR )
3210 return Standard_True;
3211 return Standard_False;
3212}
3213
3214// ------------------------------------------------------------------------------------------------
3215// static function: CheckTangentZonesExist
3216// purpose: Check if tangent zone exists
3217// ------------------------------------------------------------------------------------------------
3218Standard_Boolean CheckTangentZonesExist( const Handle(GeomAdaptor_HSurface)& theSurface1,
655fddc8 3219 const Handle(GeomAdaptor_HSurface)& theSurface2 )
7fd59977 3220{
3221 if ( ( theSurface1->GetType() != GeomAbs_Torus ) ||
3222 ( theSurface2->GetType() != GeomAbs_Torus ) )
3223 return Standard_False;
3224
7fd59977 3225 gp_Torus aTor1 = theSurface1->Torus();
3226 gp_Torus aTor2 = theSurface2->Torus();
3227
3228 if ( aTor1.Location().Distance( aTor2.Location() ) > Precision::Confusion() )
3229 return Standard_False;
3230
3231 if ( ( fabs( aTor1.MajorRadius() - aTor2.MajorRadius() ) > Precision::Confusion() ) ||
3232 ( fabs( aTor1.MinorRadius() - aTor2.MinorRadius() ) > Precision::Confusion() ) )
3233 return Standard_False;
3234
3235 if ( ( aTor1.MajorRadius() < aTor1.MinorRadius() ) ||
3236 ( aTor2.MajorRadius() < aTor2.MinorRadius() ) )
3237 return Standard_False;
3238 return Standard_True;
3239}
3240
3241// ------------------------------------------------------------------------------------------------
3242// static function: ComputeTangentZones
3243// purpose:
3244// ------------------------------------------------------------------------------------------------
3245Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
655fddc8 3246 const Handle(GeomAdaptor_HSurface)& theSurface2,
3247 const TopoDS_Face& theFace1,
3248 const TopoDS_Face& theFace2,
3249 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
3250 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
3251 Handle(TColStd_HArray1OfReal)& theResultRadius,
1e143abb 3252 const Handle(IntTools_Context)& aContext)
4f189102 3253{
7fd59977 3254 Standard_Integer aResult = 0;
3255 if ( !CheckTangentZonesExist( theSurface1, theSurface2 ) )
3256 return aResult;
3257
7fd59977 3258
3259 TColgp_SequenceOfPnt2d aSeqResultS1, aSeqResultS2;
3260 TColStd_SequenceOfReal aSeqResultRad;
3261
3262 gp_Torus aTor1 = theSurface1->Torus();
3263 gp_Torus aTor2 = theSurface2->Torus();
3264
3265 gp_Ax2 anax1( aTor1.Location(), aTor1.Axis().Direction() );
3266 gp_Ax2 anax2( aTor2.Location(), aTor2.Axis().Direction() );
3267 Standard_Integer j = 0;
3268
3269 for ( j = 0; j < 2; j++ ) {
3270 Standard_Real aCoef = ( j == 0 ) ? -1 : 1;
3271 Standard_Real aRadius1 = fabs(aTor1.MajorRadius() + aCoef * aTor1.MinorRadius());
3272 Standard_Real aRadius2 = fabs(aTor2.MajorRadius() + aCoef * aTor2.MinorRadius());
3273
3274 gp_Circ aCircle1( anax1, aRadius1 );
3275 gp_Circ aCircle2( anax2, aRadius2 );
3276
3277 // roughly compute radius of tangent zone for perpendicular case
3278 Standard_Real aCriteria = Precision::Confusion() * 0.5;
3279
3280 Standard_Real aT1 = aCriteria;
3281 Standard_Real aT2 = aCriteria;
3282 if ( j == 0 ) {
3283 // internal tangency
3284 Standard_Real aR = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3285 //aT1 = aCriteria * aCriteria + aR * aR - ( aR - aCriteria ) * ( aR - aCriteria );
3286 aT1 = 2. * aR * aCriteria;
3287 aT2 = aT1;
3288 }
3289 else {
3290 // external tangency
3291 Standard_Real aRb = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3292 Standard_Real aRm = ( aRadius1 < aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3293 Standard_Real aDelta = aRb - aCriteria;
3294 aDelta *= aDelta;
3295 aDelta -= aRm * aRm;
3296 aDelta /= 2. * (aRb - aRm);
3297 aDelta -= 0.5 * (aRb - aRm);
3298
3299 aT1 = 2. * aRm * (aRm - aDelta);
3300 aT2 = aT1;
3301 }
3302 aCriteria = ( aT1 > aT2) ? aT1 : aT2;
3303 if ( aCriteria > 0 )
3304 aCriteria = sqrt( aCriteria );
3305
3306 if ( aCriteria > 0.5 * aTor1.MinorRadius() ) {
3307 // too big zone -> drop to minimum
3308 aCriteria = Precision::Confusion();
3309 }
3310
3311 GeomAdaptor_Curve aC1( new Geom_Circle(aCircle1) );
3312 GeomAdaptor_Curve aC2( new Geom_Circle(aCircle2) );
c6541a0c 3313 Extrema_ExtCC anExtrema(aC1, aC2, 0, 2. * M_PI, 0, 2. * M_PI,
655fddc8 3314 Precision::PConfusion(), Precision::PConfusion());
3315
7fd59977 3316 if ( anExtrema.IsDone() ) {
3317
3318 Standard_Integer i = 0;
3319 for ( i = 1; i <= anExtrema.NbExt(); i++ ) {
655fddc8 3320 if ( anExtrema.SquareDistance(i) > aCriteria * aCriteria )
3321 continue;
3322
3323 Extrema_POnCurv P1, P2;
3324 anExtrema.Points( i, P1, P2 );
3325
3326 Standard_Boolean bFoundResult = Standard_True;
3327 gp_Pnt2d pr1, pr2;
3328
3329 Standard_Integer surfit = 0;
3330 for ( surfit = 0; surfit < 2; surfit++ ) {
3331 GeomAPI_ProjectPointOnSurf& aProjector =
3332 (surfit == 0) ? aContext->ProjPS(theFace1) : aContext->ProjPS(theFace2);
3333
3334 gp_Pnt aP3d = (surfit == 0) ? P1.Value() : P2.Value();
3335 aProjector.Perform(aP3d);
3336
3337 if(!aProjector.IsDone())
3338 bFoundResult = Standard_False;
3339 else {
3340 if(aProjector.LowerDistance() > aCriteria) {
3341 bFoundResult = Standard_False;
3342 }
3343 else {
3344 Standard_Real foundU = 0, foundV = 0;
3345 aProjector.LowerDistanceParameters(foundU, foundV);
3346 if ( surfit == 0 )
3347 pr1 = gp_Pnt2d( foundU, foundV );
3348 else
3349 pr2 = gp_Pnt2d( foundU, foundV );
3350 }
3351 }
3352 }
3353 if ( bFoundResult ) {
3354 aSeqResultS1.Append( pr1 );
3355 aSeqResultS2.Append( pr2 );
3356 aSeqResultRad.Append( aCriteria );
3357
3358 // torus is u and v periodic
3359 const Standard_Real twoPI = M_PI + M_PI;
3360 Standard_Real arr1tmp[2] = {pr1.X(), pr1.Y()};
3361 Standard_Real arr2tmp[2] = {pr2.X(), pr2.Y()};
3362
3363 // iteration on period bounds
3364 for ( Standard_Integer k1 = 0; k1 < 2; k1++ ) {
3365 Standard_Real aBound = ( k1 == 0 ) ? 0 : twoPI;
3366 Standard_Real aShift = ( k1 == 0 ) ? twoPI : -twoPI;
3367
3368 // iteration on surfaces
3369 for ( Standard_Integer k2 = 0; k2 < 2; k2++ ) {