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