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