0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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
631633a2 16#include <IntTools_FaceFace.hxx>
17
e2e0498b 18#include <BRepTools.hxx>
19#include <BRep_Tool.hxx>
631633a2 20#include <ElCLib.hxx>
e2e0498b 21#include <ElSLib.hxx>
22#include <Geom2dAdaptor_Curve.hxx>
23#include <Geom2dInt_GInter.hxx>
c22b52d6 24#include <Geom2d_BSplineCurve.hxx>
e2e0498b 25#include <Geom2d_Line.hxx>
26#include <Geom2d_TrimmedCurve.hxx>
27#include <GeomAPI_ProjectPointOnSurf.hxx>
c22b52d6 28#include <GeomAdaptor_Surface.hxx>
e2e0498b 29#include <GeomInt_IntSS.hxx>
30#include <GeomInt_WLApprox.hxx>
31#include <GeomLib_Check2dBSplineCurve.hxx>
32#include <GeomLib_CheckBSplineCurve.hxx>
33#include <Geom_BSplineCurve.hxx>
42cf5bc1 34#include <Geom_Circle.hxx>
42cf5bc1 35#include <Geom_Ellipse.hxx>
631633a2 36#include <Geom_Hyperbola.hxx>
e2e0498b 37#include <Geom_Line.hxx>
631633a2 38#include <Geom_OffsetSurface.hxx>
e2e0498b 39#include <Geom_Parabola.hxx>
40#include <Geom_RectangularTrimmedSurface.hxx>
41#include <Geom_TrimmedCurve.hxx>
42#include <IntAna_QuadQuadGeo.hxx>
43#include <IntPatch_GLine.hxx>
44#include <IntPatch_RLine.hxx>
e2e0498b 45#include <IntRes2d_Domain.hxx>
46#include <IntSurf_Quadric.hxx>
47#include <IntTools_Context.hxx>
7fd59977 48#include <IntTools_Tools.hxx>
49#include <IntTools_TopolTool.hxx>
d33a8cde 50#include <IntTools_WLineTool.hxx>
e2e0498b 51#include <ProjLib_Plane.hxx>
52#include <TopExp_Explorer.hxx>
53#include <TopoDS.hxx>
54#include <TopoDS_Edge.hxx>
55#include <gp_Elips.hxx>
9eee5ab7 56#include <ApproxInt_KnotTools.hxx>
d4b867e6 57
7fd59977 58static
c22b52d6 59 void Parameters(const Handle(GeomAdaptor_Surface)&,
60 const Handle(GeomAdaptor_Surface)&,
655fddc8 61 const gp_Pnt&,
62 Standard_Real&,
63 Standard_Real&,
64 Standard_Real&,
65 Standard_Real&);
7fd59977 66
7fd59977 67static
68 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
655fddc8 69 const Standard_Real theTolerance,
70 Standard_Real& theumin,
71 Standard_Real& theumax,
72 Standard_Real& thevmin,
73 Standard_Real& thevmax);
d4b867e6 74
7fd59977 75static
76 Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
655fddc8 77 const Handle(Geom_Curve)& theCurve,
78 const TopoDS_Face& theFace1,
79 const TopoDS_Face& theFace2,
80 const Standard_Real theOtherParameter,
81 const Standard_Boolean bIncreasePar,
0d0481c7 82 const Standard_Real theTol,
655fddc8 83 Standard_Real& theNewParameter,
1e143abb 84 const Handle(IntTools_Context)& );
7fd59977 85
86static
aa00364d 87 Standard_Boolean IsCurveValid(const Handle(Geom2d_Curve)& thePCurve);
7fd59977 88
7fd59977 89static
4f189102 90 Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
655fddc8 91 const gp_Sphere& theSph);
7fd59977 92
c22b52d6 93static void PerformPlanes(const Handle(GeomAdaptor_Surface)& theS1,
94 const Handle(GeomAdaptor_Surface)& theS2,
3510db62 95 const Standard_Real TolF1,
96 const Standard_Real TolF2,
5652dc62 97 const Standard_Real TolAng,
98 const Standard_Real TolTang,
655fddc8 99 const Standard_Boolean theApprox1,
100 const Standard_Boolean theApprox2,
5652dc62 101 IntTools_SequenceOfCurves& theSeqOfCurve,
102 Standard_Boolean& theTangentFaces);
7fd59977 103
c22b52d6 104static Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_Surface)& theS,
655fddc8 105 const gp_Lin2d& theLin2d,
106 const Standard_Real theTol,
107 Standard_Real& theP1,
108 Standard_Real& theP2);
0fc4f2e2 109//
7fd59977 110static
c22b52d6 111 void ApproxParameters(const Handle(GeomAdaptor_Surface)& aHS1,
112 const Handle(GeomAdaptor_Surface)& aHS2,
655fddc8 113 Standard_Integer& iDegMin,
114 Standard_Integer& iNbIter,
115 Standard_Integer& iDegMax);
7fd59977 116
0fc4f2e2 117static
c22b52d6 118 void Tolerances(const Handle(GeomAdaptor_Surface)& aHS1,
119 const Handle(GeomAdaptor_Surface)& aHS2,
788cbaf4 120 Standard_Real& aTolTang);
0fc4f2e2 121
0fc4f2e2
P
122static
123 Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
655fddc8 124 const GeomAbs_SurfaceType aType2);
0fc4f2e2
P
125static
126 Standard_Integer IndexType(const GeomAbs_SurfaceType aType);
d10203e8 127
4f189102 128//
989341c5 129static
130 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
51db0179 131 const TopoDS_Face& aFace,
132 const Handle(IntTools_Context)& theCtx);
989341c5 133
631633a2 134static
135 Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
136 const Standard_Real aT,
137 GeomAPI_ProjectPointOnSurf& theProjPS);
138
139static
140 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
141 const Standard_Real theFirst,
142 const Standard_Real theLast,
143 GeomAPI_ProjectPointOnSurf& theProjPS,
144 const Standard_Real theEps);
145
146static
147 Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
148 const Standard_Real theFirst,
149 const Standard_Real theLast,
150 const TopoDS_Face& theFace,
151 const Handle(IntTools_Context)& theContext);
152
9a5a19e9 153static
154 void CorrectPlaneBoundaries(Standard_Real& aUmin,
155 Standard_Real& aUmax,
156 Standard_Real& aVmin,
157 Standard_Real& aVmax);
158
7fd59977 159//=======================================================================
160//function :
161//purpose :
162//=======================================================================
4f189102 163IntTools_FaceFace::IntTools_FaceFace()
7fd59977 164{
3f16d970 165 myIsDone=Standard_False;
7fd59977 166 myTangentFaces=Standard_False;
167 //
c22b52d6 168 myHS1 = new GeomAdaptor_Surface ();
169 myHS2 = new GeomAdaptor_Surface ();
0d0481c7 170 myTolF1 = 0.;
171 myTolF2 = 0.;
172 myTol = 0.;
173 myFuzzyValue = Precision::Confusion();
7fd59977 174 SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
4f189102
P
175}
176//=======================================================================
177//function : SetContext
178//purpose :
179//=======================================================================
1e143abb 180void IntTools_FaceFace::SetContext(const Handle(IntTools_Context)& aContext)
4f189102
P
181{
182 myContext=aContext;
183}
184//=======================================================================
185//function : Context
186//purpose :
187//=======================================================================
1e143abb 188const Handle(IntTools_Context)& IntTools_FaceFace::Context()const
4f189102
P
189{
190 return myContext;
7fd59977 191}
192//=======================================================================
193//function : Face1
194//purpose :
195//=======================================================================
4f189102 196const TopoDS_Face& IntTools_FaceFace::Face1() const
7fd59977 197{
198 return myFace1;
199}
7fd59977 200//=======================================================================
201//function : Face2
202//purpose :
203//=======================================================================
4f189102 204const TopoDS_Face& IntTools_FaceFace::Face2() const
7fd59977 205{
206 return myFace2;
207}
7fd59977 208//=======================================================================
209//function : TangentFaces
210//purpose :
211//=======================================================================
4f189102 212Standard_Boolean IntTools_FaceFace::TangentFaces() const
7fd59977 213{
214 return myTangentFaces;
215}
216//=======================================================================
217//function : Points
218//purpose :
219//=======================================================================
4f189102 220const IntTools_SequenceOfPntOn2Faces& IntTools_FaceFace::Points() const
7fd59977 221{
222 return myPnts;
223}
224//=======================================================================
225//function : IsDone
226//purpose :
227//=======================================================================
4f189102 228Standard_Boolean IntTools_FaceFace::IsDone() const
7fd59977 229{
230 return myIsDone;
231}
232//=======================================================================
7fd59977 233//function : Lines
234//purpose : return lines of intersection
235//=======================================================================
4f189102 236const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
7fd59977 237{
4f189102
P
238 StdFail_NotDone_Raise_if
239 (!myIsDone,
788cbaf4 240 "IntTools_FaceFace::Lines() => myIntersector NOT DONE");
7fd59977 241 return mySeqOfCurve;
242}
7fd59977 243// =======================================================================
244// function: SetParameters
245//
246// =======================================================================
4f189102 247void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
655fddc8 248 const Standard_Boolean ToApproxC2dOnS1,
249 const Standard_Boolean ToApproxC2dOnS2,
250 const Standard_Real ApproximationTolerance)
7fd59977 251{
252 myApprox = ToApproxC3d;
253 myApprox1 = ToApproxC2dOnS1;
254 myApprox2 = ToApproxC2dOnS2;
255 myTolApprox = ApproximationTolerance;
256}
0d0481c7 257//=======================================================================
258//function : SetFuzzyValue
259//purpose :
260//=======================================================================
261void IntTools_FaceFace::SetFuzzyValue(const Standard_Real theFuzz)
262{
263 myFuzzyValue = Max(theFuzz, Precision::Confusion());
264}
265//=======================================================================
266//function : FuzzyValue
267//purpose :
268//=======================================================================
269Standard_Real IntTools_FaceFace::FuzzyValue() const
270{
271 return myFuzzyValue;
272}
273
7fd59977 274//=======================================================================
275//function : SetList
276//purpose :
277//=======================================================================
7fd59977 278void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
279{
280 myListOfPnts = aListOfPnts;
281}
788cbaf4 282
283
51db0179 284static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
285 const BRepAdaptor_Surface& theBAS2,
0d0481c7 286 const Standard_Real theTol)
788cbaf4 287{
288 const Standard_Real Tolang = 1.e-8;
788cbaf4 289 Standard_Real aHigh = 0.0;
290
51db0179 291 const GeomAbs_SurfaceType aType1=theBAS1.GetType();
292 const GeomAbs_SurfaceType aType2=theBAS2.GetType();
788cbaf4 293
294 gp_Pln aS1;
295 gp_Cylinder aS2;
296 if(aType1 == GeomAbs_Plane)
297 {
51db0179 298 aS1=theBAS1.Plane();
788cbaf4 299 }
300 else if(aType2 == GeomAbs_Plane)
301 {
51db0179 302 aS1=theBAS2.Plane();
788cbaf4 303 }
304 else
305 {
306 return Standard_True;
307 }
308
309 if(aType1 == GeomAbs_Cylinder)
310 {
51db0179 311 aS2=theBAS1.Cylinder();
312 const Standard_Real VMin = theBAS1.FirstVParameter();
313 const Standard_Real VMax = theBAS1.LastVParameter();
788cbaf4 314
315 if( Precision::IsNegativeInfinite(VMin) ||
316 Precision::IsPositiveInfinite(VMax))
317 return Standard_True;
318 else
319 aHigh = VMax - VMin;
320 }
321 else if(aType2 == GeomAbs_Cylinder)
322 {
51db0179 323 aS2=theBAS2.Cylinder();
788cbaf4 324
51db0179 325 const Standard_Real VMin = theBAS2.FirstVParameter();
326 const Standard_Real VMax = theBAS2.LastVParameter();
788cbaf4 327
328 if( Precision::IsNegativeInfinite(VMin) ||
329 Precision::IsPositiveInfinite(VMax))
330 return Standard_True;
331 else
332 aHigh = VMax - VMin;
333 }
334 else
335 {
336 return Standard_True;
337 }
338
339 IntAna_QuadQuadGeo inter;
0d0481c7 340 inter.Perform(aS1,aS2,Tolang,theTol, aHigh);
788cbaf4 341 if(inter.TypeInter() == IntAna_Ellipse)
342 {
343 const gp_Elips anEl = inter.Ellipse(1);
344 const Standard_Real aMajorR = anEl.MajorRadius();
345 const Standard_Real aMinorR = anEl.MinorRadius();
346
347 return (aMajorR < 100000.0 * aMinorR);
348 }
349 else
350 {
351 return inter.IsDone();
352 }
353}
7fd59977 354//=======================================================================
355//function : Perform
356//purpose : intersect surfaces of the faces
357//=======================================================================
3738565a 358void IntTools_FaceFace::Perform (const TopoDS_Face& aF1,
359 const TopoDS_Face& aF2,
360 const Standard_Boolean theToRunParallel)
7fd59977 361{
4f189102 362 if (myContext.IsNull()) {
1e143abb 363 myContext=new IntTools_Context;
4f189102 364 }
788cbaf4 365
7fd59977 366 mySeqOfCurve.Clear();
7fd59977 367 myIsDone = Standard_False;
0fc4f2e2 368 myNbrestr=0;//?
788cbaf4 369
0fc4f2e2
P
370 myFace1=aF1;
371 myFace2=aF2;
788cbaf4 372
51db0179 373 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(myFace1);
374 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(myFace2);
788cbaf4 375 GeomAbs_SurfaceType aType1=aBAS1.GetType();
376 GeomAbs_SurfaceType aType2=aBAS2.GetType();
377
378 const Standard_Boolean bReverse=SortTypes(aType1, aType2);
379 if (bReverse)
380 {
0fc4f2e2
P
381 myFace1=aF2;
382 myFace2=aF1;
383 aType1=aBAS2.GetType();
384 aType2=aBAS1.GetType();
788cbaf4 385
386 if (myListOfPnts.Extent())
387 {
0fc4f2e2
P
388 Standard_Real aU1,aV1,aU2,aV2;
389 IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
390 //
391 aItP2S.Initialize(myListOfPnts);
788cbaf4 392 for (; aItP2S.More(); aItP2S.Next())
393 {
1103eb60 394 IntSurf_PntOn2S& aP2S=aItP2S.ChangeValue();
655fddc8 395 aP2S.Parameters(aU1,aV1,aU2,aV2);
396 aP2S.SetValue(aU2,aV2,aU1,aV1);
0fc4f2e2
P
397 }
398 }
2d2aa6f1 399 //
400 Standard_Boolean anAproxTmp = myApprox1;
401 myApprox1 = myApprox2;
402 myApprox2 = anAproxTmp;
0fc4f2e2 403 }
7fd59977 404
788cbaf4 405
406 const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
407 const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
408
0d0481c7 409 Standard_Real aFuzz = myFuzzyValue / 2.;
410 myTolF1 = BRep_Tool::Tolerance(myFace1) + aFuzz;
411 myTolF2 = BRep_Tool::Tolerance(myFace2) + aFuzz;
412 myTol = myTolF1 + myTolF2;
788cbaf4 413
0d0481c7 414 Standard_Real TolArc = myTol;
788cbaf4 415 Standard_Real TolTang = TolArc;
416
417 const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
418 aType1 == GeomAbs_Cone ||
419 aType1 == GeomAbs_Torus);
420
421 const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
422 aType2 == GeomAbs_Cone ||
423 aType2 == GeomAbs_Torus);
424
a34f083b 425 if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane) {
788cbaf4 426 Standard_Real umin, umax, vmin, vmax;
a34f083b 427 //
51db0179 428 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
c22b52d6 429 myHS1->Load(S1, umin, umax, vmin, vmax);
7fd59977 430 //
51db0179 431 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
c22b52d6 432 myHS2->Load(S2, umin, umax, vmin, vmax);
a34f083b 433 //
7fd59977 434 Standard_Real TolAng = 1.e-8;
a34f083b 435 //
5652dc62 436 PerformPlanes(myHS1, myHS2,
437 myTolF1, myTolF2, TolAng, TolTang,
438 myApprox1, myApprox2,
439 mySeqOfCurve, myTangentFaces);
a34f083b 440 //
7fd59977 441 myIsDone = Standard_True;
5652dc62 442 //
443 if (!myTangentFaces) {
788cbaf4 444 const Standard_Integer NbLinPP = mySeqOfCurve.Length();
5652dc62 445 if (NbLinPP && bReverse) {
446 Handle(Geom2d_Curve) aC2D1, aC2D2;
447 const Standard_Integer aNbLin = mySeqOfCurve.Length();
448 for (Standard_Integer i = 1; i <= aNbLin; ++i) {
449 IntTools_Curve& aIC = mySeqOfCurve(i);
450 aC2D1 = aIC.FirstCurve2d();
451 aC2D2 = aIC.SecondCurve2d();
452 aIC.SetFirstCurve2d(aC2D2);
453 aIC.SetSecondCurve2d(aC2D1);
655fddc8 454 }
0fc4f2e2
P
455 }
456 }
7fd59977 457 return;
0fc4f2e2 458 }//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
788cbaf4 459
460 if ((aType1==GeomAbs_Plane) && isFace2Quad)
461 {
788cbaf4 462 Standard_Real umin, umax, vmin, vmax;
9a5a19e9 463 // F1
51db0179 464 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
9a5a19e9 465 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
c22b52d6 466 myHS1->Load(S1, umin, umax, vmin, vmax);
7fd59977 467 // F2
51db0179 468 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
0d0481c7 469 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
c22b52d6 470 myHS2->Load(S2, umin, umax, vmin, vmax);
7fd59977 471 }
788cbaf4 472 else if ((aType2==GeomAbs_Plane) && isFace1Quad)
473 {
788cbaf4 474 Standard_Real umin, umax, vmin, vmax;
9a5a19e9 475 //F1
51db0179 476 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
0d0481c7 477 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
c22b52d6 478 myHS1->Load(S1, umin, umax, vmin, vmax);
7fd59977 479 // F2
51db0179 480 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
9a5a19e9 481 CorrectPlaneBoundaries(umin, umax, vmin, vmax);
c22b52d6 482 myHS2->Load(S2, umin, umax, vmin, vmax);
7fd59977 483 }
788cbaf4 484 else
485 {
486 Standard_Real umin, umax, vmin, vmax;
51db0179 487 myContext->UVBounds(myFace1, umin, umax, vmin, vmax);
0d0481c7 488 CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
c22b52d6 489 myHS1->Load(S1, umin, umax, vmin, vmax);
51db0179 490 myContext->UVBounds(myFace2, umin, umax, vmin, vmax);
0d0481c7 491 CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
c22b52d6 492 myHS2->Load(S2, umin, umax, vmin, vmax);
7fd59977 493 }
788cbaf4 494
495 const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
496 const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
497
7fd59977 498 myLConstruct.Load(dom1, dom2, myHS1, myHS2);
788cbaf4 499
500
501 Tolerances(myHS1, myHS2, TolTang);
502
503 {
9eee5ab7 504 const Standard_Real UVMaxStep = IntPatch_Intersection::DefineUVMaxStep(myHS1, dom1, myHS2, dom2);
5c48956f 505 Standard_Real Deflection = 0.1;
506 if (aType1 == GeomAbs_BSplineSurface && aType2 == GeomAbs_BSplineSurface)
507 {
508 Deflection /= 10.;
509 }
eb75e31c 510 myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
788cbaf4 511 }
512
788cbaf4 513 if((aType1 != GeomAbs_BSplineSurface) &&
59495dbe 514 (aType1 != GeomAbs_BezierSurface) &&
788cbaf4 515 (aType1 != GeomAbs_OtherSurface) &&
516 (aType2 != GeomAbs_BSplineSurface) &&
59495dbe 517 (aType2 != GeomAbs_BezierSurface) &&
788cbaf4 518 (aType2 != GeomAbs_OtherSurface))
519 {
7fd59977 520 if ((aType1 == GeomAbs_Torus) ||
788cbaf4 521 (aType2 == GeomAbs_Torus))
522 {
7fd59977 523 myListOfPnts.Clear();
524 }
525 }
788cbaf4 526
a09c8f3a 527#ifdef INTTOOLS_FACEFACE_DEBUG
528 if(!myListOfPnts.IsEmpty()) {
529 char aBuff[10000];
a09c8f3a 530
531 Sprintf(aBuff,"bopcurves <face1 face2> -2d");
532 IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(myListOfPnts);
533 for(;IterLOP1.More(); IterLOP1.Next())
534 {
535 const IntSurf_PntOn2S& aPt = IterLOP1.Value();
536 Standard_Real u1, v1, u2, v2;
537 aPt.Parameters(u1, v1, u2, v2);
538
539 Sprintf(aBuff, "%s -p %+10.20f %+10.20f %+10.20f %+10.20f", aBuff, u1, v1, u2, v2);
540 }
541
04232180 542 std::cout << aBuff << std::endl;
a09c8f3a 543 }
544#endif
545
51db0179 546 const Standard_Boolean isGeomInt = isTreatAnalityc(aBAS1, aBAS2, myTol);
f48cb55d 547 if (aF1.IsSame(aF2))
548 myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
549 else
550 myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
7797eb38 551 myListOfPnts, isGeomInt);
788cbaf4 552
7fd59977 553 myIsDone = myIntersector.IsDone();
788cbaf4 554
555 if (myIsDone)
556 {
7fd59977 557 myTangentFaces=myIntersector.TangentFaces();
558 if (myTangentFaces) {
559 return;
560 }
561 //
51740958 562 const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
563 for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
71958f7d 564 MakeCurve(i, dom1, dom2, TolArc);
7fd59977 565 }
566 //
3738565a 567 ComputeTolReached3d (theToRunParallel);
7fd59977 568 //
0fc4f2e2
P
569 if (bReverse) {
570 Handle(Geom2d_Curve) aC2D1, aC2D2;
571 //
51740958 572 const Standard_Integer aNbLinSeqOfCurve =mySeqOfCurve.Length();
573 for (Standard_Integer i=1; i<=aNbLinSeqOfCurve; ++i)
788cbaf4 574 {
655fddc8 575 IntTools_Curve& aIC=mySeqOfCurve(i);
576 aC2D1=aIC.FirstCurve2d();
577 aC2D2=aIC.SecondCurve2d();
578 aIC.SetFirstCurve2d(aC2D2);
579 aIC.SetSecondCurve2d(aC2D1);
0fc4f2e2
P
580 }
581 }
788cbaf4 582
0fc4f2e2 583 // Points
e9e644ed 584 Standard_Boolean bValid2D1, bValid2D2;
7fd59977 585 Standard_Real U1,V1,U2,V2;
586 IntTools_PntOnFace aPntOnF1, aPntOnF2;
0fc4f2e2 587 IntTools_PntOn2Faces aPntOn2Faces;
7fd59977 588 //
788cbaf4 589 const Standard_Integer aNbPnts = myIntersector.NbPnts();
590 for (Standard_Integer i=1; i <= aNbPnts; ++i)
591 {
7fd59977 592 const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
593 const gp_Pnt& aPnt=aISPnt.Value();
594 aISPnt.Parameters(U1,V1,U2,V2);
e9e644ed 595 //
596 // check the validity of the intersection point for the faces
597 bValid2D1 = myContext->IsPointInOnFace(myFace1, gp_Pnt2d(U1, V1));
598 if (!bValid2D1) {
599 continue;
600 }
601 //
602 bValid2D2 = myContext->IsPointInOnFace(myFace2, gp_Pnt2d(U2, V2));
603 if (!bValid2D2) {
604 continue;
605 }
606 //
607 // add the intersection point
0fc4f2e2
P
608 aPntOnF1.Init(myFace1, aPnt, U1, V1);
609 aPntOnF2.Init(myFace2, aPnt, U2, V2);
d10203e8 610 //
788cbaf4 611 if (!bReverse)
612 {
655fddc8 613 aPntOn2Faces.SetP1(aPntOnF1);
614 aPntOn2Faces.SetP2(aPntOnF2);
0fc4f2e2 615 }
788cbaf4 616 else
617 {
655fddc8 618 aPntOn2Faces.SetP2(aPntOnF1);
619 aPntOn2Faces.SetP1(aPntOnF2);
0fc4f2e2 620 }
788cbaf4 621
7fd59977 622 myPnts.Append(aPntOn2Faces);
623 }
7fd59977 624 }
625}
788cbaf4 626
1b7ae951 627//=======================================================================
5652dc62 628//function :ComputeTolReached3d
1b7ae951 629//purpose :
630//=======================================================================
3738565a 631void IntTools_FaceFace::ComputeTolReached3d (const Standard_Boolean theToRunParallel)
1b7ae951 632{
5652dc62 633 Standard_Integer i, j, aNbLin = mySeqOfCurve.Length();
634 if (!aNbLin) {
635 return;
636 }
1b7ae951 637 //
5652dc62 638 // Minimal tangential tolerance for the curve
639 Standard_Real aTolFMax = Max(myTolF1, myTolF2);
1b7ae951 640 //
c22b52d6 641 const Handle(Geom_Surface)& aS1 = myHS1->Surface();
642 const Handle(Geom_Surface)& aS2 = myHS2->Surface();
1b7ae951 643 //
260f924f 644 for (i = 1; i <= aNbLin; ++i)
645 {
5652dc62 646 IntTools_Curve& aIC = mySeqOfCurve(i);
1b7ae951 647 const Handle(Geom_Curve)& aC3D = aIC.Curve();
260f924f 648 if (aC3D.IsNull())
649 {
1b7ae951 650 continue;
651 }
652 //
5652dc62 653 Standard_Real aTolC = aIC.Tolerance();
654 Standard_Real aFirst = aC3D->FirstParameter();
655 Standard_Real aLast = aC3D->LastParameter();
1b7ae951 656 //
5652dc62 657 // Compute the tolerance for the curve
1b7ae951 658 const Handle(Geom2d_Curve)& aC2D1 = aIC.FirstCurve2d();
659 const Handle(Geom2d_Curve)& aC2D2 = aIC.SecondCurve2d();
660 //
260f924f 661 for (j = 0; j < 2; ++j)
662 {
1b7ae951 663 const Handle(Geom2d_Curve)& aC2D = !j ? aC2D1 : aC2D2;
260f924f 664 if (!aC2D.IsNull())
665 {
5652dc62 666 // Look for the maximal deviation between 3D and 2D curves
667 Standard_Real aD, aT;
668 const Handle(Geom_Surface)& aS = !j ? aS1 : aS2;
3738565a 669 if (IntTools_Tools::ComputeTolerance (aC3D, aC2D, aS, aFirst, aLast, aD, aT, Precision::PConfusion(), theToRunParallel))
260f924f 670 {
5652dc62 671 if (aD > aTolC)
260f924f 672 {
5652dc62 673 aTolC = aD;
1b7ae951 674 }
675 }
676 }
631633a2 677 else
678 {
5652dc62 679 // Look for the maximal deviation between 3D curve and surface
631633a2 680 const TopoDS_Face& aF = !j ? myFace1 : myFace2;
5652dc62 681 Standard_Real aD = FindMaxDistance(aC3D, aFirst, aLast, aF, myContext);
682 if (aD > aTolC)
631633a2 683 {
5652dc62 684 aTolC = aD;
631633a2 685 }
5b111128 686 }
1b7ae951 687 }
5652dc62 688 // Set the valid tolerance for the curve
689 aIC.SetTolerance(aTolC);
690 //
691 // Set the tangential tolerance for the curve.
692 // Note, that, currently, computation of the tangential tolerance is
693 // implemented for the Plane/Plane case only.
694 // Thus, set the tangential tolerance equal to maximal tolerance of faces.
695 if (aIC.TangentialTolerance() < aTolFMax) {
696 aIC.SetTangentialTolerance(aTolFMax);
7fd59977 697 }
4e57c75e 698 }
3510db62 699}
1b7ae951 700
7fd59977 701//=======================================================================
702//function : MakeCurve
703//purpose :
704//=======================================================================
71958f7d 705void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
706 const Handle(Adaptor3d_TopolTool)& dom1,
707 const Handle(Adaptor3d_TopolTool)& dom2,
708 const Standard_Real theToler)
7fd59977 709{
4abae870 710 Standard_Boolean bDone, rejectSurface, reApprox, bAvoidLineConstructor;
711 Standard_Boolean ok, bPCurvesOk;
7fd59977 712 Standard_Integer i, j, aNbParts;
713 Standard_Real fprm, lprm;
714 Standard_Real Tolpc;
715 Handle(IntPatch_Line) L;
716 IntPatch_IType typl;
717 Handle(Geom_Curve) newc;
718 //
e67e482d 719 const Standard_Real TOLCHECK = 1.e-7;
720 const Standard_Real TOLANGCHECK = 1.e-6;
7fd59977 721 //
722 rejectSurface = Standard_False;
723 reApprox = Standard_False;
989341c5 724 //
725 bPCurvesOk = Standard_True;
59495dbe 726
727 reapprox:;
728
7fd59977 729 Tolpc = myTolApprox;
730 bAvoidLineConstructor = Standard_False;
731 L = myIntersector.Line(Index);
732 typl = L->ArcType();
733 //
734 if(typl==IntPatch_Walking) {
c5f3a425 735 Handle(IntPatch_WLine) aWLine (Handle(IntPatch_WLine)::DownCast(L));
4e14c88f 736 if(aWLine.IsNull()) {
7fd59977 737 return;
738 }
4e14c88f 739 L = aWLine;
4abae870 740
7fd59977 741 Standard_Integer nbp = aWLine->NbPnts();
742 const IntSurf_PntOn2S& p1 = aWLine->Point(1);
743 const IntSurf_PntOn2S& p2 = aWLine->Point(nbp);
744
745 const gp_Pnt& P1 = p1.Value();
746 const gp_Pnt& P2 = p2.Value();
747
748 if(P1.SquareDistance(P2) < 1.e-14) {
749 bAvoidLineConstructor = Standard_False;
750 }
7fd59977 751 }
d4b867e6 752
753 typl=L->ArcType();
754
77dbd1f1 755 if(typl == IntPatch_Restriction)
756 bAvoidLineConstructor = Standard_True;
757
7fd59977 758 //
759 // Line Constructor
760 if(!bAvoidLineConstructor) {
761 myLConstruct.Perform(L);
762 //
763 bDone=myLConstruct.IsDone();
d4b867e6 764 if(!bDone)
765 {
7fd59977 766 return;
767 }
d4b867e6 768
769 if(typl != IntPatch_Restriction)
770 {
771 aNbParts=myLConstruct.NbParts();
772 if (aNbParts <= 0)
773 {
774 return;
775 }
776 }
7fd59977 777 }
778 // Do the Curve
d4b867e6 779
780
7fd59977 781 switch (typl) {
59495dbe 782 //########################################
783 // Line, Parabola, Hyperbola
784 //########################################
7fd59977 785 case IntPatch_Lin:
786 case IntPatch_Parabola:
787 case IntPatch_Hyperbola: {
788 if (typl == IntPatch_Lin) {
789 newc =
655fddc8 790 new Geom_Line (Handle(IntPatch_GLine)::DownCast(L)->Line());
7fd59977 791 }
792
793 else if (typl == IntPatch_Parabola) {
794 newc =
655fddc8 795 new Geom_Parabola(Handle(IntPatch_GLine)::DownCast(L)->Parabola());
7fd59977 796 }
59495dbe 797
7fd59977 798 else if (typl == IntPatch_Hyperbola) {
799 newc =
655fddc8 800 new Geom_Hyperbola (Handle(IntPatch_GLine)::DownCast(L)->Hyperbola());
7fd59977 801 }
802 //
7fd59977 803 aNbParts=myLConstruct.NbParts();
804 for (i=1; i<=aNbParts; i++) {
0da45792 805 Standard_Boolean bFNIt, bLPIt;
806 //
7fd59977 807 myLConstruct.Part(i, fprm, lprm);
d4b867e6 808 //
0da45792 809 bFNIt=Precision::IsNegativeInfinite(fprm);
810 bLPIt=Precision::IsPositiveInfinite(lprm);
811 //
812 if (!bFNIt && !bLPIt) {
655fddc8 813 //
814 IntTools_Curve aCurve;
815 //
816 Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
817 aCurve.SetCurve(aCT3D);
818 if (typl == IntPatch_Parabola) {
5652dc62 819 Standard_Real aTolC = IntTools_Tools::CurveTolerance(aCT3D, myTol);
820 aCurve.SetTolerance(aTolC);
655fddc8 821 }
822 //
655fddc8 823 if(myApprox1) {
824 Handle (Geom2d_Curve) C2d;
d4b867e6 825 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
c22b52d6 826 myHS1->Surface(), newc, C2d);
e28b8c62 827
828 if (C2d.IsNull())
829 continue;
830
5652dc62 831 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
832 }
0da45792 833 //
655fddc8 834 if(myApprox2) {
835 Handle (Geom2d_Curve) C2d;
d4b867e6 836 GeomInt_IntSS::BuildPCurves(fprm, lprm, Tolpc,
c22b52d6 837 myHS2->Surface(), newc, C2d);
e28b8c62 838
839 if (C2d.IsNull())
840 continue;
841
5652dc62 842 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, fprm, lprm));
655fddc8 843 }
5652dc62 844 //
655fddc8 845 mySeqOfCurve.Append(aCurve);
0da45792 846 } //if (!bFNIt && !bLPIt) {
7fd59977 847 else {
655fddc8 848 // on regarde si on garde
849 //
655fddc8 850 Standard_Real aTestPrm, dT=100.;
0da45792 851 //
655fddc8 852 aTestPrm=0.;
655fddc8 853 if (bFNIt && !bLPIt) {
854 aTestPrm=lprm-dT;
855 }
856 else if (!bFNIt && bLPIt) {
857 aTestPrm=fprm+dT;
858 }
0da45792 859 else {
860 // i.e, if (bFNIt && bLPIt)
861 aTestPrm=IntTools_Tools::IntermediatePoint(-dT, dT);
862 }
863 //
655fddc8 864 gp_Pnt ptref(newc->Value(aTestPrm));
865 //
94218044 866 GeomAbs_SurfaceType typS1 = myHS1->GetType();
867 GeomAbs_SurfaceType typS2 = myHS2->GetType();
868 if( typS1 == GeomAbs_SurfaceOfExtrusion ||
869 typS1 == GeomAbs_OffsetSurface ||
870 typS1 == GeomAbs_SurfaceOfRevolution ||
871 typS2 == GeomAbs_SurfaceOfExtrusion ||
872 typS2 == GeomAbs_OffsetSurface ||
0da45792 873 typS2 == GeomAbs_SurfaceOfRevolution) {
94218044 874 Handle(Geom2d_BSplineCurve) H1;
875 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
876 continue;
877 }
878
655fddc8 879 Standard_Real u1, v1, u2, v2, Tol;
880
881 Tol = Precision::Confusion();
882 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
883 ok = (dom1->Classify(gp_Pnt2d(u1, v1), Tol) != TopAbs_OUT);
884 if(ok) {
885 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
886 }
887 if (ok) {
888 Handle(Geom2d_BSplineCurve) H1;
889 mySeqOfCurve.Append(IntTools_Curve(newc, H1, H1));
890 }
7fd59977 891 }
0da45792 892 }// for (i=1; i<=aNbParts; i++) {
7fd59977 893 }// case IntPatch_Lin: case IntPatch_Parabola: case IntPatch_Hyperbola:
59495dbe 894 break;
7fd59977 895
59495dbe 896 //########################################
897 // Circle and Ellipse
898 //########################################
7fd59977 899 case IntPatch_Circle:
900 case IntPatch_Ellipse: {
901
902 if (typl == IntPatch_Circle) {
903 newc = new Geom_Circle
655fddc8 904 (Handle(IntPatch_GLine)::DownCast(L)->Circle());
7fd59977 905 }
906 else { //IntPatch_Ellipse
907 newc = new Geom_Ellipse
655fddc8 908 (Handle(IntPatch_GLine)::DownCast(L)->Ellipse());
7fd59977 909 }
910 //
7fd59977 911 aNbParts=myLConstruct.NbParts();
912 //
913 Standard_Real aPeriod, aNul;
914 TColStd_SequenceOfReal aSeqFprm, aSeqLprm;
59495dbe 915
7fd59977 916 aNul=0.;
c6541a0c 917 aPeriod=M_PI+M_PI;
7fd59977 918
919 for (i=1; i<=aNbParts; i++) {
920 myLConstruct.Part(i, fprm, lprm);
921
922 if (fprm < aNul && lprm > aNul) {
655fddc8 923 // interval that goes through 0. is divided on two intervals;
924 while (fprm<aNul || fprm>aPeriod) fprm=fprm+aPeriod;
925 while (lprm<aNul || lprm>aPeriod) lprm=lprm+aPeriod;
926 //
927 if((aPeriod - fprm) > Tolpc) {
928 aSeqFprm.Append(fprm);
929 aSeqLprm.Append(aPeriod);
930 }
931 else {
932 gp_Pnt P1 = newc->Value(fprm);
933 gp_Pnt P2 = newc->Value(aPeriod);
655fddc8 934
5652dc62 935 if(P1.Distance(P2) > myTol) {
655fddc8 936 Standard_Real anewpar = fprm;
94218044 937
4abae870 938 if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2,
0d0481c7 939 lprm, Standard_False, myTol, anewpar, myContext)) {
655fddc8 940 fprm = anewpar;
941 }
942 aSeqFprm.Append(fprm);
943 aSeqLprm.Append(aPeriod);
944 }
945 }
946
947 //
948 if((lprm - aNul) > Tolpc) {
949 aSeqFprm.Append(aNul);
950 aSeqLprm.Append(lprm);
951 }
952 else {
953 gp_Pnt P1 = newc->Value(aNul);
954 gp_Pnt P2 = newc->Value(lprm);
655fddc8 955
5652dc62 956 if(P1.Distance(P2) > myTol) {
655fddc8 957 Standard_Real anewpar = lprm;
94218044 958
4abae870 959 if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2,
0d0481c7 960 fprm, Standard_True, myTol, anewpar, myContext)) {
655fddc8 961 lprm = anewpar;
962 }
963 aSeqFprm.Append(aNul);
964 aSeqLprm.Append(lprm);
965 }
966 }
7fd59977 967 }
968 else {
655fddc8 969 // usual interval
970 aSeqFprm.Append(fprm);
971 aSeqLprm.Append(lprm);
7fd59977 972 }
973 }
7fd59977 974 //
975 aNbParts=aSeqFprm.Length();
976 for (i=1; i<=aNbParts; i++) {
977 fprm=aSeqFprm(i);
978 lprm=aSeqLprm(i);
979 //
980 Standard_Real aRealEpsilon=RealEpsilon();
c6541a0c 981 if (Abs(fprm) > aRealEpsilon || Abs(lprm-2.*M_PI) > aRealEpsilon) {
655fddc8 982 //==============================================
983 ////
984 IntTools_Curve aCurve;
985 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
986 aCurve.SetCurve(aTC3D);
987 fprm=aTC3D->FirstParameter();
988 lprm=aTC3D->LastParameter ();
989 ////
990 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {////
991 if(myApprox1) {
992 Handle (Geom2d_Curve) C2d;
686926c0 993 GeomInt_IntSS::BuildPCurves(fprm, lprm,
994 myHS1->FirstUParameter(), myHS1->LastUParameter(),
995 myHS1->FirstVParameter(), myHS1->LastVParameter(),
996 Tolpc, myHS1->Surface(), newc, C2d);
655fddc8 997 aCurve.SetFirstCurve2d(C2d);
998 }
655fddc8 999
1000 if(myApprox2) {
1001 Handle (Geom2d_Curve) C2d;
686926c0 1002 GeomInt_IntSS::BuildPCurves(fprm, lprm,
1003 myHS2->FirstUParameter(), myHS2->LastUParameter(),
1004 myHS2->FirstVParameter(), myHS2->LastVParameter(),
1005 Tolpc, myHS2->Surface(), newc, C2d);
655fddc8 1006 aCurve.SetSecondCurve2d(C2d);
1007 }
655fddc8 1008 }
5652dc62 1009 //
655fddc8 1010 mySeqOfCurve.Append(aCurve);
1011 //==============================================
c6541a0c 1012 } //if (Abs(fprm) > RealEpsilon() || Abs(lprm-2.*M_PI) > RealEpsilon())
7fd59977 1013
1014 else {
655fddc8 1015 // on regarde si on garde
1016 //
1017 if (aNbParts==1) {
1018// if (Abs(fprm) < RealEpsilon() && Abs(lprm-2.*M_PI) < RealEpsilon()) {
1019 if (Abs(fprm) <= aRealEpsilon && Abs(lprm-2.*M_PI) <= aRealEpsilon) {
1020 IntTools_Curve aCurve;
1021 Handle(Geom_TrimmedCurve) aTC3D=new Geom_TrimmedCurve(newc,fprm,lprm);
1022 aCurve.SetCurve(aTC3D);
1023 fprm=aTC3D->FirstParameter();
1024 lprm=aTC3D->LastParameter ();
1025
1026 if(myApprox1) {
1027 Handle (Geom2d_Curve) C2d;
d4b867e6 1028 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
c22b52d6 1029 myHS1->Surface(),newc,C2d);
655fddc8 1030 aCurve.SetFirstCurve2d(C2d);
1031 }
655fddc8 1032
1033 if(myApprox2) {
1034 Handle (Geom2d_Curve) C2d;
d4b867e6 1035 GeomInt_IntSS::BuildPCurves(fprm,lprm,Tolpc,
c22b52d6 1036 myHS2->Surface(),newc,C2d);
655fddc8 1037 aCurve.SetSecondCurve2d(C2d);
1038 }
5652dc62 1039 //
655fddc8 1040 mySeqOfCurve.Append(aCurve);
1041 break;
1042 }
1043 }
1044 //
1045 Standard_Real aTwoPIdiv17, u1, v1, u2, v2, Tol;
1046
1047 aTwoPIdiv17=2.*M_PI/17.;
1048
1049 for (j=0; j<=17; j++) {
1050 gp_Pnt ptref (newc->Value (j*aTwoPIdiv17));
1051 Tol = Precision::Confusion();
1052
1053 Parameters(myHS1, myHS2, ptref, u1, v1, u2, v2);
1054 ok = (dom1->Classify(gp_Pnt2d(u1,v1),Tol) != TopAbs_OUT);
1055 if(ok) {
1056 ok = (dom2->Classify(gp_Pnt2d(u2,v2),Tol) != TopAbs_OUT);
1057 }
1058 if (ok) {
1059 IntTools_Curve aCurve;
1060 aCurve.SetCurve(newc);
1061 //==============================================
1062 if (typl == IntPatch_Circle || typl == IntPatch_Ellipse) {
1063
1064 if(myApprox1) {
1065 Handle (Geom2d_Curve) C2d;
686926c0 1066 GeomInt_IntSS::BuildPCurves(fprm, lprm,
1067 myHS1->FirstUParameter(), myHS1->LastUParameter(),
1068 myHS1->FirstVParameter(), myHS1->LastVParameter(),
1069 Tolpc, myHS1->Surface(), newc, C2d);
655fddc8 1070 aCurve.SetFirstCurve2d(C2d);
1071 }
5652dc62 1072
655fddc8 1073 if(myApprox2) {
1074 Handle (Geom2d_Curve) C2d;
686926c0 1075 GeomInt_IntSS::BuildPCurves(fprm, lprm,
1076 myHS2->FirstUParameter(), myHS2->LastUParameter(),
1077 myHS2->FirstVParameter(), myHS2->LastVParameter(),
1078 Tolpc, myHS2->Surface(), newc, C2d);
655fddc8 1079 aCurve.SetSecondCurve2d(C2d);
1080 }
655fddc8 1081 }// end of if (typl == IntPatch_Circle || typl == IntPatch_Ellipse)
655fddc8 1082 //==============================================
1083 //
1084 mySeqOfCurve.Append(aCurve);
1085 break;
1086
1087 }// end of if (ok) {
1088 }// end of for (Standard_Integer j=0; j<=17; j++)
1089 }// end of else { on regarde si on garde
59495dbe 1090 }// for (i=1; i<=myLConstruct.NbParts(); i++)
1091 }// IntPatch_Circle: IntPatch_Ellipse:
1092 break;
1093
e2e0498b 1094 case IntPatch_Analytic:
1095 //This case was processed earlier (in IntPatch_Intersection)
59495dbe 1096 break;
7fd59977 1097
59495dbe 1098 case IntPatch_Walking:{
7fd59977 1099 Handle(IntPatch_WLine) WL =
1100 Handle(IntPatch_WLine)::DownCast(L);
7365fad6 1101
77dbd1f1 1102#ifdef INTTOOLS_FACEFACE_DEBUG
1103 WL->Dump(0);
7365fad6 1104#endif
1105
7fd59977 1106 //
1107 Standard_Integer ifprm, ilprm;
1108 //
1109 if (!myApprox) {
1110 aNbParts = 1;
1111 if(!bAvoidLineConstructor){
655fddc8 1112 aNbParts=myLConstruct.NbParts();
7fd59977 1113 }
1114 for (i=1; i<=aNbParts; ++i) {
655fddc8 1115 Handle(Geom2d_BSplineCurve) H1, H2;
1116 Handle(Geom_Curve) aBSp;
1117 //
1118 if(bAvoidLineConstructor) {
1119 ifprm = 1;
1120 ilprm = WL->NbPnts();
1121 }
1122 else {
1123 myLConstruct.Part(i, fprm, lprm);
1124 ifprm=(Standard_Integer)fprm;
1125 ilprm=(Standard_Integer)lprm;
1126 }
1127 //
1128 if(myApprox1) {
4e14c88f 1129 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
655fddc8 1130 }
1131 //
1132 if(myApprox2) {
4e14c88f 1133 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
655fddc8 1134 }
1135 //
4e14c88f 1136 aBSp=GeomInt_IntSS::MakeBSpline(WL, ifprm, ilprm);
655fddc8 1137 IntTools_Curve aIC(aBSp, H1, H2);
1138 mySeqOfCurve.Append(aIC);
7fd59977 1139 }// for (i=1; i<=aNbParts; ++i) {
1140 }// if (!myApprox) {
1141 //
1142 else { // X
1143 Standard_Boolean bIsDecomposited;
1144 Standard_Integer nbiter, aNbSeqOfL;
4abae870 1145 Standard_Real tol2d, aTolApproxImp;
7fd59977 1146 IntPatch_SequenceOfLine aSeqOfL;
1147 GeomInt_WLApprox theapp3d;
1148 Approx_ParametrizationType aParType = Approx_ChordLength;
1149 //
1150 Standard_Boolean anApprox1 = myApprox1;
1151 Standard_Boolean anApprox2 = myApprox2;
4abae870 1152 //
1153 aTolApproxImp=1.e-5;
7fd59977 1154 tol2d = myTolApprox;
1155
1156 GeomAbs_SurfaceType typs1, typs2;
c22b52d6 1157 typs1 = myHS1->GetType();
1158 typs2 = myHS2->GetType();
7fd59977 1159 Standard_Boolean anWithPC = Standard_True;
1160
1161 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
655fddc8 1162 anWithPC =
c22b52d6 1163 ApproxWithPCurves(myHS1->Cylinder(), myHS2->Sphere());
7fd59977 1164 }
1165 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
655fddc8 1166 anWithPC =
c22b52d6 1167 ApproxWithPCurves(myHS2->Cylinder(), myHS1->Sphere());
7fd59977 1168 }
4abae870 1169 //
7fd59977 1170 if(!anWithPC) {
4abae870 1171 myTolApprox = aTolApproxImp;//1.e-5;
655fddc8 1172 anApprox1 = Standard_False;
1173 anApprox2 = Standard_False;
1174 //
1175 tol2d = myTolApprox;
7fd59977 1176 }
655fddc8 1177
d33a8cde 1178 bIsDecomposited = IntTools_WLineTool::
1179 DecompositionOfWLine(WL,
1180 myHS1,
1181 myHS2,
1182 myFace1,
1183 myFace2,
1184 myLConstruct,
1185 bAvoidLineConstructor,
0d0481c7 1186 myTol,
d33a8cde 1187 aSeqOfL,
d33a8cde 1188 myContext);
7fd59977 1189 //
1190 aNbSeqOfL=aSeqOfL.Length();
1191 //
5652dc62 1192 Standard_Real aTolC = 0.;
7fd59977 1193 if (bIsDecomposited) {
655fddc8 1194 nbiter=aNbSeqOfL;
d7f50721 1195 aTolC = Precision::Confusion();
7fd59977 1196 }
1197 else {
655fddc8 1198 nbiter=1;
1199 aNbParts=1;
1200 if (!bAvoidLineConstructor) {
1201 aNbParts=myLConstruct.NbParts();
1202 nbiter=aNbParts;
1203 }
7fd59977 1204 }
1205 //
7fd59977 1206 for(i = 1; i <= nbiter; ++i) {
655fddc8 1207 if(bIsDecomposited) {
1208 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1209 ifprm = 1;
1210 ilprm = WL->NbPnts();
1211 }
1212 else {
1213 if(bAvoidLineConstructor) {
1214 ifprm = 1;
1215 ilprm = WL->NbPnts();
1216 }
1217 else {
1218 myLConstruct.Part(i, fprm, lprm);
1219 ifprm = (Standard_Integer)fprm;
1220 ilprm = (Standard_Integer)lprm;
1221 }
1222 }
9eee5ab7 1223
1224 Standard_Boolean anApprox = myApprox;
1225 if (typs1 == GeomAbs_Plane) {
1226 anApprox = Standard_False;
1227 anApprox1 = Standard_True;
1228 }
1229 else if (typs2 == GeomAbs_Plane) {
1230 anApprox = Standard_False;
1231 anApprox2 = Standard_True;
1232 }
1233
1234 aParType = ApproxInt_KnotTools::DefineParType(WL, ifprm, ilprm,
1235 anApprox, anApprox1, anApprox2);
1236 if (myHS1 == myHS2) {
1237 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1238 rejectSurface = Standard_True;
1239 }
1240 else {
1241 if (reApprox && !rejectSurface)
1242 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30, Standard_False, aParType);
1243 else {
1244 Standard_Integer iDegMax, iDegMin, iNbIter;
1245 //
1246 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1247 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax,
1248 iNbIter, 30, Standard_True, aParType);
1249 }
1250 }
1251
655fddc8 1252 //-- lbr :
1253 //-- Si une des surfaces est un plan , on approxime en 2d
1254 //-- sur cette surface et on remonte les points 2d en 3d.
1255 if(typs1 == GeomAbs_Plane) {
1256 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1257 }
1258 else if(typs2 == GeomAbs_Plane) {
1259 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1260 }
1261 else {
1262 //
1263 if (myHS1 != myHS2){
1264 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1265 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1266
4e14c88f 1267 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1268 Standard_True, aParType);
655fddc8 1269
1270 Standard_Boolean bUseSurfaces;
d33a8cde 1271 bUseSurfaces = IntTools_WLineTool::NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
655fddc8 1272 if (bUseSurfaces) {
1273 // ######
1274 rejectSurface = Standard_True;
1275 // ######
4e14c88f 1276 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, 30,
1277 Standard_False, aParType);
655fddc8 1278 }
1279 }
1280 }
1281 //
1282 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1283 }
1284 //
94218044 1285 if (!theapp3d.IsDone()) {
655fddc8 1286 Handle(Geom2d_BSplineCurve) H1;
94218044 1287 Handle(Geom2d_BSplineCurve) H2;
655fddc8 1288 //
4e14c88f 1289 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
4abae870 1290 //
655fddc8 1291 if(myApprox1) {
4e14c88f 1292 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
655fddc8 1293 }
4abae870 1294 //
655fddc8 1295 if(myApprox2) {
4e14c88f 1296 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
655fddc8 1297 }
1298 //
1299 IntTools_Curve aIC(aBSp, H1, H2);
1300 mySeqOfCurve.Append(aIC);
1301 }
655fddc8 1302 else {
5652dc62 1303 if (typs1 == GeomAbs_Plane || typs2 == GeomAbs_Plane) {
655fddc8 1304 //
5652dc62 1305 if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1306 if (aTolC < 1.e-6) {
1307 aTolC = 1.e-6;
655fddc8 1308 }
1309 }
1310 }
5652dc62 1311 //
655fddc8 1312 Standard_Integer aNbMultiCurves, nbpoles;
1313 aNbMultiCurves=theapp3d.NbMultiCurves();
1314 for (j=1; j<=aNbMultiCurves; j++) {
1315 if(typs1 == GeomAbs_Plane) {
1316 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1317 nbpoles = mbspc.NbPoles();
1318
1319 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1320 TColgp_Array1OfPnt tpoles(1,nbpoles);
1321
1322 mbspc.Curve(1,tpoles2d);
c22b52d6 1323 const gp_Pln& Pln = myHS1->Plane();
655fddc8 1324 //
1325 Standard_Integer ik;
1326 for(ik = 1; ik<= nbpoles; ik++) {
1327 tpoles.SetValue(ik,
1328 ElSLib::Value(tpoles2d.Value(ik).X(),
1329 tpoles2d.Value(ik).Y(),
1330 Pln));
1331 }
1332 //
1333 Handle(Geom_BSplineCurve) BS =
1334 new Geom_BSplineCurve(tpoles,
1335 mbspc.Knots(),
1336 mbspc.Multiplicities(),
1337 mbspc.Degree());
1338 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1339 Check.FixTangent(Standard_True, Standard_True);
1340 //
1341 IntTools_Curve aCurve;
1342 aCurve.SetCurve(BS);
1343
1344 if(myApprox1) {
1345 Handle(Geom2d_BSplineCurve) BS1 =
1346 new Geom2d_BSplineCurve(tpoles2d,
1347 mbspc.Knots(),
1348 mbspc.Multiplicities(),
1349 mbspc.Degree());
1350 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1351 Check1.FixTangent(Standard_True,Standard_True);
1352 //
1353 // ############################################
1354 if(!rejectSurface && !reApprox) {
1355 Standard_Boolean isValid = IsCurveValid(BS1);
1356 if(!isValid) {
1357 reApprox = Standard_True;
1358 goto reapprox;
1359 }
1360 }
1361 // ############################################
1362 aCurve.SetFirstCurve2d(BS1);
1363 }
655fddc8 1364
1365 if(myApprox2) {
1366 mbspc.Curve(2, tpoles2d);
1367
1368 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
1369 mbspc.Knots(),
1370 mbspc.Multiplicities(),
1371 mbspc.Degree());
1372 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1373 newCheck.FixTangent(Standard_True,Standard_True);
1374
1375 // ###########################################
1376 if(!rejectSurface && !reApprox) {
1377 Standard_Boolean isValid = IsCurveValid(BS2);
1378 if(!isValid) {
1379 reApprox = Standard_True;
1380 goto reapprox;
1381 }
1382 }
1383 // ###########################################
1384 //
1385 aCurve.SetSecondCurve2d(BS2);
1386 }
5652dc62 1387 //
1388 aCurve.SetTolerance(aTolC);
655fddc8 1389 //
1390 mySeqOfCurve.Append(aCurve);
0cbfb9f1 1391
4abae870 1392 }//if(typs1 == GeomAbs_Plane) {
655fddc8 1393
0cbfb9f1 1394 else if(typs2 == GeomAbs_Plane)
1395 {
655fddc8 1396 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1397 nbpoles = mbspc.NbPoles();
1398
1399 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1400 TColgp_Array1OfPnt tpoles(1,nbpoles);
1401 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
c22b52d6 1402 const gp_Pln& Pln = myHS2->Plane();
655fddc8 1403 //
1404 Standard_Integer ik;
1405 for(ik = 1; ik<= nbpoles; ik++) {
1406 tpoles.SetValue(ik,
1407 ElSLib::Value(tpoles2d.Value(ik).X(),
1408 tpoles2d.Value(ik).Y(),
1409 Pln));
1410
1411 }
1412 //
1413 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1414 mbspc.Knots(),
1415 mbspc.Multiplicities(),
1416 mbspc.Degree());
1417 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1418 Check.FixTangent(Standard_True,Standard_True);
1419 //
1420 IntTools_Curve aCurve;
1421 aCurve.SetCurve(BS);
5652dc62 1422 aCurve.SetTolerance(aTolC);
655fddc8 1423
1424 if(myApprox2) {
1425 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
1426 mbspc.Knots(),
1427 mbspc.Multiplicities(),
1428 mbspc.Degree());
1429 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
1430 Check1.FixTangent(Standard_True,Standard_True);
1431 //
1432 // ###########################################
1433 if(!rejectSurface && !reApprox) {
1434 Standard_Boolean isValid = IsCurveValid(BS1);
1435 if(!isValid) {
1436 reApprox = Standard_True;
1437 goto reapprox;
1438 }
1439 }
989341c5 1440 // ###########################################
51db0179 1441 bPCurvesOk = CheckPCurve(BS1, myFace2, myContext);
655fddc8 1442 aCurve.SetSecondCurve2d(BS1);
1443 }
5652dc62 1444
655fddc8 1445 if(myApprox1) {
1446 mbspc.Curve(1,tpoles2d);
1447 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1448 mbspc.Knots(),
1449 mbspc.Multiplicities(),
1450 mbspc.Degree());
1451 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
1452 Check2.FixTangent(Standard_True,Standard_True);
1453 //
1454 // ###########################################
1455 if(!rejectSurface && !reApprox) {
1456 Standard_Boolean isValid = IsCurveValid(BS2);
1457 if(!isValid) {
1458 reApprox = Standard_True;
1459 goto reapprox;
1460 }
1461 }
989341c5 1462 // ###########################################
51db0179 1463 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1, myContext);
655fddc8 1464 aCurve.SetFirstCurve2d(BS2);
1465 }
655fddc8 1466 //
989341c5 1467 //if points of the pcurves are out of the faces bounds
1468 //create 3d and 2d curves without approximation
1469 if (!bPCurvesOk) {
1470 Handle(Geom2d_BSplineCurve) H1, H2;
655fddc8 1471 bPCurvesOk = Standard_True;
1472 //
4e14c88f 1473 Handle(Geom_Curve) aBSp=GeomInt_IntSS::MakeBSpline(WL,ifprm, ilprm);
59495dbe 1474
989341c5 1475 if(myApprox1) {
4e14c88f 1476 H1 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
51db0179 1477 bPCurvesOk = CheckPCurve(H1, myFace1, myContext);
989341c5 1478 }
59495dbe 1479
989341c5 1480 if(myApprox2) {
4e14c88f 1481 H2 = GeomInt_IntSS::MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
51db0179 1482 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2, myContext);
989341c5 1483 }
1484 //
655fddc8 1485 //if pcurves created without approximation are out of the
1486 //faces bounds, use approximated 3d and 2d curves
1487 if (bPCurvesOk) {
5652dc62 1488 IntTools_Curve aIC(aBSp, H1, H2, aTolC);
655fddc8 1489 mySeqOfCurve.Append(aIC);
1490 } else {
1491 mySeqOfCurve.Append(aCurve);
1492 }
989341c5 1493 } else {
1494 mySeqOfCurve.Append(aCurve);
1495 }
0cbfb9f1 1496
4abae870 1497 }// else if(typs2 == GeomAbs_Plane)
1498 //
1499 else { //typs2 != GeomAbs_Plane && typs1 != GeomAbs_Plane
1500 Standard_Boolean bIsValid1, bIsValid2;
1501 Handle(Geom_BSplineCurve) BS;
5652dc62 1502 IntTools_Curve aCurve;
4abae870 1503 //
1504 bIsValid1=Standard_True;
1505 bIsValid2=Standard_True;
1506 //
655fddc8 1507 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1508 nbpoles = mbspc.NbPoles();
1509 TColgp_Array1OfPnt tpoles(1,nbpoles);
1510 mbspc.Curve(1,tpoles);
4abae870 1511 BS=new Geom_BSplineCurve(tpoles,
655fddc8 1512 mbspc.Knots(),
1513 mbspc.Multiplicities(),
1514 mbspc.Degree());
1515 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1516 Check.FixTangent(Standard_True,Standard_True);
5652dc62 1517 //
655fddc8 1518 aCurve.SetCurve(BS);
5652dc62 1519 aCurve.SetTolerance(aTolC);
4abae870 1520 //
655fddc8 1521 if(myApprox1) {
1522 if(anApprox1) {
4abae870 1523 Handle(Geom2d_BSplineCurve) BS1;
655fddc8 1524 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1525 mbspc.Curve(2,tpoles2d);
4abae870 1526 //
1527 BS1=new Geom2d_BSplineCurve(tpoles2d,
5652dc62 1528 mbspc.Knots(),
1529 mbspc.Multiplicities(),
1530 mbspc.Degree());
655fddc8 1531 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
1532 newCheck.FixTangent(Standard_True,Standard_True);
1533 //
4abae870 1534 if (!reApprox) {
51db0179 1535 bIsValid1=CheckPCurve(BS1, myFace1, myContext);
4abae870 1536 }
1537 //
655fddc8 1538 aCurve.SetFirstCurve2d(BS1);
1539 }
1540 else {
1541 Handle(Geom2d_BSplineCurve) BS1;
1542 fprm = BS->FirstParameter();
1543 lprm = BS->LastParameter();
1544
1545 Handle(Geom2d_Curve) C2d;
1546 Standard_Real aTol = myTolApprox;
d4b867e6 1547 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
c22b52d6 1548 myHS1->Surface(), BS, C2d);
655fddc8 1549 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1550 aCurve.SetFirstCurve2d(BS1);
1551 }
4abae870 1552 } // if(myApprox1) {
655fddc8 1553 //
1554 if(myApprox2) {
1555 if(anApprox2) {
4abae870 1556 Handle(Geom2d_BSplineCurve) BS2;
655fddc8 1557 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1558 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
4abae870 1559 BS2=new Geom2d_BSplineCurve(tpoles2d,
655fddc8 1560 mbspc.Knots(),
1561 mbspc.Multiplicities(),
1562 mbspc.Degree());
1563 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1564 newCheck.FixTangent(Standard_True,Standard_True);
1565 //
4abae870 1566 if (!reApprox) {
51db0179 1567 bIsValid2=CheckPCurve(BS2, myFace2, myContext);
4abae870 1568 }
655fddc8 1569 aCurve.SetSecondCurve2d(BS2);
1570 }
1571 else {
1572 Handle(Geom2d_BSplineCurve) BS2;
1573 fprm = BS->FirstParameter();
1574 lprm = BS->LastParameter();
1575
1576 Handle(Geom2d_Curve) C2d;
1577 Standard_Real aTol = myTolApprox;
d4b867e6 1578 GeomInt_IntSS::BuildPCurves(fprm, lprm, aTol,
c22b52d6 1579 myHS2->Surface(), BS, C2d);
655fddc8 1580 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
1581 aCurve.SetSecondCurve2d(BS2);
1582 }
4abae870 1583 } //if(myApprox2) {
1584 if (!bIsValid1 || !bIsValid2) {
1585 myTolApprox=aTolApproxImp;//1.e-5;
1586 tol2d = myTolApprox;
1587 reApprox = Standard_True;
1588 goto reapprox;
655fddc8 1589 }
1590 //
1591 mySeqOfCurve.Append(aCurve);
1592 }
1593 }
1594 }
7fd59977 1595 }
1596 }// else { // X
1597 }// case IntPatch_Walking:{
59495dbe 1598 break;
1599
7fd59977 1600 case IntPatch_Restriction:
d4b867e6 1601 {
d4b867e6 1602 Handle(IntPatch_RLine) RL =
1603 Handle(IntPatch_RLine)::DownCast(L);
77dbd1f1 1604
1605#ifdef INTTOOLS_FACEFACE_DEBUG
1606 RL->Dump(0);
1607#endif
1608
d4b867e6 1609 Handle(Geom_Curve) aC3d;
1610 Handle(Geom2d_Curve) aC2d1, aC2d2;
1611 Standard_Real aTolReached;
1612 GeomInt_IntSS::TreatRLine(RL, myHS1, myHS2, aC3d,
1613 aC2d1, aC2d2, aTolReached);
1614
1615 if(aC3d.IsNull())
1616 break;
1617
1618 Bnd_Box2d aBox1, aBox2;
1619
1620 const Standard_Real aU1f = myHS1->FirstUParameter(),
1621 aV1f = myHS1->FirstVParameter(),
1622 aU1l = myHS1->LastUParameter(),
1623 aV1l = myHS1->LastVParameter();
1624 const Standard_Real aU2f = myHS2->FirstUParameter(),
1625 aV2f = myHS2->FirstVParameter(),
1626 aU2l = myHS2->LastUParameter(),
1627 aV2l = myHS2->LastVParameter();
1628
1629 aBox1.Add(gp_Pnt2d(aU1f, aV1f));
1630 aBox1.Add(gp_Pnt2d(aU1l, aV1l));
1631 aBox2.Add(gp_Pnt2d(aU2f, aV2f));
1632 aBox2.Add(gp_Pnt2d(aU2l, aV2l));
1633
1634 GeomInt_VectorOfReal anArrayOfParameters;
655fddc8 1635
d4b867e6 1636 //We consider here that the intersection line is same-parameter-line
1637 anArrayOfParameters.Append(aC3d->FirstParameter());
1638 anArrayOfParameters.Append(aC3d->LastParameter());
1639
1640 GeomInt_IntSS::
1641 TrimILineOnSurfBoundaries(aC2d1, aC2d2, aBox1, aBox2, anArrayOfParameters);
1642
71958f7d 1643 //Intersect with true boundaries. After that, enlarge bounding-boxes in order to
1644 //correct definition, if point on curve is inscribed in the box.
1645 aBox1.Enlarge(theToler);
1646 aBox2.Enlarge(theToler);
1647
d4b867e6 1648 const Standard_Integer aNbIntersSolutionsm1 = anArrayOfParameters.Length() - 1;
1649
1650 //Trim RLine found.
1651 for(Standard_Integer anInd = 0; anInd < aNbIntersSolutionsm1; anInd++)
1652 {
71958f7d 1653 Standard_Real &aParF = anArrayOfParameters(anInd),
1654 &aParL = anArrayOfParameters(anInd+1);
d4b867e6 1655
1656 if((aParL - aParF) <= Precision::PConfusion())
71958f7d 1657 {
1658 //In order to more precise extending to the boundaries of source curves.
1659 if(anInd < aNbIntersSolutionsm1-1)
1660 aParL = aParF;
1661
d4b867e6 1662 continue;
71958f7d 1663 }
d4b867e6 1664
1665 const Standard_Real aPar = 0.5*(aParF + aParL);
1666 gp_Pnt2d aPt;
1667
1668 Handle(Geom2d_Curve) aCurv2d1, aCurv2d2;
1669 if(!aC2d1.IsNull())
1670 {
1671 aC2d1->D0(aPar, aPt);
1672
1673 if(aBox1.IsOut(aPt))
1674 continue;
1675
1676 if(myApprox1)
1677 aCurv2d1 = new Geom2d_TrimmedCurve(aC2d1, aParF, aParL);
4abae870 1678 }
d4b867e6 1679
1680 if(!aC2d2.IsNull())
1681 {
1682 aC2d2->D0(aPar, aPt);
1683
1684 if(aBox2.IsOut(aPt))
1685 continue;
1686
1687 if(myApprox2)
1688 aCurv2d2 = new Geom2d_TrimmedCurve(aC2d2, aParF, aParL);
1689 }
1690
1691 Handle(Geom_Curve) aCurv3d = new Geom_TrimmedCurve(aC3d, aParF, aParL);
1692
1693 IntTools_Curve aIC(aCurv3d, aCurv2d1, aCurv2d2);
1694 mySeqOfCurve.Append(aIC);
7fd59977 1695 }
1696 }
d4b867e6 1697 break;
1698 default:
1699 break;
1700
7fd59977 1701 }
7fd59977 1702}
1703
1704//=======================================================================
1705//function : Parameters
1706//purpose :
1707//=======================================================================
c22b52d6 1708 void Parameters(const Handle(GeomAdaptor_Surface)& HS1,
1709 const Handle(GeomAdaptor_Surface)& HS2,
655fddc8 1710 const gp_Pnt& Ptref,
1711 Standard_Real& U1,
1712 Standard_Real& V1,
1713 Standard_Real& U2,
1714 Standard_Real& V2)
7fd59977 1715{
1716
1717 IntSurf_Quadric quad1,quad2;
c22b52d6 1718 GeomAbs_SurfaceType typs = HS1->GetType();
7fd59977 1719
1720 switch (typs) {
1721 case GeomAbs_Plane:
c22b52d6 1722 quad1.SetValue(HS1->Plane());
7fd59977 1723 break;
1724 case GeomAbs_Cylinder:
c22b52d6 1725 quad1.SetValue(HS1->Cylinder());
7fd59977 1726 break;
1727 case GeomAbs_Cone:
c22b52d6 1728 quad1.SetValue(HS1->Cone());
7fd59977 1729 break;
1730 case GeomAbs_Sphere:
c22b52d6 1731 quad1.SetValue(HS1->Sphere());
7fd59977 1732 break;
7eed5d29 1733 case GeomAbs_Torus:
c22b52d6 1734 quad1.SetValue(HS1->Torus());
7eed5d29 1735 break;
7fd59977 1736 default:
9775fa61 1737 throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
7fd59977 1738 }
1739
c22b52d6 1740 typs = HS2->GetType();
7fd59977 1741 switch (typs) {
1742 case GeomAbs_Plane:
c22b52d6 1743 quad2.SetValue(HS2->Plane());
7fd59977 1744 break;
1745 case GeomAbs_Cylinder:
c22b52d6 1746 quad2.SetValue(HS2->Cylinder());
7fd59977 1747 break;
1748 case GeomAbs_Cone:
c22b52d6 1749 quad2.SetValue(HS2->Cone());
7fd59977 1750 break;
1751 case GeomAbs_Sphere:
c22b52d6 1752 quad2.SetValue(HS2->Sphere());
7fd59977 1753 break;
7eed5d29 1754 case GeomAbs_Torus:
c22b52d6 1755 quad2.SetValue(HS2->Torus());
7eed5d29 1756 break;
7fd59977 1757 default:
9775fa61 1758 throw Standard_ConstructionError("GeomInt_IntSS::MakeCurve");
7fd59977 1759 }
1760
1761 quad1.Parameters(Ptref,U1,V1);
1762 quad2.Parameters(Ptref,U2,V2);
1763}
1764
1765//=======================================================================
1766//function : MakeBSpline
1767//purpose :
1768//=======================================================================
1769Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
655fddc8 1770 const Standard_Integer ideb,
1771 const Standard_Integer ifin)
7fd59977 1772{
1773 Standard_Integer i,nbpnt = ifin-ideb+1;
1774 TColgp_Array1OfPnt poles(1,nbpnt);
1775 TColStd_Array1OfReal knots(1,nbpnt);
1776 TColStd_Array1OfInteger mults(1,nbpnt);
1777 Standard_Integer ipidebm1;
1778 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
1779 poles(i) = WL->Point(ipidebm1).Value();
1780 mults(i) = 1;
1781 knots(i) = i-1;
1782 }
1783 mults(1) = mults(nbpnt) = 2;
1784 return
1785 new Geom_BSplineCurve(poles,knots,mults,1);
1786}
7fd59977 1787
7fd59977 1788//=======================================================================
1789//function : PrepareLines3D
1790//purpose :
1791//=======================================================================
a9f7b6b5 1792 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
7fd59977 1793{
a9f7b6b5
P
1794 Standard_Integer i, aNbCurves;
1795 GeomAbs_SurfaceType aType1, aType2;
7fd59977 1796 IntTools_SequenceOfCurves aNewCvs;
7fd59977 1797 //
a9f7b6b5 1798 // 1. Treatment closed curves
7fd59977 1799 aNbCurves=mySeqOfCurve.Length();
a9f7b6b5 1800 for (i=1; i<=aNbCurves; ++i) {
7fd59977 1801 const IntTools_Curve& aIC=mySeqOfCurve(i);
7fd59977 1802 //
a9f7b6b5
P
1803 if (bToSplit) {
1804 Standard_Integer j, aNbC;
1805 IntTools_SequenceOfCurves aSeqCvs;
1806 //
1807 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
1808 if (aNbC) {
655fddc8 1809 for (j=1; j<=aNbC; ++j) {
1810 const IntTools_Curve& aICNew=aSeqCvs(j);
1811 aNewCvs.Append(aICNew);
1812 }
a9f7b6b5
P
1813 }
1814 else {
655fddc8 1815 aNewCvs.Append(aIC);
7fd59977 1816 }
1817 }
7fd59977 1818 else {
1819 aNewCvs.Append(aIC);
1820 }
1821 }
1822 //
1823 // 2. Plane\Cone intersection when we had 4 curves
a9f7b6b5
P
1824 aType1=myHS1->GetType();
1825 aType2=myHS2->GetType();
1826 aNbCurves=aNewCvs.Length();
1827 //
7fd59977 1828 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
1829 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
7fd59977 1830 if (aNbCurves==4) {
a9f7b6b5
P
1831 GeomAbs_CurveType aCType1;
1832 //
1833 aCType1=aNewCvs(1).Type();
7fd59977 1834 if (aCType1==GeomAbs_Line) {
655fddc8 1835 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
1836 //
1837 for (i=1; i<=aNbCurves; ++i) {
1838 const IntTools_Curve& aIC=aNewCvs(i);
1839 aSeqIn.Append(aIC);
1840 }
1841 //
1842 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
1843 //
1844 aNewCvs.Clear();
1845 aNbCurves=aSeqOut.Length();
1846 for (i=1; i<=aNbCurves; ++i) {
1847 const IntTools_Curve& aIC=aSeqOut(i);
1848 aNewCvs.Append(aIC);
1849 }
7fd59977 1850 }
1851 }
a9f7b6b5 1852 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
7fd59977 1853 //
1854 // 3. Fill mySeqOfCurve
1855 mySeqOfCurve.Clear();
1856 aNbCurves=aNewCvs.Length();
a9f7b6b5 1857 for (i=1; i<=aNbCurves; ++i) {
7fd59977 1858 const IntTools_Curve& aIC=aNewCvs(i);
1859 mySeqOfCurve.Append(aIC);
1860 }
7fd59977 1861}
7fd59977 1862//=======================================================================
1863//function : CorrectSurfaceBoundaries
1864//purpose :
1865//=======================================================================
59495dbe 1866 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
c002793b 1867 const Standard_Real theTolerance,
1868 Standard_Real& theumin,
1869 Standard_Real& theumax,
1870 Standard_Real& thevmin,
1871 Standard_Real& thevmax)
7fd59977 1872{
1873 Standard_Boolean enlarge, isuperiodic, isvperiodic;
1874 Standard_Real uinf, usup, vinf, vsup, delta;
1875 GeomAbs_SurfaceType aType;
1876 Handle(Geom_Surface) aSurface;
1877 //
1878 aSurface = BRep_Tool::Surface(theFace);
1879 aSurface->Bounds(uinf, usup, vinf, vsup);
1880 delta = theTolerance;
1881 enlarge = Standard_False;
1882 //
1883 GeomAdaptor_Surface anAdaptorSurface(aSurface);
1884 //
1885 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
1886 Handle(Geom_Surface) aBasisSurface =
1887 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
1888
1889 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
1890 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1891 return;
1892 }
1893 }
1894 //
1895 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1896 Handle(Geom_Surface) aBasisSurface =
1897 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
1898
1899 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
1900 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
1901 return;
1902 }
1903 }
1904 //
1905 isuperiodic = anAdaptorSurface.IsUPeriodic();
1906 isvperiodic = anAdaptorSurface.IsVPeriodic();
1907 //
1908 aType=anAdaptorSurface.GetType();
1909 if((aType==GeomAbs_BezierSurface) ||
1910 (aType==GeomAbs_BSplineSurface) ||
1911 (aType==GeomAbs_SurfaceOfExtrusion) ||
c002793b 1912 (aType==GeomAbs_SurfaceOfRevolution) ||
1913 (aType==GeomAbs_Cylinder)) {
7fd59977 1914 enlarge=Standard_True;
1915 }
1916 //
9eee5ab7 1917
7fd59977 1918 if(!isuperiodic && enlarge) {
1919
d4b867e6 1920 if(!Precision::IsInfinite(theumin) &&
1921 ((theumin - uinf) > delta))
7fd59977 1922 theumin -= delta;
1923 else {
1924 theumin = uinf;
1925 }
1926
d4b867e6 1927 if(!Precision::IsInfinite(theumax) &&
1928 ((usup - theumax) > delta))
7fd59977 1929 theumax += delta;
1930 else
1931 theumax = usup;
1932 }
9eee5ab7 1933
7fd59977 1934 //
1935 if(!isvperiodic && enlarge) {
d4b867e6 1936 if(!Precision::IsInfinite(thevmin) &&
1937 ((thevmin - vinf) > delta)) {
7fd59977 1938 thevmin -= delta;
1939 }
1940 else {
1941 thevmin = vinf;
1942 }
d4b867e6 1943 if(!Precision::IsInfinite(thevmax) &&
1944 ((vsup - thevmax) > delta)) {
7fd59977 1945 thevmax += delta;
1946 }
1947 else {
1948 thevmax = vsup;
1949 }
1950 }
9eee5ab7 1951
7fd59977 1952 //
7fd59977 1953 if(isuperiodic || isvperiodic) {
1954 Standard_Boolean correct = Standard_False;
1955 Standard_Boolean correctU = Standard_False;
1956 Standard_Boolean correctV = Standard_False;
1957 Bnd_Box2d aBox;
1958 TopExp_Explorer anExp;
1959
1960 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
1961 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
655fddc8 1962 correct = Standard_True;
1963 Standard_Real f, l;
1964 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1965
1966 for(Standard_Integer i = 0; i < 2; i++) {
1967 if(i==0) {
1968 anEdge.Orientation(TopAbs_FORWARD);
1969 }
1970 else {
1971 anEdge.Orientation(TopAbs_REVERSED);
1972 }
1973 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
1974
1975 if(aCurve.IsNull()) {
1976 correct = Standard_False;
1977 break;
1978 }
1979 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
1980
1981 if(aLine.IsNull()) {
1982 correct = Standard_False;
1983 break;
1984 }
1985 gp_Dir2d anUDir(1., 0.);
1986 gp_Dir2d aVDir(0., 1.);
1987 Standard_Real anAngularTolerance = Precision::Angular();
1988
1989 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
1990 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
1991
1992 gp_Pnt2d pp1 = aCurve->Value(f);
1993 aBox.Add(pp1);
1994 gp_Pnt2d pp2 = aCurve->Value(l);
1995 aBox.Add(pp2);
1996 }
1997 if(!correct)
1998 break;
7fd59977 1999 }
2000 }
2001
2002 if(correct) {
2003 Standard_Real umin, vmin, umax, vmax;
2004 aBox.Get(umin, vmin, umax, vmax);
2005
2006 if(isuperiodic && correctU) {
655fddc8 2007 if(theumin < umin)
2008 theumin = umin;
655fddc8 2009 if(theumax > umax) {
2010 theumax = umax;
2011 }
7fd59977 2012 }
2013 if(isvperiodic && correctV) {
655fddc8 2014 if(thevmin < vmin)
2015 thevmin = vmin;
2016 if(thevmax > vmax)
2017 thevmax = vmax;
7fd59977 2018 }
2019 }
2020 }
2021}
4e57c75e 2022
d33a8cde 2023// ------------------------------------------------------------------------------------------------
2024// static function: ParameterOutOfBoundary
2025// purpose: Computes a new parameter for given curve. The corresponding 2d points
2026// does not lay on any boundary of given faces
2027// ------------------------------------------------------------------------------------------------
2028Standard_Boolean ParameterOutOfBoundary(const Standard_Real theParameter,
2029 const Handle(Geom_Curve)& theCurve,
2030 const TopoDS_Face& theFace1,
2031 const TopoDS_Face& theFace2,
2032 const Standard_Real theOtherParameter,
2033 const Standard_Boolean bIncreasePar,
0d0481c7 2034 const Standard_Real theTol,
d33a8cde 2035 Standard_Real& theNewParameter,
2036 const Handle(IntTools_Context)& aContext)
7fd59977 2037{
d33a8cde 2038 Standard_Boolean bIsComputed = Standard_False;
2039 theNewParameter = theParameter;
2040
2041 Standard_Real acurpar = theParameter;
2042 TopAbs_State aState = TopAbs_ON;
2043 Standard_Integer iter = 0;
0d0481c7 2044 Standard_Real asumtol = theTol;
d33a8cde 2045 Standard_Real adelta = asumtol * 0.1;
2046 adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
2047 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
2048 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
2049
2050 Standard_Real u1, u2, v1, v2;
2051
2052 GeomAPI_ProjectPointOnSurf aPrj1;
2053 aSurf1->Bounds(u1, u2, v1, v2);
2054 aPrj1.Init(aSurf1, u1, u2, v1, v2);
2055
2056 GeomAPI_ProjectPointOnSurf aPrj2;
2057 aSurf2->Bounds(u1, u2, v1, v2);
2058 aPrj2.Init(aSurf2, u1, u2, v1, v2);
2059
2060 while(aState == TopAbs_ON) {
2061 if(bIncreasePar)
2062 acurpar += adelta;
2063 else
2064 acurpar -= adelta;
2065 gp_Pnt aPCurrent = theCurve->Value(acurpar);
2066 aPrj1.Perform(aPCurrent);
2067 Standard_Real U=0., V=0.;
2068
2069 if(aPrj1.IsDone()) {
2070 aPrj1.LowerDistanceParameters(U, V);
2071 aState = aContext->StatePointFace(theFace1, gp_Pnt2d(U, V));
7fd59977 2072 }
d33a8cde 2073
2074 if(aState != TopAbs_ON) {
2075 aPrj2.Perform(aPCurrent);
2076
2077 if(aPrj2.IsDone()) {
2078 aPrj2.LowerDistanceParameters(U, V);
2079 aState = aContext->StatePointFace(theFace2, gp_Pnt2d(U, V));
2080 }
7fd59977 2081 }
d33a8cde 2082
2083 if(iter > 11) {
2084 break;
7fd59977 2085 }
d33a8cde 2086 iter++;
7fd59977 2087 }
d33a8cde 2088
2089 if(iter <= 11) {
2090 theNewParameter = acurpar;
2091 bIsComputed = Standard_True;
2092
2093 if(bIncreasePar) {
2094 if(acurpar >= theOtherParameter)
2095 theNewParameter = theOtherParameter;
7fd59977 2096 }
d33a8cde 2097 else {
2098 if(acurpar <= theOtherParameter)
2099 theNewParameter = theOtherParameter;
7fd59977 2100 }
2101 }
d33a8cde 2102 return bIsComputed;
7fd59977 2103}
2104
2105//=======================================================================
d33a8cde 2106//function : IsCurveValid
7fd59977 2107//purpose :
2108//=======================================================================
aa00364d 2109Standard_Boolean IsCurveValid (const Handle(Geom2d_Curve)& thePCurve)
7fd59977 2110{
d33a8cde 2111 if(thePCurve.IsNull())
2112 return Standard_False;
7fd59977 2113
d33a8cde 2114 Standard_Real tolint = 1.e-10;
2115 Geom2dAdaptor_Curve PCA;
2116 IntRes2d_Domain PCD;
2117 Geom2dInt_GInter PCI;
2118
2119 Standard_Real pf = 0., pl = 0.;
2120 gp_Pnt2d pntf, pntl;
2121
2122 if(!thePCurve->IsClosed() && !thePCurve->IsPeriodic()) {
2123 pf = thePCurve->FirstParameter();
2124 pl = thePCurve->LastParameter();
2125 pntf = thePCurve->Value(pf);
2126 pntl = thePCurve->Value(pl);
2127 PCA.Load(thePCurve);
2128 if(!PCA.IsPeriodic()) {
2129 if(PCA.FirstParameter() > pf) pf = PCA.FirstParameter();
2130 if(PCA.LastParameter() < pl) pl = PCA.LastParameter();
7fd59977 2131 }
d33a8cde 2132 PCD.SetValues(pntf,pf,tolint,pntl,pl,tolint);
2133 PCI.Perform(PCA,PCD,tolint,tolint);
2134 if(PCI.IsDone())
2135 if(PCI.NbPoints() > 0) {
2136 return Standard_False;
2137 }
7fd59977 2138 }
d33a8cde 2139
2140 return Standard_True;
2141}
2142
2143//=======================================================================
2144//static function : ApproxWithPCurves
2145//purpose : for bug 20964 only
2146//=======================================================================
2147Standard_Boolean ApproxWithPCurves(const gp_Cylinder& theCyl,
2148 const gp_Sphere& theSph)
2149{
2150 Standard_Boolean bRes = Standard_True;
2151 Standard_Real R1 = theCyl.Radius(), R2 = theSph.Radius();
7fd59977 2152 //
d33a8cde 2153 {
2154 Standard_Real aD2, aRc2, aEps;
2155 gp_Pnt aApexSph;
2156 //
2157 aEps=1.E-7;
2158 aRc2=R1*R1;
2159 //
2160 const gp_Ax3& aAx3Sph=theSph.Position();
2161 const gp_Pnt& aLocSph=aAx3Sph.Location();
2162 const gp_Dir& aDirSph=aAx3Sph.Direction();
2163 //
2164 const gp_Ax1& aAx1Cyl=theCyl.Axis();
2165 gp_Lin aLinCyl(aAx1Cyl);
2166 //
2167 aApexSph.SetXYZ(aLocSph.XYZ()+R2*aDirSph.XYZ());
2168 aD2=aLinCyl.SquareDistance(aApexSph);
2169 if (fabs(aD2-aRc2)<aEps) {
2170 return !bRes;
7fd59977 2171 }
d33a8cde 2172 //
2173 aApexSph.SetXYZ(aLocSph.XYZ()-R2*aDirSph.XYZ());
2174 aD2=aLinCyl.SquareDistance(aApexSph);
2175 if (fabs(aD2-aRc2)<aEps) {
2176 return !bRes;
7fd59977 2177 }
d33a8cde 2178 }
2179 //
7fd59977 2180
d33a8cde 2181 if(R1 < 2.*R2) {
2182 return bRes;
7fd59977 2183 }
d33a8cde 2184 gp_Lin anCylAx(theCyl.Axis());
7fd59977 2185
d33a8cde 2186 Standard_Real aDist = anCylAx.Distance(theSph.Location());
2187 Standard_Real aDRel = Abs(aDist - R1)/R2;
0cbfb9f1 2188
d33a8cde 2189 if(aDRel > .2) return bRes;
0cbfb9f1 2190
d33a8cde 2191 Standard_Real par = ElCLib::Parameter(anCylAx, theSph.Location());
2192 gp_Pnt aP = ElCLib::Value(par, anCylAx);
2193 gp_Vec aV(aP, theSph.Location());
0cbfb9f1 2194
d33a8cde 2195 Standard_Real dd = aV.Dot(theSph.Position().XDirection());
0cbfb9f1 2196
d33a8cde 2197 if(aDist < R1 && dd > 0.) return Standard_False;
2198 if(aDist > R1 && dd < 0.) return Standard_False;
0cbfb9f1 2199
d33a8cde 2200
2201 return bRes;
0cbfb9f1 2202}
d33a8cde 2203//=======================================================================
2204//function : PerformPlanes
2205//purpose :
2206//=======================================================================
c22b52d6 2207void PerformPlanes(const Handle(GeomAdaptor_Surface)& theS1,
2208 const Handle(GeomAdaptor_Surface)& theS2,
5652dc62 2209 const Standard_Real TolF1,
2210 const Standard_Real TolF2,
2211 const Standard_Real TolAng,
2212 const Standard_Real TolTang,
d33a8cde 2213 const Standard_Boolean theApprox1,
2214 const Standard_Boolean theApprox2,
5652dc62 2215 IntTools_SequenceOfCurves& theSeqOfCurve,
2216 Standard_Boolean& theTangentFaces)
0cbfb9f1 2217{
7fd59977 2218
c22b52d6 2219 gp_Pln aPln1 = theS1->Plane();
2220 gp_Pln aPln2 = theS2->Plane();
7fd59977 2221
d33a8cde 2222 IntAna_QuadQuadGeo aPlnInter(aPln1, aPln2, TolAng, TolTang);
7fd59977 2223
2224 if(!aPlnInter.IsDone()) {
2225 theTangentFaces = Standard_False;
2226 return;
2227 }
2228
2229 IntAna_ResultType aResType = aPlnInter.TypeInter();
2230
2231 if(aResType == IntAna_Same) {
2232 theTangentFaces = Standard_True;
2233 return;
2234 }
2235
2236 theTangentFaces = Standard_False;
2237
2238 if(aResType == IntAna_Empty) {
2239 return;
2240 }
2241
2242 gp_Lin aLin = aPlnInter.Line(1);
2243
2244 ProjLib_Plane aProj;
2245
2246 aProj.Init(aPln1);
2247 aProj.Project(aLin);
2248 gp_Lin2d aLin2d1 = aProj.Line();
2249 //
2250 aProj.Init(aPln2);
2251 aProj.Project(aLin);
2252 gp_Lin2d aLin2d2 = aProj.Line();
2253 //
2254 //classify line2d1 relatively first plane
2255 Standard_Real P11, P12;
2256 Standard_Boolean IsCrossed = ClassifyLin2d(theS1, aLin2d1, TolTang, P11, P12);
2257 if(!IsCrossed) return;
2258 //classify line2d2 relatively second plane
2259 Standard_Real P21, P22;
2260 IsCrossed = ClassifyLin2d(theS2, aLin2d2, TolTang, P21, P22);
2261 if(!IsCrossed) return;
2262
2263 //Analysis of parametric intervals: must have common part
2264
2265 if(P21 >= P12) return;
2266 if(P22 <= P11) return;
2267
2268 Standard_Real pmin, pmax;
2269 pmin = Max(P11, P21);
2270 pmax = Min(P12, P22);
2271
2272 if(pmax - pmin <= TolTang) return;
2273
2274 Handle(Geom_Line) aGLin = new Geom_Line(aLin);
2275
2276 IntTools_Curve aCurve;
2277 Handle(Geom_TrimmedCurve) aGTLin = new Geom_TrimmedCurve(aGLin, pmin, pmax);
2278
2279 aCurve.SetCurve(aGTLin);
2280
2281 if(theApprox1) {
2282 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d1);
2283 aCurve.SetFirstCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2284 }
2285 else {
2286 Handle(Geom2d_Curve) H1;
2287 aCurve.SetFirstCurve2d(H1);
2288 }
2289 if(theApprox2) {
2290 Handle(Geom2d_Line) C2d = new Geom2d_Line(aLin2d2);
2291 aCurve.SetSecondCurve2d(new Geom2d_TrimmedCurve(C2d, pmin, pmax));
2292 }
2293 else {
2294 Handle(Geom2d_Curve) H1;
2295 aCurve.SetFirstCurve2d(H1);
2296 }
3510db62 2297 //
5652dc62 2298 // Valid tolerance for the intersection curve between planar faces
2299 // is the maximal tolerance between tolerances of faces
2300 Standard_Real aTolC = Max(TolF1, TolF2);
2301 aCurve.SetTolerance(aTolC);
2302 //
2303 // Computation of the tangential tolerance
3510db62 2304 Standard_Real anAngle, aDt;
2305 gp_Dir aD1, aD2;
2306 //
2307 aD1 = aPln1.Position().Direction();
2308 aD2 = aPln2.Position().Direction();
2309 anAngle = aD1.Angle(aD2);
2310 //
2311 aDt = IntTools_Tools::ComputeIntRange(TolF1, TolF2, anAngle);
5652dc62 2312 Standard_Real aTangTol = sqrt(aDt*aDt + TolF1*TolF1);
2313 //
2314 aCurve.SetTangentialTolerance(aTangTol);
2315 //
2316 theSeqOfCurve.Append(aCurve);
7fd59977 2317}
2318
2319//=======================================================================
2320//function : ClassifyLin2d
2321//purpose :
2322//=======================================================================
2323static inline Standard_Boolean INTER(const Standard_Real d1,
655fddc8 2324 const Standard_Real d2,
2325 const Standard_Real tol)
7fd59977 2326{
2327 return (d1 > tol && d2 < -tol) ||
2328 (d1 < -tol && d2 > tol) ||
2329 ((d1 <= tol && d1 >= -tol) && (d2 > tol || d2 < -tol)) ||
2330 ((d2 <= tol && d2 >= -tol) && (d1 > tol || d1 < -tol));
2331}
2332static inline Standard_Boolean COINC(const Standard_Real d1,
655fddc8 2333 const Standard_Real d2,
2334 const Standard_Real tol)
7fd59977 2335{
2336 return (d1 <= tol && d1 >= -tol) && (d2 <= tol && d2 >= -tol);
2337}
c22b52d6 2338Standard_Boolean ClassifyLin2d(const Handle(GeomAdaptor_Surface)& theS,
655fddc8 2339 const gp_Lin2d& theLin2d,
2340 const Standard_Real theTol,
2341 Standard_Real& theP1,
2342 Standard_Real& theP2)
7fd59977 2343
2344{
2345 Standard_Real xmin, xmax, ymin, ymax, d1, d2, A, B, C;
2346 Standard_Real par[2];
2347 Standard_Integer nbi = 0;
2348
c22b52d6 2349 xmin = theS->FirstUParameter();
2350 xmax = theS->LastUParameter();
2351 ymin = theS->FirstVParameter();
2352 ymax = theS->LastVParameter();
7fd59977 2353
2354 theLin2d.Coefficients(A, B, C);
2355
2356 //xmin, ymin <-> xmin, ymax
2357 d1 = A*xmin + B*ymin + C;
2358 d2 = A*xmin + B*ymax + C;
2359
2360 if(INTER(d1, d2, theTol)) {
2361 //Intersection with boundary
2362 Standard_Real y = -(C + A*xmin)/B;
2363 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, y));
2364 nbi++;
2365 }
2366 else if (COINC(d1, d2, theTol)) {
2367 //Coincidence with boundary
2368 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2369 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2370 nbi = 2;
2371 }
2372
2373 if(nbi == 2) {
2374
2375 if(fabs(par[0]-par[1]) > theTol) {
2376 theP1 = Min(par[0], par[1]);
2377 theP2 = Max(par[0], par[1]);
2378 return Standard_True;
2379 }
2380 else return Standard_False;
2381
2382 }
2383
2384 //xmin, ymax <-> xmax, ymax
2385 d1 = d2;
2386 d2 = A*xmax + B*ymax + C;
2387
2388 if(d1 > theTol || d1 < -theTol) {//to avoid checking of
2389 //coincidence with the same point
2390 if(INTER(d1, d2, theTol)) {
2391 Standard_Real x = -(C + B*ymax)/A;
2392 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymax));
2393 nbi++;
2394 }
2395 else if (COINC(d1, d2, theTol)) {
2396 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymax));
2397 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2398 nbi = 2;
2399 }
2400 }
2401
2402 if(nbi == 2) {
2403
2404 if(fabs(par[0]-par[1]) > theTol) {
2405 theP1 = Min(par[0], par[1]);
2406 theP2 = Max(par[0], par[1]);
2407 return Standard_True;
2408 }
2409 else return Standard_False;
2410
2411 }
2412
2413 //xmax, ymax <-> xmax, ymin
2414 d1 = d2;
2415 d2 = A*xmax + B*ymin + C;
2416
2417 if(d1 > theTol || d1 < -theTol) {
2418 if(INTER(d1, d2, theTol)) {
2419 Standard_Real y = -(C + A*xmax)/B;
2420 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, y));
2421 nbi++;
2422 }
2423 else if (COINC(d1, d2, theTol)) {
2424 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymax));
2425 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2426 nbi = 2;
2427 }
2428 }
2429
2430 if(nbi == 2) {
2431 if(fabs(par[0]-par[1]) > theTol) {
2432 theP1 = Min(par[0], par[1]);
2433 theP2 = Max(par[0], par[1]);
2434 return Standard_True;
2435 }
2436 else return Standard_False;
2437 }
2438
2439 //xmax, ymin <-> xmin, ymin
2440 d1 = d2;
2441 d2 = A*xmin + B*ymin + C;
2442
2443 if(d1 > theTol || d1 < -theTol) {
2444 if(INTER(d1, d2, theTol)) {
2445 Standard_Real x = -(C + B*ymin)/A;
2446 par[nbi] = ElCLib::Parameter(theLin2d, gp_Pnt2d(x, ymin));
2447 nbi++;
2448 }
2449 else if (COINC(d1, d2, theTol)) {
2450 par[0] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmax, ymin));
2451 par[1] = ElCLib::Parameter(theLin2d, gp_Pnt2d(xmin, ymin));
2452 nbi = 2;
2453 }
2454 }
2455
2456 if(nbi == 2) {
2457 if(fabs(par[0]-par[1]) > theTol) {
2458 theP1 = Min(par[0], par[1]);
2459 theP2 = Max(par[0], par[1]);
2460 return Standard_True;
2461 }
2462 else return Standard_False;
2463 }
2464
2465 return Standard_False;
2466
2467}
2468//
7fd59977 2469//=======================================================================
2470//function : ApproxParameters
2471//purpose :
2472//=======================================================================
c22b52d6 2473void ApproxParameters(const Handle(GeomAdaptor_Surface)& aHS1,
2474 const Handle(GeomAdaptor_Surface)& aHS2,
655fddc8 2475 Standard_Integer& iDegMin,
2476 Standard_Integer& iDegMax,
2477 Standard_Integer& iNbIter)
4f189102 2478
7fd59977 2479{
2480 GeomAbs_SurfaceType aTS1, aTS2;
0fc4f2e2 2481
7fd59977 2482 //
4f189102 2483 iNbIter=0;
7fd59977 2484 iDegMin=4;
2485 iDegMax=8;
7fd59977 2486 //
c22b52d6 2487 aTS1=aHS1->GetType();
2488 aTS2=aHS2->GetType();
7fd59977 2489 //
2490 // Cylinder/Torus
2491 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2492 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
0fc4f2e2 2493 Standard_Real aRC, aRT, dR, aPC;
7fd59977 2494 gp_Cylinder aCylinder;
2495 gp_Torus aTorus;
2496 //
2497 aPC=Precision::Confusion();
2498 //
c22b52d6 2499 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Cylinder() : aHS2->Cylinder();
2500 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Torus() : aHS2->Torus();
7fd59977 2501 //
2502 aRC=aCylinder.Radius();
2503 aRT=aTorus.MinorRadius();
2504 dR=aRC-aRT;
2505 if (dR<0.) {
2506 dR=-dR;
2507 }
2508 //
2509 if (dR<aPC) {
0fc4f2e2
P
2510 iDegMax=6;
2511 }
2512 }
4f189102 2513 if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
8e0115e4 2514 iNbIter=1;
4f189102 2515 }
0fc4f2e2
P
2516}
2517//=======================================================================
2518//function : Tolerances
2519//purpose :
2520//=======================================================================
c22b52d6 2521void Tolerances(const Handle(GeomAdaptor_Surface)& aHS1,
2522 const Handle(GeomAdaptor_Surface)& aHS2,
788cbaf4 2523 Standard_Real& aTolTang)
0fc4f2e2
P
2524{
2525 GeomAbs_SurfaceType aTS1, aTS2;
2526 //
c22b52d6 2527 aTS1=aHS1->GetType();
2528 aTS2=aHS2->GetType();
0fc4f2e2
P
2529 //
2530 // Cylinder/Torus
2531 if ((aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Torus) ||
2532 (aTS2==GeomAbs_Cylinder && aTS1==GeomAbs_Torus)) {
2533 Standard_Real aRC, aRT, dR, aPC;
2534 gp_Cylinder aCylinder;
2535 gp_Torus aTorus;
2536 //
2537 aPC=Precision::Confusion();
2538 //
c22b52d6 2539 aCylinder=(aTS1==GeomAbs_Cylinder)? aHS1->Cylinder() : aHS2->Cylinder();
2540 aTorus=(aTS1==GeomAbs_Torus)? aHS1->Torus() : aHS2->Torus();
0fc4f2e2
P
2541 //
2542 aRC=aCylinder.Radius();
2543 aRT=aTorus.MinorRadius();
2544 dR=aRC-aRT;
2545 if (dR<0.) {
2546 dR=-dR;
7fd59977 2547 }
0fc4f2e2
P
2548 //
2549 if (dR<aPC) {
2550 aTolTang=0.1*aTolTang;
2551 }
2552 }
2553}
0fc4f2e2
P
2554//=======================================================================
2555//function : SortTypes
2556//purpose :
2557//=======================================================================
2558Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
655fddc8 2559 const GeomAbs_SurfaceType aType2)
0fc4f2e2
P
2560{
2561 Standard_Boolean bRet;
2562 Standard_Integer aI1, aI2;
2563 //
2564 bRet=Standard_False;
2565 //
2566 aI1=IndexType(aType1);
2567 aI2=IndexType(aType2);
2568 if (aI1<aI2){
2569 bRet=!bRet;
2570 }
2571 return bRet;
2572}
2573//=======================================================================
2574//function : IndexType
2575//purpose :
2576//=======================================================================
2577Standard_Integer IndexType(const GeomAbs_SurfaceType aType)
2578{
2579 Standard_Integer aIndex;
2580 //
2581 aIndex=11;
2582 //
2583 if (aType==GeomAbs_Plane) {
2584 aIndex=0;
7fd59977 2585 }
0fc4f2e2
P
2586 else if (aType==GeomAbs_Cylinder) {
2587 aIndex=1;
2588 }
2589 else if (aType==GeomAbs_Cone) {
2590 aIndex=2;
2591 }
2592 else if (aType==GeomAbs_Sphere) {
2593 aIndex=3;
2594 }
2595 else if (aType==GeomAbs_Torus) {
2596 aIndex=4;
2597 }
2598 else if (aType==GeomAbs_BezierSurface) {
2599 aIndex=5;
2600 }
2601 else if (aType==GeomAbs_BSplineSurface) {
2602 aIndex=6;
2603 }
2604 else if (aType==GeomAbs_SurfaceOfRevolution) {
2605 aIndex=7;
2606 }
2607 else if (aType==GeomAbs_SurfaceOfExtrusion) {
2608 aIndex=8;
2609 }
2610 else if (aType==GeomAbs_OffsetSurface) {
2611 aIndex=9;
2612 }
2613 else if (aType==GeomAbs_OtherSurface) {
2614 aIndex=10;
2615 }
2616 return aIndex;
7fd59977 2617}
260f924f 2618
631633a2 2619//=======================================================================
2620// Function : FindMaxDistance
2621// purpose :
2622//=======================================================================
2623Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theCurve,
2624 const Standard_Real theFirst,
2625 const Standard_Real theLast,
2626 const TopoDS_Face& theFace,
2627 const Handle(IntTools_Context)& theContext)
2628{
2629 Standard_Integer aNbS;
2630 Standard_Real aT1, aT2, aDt, aD, aDMax, anEps;
2631 //
2632 aNbS = 11;
2633 aDt = (theLast - theFirst) / aNbS;
2634 aDMax = 0.;
2635 anEps = 1.e-4 * aDt;
2636 //
2637 GeomAPI_ProjectPointOnSurf& aProjPS = theContext->ProjPS(theFace);
2638 aT2 = theFirst;
2639 for (;;) {
2640 aT1 = aT2;
2641 aT2 += aDt;
2642 //
2643 if (aT2 > theLast) {
2644 break;
2645 }
2646 //
2647 aD = FindMaxDistance(theCurve, aT1, aT2, aProjPS, anEps);
2648 if (aD > aDMax) {
2649 aDMax = aD;
2650 }
2651 }
2652 //
2653 return aDMax;
2654}
2655
2656//=======================================================================
2657// Function : FindMaxDistance
2658// purpose :
2659//=======================================================================
2660Standard_Real FindMaxDistance(const Handle(Geom_Curve)& theC,
2661 const Standard_Real theFirst,
2662 const Standard_Real theLast,
2663 GeomAPI_ProjectPointOnSurf& theProjPS,
2664 const Standard_Real theEps)
2665{
2666 Standard_Real aA, aB, aCf, aX, aX1, aX2, aF1, aF2, aF;
2667 //
2668 aCf = 0.61803398874989484820458683436564;//(sqrt(5.)-1)/2.;
2669 aA = theFirst;
2670 aB = theLast;
2671 //
f542b7bb 2672 aX1=aB - aCf*(aB-aA);
631633a2 2673 aF1 = MaxDistance(theC, aX1, theProjPS);
2674 aX2 = aA + aCf * (aB - aA);
2675 aF2 = MaxDistance(theC, aX2, theProjPS);
f542b7bb 2676
2677 while (Abs(aX1-aX2) > theEps)
2678 {
631633a2 2679 if (aF1 > aF2) {
2680 aB = aX2;
2681 aX2 = aX1;
2682 aF2 = aF1;
f542b7bb 2683 aX1 = aB-aCf*(aB-aA);
631633a2 2684 aF1 = MaxDistance(theC, aX1, theProjPS);
2685 }
2686 else {
2687 aA = aX1;
2688 aX1 = aX2;
2689 aF1 = aF2;
f542b7bb 2690 aX2=aA+aCf*(aB-aA);
631633a2 2691 aF2 = MaxDistance(theC, aX2, theProjPS);
2692 }
2693 }
2694 //
2695 aX = 0.5 * (aA + aB);
2696 aF = MaxDistance(theC, aX, theProjPS);
2697 //
2698 if (aF1 > aF) {
2699 aF = aF1;
2700 }
2701 //
2702 if (aF2 > aF) {
2703 aF = aF2;
2704 }
2705 //
2706 return aF;
2707}
2708
1b7ae951 2709//=======================================================================
2710// Function : MaxDistance
2711// purpose :
2712//=======================================================================
2713Standard_Real MaxDistance(const Handle(Geom_Curve)& theC,
2714 const Standard_Real aT,
2715 GeomAPI_ProjectPointOnSurf& theProjPS)
2716{
2717 Standard_Real aD;
2718 gp_Pnt aP;
2719 //
2720 theC->D0(aT, aP);
2721 theProjPS.Perform(aP);
2722 aD = theProjPS.NbPoints() ? theProjPS.LowerDistance() : 0.;
2723 //
2724 return aD;
4f189102 2725}
989341c5 2726
2727//=======================================================================
2728//function : CheckPCurve
2729//purpose : Checks if points of the pcurve are out of the face bounds.
2730//=======================================================================
51db0179 2731 Standard_Boolean CheckPCurve(const Handle(Geom2d_Curve)& aPC,
2732 const TopoDS_Face& aFace,
2733 const Handle(IntTools_Context)& theCtx)
989341c5 2734{
2735 const Standard_Integer NPoints = 23;
4abae870 2736 Standard_Integer i;
989341c5 2737 Standard_Real umin,umax,vmin,vmax;
2738
51db0179 2739 theCtx->UVBounds(aFace, umin, umax, vmin, vmax);
989341c5 2740 Standard_Real tolU = Max ((umax-umin)*0.01, Precision::Confusion());
2741 Standard_Real tolV = Max ((vmax-vmin)*0.01, Precision::Confusion());
2742 Standard_Real fp = aPC->FirstParameter();
2743 Standard_Real lp = aPC->LastParameter();
59495dbe 2744
989341c5 2745
2746 // adjust domain for periodic surfaces
2747 TopLoc_Location aLoc;
2748 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
4abae870 2749 if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
989341c5 2750 aSurf = (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf))->BasisSurface();
4abae870 2751 }
989341c5 2752 gp_Pnt2d pnt = aPC->Value((fp+lp)/2);
2753 Standard_Real u,v;
2754 pnt.Coord(u,v);
4abae870 2755 //
989341c5 2756 if (aSurf->IsUPeriodic()) {
2757 Standard_Real aPer = aSurf->UPeriod();
2758 Standard_Integer nshift = (Standard_Integer) ((u-umin)/aPer);
2759 if (u < umin+aPer*nshift) nshift--;
2760 umin += aPer*nshift;
2761 umax += aPer*nshift;
2762 }
2763 if (aSurf->IsVPeriodic()) {
2764 Standard_Real aPer = aSurf->VPeriod();
2765 Standard_Integer nshift = (Standard_Integer) ((v-vmin)/aPer);
2766 if (v < vmin+aPer*nshift) nshift--;
2767 vmin += aPer*nshift;
2768 vmax += aPer*nshift;
2769 }
4abae870 2770 //
2771 //--------------------------------------------------------
2772 Standard_Boolean bRet;
2773 Standard_Integer j, aNbIntervals;
2774 Standard_Real aT, dT;
2775 gp_Pnt2d aP2D;
2776 //
2777 Geom2dAdaptor_Curve aGAC(aPC);
2778 aNbIntervals=aGAC.NbIntervals(GeomAbs_CN);
2779 //
2780 TColStd_Array1OfReal aTI(1, aNbIntervals+1);
2781 aGAC.Intervals(aTI,GeomAbs_CN);
2782 //
2783 bRet=Standard_False;
2784 //
2785 aT=aGAC.FirstParameter();
2786 for (j=1; j<=aNbIntervals; ++j) {
2787 dT=(aTI(j+1)-aTI(j))/NPoints;
2788 //
2789 for (i=1; i<NPoints; i++) {
2790 aT=aT+dT;
2791 aGAC.D0(aT, aP2D);
2792 aP2D.Coord(u,v);
59495dbe 2793 if (umin-u > tolU || u-umax > tolU ||
4abae870 2794 vmin-v > tolV || v-vmax > tolV) {
2795 return bRet;
59495dbe 2796 }
2797}
989341c5 2798 }
4abae870 2799 return !bRet;
989341c5 2800}
9a5a19e9 2801//=======================================================================
2802//function : CorrectPlaneBoundaries
2803//purpose :
2804//=======================================================================
2805 void CorrectPlaneBoundaries(Standard_Real& aUmin,
2806 Standard_Real& aUmax,
2807 Standard_Real& aVmin,
2808 Standard_Real& aVmax)
2809{
2810 if (!(Precision::IsInfinite(aUmin) ||
2811 Precision::IsInfinite(aUmax))) {
2812 Standard_Real dU;
2813 //
2814 dU=0.1*(aUmax-aUmin);
2815 aUmin=aUmin-dU;
2816 aUmax=aUmax+dU;
2817 }
2818 if (!(Precision::IsInfinite(aVmin) ||
2819 Precision::IsInfinite(aVmax))) {
2820 Standard_Real dV;
2821 //
2822 dV=0.1*(aVmax-aVmin);
2823 aVmin=aVmin-dV;
2824 aVmax=aVmax+dV;
2825 }
2826}