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