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