0024489: Avoid type casts in call to Standard::Free()
[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;
1648 default:
1649 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 1");
1650 }
1651
7fd59977 1652 typs = myHS2->Surface().GetType();
94218044 1653
7fd59977 1654 switch (typs) {
94218044 1655 case GeomAbs_Plane:
1656 quad2.SetValue(myHS2->Surface().Plane());
1657 break;
1658 case GeomAbs_Cylinder:
1659 quad2.SetValue(myHS2->Surface().Cylinder());
1660 break;
1661 case GeomAbs_Cone:
1662 quad2.SetValue(myHS2->Surface().Cone());
1663 break;
1664 case GeomAbs_Sphere:
1665 quad2.SetValue(myHS2->Surface().Sphere());
1666 break;
1667 default:
1668 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve 2");
1669 }
7fd59977 1670 //
1671 //=========
1672 IntPatch_ALineToWLine convert (quad1, quad2);
94218044 1673
7fd59977 1674 if (!myApprox) {
1675 aNbParts=myLConstruct.NbParts();
1676 for (i=1; i<=aNbParts; i++) {
94218044 1677 myLConstruct.Part(i, fprm, lprm);
1678 Handle(IntPatch_WLine) WL =
1679 convert.MakeWLine(Handle(IntPatch_ALine)::DownCast(L), fprm, lprm);
1680 //
1681 Handle(Geom2d_BSplineCurve) H1;
1682 Handle(Geom2d_BSplineCurve) H2;
7fd59977 1683
94218044 1684 if(myApprox1) {
1685 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1686 }
1687
1688 if(myApprox2) {
1689 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1690 }
1691 //
1692 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
7fd59977 1693 }
1694 } // if (!myApprox)
1695
1696 else { // myApprox=TRUE
1697 GeomInt_WLApprox theapp3d;
1698 //
1699 Standard_Real tol2d = myTolApprox;
1700 //
1701 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True);
94218044 1702
7fd59977 1703 aNbParts=myLConstruct.NbParts();
1704 for (i=1; i<=aNbParts; i++) {
94218044 1705 myLConstruct.Part(i, fprm, lprm);
1706 Handle(IntPatch_WLine) WL =
1707 convert.MakeWLine(Handle(IntPatch_ALine):: DownCast(L),fprm,lprm);
7fd59977 1708
94218044 1709 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,myApprox1,myApprox2, 1, WL->NbPnts());
7fd59977 1710
94218044 1711 if (!theapp3d.IsDone()) {
1712 //
1713 Handle(Geom2d_BSplineCurve) H1;
1714 Handle(Geom2d_BSplineCurve) H2;
7fd59977 1715
94218044 1716 if(myApprox1) {
1717 H1 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_True);
1718 }
7fd59977 1719
94218044 1720 if(myApprox2) {
1721 H2 = MakeBSpline2d(WL, 1, WL->NbPnts(), Standard_False);
1722 }
1723 //
1724 mySeqOfCurve.Append(IntTools_Curve(MakeBSpline(WL,1,WL->NbPnts()), H1, H2));
1725 }
1726
1727 else {
1728 if(myApprox1 || myApprox2) {
1729 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0) {
1730 myTolReached2d = theapp3d.TolReached2d();
1731 }
1732 }
1733
1734 if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0) {
1735 myTolReached3d = theapp3d.TolReached3d();
1736 }
7fd59977 1737
94218044 1738 Standard_Integer aNbMultiCurves, nbpoles;
1739 aNbMultiCurves=theapp3d.NbMultiCurves();
1740 for (j=1; j<=aNbMultiCurves; j++) {
1741 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
1742 nbpoles = mbspc.NbPoles();
1743
1744 TColgp_Array1OfPnt tpoles(1, nbpoles);
1745 mbspc.Curve(1, tpoles);
1746 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
1747 mbspc.Knots(),
1748 mbspc.Multiplicities(),
1749 mbspc.Degree());
1750
1751 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
1752 Check.FixTangent(Standard_True,Standard_True);
1753 //
1754 IntTools_Curve aCurve;
1755 aCurve.SetCurve(BS);
1756
1757 if(myApprox1) {
1758 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
1759 mbspc.Curve(2,tpoles2d);
1760 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
1761 mbspc.Knots(),
1762 mbspc.Multiplicities(),
1763 mbspc.Degree());
1764
1765 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1766 newCheck.FixTangent(Standard_True,Standard_True);
1767 //
1768 aCurve.SetFirstCurve2d(BS2);
1769 }
1770 else {
1771 Handle(Geom2d_BSplineCurve) H1;
1772 aCurve.SetFirstCurve2d(H1);
1773 }
1774
1775 if(myApprox2) {
1776 TColgp_Array1OfPnt2d tpoles2d(1, nbpoles);
1777 Standard_Integer TwoOrThree;
1778 TwoOrThree=myApprox1 ? 3 : 2;
1779 mbspc.Curve(TwoOrThree, tpoles2d);
1780 Handle(Geom2d_BSplineCurve) BS2 =new Geom2d_BSplineCurve(tpoles2d,
1781 mbspc.Knots(),
1782 mbspc.Multiplicities(),
1783 mbspc.Degree());
1784
1785 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
1786 newCheck.FixTangent(Standard_True,Standard_True);
1787 //
1788 aCurve.SetSecondCurve2d(BS2);
1789 }
1790 else {
1791 Handle(Geom2d_BSplineCurve) H2;
1792 aCurve.SetSecondCurve2d(H2);
1793 }
1794 //
1795 mySeqOfCurve.Append(aCurve);
1796
1797 }// for (j=1; j<=aNbMultiCurves; j++) {
1798 }// else from if (!theapp3d.IsDone())
7fd59977 1799 }// for (i=1; i<=aNbParts; i++) {
1800 }// else { // myApprox=TRUE
1801 }// case IntPatch_Analytic:
94218044 1802 break;
7fd59977 1803
1804 case IntPatch_Walking:{
1805 Handle(IntPatch_WLine) WL =
1806 Handle(IntPatch_WLine)::DownCast(L);
1807 //
1808 Standard_Integer ifprm, ilprm;
1809 //
1810 if (!myApprox) {
1811 aNbParts = 1;
1812 if(!bAvoidLineConstructor){
94218044 1813 aNbParts=myLConstruct.NbParts();
7fd59977 1814 }
1815 for (i=1; i<=aNbParts; ++i) {
94218044 1816 Handle(Geom2d_BSplineCurve) H1, H2;
1817 Handle(Geom_Curve) aBSp;
1818 //
1819 if(bAvoidLineConstructor) {
1820 ifprm = 1;
1821 ilprm = WL->NbPnts();
1822 }
1823 else {
1824 myLConstruct.Part(i, fprm, lprm);
1825 ifprm=(Standard_Integer)fprm;
1826 ilprm=(Standard_Integer)lprm;
1827 }
1828 //
1829 if(myApprox1) {
1830 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1831 }
1832 //
1833 if(myApprox2) {
1834 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1835 }
1836 //
1837 aBSp=MakeBSpline(WL, ifprm, ilprm);
1838 IntTools_Curve aIC(aBSp, H1, H2);
1839 mySeqOfCurve.Append(aIC);
7fd59977 1840 }// for (i=1; i<=aNbParts; ++i) {
1841 }// if (!myApprox) {
1842 //
1843 else { // X
1844 Standard_Boolean bIsDecomposited;
1845 Standard_Integer nbiter, aNbSeqOfL;
1846 Standard_Real tol2d;
1847 IntPatch_SequenceOfLine aSeqOfL;
1848 GeomInt_WLApprox theapp3d;
1849 Approx_ParametrizationType aParType = Approx_ChordLength;
1850 //
1851 Standard_Boolean anApprox1 = myApprox1;
1852 Standard_Boolean anApprox2 = myApprox2;
1853
1854 tol2d = myTolApprox;
1855
1856 GeomAbs_SurfaceType typs1, typs2;
1857 typs1 = myHS1->Surface().GetType();
1858 typs2 = myHS2->Surface().GetType();
1859 Standard_Boolean anWithPC = Standard_True;
1860
1861 if(typs1 == GeomAbs_Cylinder && typs2 == GeomAbs_Sphere) {
94218044 1862 anWithPC =
1863 ApproxWithPCurves(myHS1->Surface().Cylinder(), myHS2->Surface().Sphere());
7fd59977 1864 }
1865 else if (typs1 == GeomAbs_Sphere && typs2 == GeomAbs_Cylinder) {
94218044 1866 anWithPC =
1867 ApproxWithPCurves(myHS2->Surface().Cylinder(), myHS1->Surface().Sphere());
7fd59977 1868 }
1869 if(!anWithPC) {
94218044 1870 //aParType = Approx_Centripetal;
1871 myTolApprox = 1.e-5;
1872 anApprox1 = Standard_False;
1873 anApprox2 = Standard_False;
1874 //
1875 tol2d = myTolApprox;
7fd59977 1876 }
94218044 1877
7fd59977 1878 if(myHS1 == myHS2) {
94218044 1879 //
1880 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1881 rejectSurface = Standard_True;
7fd59977 1882 }
1883 else {
94218044 1884 if(reApprox && !rejectSurface)
1885 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1886 else {
1887 Standard_Integer iDegMax, iDegMin, iNbIter;
1888 //
1889 ApproxParameters(myHS1, myHS2, iDegMin, iDegMax, iNbIter);
1890 theapp3d.SetParameters(myTolApprox, tol2d, iDegMin, iDegMax, iNbIter, Standard_True, aParType);
1891 //
1892 }
7fd59977 1893 }
1894 //
1895 Standard_Real aReachedTol = Precision::Confusion();
1896 bIsDecomposited=DecompositionOfWLine(WL,
94218044 1897 myHS1,
1898 myHS2,
1899 myFace1,
1900 myFace2,
1901 myLConstruct,
1902 bAvoidLineConstructor,
1903 aSeqOfL,
1904 aReachedTol,
1905 myContext);
7fd59977 1906 if ( bIsDecomposited && ( myTolReached3d < aReachedTol ) )
94218044 1907 myTolReached3d = aReachedTol;
7fd59977 1908
1909 //
1910 aNbSeqOfL=aSeqOfL.Length();
1911 //
1912 if (bIsDecomposited) {
94218044 1913 nbiter=aNbSeqOfL;
7fd59977 1914 }
1915 else {
94218044 1916 nbiter=1;
1917 aNbParts=1;
1918 if (!bAvoidLineConstructor) {
1919 aNbParts=myLConstruct.NbParts();
1920 nbiter=aNbParts;
1921 }
7fd59977 1922 }
1923 //
1924 // nbiter=(bIsDecomposited) ? aSeqOfL.Length() :
1925 // ((bAvoidLineConstructor) ? 1 :aNbParts);
1926 //
1927 for(i = 1; i <= nbiter; ++i) {
94218044 1928 if(bIsDecomposited) {
1929 WL = Handle(IntPatch_WLine)::DownCast(aSeqOfL.Value(i));
1930 ifprm = 1;
1931 ilprm = WL->NbPnts();
1932 }
1933 else {
1934 if(bAvoidLineConstructor) {
1935 ifprm = 1;
1936 ilprm = WL->NbPnts();
1937 }
1938 else {
1939 myLConstruct.Part(i, fprm, lprm);
1940 ifprm = (Standard_Integer)fprm;
1941 ilprm = (Standard_Integer)lprm;
1942 }
1943 }
1944 //-- lbr :
1945 //-- Si une des surfaces est un plan , on approxime en 2d
1946 //-- sur cette surface et on remonte les points 2d en 3d.
1947 if(typs1 == GeomAbs_Plane) {
1948 theapp3d.Perform(myHS1, myHS2, WL, Standard_False,Standard_True, myApprox2,ifprm,ilprm);
1949 }
1950 else if(typs2 == GeomAbs_Plane) {
1951 theapp3d.Perform(myHS1,myHS2,WL,Standard_False,myApprox1,Standard_True,ifprm,ilprm);
1952 }
1953 else {
1954 //
1955 if (myHS1 != myHS2){
1956 if ((typs1==GeomAbs_BezierSurface || typs1==GeomAbs_BSplineSurface) &&
1957 (typs2==GeomAbs_BezierSurface || typs2==GeomAbs_BSplineSurface)) {
1958
1959 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_True, aParType);
1960
1961 Standard_Boolean bUseSurfaces;
1962 bUseSurfaces=NotUseSurfacesForApprox(myFace1, myFace2, WL, ifprm, ilprm);
1963 if (bUseSurfaces) {
1964 // ######
1965 rejectSurface = Standard_True;
1966 // ######
1967 theapp3d.SetParameters(myTolApprox, tol2d, 4, 8, 0, Standard_False, aParType);
1968 }
1969 }
1970 }
1971 //
1972 theapp3d.Perform(myHS1,myHS2,WL,Standard_True,anApprox1,anApprox2,ifprm,ilprm);
1973 }
1974
1975 if (!theapp3d.IsDone()) {
1976 //
1977 Handle(Geom2d_BSplineCurve) H1;
1978 //
1979 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
1980 Handle(Geom2d_BSplineCurve) H2;
1981
1982 if(myApprox1) {
1983 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
1984 }
1985
1986 if(myApprox2) {
1987 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
1988 }
1989 //
1990 IntTools_Curve aIC(aBSp, H1, H2);
1991 mySeqOfCurve.Append(aIC);
1992 }
1993
1994 else {
1995 if(myApprox1 || myApprox2 || (typs1==GeomAbs_Plane || typs2==GeomAbs_Plane)) {
1996 if( theapp3d.TolReached2d()>myTolReached2d || myTolReached2d==0.) {
1997 myTolReached2d = theapp3d.TolReached2d();
1998 }
1999 }
2000 if(typs1==GeomAbs_Plane || typs2==GeomAbs_Plane) {
2001 myTolReached3d = myTolReached2d;
2002 //
2003 if (typs1==GeomAbs_Torus || typs2==GeomAbs_Torus) {
2004 if (myTolReached3d<1.e-6) {
2005 myTolReached3d = theapp3d.TolReached3d();
2006 myTolReached3d=1.e-6;
2007 }
2008 }
2009 //
2010 }
2011 else if( theapp3d.TolReached3d()>myTolReached3d || myTolReached3d==0.) {
2012 myTolReached3d = theapp3d.TolReached3d();
2013 }
2014
2015 Standard_Integer aNbMultiCurves, nbpoles;
2016 aNbMultiCurves=theapp3d.NbMultiCurves();
2017 for (j=1; j<=aNbMultiCurves; j++) {
2018 if(typs1 == GeomAbs_Plane) {
2019 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2020 nbpoles = mbspc.NbPoles();
2021
2022 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2023 TColgp_Array1OfPnt tpoles(1,nbpoles);
2024
2025 mbspc.Curve(1,tpoles2d);
2026 const gp_Pln& Pln = myHS1->Surface().Plane();
2027 //
2028 Standard_Integer ik;
2029 for(ik = 1; ik<= nbpoles; ik++) {
2030 tpoles.SetValue(ik,
2031 ElSLib::Value(tpoles2d.Value(ik).X(),
2032 tpoles2d.Value(ik).Y(),
2033 Pln));
2034 }
2035 //
2036 Handle(Geom_BSplineCurve) BS =
2037 new Geom_BSplineCurve(tpoles,
2038 mbspc.Knots(),
2039 mbspc.Multiplicities(),
2040 mbspc.Degree());
2041 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2042 Check.FixTangent(Standard_True, Standard_True);
2043 //
2044 IntTools_Curve aCurve;
2045 aCurve.SetCurve(BS);
2046
2047 if(myApprox1) {
2048 Handle(Geom2d_BSplineCurve) BS1 =
2049 new Geom2d_BSplineCurve(tpoles2d,
2050 mbspc.Knots(),
2051 mbspc.Multiplicities(),
2052 mbspc.Degree());
2053 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
2054 Check1.FixTangent(Standard_True,Standard_True);
2055 //
2056 // ############################################
2057 if(!rejectSurface && !reApprox) {
2058 Standard_Boolean isValid = IsCurveValid(BS1);
2059 if(!isValid) {
2060 reApprox = Standard_True;
2061 goto reapprox;
2062 }
2063 }
2064 // ############################################
2065 aCurve.SetFirstCurve2d(BS1);
2066 }
2067 else {
2068 Handle(Geom2d_BSplineCurve) H1;
2069 aCurve.SetFirstCurve2d(H1);
2070 }
2071
2072 if(myApprox2) {
2073 mbspc.Curve(2, tpoles2d);
2074
2075 Handle(Geom2d_BSplineCurve) BS2 = new Geom2d_BSplineCurve(tpoles2d,
2076 mbspc.Knots(),
2077 mbspc.Multiplicities(),
2078 mbspc.Degree());
2079 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
2080 newCheck.FixTangent(Standard_True,Standard_True);
2081
2082 // ###########################################
2083 if(!rejectSurface && !reApprox) {
2084 Standard_Boolean isValid = IsCurveValid(BS2);
2085 if(!isValid) {
2086 reApprox = Standard_True;
2087 goto reapprox;
2088 }
2089 }
2090 // ###########################################
2091 //
2092 aCurve.SetSecondCurve2d(BS2);
2093 }
2094 else {
2095 Handle(Geom2d_BSplineCurve) H2;
2096 //
2097 aCurve.SetSecondCurve2d(H2);
2098 }
2099 //
2100 mySeqOfCurve.Append(aCurve);
2101 }
2102
2103 else if(typs2 == GeomAbs_Plane) {
2104 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2105 nbpoles = mbspc.NbPoles();
2106
2107 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2108 TColgp_Array1OfPnt tpoles(1,nbpoles);
2109 mbspc.Curve((myApprox1==Standard_True)? 2 : 1,tpoles2d);
2110 const gp_Pln& Pln = myHS2->Surface().Plane();
2111 //
2112 Standard_Integer ik;
2113 for(ik = 1; ik<= nbpoles; ik++) {
2114 tpoles.SetValue(ik,
2115 ElSLib::Value(tpoles2d.Value(ik).X(),
2116 tpoles2d.Value(ik).Y(),
2117 Pln));
2118
2119 }
2120 //
2121 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
2122 mbspc.Knots(),
2123 mbspc.Multiplicities(),
2124 mbspc.Degree());
2125 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2126 Check.FixTangent(Standard_True,Standard_True);
2127 //
2128 IntTools_Curve aCurve;
2129 aCurve.SetCurve(BS);
2130
2131 if(myApprox2) {
2132 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
2133 mbspc.Knots(),
2134 mbspc.Multiplicities(),
2135 mbspc.Degree());
2136 GeomLib_Check2dBSplineCurve Check1(BS1,TOLCHECK,TOLANGCHECK);
2137 Check1.FixTangent(Standard_True,Standard_True);
2138 //
2139 // ###########################################
2140 if(!rejectSurface && !reApprox) {
2141 Standard_Boolean isValid = IsCurveValid(BS1);
2142 if(!isValid) {
2143 reApprox = Standard_True;
2144 goto reapprox;
2145 }
2146 }
989341c5 2147 // ###########################################
2148 bPCurvesOk = CheckPCurve(BS1, myFace2);
94218044 2149 aCurve.SetSecondCurve2d(BS1);
2150 }
2151 else {
2152 Handle(Geom2d_BSplineCurve) H2;
2153 aCurve.SetSecondCurve2d(H2);
2154 }
2155
2156 if(myApprox1) {
2157 mbspc.Curve(1,tpoles2d);
2158 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2159 mbspc.Knots(),
2160 mbspc.Multiplicities(),
2161 mbspc.Degree());
2162 GeomLib_Check2dBSplineCurve Check2(BS2,TOLCHECK,TOLANGCHECK);
2163 Check2.FixTangent(Standard_True,Standard_True);
2164 //
2165 // ###########################################
2166 if(!rejectSurface && !reApprox) {
2167 Standard_Boolean isValid = IsCurveValid(BS2);
2168 if(!isValid) {
2169 reApprox = Standard_True;
2170 goto reapprox;
2171 }
2172 }
989341c5 2173 // ###########################################
2174 bPCurvesOk = bPCurvesOk && CheckPCurve(BS2, myFace1);
94218044 2175 aCurve.SetFirstCurve2d(BS2);
2176 }
2177 else {
2178 Handle(Geom2d_BSplineCurve) H1;
2179 //
2180 aCurve.SetFirstCurve2d(H1);
2181 }
2182 //
989341c5 2183 //if points of the pcurves are out of the faces bounds
2184 //create 3d and 2d curves without approximation
2185 if (!bPCurvesOk) {
2186 Handle(Geom2d_BSplineCurve) H1, H2;
94218044 2187 bPCurvesOk = Standard_True;
989341c5 2188 //
2189 Handle(Geom_Curve) aBSp=MakeBSpline(WL,ifprm, ilprm);
94218044 2190
989341c5 2191 if(myApprox1) {
2192 H1 = MakeBSpline2d(WL, ifprm, ilprm, Standard_True);
94218044 2193 bPCurvesOk = CheckPCurve(H1, myFace1);
989341c5 2194 }
94218044 2195
989341c5 2196 if(myApprox2) {
2197 H2 = MakeBSpline2d(WL, ifprm, ilprm, Standard_False);
94218044 2198 bPCurvesOk = bPCurvesOk && CheckPCurve(H2, myFace2);
989341c5 2199 }
2200 //
94218044 2201 //if pcurves created without approximation are out of the
2202 //faces bounds, use approximated 3d and 2d curves
2203 if (bPCurvesOk) {
2204 IntTools_Curve aIC(aBSp, H1, H2);
2205 mySeqOfCurve.Append(aIC);
2206 } else {
2207 mySeqOfCurve.Append(aCurve);
2208 }
989341c5 2209 } else {
2210 mySeqOfCurve.Append(aCurve);
2211 }
94218044 2212 }
2213 else {
2214 const AppParCurves_MultiBSpCurve& mbspc = theapp3d.Value(j);
2215 nbpoles = mbspc.NbPoles();
2216 TColgp_Array1OfPnt tpoles(1,nbpoles);
2217 mbspc.Curve(1,tpoles);
2218 Handle(Geom_BSplineCurve) BS=new Geom_BSplineCurve(tpoles,
2219 mbspc.Knots(),
2220 mbspc.Multiplicities(),
2221 mbspc.Degree());
2222 GeomLib_CheckBSplineCurve Check(BS,TOLCHECK,TOLANGCHECK);
2223 Check.FixTangent(Standard_True,Standard_True);
2224 //
2225 IntTools_Curve aCurve;
2226 aCurve.SetCurve(BS);
2227
2228 if(myApprox1) {
2229 if(anApprox1) {
2230 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2231 mbspc.Curve(2,tpoles2d);
2232 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(tpoles2d,
2233 mbspc.Knots(),
2234 mbspc.Multiplicities(),
2235 mbspc.Degree());
2236 GeomLib_Check2dBSplineCurve newCheck(BS1,TOLCHECK,TOLANGCHECK);
2237 newCheck.FixTangent(Standard_True,Standard_True);
2238 //
2239 aCurve.SetFirstCurve2d(BS1);
2240 }
2241 else {
2242 Handle(Geom2d_BSplineCurve) BS1;
2243 fprm = BS->FirstParameter();
2244 lprm = BS->LastParameter();
2245
2246 Handle(Geom2d_Curve) C2d;
2247 Standard_Real aTol = myTolApprox;
2248 BuildPCurves(fprm, lprm, aTol, myHS1->ChangeSurface().Surface(), BS, C2d);
2249 BS1 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2250 aCurve.SetFirstCurve2d(BS1);
2251 }
2252
2253 }
2254 else {
2255 Handle(Geom2d_BSplineCurve) H1;
2256 //
2257 aCurve.SetFirstCurve2d(H1);
2258 }
2259 if(myApprox2) {
2260 if(anApprox2) {
2261 TColgp_Array1OfPnt2d tpoles2d(1,nbpoles);
2262 mbspc.Curve((myApprox1==Standard_True)? 3 : 2,tpoles2d);
2263 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(tpoles2d,
2264 mbspc.Knots(),
2265 mbspc.Multiplicities(),
2266 mbspc.Degree());
2267 GeomLib_Check2dBSplineCurve newCheck(BS2,TOLCHECK,TOLANGCHECK);
2268 newCheck.FixTangent(Standard_True,Standard_True);
2269 //
2270 aCurve.SetSecondCurve2d(BS2);
2271 }
2272 else {
2273 Handle(Geom2d_BSplineCurve) BS2;
2274 fprm = BS->FirstParameter();
2275 lprm = BS->LastParameter();
2276
2277 Handle(Geom2d_Curve) C2d;
2278 Standard_Real aTol = myTolApprox;
2279 BuildPCurves(fprm, lprm, aTol, myHS2->ChangeSurface().Surface(), BS, C2d);
2280 BS2 = Handle(Geom2d_BSplineCurve)::DownCast(C2d);
2281 aCurve.SetSecondCurve2d(BS2);
2282 }
2283
2284 }
2285 else {
2286 Handle(Geom2d_BSplineCurve) H2;
2287 //
2288 aCurve.SetSecondCurve2d(H2);
2289 }
2290 //
2291 mySeqOfCurve.Append(aCurve);
2292 }
2293 }
2294 }
7fd59977 2295 }
2296 }// else { // X
2297 }// case IntPatch_Walking:{
94218044 2298 break;
2299
7fd59977 2300 case IntPatch_Restriction:
2301 break;
2302
2303 }
2304}
2305
2306//=======================================================================
2307//function : BuildPCurves
2308//purpose :
2309//=======================================================================
2310 void BuildPCurves (Standard_Real f,
2311 Standard_Real l,
2312 Standard_Real& Tol,
2313 const Handle (Geom_Surface)& S,
2314 const Handle (Geom_Curve)& C,
2315 Handle (Geom2d_Curve)& C2d)
2316{
2317
2318 Standard_Real umin,umax,vmin,vmax;
2319 //
2320
2321 if (C2d.IsNull()) {
2322
2323 // in class ProjLib_Function the range of parameters is shrank by 1.e-09
2324 if((l - f) > 2.e-09) {
2325 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2326 //
2327 if (C2d.IsNull()) {
2328 // proj. a circle that goes through the pole on a sphere to the sphere
2329 Tol=Tol+1.e-7;
2330 C2d = GeomProjLib::Curve2d(C,f,l,S,Tol);
2331 }
2332 }
2333 else {
2334 if((l - f) > Epsilon(Abs(f))) {
2335 GeomAPI_ProjectPointOnSurf aProjector1, aProjector2;
2336 gp_Pnt P1 = C->Value(f);
2337 gp_Pnt P2 = C->Value(l);
2338 aProjector1.Init(P1, S);
2339 aProjector2.Init(P2, S);
2340
2341 if(aProjector1.IsDone() && aProjector2.IsDone()) {
2342 Standard_Real U=0., V=0.;
2343 aProjector1.LowerDistanceParameters(U, V);
2344 gp_Pnt2d p1(U, V);
2345
2346 aProjector2.LowerDistanceParameters(U, V);
2347 gp_Pnt2d p2(U, V);
2348
2349 if(p1.Distance(p2) > gp::Resolution()) {
2350 TColgp_Array1OfPnt2d poles(1,2);
2351 TColStd_Array1OfReal knots(1,2);
2352 TColStd_Array1OfInteger mults(1,2);
2353 poles(1) = p1;
2354 poles(2) = p2;
2355 knots(1) = f;
2356 knots(2) = l;
2357 mults(1) = mults(2) = 2;
2358
2359 C2d = new Geom2d_BSplineCurve(poles,knots,mults,1);
2360
2361 // compute reached tolerance.begin
2362 gp_Pnt PMid = C->Value((f + l) * 0.5);
2363 aProjector1.Perform(PMid);
2364
2365 if(aProjector1.IsDone()) {
2366 aProjector1.LowerDistanceParameters(U, V);
2367 gp_Pnt2d pmidproj(U, V);
2368 gp_Pnt2d pmidcurve2d = C2d->Value((f + l) * 0.5);
2369 Standard_Real adist = pmidcurve2d.Distance(pmidproj);
2370 Tol = (adist > Tol) ? adist : Tol;
2371 }
2372 // compute reached tolerance.end
2373 }
2374 }
2375 }
2376 }
2377 //
2378 S->Bounds(umin, umax, vmin, vmax);
2379
2380 if (S->IsUPeriodic() && !C2d.IsNull()) {
0fc4f2e2 2381 // Recadre dans le domaine UV de la face
7fd59977 2382 Standard_Real period, U0, du, aEps;
2383
2384 du =0.0;
2385 aEps=Precision::PConfusion();
2386 period = S->UPeriod();
2387 gp_Pnt2d Pf = C2d->Value(f);
2388 U0=Pf.X();
2389 //
2390 gp_Pnt2d Pl = C2d->Value(l);
2391
2392 U0 = Min(Pl.X(), U0);
2393// while(U0-umin<aEps) {
2394 while(U0-umin<-aEps) {
2395 U0+=period;
2396 du+=period;
2397 }
2398 //
2399 while(U0-umax>aEps) {
2400 U0-=period;
2401 du-=period;
2402 }
2403 if (du != 0) {
2404 gp_Vec2d T1(du,0.);
2405 C2d->Translate(T1);
2406 }
2407 }
2408 }
7fd59977 2409}
2410
2411//=======================================================================
2412//function : Parameters
2413//purpose :
2414//=======================================================================
2415 void Parameters(const Handle(GeomAdaptor_HSurface)& HS1,
2416 const Handle(GeomAdaptor_HSurface)& HS2,
2417 const gp_Pnt& Ptref,
2418 Standard_Real& U1,
2419 Standard_Real& V1,
2420 Standard_Real& U2,
2421 Standard_Real& V2)
2422{
2423
2424 IntSurf_Quadric quad1,quad2;
2425 GeomAbs_SurfaceType typs = HS1->Surface().GetType();
2426
2427 switch (typs) {
2428 case GeomAbs_Plane:
2429 quad1.SetValue(HS1->Surface().Plane());
2430 break;
2431 case GeomAbs_Cylinder:
2432 quad1.SetValue(HS1->Surface().Cylinder());
2433 break;
2434 case GeomAbs_Cone:
2435 quad1.SetValue(HS1->Surface().Cone());
2436 break;
2437 case GeomAbs_Sphere:
2438 quad1.SetValue(HS1->Surface().Sphere());
2439 break;
2440 default:
2441 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2442 }
2443
2444 typs = HS2->Surface().GetType();
2445 switch (typs) {
2446 case GeomAbs_Plane:
2447 quad2.SetValue(HS2->Surface().Plane());
2448 break;
2449 case GeomAbs_Cylinder:
2450 quad2.SetValue(HS2->Surface().Cylinder());
2451 break;
2452 case GeomAbs_Cone:
2453 quad2.SetValue(HS2->Surface().Cone());
2454 break;
2455 case GeomAbs_Sphere:
2456 quad2.SetValue(HS2->Surface().Sphere());
2457 break;
2458 default:
2459 Standard_ConstructionError::Raise("GeomInt_IntSS::MakeCurve");
2460 }
2461
2462 quad1.Parameters(Ptref,U1,V1);
2463 quad2.Parameters(Ptref,U2,V2);
2464}
2465
2466//=======================================================================
2467//function : MakeBSpline
2468//purpose :
2469//=======================================================================
2470Handle(Geom_Curve) MakeBSpline (const Handle(IntPatch_WLine)& WL,
2471 const Standard_Integer ideb,
2472 const Standard_Integer ifin)
2473{
2474 Standard_Integer i,nbpnt = ifin-ideb+1;
2475 TColgp_Array1OfPnt poles(1,nbpnt);
2476 TColStd_Array1OfReal knots(1,nbpnt);
2477 TColStd_Array1OfInteger mults(1,nbpnt);
2478 Standard_Integer ipidebm1;
2479 for(i=1,ipidebm1=i+ideb-1; i<=nbpnt;ipidebm1++, i++) {
2480 poles(i) = WL->Point(ipidebm1).Value();
2481 mults(i) = 1;
2482 knots(i) = i-1;
2483 }
2484 mults(1) = mults(nbpnt) = 2;
2485 return
2486 new Geom_BSplineCurve(poles,knots,mults,1);
2487}
2488//
2489
2490//=======================================================================
2491//function : MakeBSpline2d
2492//purpose :
2493//=======================================================================
2494Handle(Geom2d_BSplineCurve) MakeBSpline2d(const Handle(IntPatch_WLine)& theWLine,
2495 const Standard_Integer ideb,
2496 const Standard_Integer ifin,
2497 const Standard_Boolean onFirst)
2498{
2499 Standard_Integer i, nbpnt = ifin-ideb+1;
2500 TColgp_Array1OfPnt2d poles(1,nbpnt);
2501 TColStd_Array1OfReal knots(1,nbpnt);
2502 TColStd_Array1OfInteger mults(1,nbpnt);
2503 Standard_Integer ipidebm1;
2504
2505 for(i = 1, ipidebm1 = i+ideb-1; i <= nbpnt; ipidebm1++, i++) {
2506 Standard_Real U, V;
2507 if(onFirst)
2508 theWLine->Point(ipidebm1).ParametersOnS1(U, V);
2509 else
2510 theWLine->Point(ipidebm1).ParametersOnS2(U, V);
2511 poles(i).SetCoord(U, V);
2512 mults(i) = 1;
2513 knots(i) = i-1;
2514 }
2515 mults(1) = mults(nbpnt) = 2;
2516
2517 return new Geom2d_BSplineCurve(poles,knots,mults,1);
2518}
2519//=======================================================================
2520//function : PrepareLines3D
2521//purpose :
2522//=======================================================================
a9f7b6b5 2523 void IntTools_FaceFace::PrepareLines3D(const Standard_Boolean bToSplit)
7fd59977 2524{
a9f7b6b5
P
2525 Standard_Integer i, aNbCurves;
2526 GeomAbs_SurfaceType aType1, aType2;
7fd59977 2527 IntTools_SequenceOfCurves aNewCvs;
7fd59977 2528 //
a9f7b6b5 2529 // 1. Treatment closed curves
7fd59977 2530 aNbCurves=mySeqOfCurve.Length();
a9f7b6b5 2531 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2532 const IntTools_Curve& aIC=mySeqOfCurve(i);
7fd59977 2533 //
a9f7b6b5
P
2534 if (bToSplit) {
2535 Standard_Integer j, aNbC;
2536 IntTools_SequenceOfCurves aSeqCvs;
2537 //
2538 aNbC=IntTools_Tools::SplitCurve(aIC, aSeqCvs);
2539 if (aNbC) {
2540 for (j=1; j<=aNbC; ++j) {
2541 const IntTools_Curve& aICNew=aSeqCvs(j);
2542 aNewCvs.Append(aICNew);
2543 }
2544 }
2545 else {
2546 aNewCvs.Append(aIC);
7fd59977 2547 }
2548 }
7fd59977 2549 else {
2550 aNewCvs.Append(aIC);
2551 }
2552 }
2553 //
2554 // 2. Plane\Cone intersection when we had 4 curves
a9f7b6b5
P
2555 aType1=myHS1->GetType();
2556 aType2=myHS2->GetType();
2557 aNbCurves=aNewCvs.Length();
2558 //
7fd59977 2559 if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone) ||
2560 (aType2==GeomAbs_Plane && aType1==GeomAbs_Cone)) {
7fd59977 2561 if (aNbCurves==4) {
a9f7b6b5
P
2562 GeomAbs_CurveType aCType1;
2563 //
2564 aCType1=aNewCvs(1).Type();
7fd59977 2565 if (aCType1==GeomAbs_Line) {
2566 IntTools_SequenceOfCurves aSeqIn, aSeqOut;
2567 //
a9f7b6b5 2568 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2569 const IntTools_Curve& aIC=aNewCvs(i);
2570 aSeqIn.Append(aIC);
2571 }
2572 //
2573 IntTools_Tools::RejectLines(aSeqIn, aSeqOut);
2574 //
2575 aNewCvs.Clear();
2576 aNbCurves=aSeqOut.Length();
a9f7b6b5 2577 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2578 const IntTools_Curve& aIC=aSeqOut(i);
2579 aNewCvs.Append(aIC);
2580 }
7fd59977 2581 }
2582 }
a9f7b6b5 2583 }// if ((aType1==GeomAbs_Plane && aType2==GeomAbs_Cone)...
7fd59977 2584 //
2585 // 3. Fill mySeqOfCurve
2586 mySeqOfCurve.Clear();
2587 aNbCurves=aNewCvs.Length();
a9f7b6b5 2588 for (i=1; i<=aNbCurves; ++i) {
7fd59977 2589 const IntTools_Curve& aIC=aNewCvs(i);
2590 mySeqOfCurve.Append(aIC);
2591 }
7fd59977 2592}
7fd59977 2593//=======================================================================
2594//function : CorrectSurfaceBoundaries
2595//purpose :
2596//=======================================================================
2597 void CorrectSurfaceBoundaries(const TopoDS_Face& theFace,
2598 const Standard_Real theTolerance,
2599 Standard_Real& theumin,
2600 Standard_Real& theumax,
2601 Standard_Real& thevmin,
2602 Standard_Real& thevmax)
2603{
2604 Standard_Boolean enlarge, isuperiodic, isvperiodic;
2605 Standard_Real uinf, usup, vinf, vsup, delta;
2606 GeomAbs_SurfaceType aType;
2607 Handle(Geom_Surface) aSurface;
2608 //
2609 aSurface = BRep_Tool::Surface(theFace);
2610 aSurface->Bounds(uinf, usup, vinf, vsup);
2611 delta = theTolerance;
2612 enlarge = Standard_False;
2613 //
2614 GeomAdaptor_Surface anAdaptorSurface(aSurface);
2615 //
2616 if(aSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
2617 Handle(Geom_Surface) aBasisSurface =
2618 (Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface))->BasisSurface();
2619
2620 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2621 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2622 return;
2623 }
2624 }
2625 //
2626 if(aSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2627 Handle(Geom_Surface) aBasisSurface =
2628 (Handle(Geom_OffsetSurface)::DownCast(aSurface))->BasisSurface();
2629
2630 if(aBasisSurface->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)) ||
2631 aBasisSurface->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
2632 return;
2633 }
2634 }
2635 //
2636 isuperiodic = anAdaptorSurface.IsUPeriodic();
2637 isvperiodic = anAdaptorSurface.IsVPeriodic();
2638 //
2639 aType=anAdaptorSurface.GetType();
2640 if((aType==GeomAbs_BezierSurface) ||
2641 (aType==GeomAbs_BSplineSurface) ||
2642 (aType==GeomAbs_SurfaceOfExtrusion) ||
2643 (aType==GeomAbs_SurfaceOfRevolution)) {
2644 enlarge=Standard_True;
2645 }
2646 //
2647 if(!isuperiodic && enlarge) {
2648
2649 if((theumin - uinf) > delta )
2650 theumin -= delta;
2651 else {
2652 theumin = uinf;
2653 }
2654
2655 if((usup - theumax) > delta )
2656 theumax += delta;
2657 else
2658 theumax = usup;
2659 }
2660 //
2661 if(!isvperiodic && enlarge) {
2662 if((thevmin - vinf) > delta ) {
2663 thevmin -= delta;
2664 }
2665 else {
2666 thevmin = vinf;
2667 }
2668 if((vsup - thevmax) > delta ) {
2669 thevmax += delta;
2670 }
2671 else {
2672 thevmax = vsup;
2673 }
2674 }
2675 //
2676 {
2677 Standard_Integer aNbP;
2678 Standard_Real aXP, dXfact, aXmid, aX1, aX2, aTolPA;
2679 //
2680 aTolPA=Precision::Angular();
2681 // U
2682 if (isuperiodic) {
2683 aXP=anAdaptorSurface.UPeriod();
2684 dXfact=theumax-theumin;
2685 if (dXfact-aTolPA>aXP) {
2686 aXmid=0.5*(theumax+theumin);
2687 aNbP=RealToInt(aXmid/aXP);
2688 if (aXmid<0.) {
2689 aNbP=aNbP-1;
2690 }
2691 aX1=aNbP*aXP;
0fc4f2e2
P
2692 if (theumin>aTolPA) {
2693 aX1=theumin+aNbP*aXP;
2694 }
7fd59977 2695 aX2=aX1+aXP;
2696 if (theumin<aX1) {
2697 theumin=aX1;
2698 }
2699 if (theumax>aX2) {
2700 theumax=aX2;
2701 }
2702 }
2703 }
2704 // V
2705 if (isvperiodic) {
2706 aXP=anAdaptorSurface.VPeriod();
2707 dXfact=thevmax-thevmin;
2708 if (dXfact-aTolPA>aXP) {
2709 aXmid=0.5*(thevmax+thevmin);
2710 aNbP=RealToInt(aXmid/aXP);
2711 if (aXmid<0.) {
2712 aNbP=aNbP-1;
2713 }
2714 aX1=aNbP*aXP;
0fc4f2e2
P
2715 if (thevmin>aTolPA) {
2716 aX1=thevmin+aNbP*aXP;
2717 }
7fd59977 2718 aX2=aX1+aXP;
2719 if (thevmin<aX1) {
2720 thevmin=aX1;
2721 }
2722 if (thevmax>aX2) {
2723 thevmax=aX2;
2724 }
2725 }
2726 }
2727 }
2728 //
2729 if(isuperiodic || isvperiodic) {
2730 Standard_Boolean correct = Standard_False;
2731 Standard_Boolean correctU = Standard_False;
2732 Standard_Boolean correctV = Standard_False;
2733 Bnd_Box2d aBox;
2734 TopExp_Explorer anExp;
2735
2736 for(anExp.Init(theFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
2737 if(BRep_Tool::IsClosed(TopoDS::Edge(anExp.Current()), theFace)) {
2738 correct = Standard_True;
2739 Standard_Real f, l;
2740 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
2741
2742 for(Standard_Integer i = 0; i < 2; i++) {
2743 if(i==0) {
2744 anEdge.Orientation(TopAbs_FORWARD);
2745 }
2746 else {
2747 anEdge.Orientation(TopAbs_REVERSED);
2748 }
2749 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, f, l);
2750
2751 if(aCurve.IsNull()) {
2752 correct = Standard_False;
2753 break;
2754 }
2755 Handle(Geom2d_Line) aLine = Handle(Geom2d_Line)::DownCast(aCurve);
2756
2757 if(aLine.IsNull()) {
2758 correct = Standard_False;
2759 break;
2760 }
2761 gp_Dir2d anUDir(1., 0.);
2762 gp_Dir2d aVDir(0., 1.);
2763 Standard_Real anAngularTolerance = Precision::Angular();
2764
2765 correctU = correctU || aLine->Position().Direction().IsParallel(aVDir, anAngularTolerance);
2766 correctV = correctV || aLine->Position().Direction().IsParallel(anUDir, anAngularTolerance);
2767
2768 gp_Pnt2d pp1 = aCurve->Value(f);
2769 aBox.Add(pp1);
2770 gp_Pnt2d pp2 = aCurve->Value(l);
2771 aBox.Add(pp2);
2772 }
2773 if(!correct)
2774 break;
2775 }
2776 }
2777
2778 if(correct) {
2779 Standard_Real umin, vmin, umax, vmax;
2780 aBox.Get(umin, vmin, umax, vmax);
2781
2782 if(isuperiodic && correctU) {
2783
2784 if(theumin < umin)
2785 theumin = umin;
2786
2787 if(theumax > umax) {
2788 theumax = umax;
2789 }
2790 }
2791 if(isvperiodic && correctV) {
2792
2793 if(thevmin < vmin)
2794 thevmin = vmin;
2795 if(thevmax > vmax)
2796 thevmax = vmax;
2797 }
2798 }
2799 }
2800}
2801//
2802//
2803// The block is dedicated to determine whether WLine [ifprm, ilprm]
2804// crosses the degenerated zone on each given surface or not.
2805// If Yes -> We will not use info about surfaces during approximation
8e0115e4 2806// because inside degenerated zone of the surface the approx. algo.
7fd59977 2807// uses wrong values of normal, etc., and resulting curve will have
2808// oscillations that we would not like to have.
7fd59977 2809
2810
4e57c75e 2811
7fd59977 2812static
2813 Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2814 const Handle(Geom_Surface)& aS,
2815 const Standard_Integer iDir);
2816static
2817 Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2818 const TopoDS_Face& aF1,
2819 const TopoDS_Face& aF2);
2820//=======================================================================
2821//function : NotUseSurfacesForApprox
2822//purpose :
2823//=======================================================================
2824Standard_Boolean NotUseSurfacesForApprox(const TopoDS_Face& aF1,
2825 const TopoDS_Face& aF2,
2826 const Handle(IntPatch_WLine)& WL,
2827 const Standard_Integer ifprm,
2828 const Standard_Integer ilprm)
2829{
2830 Standard_Boolean bPInDZ;
2831
2832 Handle(IntSurf_LineOn2S) aLineOn2S=WL->Curve();
2833
2834 const IntSurf_PntOn2S& aP2Sfprm=aLineOn2S->Value(ifprm);
2835 bPInDZ=IsPointInDegeneratedZone(aP2Sfprm, aF1, aF2);
2836 if (bPInDZ) {
2837 return bPInDZ;
2838 }
2839
2840 const IntSurf_PntOn2S& aP2Slprm=aLineOn2S->Value(ilprm);
2841 bPInDZ=IsPointInDegeneratedZone(aP2Slprm, aF1, aF2);
2842
2843 return bPInDZ;
2844}
2845//=======================================================================
2846//function : IsPointInDegeneratedZone
2847//purpose :
2848//=======================================================================
2849Standard_Boolean IsPointInDegeneratedZone(const IntSurf_PntOn2S& aP2S,
2850 const TopoDS_Face& aF1,
2851 const TopoDS_Face& aF2)
2852
2853{
2854 Standard_Boolean bFlag=Standard_True;
2855 Standard_Real US11, US12, VS11, VS12, US21, US22, VS21, VS22;
2856 Standard_Real U1, V1, U2, V2, aDelta, aD;
2857 gp_Pnt2d aP2d;
2858
2859 Handle(Geom_Surface)aS1 = BRep_Tool::Surface(aF1);
2860 aS1->Bounds(US11, US12, VS11, VS12);
2861 GeomAdaptor_Surface aGAS1(aS1);
2862
2863 Handle(Geom_Surface)aS2 = BRep_Tool::Surface(aF2);
2864 aS1->Bounds(US21, US22, VS21, VS22);
2865 GeomAdaptor_Surface aGAS2(aS2);
2866 //
2867 //const gp_Pnt& aP=aP2S.Value();
2868 aP2S.Parameters(U1, V1, U2, V2);
2869 //
2870 aDelta=1.e-7;
2871 // Check on Surf 1
2872 aD=aGAS1.UResolution(aDelta);
2873 aP2d.SetCoord(U1, V1);
2874 if (fabs(U1-US11) < aD) {
2875 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2876 if (bFlag) {
2877 return bFlag;
2878 }
2879 }
2880 if (fabs(U1-US12) < aD) {
2881 bFlag=IsDegeneratedZone(aP2d, aS1, 1);
2882 if (bFlag) {
2883 return bFlag;
2884 }
2885 }
2886 aD=aGAS1.VResolution(aDelta);
2887 if (fabs(V1-VS11) < aDelta) {
2888 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2889 if (bFlag) {
2890 return bFlag;
2891 }
2892 }
2893 if (fabs(V1-VS12) < aDelta) {
2894 bFlag=IsDegeneratedZone(aP2d, aS1, 2);
2895 if (bFlag) {
2896 return bFlag;
2897 }
2898 }
2899 // Check on Surf 2
2900 aD=aGAS2.UResolution(aDelta);
2901 aP2d.SetCoord(U2, V2);
2902 if (fabs(U2-US21) < aDelta) {
2903 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2904 if (bFlag) {
2905 return bFlag;
2906 }
2907 }
2908 if (fabs(U2-US22) < aDelta) {
2909 bFlag=IsDegeneratedZone(aP2d, aS2, 1);
2910 if (bFlag) {
2911 return bFlag;
2912 }
2913 }
2914 aD=aGAS2.VResolution(aDelta);
2915 if (fabs(V2-VS21) < aDelta) {
2916 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2917 if (bFlag) {
2918 return bFlag;
2919 }
2920 }
2921 if (fabs(V2-VS22) < aDelta) {
2922 bFlag=IsDegeneratedZone(aP2d, aS2, 2);
2923 if (bFlag) {
2924 return bFlag;
2925 }
2926 }
2927 return !bFlag;
2928}
2929
2930//=======================================================================
2931//function : IsDegeneratedZone
2932//purpose :
2933//=======================================================================
2934Standard_Boolean IsDegeneratedZone(const gp_Pnt2d& aP2d,
2935 const Handle(Geom_Surface)& aS,
2936 const Standard_Integer iDir)
2937{
2938 Standard_Boolean bFlag=Standard_True;
2939 Standard_Real US1, US2, VS1, VS2, dY, dX, d1, d2, dD;
2940 Standard_Real aXm, aYm, aXb, aYb, aXe, aYe;
2941 aS->Bounds(US1, US2, VS1, VS2);
2942
2943 gp_Pnt aPm, aPb, aPe;
2944
2945 aXm=aP2d.X();
2946 aYm=aP2d.Y();
2947
2948 aS->D0(aXm, aYm, aPm);
2949
2950 dX=1.e-5;
2951 dY=1.e-5;
2952 dD=1.e-12;
2953
2954 if (iDir==1) {
2955 aXb=aXm;
2956 aXe=aXm;
2957 aYb=aYm-dY;
2958 if (aYb < VS1) {
2959 aYb=VS1;
2960 }
2961 aYe=aYm+dY;
2962 if (aYe > VS2) {
2963 aYe=VS2;
2964 }
2965 aS->D0(aXb, aYb, aPb);
2966 aS->D0(aXe, aYe, aPe);
2967
2968 d1=aPm.Distance(aPb);
2969 d2=aPm.Distance(aPe);
2970 if (d1 < dD && d2 < dD) {
2971 return bFlag;
2972 }
2973 return !bFlag;
2974 }
2975 //
2976 else if (iDir==2) {
2977 aYb=aYm;
2978 aYe=aYm;
2979 aXb=aXm-dX;
2980 if (aXb < US1) {
2981 aXb=US1;
2982 }
2983 aXe=aXm+dX;
2984 if (aXe > US2) {
2985 aXe=US2;
2986 }
2987 aS->D0(aXb, aYb, aPb);
2988 aS->D0(aXe, aYe, aPe);
2989
2990 d1=aPm.Distance(aPb);
2991 d2=aPm.Distance(aPe);
2992 if (d1 < dD && d2 < dD) {
2993 return bFlag;
2994 }
2995 return !bFlag;
2996 }
2997 return !bFlag;
2998}
2999
3000//=========================================================================
3001// static function : ComputePurgedWLine
3002// purpose : Removes equal points (leave one of equal points) from theWLine
3003// and recompute vertex parameters.
3004// Returns new WLine or null WLine if the number
3005// of the points is less than 2.
3006//=========================================================================
3007Handle(IntPatch_WLine) ComputePurgedWLine(const Handle(IntPatch_WLine)& theWLine) {
3928aec6 3008
3928aec6 3009 Standard_Integer i, k, v, nb, nbvtx;
7fd59977 3010 Handle(IntPatch_WLine) aResult;
3928aec6
P
3011 nbvtx = theWLine->NbVertex();
3012 nb = theWLine->NbPnts();
3013 if (nb==2) {
3014 const IntSurf_PntOn2S& p1 = theWLine->Point(1);
3015 const IntSurf_PntOn2S& p2 = theWLine->Point(2);
3016 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
3017 return aResult;
3018 }
3019 }
3020 //
7fd59977 3021 Handle(IntPatch_WLine) aLocalWLine;
3022 Handle(IntPatch_WLine) aTmpWLine = theWLine;
7fd59977 3023 Handle(IntSurf_LineOn2S) aLineOn2S = new IntSurf_LineOn2S();
3024 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
7fd59977 3025 for(i = 1; i <= nb; i++) {
3026 aLineOn2S->Add(theWLine->Point(i));
3027 }
3028
3029 for(v = 1; v <= nbvtx; v++) {
3030 aLocalWLine->AddVertex(theWLine->Vertex(v));
3031 }
3032
3033 for(i = 1; i <= aLineOn2S->NbPoints(); i++) {
3034 Standard_Integer aStartIndex = i + 1;
3035 Standard_Integer anEndIndex = i + 5;
3036 nb = aLineOn2S->NbPoints();
3037 anEndIndex = (anEndIndex > nb) ? nb : anEndIndex;
3038
a2eede02 3039 if((aStartIndex > nb) || (anEndIndex <= 1)) {
7fd59977 3040 continue;
3041 }
3042 k = aStartIndex;
3043
3044 while(k <= anEndIndex) {
3045
3046 if(i != k) {
3047 IntSurf_PntOn2S p1 = aLineOn2S->Value(i);
3048 IntSurf_PntOn2S p2 = aLineOn2S->Value(k);
3049
3050 if(p1.Value().IsEqual(p2.Value(), gp::Resolution())) {
3051 aTmpWLine = aLocalWLine;
3052 aLocalWLine = new IntPatch_WLine(aLineOn2S, Standard_False);
3053
3054 for(v = 1; v <= aTmpWLine->NbVertex(); v++) {
3055 IntPatch_Point aVertex = aTmpWLine->Vertex(v);
3056 Standard_Integer avertexindex = (Standard_Integer)aVertex.ParameterOnLine();
3057
3058 if(avertexindex >= k) {
3059 aVertex.SetParameter(aVertex.ParameterOnLine() - 1.);
3060 }
3061 aLocalWLine->AddVertex(aVertex);
3062 }
3063 aLineOn2S->RemovePoint(k);
3064 anEndIndex--;
3065 continue;
3066 }
3067 }
3068 k++;
3069 }
3070 }
3071
3072 if(aLineOn2S->NbPoints() > 1) {
3073 aResult = aLocalWLine;
3074 }
3075 return aResult;
3076}
3077
3078//=======================================================================
3079//function : TolR3d
3080//purpose :
3081//=======================================================================
3082void TolR3d(const TopoDS_Face& aF1,
3083 const TopoDS_Face& aF2,
3084 Standard_Real& myTolReached3d)
3085{
3086 Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
3087
3088 aTolTresh=2.999999e-3;
3089 aTolF1 = BRep_Tool::Tolerance(aF1);
3090 aTolF2 = BRep_Tool::Tolerance(aF2);
3091 aTolFMax=Max(aTolF1, aTolF2);
3092
3093 if (aTolFMax>aTolTresh) {
3094 myTolReached3d=aTolFMax;
3095 }
3096}
3097//=======================================================================
3098//function : AdjustPeriodic
3099//purpose :
3100//=======================================================================
3101Standard_Real AdjustPeriodic(const Standard_Real theParameter,
3102 const Standard_Real parmin,
3103 const Standard_Real parmax,
3104 const Standard_Real thePeriod,
3105 Standard_Real& theOffset)
3106{
3107 Standard_Real aresult;
3108 //
3109 theOffset = 0.;
3110 aresult = theParameter;
3111 while(aresult < parmin) {
3112 aresult += thePeriod;
3113 theOffset += thePeriod;
3114 }
3115
3116 while(aresult > parmax) {
3117 aresult -= thePeriod;
3118 theOffset -= thePeriod;
3119 }
3120 return aresult;
3121}
3122//=======================================================================
3123//function : IsPointOnBoundary
3124//purpose :
3125//=======================================================================
3126Standard_Boolean IsPointOnBoundary(const Standard_Real theParameter,
3127 const Standard_Real theFirstBoundary,
3128 const Standard_Real theSecondBoundary,
3129 const Standard_Real theResolution,
3130 Standard_Boolean& IsOnFirstBoundary)
3131{
3132 Standard_Boolean bRet;
3133 Standard_Integer i;
3134 Standard_Real adist;
3135 //
3136 bRet=Standard_False;
3137 for(i = 0; i < 2; ++i) {
3138 IsOnFirstBoundary = (i == 0);
3139 if (IsOnFirstBoundary) {
3140 adist = fabs(theParameter - theFirstBoundary);
3141 }
3142 else {
3143 adist = fabs(theParameter - theSecondBoundary);
3144 }
3145 if(adist < theResolution) {
3146 return !bRet;
3147 }
3148 }
3149 return bRet;
3150}
3151// ------------------------------------------------------------------------------------------------
3152// static function: FindPoint
3153// purpose:
3154// ------------------------------------------------------------------------------------------------
3155Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
3156 const gp_Pnt2d& theLastPoint,
3157 const Standard_Real theUmin,
3158 const Standard_Real theUmax,
3159 const Standard_Real theVmin,
3160 const Standard_Real theVmax,
3161 gp_Pnt2d& theNewPoint) {
3162
3163 gp_Vec2d aVec(theFirstPoint, theLastPoint);
3164 Standard_Integer i = 0, j = 0;
3165
3166 for(i = 0; i < 4; i++) {
3167 gp_Vec2d anOtherVec;
3168 gp_Vec2d anOtherVecNormal;
3169 gp_Pnt2d aprojpoint = theLastPoint;
3170
3171 if((i % 2) == 0) {
3172 anOtherVec.SetX(0.);
3173 anOtherVec.SetY(1.);
3174 anOtherVecNormal.SetX(1.);
3175 anOtherVecNormal.SetY(0.);
3176
3177 if(i < 2)
3178 aprojpoint.SetX(theUmin);
3179 else
3180 aprojpoint.SetX(theUmax);
3181 }
3182 else {
3183 anOtherVec.SetX(1.);
3184 anOtherVec.SetY(0.);
3185 anOtherVecNormal.SetX(0.);
3186 anOtherVecNormal.SetY(1.);
3187
3188 if(i < 2)
3189 aprojpoint.SetY(theVmin);
3190 else
3191 aprojpoint.SetY(theVmax);
3192 }
3193 gp_Vec2d anormvec = aVec;
3194 anormvec.Normalize();
fa9681ca 3195 RefineVector(anormvec);
7fd59977 3196 Standard_Real adot1 = anormvec.Dot(anOtherVecNormal);
3197
3198 if(fabs(adot1) < Precision::Angular())
3199 continue;
3200 Standard_Real adist = 0.;
3201 Standard_Boolean bIsOut = Standard_False;
3202
3203 if((i % 2) == 0) {
3204 adist = (i < 2) ? fabs(theLastPoint.X() - theUmin) : fabs(theLastPoint.X() - theUmax);
3205 bIsOut = (i < 2) ? (theLastPoint.X() < theUmin) : (theLastPoint.X() > theUmax);
3206 }
3207 else {
3208 adist = (i < 2) ? fabs(theLastPoint.Y() - theVmin) : fabs(theLastPoint.Y() - theVmax);
3209 bIsOut = (i < 2) ? (theLastPoint.Y() < theVmin) : (theLastPoint.Y() > theVmax);
3210 }
3211 Standard_Real anoffset = adist * anOtherVec.Dot(anormvec) / adot1;
3212
3213 for(j = 0; j < 2; j++) {
3214 anoffset = (j == 0) ? anoffset : -anoffset;
3215 gp_Pnt2d acurpoint(aprojpoint.XY() + (anOtherVec.XY()*anoffset));
3216 gp_Vec2d acurvec(theLastPoint, acurpoint);
3217 if ( bIsOut )
3218 acurvec.Reverse();
3219
9e9df9d9
P
3220 Standard_Real aDotX, anAngleX;
3221 //
3222 aDotX = aVec.Dot(acurvec);
3223 anAngleX = aVec.Angle(acurvec);
3224 //
3225 if(aDotX > 0. && fabs(anAngleX) < Precision::PConfusion()) {
7fd59977 3226 if((i % 2) == 0) {
3227 if((acurpoint.Y() >= theVmin) &&
3228 (acurpoint.Y() <= theVmax)) {
3229 theNewPoint = acurpoint;
3230 return Standard_True;
3231 }
3232 }
3233 else {
3234 if((acurpoint.X() >= theUmin) &&
3235 (acurpoint.X() <= theUmax)) {
3236 theNewPoint = acurpoint;
3237 return Standard_True;
3238 }
3239 }
3240 }
3241 }
3242 }
3243 return Standard_False;
3244}
3245
3246
3247// ------------------------------------------------------------------------------------------------
3248// static function: FindPoint
3249// purpose: Find point on the boundary of radial tangent zone
3250// ------------------------------------------------------------------------------------------------
3251Standard_Boolean FindPoint(const gp_Pnt2d& theFirstPoint,
3252 const gp_Pnt2d& theLastPoint,
3253 const Standard_Real theUmin,
3254 const Standard_Real theUmax,
3255 const Standard_Real theVmin,
3256 const Standard_Real theVmax,
3257 const gp_Pnt2d& theTanZoneCenter,
3258 const Standard_Real theZoneRadius,
3259 Handle(GeomAdaptor_HSurface) theGASurface,
3260 gp_Pnt2d& theNewPoint) {
3261 theNewPoint = theLastPoint;
3262
3263 if ( !IsInsideTanZone( theLastPoint, theTanZoneCenter, theZoneRadius, theGASurface) )
3264 return Standard_False;
3265
3266 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3267 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3268
3269 Standard_Real aRadius = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3270 gp_Ax22d anAxis( theTanZoneCenter, gp_Dir2d(1, 0), gp_Dir2d(0, 1) );
3271 gp_Circ2d aCircle( anAxis, aRadius );
3272
3273 //
3274 gp_Vec2d aDir( theLastPoint.XY() - theFirstPoint.XY() );
3275 Standard_Real aLength = aDir.Magnitude();
3276 if ( aLength <= gp::Resolution() )
3277 return Standard_False;
3278 gp_Lin2d aLine( theFirstPoint, aDir );
3279
3280 //
3281 Handle(Geom2d_Line) aCLine = new Geom2d_Line( aLine );
3282 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve( aCLine, 0, aLength );
3283 Handle(Geom2d_Circle) aC2 = new Geom2d_Circle( aCircle );
3284
3285 Standard_Real aTol = aRadius * 0.001;
3286 aTol = ( aTol < Precision::PConfusion() ) ? Precision::PConfusion() : aTol;
3287
3288 Geom2dAPI_InterCurveCurve anIntersector;
3289 anIntersector.Init( aC1, aC2, aTol );
3290
3291 if ( anIntersector.NbPoints() == 0 )
3292 return Standard_False;
3293
3294 Standard_Boolean aFound = Standard_False;
3295 Standard_Real aMinDist = aLength * aLength;
3296 Standard_Integer i = 0;
3297 for ( i = 1; i <= anIntersector.NbPoints(); i++ ) {
3298 gp_Pnt2d aPInt = anIntersector.Point( i );
3299 if ( aPInt.SquareDistance( theFirstPoint ) < aMinDist ) {
3300 if ( ( aPInt.X() >= theUmin ) && ( aPInt.X() <= theUmax ) &&
3301 ( aPInt.Y() >= theVmin ) && ( aPInt.Y() <= theVmax ) ) {
3302 theNewPoint = aPInt;
3303 aFound = Standard_True;
3304 }
3305 }
3306 }
3307
3308 return aFound;
3309}
3310
3311// ------------------------------------------------------------------------------------------------
3312// static function: IsInsideTanZone
3313// purpose: Check if point is inside a radial tangent zone
3314// ------------------------------------------------------------------------------------------------
3315Standard_Boolean IsInsideTanZone(const gp_Pnt2d& thePoint,
3316 const gp_Pnt2d& theTanZoneCenter,
3317 const Standard_Real theZoneRadius,
3318 Handle(GeomAdaptor_HSurface) theGASurface) {
3319
3320 Standard_Real aUResolution = theGASurface->UResolution( theZoneRadius );
3321 Standard_Real aVResolution = theGASurface->VResolution( theZoneRadius );
3322 Standard_Real aRadiusSQR = ( aUResolution < aVResolution ) ? aUResolution : aVResolution;
3323 aRadiusSQR *= aRadiusSQR;
3324 if ( thePoint.SquareDistance( theTanZoneCenter ) <= aRadiusSQR )
3325 return Standard_True;
3326 return Standard_False;
3327}
3328
3329// ------------------------------------------------------------------------------------------------
3330// static function: CheckTangentZonesExist
3331// purpose: Check if tangent zone exists
3332// ------------------------------------------------------------------------------------------------
3333Standard_Boolean CheckTangentZonesExist( const Handle(GeomAdaptor_HSurface)& theSurface1,
3334 const Handle(GeomAdaptor_HSurface)& theSurface2 )
3335{
3336 if ( ( theSurface1->GetType() != GeomAbs_Torus ) ||
3337 ( theSurface2->GetType() != GeomAbs_Torus ) )
3338 return Standard_False;
3339
7fd59977 3340 gp_Torus aTor1 = theSurface1->Torus();
3341 gp_Torus aTor2 = theSurface2->Torus();
3342
3343 if ( aTor1.Location().Distance( aTor2.Location() ) > Precision::Confusion() )
3344 return Standard_False;
3345
3346 if ( ( fabs( aTor1.MajorRadius() - aTor2.MajorRadius() ) > Precision::Confusion() ) ||
3347 ( fabs( aTor1.MinorRadius() - aTor2.MinorRadius() ) > Precision::Confusion() ) )
3348 return Standard_False;
3349
3350 if ( ( aTor1.MajorRadius() < aTor1.MinorRadius() ) ||
3351 ( aTor2.MajorRadius() < aTor2.MinorRadius() ) )
3352 return Standard_False;
3353 return Standard_True;
3354}
3355
3356// ------------------------------------------------------------------------------------------------
3357// static function: ComputeTangentZones
3358// purpose:
3359// ------------------------------------------------------------------------------------------------
3360Standard_Integer ComputeTangentZones( const Handle(GeomAdaptor_HSurface)& theSurface1,
3361 const Handle(GeomAdaptor_HSurface)& theSurface2,
3362 const TopoDS_Face& theFace1,
3363 const TopoDS_Face& theFace2,
3364 Handle(TColgp_HArray1OfPnt2d)& theResultOnS1,
3365 Handle(TColgp_HArray1OfPnt2d)& theResultOnS2,
4f189102 3366 Handle(TColStd_HArray1OfReal)& theResultRadius,
4e57c75e 3367 const Handle(BOPInt_Context)& aContext)
4f189102 3368{
7fd59977 3369 Standard_Integer aResult = 0;
3370 if ( !CheckTangentZonesExist( theSurface1, theSurface2 ) )
3371 return aResult;
3372
7fd59977 3373
3374 TColgp_SequenceOfPnt2d aSeqResultS1, aSeqResultS2;
3375 TColStd_SequenceOfReal aSeqResultRad;
3376
3377 gp_Torus aTor1 = theSurface1->Torus();
3378 gp_Torus aTor2 = theSurface2->Torus();
3379
3380 gp_Ax2 anax1( aTor1.Location(), aTor1.Axis().Direction() );
3381 gp_Ax2 anax2( aTor2.Location(), aTor2.Axis().Direction() );
3382 Standard_Integer j = 0;
3383
3384 for ( j = 0; j < 2; j++ ) {
3385 Standard_Real aCoef = ( j == 0 ) ? -1 : 1;
3386 Standard_Real aRadius1 = fabs(aTor1.MajorRadius() + aCoef * aTor1.MinorRadius());
3387 Standard_Real aRadius2 = fabs(aTor2.MajorRadius() + aCoef * aTor2.MinorRadius());
3388
3389 gp_Circ aCircle1( anax1, aRadius1 );
3390 gp_Circ aCircle2( anax2, aRadius2 );
3391
3392 // roughly compute radius of tangent zone for perpendicular case
3393 Standard_Real aCriteria = Precision::Confusion() * 0.5;
3394
3395 Standard_Real aT1 = aCriteria;
3396 Standard_Real aT2 = aCriteria;
3397 if ( j == 0 ) {
3398 // internal tangency
3399 Standard_Real aR = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3400 //aT1 = aCriteria * aCriteria + aR * aR - ( aR - aCriteria ) * ( aR - aCriteria );
3401 aT1 = 2. * aR * aCriteria;
3402 aT2 = aT1;
3403 }
3404 else {
3405 // external tangency
3406 Standard_Real aRb = ( aRadius1 > aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3407 Standard_Real aRm = ( aRadius1 < aTor2.MinorRadius() ) ? aRadius1 : aTor2.MinorRadius();
3408 Standard_Real aDelta = aRb - aCriteria;
3409 aDelta *= aDelta;
3410 aDelta -= aRm * aRm;
3411 aDelta /= 2. * (aRb - aRm);
3412 aDelta -= 0.5 * (aRb - aRm);
3413
3414 aT1 = 2. * aRm * (aRm - aDelta);
3415 aT2 = aT1;
3416 }
3417 aCriteria = ( aT1 > aT2) ? aT1 : aT2;
3418 if ( aCriteria > 0 )
3419 aCriteria = sqrt( aCriteria );
3420
3421 if ( aCriteria > 0.5 * aTor1.MinorRadius() ) {
3422 // too big zone -> drop to minimum
3423 aCriteria = Precision::Confusion();
3424 }
3425
3426 GeomAdaptor_Curve aC1( new Geom_Circle(aCircle1) );
3427 GeomAdaptor_Curve aC2( new Geom_Circle(aCircle2) );
c6541a0c 3428 Extrema_ExtCC anExtrema(aC1, aC2, 0, 2. * M_PI, 0, 2. * M_PI,
7fd59977 3429 Precision::PConfusion(), Precision::PConfusion());
3430
3431 if ( anExtrema.IsDone() ) {
3432
3433 Standard_Integer i = 0;
3434 for ( i = 1; i <= anExtrema.NbExt(); i++ ) {
3435 if ( anExtrema.SquareDistance(i) > aCriteria * aCriteria )
3436 continue;
3437
3438 Extrema_POnCurv P1, P2;
3439 anExtrema.Points( i, P1, P2 );
3440
3441 Standard_Boolean bFoundResult = Standard_True;
3442 gp_Pnt2d pr1, pr2;
3443
3444 Standard_Integer surfit = 0;
3445 for ( surfit = 0; surfit < 2; surfit++ ) {
4f189102
P
3446 GeomAPI_ProjectPointOnSurf& aProjector =
3447 (surfit == 0) ? aContext->ProjPS(theFace1) : aContext->ProjPS(theFace2);
7fd59977 3448
3449 gp_Pnt aP3d = (surfit == 0) ? P1.Value() : P2.Value();
3450 aProjector.Perform(aP3d);
3451
3452 if(!aProjector.IsDone())
3453 bFoundResult = Standard_False;
3454 else {
3455 if(aProjector.LowerDistance() > aCriteria) {
3456 bFoundResult = Standard_False;
3457 }
3458 else {
3459 Standard_Real foundU = 0, foundV = 0;
3460 aProjector.LowerDistanceParameters(foundU, foundV);
3461 if ( surfit == 0 )
3462 pr1 = gp_Pnt2d( foundU, foundV );
3463 else
3464 pr2 = gp_Pnt2d( foundU, foundV );
3465 }
3466 }
3467 }
3468 if ( bFoundResult ) {
3469 aSeqResultS1.Append( pr1 );
3470 aSeqResultS2.Append( pr2 );
3471 aSeqResultRad.Append( aCriteria );
3472
3473 // torus is u and v periodic
c6541a0c 3474 const Standard_Real twoPI = M_PI + M_PI;
7fd59977 3475 Standard_Real arr1tmp[2] = {pr1.X(), pr1.Y()};
3476 Standard_Real arr2tmp[2] = {pr2.X(), pr2.Y()};
3477
3478 // iteration on period bounds
3479 for ( Standard_Integer k1 = 0; k1 < 2; k1++ ) {
3480 Standard_Real aBound = ( k1 == 0 ) ? 0 : twoPI;
3481 Standard_Real aShift = ( k1 == 0 ) ? twoPI : -twoPI;
3482
3483 // iteration on surfaces
3484 for ( Standard_Integer k2 = 0; k2 < 2; k2++ ) {
3485 Standard_Real* arr1 = ( k2 == 0 ) ? arr1tmp : arr2tmp;
3486 Standard_Real* arr2 = ( k2 != 0 ) ? arr1tmp : arr2tmp;
3487 TColgp_SequenceOfPnt2d& aSeqS1 = ( k2 == 0 ) ? aSeqResultS1 : aSeqResultS2;
3488 TColgp_SequenceOfPnt2d& aSeqS2 = ( k2 != 0 ) ? aSeqResultS1 : aSeqResultS2;
3489
3490 if (fabs(arr1[0] - aBound) < Precision::PConfusion()) {
3491 aSeqS1.Append( gp_Pnt2d( arr1[0] + aShift, arr1[1] ) );
3492 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3493 aSeqResultRad.Append( aCriteria );
3494 }
3495 if (fabs(arr1[1] - aBound) < Precision::PConfusion()) {
3496 aSeqS1.Append( gp_Pnt2d( arr1[0], arr1[1] + aShift) );
3497 aSeqS2.Append( gp_Pnt2d( arr2[0], arr2[1] ) );
3498 aSeqResultRad.Append( aCriteria );
3499 }
3500 }
3501 } //
3502 }
3503 }
3504 }
3505 }
3506 aResult = aSeqResultRad.Length();
3507
3508 if ( aResult > 0 ) {
3509 theResultOnS1 = new TColgp_HArray1OfPnt2d( 1, aResult );
3510 theResultOnS2 = new TColgp_HArray1OfPnt2d( 1, aResult );
3511 theResultRadius = new TColStd_HArray1OfReal( 1, aResult );
3512
3513 for ( Standard_Integer i = 1 ; i <= aResult; i++ ) {
3514 theResultOnS1->SetValue( i, aSeqResultS1.Value(i) );
3515 theResultOnS2->SetValue( i, aSeqResultS2.Value(i) );
3516 theResultRadius->SetValue( i, aSeqResultRad.Value(i) );
3517 }
3518 }
3519 return aResult;
3520}
3521
3522// ------------------------------------------------------------------------------------------------
3523// static function: AdjustByNeighbour
3524// purpose:
3525// ------------------------------------------------------------------------------------------------
3526gp_Pnt2d AdjustByNeighbour(const gp_Pnt2d& theaNeighbourPoint,
3527 const gp_Pnt2d& theOriginalPoint,
3528 Handle(GeomAdaptor_HSurface) theGASurface) {
3529
3530 gp_Pnt2d ap1 = theaNeighbourPoint;
3531 gp_Pnt2d ap2 = theOriginalPoint;
3532
3533 if ( theGASurface->IsUPeriodic() ) {
3534 Standard_Real aPeriod = theGASurface->UPeriod();
3535 gp_Pnt2d aPTest = ap2;
3536 Standard_Real aSqDistMin = 1.e+100;
3537
3538 for ( Standard_Integer pIt = -1; pIt <= 1; pIt++) {
3539 aPTest.SetX( theOriginalPoint.X() + aPeriod * pIt );
3540 Standard_Real dd = ap1.SquareDistance( aPTest );
3541
3542 if ( dd < aSqDistMin ) {
3543 ap2 = aPTest;
3544 aSqDistMin = dd;
3545 }
3546 }
3547 }
3548 if ( theGASurface->IsVPeriodic() ) {
3549 Standard_Real aPeriod = theGASurface->VPeriod();
3550 gp_Pnt2d aPTest = ap2;
3551 Standard_Real aSqDistMin = 1.e+100;
3552
3553 for ( Standard_Integer pIt = -1; pIt <= 1; pIt++) {
3554 aPTest.S